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

Reply via email to