Skip to content

Commit 601168e

Browse files
Jaroslav Sevcikjaro-sevcik
authored andcommitted
[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
1 parent 5f7a535 commit 601168e

File tree

2 files changed

+133
-105
lines changed

2 files changed

+133
-105
lines changed

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 120 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -2135,7 +2135,7 @@ void SymbolFileDWARF::FindGlobalVariables(
21352135
}
21362136
}
21372137

2138-
ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
2138+
ParseAndAppendGlobalVariable(sc, die, variables);
21392139
while (pruned_idx < variables.GetSize()) {
21402140
VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);
21412141
if (name_is_mangled ||
@@ -2188,7 +2188,7 @@ void SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
21882188
return true;
21892189
sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
21902190

2191-
ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
2191+
ParseAndAppendGlobalVariable(sc, die, variables);
21922192

21932193
return variables.GetSize() - original_size < max_matches;
21942194
});
@@ -3049,8 +3049,8 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
30493049
/*check_hi_lo_pc=*/true))
30503050
func_lo_pc = ranges.GetMinRangeBase(0);
30513051
if (func_lo_pc != LLDB_INVALID_ADDRESS) {
3052-
const size_t num_variables = ParseVariables(
3053-
sc, function_die.GetFirstChild(), func_lo_pc, true, true);
3052+
const size_t num_variables =
3053+
ParseVariablesInFunctionContext(sc, function_die, func_lo_pc);
30543054

30553055
// Let all blocks know they have parse all their variables
30563056
sc.function->GetBlock(false).SetDidParseVariables(true, true);
@@ -3479,117 +3479,137 @@ SymbolFileDWARF::FindBlockContainingSpecification(
34793479
return DWARFDIE();
34803480
}
34813481

3482-
size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
3483-
const DWARFDIE &orig_die,
3484-
const lldb::addr_t func_low_pc,
3485-
bool parse_siblings, bool parse_children,
3486-
VariableList *cc_variable_list) {
3487-
if (!orig_die)
3488-
return 0;
3482+
void SymbolFileDWARF::ParseAndAppendGlobalVariable(
3483+
const SymbolContext &sc, const DWARFDIE &die,
3484+
VariableList &cc_variable_list) {
3485+
if (!die)
3486+
return;
34893487

3488+
dw_tag_t tag = die.Tag();
3489+
if (tag != DW_TAG_variable && tag != DW_TAG_constant)
3490+
return;
3491+
3492+
// Check to see if we have already parsed this variable or constant?
3493+
VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
3494+
if (var_sp) {
3495+
cc_variable_list.AddVariableIfUnique(var_sp);
3496+
return;
3497+
}
3498+
3499+
// We haven't already parsed it, lets do that now.
34903500
VariableListSP variable_list_sp;
3501+
DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
3502+
dw_tag_t parent_tag = sc_parent_die.Tag();
3503+
switch (parent_tag) {
3504+
case DW_TAG_compile_unit:
3505+
case DW_TAG_partial_unit:
3506+
if (sc.comp_unit != nullptr) {
3507+
variable_list_sp = sc.comp_unit->GetVariableList(false);
3508+
} else {
3509+
GetObjectFile()->GetModule()->ReportError(
3510+
"parent 0x%8.8" PRIx64 " %s with no valid compile unit in "
3511+
"symbol context for 0x%8.8" PRIx64 " %s.\n",
3512+
sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(), die.GetID(),
3513+
die.GetTagAsCString());
3514+
return;
3515+
}
3516+
break;
3517+
3518+
default:
3519+
GetObjectFile()->GetModule()->ReportError(
3520+
"didn't find appropriate parent DIE for variable list for "
3521+
"0x%8.8" PRIx64 " %s.\n",
3522+
die.GetID(), die.GetTagAsCString());
3523+
return;
3524+
}
3525+
3526+
var_sp = ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS);
3527+
if (!var_sp)
3528+
return;
3529+
3530+
cc_variable_list.AddVariableIfUnique(var_sp);
3531+
if (variable_list_sp)
3532+
variable_list_sp->AddVariableIfUnique(var_sp);
3533+
}
3534+
3535+
size_t SymbolFileDWARF::ParseVariablesInFunctionContext(
3536+
const SymbolContext &sc, const DWARFDIE &die,
3537+
const lldb::addr_t func_low_pc) {
3538+
if (!die || !sc.function)
3539+
return 0;
34913540

3541+
Block *block =
3542+
sc.function->GetBlock(/*can_create=*/true).FindBlockByID(die.GetID());
3543+
const bool can_create = false;
3544+
VariableListSP variable_list_sp = block->GetBlockVariableList(can_create);
3545+
return ParseVariablesInFunctionContextRecursive(sc, die, func_low_pc,
3546+
*variable_list_sp);
3547+
}
3548+
3549+
size_t SymbolFileDWARF::ParseVariablesInFunctionContextRecursive(
3550+
const lldb_private::SymbolContext &sc, const DWARFDIE &die,
3551+
const lldb::addr_t func_low_pc, VariableList &variable_list) {
34923552
size_t vars_added = 0;
3493-
DWARFDIE die = orig_die;
3494-
while (die) {
3495-
dw_tag_t tag = die.Tag();
3553+
dw_tag_t tag = die.Tag();
34963554

3497-
// Check to see if we have already parsed this variable or constant?
3498-
VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
3555+
if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
3556+
(tag == DW_TAG_formal_parameter)) {
3557+
VariableSP var_sp(ParseVariableDIE(sc, die, func_low_pc));
34993558
if (var_sp) {
3500-
if (cc_variable_list)
3501-
cc_variable_list->AddVariableIfUnique(var_sp);
3502-
} else {
3503-
// We haven't already parsed it, lets do that now.
3504-
if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
3505-
(tag == DW_TAG_formal_parameter && sc.function)) {
3506-
if (variable_list_sp.get() == nullptr) {
3507-
DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
3508-
dw_tag_t parent_tag = sc_parent_die.Tag();
3509-
switch (parent_tag) {
3510-
case DW_TAG_compile_unit:
3511-
case DW_TAG_partial_unit:
3512-
if (sc.comp_unit != nullptr) {
3513-
variable_list_sp = sc.comp_unit->GetVariableList(false);
3514-
if (variable_list_sp.get() == nullptr) {
3515-
variable_list_sp = std::make_shared<VariableList>();
3516-
}
3517-
} else {
3518-
GetObjectFile()->GetModule()->ReportError(
3519-
"parent 0x%8.8" PRIx64 " %s with no valid compile unit in "
3520-
"symbol context for 0x%8.8" PRIx64 " %s.\n",
3521-
sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(),
3522-
orig_die.GetID(), orig_die.GetTagAsCString());
3523-
}
3524-
break;
3525-
3526-
case DW_TAG_subprogram:
3527-
case DW_TAG_inlined_subroutine:
3528-
case DW_TAG_lexical_block:
3529-
if (sc.function != nullptr) {
3530-
// Check to see if we already have parsed the variables for the
3531-
// given scope
3532-
3533-
Block *block = sc.function->GetBlock(true).FindBlockByID(
3534-
sc_parent_die.GetID());
3535-
if (block == nullptr) {
3536-
// This must be a specification or abstract origin with a
3537-
// concrete block counterpart in the current function. We need
3538-
// to find the concrete block so we can correctly add the
3539-
// variable to it
3540-
const DWARFDIE concrete_block_die =
3541-
FindBlockContainingSpecification(
3542-
GetDIE(sc.function->GetID()),
3543-
sc_parent_die.GetOffset());
3544-
if (concrete_block_die)
3545-
block = sc.function->GetBlock(true).FindBlockByID(
3546-
concrete_block_die.GetID());
3547-
}
3559+
variable_list.AddVariableIfUnique(var_sp);
3560+
++vars_added;
3561+
}
3562+
}
35483563

3549-
if (block != nullptr) {
3550-
const bool can_create = false;
3551-
variable_list_sp = block->GetBlockVariableList(can_create);
3552-
if (variable_list_sp.get() == nullptr) {
3553-
variable_list_sp = std::make_shared<VariableList>();
3554-
block->SetVariableList(variable_list_sp);
3555-
}
3556-
}
3557-
}
3558-
break;
3564+
switch (tag) {
3565+
case DW_TAG_subprogram:
3566+
case DW_TAG_inlined_subroutine:
3567+
case DW_TAG_lexical_block: {
3568+
// If we start a new block, compute a new block variable list and recurse.
3569+
Block *block =
3570+
sc.function->GetBlock(/*can_create=*/true).FindBlockByID(die.GetID());
3571+
if (block == nullptr) {
3572+
// This must be a specification or abstract origin with a
3573+
// concrete block counterpart in the current function. We need
3574+
// to find the concrete block so we can correctly add the
3575+
// variable to it.
3576+
const DWARFDIE concrete_block_die = FindBlockContainingSpecification(
3577+
GetDIE(sc.function->GetID()), die.GetOffset());
3578+
if (concrete_block_die)
3579+
block = sc.function->GetBlock(/*can_create=*/true)
3580+
.FindBlockByID(concrete_block_die.GetID());
3581+
}
35593582

3560-
default:
3561-
GetObjectFile()->GetModule()->ReportError(
3562-
"didn't find appropriate parent DIE for variable list for "
3563-
"0x%8.8" PRIx64 " %s.\n",
3564-
orig_die.GetID(), orig_die.GetTagAsCString());
3565-
break;
3566-
}
3567-
}
3583+
if (block == nullptr)
3584+
return 0;
35683585

3569-
if (variable_list_sp) {
3570-
VariableSP var_sp(ParseVariableDIE(sc, die, func_low_pc));
3571-
if (var_sp) {
3572-
variable_list_sp->AddVariableIfUnique(var_sp);
3573-
if (cc_variable_list)
3574-
cc_variable_list->AddVariableIfUnique(var_sp);
3575-
++vars_added;
3576-
}
3577-
}
3578-
}
3586+
const bool can_create = false;
3587+
VariableListSP block_variable_list_sp =
3588+
block->GetBlockVariableList(can_create);
3589+
if (block_variable_list_sp.get() == nullptr) {
3590+
block_variable_list_sp = std::make_shared<VariableList>();
3591+
block->SetVariableList(block_variable_list_sp);
3592+
}
3593+
for (DWARFDIE child = die.GetFirstChild(); child;
3594+
child = child.GetSibling()) {
3595+
vars_added += ParseVariablesInFunctionContextRecursive(
3596+
sc, child, func_low_pc, *block_variable_list_sp);
35793597
}
35803598

3581-
bool skip_children = (sc.function == nullptr && tag == DW_TAG_subprogram);
3599+
break;
3600+
}
35823601

3583-
if (!skip_children && parse_children && die.HasChildren()) {
3584-
vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true,
3585-
true, cc_variable_list);
3602+
default:
3603+
// Recurse to children with the same variable list.
3604+
for (DWARFDIE child = die.GetFirstChild(); child;
3605+
child = child.GetSibling()) {
3606+
vars_added += ParseVariablesInFunctionContextRecursive(
3607+
sc, child, func_low_pc, variable_list);
35863608
}
35873609

3588-
if (parse_siblings)
3589-
die = die.GetSibling();
3590-
else
3591-
die.Clear();
3610+
break;
35923611
}
3612+
35933613
return vars_added;
35943614
}
35953615

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,11 +378,19 @@ class SymbolFileDWARF : public lldb_private::SymbolFile,
378378
const DWARFDIE &die,
379379
const lldb::addr_t func_low_pc);
380380

381-
size_t ParseVariables(const lldb_private::SymbolContext &sc,
382-
const DWARFDIE &orig_die,
383-
const lldb::addr_t func_low_pc, bool parse_siblings,
384-
bool parse_children,
385-
lldb_private::VariableList *cc_variable_list = nullptr);
381+
void
382+
ParseAndAppendGlobalVariable(const lldb_private::SymbolContext &sc,
383+
const DWARFDIE &die,
384+
lldb_private::VariableList &cc_variable_list);
385+
386+
size_t ParseVariablesInFunctionContext(const lldb_private::SymbolContext &sc,
387+
const DWARFDIE &die,
388+
const lldb::addr_t func_low_pc);
389+
390+
size_t ParseVariablesInFunctionContextRecursive(
391+
const lldb_private::SymbolContext &sc, const DWARFDIE &die,
392+
const lldb::addr_t func_low_pc,
393+
lldb_private::VariableList &variable_list);
386394

387395
bool ClassOrStructIsVirtual(const DWARFDIE &die);
388396

0 commit comments

Comments
 (0)