diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -297,6 +297,11 @@ const lldb::ModuleSP &module_sp, std::vector> &base_classes, lldb_private::ClangASTImporter::LayoutInfo &layout_info); + + /// Add to 'record_decl' a 'clang::PreferredNameAttr' pointing to the type + /// represented by 'pref_die'. + void AttachPreferredNameAttr(DWARFDIE pref_die, + clang::CXXRecordDecl *record_decl); }; /// Parsed form of all attributes that are relevant for type reconstruction. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2200,6 +2200,15 @@ GetClangASTImporter().SetRecordLayout(record_decl, layout_info); } + // Need to set preferred name here instead of ParseStructureLikeDIE + // since the type that the typedef links back to is probably in the + // process of being created. + if (DWARFDIE pref_name_die = + die.GetAttributeValueAsReferenceDIE(DW_AT_LLVM_preferred_name)) + if (clang::CXXRecordDecl *record_decl = + m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType())) + AttachPreferredNameAttr(pref_name_die, record_decl); + return (bool)clang_type; } @@ -3693,3 +3702,22 @@ return !failures.empty(); } + +void DWARFASTParserClang::AttachPreferredNameAttr( + DWARFDIE pref_die, clang::CXXRecordDecl *record_decl) { + assert(record_decl != nullptr); + + Type *lldb_type = pref_die.ResolveType(); + if (!lldb_type) + return; + + CompilerType pref_name = lldb_type->GetFullCompilerType(); + if (!pref_name) + return; + + clang::QualType pref_name_type = ClangUtil::GetQualType(pref_name); + if (!pref_name_type.isNull()) + record_decl->addAttr(clang::PreferredNameAttr::CreateImplicit( + m_ast.getASTContext(), + m_ast.getASTContext().getTrivialTypeSourceInfo(pref_name_type))); +} diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -1714,6 +1714,7 @@ class_template_specialization_decl->setDeclName( class_template_decl->getDeclName()); SetOwningModule(class_template_specialization_decl, owning_module); + decl_ctx->addDecl(class_template_specialization_decl); class_template_specialization_decl->setSpecializationKind( 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.expectedCompiler(["clang"]) and 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.expectedCompiler(["clang"]) and 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 > > >' diff --git a/lldb/test/API/lang/cpp/preferred_name/Makefile b/lldb/test/API/lang/cpp/preferred_name/Makefile new file mode 100644 --- /dev/null +++ b/lldb/test/API/lang/cpp/preferred_name/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp +CXXFLAGS_EXTRAS := -std=c++20 -glldb +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/preferred_name/TestPreferredName.py b/lldb/test/API/lang/cpp/preferred_name/TestPreferredName.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/lang/cpp/preferred_name/TestPreferredName.py @@ -0,0 +1,21 @@ +""" +Test formatting of types annotated with +[[clang::preferred_name]] attributes. +""" + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * +from lldbsuite.test import decorators + + +class TestPreferredName(TestBase): + + def test(self): + self.build() + lldbutil.run_to_source_breakpoint(self, "return", lldb.SBFileSpec("main.cpp")) + + self.expect("frame variable varInt", substrs=["BarInt"]) + self.expect("frame variable varDouble", substrs=["BarDouble"]) + self.expect("frame variable varShort", substrs=["Bar"]) + self.expect("frame variable varChar", substrs=["Bar"]) diff --git a/lldb/test/API/lang/cpp/preferred_name/main.cpp b/lldb/test/API/lang/cpp/preferred_name/main.cpp new file mode 100644 --- /dev/null +++ b/lldb/test/API/lang/cpp/preferred_name/main.cpp @@ -0,0 +1,22 @@ +template struct Foo; + +typedef Foo BarInt; +typedef Foo BarDouble; + +template using Bar = Foo; + +template +struct [[clang::preferred_name(BarInt), clang::preferred_name(BarDouble), + clang::preferred_name(Bar), clang::preferred_name(Bar), + clang::preferred_name(Bar), + clang::preferred_name(Bar)]] Foo { + int mem = 0; +}; + +int main() { + Foo varInt; + Foo varDouble; + Foo varShort; + Foo varChar; + return 0; +}