diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -267,6 +267,12 @@ SmallVectorImpl &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( diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2576,6 +2576,18 @@ return CreateTypeDefinition(Ty); } +llvm::DIType *CGDebugInfo::GetPreferredNameType(const CXXRecordDecl *RD, + llvm::DIFile *Unit) { + if (!RD) + return nullptr; + + auto const *PNA = RD->getAttr(); + if (!PNA) + return nullptr; + + return getOrCreateType(PNA->getTypedefType(), Unit); +} + llvm::DIType *CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { RecordDecl *RD = Ty->getDecl(); @@ -2630,6 +2642,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; } diff --git a/clang/test/CodeGen/attr-preferred_name-alias-template.cpp b/clang/test/CodeGen/attr-preferred_name-alias-template.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/attr-preferred_name-alias-template.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 +struct Foo; + +template +using Bar = Foo; + +template +struct [[clang::preferred_name(Bar)]] Foo {}; + +Foo varInt; +Foo> varFooInt; + +// LLDB: ![[FOO_FOO_INT:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo >" +// GDB-NOT: preferredName: ![[FOO_INT_PREF:[0-9]+]]) +// LLDB-SAME: preferredName: ![[FOO_INT_PREF:[0-9]+]]) + +// LLDB: ![[FOO_INT:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo" +// GDB-NOT: preferredName: ![[INT_PREF:[0-9]+]]) +// LLDB-SAME: preferredName: ![[INT_PREF:[0-9]+]]) + +// LLDB: !DIDerivedType(tag: DW_TAG_typedef, name: "Bar", +// LLDB-SAME: baseType: ![[FOO_INT]]) +// LLDB: !DIDerivedType(tag: DW_TAG_typedef, name: "Bar >", +// LLDB-SAME: baseType: ![[FOO_FOO_INT]]) diff --git a/clang/test/CodeGen/attr-preferred_name-typedef.cpp b/clang/test/CodeGen/attr-preferred_name-typedef.cpp new file mode 100644 --- /dev/null +++ b/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 +struct Foo; + +typedef Foo BarInt; +typedef Foo BarDouble; + +template +struct [[clang::preferred_name(BarInt), + clang::preferred_name(BarDouble)]] Foo {}; + +Foo varInt; +Foo varDouble; + +// LLDB: ![[FOO_DOUBLE:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo" +// 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" +// 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]])