https://github.com/Michael137 updated 
https://github.com/llvm/llvm-project/pull/168533

>From 744585fc5c9cc79f24683db6ed69a2e96c7e8413 Mon Sep 17 00:00:00 2001
From: Michael Buch <[email protected]>
Date: Mon, 16 Feb 2026 16:23:08 +0000
Subject: [PATCH 1/2] [clang][TypePrinter] Helper to print tag locations

---
 clang/include/clang/AST/Decl.h |  3 +++
 clang/lib/AST/Decl.cpp         | 48 ++++++++++++++++++----------------
 2 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 5c46c912186c4..c3cd74a5b34db 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -3774,6 +3774,9 @@ class TagDecl : public TypeDecl,
   void printAnonymousTagDecl(llvm::raw_ostream &OS,
                              const PrintingPolicy &Policy) const;
 
+  void printAnonymousTagDeclLocation(llvm::raw_ostream &OS,
+                                     const PrintingPolicy &Policy) const;
+
 public:
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 4148e0ce16b7d..37b00eeca539c 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4961,6 +4961,30 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc 
QualifierLoc) {
   }
 }
 
+void TagDecl::printAnonymousTagDeclLocation(
+    llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {
+  PresumedLoc PLoc =
+      getASTContext().getSourceManager().getPresumedLoc(getLocation());
+  if (!PLoc.isValid())
+    return;
+
+  OS << " at ";
+  StringRef File = PLoc.getFilename();
+  llvm::SmallString<1024> WrittenFile(File);
+  if (auto *Callbacks = Policy.Callbacks)
+    WrittenFile = Callbacks->remapPath(File);
+  // Fix inconsistent path separator created by
+  // clang::DirectoryLookup::LookupFile when the file path is relative
+  // path.
+  llvm::sys::path::Style Style =
+      llvm::sys::path::is_absolute(WrittenFile)
+          ? llvm::sys::path::Style::native
+          : (Policy.MSVCFormatting ? llvm::sys::path::Style::windows_backslash
+                                   : llvm::sys::path::Style::posix);
+  llvm::sys::path::native(WrittenFile, Style);
+  OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
+}
+
 void TagDecl::printAnonymousTagDecl(llvm::raw_ostream &OS,
                                     const PrintingPolicy &Policy) const {
   if (TypedefNameDecl *Typedef = getTypedefNameForAnonDecl()) {
@@ -4996,28 +5020,8 @@ void TagDecl::printAnonymousTagDecl(llvm::raw_ostream 
&OS,
     OS << ' ' << getKindName();
 
   if (Policy.AnonymousTagNameStyle ==
-      llvm::to_underlying(PrintingPolicy::AnonymousTagMode::SourceLocation)) {
-    PresumedLoc PLoc =
-        getASTContext().getSourceManager().getPresumedLoc(getLocation());
-    if (PLoc.isValid()) {
-      OS << " at ";
-      StringRef File = PLoc.getFilename();
-      llvm::SmallString<1024> WrittenFile(File);
-      if (auto *Callbacks = Policy.Callbacks)
-        WrittenFile = Callbacks->remapPath(File);
-      // Fix inconsistent path separator created by
-      // clang::DirectoryLookup::LookupFile when the file path is relative
-      // path.
-      llvm::sys::path::Style Style =
-          llvm::sys::path::is_absolute(WrittenFile)
-              ? llvm::sys::path::Style::native
-              : (Policy.MSVCFormatting
-                     ? llvm::sys::path::Style::windows_backslash
-                     : llvm::sys::path::Style::posix);
-      llvm::sys::path::native(WrittenFile, Style);
-      OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
-    }
-  }
+      llvm::to_underlying(PrintingPolicy::AnonymousTagMode::SourceLocation))
+    printAnonymousTagDeclLocation(OS, Policy);
 
   OS << (Policy.MSVCFormatting ? '\'' : ')');
 }

>From 4efbed704d9176e790e1f4eaf2f74691d85915ed Mon Sep 17 00:00:00 2001
From: Michael Buch <[email protected]>
Date: Fri, 14 Nov 2025 16:28:19 +0000
Subject: [PATCH 2/2] [clang][TypePrinter] Add AnonymousTagMode::CanonicalName

---
 clang/include/clang/AST/Decl.h                       |  5 +++--
 clang/include/clang/AST/PrettyPrinter.h              |  6 ++++--
 clang/lib/AST/Decl.cpp                               | 12 +++++++++---
 clang/lib/AST/TypePrinter.cpp                        | 12 +++++++++---
 clang/lib/CodeGen/CGDebugInfo.cpp                    |  4 ++++
 clang/test/DebugInfo/CXX/prefix-map-lambda.cpp       | 10 ----------
 clang/test/DebugInfo/CXX/simple-template-names.cpp   | 12 ++++++------
 .../DebugInfo/Generic/Inputs/debug-info-slash.cpp    |  2 --
 .../test/DebugInfo/Generic/Inputs/debug-info-slash.h |  6 ------
 clang/test/DebugInfo/Generic/debug-prefix-map.cpp    | 11 -----------
 clang/test/DebugInfo/Generic/slash.test              | 10 ----------
 11 files changed, 35 insertions(+), 55 deletions(-)
 delete mode 100644 clang/test/DebugInfo/CXX/prefix-map-lambda.cpp
 delete mode 100644 clang/test/DebugInfo/Generic/Inputs/debug-info-slash.cpp
 delete mode 100644 clang/test/DebugInfo/Generic/Inputs/debug-info-slash.h
 delete mode 100644 clang/test/DebugInfo/Generic/debug-prefix-map.cpp
 delete mode 100644 clang/test/DebugInfo/Generic/slash.test

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index c3cd74a5b34db..4b869d9d2404a 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -357,9 +357,10 @@ class NamedDecl : public Decl {
   /// including the '::' at the end. E.g.
   ///    when `printQualifiedName(D)` prints "A::B::i",
   ///    this function prints "A::B::".
-  void printNestedNameSpecifier(raw_ostream &OS) const;
   void printNestedNameSpecifier(raw_ostream &OS,
-                                const PrintingPolicy &Policy) const;
+                                bool AllowFunctionContext = false) const;
+  void printNestedNameSpecifier(raw_ostream &OS, const PrintingPolicy &Policy,
+                                bool AllowFunctionContext = false) const;
 
   // FIXME: Remove string version.
   std::string getQualifiedNameAsString() const;
diff --git a/clang/include/clang/AST/PrettyPrinter.h 
b/clang/include/clang/AST/PrettyPrinter.h
index a937d020b7277..d849bc7845a98 100644
--- a/clang/include/clang/AST/PrettyPrinter.h
+++ b/clang/include/clang/AST/PrettyPrinter.h
@@ -65,7 +65,9 @@ struct PrintingPolicy {
 
     /// When printing an anonymous tag name, also print the location of that
     /// entity (e.g., "enum <anonymous at t.h:10:5>").
-    SourceLocation
+    SourceLocation,
+
+    CanonicalName,
   };
 
   /// Create a default printing policy for the specified language.
@@ -208,7 +210,7 @@ struct PrintingPolicy {
   unsigned ConstantArraySizeAsWritten : 1;
 
   LLVM_PREFERRED_TYPE(AnonymousTagMode)
-  unsigned AnonymousTagNameStyle : 1;
+  unsigned AnonymousTagNameStyle : 2;
 
   /// When true, suppress printing of the __strong lifetime qualifier in ARC.
   LLVM_PREFERRED_TYPE(bool)
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 37b00eeca539c..f89d619514599 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1711,12 +1711,14 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
   }
 }
 
-void NamedDecl::printNestedNameSpecifier(raw_ostream &OS) const {
+void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
+                                         bool AllowFunctionContext) const {
   printNestedNameSpecifier(OS, getASTContext().getPrintingPolicy());
 }
 
 void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
-                                         const PrintingPolicy &P) const {
+                                         const PrintingPolicy &P,
+                                         bool AllowFunctionContext) const {
   const DeclContext *Ctx = getDeclContext();
 
   // For ObjC methods and properties, look through categories and use the
@@ -1733,7 +1735,7 @@ void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
       Ctx = CI;
   }
 
