https://github.com/cor3ntin created 
https://github.com/llvm/llvm-project/pull/218425

Use a `TraverseQualifier` bool like we do for type, instead of doing the 
decomposition ad-hoc in call sites.

This is (yet another PR) in preparation for P3670

Assisted-By: Opus 5

>From 27d178abebd9a889cae7b1e2507ec3c99958757c Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Mon, 24 Aug 2026 16:07:37 +0200
Subject: [PATCH] [clang][NFC] Improve TemplateName traversal in
 RecursiveASTVisitor.

Use a "TraverseQualifier" bool like we do for type, instead
of doing the decomposition ad-hoc in call sites.

This is (yet another PR) in preparation for P3670
---
 clang-tools-extra/clangd/DumpAST.cpp          |  8 ++--
 .../clang/AST/DynamicRecursiveASTVisitor.h    |  3 +-
 clang/include/clang/AST/RecursiveASTVisitor.h | 39 +++++++------------
 clang/lib/AST/DynamicRecursiveASTVisitor.cpp  | 14 +++++--
 clang/lib/Sema/SemaConcept.cpp                |  5 ++-
 clang/lib/Sema/SemaTemplate.cpp               |  5 ++-
 clang/lib/Sema/SemaTemplateDeduction.cpp      |  6 ++-
 clang/lib/Sema/SemaTemplateVariadic.cpp       |  6 ++-
 8 files changed, 45 insertions(+), 41 deletions(-)

diff --git a/clang-tools-extra/clangd/DumpAST.cpp 
b/clang-tools-extra/clangd/DumpAST.cpp
index 2bcbbc09d90fe..c3c35c51cf1ea 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -346,9 +346,11 @@ class DumpVisitor : public 
RecursiveASTVisitor<DumpVisitor> {
       Base::TraverseTypeLoc(TL, TraverseQualifier);
     });
   }
