@@ -1305,76 +1305,121 @@ bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) {
13051305 return true ;
13061306}
13071307
1308- size_t SymbolFileDWARF::ParseBlocksRecursive (CompileUnit &comp_unit,
1309- Block *parent_block, DWARFDIE die ,
1310- addr_t subprogram_low_pc) {
1308+ size_t SymbolFileDWARF::ParseBlocksRecursive (
1309+ lldb_private::CompileUnit &comp_unit, Block *parent_block,
1310+ const DWARFDIE &orig_die, addr_t subprogram_low_pc, uint32_t depth ) {
13111311 size_t blocks_added = 0 ;
1312- for (; die; die = die.GetSibling ()) {
1312+ DWARFDIE die = orig_die;
1313+ while (die) {
13131314 dw_tag_t tag = die.Tag ();
13141315
1315- if (tag != DW_TAG_inlined_subroutine && tag != DW_TAG_lexical_block)
1316- continue ;
1316+ switch (tag) {
1317+ case DW_TAG_inlined_subroutine:
1318+ case DW_TAG_subprogram:
1319+ case DW_TAG_lexical_block: {
1320+ Block *block = nullptr ;
1321+ if (tag == DW_TAG_subprogram) {
1322+ // Skip any DW_TAG_subprogram DIEs that are inside of a normal or
1323+ // inlined functions. These will be parsed on their own as separate
1324+ // entities.
13171325
1318- Block *block = parent_block->CreateChild (die.GetID ()).get ();
1319- DWARFRangeList ranges;
1320- const char *name = nullptr ;
1321- const char *mangled_name = nullptr ;
1322-
1323- std::optional<int > decl_file;
1324- std::optional<int > decl_line;
1325- std::optional<int > decl_column;
1326- std::optional<int > call_file;
1327- std::optional<int > call_line;
1328- std::optional<int > call_column;
1329- if (die.GetDIENamesAndRanges (name, mangled_name, ranges, decl_file,
1330- decl_line, decl_column, call_file, call_line,
1331- call_column, nullptr )) {
1332- const size_t num_ranges = ranges.GetSize ();
1333- for (size_t i = 0 ; i < num_ranges; ++i) {
1334- const DWARFRangeList::Entry &range = ranges.GetEntryRef (i);
1335- const addr_t range_base = range.GetRangeBase ();
1336- if (range_base >= subprogram_low_pc)
1337- block->AddRange (Block::Range (range_base - subprogram_low_pc,
1338- range.GetByteSize ()));
1339- else {
1340- GetObjectFile ()->GetModule ()->ReportError (
1341- " {0:x8}: adding range [{1:x16}-{2:x16}) which has a base "
1342- " that is less than the function's low PC {3:x16}. Please file "
1343- " a bug and attach the file at the "
1344- " start of this error message" ,
1345- block->GetID (), range_base, range.GetRangeEnd (),
1346- subprogram_low_pc);
1347- }
1348- }
1349- block->FinalizeRanges ();
1350-
1351- if (tag != DW_TAG_subprogram &&
1352- (name != nullptr || mangled_name != nullptr )) {
1353- std::unique_ptr<Declaration> decl_up;
1354- if (decl_file || decl_line || decl_column)
1355- decl_up = std::make_unique<Declaration>(
1356- comp_unit.GetSupportFiles ().GetFileSpecAtIndex (
1357- decl_file ? *decl_file : 0 ),
1358- decl_line ? *decl_line : 0 , decl_column ? *decl_column : 0 );
1359-
1360- std::unique_ptr<Declaration> call_up;
1361- if (call_file || call_line || call_column)
1362- call_up = std::make_unique<Declaration>(
1363- comp_unit.GetSupportFiles ().GetFileSpecAtIndex (
1364- call_file ? *call_file : 0 ),
1365- call_line ? *call_line : 0 , call_column ? *call_column : 0 );
1366-
1367- block->SetInlinedFunctionInfo (name, mangled_name, decl_up.get (),
1368- call_up.get ());
1326+ if (depth > 0 )
1327+ break ;
1328+
1329+ block = parent_block;
1330+ } else {
1331+ block = parent_block->CreateChild (die.GetID ()).get ();
13691332 }
1333+ DWARFRangeList ranges;
1334+ const char *name = nullptr ;
1335+ const char *mangled_name = nullptr ;
1336+
1337+ std::optional<int > decl_file;
1338+ std::optional<int > decl_line;
1339+ std::optional<int > decl_column;
1340+ std::optional<int > call_file;
1341+ std::optional<int > call_line;
1342+ std::optional<int > call_column;
1343+ if (die.GetDIENamesAndRanges (name, mangled_name, ranges, decl_file,
1344+ decl_line, decl_column, call_file, call_line,
1345+ call_column, nullptr )) {
1346+ if (tag == DW_TAG_subprogram) {
1347+ assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1348+ subprogram_low_pc = ranges.GetMinRangeBase (0 );
1349+ } else if (tag == DW_TAG_inlined_subroutine) {
1350+ // We get called here for inlined subroutines in two ways. The first
1351+ // time is when we are making the Function object for this inlined
1352+ // concrete instance. Since we're creating a top level block at
1353+ // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we
1354+ // need to adjust the containing address. The second time is when we
1355+ // are parsing the blocks inside the function that contains the
1356+ // inlined concrete instance. Since these will be blocks inside the
1357+ // containing "real" function the offset will be for that function.
1358+ if (subprogram_low_pc == LLDB_INVALID_ADDRESS) {
1359+ subprogram_low_pc = ranges.GetMinRangeBase (0 );
1360+ }
1361+ }
13701362
1371- ++blocks_added;
1363+ const size_t num_ranges = ranges.GetSize ();
1364+ for (size_t i = 0 ; i < num_ranges; ++i) {
1365+ const DWARFRangeList::Entry &range = ranges.GetEntryRef (i);
1366+ const addr_t range_base = range.GetRangeBase ();
1367+ if (range_base >= subprogram_low_pc)
1368+ block->AddRange (Block::Range (range_base - subprogram_low_pc,
1369+ range.GetByteSize ()));
1370+ else {
1371+ GetObjectFile ()->GetModule ()->ReportError (
1372+ " {0:x8}: adding range [{1:x16}-{2:x16}) which has a base "
1373+ " that is less than the function's low PC {3:x16}. Please file "
1374+ " a bug and attach the file at the "
1375+ " start of this error message" ,
1376+ block->GetID (), range_base, range.GetRangeEnd (),
1377+ subprogram_low_pc);
1378+ }
1379+ }
1380+ block->FinalizeRanges ();
1381+
1382+ if (tag != DW_TAG_subprogram &&
1383+ (name != nullptr || mangled_name != nullptr )) {
1384+ std::unique_ptr<Declaration> decl_up;
1385+ if (decl_file || decl_line || decl_column)
1386+ decl_up = std::make_unique<Declaration>(
1387+ comp_unit.GetSupportFiles ().GetFileSpecAtIndex (
1388+ decl_file ? *decl_file : 0 ),
1389+ decl_line ? *decl_line : 0 , decl_column ? *decl_column : 0 );
1390+
1391+ std::unique_ptr<Declaration> call_up;
1392+ if (call_file || call_line || call_column)
1393+ call_up = std::make_unique<Declaration>(
1394+ comp_unit.GetSupportFiles ().GetFileSpecAtIndex (
1395+ call_file ? *call_file : 0 ),
1396+ call_line ? *call_line : 0 , call_column ? *call_column : 0 );
1397+
1398+ block->SetInlinedFunctionInfo (name, mangled_name, decl_up.get (),
1399+ call_up.get ());
1400+ }
1401+
1402+ ++blocks_added;
13721403
1373- if (die.HasChildren ()) {
1374- blocks_added += ParseBlocksRecursive (
1375- comp_unit, block, die.GetFirstChild (), subprogram_low_pc);
1404+ if (die.HasChildren ()) {
1405+ blocks_added +=
1406+ ParseBlocksRecursive (comp_unit, block, die.GetFirstChild (),
1407+ subprogram_low_pc, depth + 1 );
1408+ }
13761409 }
1410+ } break ;
1411+ default :
1412+ break ;
13771413 }
1414+
1415+ // Only parse siblings of the block if we are not at depth zero. A depth of
1416+ // zero indicates we are currently parsing the top level DW_TAG_subprogram
1417+ // DIE
1418+
1419+ if (depth == 0 )
1420+ die.Clear ();
1421+ else
1422+ die = die.GetSibling ();
13781423 }
13791424 return blocks_added;
13801425}
@@ -3195,16 +3240,8 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
31953240 DWARFDIE function_die =
31963241 dwarf_cu->GetNonSkeletonUnit ().GetDIE (function_die_offset);
31973242 if (function_die) {
3198- // We can't use the file address from the Function object as (in the OSO
3199- // case) it will already be remapped to the main module.
3200- DWARFRangeList ranges = function_die.GetDIE ()->GetAttributeAddressRanges (
3201- function_die.GetCU (),
3202- /* check_hi_lo_pc=*/ true );
3203- lldb::addr_t function_file_addr =
3204- ranges.GetMinRangeBase (LLDB_INVALID_ADDRESS);
3205- if (function_file_addr != LLDB_INVALID_ADDRESS)
3206- ParseBlocksRecursive (*comp_unit, &func.GetBlock (false ),
3207- function_die.GetFirstChild (), function_file_addr);
3243+ ParseBlocksRecursive (*comp_unit, &func.GetBlock (false ), function_die,
3244+ LLDB_INVALID_ADDRESS, 0 );
32083245 }
32093246
32103247 return functions_added;
0 commit comments