blob: 409e9bb37ab28b9719b0ca074d8adfc61567431e [file] [log] [blame]
//===-- DWARFASTParser.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DWARFASTParser.h"
#include "DWARFAttribute.h"
#include "DWARFDIE.h"
#include "SymbolFileDWARF.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/StackFrame.h"
#include <optional>
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::dwarf;
using namespace lldb_private::plugin::dwarf;
std::optional<SymbolFile::ArrayInfo>
DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
const ExecutionContext *exe_ctx) {
SymbolFile::ArrayInfo array_info;
if (!parent_die)
return std::nullopt;
for (DWARFDIE die : parent_die.children()) {
const dw_tag_t tag = die.Tag();
if (tag != DW_TAG_subrange_type)
continue;
DWARFAttributes attributes = die.GetAttributes();
if (attributes.Size() == 0)
continue;
uint64_t num_elements = 0;
uint64_t lower_bound = 0;
uint64_t upper_bound = 0;
bool upper_bound_valid = false;
for (size_t i = 0; i < attributes.Size(); ++i) {
const dw_attr_t attr = attributes.AttributeAtIndex(i);
DWARFFormValue form_value;
if (attributes.ExtractFormValueAtIndex(i, form_value)) {
switch (attr) {
case DW_AT_name:
break;
case DW_AT_count:
if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) {
if (var_die.Tag() == DW_TAG_variable)
if (exe_ctx) {
if (auto frame = exe_ctx->GetFrameSP()) {
Status error;
lldb::VariableSP var_sp;
auto valobj_sp = frame->GetValueForVariableExpressionPath(
var_die.GetName(), eNoDynamicValues, 0, var_sp, error);
if (valobj_sp) {
num_elements = valobj_sp->GetValueAsUnsigned(0);
break;
}
}
}
} else
num_elements = form_value.Unsigned();
break;
case DW_AT_bit_stride:
array_info.bit_stride = form_value.Unsigned();
break;
case DW_AT_byte_stride:
array_info.byte_stride = form_value.Unsigned();
break;
case DW_AT_lower_bound:
lower_bound = form_value.Unsigned();
break;
case DW_AT_upper_bound:
upper_bound_valid = true;
upper_bound = form_value.Unsigned();
break;
default:
break;
}
}
}
if (num_elements == 0) {
if (upper_bound_valid && upper_bound >= lower_bound)
num_elements = upper_bound - lower_bound + 1;
}
array_info.element_orders.push_back(num_elements);
}
return array_info;
}
Type *DWARFASTParser::GetTypeForDIE(const DWARFDIE &die) {
if (!die)
return nullptr;
SymbolFileDWARF *dwarf = die.GetDWARF();
if (!dwarf)
return nullptr;
DWARFAttributes attributes = die.GetAttributes();
if (attributes.Size() == 0)
return nullptr;
DWARFFormValue type_die_form;
for (size_t i = 0; i < attributes.Size(); ++i) {
dw_attr_t attr = attributes.AttributeAtIndex(i);
DWARFFormValue form_value;
if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value))
return dwarf->ResolveTypeUID(form_value.Reference(), true);
}
return nullptr;
}
AccessType
DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) {
switch (dwarf_accessibility) {
case DW_ACCESS_public:
return eAccessPublic;
case DW_ACCESS_private:
return eAccessPrivate;
case DW_ACCESS_protected:
return eAccessProtected;
default:
break;
}
return eAccessNone;
}