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( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits