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 @@ -789,6 +789,11 @@ std::memcpy(Data + A.size(), B.data(), B.size()); return StringRef(Data, A.size() + B.size()); } + + /// Returns the QualType of the typedef that the PreferredNameAttr + /// of 'orig' refers to, if any such attribute exists. Returns 'orig' + /// otherwise. + QualType maybeGetPreferredNameType(QualType orig) const; }; /// A scoped helper to set the current debug location to the specified 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 @@ -250,7 +250,7 @@ PP.SuppressInlineNamespace = false; PP.PrintCanonicalTypes = true; - PP.UsePreferredNames = false; + PP.UsePreferredNames = CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB; PP.AlwaysIncludeTypeForTemplateArgument = true; PP.UseEnumerators = false; @@ -2016,7 +2016,8 @@ switch (TA.getKind()) { case TemplateArgument::Type: { - llvm::DIType *TTy = getOrCreateType(TA.getAsType(), Unit); + llvm::DIType *TTy = + getOrCreateType(maybeGetPreferredNameType(TA.getAsType()), Unit); TemplateParams.push_back(DBuilder.createTemplateTypeParameter( TheCU, Name, TTy, defaultParameter)); @@ -2029,7 +2030,8 @@ } break; case TemplateArgument::Declaration: { const ValueDecl *D = TA.getAsDecl(); - QualType T = TA.getParamTypeForDecl().getDesugaredType(CGM.getContext()); + QualType T = maybeGetPreferredNameType( + TA.getParamTypeForDecl().getDesugaredType(CGM.getContext())); llvm::DIType *TTy = getOrCreateType(T, Unit); llvm::Constant *V = nullptr; // Skip retrieve the value if that template parameter has cuda device @@ -4461,7 +4463,7 @@ if (VD->hasAttr()) Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType; else - Ty = getOrCreateType(VD->getType(), Unit); + Ty = getOrCreateType(maybeGetPreferredNameType(VD->getType()), Unit); // If there is no debug info for this type then do not emit debug info // for this variable. @@ -5760,3 +5762,12 @@ return llvm::DINode::FlagAllCallsDescribed; } + +QualType CGDebugInfo::maybeGetPreferredNameType(QualType orig) const { + if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) + if (auto *RecordDecl = orig->getAsCXXRecordDecl()) + if (auto *Attr = RecordDecl->getAttr()) + return Attr->getTypedefType(); + + return orig; +} diff --git a/clang/test/CodeGen/debug-info-preferred-names.cpp b/clang/test/CodeGen/debug-info-preferred-names.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/debug-info-preferred-names.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone %s -o - -debugger-tuning=lldb | FileCheck --check-prefixes=COMMON,LLDB %s +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone %s -o - -debugger-tuning=gdb | FileCheck --check-prefixes=COMMON,GDB %s + +template +class Qux {}; + +template +struct Foo; + +template +using Bar = Foo; + +template +struct [[clang::preferred_name(Bar)]] Foo {}; + +int main() { + /* Trivial cases */ + + Bar b; +// COMMON: !DIDerivedType(tag: DW_TAG_typedef, name: "Bar" + + Foo f1; +// COMMON: !DICompositeType(tag: DW_TAG_structure_type, name: "Foo" + + /* Alias template case */ + + Bar> f2; +// GDB: !DIDerivedType(tag: DW_TAG_typedef, name: "Bar >" +// LLDB: !DIDerivedType(tag: DW_TAG_typedef, name: "Bar >" + + /* Nested cases */ + + Foo> f3; +// GDB: !DICompositeType(tag: DW_TAG_structure_type, name: "Foo >" +// LLDB: !DICompositeType(tag: DW_TAG_structure_type, name: "Foo >" + + Qux> f4; +// GDB: !DICompositeType(tag: DW_TAG_class_type, name: "Qux >" +// LLDB: !DICompositeType(tag: DW_TAG_class_type, name: "Qux >" + + return 0; +} diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py @@ -59,13 +59,13 @@ self.assertNotEqual(valobj.child[0].unsigned, 0) if self.expectedCompilerVersion(['>', '16.0']): - string_type = "std::basic_string" + string_type = "std::string" else: - string_type = "std::basic_string, std::allocator >" + string_type = "std::basic_string, std::allocator > " valobj = self.expect_var_path( "sp_str", - type="std::shared_ptr<" + string_type + " >", + type="std::shared_ptr<" + string_type + ">", children=[ValueCheck(name="__ptr_", summary='"hello"')], ) self.assertRegex(valobj.summary, r'^"hello"( strong=1)? weak=1$') diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py @@ -22,7 +22,7 @@ def make_expected_basic_string_ptr(self) -> str: if self.expectedCompilerVersion(['>', '16.0']): - return f'std::unique_ptr >' + return f'std::unique_ptr' else: return 'std::unique_ptr, std::allocator >, ' \ 'std::default_delete, std::allocator > > >'