https://github.com/ilovepi created 
https://github.com/llvm/llvm-project/pull/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.

>From e63525d4f71ba361031f501ec84b3bacafb29889 Mon Sep 17 00:00:00 2001
From: Paul Kirth <[email protected]>
Date: Fri, 5 Dec 2025 13:56:44 -0800
Subject: [PATCH] [clang] Add missing support for traversal kind in addMatcher
 overloads

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.
---
 clang/lib/ASTMatchers/ASTMatchFinder.cpp      | 57 ++++++++++++++++---
 .../ASTMatchers/ASTMatchersInternalTest.cpp   | 35 ++++++++++++
 2 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp 
b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index e8a0004c2e187..81fb881302af5 100644
--- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -1681,7 +1681,13 @@ void MatchFinder::addMatcher(const DeclarationMatcher 
&NodeMatch,
 
 void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,
                              MatchCallback *Action) {
-  Matchers.Type.emplace_back(NodeMatch, Action);
+  std::optional<TraversalKind> TK;
+  if (Action)
+    TK = Action->getCheckTraversalKind();
+  if (TK)
+    Matchers.Type.emplace_back(traverse(*TK, NodeMatch), Action);
+  else
+    Matchers.Type.emplace_back(NodeMatch, Action);
   Matchers.AllCallbacks.insert(Action);
 }
 
@@ -1699,37 +1705,74 @@ void MatchFinder::addMatcher(const StatementMatcher 
&NodeMatch,
 
 void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
                              MatchCallback *Action) {
-  Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action);
+  std::optional<TraversalKind> TK;
+  if (Action)
+    TK = Action->getCheckTraversalKind();
+  if (TK)
+    Matchers.NestedNameSpecifier.emplace_back(traverse(*TK, NodeMatch), 
Action);
+  else
+    Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action);
   Matchers.AllCallbacks.insert(Action);
 }
 
 void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
                              MatchCallback *Action) {
-  Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action);
+  std::optional<TraversalKind> TK;
+  if (Action)
+    TK = Action->getCheckTraversalKind();
+  if (TK)
+    Matchers.NestedNameSpecifierLoc.emplace_back(traverse(*TK, NodeMatch),
+                                                 Action);
+  else
+    Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action);
   Matchers.AllCallbacks.insert(Action);
 }
 
 void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch,
                              MatchCallback *Action) {
-  Matchers.TypeLoc.emplace_back(NodeMatch, Action);
+  std::optional<TraversalKind> TK;
+  if (Action)
+    TK = Action->getCheckTraversalKind();
+  if (TK)
+    Matchers.TypeLoc.emplace_back(traverse(*TK, NodeMatch), Action);
+  else
+    Matchers.TypeLoc.emplace_back(NodeMatch, Action);
   Matchers.AllCallbacks.insert(Action);
 }
 
 void MatchFinder::addMatcher(const CXXCtorInitializerMatcher &NodeMatch,
                              MatchCallback *Action) {
-  Matchers.CtorInit.emplace_back(NodeMatch, Action);
+  std::optional<TraversalKind> TK;
+  if (Action)
+    TK = Action->getCheckTraversalKind();
+  if (TK)
+    Matchers.CtorInit.emplace_back(traverse(*TK, NodeMatch), Action);
+  else
+    Matchers.CtorInit.emplace_back(NodeMatch, Action);
   Matchers.AllCallbacks.insert(Action);
 }
 
 void MatchFinder::addMatcher(const TemplateArgumentLocMatcher &NodeMatch,
                              MatchCallback *Action) {
-  Matchers.TemplateArgumentLoc.emplace_back(NodeMatch, Action);
+  std::optional<TraversalKind> TK;
+  if (Action)
+    TK = Action->getCheckTraversalKind();
+  if (TK)
+    Matchers.TemplateArgumentLoc.emplace_back(traverse(*TK, NodeMatch), 
Action);
+  else
+    Matchers.TemplateArgumentLoc.emplace_back(NodeMatch, Action);
   Matchers.AllCallbacks.insert(Action);
 }
 
 void MatchFinder::addMatcher(const AttrMatcher &AttrMatch,
                              MatchCallback *Action) {
-  Matchers.Attr.emplace_back(AttrMatch, Action);
+  std::optional<TraversalKind> TK;
+  if (Action)
+    TK = Action->getCheckTraversalKind();
+  if (TK)
+    Matchers.Attr.emplace_back(traverse(*TK, AttrMatch), Action);
+  else
+    Matchers.Attr.emplace_back(AttrMatch, 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