[llvm-branch-commits] [clang] release/22.x: [clang] Add missing support for traversal kind in addMatcher overloads (#170953) (PR #184039)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Mar 1 12:55:56 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Victor Chernyakin (localspook)
<details>
<summary>Changes</summary>
Backport 64e1318
As requested here: https://github.com/llvm/llvm-project/issues/179386#issuecomment-3953710324
---
Full diff: https://github.com/llvm/llvm-project/pull/184039.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+1)
- (modified) clang/lib/ASTMatchers/ASTMatchFinder.cpp (+25-21)
- (modified) clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp (+35)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d4c6025ee0638..123ec921b96cd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -839,6 +839,7 @@ AST Matchers
- Added ``hasExplicitParameters`` for ``LambdaExpr`` as an output attribute to
AST JSON dumps.
- Add ``arrayTypeLoc`` matcher for matching ``ArrayTypeLoc``.
+- Add missing support for ``TraversalKind`` in some ``addMatcher()`` overloads.
clang-format
------------
diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index e8a0004c2e187..83ffae65c67d4 100644
--- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -1654,6 +1654,16 @@ class MatchASTConsumer : public ASTConsumer {
} // end namespace
} // end namespace internal
+template <typename T>
+static internal::Matcher<T>
+adjustTraversalKind(const internal::Matcher<T> &NodeMatch,
+ MatchFinder::MatchCallback *Action) {
+ if (Action)
+ if (std::optional<TraversalKind> TK = Action->getCheckTraversalKind())
+ return traverse(*TK, NodeMatch);
+ return NodeMatch;
+}
+
MatchFinder::MatchResult::MatchResult(const BoundNodes &Nodes,
ASTContext *Context)
: Nodes(Nodes), Context(Context),
@@ -1669,67 +1679,61 @@ MatchFinder::~MatchFinder() {}
void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch,
MatchCallback *Action) {
- std::optional<TraversalKind> TK;
- if (Action)
- TK = Action->getCheckTraversalKind();
- if (TK)
- Matchers.DeclOrStmt.emplace_back(traverse(*TK, NodeMatch), Action);
- else
- Matchers.DeclOrStmt.emplace_back(NodeMatch, Action);
+ Matchers.DeclOrStmt.emplace_back(adjustTraversalKind(NodeMatch, Action),
+ Action);
Matchers.AllCallbacks.insert(Action);
}
void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,
MatchCallback *Action) {
- Matchers.Type.emplace_back(NodeMatch, Action);
+ Matchers.Type.emplace_back(adjustTraversalKind(NodeMatch, Action), Action);
Matchers.AllCallbacks.insert(Action);
}
void MatchFinder::addMatcher(const StatementMatcher &NodeMatch,
MatchCallback *Action) {
- std::optional<TraversalKind> TK;
- if (Action)
- TK = Action->getCheckTraversalKind();
- if (TK)
- Matchers.DeclOrStmt.emplace_back(traverse(*TK, NodeMatch), Action);
- else
- Matchers.DeclOrStmt.emplace_back(NodeMatch, Action);
+ Matchers.DeclOrStmt.emplace_back(adjustTraversalKind(NodeMatch, Action),
+ Action);
Matchers.AllCallbacks.insert(Action);
}
void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
MatchCallback *Action) {
- Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action);
+ Matchers.NestedNameSpecifier.emplace_back(
+ adjustTraversalKind(NodeMatch, Action), Action);
Matchers.AllCallbacks.insert(Action);
}
void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
MatchCallback *Action) {
- Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action);
+ Matchers.NestedNameSpecifierLoc.emplace_back(
+ adjustTraversalKind(NodeMatch, Action), Action);
Matchers.AllCallbacks.insert(Action);
}
void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch,
MatchCallback *Action) {
- Matchers.TypeLoc.emplace_back(NodeMatch, Action);
+ Matchers.TypeLoc.emplace_back(adjustTraversalKind(NodeMatch, Action), Action);
Matchers.AllCallbacks.insert(Action);
}
void MatchFinder::addMatcher(const CXXCtorInitializerMatcher &NodeMatch,
MatchCallback *Action) {
- Matchers.CtorInit.emplace_back(NodeMatch, Action);
+ Matchers.CtorInit.emplace_back(adjustTraversalKind(NodeMatch, Action),
+ Action);
Matchers.AllCallbacks.insert(Action);
}
void MatchFinder::addMatcher(const TemplateArgumentLocMatcher &NodeMatch,
MatchCallback *Action) {
- Matchers.TemplateArgumentLoc.emplace_back(NodeMatch, Action);
+ Matchers.TemplateArgumentLoc.emplace_back(
+ adjustTraversalKind(NodeMatch, Action), Action);
Matchers.AllCallbacks.insert(Action);
}
void MatchFinder::addMatcher(const AttrMatcher &AttrMatch,
MatchCallback *Action) {
- Matchers.Attr.emplace_back(AttrMatch, Action);
+ Matchers.Attr.emplace_back(adjustTraversalKind(AttrMatch, Action), Action);
Matchers.AllCallbacks.insert(Action);
}
diff --git a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
index a930638f355b9..3fa71804710ac 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
@@ -297,6 +297,41 @@ TEST(DynTypedMatcherTest, ConstructWithTraversalKindOverridesNestedTK) {
llvm::ValueIs(TK_IgnoreUnlessSpelledInSource));
}
+TEST(MatchFinder, AddMatcherOverloadsHonorTraversalKind) {
+ StringRef Code = R"cpp(
+ struct B {};
+ struct C : B {
+ C() {}
+ };
+ )cpp";
+
+ // C() has an implicit initializer for B.
+ auto Matcher = cxxCtorInitializer(isBaseInitializer());
+
+ {
+ bool Matched = false;
+ MatchFinder Finder;
+ struct TestCallback : public MatchFinder::MatchCallback {
+ std::optional<TraversalKind> TK;
+ bool *Matched;
+ TestCallback(std::optional<TraversalKind> TK, bool *Matched)
+ : TK(TK), Matched(Matched) {}
+ void run(const MatchFinder::MatchResult &Result) override {
+ *Matched = true;
+ }
+ std::optional<TraversalKind> getCheckTraversalKind() const override {
+ return TK;
+ }
+ } Callback(TK_IgnoreUnlessSpelledInSource, &Matched);
+ Finder.addMatcher(Matcher, &Callback);
+ std::unique_ptr<FrontendActionFactory> Factory(
+ newFrontendActionFactory(&Finder));
+ ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), Code));
+ EXPECT_FALSE(Matched) << "Matcher not using specified TraversalKind, "
+ "TK_IgnoreUnlessSpelledInSource";
+ }
+}
+
TEST(IsInlineMatcher, IsInline) {
EXPECT_TRUE(matches("void g(); inline void f();",
functionDecl(isInline(), hasName("f"))));
``````````
</details>
https://github.com/llvm/llvm-project/pull/184039
More information about the llvm-branch-commits
mailing list