-  bool TraverseTemplateName(const TemplateName &TN) {
-    return TN.isNull() || traverseNode("template name", TN,
-                                       [&] { Base::TraverseTemplateName(TN); 
});
+  bool TraverseTemplateName(const TemplateName &TN,
+                            bool TraverseQualifier = true) {
+    return TN.isNull() || traverseNode("template name", TN, [&] {
+             Base::TraverseTemplateName(TN, TraverseQualifier);
+           });
   }
   bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
     return traverseNode("template argument", TAL,
diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h 
b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index 67b87171719e8..78f443128e9ba 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -173,7 +173,8 @@ template <bool IsConst> class 
DynamicRecursiveASTVisitorBase {
   /// appropriate method.
   ///
   /// \returns false if the visitation was terminated early, true otherwise.
-  virtual bool TraverseTemplateName(TemplateName Template);
+  virtual bool TraverseTemplateName(TemplateName Template,
+                                    bool TraverseQualifier = true);
 
   /// Recursively visit a type, by dispatching to
   /// Traverse*Type() based on the argument's getTypeClass() property.
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index 1f7c8d762e1b5..a933662f77273 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -259,7 +259,8 @@ template <typename Derived> class RecursiveASTVisitor {
   /// appropriate method.
   ///
   /// \returns false if the visitation was terminated early, true otherwise.
-  bool TraverseTemplateName(TemplateName Template);
+  bool TraverseTemplateName(TemplateName Template,
+                            bool TraverseQualifier = true);
 
   /// Recursively visit a template argument and dispatch to the
   /// appropriate method for the argument type.
@@ -871,12 +872,14 @@ bool 
RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
 }
 
 template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) 
{
+bool RecursiveASTVisitor<Derived>::TraverseTemplateName(
+    TemplateName Template, bool TraverseQualifier) {
   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
-    TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
+    if (TraverseQualifier)
+      TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
   } else if (QualifiedTemplateName *QTN =
                  Template.getAsQualifiedTemplateName()) {
-    if (QTN->getQualifier()) {
+    if (TraverseQualifier && QTN->getQualifier()) {
       TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
     }
   }
@@ -1209,24 +1212,12 @@ DEF_TRAVERSE_TYPE(DependentNameType, {
 })
 
 DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
-  if (TraverseQualifier) {
-    TRY_TO(TraverseTemplateName(T->getTemplateName()));
-  } else {
-    // FIXME: Try to preserve the rest of the template name.
-    TRY_TO(TraverseTemplateName(TemplateName(
-        T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
-  }
+  TRY_TO(TraverseTemplateName(T->getTemplateName(), TraverseQualifier));
   TRY_TO(TraverseTemplateArguments(T->template_arguments()));
 })
 
 DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
-  if (TraverseQualifier) {
-    TRY_TO(TraverseTemplateName(T->getTemplateName()));
-  } else {
-    // FIXME: Try to preserve the rest of the template name.
-    TRY_TO(TraverseTemplateName(TemplateName(
-        T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
-  }
+  TRY_TO(TraverseTemplateName(T->getTemplateName(), TraverseQualifier));
   TRY_TO(TraverseType(T->getDeducedType()));
 })
 
@@ -1565,10 +1556,8 @@ DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
   if (TraverseQualifier)
     TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
 
-  // FIXME: Try to preserve the rest of the template name.
-  TRY_TO(TraverseTemplateName(
-      TemplateName(TL.getTypePtr()->getTemplateName().getAsTemplateDecl(
-          /*IgnoreDeduced=*/true))));
+  TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName(),
+                              /*TraverseQualifier=*/false));
 
   for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
     TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
@@ -1580,10 +1569,8 @@ DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
     TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
 
   const auto *T = TL.getTypePtr();
-  // FIXME: Try to preserve the rest of the template name.
-  TRY_TO(
-      TraverseTemplateName(TemplateName(T->getTemplateName().getAsTemplateDecl(
-          /*IgnoreDeduced=*/true))));
+  TRY_TO(TraverseTemplateName(T->getTemplateName(),
+                              /*TraverseQualifier=*/false));
 
   TRY_TO(TraverseType(T->getDeducedType()));
 })
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp 
b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index dde18aba4fcf7..4e802541d31bc 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -135,8 +135,9 @@ template <bool Const> struct Impl : 
RecursiveASTVisitor<Impl<Const>> {
     return Visitor.TraverseTemplateArgumentLoc(ArgLoc);
   }
 
-  bool TraverseTemplateName(TemplateName Template) {
-    return Visitor.TraverseTemplateName(Template);
+  bool TraverseTemplateName(TemplateName Template,
+                            bool TraverseQualifier = true) {
+    return Visitor.TraverseTemplateName(Template, TraverseQualifier);
   }
 
   bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc) {
@@ -325,9 +326,16 @@ FORWARD_TO_BASE_EXACT(TraverseDeclarationNameInfo, 
DeclarationNameInfo)
 FORWARD_TO_BASE_EXACT(TraverseTemplateArgument, const TemplateArgument &)
 FORWARD_TO_BASE_EXACT(TraverseTemplateArguments, ArrayRef<TemplateArgument>)
 FORWARD_TO_BASE_EXACT(TraverseTemplateArgumentLoc, const TemplateArgumentLoc &)
-FORWARD_TO_BASE_EXACT(TraverseTemplateName, TemplateName)
 FORWARD_TO_BASE_EXACT(TraverseNestedNameSpecifier, NestedNameSpecifier)
 
+template <bool Const>
+bool DynamicRecursiveASTVisitorBase<Const>::TraverseTemplateName(
+    TemplateName Template, bool TraverseQualifier) {
+  return Impl<Const>(*this)
+      .RecursiveASTVisitor<Impl<Const>>::TraverseTemplateName(
+          Template, TraverseQualifier);
+}
+
 template <bool Const>
 bool DynamicRecursiveASTVisitorBase<Const>::TraverseType(
     QualType T, bool TraverseQualifier) {
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 514df9c754482..def80e274e10c 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -475,7 +475,8 @@ class HashParameterMapping : public 
RecursiveASTVisitor<HashParameterMapping> {
     return inherited::TraverseStmt(E->getReplacement());
   }
 
-  bool TraverseTemplateName(TemplateName Template) {
+  bool TraverseTemplateName(TemplateName Template,
+                            bool TraverseQualifier = true) {
     if (auto *TTP = dyn_cast_if_present<TemplateTemplateParmDecl>(
             Template.getAsTemplateDecl());
         TTP && TTP->getDepth() < TemplateArgs.getNumLevels()) {
@@ -494,7 +495,7 @@ class HashParameterMapping : public 
RecursiveASTVisitor<HashParameterMapping> {
       UsedTemplateArgs.push_back(
           SemaRef.Context.getCanonicalTemplateArgument(Arg));
     }
-    return inherited::TraverseTemplateName(Template);
+    return inherited::TraverseTemplateName(Template, TraverseQualifier);
   }
 
   void VisitConstraint(const NormalizedConstraintWithParamMapping &Constraint) 
{
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 67289855685db..64a05a8bc34e3 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2775,12 +2775,13 @@ struct DependencyChecker : DynamicRecursiveASTVisitor {
     return IgnoreNonTypeDependent || !Matches(T->getDepth());
   }
 
-  bool TraverseTemplateName(TemplateName N) override {
+  bool TraverseTemplateName(TemplateName N, bool TraverseQualifier) override {
     if (TemplateTemplateParmDecl *PD =
           dyn_cast_or_null<TemplateTemplateParmDecl>(N.getAsTemplateDecl()))
       if (Matches(PD->getDepth()))
         return false;
-    return DynamicRecursiveASTVisitor::TraverseTemplateName(N);
+    return DynamicRecursiveASTVisitor::TraverseTemplateName(N,
+                                                            TraverseQualifier);
   }
 
   bool VisitDeclRefExpr(DeclRefExpr *E) override {
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 54edc6ca046a0..f177f0aa8645e 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -6858,12 +6858,14 @@ struct MarkUsedTemplateParameterVisitor : 
DynamicRecursiveASTVisitor {
     return true;
   }
 
-  bool TraverseTemplateName(TemplateName Template) override {
+  bool TraverseTemplateName(TemplateName Template,
+                            bool TraverseQualifier) override {
     if (auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
             Template.getAsTemplateDecl()))
       if (TTP->getDepth() == Depth)
         Used[TTP->getIndex()] = true;
-    DynamicRecursiveASTVisitor::TraverseTemplateName(Template);
+    DynamicRecursiveASTVisitor::TraverseTemplateName(Template,
+                                                     TraverseQualifier);
     return true;
   }
 
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp 
b/clang/lib/Sema/SemaTemplateVariadic.cpp
index aa818aad7ff68..a53500f2da497 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -143,7 +143,8 @@ class CollectUnexpandedParameterPacksVisitor
     }
 
     /// Record occurrences of template template parameter packs.
-    bool TraverseTemplateName(TemplateName Template) override {
+    bool TraverseTemplateName(TemplateName Template,
+                              bool TraverseQualifier = true) override {
       if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
               Template.getAsTemplateDecl())) {
         if (TTP->isParameterPack())
@@ -155,7 +156,8 @@ class CollectUnexpandedParameterPacksVisitor
           (bool)Template.getAsSubstTemplateTemplateParmPack();
 #endif
 
-      return DynamicRecursiveASTVisitor::TraverseTemplateName(Template);
+      return DynamicRecursiveASTVisitor::TraverseTemplateName(
+          Template, TraverseQualifier);
     }
 
     bool

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to