[lldb] Refactor variable parsing
Separates the methods for recursive variable parsing in function context and non-recursive parsing of global variables. Differential Revision: https://reviews.llvm.org/D110570
This commit is contained in:
parent
5f7a535330
commit
601168e420
|
|
@ -2135,7 +2135,7 @@ void SymbolFileDWARF::FindGlobalVariables(
|
|||
}
|
||||
}
|
||||
|
||||
ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
|
||||
ParseAndAppendGlobalVariable(sc, die, variables);
|
||||
while (pruned_idx < variables.GetSize()) {
|
||||
VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);
|
||||
if (name_is_mangled ||
|
||||
|
|
@ -2188,7 +2188,7 @@ void SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex,
|
|||
return true;
|
||||
sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
|
||||
|
||||
ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
|
||||
ParseAndAppendGlobalVariable(sc, die, variables);
|
||||
|
||||
return variables.GetSize() - original_size < max_matches;
|
||||
});
|
||||
|
|
@ -3049,8 +3049,8 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
|
|||
/*check_hi_lo_pc=*/true))
|
||||
func_lo_pc = ranges.GetMinRangeBase(0);
|
||||
if (func_lo_pc != LLDB_INVALID_ADDRESS) {
|
||||
const size_t num_variables = ParseVariables(
|
||||
sc, function_die.GetFirstChild(), func_lo_pc, true, true);
|
||||
const size_t num_variables =
|
||||
ParseVariablesInFunctionContext(sc, function_die, func_lo_pc);
|
||||
|
||||
// Let all blocks know they have parse all their variables
|
||||
sc.function->GetBlock(false).SetDidParseVariables(true, true);
|
||||
|
|
@ -3479,81 +3479,39 @@ SymbolFileDWARF::FindBlockContainingSpecification(
|
|||
return DWARFDIE();
|
||||
}
|
||||
|
||||
size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
|
||||
const DWARFDIE &orig_die,
|
||||
const lldb::addr_t func_low_pc,
|
||||
bool parse_siblings, bool parse_children,
|
||||
VariableList *cc_variable_list) {
|
||||
if (!orig_die)
|
||||
return 0;
|
||||
void SymbolFileDWARF::ParseAndAppendGlobalVariable(
|
||||
const SymbolContext &sc, const DWARFDIE &die,
|
||||
VariableList &cc_variable_list) {
|
||||
if (!die)
|
||||
return;
|
||||
|
||||
VariableListSP variable_list_sp;
|
||||
|
||||
size_t vars_added = 0;
|
||||
DWARFDIE die = orig_die;
|
||||
while (die) {
|
||||
dw_tag_t tag = die.Tag();
|
||||
if (tag != DW_TAG_variable && tag != DW_TAG_constant)
|
||||
return;
|
||||
|
||||
// Check to see if we have already parsed this variable or constant?
|
||||
VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
|
||||
if (var_sp) {
|
||||
if (cc_variable_list)
|
||||
cc_variable_list->AddVariableIfUnique(var_sp);
|
||||
} else {
|
||||
cc_variable_list.AddVariableIfUnique(var_sp);
|
||||
return;
|
||||
}
|
||||
|
||||
// We haven't already parsed it, lets do that now.
|
||||
if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
|
||||
(tag == DW_TAG_formal_parameter && sc.function)) {
|
||||
if (variable_list_sp.get() == nullptr) {
|
||||
DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
|
||||
VariableListSP variable_list_sp;
|
||||
DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
|
||||
dw_tag_t parent_tag = sc_parent_die.Tag();
|
||||
switch (parent_tag) {
|
||||
case DW_TAG_compile_unit:
|
||||
case DW_TAG_partial_unit:
|
||||
if (sc.comp_unit != nullptr) {
|
||||
variable_list_sp = sc.comp_unit->GetVariableList(false);
|
||||
if (variable_list_sp.get() == nullptr) {
|
||||
variable_list_sp = std::make_shared<VariableList>();
|
||||
}
|
||||
} else {
|
||||
GetObjectFile()->GetModule()->ReportError(
|
||||
"parent 0x%8.8" PRIx64 " %s with no valid compile unit in "
|
||||
"symbol context for 0x%8.8" PRIx64 " %s.\n",
|
||||
sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(),
|
||||
orig_die.GetID(), orig_die.GetTagAsCString());
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_TAG_subprogram:
|
||||
case DW_TAG_inlined_subroutine:
|
||||
case DW_TAG_lexical_block:
|
||||
if (sc.function != nullptr) {
|
||||
// Check to see if we already have parsed the variables for the
|
||||
// given scope
|
||||
|
||||
Block *block = sc.function->GetBlock(true).FindBlockByID(
|
||||
sc_parent_die.GetID());
|
||||
if (block == nullptr) {
|
||||
// This must be a specification or abstract origin with a
|
||||
// concrete block counterpart in the current function. We need
|
||||
// to find the concrete block so we can correctly add the
|
||||
// variable to it
|
||||
const DWARFDIE concrete_block_die =
|
||||
FindBlockContainingSpecification(
|
||||
GetDIE(sc.function->GetID()),
|
||||
sc_parent_die.GetOffset());
|
||||
if (concrete_block_die)
|
||||
block = sc.function->GetBlock(true).FindBlockByID(
|
||||
concrete_block_die.GetID());
|
||||
}
|
||||
|
||||
if (block != nullptr) {
|
||||
const bool can_create = false;
|
||||
variable_list_sp = block->GetBlockVariableList(can_create);
|
||||
if (variable_list_sp.get() == nullptr) {
|
||||
variable_list_sp = std::make_shared<VariableList>();
|
||||
block->SetVariableList(variable_list_sp);
|
||||
}
|
||||
}
|
||||
sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(), die.GetID(),
|
||||
die.GetTagAsCString());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -3561,35 +3519,97 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
|
|||
GetObjectFile()->GetModule()->ReportError(
|
||||
"didn't find appropriate parent DIE for variable list for "
|
||||
"0x%8.8" PRIx64 " %s.\n",
|
||||
orig_die.GetID(), orig_die.GetTagAsCString());
|
||||
break;
|
||||
}
|
||||
die.GetID(), die.GetTagAsCString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (variable_list_sp) {
|
||||
var_sp = ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS);
|
||||
if (!var_sp)
|
||||
return;
|
||||
|
||||
cc_variable_list.AddVariableIfUnique(var_sp);
|
||||
if (variable_list_sp)
|
||||
variable_list_sp->AddVariableIfUnique(var_sp);
|
||||
}
|
||||
|
||||
size_t SymbolFileDWARF::ParseVariablesInFunctionContext(
|
||||
const SymbolContext &sc, const DWARFDIE &die,
|
||||
const lldb::addr_t func_low_pc) {
|
||||
if (!die || !sc.function)
|
||||
return 0;
|
||||
|
||||
Block *block =
|
||||
sc.function->GetBlock(/*can_create=*/true).FindBlockByID(die.GetID());
|
||||
const bool can_create = false;
|
||||
VariableListSP variable_list_sp = block->GetBlockVariableList(can_create);
|
||||
return ParseVariablesInFunctionContextRecursive(sc, die, func_low_pc,
|
||||
*variable_list_sp);
|
||||
}
|
||||
|
||||
size_t SymbolFileDWARF::ParseVariablesInFunctionContextRecursive(
|
||||
const lldb_private::SymbolContext &sc, const DWARFDIE &die,
|
||||
const lldb::addr_t func_low_pc, VariableList &variable_list) {
|
||||
size_t vars_added = 0;
|
||||
dw_tag_t tag = die.Tag();
|
||||
|
||||
if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
|
||||
(tag == DW_TAG_formal_parameter)) {
|
||||
VariableSP var_sp(ParseVariableDIE(sc, die, func_low_pc));
|
||||
if (var_sp) {
|
||||
variable_list_sp->AddVariableIfUnique(var_sp);
|
||||
if (cc_variable_list)
|
||||
cc_variable_list->AddVariableIfUnique(var_sp);
|
||||
variable_list.AddVariableIfUnique(var_sp);
|
||||
++vars_added;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (tag) {
|
||||
case DW_TAG_subprogram:
|
||||
case DW_TAG_inlined_subroutine:
|
||||
case DW_TAG_lexical_block: {
|
||||
// If we start a new block, compute a new block variable list and recurse.
|
||||
Block *block =
|
||||
sc.function->GetBlock(/*can_create=*/true).FindBlockByID(die.GetID());
|
||||
if (block == nullptr) {
|
||||
// This must be a specification or abstract origin with a
|
||||
// concrete block counterpart in the current function. We need
|
||||
// to find the concrete block so we can correctly add the
|
||||
// variable to it.
|
||||
const DWARFDIE concrete_block_die = FindBlockContainingSpecification(
|
||||
GetDIE(sc.function->GetID()), die.GetOffset());
|
||||
if (concrete_block_die)
|
||||
block = sc.function->GetBlock(/*can_create=*/true)
|
||||
.FindBlockByID(concrete_block_die.GetID());
|
||||
}
|
||||
|
||||
bool skip_children = (sc.function == nullptr && tag == DW_TAG_subprogram);
|
||||
if (block == nullptr)
|
||||
return 0;
|
||||
|
||||
if (!skip_children && parse_children && die.HasChildren()) {
|
||||
vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true,
|
||||
true, cc_variable_list);
|
||||
const bool can_create = false;
|
||||
VariableListSP block_variable_list_sp =
|
||||
block->GetBlockVariableList(can_create);
|
||||
if (block_variable_list_sp.get() == nullptr) {
|
||||
block_variable_list_sp = std::make_shared<VariableList>();
|
||||
block->SetVariableList(block_variable_list_sp);
|
||||
}
|
||||
for (DWARFDIE child = die.GetFirstChild(); child;
|
||||
child = child.GetSibling()) {
|
||||
vars_added += ParseVariablesInFunctionContextRecursive(
|
||||
sc, child, func_low_pc, *block_variable_list_sp);
|
||||
}
|
||||
|
||||
if (parse_siblings)
|
||||
die = die.GetSibling();
|
||||
else
|
||||
die.Clear();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Recurse to children with the same variable list.
|
||||
for (DWARFDIE child = die.GetFirstChild(); child;
|
||||
child = child.GetSibling()) {
|
||||
vars_added += ParseVariablesInFunctionContextRecursive(
|
||||
sc, child, func_low_pc, variable_list);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return vars_added;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -378,11 +378,19 @@ protected:
|
|||
const DWARFDIE &die,
|
||||
const lldb::addr_t func_low_pc);
|
||||
|
||||
size_t ParseVariables(const lldb_private::SymbolContext &sc,
|
||||
const DWARFDIE &orig_die,
|
||||
const lldb::addr_t func_low_pc, bool parse_siblings,
|
||||
bool parse_children,
|
||||
lldb_private::VariableList *cc_variable_list = nullptr);
|
||||
void
|
||||
ParseAndAppendGlobalVariable(const lldb_private::SymbolContext &sc,
|
||||
const DWARFDIE &die,
|
||||
lldb_private::VariableList &cc_variable_list);
|
||||
|
||||
size_t ParseVariablesInFunctionContext(const lldb_private::SymbolContext &sc,
|
||||
const DWARFDIE &die,
|
||||
const lldb::addr_t func_low_pc);
|
||||
|
||||
size_t ParseVariablesInFunctionContextRecursive(
|
||||
const lldb_private::SymbolContext &sc, const DWARFDIE &die,
|
||||
const lldb::addr_t func_low_pc,
|
||||
lldb_private::VariableList &variable_list);
|
||||
|
||||
bool ClassOrStructIsVirtual(const DWARFDIE &die);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue