diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp new file mode 100644 index 000000000000..409e9bb37ab2 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp @@ -0,0 +1,141 @@ +//===-- 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; +} |