https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/168533
>From 2b86000b9596dd9eabecde5684a2e175903f50f2 Mon Sep 17 00:00:00 2001 From: Michael Buch <[email protected]> Date: Mon, 16 Feb 2026 16:09:27 +0000 Subject: [PATCH 1/3] [clang][TypePrinter] Introduce AnonymousTagMode enum --- clang/include/clang/AST/PrettyPrinter.h | 21 ++++++++++++------- clang/lib/AST/Decl.cpp | 7 +++++-- clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 3 ++- clang/lib/ExtractAPI/ExtractAPIConsumer.cpp | 6 ++++-- clang/lib/Index/USRGeneration.cpp | 3 ++- clang/lib/Interpreter/InterpreterUtils.cpp | 3 ++- clang/lib/Sema/SemaChecking.cpp | 3 ++- clang/lib/Sema/SemaCodeComplete.cpp | 3 ++- clang/lib/Tooling/ASTDiff/ASTDiff.cpp | 3 ++- clang/tools/libclang/CIndex.cpp | 11 ++++++++-- clang/unittests/AST/TypePrinterTest.cpp | 15 ++++++++----- clang/unittests/Tooling/QualTypeNamesTest.cpp | 3 ++- 12 files changed, 56 insertions(+), 25 deletions(-) diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h index 1564204833e64..b6cd8ee70188d 100644 --- a/clang/include/clang/AST/PrettyPrinter.h +++ b/clang/include/clang/AST/PrettyPrinter.h @@ -58,6 +58,15 @@ class PrintingCallbacks { struct PrintingPolicy { enum class SuppressInlineNamespaceMode : uint8_t { None, Redundant, All }; + enum class AnonymousTagMode : uint8_t { + None, + + /// When printing an anonymous tag name, also print the location of that + /// entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just prints + /// "(anonymous)" for the name. + SourceLocation + }; + /// Create a default printing policy for the specified language. PrintingPolicy(const LangOptions &LO) : Indentation(2), SuppressSpecifiers(false), @@ -67,8 +76,9 @@ struct PrintingPolicy { SuppressInlineNamespace( llvm::to_underlying(SuppressInlineNamespaceMode::Redundant)), SuppressInitializers(false), ConstantArraySizeAsWritten(false), - AnonymousTagLocations(true), SuppressStrongLifetime(false), - SuppressLifetimeQualifiers(false), + AnonymousTagNameStyle( + llvm::to_underlying(AnonymousTagMode::SourceLocation)), + SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false), SuppressTemplateArgsInCXXConstructors(false), SuppressDefaultTemplateArgs(true), Bool(LO.Bool), Nullptr(LO.CPlusPlus11 || LO.C23), NullptrTypeInNamespace(LO.CPlusPlus), @@ -196,11 +206,8 @@ struct PrintingPolicy { LLVM_PREFERRED_TYPE(bool) unsigned ConstantArraySizeAsWritten : 1; - /// When printing an anonymous tag name, also print the location of that - /// entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just prints - /// "(anonymous)" for the name. - LLVM_PREFERRED_TYPE(bool) - unsigned AnonymousTagLocations : 1; + LLVM_PREFERRED_TYPE(AnonymousTagMode) + unsigned AnonymousTagNameStyle : 1; /// 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 66c625f41158a..d7d61e7e29a6f 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1800,7 +1800,8 @@ void NamedDecl::printNestedNameSpecifier(raw_ostream &OS, // suppress tag in name Copy.SuppressTagKeyword = true; Copy.SuppressTagKeywordInAnonNames = false; - Copy.AnonymousTagLocations = false; + Copy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); RD->printName(OS, Copy); } else if (const auto *FD = dyn_cast<FunctionDecl>(DC)) { const FunctionProtoType *FT = nullptr; @@ -4994,7 +4995,9 @@ void TagDecl::printAnonymousTagDecl(llvm::raw_ostream &OS, if (!SuppressTagKeywordInName) OS << ' ' << getKindName(); - if (Policy.AnonymousTagLocations) { + if (Policy.AnonymousTagNameStyle == + llvm::to_underlying( + PrintingPolicy::AnonymousTagMode::SourceLocation)) { PresumedLoc PLoc = getASTContext().getSourceManager().getPresumedLoc(getLocation()); if (PLoc.isValid()) { diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 5b84a33c86821..4aa3e34b3bc65 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -518,7 +518,8 @@ static StringRef getNodeName(const RecordDecl &Node, llvm::raw_svector_ostream OS(Scratch); PrintingPolicy Copy(Node.getASTContext().getPrintingPolicy()); - Copy.AnonymousTagLocations = false; + Copy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); Node.printName(OS, Copy); return OS.str(); diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index 6966d4097d64a..efe4e78afc304 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -419,7 +419,8 @@ ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { // Do not include location in anonymous decls. PrintingPolicy Policy = CI.getASTContext().getPrintingPolicy(); - Policy.AnonymousTagLocations = false; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); CI.getASTContext().setPrintingPolicy(Policy); if (!CI.getFrontendOpts().ExtractAPIIgnoresFileList.empty()) { @@ -522,7 +523,8 @@ WrappingExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, // Do not include location in anonymous decls. PrintingPolicy Policy = CI.getASTContext().getPrintingPolicy(); - Policy.AnonymousTagLocations = false; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); CI.getASTContext().setPrintingPolicy(Policy); if (!CI.getFrontendOpts().ExtractAPIIgnoresFileList.empty()) { diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp index 08835ea786997..1aeecad9bbd65 100644 --- a/clang/lib/Index/USRGeneration.cpp +++ b/clang/lib/Index/USRGeneration.cpp @@ -659,7 +659,8 @@ static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts, PO.SuppressTagKeyword = true; PO.SuppressUnwrittenScope = true; PO.ConstantArraySizeAsWritten = false; - PO.AnonymousTagLocations = false; + PO.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); NNS.print(Out, PO); } diff --git a/clang/lib/Interpreter/InterpreterUtils.cpp b/clang/lib/Interpreter/InterpreterUtils.cpp index a19f96c80b94f..ec80f891a060c 100644 --- a/clang/lib/Interpreter/InterpreterUtils.cpp +++ b/clang/lib/Interpreter/InterpreterUtils.cpp @@ -107,7 +107,8 @@ std::string GetFullTypeName(ASTContext &Ctx, QualType QT) { QualType FQT = TypeName::getFullyQualifiedType(QT, Ctx); PrintingPolicy Policy(Ctx.getPrintingPolicy()); Policy.SuppressScope = false; - Policy.AnonymousTagLocations = false; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); return FQT.getAsString(Policy); } } // namespace clang diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 45006bfc11644..f48d272206930 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -493,7 +493,8 @@ struct BuiltinDumpStructGenerator { BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall) : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()), Policy(S.Context.getPrintingPolicy()) { - Policy.AnonymousTagLocations = false; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); } Expr *makeOpaqueValueExpr(Expr *Inner) { diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 4a3559955ade3..d67b26c81bb09 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2043,7 +2043,8 @@ static bool WantTypesInContext(SemaCodeCompletion::ParserCompletionContext CCC, static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context, const Preprocessor &PP) { PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP); - Policy.AnonymousTagLocations = false; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); Policy.SuppressStrongLifetime = true; Policy.SuppressUnwrittenScope = true; Policy.CleanUglifiedParameters = true; diff --git a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp index d70a679cc8dd0..9481e5fcf15a2 100644 --- a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp +++ b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp @@ -260,7 +260,8 @@ struct PreorderVisitor : public RecursiveASTVisitor<PreorderVisitor> { SyntaxTree::Impl::Impl(SyntaxTree *Parent, ASTContext &AST) : Parent(Parent), AST(AST), TypePP(AST.getLangOpts()) { - TypePP.AnonymousTagLocations = false; + TypePP.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); } SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, ASTContext &AST) diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 15eec87652451..4c83f4ede59b0 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -5659,7 +5659,9 @@ clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy, case CXPrintingPolicy_ConstantArraySizeAsWritten: return P->ConstantArraySizeAsWritten; case CXPrintingPolicy_AnonymousTagLocations: - return P->AnonymousTagLocations; + return P->AnonymousTagNameStyle == + llvm::to_underlying( + PrintingPolicy::AnonymousTagMode::SourceLocation); case CXPrintingPolicy_SuppressStrongLifetime: return P->SuppressStrongLifetime; case CXPrintingPolicy_SuppressLifetimeQualifiers: @@ -5733,7 +5735,12 @@ void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, P->ConstantArraySizeAsWritten = Value; return; case CXPrintingPolicy_AnonymousTagLocations: - P->AnonymousTagLocations = Value; + if (Value) + P->AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::SourceLocation); + else + P->AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); return; case CXPrintingPolicy_SuppressStrongLifetime: P->SuppressStrongLifetime = Value; diff --git a/clang/unittests/AST/TypePrinterTest.cpp b/clang/unittests/AST/TypePrinterTest.cpp index de4cfa4074eba..e2f2c9e4fec70 100644 --- a/clang/unittests/AST/TypePrinterTest.cpp +++ b/clang/unittests/AST/TypePrinterTest.cpp @@ -315,14 +315,16 @@ TEST(TypePrinter, NestedNameSpecifiers) { Code, {}, varDecl(hasName("imem"), hasType(qualType().bind("id"))), "struct (unnamed)", [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; - Policy.AnonymousTagLocations = false; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); })); ASSERT_TRUE(PrintedTypeMatches( Code, {}, varDecl(hasName("imem"), hasType(qualType().bind("id"))), "struct (unnamed)", [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = false; - Policy.AnonymousTagLocations = false; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); })); // Further levels of nesting print the entire scope. @@ -331,14 +333,16 @@ TEST(TypePrinter, NestedNameSpecifiers) { "union level1()::Inner::Inner(int)::(unnamed struct)::(unnamed)", [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; - Policy.AnonymousTagLocations = false; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); })); ASSERT_TRUE(PrintedTypeMatches( Code, {}, fieldDecl(hasName("u"), hasType(qualType().bind("id"))), "union (unnamed)", [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = false; - Policy.AnonymousTagLocations = false; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); })); } @@ -357,6 +361,7 @@ TEST(TypePrinter, NestedNameSpecifiersTypedef) { Code, {}, fieldDecl(hasName("bar"), hasType(qualType().bind("id"))), "struct foo::(anonymous struct)::(unnamed)", [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; - Policy.AnonymousTagLocations = false; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::None); })); } diff --git a/clang/unittests/Tooling/QualTypeNamesTest.cpp b/clang/unittests/Tooling/QualTypeNamesTest.cpp index 3dfc94a9d27de..cb83d6e86cb23 100644 --- a/clang/unittests/Tooling/QualTypeNamesTest.cpp +++ b/clang/unittests/Tooling/QualTypeNamesTest.cpp @@ -22,7 +22,8 @@ struct TypeNameVisitor : TestVisitor { if (ExpectedName != "") { PrintingPolicy Policy(Context->getPrintingPolicy()); Policy.SuppressScope = false; - Policy.AnonymousTagLocations = true; + Policy.AnonymousTagNameStyle = + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::SourceLocation); Policy.PolishForDeclaration = true; Policy.SuppressUnwrittenScope = true; std::string ActualName = TypeName::getFullyQualifiedName( >From 47dcc4148f6786c46d89a77aa37d68df09241847 Mon Sep 17 00:00:00 2001 From: Michael Buch <[email protected]> Date: Mon, 16 Feb 2026 16:23:08 +0000 Subject: [PATCH 2/3] [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 d7d61e7e29a6f..8109dfb381458 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()) { @@ -4997,28 +5021,8 @@ void TagDecl::printAnonymousTagDecl(llvm::raw_ostream &OS, 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(); - } - } + PrintingPolicy::AnonymousTagMode::SourceLocation)) + printAnonymousTagDeclLocation(OS, Policy); OS << (Policy.MSVCFormatting ? '\'' : ')'); } >From b7a6e972d73af03c900021eb147970ab0e85f60b Mon Sep 17 00:00:00 2001 From: Michael Buch <[email protected]> Date: Fri, 14 Nov 2025 16:28:19 +0000 Subject: [PATCH 3/3] [clang][TypePrinter] Add AnonymousTagMode::CanonicalName --- clang/include/clang/AST/Decl.h | 5 +++-- clang/include/clang/AST/PrettyPrinter.h | 6 ++++-- clang/lib/AST/Decl.cpp | 15 ++++++++++----- clang/lib/AST/TypePrinter.cpp | 12 +++++++++--- clang/lib/CodeGen/CGDebugInfo.cpp | 4 ++++ clang/test/DebugInfo/CXX/prefix-map-lambda.cpp | 10 ---------- .../test/DebugInfo/CXX/simple-template-names.cpp | 12 ++++++------ .../DebugInfo/Generic/Inputs/debug-info-slash.cpp | 2 -- .../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, 36 insertions(+), 57 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 b6cd8ee70188d..dd878b450c807 100644 --- a/clang/include/clang/AST/PrettyPrinter.h +++ b/clang/include/clang/AST/PrettyPrinter.h @@ -64,7 +64,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>"). Otherwise, just prints /// "(anonymous)" for the name. - SourceLocation + SourceLocation, + + CanonicalName, }; /// Create a default printing policy for the specified language. @@ -207,7 +209,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 8109dfb381458..5ae702fa6814e 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,12 +5018,15 @@ 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(); if (Policy.AnonymousTagNameStyle == - llvm::to_underlying( - PrintingPolicy::AnonymousTagMode::SourceLocation)) + llvm::to_underlying(PrintingPolicy::AnonymousTagMode::SourceLocation)) printAnonymousTagDeclLocation(OS, Policy); OS << (Policy.MSVCFormatting ? '\'' : ')'); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 3a2f6a1486ddf..11c784ed5378f 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1533,20 +1533,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 5e452245ee627..580d93bc9b21c 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
