aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp
diff options
context:
space:
mode:
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.cpp141
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;
+}