https://github.com/mygitljf updated 
https://github.com/llvm/llvm-project/pull/206041

>From f34d7896cebb2a33c7f68397ba8dd6c38a5b492c Mon Sep 17 00:00:00 2001
From: mygitljf <[email protected]>
Date: Fri, 26 Jun 2026 19:42:36 +0000
Subject: [PATCH 1/2] [clang][AST] Qualify DeclRefExpr printing

---
 clang/lib/AST/StmtPrinter.cpp           | 73 ++++++++++++++-----------
 clang/unittests/AST/StmtPrinterTest.cpp | 43 +++++++++++++++
 clang/unittests/AST/TypePrinterTest.cpp | 24 ++++++++
 3 files changed, 107 insertions(+), 33 deletions(-)

diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 6c3294573e9d4..e4dc41cf2c043 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1330,42 +1330,49 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
     TPOD->printAsExpr(OS, Policy);
     return;
   }
-  Node->getQualifier().print(OS, Policy);
-  if (Node->hasTemplateKeyword())
-    OS << "template ";
-
   bool ForceAnonymous =
       Policy.PrintAsCanonical && VD->getKind() == Decl::NonTypeTemplateParm;
-  DeclarationNameInfo NameInfo = Node->getNameInfo();
-  if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo();
-      !ForceAnonymous &&
-      (ID || NameInfo.getName().getNameKind() != DeclarationName::Identifier)) 
{
-    if (Policy.CleanUglifiedParameters &&
-        isa<ParmVarDecl, NonTypeTemplateParmDecl>(VD) && ID)
-      OS << ID->deuglifiedName();
-    else
-      NameInfo.printName(OS, Policy);
+  bool CleanUglifiedParameter = Policy.CleanUglifiedParameters &&
+                                isa<ParmVarDecl, NonTypeTemplateParmDecl>(VD);
+
+  if (Policy.FullyQualifiedName && !ForceAnonymous && !CleanUglifiedParameter) 
{
+    VD->printQualifiedName(OS, Policy);
   } else {
-    switch (VD->getKind()) {
-    case Decl::NonTypeTemplateParm: {
-      auto *TD = cast<NonTypeTemplateParmDecl>(VD);
-      OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex() << 
"";
-      break;
-    }
-    case Decl::ParmVar: {
-      auto *PD = cast<ParmVarDecl>(VD);
-      OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-'
-         << PD->getFunctionScopeIndex();
-      break;
-    }
-    case Decl::Decomposition:
-      OS << "decomposition";
-      for (const auto &I : cast<DecompositionDecl>(VD)->bindings())
-        OS << '-' << I->getName();
-      break;
-    default:
-      OS << "unhandled-anonymous-" << VD->getDeclKindName();
-      break;
+    Node->getQualifier().print(OS, Policy);
+    if (Node->hasTemplateKeyword())
+      OS << "template ";
+
+    DeclarationNameInfo NameInfo = Node->getNameInfo();
+    if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo();
+        !ForceAnonymous && (ID || NameInfo.getName().getNameKind() !=
+                                      DeclarationName::Identifier)) {
+      if (CleanUglifiedParameter && ID)
+        OS << ID->deuglifiedName();
+      else
+        NameInfo.printName(OS, Policy);
+    } else {
+      switch (VD->getKind()) {
+      case Decl::NonTypeTemplateParm: {
+        auto *TD = cast<NonTypeTemplateParmDecl>(VD);
+        OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex()
+           << "";
+        break;
+      }
+      case Decl::ParmVar: {
+        auto *PD = cast<ParmVarDecl>(VD);
+        OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-'
+           << PD->getFunctionScopeIndex();
+        break;
+      }
+      case Decl::Decomposition:
+        OS << "decomposition";
+        for (const auto &I : cast<DecompositionDecl>(VD)->bindings())
+          OS << '-' << I->getName();
+        break;
+      default:
+        OS << "unhandled-anonymous-" << VD->getDeclKindName();
+        break;
+      }
     }
   }
   if (Node->hasExplicitTemplateArgs()) {
diff --git a/clang/unittests/AST/StmtPrinterTest.cpp 
b/clang/unittests/AST/StmtPrinterTest.cpp
index 24ad5f30d9480..2b75253fa6698 100644
--- a/clang/unittests/AST/StmtPrinterTest.cpp
+++ b/clang/unittests/AST/StmtPrinterTest.cpp
@@ -297,6 +297,42 @@ TEST(StmtPrinter, TerseOutputWithLambdas) {
       [](PrintingPolicy &PP) { PP.TerseOutput = true; }));
 }
 
+TEST(StmtPrinter, FullyQualifiedDeclRefExpr) {
+  auto FullyQualified = [](PrintingPolicy &Policy) {
+    Policy.FullyQualifiedName = true;
+  };
+
+  ASSERT_TRUE(PrintedStmtCXXMatches(
+      StdVer::CXX17,
+      R"cpp(
+        namespace ns { int value; }
+        using namespace ns;
+        void A() { (void)value; }
+      )cpp",
+      declRefExpr(to(varDecl(hasName("::ns::value")))).bind("id"), "ns::value",
+      FullyQualified));
+
+  ASSERT_TRUE(PrintedStmtCXXMatches(
+      StdVer::CXX17,
+      R"cpp(
+        namespace ns { template <class T> void func(); }
+        using namespace ns;
+        void A() { func<int>(); }
+      )cpp",
+      declRefExpr(to(functionDecl(hasName("::ns::func")))).bind("id"),
+      "ns::func<int>", FullyQualified));
+
+  ASSERT_TRUE(PrintedStmtCXXMatches(
+      StdVer::CXX17, "void A(int param) { (void)param; }",
+      declRefExpr(to(parmVarDecl(hasName("param")))).bind("id"), "param",
+      FullyQualified));
+
+  ASSERT_TRUE(PrintedStmtCXXMatches(
+      StdVer::CXX17, "void A() { int local = 0; (void)local; }",
+      declRefExpr(to(varDecl(hasName("local")))).bind("id"), "local",
+      FullyQualified));
+}
+
 TEST(StmtPrinter, ParamsUglified) {
   llvm::StringLiteral Code = R"cpp(
     template <typename _T, int _I, template <typename> class _C>
@@ -307,6 +343,10 @@ TEST(StmtPrinter, ParamsUglified) {
   auto Clean = [](PrintingPolicy &Policy) {
     Policy.CleanUglifiedParameters = true;
   };
+  auto CleanFullyQualified = [](PrintingPolicy &Policy) {
+    Policy.CleanUglifiedParameters = true;
+    Policy.FullyQualifiedName = true;
+  };
 
   ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX14, Code,
                                     returnStmt().bind("id"),
@@ -314,4 +354,7 @@ TEST(StmtPrinter, ParamsUglified) {
   ASSERT_TRUE(
       PrintedStmtCXXMatches(StdVer::CXX14, Code, returnStmt().bind("id"),
                             "return typename C<T>::_F(I, j);\n", Clean));
+  ASSERT_TRUE(PrintedStmtCXXMatches(
+      StdVer::CXX14, Code, returnStmt().bind("id"),
+      "return typename _C<T>::_F(I, j);\n", CleanFullyQualified));
 }
diff --git a/clang/unittests/AST/TypePrinterTest.cpp 
b/clang/unittests/AST/TypePrinterTest.cpp
index 5023b5e093ec3..79f75909c57b5 100644
--- a/clang/unittests/AST/TypePrinterTest.cpp
+++ b/clang/unittests/AST/TypePrinterTest.cpp
@@ -121,6 +121,30 @@ TEST(TypePrinter, TemplateSpecializationFullyQualified) {
       [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; }));
 }
 
+TEST(TypePrinter, TemplateArgumentExpressionFullyQualified) {
+  llvm::StringLiteral Code = R"cpp(
+    namespace ns {
+      template <class T> inline constexpr bool pred_v = sizeof(T) > 0;
+      template <bool, class T> struct ei {};
+      template <class T> struct ei<true, T> { using type = T; };
+      template <bool B, class T> using enable_if_t = typename ei<B, T>::type;
+      struct Ret {};
+      template <class T> enable_if_t<pred_v<T>, Ret> f() { return {}; }
+    }
+    inline auto *ns_f_int = &ns::f<int>;
+  )cpp";
+
+  auto Matcher = functionDecl(hasName("::ns::f"), isTemplateInstantiation(),
+                              returns(qualType().bind("id")));
+  ASSERT_TRUE(PrintedTypeMatches(
+      Code, {"-std=c++17"}, Matcher, "enable_if_t<pred_v<int>, Ret>",
+      [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = false; }));
+  ASSERT_TRUE(PrintedTypeMatches(
+      Code, {"-std=c++17"}, Matcher,
+      "ns::enable_if_t<ns::pred_v<int>, ns::Ret>",
+      [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; }));
+}
+
 TEST(TypePrinter, TemplateIdWithNTTP) {
   constexpr char Code[] = R"cpp(
     template <int N>

>From 8a84ede955841c8605f580bd975ddef369beb3b1 Mon Sep 17 00:00:00 2001
From: mygitljf <[email protected]>
Date: Sat, 27 Jun 2026 10:35:22 +0000
Subject: [PATCH 2/2] [clang][docs] Add AST printer release note

---
 clang/docs/ReleaseNotes.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d1303d4c98507..f8e307a4510cc 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -125,6 +125,10 @@ AST Dumping Potentially Breaking Changes
   fields were missing from the JSON output.
 - Colons that appear at the end of a ParamCommentCommand name are not 
serialized
   as part of the name.
+- AST pretty-printing now respects ``PrintingPolicy::FullyQualifiedName`` when
+  printing ``DeclRefExpr`` names, including expression-form non-type template
+  arguments in printed types. Previously, these references could be printed
+  unqualified. (#GH206041)
 
 Clang Frontend Potentially Breaking Changes
 -------------------------------------------

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

Reply via email to