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 #include <optional>
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 using namespace lldb_private::dwarf;
21 
22 std::optional<SymbolFile::ArrayInfo>
23 DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
24                                     const ExecutionContext *exe_ctx) {
25   SymbolFile::ArrayInfo array_info;
26   if (!parent_die)
27     return std::nullopt;
28 
29   for (DWARFDIE die : parent_die.children()) {
30     const dw_tag_t tag = die.Tag();
31     if (tag != DW_TAG_subrange_type)
32       continue;
33 
34     DWARFAttributes attributes;
35     const size_t num_child_attributes = die.GetAttributes(attributes);
36     if (num_child_attributes > 0) {
37       uint64_t num_elements = 0;
38       uint64_t lower_bound = 0;
39       uint64_t upper_bound = 0;
40       bool upper_bound_valid = false;
41       uint32_t i;
42       for (i = 0; i < num_child_attributes; ++i) {
43         const dw_attr_t attr = attributes.AttributeAtIndex(i);
44         DWARFFormValue form_value;
45         if (attributes.ExtractFormValueAtIndex(i, form_value)) {
46           switch (attr) {
47           case DW_AT_name:
48             break;
49 
50           case DW_AT_count:
51             if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) {
52               if (var_die.Tag() == DW_TAG_variable)
53                 if (exe_ctx) {
54                   if (auto frame = exe_ctx->GetFrameSP()) {
55                     Status error;
56                     lldb::VariableSP var_sp;
57                     auto valobj_sp = frame->GetValueForVariableExpressionPath(
58                         var_die.GetName(), eNoDynamicValues, 0, var_sp, error);
59                     if (valobj_sp) {
60                       num_elements = valobj_sp->GetValueAsUnsigned(0);
61                       break;
62                     }
63                   }
64                 }
65             } else
66               num_elements = form_value.Unsigned();
67             break;
68 
69           case DW_AT_bit_stride:
70             array_info.bit_stride = form_value.Unsigned();
71             break;
72 
73           case DW_AT_byte_stride:
74             array_info.byte_stride = form_value.Unsigned();
75             break;
76 
77           case DW_AT_lower_bound:
78             lower_bound = form_value.Unsigned();
79             break;
80 
81           case DW_AT_upper_bound:
82             upper_bound_valid = true;
83             upper_bound = form_value.Unsigned();
84             break;
85 
86           default:
87             break;
88           }
89         }
90       }
91 
92       if (num_elements == 0) {
93         if (upper_bound_valid && upper_bound >= lower_bound)
94           num_elements = upper_bound - lower_bound + 1;
95       }
96 
97       array_info.element_orders.push_back(num_elements);
98     }
99   }
100   return array_info;
101 }
102 
103 AccessType
104 DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) {
105   switch (dwarf_accessibility) {
106   case DW_ACCESS_public:
107     return eAccessPublic;
108   case DW_ACCESS_private:
109     return eAccessPrivate;
110   case DW_ACCESS_protected:
111     return eAccessProtected;
112   default:
113     break;
114   }
115   return eAccessNone;
116 }
117