[llvm] [lldb] [DoNotMerge] DW_IDX_parent full implementation (PR #77121)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 5 09:23:53 PST 2024
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
More information about the llvm-commits
mailing list