summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
diff options
context:
space:
mode:
authorKoakuma <koachan@protonmail.com>2024-07-08 19:19:54 +0700
committerKoakuma <koachan@protonmail.com>2024-07-08 19:19:54 +0700
commit5c4fdc2fd5898ebd9e89999a4f4b8aa289ca637f (patch)
treef3b92a07f3dfc6e70f36d1000605f36a3c15af46 /lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
parentdbda8e2f2cd8764e0badd983915d62a2c3377f4d (diff)
parente9b8cd0c806db00f0981fb36717077c941426302 (diff)
Created using spr 1.3.5 [skip ci]
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp98
1 files changed, 72 insertions, 26 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 7cf92adc6ef5..fb32e2adeb3f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -367,20 +367,6 @@ lldb_private::Type *DWARFDIE::ResolveTypeUID(const DWARFDIE &die) const {
return nullptr;
}
-std::vector<DWARFDIE> DWARFDIE::GetDeclContextDIEs() const {
- if (!IsValid())
- return {};
-
- std::vector<DWARFDIE> result;
- DWARFDIE parent = GetParentDeclContextDIE();
- while (parent.IsValid() && parent.GetDIE() != GetDIE()) {
- result.push_back(std::move(parent));
- parent = parent.GetParentDeclContextDIE();
- }
-
- return result;
-}
-
static void GetDeclContextImpl(DWARFDIE die,
llvm::SmallSet<lldb::user_id_t, 4> &seen,
std::vector<CompilerContext> &context) {
@@ -408,15 +394,13 @@ static void GetDeclContextImpl(DWARFDIE die,
case DW_TAG_namespace:
push_ctx(CompilerContextKind::Namespace, die.GetName());
break;
+ case DW_TAG_class_type:
case DW_TAG_structure_type:
- push_ctx(CompilerContextKind::Struct, die.GetName());
+ push_ctx(CompilerContextKind::ClassOrStruct, die.GetName());
break;
case DW_TAG_union_type:
push_ctx(CompilerContextKind::Union, die.GetName());
break;
- case DW_TAG_class_type:
- push_ctx(CompilerContextKind::Class, die.GetName());
- break;
case DW_TAG_enumeration_type:
push_ctx(CompilerContextKind::Enum, die.GetName());
break;
@@ -470,15 +454,13 @@ static void GetTypeLookupContextImpl(DWARFDIE die,
case DW_TAG_namespace:
push_ctx(CompilerContextKind::Namespace, die.GetName());
break;
+ case DW_TAG_class_type:
case DW_TAG_structure_type:
- push_ctx(CompilerContextKind::Struct, die.GetName());
+ push_ctx(CompilerContextKind::ClassOrStruct, die.GetName());
break;
case DW_TAG_union_type:
push_ctx(CompilerContextKind::Union, die.GetName());
break;
- case DW_TAG_class_type:
- push_ctx(CompilerContextKind::Class, die.GetName());
- break;
case DW_TAG_enumeration_type:
push_ctx(CompilerContextKind::Enum, die.GetName());
break;
@@ -491,6 +473,18 @@ static void GetTypeLookupContextImpl(DWARFDIE die,
case DW_TAG_base_type:
push_ctx(CompilerContextKind::Builtin, name);
break;
+ // If any of the tags below appear in the parent chain, stop the decl
+ // context and return. Prior to these being in here, if a type existed in a
+ // namespace "a" like "a::my_struct", but we also have a function in that
+ // same namespace "a" which contained a type named "my_struct", both would
+ // return "a::my_struct" as the declaration context since the
+ // DW_TAG_subprogram would be skipped and its parent would be found.
+ case DW_TAG_compile_unit:
+ case DW_TAG_type_unit:
+ case DW_TAG_subprogram:
+ case DW_TAG_lexical_block:
+ case DW_TAG_inlined_subroutine:
+ return;
default:
break;
}
@@ -507,12 +501,64 @@ std::vector<CompilerContext> DWARFDIE::GetTypeLookupContext() const {
return context;
}
+static DWARFDeclContext GetDWARFDeclContextImpl(DWARFDIE die) {
+ DWARFDeclContext dwarf_decl_ctx;
+ while (die) {
+ const dw_tag_t tag = die.Tag();
+ if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
+ break;
+ dwarf_decl_ctx.AppendDeclContext(tag, die.GetName());
+ DWARFDIE parent_decl_ctx_die = die.GetParentDeclContextDIE();
+ if (parent_decl_ctx_die == die)
+ break;
+ die = parent_decl_ctx_die;
+ }
+ return dwarf_decl_ctx;
+}
+
+DWARFDeclContext DWARFDIE::GetDWARFDeclContext() const {
+ return GetDWARFDeclContextImpl(*this);
+}
+
+static DWARFDIE GetParentDeclContextDIEImpl(DWARFDIE die) {
+ DWARFDIE orig_die = die;
+ while (die) {
+ // If this is the original DIE that we are searching for a declaration for,
+ // then don't look in the cache as we don't want our own decl context to be
+ // our decl context...
+ if (die != orig_die) {
+ switch (die.Tag()) {
+ case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
+ case DW_TAG_namespace:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type:
+ return die;
+
+ default:
+ break;
+ }
+ }
+
+ if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) {
+ if (DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE())
+ return decl_ctx_die;
+ }
+
+ if (DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin)) {
+ if (DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE())
+ return decl_ctx_die;
+ }
+
+ die = die.GetParent();
+ }
+ return DWARFDIE();
+}
+
DWARFDIE
DWARFDIE::GetParentDeclContextDIE() const {
- if (IsValid())
- return m_die->GetParentDeclContextDIE(m_cu);
- else
- return DWARFDIE();
+ return GetParentDeclContextDIEImpl(*this);
}
bool DWARFDIE::IsStructUnionOrClass() const {