[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Treat DW_TAG_template_alias like we do DW_TAG_typedef (PR #170135)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Mon Dec 1 05:34:18 PST 2025
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/170135
>From d8a151fbcadbb3afe8fcd1f6b9cdb583959f215c Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 1 Dec 2025 22:05:46 +0900
Subject: [PATCH 1/3] [lldb][test] DWARFASTParserClangTests: extract test setup
into helper structure
We keep repeating the boilerplate of creating a `DWARFASTParserClangStub` and `TypeSystemClangHolder` in all the unit-test cases. Lets extract this into a helper to make the tests easier to grok.
---
.../DWARF/DWARFASTParserClangTests.cpp | 293 +++++++-----------
1 file changed, 111 insertions(+), 182 deletions(-)
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index cef3a25a4a960..bd7aed8d8c2aa 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -42,6 +42,46 @@ class DWARFASTParserClangStub : public DWARFASTParserClang {
return keys;
}
};
+
+/// Helper structure for DWARFASTParserClang tests that want to parse DWARF
+/// generated using yaml2obj. On construction parses the supplied YAML data
+/// into a DWARF module and creates a DWARFASTParserClang and TypeSystem that
+/// live for the duration of this object.
+class DWARFASTParserClangYAMLTester {
+public:
+ DWARFASTParserClangYAMLTester(llvm::StringRef yaml_data)
+ : m_module_tester(yaml_data),
+ m_ast_holder_up(
+ std::make_unique<clang_utils::TypeSystemClangHolder>("ast")),
+ m_stub(*m_ast_holder_up->GetAST()) {}
+
+ DWARFDIE GetCUDIE() {
+ DWARFUnit *unit = m_module_tester.GetDwarfUnit();
+ assert(unit);
+
+ const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
+ assert(cu_entry->Tag() == DW_TAG_compile_unit);
+
+ return DWARFDIE(unit, cu_entry);
+ }
+
+ DWARFASTParserClangStub &GetParser() { return m_stub; }
+
+ TypeSystemClang &GetTypeSystem() {
+ assert(m_ast_holder_up);
+
+ TypeSystemClang *ts = m_ast_holder_up->GetAST();
+
+ assert(ts);
+
+ return *ts;
+ }
+
+private:
+ YAMLModuleTester m_module_tester;
+ std::unique_ptr<clang_utils::TypeSystemClangHolder> m_ast_holder_up;
+ DWARFASTParserClangStub m_stub;
+};
} // namespace
// If your implementation needs to dereference the dummy pointers we are
@@ -100,23 +140,15 @@ TEST_F(DWARFASTParserClangTests,
- AbbrCode: 0x00000000
)";
- YAMLModuleTester t(yamldata);
- ASSERT_TRUE((bool)t.GetDwarfUnit());
-
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFASTParserClangStub &ast_parser = tester.GetParser();
- DWARFASTParserClangStub ast_parser(ast_ctx);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE();
- const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild();
- const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling();
- const DWARFDebugInfoEntry *die_child2 = die_child1->GetSibling();
- const DWARFDebugInfoEntry *die_child3 = die_child2->GetSibling();
- std::vector<DWARFDIE> dies = {
- DWARFDIE(unit, die_child0), DWARFDIE(unit, die_child1),
- DWARFDIE(unit, die_child2), DWARFDIE(unit, die_child3)};
+ DWARFDIE die_first = tester.GetCUDIE();
+ DWARFDIE die_child0 = die_first.GetFirstChild();
+ DWARFDIE die_child1 = die_child0.GetSibling();
+ DWARFDIE die_child2 = die_child1.GetSibling();
+ DWARFDIE die_child3 = die_child2.GetSibling();
+ std::vector<DWARFDIE> dies = {die_child0, die_child1, die_child2, die_child3};
std::vector<clang::DeclContext *> decl_ctxs = {
(clang::DeclContext *)1LL, (clang::DeclContext *)2LL,
(clang::DeclContext *)2LL, (clang::DeclContext *)3LL};
@@ -248,17 +280,9 @@ TEST_F(DWARFASTParserClangTests, TestCallingConventionParsing) {
- AbbrCode: 0x0
...
)";
- YAMLModuleTester t(yamldata);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- DWARFDIE cu_die(unit, cu_entry);
+ DWARFASTParserClangYAMLTester tester(yamldata);
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
- DWARFASTParserClangStub ast_parser(ast_ctx);
+ DWARFDIE cu_die = tester.GetCUDIE();
std::vector<std::string> found_function_types;
// The DWARF above is just a list of functions. Parse all of them to
@@ -267,7 +291,8 @@ TEST_F(DWARFASTParserClangTests, TestCallingConventionParsing) {
ASSERT_EQ(func.Tag(), DW_TAG_subprogram);
SymbolContext sc;
bool new_type = false;
- lldb::TypeSP type = ast_parser.ParseTypeFromDWARF(sc, func, &new_type);
+ lldb::TypeSP type =
+ tester.GetParser().ParseTypeFromDWARF(sc, func, &new_type);
found_function_types.push_back(
type->GetForwardCompilerType().GetTypeName().AsCString());
}
@@ -394,18 +419,9 @@ TEST_F(DWARFASTParserClangTests, TestPtrAuthParsing) {
- AbbrCode: 0x00 # end of child tags of 0x0c
...
)";
- YAMLModuleTester t(yamldata);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- DWARFDIE cu_die(unit, cu_entry);
-
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
- DWARFASTParserClangStub ast_parser(ast_ctx);
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFDIE cu_die = tester.GetCUDIE();
DWARFDIE ptrauth_variable = cu_die.GetFirstChild();
ASSERT_EQ(ptrauth_variable.Tag(), DW_TAG_variable);
DWARFDIE ptrauth_type =
@@ -415,7 +431,7 @@ TEST_F(DWARFASTParserClangTests, TestPtrAuthParsing) {
SymbolContext sc;
bool new_type = false;
lldb::TypeSP type_sp =
- ast_parser.ParseTypeFromDWARF(sc, ptrauth_type, &new_type);
+ tester.GetParser().ParseTypeFromDWARF(sc, ptrauth_type, &new_type);
CompilerType compiler_type = type_sp->GetForwardCompilerType();
ASSERT_EQ(compiler_type.GetPtrAuthKey(), 0U);
ASSERT_EQ(compiler_type.GetPtrAuthAddressDiversity(), false);
@@ -554,24 +570,17 @@ TEST_F(DWARFASTParserClangTests, TestDefaultTemplateParamParsing) {
auto BufferOrError = llvm::MemoryBuffer::getFile(
GetInputFilePath("DW_AT_default_value-test.yaml"), /*IsText=*/true);
ASSERT_TRUE(BufferOrError);
- YAMLModuleTester t(BufferOrError.get()->getBuffer());
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- DWARFDIE cu_die(unit, cu_entry);
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
- DWARFASTParserClangStub ast_parser(ast_ctx);
+ DWARFASTParserClangYAMLTester tester(BufferOrError.get()->getBuffer());
+ DWARFDIE cu_die = tester.GetCUDIE();
llvm::SmallVector<lldb::TypeSP, 2> types;
for (DWARFDIE die : cu_die.children()) {
if (die.Tag() == DW_TAG_class_type) {
SymbolContext sc;
bool new_type = false;
- types.push_back(ast_parser.ParseTypeFromDWARF(sc, die, &new_type));
+ types.push_back(
+ tester.GetParser().ParseTypeFromDWARF(sc, die, &new_type));
}
}
@@ -605,23 +614,14 @@ TEST_F(DWARFASTParserClangTests, TestSpecDeclExistsError) {
auto BufferOrError = llvm::MemoryBuffer::getFile(
GetInputFilePath("DW_AT_spec_decl_exists-test.yaml"), /*IsText=*/true);
ASSERT_TRUE(BufferOrError);
- YAMLModuleTester t(BufferOrError.get()->getBuffer());
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- DWARFDIE cu_die(unit, cu_entry);
-
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
- DWARFASTParserClangStub ast_parser(ast_ctx);
+ DWARFASTParserClangYAMLTester tester(BufferOrError.get()->getBuffer());
+ DWARFDIE cu_die = tester.GetCUDIE();
llvm::SmallVector<lldb::TypeSP, 2> specializations;
for (DWARFDIE die : cu_die.children()) {
SymbolContext sc;
bool new_type = false;
- auto type = ast_parser.ParseTypeFromDWARF(sc, die, &new_type);
+ auto type = tester.GetParser().ParseTypeFromDWARF(sc, die, &new_type);
llvm::StringRef die_name = llvm::StringRef(die.GetName());
if (die_name.starts_with("_Optional_payload")) {
specializations.push_back(std::move(type));
@@ -730,18 +730,8 @@ TEST_F(DWARFASTParserClangTests, TestUniqueDWARFASTTypeMap_CppInsertMapFind) {
- AbbrCode: 0x00 # end of child tags of 0x0c
...
)";
- YAMLModuleTester t(yamldata);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
- DWARFDIE cu_die(unit, cu_entry);
-
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
- DWARFASTParserClangStub ast_parser(ast_ctx);
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFDIE cu_die = tester.GetCUDIE();
DWARFDIE decl_die;
DWARFDIE def_die;
@@ -762,6 +752,8 @@ TEST_F(DWARFASTParserClangTests, TestUniqueDWARFASTTypeMap_CppInsertMapFind) {
ParsedDWARFTypeAttributes attrs(def_die);
ASSERT_TRUE(attrs.decl.IsValid());
+ DWARFASTParserClangStub &ast_parser = tester.GetParser();
+
SymbolContext sc;
bool new_type = false;
lldb::TypeSP type_sp = ast_parser.ParseTypeFromDWARF(sc, decl_die, &new_type);
@@ -906,18 +898,8 @@ TEST_F(DWARFASTParserClangTests, TestObjectPointer) {
- AbbrCode: 0x0
...
)";
- YAMLModuleTester t(yamldata);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
- DWARFDIE cu_die(unit, cu_entry);
-
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
- DWARFASTParserClangStub ast_parser(ast_ctx);
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFDIE cu_die = tester.GetCUDIE();
auto context_die = cu_die.GetFirstChild();
ASSERT_TRUE(context_die.IsValid());
@@ -932,7 +914,8 @@ TEST_F(DWARFASTParserClangTests, TestObjectPointer) {
auto param_die = decl_die.GetFirstChild();
ASSERT_TRUE(param_die.IsValid());
- EXPECT_EQ(param_die, ast_parser.GetObjectParameter(decl_die, context_die));
+ EXPECT_EQ(param_die,
+ tester.GetParser().GetObjectParameter(decl_die, context_die));
}
{
@@ -945,8 +928,8 @@ TEST_F(DWARFASTParserClangTests, TestObjectPointer) {
auto param_die = subprogram_definition.GetFirstChild();
ASSERT_TRUE(param_die.IsValid());
- EXPECT_EQ(param_die, ast_parser.GetObjectParameter(subprogram_definition,
- context_die));
+ EXPECT_EQ(param_die, tester.GetParser().GetObjectParameter(
+ subprogram_definition, context_die));
}
}
@@ -1076,18 +1059,8 @@ TEST_F(DWARFASTParserClangTests,
- AbbrCode: 0x0
...
)";
- YAMLModuleTester t(yamldata);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
- DWARFDIE cu_die(unit, cu_entry);
-
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
- DWARFASTParserClangStub ast_parser(ast_ctx);
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFDIE cu_die = tester.GetCUDIE();
auto context_die = cu_die.GetFirstChild();
ASSERT_TRUE(context_die.IsValid());
@@ -1105,7 +1078,7 @@ TEST_F(DWARFASTParserClangTests,
auto param_die = subprogram_definition.GetFirstChild();
ASSERT_TRUE(param_die.IsValid());
EXPECT_EQ(param_die,
- ast_parser.GetObjectParameter(subprogram_definition, {}));
+ tester.GetParser().GetObjectParameter(subprogram_definition, {}));
}
TEST_F(DWARFASTParserClangTests, TestParseSubroutine_ExplicitObjectParameter) {
@@ -1243,14 +1216,8 @@ TEST_F(DWARFASTParserClangTests, TestParseSubroutine_ExplicitObjectParameter) {
- AbbrCode: 0x0
...
)";
- YAMLModuleTester t(yamldata);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
- DWARFDIE cu_die(unit, cu_entry);
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFDIE cu_die = tester.GetCUDIE();
auto ts_or_err =
cu_die.GetDWARF()->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
@@ -1419,22 +1386,8 @@ TEST_F(DWARFASTParserClangTests, TestParseSubroutine_ParameterCreation) {
- AbbrCode: 0x0
...
)";
- YAMLModuleTester t(yamldata);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
- DWARFDIE cu_die(unit, cu_entry);
-
- auto ts_or_err =
- cu_die.GetDWARF()->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
- ASSERT_TRUE(static_cast<bool>(ts_or_err));
- llvm::consumeError(ts_or_err.takeError());
-
- auto *ts = static_cast<TypeSystemClang *>(ts_or_err->get());
- auto *parser = static_cast<DWARFASTParserClang *>(ts->GetDWARFParser());
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFDIE cu_die = tester.GetCUDIE();
auto subprogram = cu_die.GetFirstChild();
ASSERT_TRUE(subprogram.IsValid());
@@ -1442,11 +1395,13 @@ TEST_F(DWARFASTParserClangTests, TestParseSubroutine_ParameterCreation) {
SymbolContext sc;
bool new_type;
- auto type_sp = parser->ParseTypeFromDWARF(sc, subprogram, &new_type);
+ auto type_sp =
+ tester.GetParser().ParseTypeFromDWARF(sc, subprogram, &new_type);
ASSERT_NE(type_sp, nullptr);
- auto result = ts->GetTranslationUnitDecl()->lookup(
- clang_utils::getDeclarationName(*ts, "func"));
+ TypeSystemClang &ts = tester.GetTypeSystem();
+ auto result = ts.GetTranslationUnitDecl()->lookup(
+ clang_utils::getDeclarationName(ts, "func"));
ASSERT_TRUE(result.isSingleResult());
auto const *func = llvm::cast<clang::FunctionDecl>(result.front());
@@ -1609,19 +1564,8 @@ TEST_F(DWARFASTParserClangTests, TestObjectPointer_IndexEncoding) {
- AbbrCode: 0x0
...
)";
-
- YAMLModuleTester t(yamldata);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
- DWARFDIE cu_die(unit, cu_entry);
-
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
- DWARFASTParserClangStub ast_parser(ast_ctx);
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFDIE cu_die = tester.GetCUDIE();
auto context_die = cu_die.GetFirstChild();
ASSERT_TRUE(context_die.IsValid());
@@ -1640,7 +1584,8 @@ TEST_F(DWARFASTParserClangTests, TestObjectPointer_IndexEncoding) {
auto param_die = sub1.GetFirstChild().GetSibling();
ASSERT_TRUE(param_die.IsValid());
- EXPECT_EQ(param_die, ast_parser.GetObjectParameter(sub1, context_die));
+ EXPECT_EQ(param_die,
+ tester.GetParser().GetObjectParameter(sub1, context_die));
}
// Object parameter is at constant index 0
@@ -1648,7 +1593,8 @@ TEST_F(DWARFASTParserClangTests, TestObjectPointer_IndexEncoding) {
auto param_die = sub2.GetFirstChild();
ASSERT_TRUE(param_die.IsValid());
- EXPECT_EQ(param_die, ast_parser.GetObjectParameter(sub2, context_die));
+ EXPECT_EQ(param_die,
+ tester.GetParser().GetObjectParameter(sub2, context_die));
}
}
@@ -1711,19 +1657,8 @@ TEST_F(DWARFASTParserClangTests, TestTypeBitSize) {
- Value: 0x02
...
)";
-
- YAMLModuleTester t(yamldata);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
- DWARFDIE cu_die(unit, cu_entry);
-
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
- DWARFASTParserClangStub ast_parser(ast_ctx);
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFDIE cu_die = tester.GetCUDIE();
auto type_die = cu_die.GetFirstChild();
ASSERT_TRUE(type_die.IsValid());
@@ -1734,8 +1669,8 @@ TEST_F(DWARFASTParserClangTests, TestTypeBitSize) {
EXPECT_EQ(attrs.data_bit_size.value_or(0), 2U);
SymbolContext sc;
- auto type_sp =
- ast_parser.ParseTypeFromDWARF(sc, type_die, /*type_is_new_ptr=*/nullptr);
+ auto type_sp = tester.GetParser().ParseTypeFromDWARF(
+ sc, type_die, /*type_is_new_ptr=*/nullptr);
ASSERT_NE(type_sp, nullptr);
EXPECT_EQ(llvm::expectedToOptional(type_sp->GetByteSize(nullptr)).value_or(0),
@@ -1857,27 +1792,17 @@ TEST_F(DWARFASTParserClangTests, TestBitIntParsing) {
...
)";
-
- YAMLModuleTester t(yamldata);
-
- DWARFUnit *unit = t.GetDwarfUnit();
- ASSERT_NE(unit, nullptr);
- const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
- ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
- ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
- DWARFDIE cu_die(unit, cu_entry);
-
- auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
- auto &ast_ctx = *holder->GetAST();
- DWARFASTParserClangStub ast_parser(ast_ctx);
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFDIE cu_die = tester.GetCUDIE();
auto type_die = cu_die.GetFirstChild();
ASSERT_TRUE(type_die.IsValid());
{
SymbolContext sc;
- auto type_sp = ast_parser.ParseTypeFromDWARF(sc, type_die,
- /*type_is_new_ptr=*/nullptr);
+ auto type_sp =
+ tester.GetParser().ParseTypeFromDWARF(sc, type_die,
+ /*type_is_new_ptr=*/nullptr);
ASSERT_NE(type_sp, nullptr);
EXPECT_EQ(
@@ -1891,8 +1816,9 @@ TEST_F(DWARFASTParserClangTests, TestBitIntParsing) {
{
type_die = type_die.GetSibling();
SymbolContext sc;
- auto type_sp = ast_parser.ParseTypeFromDWARF(sc, type_die,
- /*type_is_new_ptr=*/nullptr);
+ auto type_sp =
+ tester.GetParser().ParseTypeFromDWARF(sc, type_die,
+ /*type_is_new_ptr=*/nullptr);
ASSERT_NE(type_sp, nullptr);
EXPECT_EQ(
@@ -1906,8 +1832,9 @@ TEST_F(DWARFASTParserClangTests, TestBitIntParsing) {
{
type_die = type_die.GetSibling();
SymbolContext sc;
- auto type_sp = ast_parser.ParseTypeFromDWARF(sc, type_die,
- /*type_is_new_ptr=*/nullptr);
+ auto type_sp =
+ tester.GetParser().ParseTypeFromDWARF(sc, type_die,
+ /*type_is_new_ptr=*/nullptr);
ASSERT_NE(type_sp, nullptr);
EXPECT_EQ(
@@ -1922,8 +1849,9 @@ TEST_F(DWARFASTParserClangTests, TestBitIntParsing) {
{
type_die = type_die.GetSibling();
SymbolContext sc;
- auto type_sp = ast_parser.ParseTypeFromDWARF(sc, type_die,
- /*type_is_new_ptr=*/nullptr);
+ auto type_sp =
+ tester.GetParser().ParseTypeFromDWARF(sc, type_die,
+ /*type_is_new_ptr=*/nullptr);
ASSERT_NE(type_sp, nullptr);
EXPECT_EQ(
@@ -1938,8 +1866,9 @@ TEST_F(DWARFASTParserClangTests, TestBitIntParsing) {
{
type_die = type_die.GetSibling();
SymbolContext sc;
- auto type_sp = ast_parser.ParseTypeFromDWARF(sc, type_die,
- /*type_is_new_ptr=*/nullptr);
+ auto type_sp =
+ tester.GetParser().ParseTypeFromDWARF(sc, type_die,
+ /*type_is_new_ptr=*/nullptr);
ASSERT_NE(type_sp, nullptr);
EXPECT_EQ(
>From 83792f3b5de631b998436722d26eebb835e84e85 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 1 Dec 2025 18:48:28 +0900
Subject: [PATCH 2/3] [lldb][DWARFASTParserClang] Treat DW_TAG_template_alias
like we do DW_TAG_typedef
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.
One compelling reason to support `DW_TAG_template_alias` is that with `-gsimple-template-names`, `DW_TAG_typedef`s for alias templates have their template parameters stripped from the `DW_AT_name`. With just a plain `DW_TAG_typedef`, LLDB has no way to reconstruct the full `DW_AT_name`. But since `DW_TAG_template_alias` can carry template parameter children, LLDB can reconstitute the name by concatenating the `DW_AT_name`s of the child tags.
---
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 4 +-
.../DWARF/DWARFASTParserClangTests.cpp | 99 +++++++++++++++++++
2 files changed, 102 insertions(+), 1 deletion(-)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 36aa49ac3de95..3d556aea7b183 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 bd7aed8d8c2aa..ae39009a5f79c 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -1882,3 +1882,102 @@ 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
+...
+)";
+ DWARFASTParserClangYAMLTester tester(yamldata);
+ DWARFDIE cu_die = tester.GetCUDIE();
+
+ auto alias_die = cu_die.GetFirstChild().GetSibling();
+ ASSERT_TRUE(alias_die.IsValid());
+
+ 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>");
+}
>From 2aa6433c7b22b42bc26c69640f712c09933a2671 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 1 Dec 2025 22:34:05 +0900
Subject: [PATCH 3/3] fixup! stricter test assertion
---
lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index ae39009a5f79c..1c08d1bc4af9d 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -1969,7 +1969,7 @@ TEST_F(DWARFASTParserClangTests, TestTemplateAlias_NoSimpleTemplateNames) {
DWARFDIE cu_die = tester.GetCUDIE();
auto alias_die = cu_die.GetFirstChild().GetSibling();
- ASSERT_TRUE(alias_die.IsValid());
+ ASSERT_EQ(alias_die.Tag(), DW_TAG_template_alias);
SymbolContext sc;
auto type_sp =
More information about the lldb-commits
mailing list