[clang] ad0a458 - Allow using traverse() with bindings

Stephen Kelly via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 5 12:50:43 PST 2020


Author: Stephen Kelly
Date: 2020-01-05T20:48:56Z
New Revision: ad0a45833b940057cc74364c82271247bd7925e1

URL: https://github.com/llvm/llvm-project/commit/ad0a45833b940057cc74364c82271247bd7925e1
DIFF: https://github.com/llvm/llvm-project/commit/ad0a45833b940057cc74364c82271247bd7925e1.diff

LOG: Allow using traverse() with bindings

Added: 
    

Modified: 
    clang/include/clang/ASTMatchers/ASTMatchers.h
    clang/lib/ASTMatchers/ASTMatchersInternal.cpp
    clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 7db5f7a5de82..54ccaabadbe4 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -714,6 +714,17 @@ internal::Matcher<T> traverse(ast_type_traits::TraversalKind TK,
       .template unconditionalConvertTo<T>();
 }
 
+template <typename T>
+internal::BindableMatcher<T>
+traverse(ast_type_traits::TraversalKind TK,
+         const internal::BindableMatcher<T> &InnerMatcher) {
+  return internal::BindableMatcher<T>(
+      internal::DynTypedMatcher::constructRestrictedWrapper(
+          new internal::TraversalMatcher<T>(TK, InnerMatcher),
+          InnerMatcher.getID().first)
+          .template unconditionalConvertTo<T>());
+}
+
 template <typename... T>
 internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>
 traverse(ast_type_traits::TraversalKind TK,

diff  --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index efa628cfeefc..75846ab2d4b1 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -112,6 +112,11 @@ class IdDynMatcher : public DynMatcherInterface {
     return Result;
   }
 
+  llvm::Optional<ast_type_traits::TraversalKind>
+  TraversalKind() const override {
+    return InnerMatcher->TraversalKind();
+  }
+
 private:
   const std::string ID;
   const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;

diff  --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index ea1ad424c94d..327ed979962f 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1700,6 +1700,28 @@ void bar()
                                             hasDescendant(floatLiteral())))));
 }
 
+template <typename MatcherT>
+bool matcherTemplateWithBinding(StringRef Code, const MatcherT &M) {
+  return matchAndVerifyResultTrue(
+      Code, M.bind("matchedStmt"),
+      std::make_unique<VerifyIdIsBoundTo<ReturnStmt>>("matchedStmt", 1));
+}
+
+TEST(Traversal, traverseWithBinding) {
+  // Some existing matcher code expects to take a matcher as a
+  // template arg and bind to it.  Verify that that works.
+
+  EXPECT_TRUE(matcherTemplateWithBinding(
+      R"cpp(
+int foo()
+{
+  return 42.0;
+}
+)cpp",
+      traverse(ast_type_traits::TK_AsIs,
+               returnStmt(has(implicitCastExpr(has(floatLiteral())))))));
+}
+
 TEST(Traversal, traverseMatcherNesting) {
 
   StringRef Code = R"cpp(


        


More information about the cfe-commits mailing list