[Lldb-commits] [lldb] 1f35b52 - [lldb][DWARFASTParserClang] Treat DW_TAG_template_alias like we do DW_TAG_typedef (#170135)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Dec 2 19:07:20 PST 2025
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>");
+}
More information about the lldb-commits
mailing list