-  if (Ctx->isFunctionOrMethod())
+  if (Ctx->isFunctionOrMethod() && !AllowFunctionContext)
     return;
 
   using ContextsTy = SmallVector<const DeclContext *, 8>;
@@ -5016,6 +5018,10 @@ void TagDecl::printAnonymousTagDecl(llvm::raw_ostream 
&OS,
     OS << "unnamed";
   }
 
+  if (Policy.AnonymousTagNameStyle ==
+      llvm::to_underlying(PrintingPolicy::AnonymousTagMode::CanonicalName))
+    OS << getASTContext().getManglingNumber(this);
+
   if (!SuppressTagKeywordInName)
     OS << ' ' << getKindName();
 
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index d8a48af62bb75..bcc17a158639b 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1534,20 +1534,26 @@ void TypePrinter::printTagType(const TagType *T, 
raw_ostream &OS) {
     }
   }
 
+  const IdentifierInfo *II = D->getIdentifier();
+  const bool PrintingCanonicalAnonName =
+      !II &&
+      Policy.AnonymousTagNameStyle ==
+          llvm::to_underlying(PrintingPolicy::AnonymousTagMode::CanonicalName);
+
   if (!Policy.FullyQualifiedName && !T->isCanonicalUnqualified()) {
     T->getQualifier().print(OS, Policy);
   } else if (!Policy.SuppressScope) {
     // Compute the full nested-name-specifier for this type.
     // In C, this will always be empty except when the type
     // being printed is anonymous within other Record.
-    D->printNestedNameSpecifier(OS, Policy);
+    D->printNestedNameSpecifier(
+        OS, Policy, /*AllowFunctionContext=*/PrintingCanonicalAnonName);
   }
 
