blob: f1048c86feab5b9251d4b319e8215afc34aadc63 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/debug/zxdb/symbols/dwarf_die_scanner.h"
#include <lib/syslog/cpp/macros.h>
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "src/developer/debug/zxdb/symbols/dwarf_tag.h"
namespace zxdb {
DwarfDieScanner2::DwarfDieScanner2(llvm::DWARFUnit* unit) : unit_(unit) {
die_count_ = unit_->getNumDIEs();
// We prefer not to reallocate and normally the C++ component depth is < 8.
tree_stack_.reserve(8);
}
DwarfDieScanner2::~DwarfDieScanner2() = default;
const llvm::DWARFDebugInfoEntry* DwarfDieScanner2::Prepare() {
if (done())
return nullptr;
cur_die_ = unit_->getDIEAtIndex(die_index_).getDebugInfoEntry();
uint32_t parent_idx = cur_die_->getParentIdx().getValueOr(kNoParent);
while (!tree_stack_.empty() && tree_stack_.back().index != parent_idx)
tree_stack_.pop_back();
tree_stack_.emplace_back(die_index_, false);
// Fix up the inside function flag.
switch (static_cast<DwarfTag>(cur_die_->getTag())) {
case DwarfTag::kLexicalBlock:
case DwarfTag::kVariable:
// Inherits from previous. For a block and a variable there should always be the parent,
// since at least there's the unit root DIE.
FX_DCHECK(tree_stack_.size() >= 2);
tree_stack_.back().inside_function = tree_stack_[tree_stack_.size() - 2].inside_function;
break;
case DwarfTag::kSubprogram:
case DwarfTag::kInlinedSubroutine:
tree_stack_.back().inside_function = true;
break;
default:
tree_stack_.back().inside_function = false;
break;
}
return cur_die_;
}
void DwarfDieScanner2::Advance() {
FX_DCHECK(!done());
die_index_++;
}
uint32_t DwarfDieScanner2::GetParentIndex(uint32_t index) const {
return unit_->getDIEAtIndex(index).getDebugInfoEntry()->getParentIdx().getValueOr(kNoParent);
}
} // namespace zxdb