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

Reply via email to