[lldb] Move DWARFDeclContext functions from DWARFDebugInfoEntry to DW… (#95227)

…ARFDIE

This puts them closer to the other two functions doing something very
similar. I've tried to stick to the original logic of the functions as
much as possible, though I did apply some easy simplifications.

The changes in DWARFDeclContext.h are there to make the unit tests
produce more useful error messages.
This commit is contained in:
Pavel Labath
2024-06-13 10:44:45 +02:00
committed by GitHub
parent 65f746e76c
commit b37f9e0bdf
11 changed files with 95 additions and 114 deletions

View File

@@ -2461,7 +2461,7 @@ DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
std::vector<clang::ParmVarDecl *> param_decls;
StreamString sstr;
DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die);
DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
sstr << decl_ctx.GetQualifiedName();
clang::DeclContext *containing_decl_ctx =

View File

@@ -505,12 +505,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 {

View File

@@ -86,6 +86,8 @@ public:
/// using a full or partial CompilerContext array.
std::vector<CompilerContext> GetTypeLookupContext() const;
DWARFDeclContext GetDWARFDeclContext() const;
// Getting attribute values from the DIE.
//
// GetAttributeValueAsXXX() functions should only be used if you are

View File

@@ -610,79 +610,6 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
}
}
DWARFDeclContext
DWARFDebugInfoEntry::GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die,
DWARFUnit *cu) {
DWARFDeclContext dwarf_decl_ctx;
for (;;) {
const dw_tag_t tag = die->Tag();
if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
return dwarf_decl_ctx;
dwarf_decl_ctx.AppendDeclContext(tag, die->GetName(cu));
DWARFDIE parent_decl_ctx_die = die->GetParentDeclContextDIE(cu);
if (!parent_decl_ctx_die || parent_decl_ctx_die.GetDIE() == die)
return dwarf_decl_ctx;
if (parent_decl_ctx_die.Tag() == DW_TAG_compile_unit ||
parent_decl_ctx_die.Tag() == DW_TAG_partial_unit)
return dwarf_decl_ctx;
die = parent_decl_ctx_die.GetDIE();
cu = parent_decl_ctx_die.GetCU();
}
}
DWARFDeclContext DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnit *cu) const {
return GetDWARFDeclContextStatic(this, cu);
}
DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
DWARFAttributes attributes = GetAttributes(cu, Recurse::yes);
return GetParentDeclContextDIE(cu, attributes);
}
DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(
DWARFUnit *cu, const DWARFAttributes &attributes) const {
DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
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.GetDIE() != this) {
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;
}
}
DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification);
if (spec_die) {
DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
if (decl_ctx_die)
return decl_ctx_die;
}
DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin);
if (abs_die) {
DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
if (decl_ctx_die)
return decl_ctx_die;
}
die = die.GetParent();
}
return DWARFDIE();
}
lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const {
return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
}

View File

@@ -157,12 +157,6 @@ public:
return HasChildren() ? this + 1 : nullptr;
}
DWARFDeclContext GetDWARFDeclContext(DWARFUnit *cu) const;
DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const;
DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu,
const DWARFAttributes &attributes) const;
void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; }
void SetParentIndex(uint32_t idx) { m_parent_idx = idx; }
@@ -172,9 +166,6 @@ public:
bool IsGlobalOrStaticScopeVariable() const;
protected:
static DWARFDeclContext
GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu);
// Up to 2TB offset within the .debug_info/.debug_types
dw_offset_t m_offset : DW_DIE_OFFSET_MAX_BITSIZE;
// How many to subtract from "this" to get the parent. If zero this die has no

View File

@@ -12,18 +12,16 @@
using namespace lldb_private::dwarf;
using namespace lldb_private::plugin::dwarf;
/// Returns the name of `entry` if it has one, or the appropriate "anonymous
/// {namespace, class, struct, union}".
static const char *GetName(DWARFDeclContext::Entry entry) {
if (entry.name != nullptr)
return entry.name;
if (entry.tag == DW_TAG_namespace)
const char *DWARFDeclContext::Entry::GetName() const {
if (name != nullptr)
return name;
if (tag == DW_TAG_namespace)
return "(anonymous namespace)";
if (entry.tag == DW_TAG_class_type)
if (tag == DW_TAG_class_type)
return "(anonymous class)";
if (entry.tag == DW_TAG_structure_type)
if (tag == DW_TAG_structure_type)
return "(anonymous struct)";
if (entry.tag == DW_TAG_union_type)
if (tag == DW_TAG_union_type)
return "(anonymous union)";
return "(anonymous)";
}
@@ -46,7 +44,7 @@ const char *DWARFDeclContext::GetQualifiedName() const {
llvm::raw_string_ostream string_stream(m_qualified_name);
llvm::interleave(
llvm::reverse(m_entries), string_stream,
[&](auto entry) { string_stream << GetName(entry); }, "::");
[&](auto entry) { string_stream << entry.GetName(); }, "::");
}
}
}

View File

@@ -9,8 +9,9 @@
#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H
#include "lldb/Utility/ConstString.h"
#include "DWARFDefines.h"
#include "lldb/Utility/ConstString.h"
#include "llvm/ADT/StringExtras.h"
#include <cassert>
#include <string>
@@ -38,6 +39,10 @@ public:
return false;
}
/// Returns the name of this entry if it has one, or the appropriate
/// "anonymous {namespace, class, struct, union}".
const char *GetName() const;
// Test operator
explicit operator bool() const { return tag != 0; }
@@ -83,6 +88,17 @@ public:
m_qualified_name.clear();
}
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const DWARFDeclContext &ctx) {
OS << "DWARFDeclContext{";
llvm::ListSeparator LS;
for (const Entry &e : ctx.m_entries) {
OS << LS << "{" << DW_TAG_value_to_name(e.tag) << ", " << e.GetName()
<< "}";
}
return OS << "}";
}
protected:
typedef std::vector<Entry> collection;
collection m_entries;

View File

@@ -121,8 +121,7 @@ void DWARFIndex::GetFullyQualifiedType(
bool DWARFIndex::GetFullyQualifiedTypeImpl(
const DWARFDeclContext &context, DWARFDIE die,
llvm::function_ref<bool(DWARFDIE die)> callback) {
DWARFDeclContext dwarf_decl_ctx =
die.GetDIE()->GetDWARFDeclContext(die.GetCU());
DWARFDeclContext dwarf_decl_ctx = die.GetDWARFDeclContext();
if (dwarf_decl_ctx == context)
return callback(die);
return true;

View File

@@ -3080,7 +3080,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
template_params = dwarf_ast->GetDIEClassTemplateParams(die);
}
const DWARFDeclContext die_dwarf_decl_ctx = GetDWARFDeclContext(die);
const DWARFDeclContext die_dwarf_decl_ctx = die.GetDWARFDeclContext();
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
@@ -3109,7 +3109,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
}
if (log) {
DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die);
DWARFDeclContext type_dwarf_decl_ctx = type_die.GetDWARFDeclContext();
GetObjectFile()->GetModule()->LogMessage(
log,
"SymbolFileDWARF::"
@@ -3535,8 +3535,9 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
if ((parent_tag == DW_TAG_compile_unit ||
parent_tag == DW_TAG_partial_unit) &&
Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))
mangled =
GetDWARFDeclContext(die).GetQualifiedNameAsConstString().GetCString();
mangled = die.GetDWARFDeclContext()
.GetQualifiedNameAsConstString()
.GetCString();
}
if (tag == DW_TAG_formal_parameter)
@@ -4361,14 +4362,6 @@ SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) {
return CompilerDeclContext();
}
DWARFDeclContext SymbolFileDWARF::GetDWARFDeclContext(const DWARFDIE &die) {
if (!die.IsValid())
return {};
DWARFDeclContext dwarf_decl_ctx =
die.GetDIE()->GetDWARFDeclContext(die.GetCU());
return dwarf_decl_ctx;
}
LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) {
// Note: user languages between lo_user and hi_user must be handled
// explicitly here.

View File

@@ -296,8 +296,6 @@ public:
static CompilerDeclContext GetContainingDeclContext(const DWARFDIE &die);
static DWARFDeclContext GetDWARFDeclContext(const DWARFDIE &die);
static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
static lldb::LanguageType GetLanguage(DWARFUnit &unit);