llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Felipe de Azevedo Piovezan (felipepiovezan) <details> <summary>Changes</summary> https://discourse.llvm.org/t/rfc-improve-dwarf-5-debug-names-type-lookup-parsing-speed/74151 --- Patch is 52.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/77121.diff 25 Files Affected: - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp (+7) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h (+5) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp (+6) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h (+5) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp (+20) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h (+14) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp (+8) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h (+5) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp (+96) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h (+9) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (+2-7) - (modified) lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp (+109) - (modified) llvm/include/llvm/CodeGen/AccelTable.h (+25-9) - (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h (+17) - (modified) llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp (+107-20) - (modified) llvm/lib/DWARFLinker/DWARFLinker.cpp (+8) - (modified) llvm/lib/DWARFLinkerParallel/DWARFLinkerImpl.cpp (+2-1) - (modified) llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp (+15) - (modified) llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp (+15-1) - (added) llvm/test/CodeGen/X86/dwarf-headers.o () - (modified) llvm/test/DebugInfo/X86/debug-names-dwarf64.ll (+12-4) - (modified) llvm/test/DebugInfo/X86/debug-names-end-of-list.ll (+4-2) - (modified) llvm/test/DebugInfo/X86/debug-names-types.ll (+39-19) - (modified) llvm/test/tools/dsymutil/ARM/accel-imported-declarations.test (+2) - (modified) llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test (+8-4) ``````````diff diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index 553b6a4c551d20..775b7a2e73f512 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -191,3 +191,10 @@ DWARFDebugInfo::GetDIE(const DIERef &die_ref) { return cu->GetNonSkeletonUnit().GetDIE(die_ref.die_offset()); return DWARFDIE(); // Not found } + +llvm::StringRef +DWARFDebugInfo::PeekDIEName(const DIERef &die_ref) { + if(DWARFUnit *cu = GetUnit(die_ref)) + return cu->GetNonSkeletonUnit().PeekDIEName(die_ref.die_offset()); + return llvm::StringRef(); +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h index d5e48f312ea0e9..a8b5abc3beed2d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -43,6 +43,11 @@ class DWARFDebugInfo { bool ContainsTypeUnits(); DWARFDIE GetDIE(const DIERef &die_ref); + /// Returns the AT_Name of this DIE, if it exists, without parsing the entire + /// compile unit. An empty is string is returned upon error or if the + /// attribute is not present. + llvm::StringRef PeekDIEName(const DIERef &die_ref); + enum { eDumpFlag_Verbose = (1 << 0), // Verbose dumping eDumpFlag_ShowForm = (1 << 1), // Show the DW_form type diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp index 44421c0eda3eec..3cdb47d50bbfc0 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp @@ -55,6 +55,12 @@ const char *DWARFDeclContext::GetQualifiedName() const { return m_qualified_name.c_str(); } +llvm::SmallVector<llvm::StringRef> +DWARFDeclContext::GetQualifiedNameAsVector() const { + return llvm::to_vector_of<llvm::StringRef>( + llvm::map_range(m_entries, GetName)); +} + bool DWARFDeclContext::operator==(const DWARFDeclContext &rhs) const { if (m_entries.size() != rhs.m_entries.size()) return false; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h index a20a862d340296..40ebb72c91d8f0 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -68,6 +68,11 @@ class DWARFDeclContext { const char *GetQualifiedName() const; + /// Returns a vector of string, one string per entry in the fully qualified + /// name. For example, for the name `A::B::C`, this methods returns `{"A", + /// "B", "C"}` + llvm::SmallVector<llvm::StringRef> GetQualifiedNameAsVector() const; + // Same as GetQualifiedName, but the life time of the returned string will // be that of the LLDB session. ConstString GetQualifiedNameAsConstString() const { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp index b1c323b101cef3..20c07a94b50769 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" +#include "DWARFDebugInfoEntry.h" +#include "DWARFDeclContext.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" @@ -112,3 +114,21 @@ void DWARFIndex::ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const { "bad die {0:x16} for '{1}')\n", ref.die_offset(), name.str().c_str()); } + +void DWARFIndex::GetFullyQualifiedType( + const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback) { + GetTypes(context, [&](DWARFDIE die) { + return GetFullyQualifiedTypeImpl(context, die, callback); + }); +} + +bool DWARFIndex::GetFullyQualifiedTypeImpl( + const DWARFDeclContext &context, DWARFDIE die, + llvm::function_ref<bool(DWARFDIE die)> callback) { + DWARFDeclContext dwarf_decl_ctx = + die.GetDIE()->GetDWARFDeclContext(die.GetCU()); + if (dwarf_decl_ctx == context) + return callback(die); + return true; +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h index 9aadeddbb21753..0551b07100a96b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -53,6 +53,14 @@ class DWARFIndex { llvm::function_ref<bool(DWARFDIE die)> callback) = 0; virtual void GetTypes(const DWARFDeclContext &context, llvm::function_ref<bool(DWARFDIE die)> callback) = 0; + + /// Finds all DIEs whose fully qualified name matches `context`. A base + /// implementation is provided, and it uses the entire CU to check the DIE + /// parent hierarchy. Specializations should override this if they are able + /// to provide a faster implementation. + virtual void + GetFullyQualifiedType(const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback); virtual void GetNamespaces(ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) = 0; @@ -102,6 +110,12 @@ class DWARFIndex { } void ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const; + + /// Implementation of `GetFullyQualifiedType` to check a single entry, + /// shareable with derived classes. + bool + GetFullyQualifiedTypeImpl(const DWARFDeclContext &context, DWARFDIE die, + llvm::function_ref<bool(DWARFDIE die)> callback); }; } // namespace dwarf } // namespace lldb_private::plugin diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 0e2f4d45543bb5..7db279ed37d04a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -663,6 +663,14 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) { return DWARFDIE(); // Not found } +llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) { + const DWARFDataExtractor &data = GetData(); + DWARFDebugInfoEntry die; + if (!die.Extract(data, this, &die_offset)) + return llvm::StringRef(); + return die.GetName(this); +} + DWARFUnit &DWARFUnit::GetNonSkeletonUnit() { ExtractUnitDIEIfNeeded(); if (m_dwo) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 3f528e913d8cfa..bc225a52e1d030 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -187,6 +187,11 @@ class DWARFUnit : public UserID { DWARFDIE GetDIE(dw_offset_t die_offset); + /// Returns the AT_Name of the DIE at `die_offset`, if it exists, without + /// parsing the entire compile unit. An empty is string is returned upon + /// error or if the attribute is not present. + llvm::StringRef PeekDIEName(dw_offset_t die_offset); + DWARFUnit &GetNonSkeletonUnit(); static uint8_t GetAddressByteSize(const DWARFUnit *cu); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index b718f98340a70b..8a82a77e6b1642 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -218,6 +218,102 @@ void DebugNamesDWARFIndex::GetCompleteObjCClass( m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, callback); } +namespace { +using Entry = llvm::DWARFDebugNames::Entry; + +// If `entry` and all of its parents have an `IDX_parent`, use that information +// to build and return a list of at most `max_parents` parent Entries. +// `entry` itself is not included in the list. +// If any parent does not have an `IDX_parent`, nullopt is returned. +static std::optional<llvm::SmallVector<Entry, 4>> +getParentChain(Entry entry, uint32_t max_parents) { + llvm::SmallVector<Entry, 4> parent_entries; + + do { + if (!entry.hasParentInformation()) + return std::nullopt; + + llvm::Expected<std::optional<Entry>> parent = entry.getParentDIEEntry(); + if (!parent) { // Bad data. + consumeError(parent.takeError()); + return std::nullopt; + } + + // Last parent in the chain + if (!parent->has_value()) + break; + + parent_entries.push_back(**parent); + entry = **parent; + } while (parent_entries.size() < max_parents); + + return parent_entries; +} +} // namespace + +void DebugNamesDWARFIndex::GetFullyQualifiedType( + const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback) { + + // Fallback: use the base class implementation. + auto fallback_impl = [&](const DebugNames::Entry &entry) { + return ProcessEntry(entry, [&](DWARFDIE die) { + return GetFullyQualifiedTypeImpl(context, die, callback); + }); + }; + + auto qualified_names = context.GetQualifiedNameAsVector(); + if (qualified_names.empty()) + return; + auto leaf_name = qualified_names.front(); + auto parent_names = llvm::makeArrayRef(qualified_names).drop_front(); + + for (const DebugNames::Entry &entry : + m_debug_names_up->equal_range(leaf_name)) { + if (!isType(entry.tag())) + continue; + + // Grab at most one extra parent, extra parents are not useful to test + // equality. + auto parent_chain = getParentChain(entry, parent_names.size() + 1); + + if (!parent_chain) { + if (!fallback_impl(entry)) + return; + continue; + } + + if (CheckParentChain(parent_names, *parent_chain) && + (!ProcessEntry(entry, callback))) + return; + } +} + +bool DebugNamesDWARFIndex::CheckParentChain( + llvm::ArrayRef<llvm::StringRef> expected_parent_names, + llvm::ArrayRef<DebugNames::Entry> parent_entries) const { + + if (parent_entries.size() != expected_parent_names.size()) + return false; + + auto CompareEntryATName = [this](llvm::StringRef expected_name, + const DebugNames::Entry &entry) { + auto maybe_dieoffset = entry.getDIEUnitOffset(); + if (!maybe_dieoffset) + return false; + auto die_ref = ToDIERef(entry); + if (!die_ref) + return false; + return expected_name == m_debug_info.PeekDIEName(*die_ref); + }; + + for (auto [expected_parent_name, parent_entry] : + llvm::zip_equal(expected_parent_names, parent_entries)) + if (!CompareEntryATName(expected_parent_name, parent_entry)) + return false; + return true; +} + void DebugNamesDWARFIndex::GetTypes( ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) { for (const DebugNames::Entry &entry : diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h index cca0913c4124c9..15eff7a2659633 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -14,6 +14,7 @@ #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "lldb/Utility/ConstString.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" #include <optional> @@ -42,6 +43,11 @@ class DebugNamesDWARFIndex : public DWARFIndex { void GetCompleteObjCClass( ConstString class_name, bool must_be_implementation, llvm::function_ref<bool(DWARFDIE die)> callback) override; + + /// Uses DWARF5's IDX_parent fields, when available, to speed up this query. + void GetFullyQualifiedType( + const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback) override; void GetTypes(ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) override; void GetTypes(const DWARFDeclContext &context, @@ -83,6 +89,9 @@ class DebugNamesDWARFIndex : public DWARFIndex { bool ProcessEntry(const DebugNames::Entry &entry, llvm::function_ref<bool(DWARFDIE die)> callback); + bool CheckParentChain(llvm::ArrayRef<llvm::StringRef> parent_names, + llvm::ArrayRef<DebugNames::Entry> parent_entries) const; + static void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni, llvm::StringRef name); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 447930ffe07b3f..737da7798b82b9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3138,7 +3138,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) { } const DWARFDeclContext die_dwarf_decl_ctx = GetDWARFDeclContext(die); - m_index->GetTypes(die_dwarf_decl_ctx, [&](DWARFDIE type_die) { + m_index->GetFullyQualifiedType(die_dwarf_decl_ctx, [&](DWARFDIE type_die) { // Make sure type_die's language matches the type system we are // looking for. We don't want to find a "Foo" type from Java if we // are looking for a "Foo" type for C, C++, ObjC, or ObjC++. @@ -3165,9 +3165,8 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) { return true; } - DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die); - if (log) { + DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die); GetObjectFile()->GetModule()->LogMessage( log, "SymbolFileDWARF::" @@ -3177,10 +3176,6 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) { type_dwarf_decl_ctx.GetQualifiedName()); } - // Make sure the decl contexts match all the way up - if (die_dwarf_decl_ctx != type_dwarf_decl_ctx) - return true; - Type *resolved_type = ResolveType(type_die, false); if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) return true; diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp index 8497855b2f3db5..5672270ee31f89 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp @@ -7,8 +7,10 @@ //===----------------------------------------------------------------------===// #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" +#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h" #include "TestingSupport/Symbol/YAMLModuleTester.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -104,3 +106,110 @@ TEST(DWARFDIETest, ChildIteration) { DWARFDIE no_children_die(unit, die_child0); EXPECT_TRUE(no_children_die.children().empty()); } + +TEST(DWARFDIETest, DeclContext) { + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_386 +DWARF: + debug_str: + - 'mynamespace' + - 'mystruct' + - 'mytype' + debug_abbrev: + - Table: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Code: 0x00000002 + Tag: DW_TAG_structure_type + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Code: 0x00000003 + Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Code: 0x00000004 + Tag: DW_TAG_namespace + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + debug_info: + - Version: 4 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 # compile_unit + Values: + - Value: 0x000000000000000C + - AbbrCode: 0x00000004 # namespace + Values: + - Value: 0x0000000000000000 # DW_ATE_strp + - AbbrCode: 0x00000002 # structure_type + Values: + - Value: 0x000000000000000c # DW_ATE_strp + - AbbrCode: 0x00000003 # base_type + Values: + - Value: 0x0000000000000015 # DW_ATE_strp + - AbbrCode: 0x00000000 +)"; + + YAMLModuleTester t(yamldata); + DWARFUnit *unit = t.GetDwarfUnit(); + ASSERT_TRUE(unit != nullptr); + auto &ctx = unit->GetSymbolFileDWARF(); + + auto top_level_die = unit->DIE(); + { + ASSERT_TRUE(top_level_die); + auto top_level_ctx = ctx.GetDWARFDeclContext(top_level_die); + auto top_level_name = llvm::StringRef(top_level_ctx.GetQualifiedName()); + ASSERT_EQ(top_level_name, ""); + } + + auto namespace_die = top_level_die.GetFirstChild(); + { + ASSERT_TRUE(namespace_die); + auto namespace_ctx = ctx.GetDWARFDeclContext(namespace_die); + auto namespace_name = llvm::StringRef(namespace_ctx.GetQualifiedName()); + ASSERT_EQ(namespace_name, "::mynamespace"); + auto namespace_names = namespace_ctx.GetQualifiedNameAsVector(); + ASSERT_EQ(namespace_names.size(), 1u); + ASSERT_EQ(namespace_names.front(), "mynamespace"); + } + + auto struct_die = namespace_die.GetFirstChild(); + { + ASSERT_TRUE(struct_die); + auto struct_ctx = ctx.GetDWARFDeclContext(struct_die); + auto struct_name = llvm::StringRef(struct_ctx.GetQualifiedName()); + ASSERT_EQ(struct_name, "mynamespace::mystruct"); + auto struct_names = struct_ctx.GetQualifiedNameAsVector(); + ASSERT_EQ(struct_names.size(), 2u); + ASSERT_EQ(struct_names[0], "mystruct"); + ASSERT_EQ(struct_names[1], "mynamespace"); + } + auto simple_type_die = struct_die.GetFirstChild(); + { + ASSERT_TRUE(simple_type_die); + auto simple_type_ctx = ctx.GetDWARFDeclContext(simple_type_die); + auto simple_type_name = llvm::StringRef(simple_type_ctx.GetQualifiedName()); + ASSERT_EQ(simple_type_name, "mynamespace::mystruct::mytype"); + auto simple_type_names = simple_type_ctx.GetQualifiedNameAsVector(); + ASSERT_EQ(simple_type_names.size(), 3u); + ASSERT_EQ(simple_type_names[0], "mytype"); + ASSERT_EQ(simple_type_names[1], "mystruct"); + ASSERT_EQ(simple_type_names[2], "mynamespace"); + } +} diff --git a/llvm/include/llvm/CodeGen/AccelTable.h b/llvm/include/llvm/CodeGen/AccelTable.h index 6eb09f32f9f951..ddccc4600f14c1 100644 --- a/llvm/include/llvm/CodeGen/AccelTable.h +++ b/llvm/include/llvm/CodeGen/AccelTable.h @@ -143,6 +143,11 @@ class AccelTableBase { std::vector<AccelTableData *> Values; MCSymbol *Sym; + template <typename T = AccelTableData *> auto getValues() const { + return map_range( + Values, [](AccelTableData *Data) { return static_cast<T>(Data); }); + } + #ifndef NDEBUG void print(raw_ostream &OS) const; void dump() const { print(dbgs()); } @@ -261,9 +266,12 @@ class DWARF5AccelTableData : public AccelTableData { DWARF5AccelTableData(const DIE &Die, const uint32_t UnitID, const bool IsTU = false); - DWARF5AccelTableData(const uint64_t DieOffset, const unsigned DieTag, - const unsigned UnitID, const bool IsTU = false) - : OffsetVal(DieOffset), DieTag(DieTag), UnitID(UnitID), IsTU(IsTU) {} + DWARF5AccelTableData(const uint64_t DieOffset, + const std::optional<uint64_t> ParentOffset, + const unsigned DieTag, const unsigned UnitID, + const bool IsTU = false) + : OffsetVal(DieOffset), ParentOffset(ParentOffset), DieTag(DieT... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/77121 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits