https://github.com/localspook created https://github.com/llvm/llvm-project/pull/184039
Backport 64e1318 As requested here: https://github.com/llvm/llvm-project/issues/179386#issuecomment-3953710324 >From 900b8e6d62b12f5c6bafb7c57f8d2eac5490c871 Mon Sep 17 00:00:00 2001 From: Paul Kirth <[email protected]> Date: Thu, 19 Feb 2026 15:54:19 -0800 Subject: [PATCH] [clang] Backport: Add missing support for traversal kind in addMatcher overloads (#170953) This was noted in #170540, and seems to simply be an oversight. This patch just add the same logic already used in other addMatcher() implementations that honor the traversal kind. Fixes #179386. --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/ASTMatchers/ASTMatchFinder.cpp | 46 ++++++++++--------- .../ASTMatchers/ASTMatchersInternalTest.cpp | 35 ++++++++++++++ 3 files changed, 61 insertions(+), 21 deletions(-) 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")))); _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