-  if (const IdentifierInfo *II = D->getIdentifier())
+  if (II)
     OS << II->getName();
   else {
     clang::PrintingPolicy Copy(Policy);
-
     // Suppress the redundant tag keyword if we just printed one.
     if (PrintedKindDecoration) {
       Copy.SuppressTagKeywordInAnonNames = true;
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 2b123631c526c..c3e4181e3b74a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/LambdaCapture.h"
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/VTableBuilder.h"
@@ -39,6 +40,7 @@
 #include "clang/Lex/ModuleMap.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Constants.h"
@@ -430,6 +432,8 @@ PrintingPolicy CGDebugInfo::getPrintingPolicy() const {
   PP.UsePreferredNames = false;
   PP.AlwaysIncludeTypeForTemplateArgument = true;
   PP.UseEnumerators = false;
+  PP.AnonymousTagNameStyle =
+      llvm::to_underlying(PrintingPolicy::AnonymousTagMode::CanonicalName);
 
   // Apply -fdebug-prefix-map.
   PP.Callbacks = &PrintCB;
diff --git a/clang/test/DebugInfo/CXX/prefix-map-lambda.cpp 
b/clang/test/DebugInfo/CXX/prefix-map-lambda.cpp
deleted file mode 100644
index f0fb1a312c8be..0000000000000
--- a/clang/test/DebugInfo/CXX/prefix-map-lambda.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple \
-// RUN:   -fdebug-prefix-map=%S=/SOURCE_ROOT %s -emit-llvm -o - | FileCheck %s
-
-template <typename T> void b(T) {}
-void c() {
-  // CHECK: !DISubprogram(name: "b<(lambda at
-  // CHECK-SAME:          SOURCE_ROOT
-  // CHECK-SAME:          [[@LINE+1]]:{{[0-9]+}})>"
-  b([]{});
-}
diff --git a/clang/test/DebugInfo/CXX/simple-template-names.cpp 
b/clang/test/DebugInfo/CXX/simple-template-names.cpp
index a682a087e1406..446d3ced99a26 100644
--- a/clang/test/DebugInfo/CXX/simple-template-names.cpp
+++ b/clang/test/DebugInfo/CXX/simple-template-names.cpp
@@ -70,18 +70,18 @@ void f() {
   // anything other than another unnamed class/struct.
   auto Lambda = [] {};
   f1<decltype(Lambda)>();
-  // CHECK: !DISubprogram(name: "f1<(lambda at 
{{.*}}simple-template-names.cpp:[[# @LINE - 2]]:17)>",
+  // CHECK: !DISubprogram(name: "f1<f()::(lambda1)>",
   f1<t1<t1<decltype(Lambda)>>>();
-  // CHECK: !DISubprogram(name: "f1<t1<t1<(lambda at {{.*}}> > >",
+  // CHECK: !DISubprogram(name: "f1<t1<t1<f()::(lambda1)> > >",
   struct {
   } unnamed_struct;
   f1<decltype(unnamed_struct)>();
-  // CHECK: !DISubprogram(name: "f1<(unnamed struct at 
{{.*}}simple-template-names.cpp:[[# @LINE - 3]]:3)>",
+  // CHECK: !DISubprogram(name: "f1<f()::(unnamed1 struct)>",
   f1<void (decltype(unnamed_struct))>();
-  // CHECK: !DISubprogram(name: "f1<void ((unnamed struct at 
{{.*}}simple-template-names.cpp:[[# @LINE - 5]]:3))>",
+  // CHECK: !DISubprogram(name: "f1<void (f()::(unnamed1 struct))>",
   enum {} unnamed_enum;
   f1<decltype(unnamed_enum)>();
-  // CHECK: !DISubprogram(name: "f1<(unnamed enum at 
{{.*}}simple-template-names.cpp:[[# @LINE - 2]]:3)>",
+  // CHECK: !DISubprogram(name: "f1<f()::(unnamed1 enum)>",
 
   // Declarations can't readily be reversed as the value in the DWARF only
   // contains the address of the value - we'd have to do symbol lookup to find
@@ -145,5 +145,5 @@ void f() {
   // CHECK: !DISubprogram(name: "f1<int () __attribute__((noreturn))>",
   
   f4<UnnamedEnum1>();
-  // CHECK: !DISubprogram(name: "f4<((unnamed enum at {{.*}}))0>"
+  // CHECK: !DISubprogram(name: "f4<((unnamed1 enum))0>"
 }
diff --git a/clang/test/DebugInfo/Generic/Inputs/debug-info-slash.cpp 
b/clang/test/DebugInfo/Generic/Inputs/debug-info-slash.cpp
deleted file mode 100644
index 563077ed342a1..0000000000000
--- a/clang/test/DebugInfo/Generic/Inputs/debug-info-slash.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "Inputs/debug-info-slash.h"
-int main() { a(); return 0; }
diff --git a/clang/test/DebugInfo/Generic/Inputs/debug-info-slash.h 
b/clang/test/DebugInfo/Generic/Inputs/debug-info-slash.h
deleted file mode 100644
index 9092f4a5e8170..0000000000000
--- a/clang/test/DebugInfo/Generic/Inputs/debug-info-slash.h
+++ /dev/null
@@ -1,6 +0,0 @@
-template <typename... T>
-void f1() {}
-void a() {
-  auto Lambda = [] {};
-  f1<decltype(Lambda)>();
-}
diff --git a/clang/test/DebugInfo/Generic/debug-prefix-map.cpp 
b/clang/test/DebugInfo/Generic/debug-prefix-map.cpp
deleted file mode 100644
index 174bef5a07699..0000000000000
--- a/clang/test/DebugInfo/Generic/debug-prefix-map.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: %clang_cc1 -debug-info-kind=standalone 
-fdebug-prefix-map=%p=./UNLIKELY_PATH/empty %s -emit-llvm -o - | FileCheck %s
-
-struct alignas(64) an {
-  struct {
-    unsigned char x{0};
-  } arr[64];
-};
-
-struct an *pan = new an;
-
-// CHECK: !DISubprogram(name: "(unnamed struct at 
./UNLIKELY_PATH/empty{{/|\\\\}}{{.*}}",
diff --git a/clang/test/DebugInfo/Generic/slash.test 
b/clang/test/DebugInfo/Generic/slash.test
deleted file mode 100644
index 0e42912c18d21..0000000000000
--- a/clang/test/DebugInfo/Generic/slash.test
+++ /dev/null
@@ -1,10 +0,0 @@
-RUN: rm -rf %t-dir
-RUN: mkdir -p %t-dir/header/Inputs
-RUN: cp %S/Inputs/debug-info-slash.cpp %t-dir/
-RUN: cp %S/Inputs/debug-info-slash.h %t-dir/header/Inputs
-RUN: cd %t-dir
-RUN: %clang -target x86_64-pc-win32 -emit-llvm -S -g  
%t-dir/debug-info-slash.cpp -Iheader -o - | FileCheck --check-prefix=WIN %s
-RUN: %clang -target x86_64-linux-gnu -emit-llvm -S -g  
%t-dir/debug-info-slash.cpp -Iheader -o - | FileCheck --check-prefix=LINUX %s
-
-WIN:   lambda at header\\Inputs\\debug-info-slash.h
-LINUX: lambda at header/Inputs/debug-info-slash.h

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

Reply via email to