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