[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