https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/168533
>From 127112f8cd46ebc7b2365b4390e1e26767d4e3b7 Mon Sep 17 00:00:00 2001 From: Michael Buch <[email protected]> Date: Fri, 14 Nov 2025 16:28:19 +0000 Subject: [PATCH] [clang][TypePrinter] Add AnonymousTagMode::CanonicalName --- clang/include/clang/AST/Decl.h | 5 ++-- clang/include/clang/AST/PrettyPrinter.h | 6 +++-- clang/lib/AST/Decl.cpp | 27 ++++++++++++++++--- clang/lib/AST/TypePrinter.cpp | 12 ++++++--- clang/lib/CodeGen/CGDebugInfo.cpp | 4 +++ .../test/DebugInfo/CXX/prefix-map-lambda.cpp | 10 ------- .../DebugInfo/CXX/simple-template-names.cpp | 12 ++++----- .../Generic/Inputs/debug-info-slash.cpp | 2 -- .../Generic/Inputs/debug-info-slash.h | 6 ----- .../DebugInfo/Generic/debug-prefix-map.cpp | 11 -------- clang/test/DebugInfo/Generic/slash.test | 10 ------- 11 files changed, 49 insertions(+), 56 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..c57584c021e69 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>; @@ -5006,7 +5008,10 @@ void TagDecl::printAnonymousTagDecl(llvm::raw_ostream &OS, // (anonymous enum at /usr/include/string.h:120:9) OS << (Policy.MSVCFormatting ? '`' : '('); - if (isa<CXXRecordDecl>(this) && cast<CXXRecordDecl>(this)->isLambda()) { + const CXXRecordDecl *CXX = dyn_cast<CXXRecordDecl>(this); + const bool IsLambda = CXX && CXX->isLambda(); + + if (IsLambda) { OS << "lambda"; SuppressTagKeywordInName = true; } else if ((isa<RecordDecl>(this) && @@ -5016,6 +5021,20 @@ void TagDecl::printAnonymousTagDecl(llvm::raw_ostream &OS, OS << "unnamed"; } + if (Policy.AnonymousTagNameStyle == + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::CanonicalName)) { + if (IsLambda) { + OS << CXX->getLambdaManglingNumber(); + OS << '('; + if (const auto *Op = CXX->getLambdaCallOperator()) + for (const auto &Param : Op->parameters()) + Param->print(OS, Policy); + OS << ')'; + } else { + 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 401d8bc16d290..a680bb9731b1b 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..24b024920faa0 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()::(lambda0())>", f1<t1<t1<decltype(Lambda)>>>(); - // CHECK: !DISubprogram(name: "f1<t1<t1<(lambda at {{.*}}> > >", + // CHECK: !DISubprogram(name: "f1<t1<t1<f()::(lambda0())> > >", 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
