[llvm-branch-commits] [clang] release/22.x: [clang] Add missing support for traversal kind in addMatcher overloads (#170953) (PR #184039)

Victor Chernyakin via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Mar 1 12:55:29 PST 2026


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 <paulkirth at google.com>
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"))));



More information about the llvm-branch-commits mailing list