Author: Michael Buch Date: 2025-12-03T12:07:16+09:00 New Revision: 1f35b52a00ebd7d595deaffd5e72f72088f450b1
URL: https://github.com/llvm/llvm-project/commit/1f35b52a00ebd7d595deaffd5e72f72088f450b1 DIFF: https://github.com/llvm/llvm-project/commit/1f35b52a00ebd7d595deaffd5e72f72088f450b1.diff LOG: [lldb][DWARFASTParserClang] Treat DW_TAG_template_alias like we do DW_TAG_typedef (#170135) Depends on: * https://github.com/llvm/llvm-project/pull/170132 Clang gained the `-gtemplate-alias` not too long ago, which emits C++ alias templates as `DW_TAG_template_alias` (instead of `DW_TAG_typedef`). The main difference is that `DW_TAG_template_alias` has `DW_TAG_template_XXX` children. The flag was not enabled by default because consumers (mainly LLDB) didn't know how to handle it. This patch adds rudimentary support for debugging with `DW_TAG_template_alias`. This patch simply creates the same kind of `TypedefDecl` as we do for `DW_TAG_typedef`. The more complete solution would be to create a `TypeAliasTemplateDecl` and associated `TypeAliasDecl`. But that would require DWARF to carry generic template information, but currently each `DW_TAG_template_alias` represents a concrete instantiation. We could probably hack up some working AST representation that includes the template parameters, but I currently don't see a compelling reason to. All we need is the `DW_AT_name` and the `DW_AT_type` that the typedef refers to. rdar://137499401 Added: Modified: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 7160c6eec564b..d65aa40b5be86 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -623,6 +623,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, switch (tag) { case DW_TAG_typedef: + case DW_TAG_template_alias: case DW_TAG_base_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: @@ -748,7 +749,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, TypeSP type_sp; CompilerType clang_type; - if (tag == DW_TAG_typedef) { + if (tag == DW_TAG_typedef || tag == DW_TAG_template_alias) { // DeclContext will be populated when the clang type is materialized in // Type::ResolveCompilerType. PrepareContextToReceiveMembers( @@ -836,6 +837,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, encoding_data_type = Type::eEncodingIsRValueReferenceUID; break; case DW_TAG_typedef: + case DW_TAG_template_alias: encoding_data_type = Type::eEncodingIsTypedefUID; break; case DW_TAG_const_type: diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp index 642dde9924f3a..6a753b6b33edf 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -145,7 +145,6 @@ TEST_F(DWARFASTParserClangTests, - Value: 0x0000000000000001 - AbbrCode: 0x00000000 )"; - YAMLModuleTester t(yamldata); ASSERT_TRUE((bool)t.GetDwarfUnit()); @@ -1896,3 +1895,226 @@ TEST_F(DWARFASTParserClangTests, TestBitIntParsing) { EXPECT_EQ(type_sp->GetForwardCompilerType().GetTypeName(), "_BitInt(64)"); } } + +TEST_F(DWARFASTParserClangTests, TestTemplateAlias_NoSimpleTemplateNames) { + // Tests that we correctly parse the DW_TAG_template_alias generated by + // -gno-simple-template-names. + + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_AARCH64 +DWARF: + debug_abbrev: + - ID: 0 + Table: + - Code: 0x1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Code: 0x2 + Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Code: 0x3 + Tag: DW_TAG_template_alias + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Code: 0x4 + Tag: DW_TAG_template_type_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + + debug_info: + - Version: 5 + UnitType: DW_UT_compile + AddrSize: 8 + Entries: + +# DW_TAG_compile_unit +# DW_AT_language (DW_LANG_C_plus_plus) + + - AbbrCode: 0x1 + Values: + - Value: 0x04 + +# DW_TAG_base_type +# DW_AT_name ('int') + + - AbbrCode: 0x2 + Values: + - CStr: int + +# DW_TAG_template_alias +# DW_AT_name ('Foo<int>') +# DW_AT_type ('int') +# DW_TAG_template_type_parameter +# DW_AT_name ('T') +# DW_AT_type ('int') + + - AbbrCode: 0x3 + Values: + - CStr: Foo<int> + - Value: 0xf + + - AbbrCode: 0x4 + Values: + - CStr: T + - Value: 0xf + + - AbbrCode: 0x0 + - AbbrCode: 0x0 +... +)"; + DWARFASTParserClangYAMLTester tester(yamldata); + DWARFDIE cu_die = tester.GetCUDIE(); + + auto alias_die = cu_die.GetFirstChild().GetSibling(); + ASSERT_EQ(alias_die.Tag(), DW_TAG_template_alias); + + SymbolContext sc; + auto type_sp = + tester.GetParser().ParseTypeFromDWARF(sc, alias_die, + /*type_is_new_ptr=*/nullptr); + ASSERT_NE(type_sp, nullptr); + + EXPECT_TRUE(type_sp->IsTypedef()); + EXPECT_EQ(type_sp->GetName(), "Foo<int>"); + EXPECT_EQ(type_sp->GetForwardCompilerType().GetTypeName(), "Foo<int>"); +} + +TEST_F(DWARFASTParserClangTests, + TestTemplateAlias_InStruct_NoSimpleTemplateNames) { + // Tests that we correctly parse the DW_TAG_template_alias scoped inside a + // DW_TAG_structure_type *declaration* generated by + // -gno-simple-template-names. This tests the codepath the forcefully + // completes the context of the alias via PrepareContextToReceiveMembers. + + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_AARCH64 +DWARF: + debug_abbrev: + - ID: 0 + Table: + - Code: 0x1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Code: 0x2 + Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Code: 0x3 + Tag: DW_TAG_structure_type + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_declaration + Form: DW_FORM_flag_present + - Code: 0x4 + Tag: DW_TAG_template_alias + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Code: 0x5 + Tag: DW_TAG_template_type_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + + debug_info: + - Version: 5 + UnitType: DW_UT_compile + AddrSize: 8 + Entries: + +# DW_TAG_compile_unit +# DW_AT_language (DW_LANG_C_plus_plus) + + - AbbrCode: 0x1 + Values: + - Value: 0x04 + +# DW_TAG_base_type +# DW_AT_name ('int') + + - AbbrCode: 0x2 + Values: + - CStr: int + +# DW_TAG_structure_type +# DW_AT_name ('Foo') + + - AbbrCode: 0x3 + Values: + - CStr: Foo + +# DW_TAG_template_alias +# DW_AT_name ('Bar<int>') +# DW_AT_type ('int') +# DW_TAG_template_type_parameter +# DW_AT_name ('T') +# DW_AT_type ('int') + + - AbbrCode: 0x4 + Values: + - CStr: Bar<int> + - Value: 0xf + + - AbbrCode: 0x5 + Values: + - CStr: T + - Value: 0xf + + - AbbrCode: 0x0 + - AbbrCode: 0x0 + - AbbrCode: 0x0 +... +)"; + DWARFASTParserClangYAMLTester tester(yamldata); + DWARFDIE cu_die = tester.GetCUDIE(); + + auto alias_die = cu_die.GetFirstChild().GetSibling().GetFirstChild(); + ASSERT_EQ(alias_die.Tag(), DW_TAG_template_alias); + + SymbolContext sc; + auto type_sp = + tester.GetParser().ParseTypeFromDWARF(sc, alias_die, + /*type_is_new_ptr=*/nullptr); + ASSERT_NE(type_sp, nullptr); + + EXPECT_TRUE(type_sp->IsTypedef()); + EXPECT_EQ(type_sp->GetName(), "Bar<int>"); + EXPECT_EQ(type_sp->GetForwardCompilerType().GetTypeName(), "Foo::Bar<int>"); +} _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
