Michael137 created this revision. Michael137 added reviewers: aprantl, dblaikie. Herald added a project: All. Michael137 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
With this patch, we now emit a `DW_AT_LLVM_preferred_name` for the `[clang::preferred_name]]` attribute attached to a class template. This is useful for consumers in case they want to display the name in terms of the preferred name, e.g., LLDB's type-summaries. For now this is behind an LLDB tuning. E.g., for following code: template<typename T> struct Foo; typedef Foo<int> BarInt; typedef Foo<double> BarDouble; template<typename T> struct [[clang::preferred_name(BarInt), clang::preferred_name(BarDouble)]] Foo {}; ...the generated DWARF with this patch looks as follows: 0x0000006b: DW_TAG_structure_type DW_AT_LLVM_preferred_name (0x00000082) DW_AT_name ("Foo<int>") 0x00000082: DW_TAG_typedef DW_AT_type (0x0000006b "Foo<int>") DW_AT_name ("BarInt") 0x0000008d: DW_TAG_structure_type DW_AT_LLVM_preferred_name (0x000000ab) DW_AT_name ("Foo<double>") 0x000000ab: DW_TAG_typedef DW_AT_type (0x0000008d "Foo<double>") DW_AT_name ("BarDouble") Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D145077 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/CodeGen/CGDebugInfo.h clang/test/CodeGen/attr-preferred_name-alias-template.cpp clang/test/CodeGen/attr-preferred_name-typedef.cpp
Index: clang/test/CodeGen/attr-preferred_name-typedef.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/attr-preferred_name-typedef.cpp @@ -0,0 +1,27 @@ +// RUN: %clang -target x86_64 -glldb -S -emit-llvm -o - %s | FileCheck %s --check-prefix=LLDB +// RUN: %clang -target x86_64 -ggdb -S -emit-llvm -o - %s | FileCheck %s --check-prefix=GDB + +template<typename T> +struct Foo; + +typedef Foo<int> BarInt; +typedef Foo<double> BarDouble; + +template<typename T> +struct [[clang::preferred_name(BarInt), + clang::preferred_name(BarDouble)]] Foo {}; + +Foo<int> varInt; +Foo<double> varDouble; + +// LLDB: ![[FOO_DOUBLE:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<double>" +// GDB-NOT: preferredName: ![[DOUBLE_PREF:[0-9]+]]) +// LLDB-SAME: preferredName: ![[DOUBLE_PREF:[0-9]+]]) +// LLDB: !DIDerivedType(tag: DW_TAG_typedef, name: "BarDouble", +// LLDB-SAME: baseType: ![[FOO_DOUBLE]]) + +// LLDB: ![[FOO_INT:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>" +// GDB-NOT: preferredName: ![[INT_PREF:[0-9]+]]) +// LLDB-SAME: preferredName: ![[INT_PREF:[0-9]+]]) +// LLDB: !DIDerivedType(tag: DW_TAG_typedef, name: "BarInt", +// LLDB-SAME: baseType: ![[FOO_INT]]) Index: clang/test/CodeGen/attr-preferred_name-alias-template.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/attr-preferred_name-alias-template.cpp @@ -0,0 +1,19 @@ +// RUN: %clang -target x86_64 -glldb -S -emit-llvm -o - %s | FileCheck %s --check-prefix=LLDB +// RUN: %clang -target x86_64 -ggdb -S -emit-llvm -o - %s | FileCheck %s --check-prefix=GDB + +template<typename T> +struct Foo; + +template<typename T> +using Bar = Foo<T>; + +template<typename T> +struct [[clang::preferred_name(Bar<T>)]] Foo {}; + +Foo<int> varInt; + +// LLDB: ![[FOO_INT:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>" +// GDB-NOT: preferredName: ![[INT_PREF:[0-9]+]]) +// LLDB-SAME: preferredName: ![[INT_PREF:[0-9]+]]) +// LLDB: !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<int>", +// LLDB-SAME: baseType: ![[FOO_INT]]) Index: clang/lib/CodeGen/CGDebugInfo.h =================================================================== --- clang/lib/CodeGen/CGDebugInfo.h +++ clang/lib/CodeGen/CGDebugInfo.h @@ -267,6 +267,11 @@ SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy); + /// Helper class that retrieves returns llvm::DIType the that + /// PreferredNameAttr attribute on \ref RD refers to. If no such + /// attribute exists, returns nullptr. + llvm::DIType * GetPreferredNameType(const CXXRecordDecl *RD, llvm::DIFile *Unit); + /// Helper function for CollectCXXBases. /// Adds debug info entries for types in Bases that are not in SeenTypes. void CollectCXXBasesAux( Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -1301,6 +1301,8 @@ llvm::raw_svector_ostream OS(NS); auto PP = getPrintingPolicy(); + // TODO: Not strictly needed for std::string? + PP.UsePreferredNames = CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB; Ty->getTemplateName().print(OS, PP, TemplateName::Qualified::None); // Disable PrintCanonicalTypes here because we want @@ -2576,6 +2578,18 @@ return CreateTypeDefinition(Ty); } +llvm::DIType * CGDebugInfo::GetPreferredNameType( + const CXXRecordDecl *RD, llvm::DIFile *Unit) { + if (!RD) + return nullptr; + + auto const* PNA = RD->getAttr<PreferredNameAttr>(); + if (!PNA) + return nullptr; + + return getOrCreateType(PNA->getTypedefType(), Unit); +} + llvm::DIType *CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { RecordDecl *RD = Ty->getDecl(); @@ -2630,6 +2644,9 @@ FwdDecl = llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl)); + if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) + FwdDecl->replacePreferredName(GetPreferredNameType(CXXDecl, DefUnit)); + RegionMap[Ty->getDecl()].reset(FwdDecl); return FwdDecl; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits