Adds a convenience function selectFirst to simplify matching.

A very common use case is to search for the first occurrence of
a certain node that is a descendant of another node. In that
case, selectFirst significantly simplifies the code at the client side.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174499 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index 44e1731..870a39b 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -172,6 +172,7 @@
 /// Multiple results occur when using matchers like \c forEachDescendant,
 /// which generate a result for each sub-match.
 ///
+/// \see selectFirst
 /// @{
 template <typename MatcherT, typename NodeT>
 SmallVector<BoundNodes, 1>
@@ -183,6 +184,28 @@
       ASTContext &Context);
 /// @}
 
+/// \brief Returns the first result of type \c NodeT bound to \p BoundTo.
+///
+/// Returns \c NULL if there is no match, or if the matching node cannot be
+/// casted to \c NodeT.
+///
+/// This is useful in combanation with \c match():
+/// \code
+///   Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"),
+///                                           Node, Context));
+/// \endcode
+template <typename NodeT>
+NodeT *
+selectFirst(StringRef BoundTo, const SmallVectorImpl<BoundNodes> &Results) {
+  for (SmallVectorImpl<BoundNodes>::const_iterator I = Results.begin(),
+                                                   E = Results.end();
+       I != E; ++I) {
+    if (NodeT *Node = I->getNodeAs<NodeT>(BoundTo))
+      return Node;
+  }
+  return NULL;
+}
+
 namespace internal {
 class CollectMatchesCallback : public MatchFinder::MatchCallback {
 public:
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index 8668b49..60a79e8 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3493,53 +3493,57 @@
 
 template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
 public:
-  VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher)
-      : Id(Id), InnerMatcher(InnerMatcher) {
+  VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
+                    StringRef InnerId)
+      : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
   }
 
   virtual bool run(const BoundNodes *Nodes) { return false; }
 
   virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
     const T *Node = Nodes->getNodeAs<T>(Id);
-    SmallVector<BoundNodes, 1> Result = match(InnerMatcher, *Node, *Context);
-    return !Result.empty();
+    return selectFirst<const T>(InnerId,
+                                match(InnerMatcher, *Node, *Context)) != NULL;
   }
 private:
   std::string Id;
   internal::Matcher<T> InnerMatcher;
+  std::string InnerId;
 };
 
 TEST(MatchFinder, CanMatchDeclarationsRecursively) {
   EXPECT_TRUE(matchAndVerifyResultTrue(
       "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
       new VerifyMatchOnNode<clang::Decl>(
-          "X", decl(hasDescendant(recordDecl(hasName("X::Y")))))));
+          "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
+          "Y")));
   EXPECT_TRUE(matchAndVerifyResultFalse(
       "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
       new VerifyMatchOnNode<clang::Decl>(
-          "X", decl(hasDescendant(recordDecl(hasName("X::Z")))))));
+          "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
+          "Z")));
 }
 
 TEST(MatchFinder, CanMatchStatementsRecursively) {
   EXPECT_TRUE(matchAndVerifyResultTrue(
       "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
-      new VerifyMatchOnNode<clang::Stmt>("if",
-                                         stmt(hasDescendant(forStmt())))));
+      new VerifyMatchOnNode<clang::Stmt>(
+          "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
   EXPECT_TRUE(matchAndVerifyResultFalse(
       "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
-      new VerifyMatchOnNode<clang::Stmt>("if",
-                                         stmt(hasDescendant(declStmt())))));
+      new VerifyMatchOnNode<clang::Stmt>(
+          "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
 }
 
 TEST(MatchFinder, CanMatchSingleNodesRecursively) {
   EXPECT_TRUE(matchAndVerifyResultTrue(
       "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
       new VerifyMatchOnNode<clang::Decl>(
-          "X", recordDecl(has(recordDecl(hasName("X::Y")))))));
+          "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
   EXPECT_TRUE(matchAndVerifyResultFalse(
       "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
       new VerifyMatchOnNode<clang::Decl>(
-          "X", recordDecl(has(recordDecl(hasName("X::Z")))))));
+          "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
 }
 
 class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {