Author: Paul Kirth Date: 2026-02-19T23:54:19Z New Revision: 64e1318c55b94c1c99a80fdf1424367a80a2e9d5
URL: https://github.com/llvm/llvm-project/commit/64e1318c55b94c1c99a80fdf1424367a80a2e9d5 DIFF: https://github.com/llvm/llvm-project/commit/64e1318c55b94c1c99a80fdf1424367a80a2e9d5.diff LOG: [clang] 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. Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/ASTMatchers/ASTMatchFinder.cpp clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b2302cbdb3f54..8d5d704c1766a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -396,6 +396,7 @@ Fixed Point Support in Clang AST Matchers ------------ - Add ``functionTypeLoc`` matcher for matching ``FunctionTypeLoc``. +- 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")))); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
