Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lldb/DWARF] Remove parsing recursion when searching for definition DIEs #96484

Merged
merged 2 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 107 additions & 103 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Large diffs are not rendered by default.

187 changes: 91 additions & 96 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3038,118 +3038,113 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
return type_sp;
}

TypeSP
SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
TypeSP type_sp;
DWARFDIE
SymbolFileDWARF::FindDefinitionDIE(const DWARFDIE &die) {
if (!die.GetName())
return {};

if (die.GetName()) {
const dw_tag_t tag = die.Tag();
const dw_tag_t tag = die.Tag();

Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
if (log) {
GetObjectFile()->GetModule()->LogMessage(
log,
"SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag={0} "
"({1}), name='{2}')",
DW_TAG_value_to_name(tag), tag, die.GetName());
}
Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
if (log) {
GetObjectFile()->GetModule()->LogMessage(
log,
"SymbolFileDWARF::FindDefinitionDIE(tag={0} "
"({1}), name='{2}')",
DW_TAG_value_to_name(tag), tag, die.GetName());
}

// Get the type system that we are looking to find a type for. We will
// use this to ensure any matches we find are in a language that this
// type system supports
const LanguageType language = GetLanguage(*die.GetCU());
TypeSystemSP type_system = nullptr;
if (language != eLanguageTypeUnknown) {
auto type_system_or_err = GetTypeSystemForLanguage(language);
if (auto err = type_system_or_err.takeError()) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
"Cannot get TypeSystem for language {1}: {0}",
Language::GetNameForLanguageType(language));
} else {
type_system = *type_system_or_err;
}
// Get the type system that we are looking to find a type for. We will
// use this to ensure any matches we find are in a language that this
// type system supports
const LanguageType language = GetLanguage(*die.GetCU());
TypeSystemSP type_system = nullptr;
if (language != eLanguageTypeUnknown) {
auto type_system_or_err = GetTypeSystemForLanguage(language);
if (auto err = type_system_or_err.takeError()) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
"Cannot get TypeSystem for language {1}: {0}",
Language::GetNameForLanguageType(language));
} else {
type_system = *type_system_or_err;
}
}

// See comments below about -gsimple-template-names for why we attempt to
// compute missing template parameter names.
std::vector<std::string> template_params;
DWARFDeclContext die_dwarf_decl_ctx;
DWARFASTParser *dwarf_ast = type_system ? type_system->GetDWARFParser() : nullptr;
for (DWARFDIE ctx_die = die; ctx_die && !isUnitType(ctx_die.Tag());
ctx_die = ctx_die.GetParentDeclContextDIE()) {
die_dwarf_decl_ctx.AppendDeclContext(ctx_die.Tag(), ctx_die.GetName());
template_params.push_back(
(ctx_die.IsStructUnionOrClass() && dwarf_ast)
? dwarf_ast->GetDIEClassTemplateParams(ctx_die)
: "");
}
const bool any_template_params = llvm::any_of(
template_params, [](llvm::StringRef p) { return !p.empty(); });

