Michael137 created this revision. Michael137 added a reviewer: aprantl. Herald added a project: All. Michael137 added a comment. Michael137 updated this revision to Diff 504274. Michael137 updated this revision to Diff 504276. Michael137 edited the summary of this revision. Michael137 added a reviewer: dblaikie. Michael137 published this revision for review. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Yet another alternative for emitting preferred_names. Makes the attribute introduced in https://reviews.llvm.org/D145077 redundant. Also doesn't require any changes to LLDB (making https://reviews.llvm.org/D145078 redundant, which got a bit hairy) aprantl added a comment. This seems to be a much simpler implementation that just automatically works. I think I'd prefer that over adding new DWARF attributes. Michael137 added a comment. - Add test Michael137 added a comment. - Update commit message [clang][DebugInfo] Emit DW_AT_type of preferred name if available With this patch, whenever we emit a `DW_AT_type` for some declaration and the type is a template class with a `clang::PreferredNameAttr`, we will emit the typedef that the attribute refers to instead. I.e., 0x123 DW_TAG_variable DW_AT_name "var" DW_AT_type (0x123 "basic_string<char>") 0x124 DW_TAG_structure_type DW_AT_name "basic_string<char>" ...becomes 0x123 DW_TAG_variable DW_AT_name "var" DW_AT_type (0x124 "std::string") 0x124 DW_TAG_structure_type DW_AT_name "basic_string<char>" 0x125 DW_TAG_typedef DW_AT_name "std::string" DW_AT_type (0x124 "basic_string<char>") For now we keep this behind LLDB tuning. **Testing** - Added clang unit-test - `check-llvm`, `check-clang` pass - Confirmed that this change correctly repoints `basic_string` references in some of my test programs. - Will add follow-up LLDB API tests Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D145803 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/CodeGen/CGDebugInfo.h clang/test/CodeGen/preferred_name.cpp
Index: clang/test/CodeGen/preferred_name.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/preferred_name.cpp @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -debugger-tuning=lldb %s | FileCheck %s --check-prefixes=COMMON,LLDB +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -debugger-tuning=gdb %s | FileCheck %s --check-prefixes=COMMON,GDB + +template <typename T> +struct Foo; + +typedef Foo<int> BarInt; +typedef Foo<double> BarDouble; + +template <typename T> +using Bar = Foo<T>; + +template <typename T> +struct [[clang::preferred_name(BarInt), + clang::preferred_name(BarDouble), + clang::preferred_name(Bar<short>), + clang::preferred_name(Bar<char>)]] Foo{ + }; + +int main() { + Foo<int> varInt; + +// COMMON: !DILocalVariable(name: "varInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_INT_TY:[0-9]+]]) +// LLDB: ![[BAR_INT_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarInt", file: ![[#]], line: [[#]], baseType: ![[BAR_INT_BASE:[0-9]+]]) +// LLDB: ![[BAR_INT_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>", file: ![[#]], line: [[#]], size: [[#]] +// GDB: ![[BAR_INT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>", file: ![[#]], line: [[#]], size: [[#]] + + Foo<double> varDouble; + +// COMMON: !DILocalVariable(name: "varDouble", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_DOUBLE_TY:[0-9]+]]) +// LLDB: ![[BAR_DOUBLE_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarDouble", file: ![[#]], line: [[#]], baseType: ![[BAR_DOUBLE_BASE:[0-9]+]]) +// LLDB: ![[BAR_DOUBLE_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<double>" +// GDB: ![[BAR_DOUBLE_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<double>" + + Foo<short> varShort; + +// COMMON: !DILocalVariable(name: "varShort", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_SHORT_TY:[0-9]+]]) +// LLDB: ![[BAR_SHORT_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<short>", file: ![[#]], line: [[#]], baseType: ![[BAR_SHORT_BASE:[0-9]+]]) +// LLDB: ![[BAR_SHORT_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<short>" +// GDB: ![[BAR_SHORT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<short>" + + Foo<char> varChar; + +// COMMON: !DILocalVariable(name: "varChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_CHAR_TY:[0-9]+]]) +// LLDB: ![[BAR_CHAR_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>", file: ![[#]], line: [[#]], baseType: ![[BAR_CHAR_BASE:[0-9]+]]) +// LLDB: ![[BAR_CHAR_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<char>" +// GDB: ![[BAR_CHAR_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<char>" + + Foo<Foo<int>> varFooInt; + +// COMMON: !DILocalVariable(name: "varFooInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_FOO_INT_TY:[0-9]+]]) +// COMMON: ![[BAR_FOO_INT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<Foo<int> >" + + BarInt barInt; + +// LLDB: !DILocalVariable(name: "barInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_INT_TY]]) +// GDB: !DILocalVariable(name: "barInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_INT_TYPEDEF:[0-9]+]]) +// GDB: ![[BAR_INT_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarInt" + + BarDouble barDouble; + +// LLDB: !DILocalVariable(name: "barDouble", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_DOUBLE_TY]]) +// GDB: !DILocalVariable(name: "barDouble", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_DOUBLE_TYPEDEF:[0-9]+]]) +// GDB: ![[BAR_DOUBLE_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarDouble" + + Bar<short> barShort; + +// LLDB: !DILocalVariable(name: "barShort", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_SHORT_TY_2:[0-9]+]]) +// GDB: !DILocalVariable(name: "barShort", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_SHORT_TYPEDEF:[0-9]+]]) +// GDB: ![[BAR_SHORT_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<short>" + + Bar<char> barChar; + +// LLDB: ![[BAR_SHORT_TY_2]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<short>", file: ![[#]], line: [[#]], baseType: ![[BAR_SHORT_TY]]) + +// LLDB: !DILocalVariable(name: "barChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_CHAR_TY_2:[0-9]+]]) +// GDB: !DILocalVariable(name: "barChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_CHAR_TYPEDEF:[0-9]+]]) +// GDB: ![[BAR_CHAR_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>" + +// LLDB: ![[BAR_CHAR_TY_2]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>", file: ![[#]], line: [[#]], baseType: ![[BAR_CHAR_TY]]) + + return 0; +} + + Index: clang/lib/CodeGen/CGDebugInfo.h =================================================================== --- clang/lib/CodeGen/CGDebugInfo.h +++ clang/lib/CodeGen/CGDebugInfo.h @@ -276,6 +276,12 @@ llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes, llvm::DINode::DIFlags StartingFlags); + /// 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); + struct TemplateArgs { const TemplateParameterList *TList; llvm::ArrayRef<TemplateArgument> Args; Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -2602,6 +2602,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(); @@ -2657,6 +2669,11 @@ llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl)); RegionMap[Ty->getDecl()].reset(FwdDecl); + + if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) + if (auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit)) + return PrefDI; + return FwdDecl; } @@ -3685,7 +3702,7 @@ void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType *RealDecl) { // A class's primary base or the class itself contains the vtable. - llvm::DICompositeType *ContainingType = nullptr; + llvm::DIType *ContainingType = nullptr; const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) { // Seek non-virtual primary base root. @@ -3697,9 +3714,8 @@ else break; } - ContainingType = cast<llvm::DICompositeType>( - getOrCreateType(QualType(PBase->getTypeForDecl(), 0), - getOrCreateFile(RD->getLocation()))); + ContainingType = getOrCreateType(QualType(PBase->getTypeForDecl(), 0), + getOrCreateFile(RD->getLocation())); } else if (RD->isDynamicClass()) ContainingType = RealDecl;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits