diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index e13005349582e..c5b1cd2a329ae 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -638,6 +638,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: @@ -777,7 +778,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( @@ -865,6 +866,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: @@ -3848,12 +3850,10 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( } } - DWARFASTParserClang *src_dwarf_ast_parser = - static_cast( - SymbolFileDWARF::GetDWARFParser(*src_class_die.GetCU())); - DWARFASTParserClang *dst_dwarf_ast_parser = - static_cast( - SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU())); + auto *src_dwarf_ast_parser = llvm::cast( + SymbolFileDWARF::GetDWARFParser(*src_class_die.GetCU())); + auto *dst_dwarf_ast_parser = llvm::cast( + SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU())); auto link = [&](DWARFDIE src, DWARFDIE dst) { auto &die_to_type = dst_class_die.GetDWARF()->GetDIEToType(); clang::DeclContext *dst_decl_ctx = diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 338eeeec8fb0b..189427023b27d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -47,6 +47,11 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser { ~DWARFASTParserClang() override; + // LLVM RTTI support + static bool classof(const DWARFASTParser *Parser) { + return Parser->GetKind() == Kind::DWARFASTParserClang; + } + // DWARFASTParser interface. lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, @@ -276,10 +281,6 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser { lldb::ModuleSP GetModuleForType(const lldb_private::plugin::dwarf::DWARFDIE &die); - static bool classof(const DWARFASTParser *Parser) { - return Parser->GetKind() == Kind::DWARFASTParserClang; - } - private: struct FieldInfo { /// Size in bits that this field occupies. Can but diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index adf8bd00b776b..f2f83f0e0d2e7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1573,8 +1573,8 @@ bool SymbolFileDWARF::HasForwardDeclForCompilerType( auto clang_type_system = compiler_type.GetTypeSystem(); if (!clang_type_system) return false; - DWARFASTParserClang *ast_parser = - static_cast(clang_type_system->GetDWARFParser()); + auto *ast_parser = + llvm::cast(clang_type_system->GetDWARFParser()); return ast_parser->GetClangASTImporter().CanImport(compiler_type); } @@ -1582,8 +1582,8 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { std::lock_guard guard(GetModuleMutex()); auto clang_type_system = compiler_type.GetTypeSystem(); if (clang_type_system) { - DWARFASTParserClang *ast_parser = - static_cast(clang_type_system->GetDWARFParser()); + auto *ast_parser = + llvm::cast(clang_type_system->GetDWARFParser()); if (ast_parser && ast_parser->GetClangASTImporter().CanImport(compiler_type)) return ast_parser->GetClangASTImporter().CompleteType(compiler_type); @@ -1627,8 +1627,7 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { if (decl_die != def_die) { GetDIEToType()[def_die.GetDIE()] = type; - DWARFASTParserClang *ast_parser = - static_cast(dwarf_ast); + auto *ast_parser = llvm::cast(dwarf_ast); ast_parser->MapDeclDIEToDefDIE(decl_die, def_die); } diff --git a/lldb/unittests/Symbol/TestClangASTImporter.cpp b/lldb/unittests/Symbol/TestClangASTImporter.cpp index f1b3d7911c4bd..07c42088b9101 100644 --- a/lldb/unittests/Symbol/TestClangASTImporter.cpp +++ b/lldb/unittests/Symbol/TestClangASTImporter.cpp @@ -287,7 +287,7 @@ TEST_F(TestClangASTImporter, RecordLayoutFromOrigin) { clang_utils::SourceASTWithRecord source; auto *dwarf_parser = - static_cast(source.ast->GetDWARFParser()); + llvm::cast(source.ast->GetDWARFParser()); auto &importer = dwarf_parser->GetClangASTImporter(); // Set the layout for the origin decl in the origin ClangASTImporter. diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp index 0a1b29a292c7c..1753f221cc0e0 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -42,6 +42,52 @@ 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 thereafter vends a DWARFASTParserClang and +/// TypeSystemClang that are guaranteed to live for the duration of this object. +class DWARFASTParserClangYAMLTester { +public: + DWARFASTParserClangYAMLTester(llvm::StringRef yaml_data) + : m_module_tester(yaml_data) {} + + 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); + } + + DWARFASTParserClang &GetParser() { + auto *parser = GetTypeSystem().GetDWARFParser(); + + assert(llvm::isa_and_nonnull(parser)); + + return *llvm::cast(parser); + } + + TypeSystemClang &GetTypeSystem() { + ModuleSP module_sp = m_module_tester.GetModule(); + assert(module_sp); + + SymbolFile *symfile = module_sp->GetSymbolFile(); + assert(symfile); + + TypeSystemSP ts_sp = llvm::cantFail( + symfile->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); + + assert(llvm::isa_and_nonnull(ts_sp.get())); + + return llvm::cast(*ts_sp); + } + +private: + YAMLModuleTester m_module_tester; +}; } // namespace // If your implementation needs to dereference the dummy pointers we are @@ -99,7 +145,6 @@ TEST_F(DWARFASTParserClangTests, - Value: 0x0000000000000001 - AbbrCode: 0x00000000 )"; - YAMLModuleTester t(yamldata); ASSERT_TRUE((bool)t.GetDwarfUnit()); @@ -248,17 +293,9 @@ TEST_F(DWARFASTParserClangTests, TestCallingConventionParsing) { - AbbrCode: 0x0 ... )"; - YAMLModuleTester t(yamldata); + DWARFASTParserClangYAMLTester tester(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("ast"); - auto &ast_ctx = *holder->GetAST(); - DWARFASTParserClangStub ast_parser(ast_ctx); + DWARFDIE cu_die = tester.GetCUDIE(); std::vector found_function_types; // The DWARF above is just a list of functions. Parse all of them to @@ -267,7 +304,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 +432,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("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 +444,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 +583,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("ast"); - auto &ast_ctx = *holder->GetAST(); - DWARFASTParserClangStub ast_parser(ast_ctx); + DWARFASTParserClangYAMLTester tester(BufferOrError.get()->getBuffer()); + DWARFDIE cu_die = tester.GetCUDIE(); llvm::SmallVector 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)); } } @@ -696,18 +718,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("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; @@ -728,6 +740,8 @@ TEST_F(DWARFASTParserClangTests, TestUniqueDWARFASTTypeMap_CppInsertMapFind) { ParsedDWARFTypeAttributes attrs(def_die); ASSERT_TRUE(attrs.decl.IsValid()); + DWARFASTParserClang &ast_parser = tester.GetParser(); + SymbolContext sc; bool new_type = false; lldb::TypeSP type_sp = ast_parser.ParseTypeFromDWARF(sc, decl_die, &new_type); @@ -872,18 +886,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("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()); @@ -898,7 +902,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)); } { @@ -911,8 +916,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)); } } @@ -1042,18 +1047,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("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()); @@ -1071,7 +1066,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) { @@ -1209,21 +1204,15 @@ 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); ASSERT_TRUE(static_cast(ts_or_err)); llvm::consumeError(ts_or_err.takeError()); auto *parser = - static_cast((*ts_or_err)->GetDWARFParser()); + llvm::cast((*ts_or_err)->GetDWARFParser()); auto context_die = cu_die.GetFirstChild(); ASSERT_TRUE(context_die.IsValid()); @@ -1385,22 +1374,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(ts_or_err)); - llvm::consumeError(ts_or_err.takeError()); - - auto *ts = static_cast(ts_or_err->get()); - auto *parser = static_cast(ts->GetDWARFParser()); + DWARFASTParserClangYAMLTester tester(yamldata); + DWARFDIE cu_die = tester.GetCUDIE(); auto subprogram = cu_die.GetFirstChild(); ASSERT_TRUE(subprogram.IsValid()); @@ -1408,11 +1383,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(result.front()); @@ -1575,19 +1552,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("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()); @@ -1606,7 +1572,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 @@ -1614,7 +1581,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)); } } @@ -1677,19 +1645,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("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()); @@ -1700,8 +1657,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), @@ -1823,27 +1780,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("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( @@ -1857,8 +1804,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( @@ -1872,8 +1820,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( @@ -1888,8 +1837,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( @@ -1904,8 +1854,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( @@ -1919,3 +1870,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') +# DW_AT_type ('int') +# DW_TAG_template_type_parameter +# DW_AT_name ('T') +# DW_AT_type ('int') + + - AbbrCode: 0x3 + Values: + - CStr: Foo + - 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"); + EXPECT_EQ(type_sp->GetForwardCompilerType().GetTypeName(), "Foo"); +} + +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') +# DW_AT_type ('int') +# DW_TAG_template_type_parameter +# DW_AT_name ('T') +# DW_AT_type ('int') + + - AbbrCode: 0x4 + Values: + - CStr: Bar + - 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"); + EXPECT_EQ(type_sp->GetForwardCompilerType().GetTypeName(), "Foo::Bar"); +}