auto die_matches = [&](DWARFDIE type_die) {
// Resolve the type if both have the same tag or {class, struct} tags.
const bool tag_matches =
type_die.Tag() == tag ||
(IsStructOrClassTag(type_die.Tag()) && IsStructOrClassTag(tag));
if (!tag_matches)
return false;
if (any_template_params) {
size_t pos = 0;
for (DWARFDIE ctx_die = type_die;
ctx_die && !isUnitType(ctx_die.Tag()) &&
pos < template_params.size();
ctx_die = ctx_die.GetParentDeclContextDIE(), ++pos) {
if (template_params[pos].empty())
continue;
if (template_params[pos] != dwarf_ast->GetDIEClassTemplateParams(ctx_die))
return false;
}
if (pos != template_params.size())
// See comments below about -gsimple-template-names for why we attempt to
// compute missing template parameter names.
std::vector<std::string> template_params;
DWARFDeclContext die_dwarf_decl_ctx;
DWARFASTParser *dwarf_ast =
type_system ? type_system->GetDWARFParser() : nullptr;
for (DWARFDIE ctx_die = die; ctx_die && !isUnitType(ctx_die.Tag());
ctx_die = ctx_die.GetParentDeclContextDIE()) {
die_dwarf_decl_ctx.AppendDeclContext(ctx_die.Tag(), ctx_die.GetName());
template_params.push_back(
(ctx_die.IsStructUnionOrClass() && dwarf_ast)
? dwarf_ast->GetDIEClassTemplateParams(ctx_die)
: "");
}
const bool any_template_params = llvm::any_of(
template_params, [](llvm::StringRef p) { return !p.empty(); });

auto die_matches = [&](DWARFDIE type_die) {
// Resolve the type if both have the same tag or {class, struct} tags.
const bool tag_matches =
type_die.Tag() == tag ||
(IsStructOrClassTag(type_die.Tag()) && IsStructOrClassTag(tag));
if (!tag_matches)
return false;
if (any_template_params) {
size_t pos = 0;
for (DWARFDIE ctx_die = type_die; ctx_die && !isUnitType(ctx_die.Tag()) &&
pos < template_params.size();
ctx_die = ctx_die.GetParentDeclContextDIE(), ++pos) {
if (template_params[pos].empty())
continue;
if (template_params[pos] !=
dwarf_ast->GetDIEClassTemplateParams(ctx_die))
return false;
}
if (pos != template_params.size())
return false;
}
return true;
};
DWARFDIE result;
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++.
if (type_system &&
!type_system->SupportsLanguage(GetLanguage(*type_die.GetCU())))
return true;
};
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++.
if (type_system &&
!type_system->SupportsLanguage(GetLanguage(*type_die.GetCU())))
return true;

if (!die_matches(type_die)) {
if (log) {
GetObjectFile()->GetModule()->LogMessage(
log,
"SymbolFileDWARF::"
"FindDefinitionTypeForDWARFDeclContext(tag={0} ({1}), "
"name='{2}') ignoring die={3:x16} ({4})",
DW_TAG_value_to_name(tag), tag, die.GetName(),
type_die.GetOffset(), type_die.GetName());
}
return true;
}

if (!die_matches(type_die)) {
if (log) {
DWARFDeclContext type_dwarf_decl_ctx = type_die.GetDWARFDeclContext();
GetObjectFile()->GetModule()->LogMessage(
log,
"SymbolFileDWARF::"
"FindDefinitionTypeForDWARFDeclContext(tag={0} ({1}), name='{2}') "
"trying die={3:x16} ({4})",
"SymbolFileDWARF::FindDefinitionDIE(tag={0} ({1}), "
"name='{2}') ignoring die={3:x16} ({4})",
DW_TAG_value_to_name(tag), tag, die.GetName(), type_die.GetOffset(),
type_dwarf_decl_ctx.GetQualifiedName());
type_die.GetName());
}
return true;
}

Type *resolved_type = ResolveType(type_die, false);
if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
return true;
if (log) {
DWARFDeclContext type_dwarf_decl_ctx = type_die.GetDWARFDeclContext();
GetObjectFile()->GetModule()->LogMessage(
log,
"SymbolFileDWARF::FindDefinitionTypeDIE(tag={0} ({1}), name='{2}') "
"trying die={3:x16} ({4})",
DW_TAG_value_to_name(tag), tag, die.GetName(), type_die.GetOffset(),
type_dwarf_decl_ctx.GetQualifiedName());
}

type_sp = resolved_type->shared_from_this();
return false;
});
}
return type_sp;
result = type_die;
return false;
});
return result;
}

TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
Expand Down
3 changes: 1 addition & 2 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,7 @@ class SymbolFileDWARF : public SymbolFileCommon {

SymbolFileDWARFDebugMap *GetDebugMapSymfile();

virtual lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die);
virtual DWARFDIE FindDefinitionDIE(const DWARFDIE &die);

virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
const DWARFDIE &die, ConstString type_name, bool must_be_implementation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1147,14 +1147,13 @@ SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(
return {};
}

TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext(
const DWARFDIE &die) {
TypeSP type_sp;
DWARFDIE SymbolFileDWARFDebugMap::FindDefinitionDIE(const DWARFDIE &die) {
DWARFDIE result;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die);
return type_sp ? IterationAction::Stop : IterationAction::Continue;
result = oso_dwarf->FindDefinitionDIE(die);
return result ? IterationAction::Stop : IterationAction::Continue;
});
return type_sp;
return result;
}

bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {

CompileUnitInfo *GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf);

lldb::TypeSP FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die);
DWARFDIE FindDefinitionDIE(const DWARFDIE &die);

bool Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF *skip_dwarf_oso);

Expand Down
5 changes: 2 additions & 3 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {
return GetBaseSymbolFile().GetUniqueDWARFASTTypeMap();
}

lldb::TypeSP
SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
return GetBaseSymbolFile().FindDefinitionTypeForDWARFDeclContext(die);
DWARFDIE SymbolFileDWARFDwo::FindDefinitionDIE(const DWARFDIE &die) {
return GetBaseSymbolFile().FindDefinitionDIE(die);
}

lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE(
Expand Down
3 changes: 1 addition & 2 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ class SymbolFileDWARFDwo : public SymbolFileDWARF {

UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() override;

lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) override;
DWARFDIE FindDefinitionDIE(const DWARFDIE &die) override;

lldb::TypeSP
FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE &die,
Expand Down
Loading