1f9b8f422SLuís Ferreira //===-- DWARFASTParser.cpp ------------------------------------------------===//
2f9b8f422SLuís Ferreira //
3f9b8f422SLuís Ferreira // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f9b8f422SLuís Ferreira // See https://llvm.org/LICENSE.txt for license information.
5f9b8f422SLuís Ferreira // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f9b8f422SLuís Ferreira //
7f9b8f422SLuís Ferreira //===----------------------------------------------------------------------===//
8f9b8f422SLuís Ferreira 
9f9b8f422SLuís Ferreira #include "DWARFASTParser.h"
10f9b8f422SLuís Ferreira #include "DWARFAttribute.h"
11f9b8f422SLuís Ferreira #include "DWARFDIE.h"
12f9b8f422SLuís Ferreira 
13f9b8f422SLuís Ferreira #include "lldb/Core/ValueObject.h"
14f9b8f422SLuís Ferreira #include "lldb/Symbol/SymbolFile.h"
15f9b8f422SLuís Ferreira #include "lldb/Target/StackFrame.h"
16f9b8f422SLuís Ferreira 
17f9b8f422SLuís Ferreira using namespace lldb;
18f9b8f422SLuís Ferreira using namespace lldb_private;
19f9b8f422SLuís Ferreira using namespace lldb_private::dwarf;
20f9b8f422SLuís Ferreira 
21f9b8f422SLuís Ferreira llvm::Optional<SymbolFile::ArrayInfo>
ParseChildArrayInfo(const DWARFDIE & parent_die,const ExecutionContext * exe_ctx)22f9b8f422SLuís Ferreira DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
23f9b8f422SLuís Ferreira                                     const ExecutionContext *exe_ctx) {
24f9b8f422SLuís Ferreira   SymbolFile::ArrayInfo array_info;
25f9b8f422SLuís Ferreira   if (!parent_die)
26f9b8f422SLuís Ferreira     return llvm::None;
27f9b8f422SLuís Ferreira 
28f9b8f422SLuís Ferreira   for (DWARFDIE die : parent_die.children()) {
29f9b8f422SLuís Ferreira     const dw_tag_t tag = die.Tag();
30f9b8f422SLuís Ferreira     if (tag != DW_TAG_subrange_type)
31f9b8f422SLuís Ferreira       continue;
32f9b8f422SLuís Ferreira 
33f9b8f422SLuís Ferreira     DWARFAttributes attributes;
34f9b8f422SLuís Ferreira     const size_t num_child_attributes = die.GetAttributes(attributes);
35f9b8f422SLuís Ferreira     if (num_child_attributes > 0) {
36f9b8f422SLuís Ferreira       uint64_t num_elements = 0;
37f9b8f422SLuís Ferreira       uint64_t lower_bound = 0;
38f9b8f422SLuís Ferreira       uint64_t upper_bound = 0;
39f9b8f422SLuís Ferreira       bool upper_bound_valid = false;
40f9b8f422SLuís Ferreira       uint32_t i;
41f9b8f422SLuís Ferreira       for (i = 0; i < num_child_attributes; ++i) {
42f9b8f422SLuís Ferreira         const dw_attr_t attr = attributes.AttributeAtIndex(i);
43f9b8f422SLuís Ferreira         DWARFFormValue form_value;
44f9b8f422SLuís Ferreira         if (attributes.ExtractFormValueAtIndex(i, form_value)) {
45f9b8f422SLuís Ferreira           switch (attr) {
46f9b8f422SLuís Ferreira           case DW_AT_name:
47f9b8f422SLuís Ferreira             break;
48f9b8f422SLuís Ferreira 
49f9b8f422SLuís Ferreira           case DW_AT_count:
50f9b8f422SLuís Ferreira             if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) {
51f9b8f422SLuís Ferreira               if (var_die.Tag() == DW_TAG_variable)
52f9b8f422SLuís Ferreira                 if (exe_ctx) {
53f9b8f422SLuís Ferreira                   if (auto frame = exe_ctx->GetFrameSP()) {
54f9b8f422SLuís Ferreira                     Status error;
55f9b8f422SLuís Ferreira                     lldb::VariableSP var_sp;
56f9b8f422SLuís Ferreira                     auto valobj_sp = frame->GetValueForVariableExpressionPath(
57f9b8f422SLuís Ferreira                         var_die.GetName(), eNoDynamicValues, 0, var_sp, error);
58f9b8f422SLuís Ferreira                     if (valobj_sp) {
59f9b8f422SLuís Ferreira                       num_elements = valobj_sp->GetValueAsUnsigned(0);
60f9b8f422SLuís Ferreira                       break;
61f9b8f422SLuís Ferreira                     }
62f9b8f422SLuís Ferreira                   }
63f9b8f422SLuís Ferreira                 }
64f9b8f422SLuís Ferreira             } else
65f9b8f422SLuís Ferreira               num_elements = form_value.Unsigned();
66f9b8f422SLuís Ferreira             break;
67f9b8f422SLuís Ferreira 
68f9b8f422SLuís Ferreira           case DW_AT_bit_stride:
69f9b8f422SLuís Ferreira             array_info.bit_stride = form_value.Unsigned();
70f9b8f422SLuís Ferreira             break;
71f9b8f422SLuís Ferreira 
72f9b8f422SLuís Ferreira           case DW_AT_byte_stride:
73f9b8f422SLuís Ferreira             array_info.byte_stride = form_value.Unsigned();
74f9b8f422SLuís Ferreira             break;
75f9b8f422SLuís Ferreira 
76f9b8f422SLuís Ferreira           case DW_AT_lower_bound:
77f9b8f422SLuís Ferreira             lower_bound = form_value.Unsigned();
78f9b8f422SLuís Ferreira             break;
79f9b8f422SLuís Ferreira 
80f9b8f422SLuís Ferreira           case DW_AT_upper_bound:
81f9b8f422SLuís Ferreira             upper_bound_valid = true;
82f9b8f422SLuís Ferreira             upper_bound = form_value.Unsigned();
83f9b8f422SLuís Ferreira             break;
84f9b8f422SLuís Ferreira 
85f9b8f422SLuís Ferreira           default:
86f9b8f422SLuís Ferreira             break;
87f9b8f422SLuís Ferreira           }
88f9b8f422SLuís Ferreira         }
89f9b8f422SLuís Ferreira       }
90f9b8f422SLuís Ferreira 
91f9b8f422SLuís Ferreira       if (num_elements == 0) {
92f9b8f422SLuís Ferreira         if (upper_bound_valid && upper_bound >= lower_bound)
93f9b8f422SLuís Ferreira           num_elements = upper_bound - lower_bound + 1;
94f9b8f422SLuís Ferreira       }
95f9b8f422SLuís Ferreira 
96f9b8f422SLuís Ferreira       array_info.element_orders.push_back(num_elements);
97f9b8f422SLuís Ferreira     }
98f9b8f422SLuís Ferreira   }
99f9b8f422SLuís Ferreira   return array_info;
100f9b8f422SLuís Ferreira }
101*3da4f9c5SLuís Ferreira 
102*3da4f9c5SLuís Ferreira AccessType
GetAccessTypeFromDWARF(uint32_t dwarf_accessibility)103*3da4f9c5SLuís Ferreira DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) {
104*3da4f9c5SLuís Ferreira   switch (dwarf_accessibility) {
105*3da4f9c5SLuís Ferreira   case DW_ACCESS_public:
106*3da4f9c5SLuís Ferreira     return eAccessPublic;
107*3da4f9c5SLuís Ferreira   case DW_ACCESS_private:
108*3da4f9c5SLuís Ferreira     return eAccessPrivate;
109*3da4f9c5SLuís Ferreira   case DW_ACCESS_protected:
110*3da4f9c5SLuís Ferreira     return eAccessProtected;
111*3da4f9c5SLuís Ferreira   default:
112*3da4f9c5SLuís Ferreira     break;
113*3da4f9c5SLuís Ferreira   }
114*3da4f9c5SLuís Ferreira   return eAccessNone;
115*3da4f9c5SLuís Ferreira }
116