1 //===-- ValueObjectChild.cpp ------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Core/ValueObjectChild.h"
11
12 #include "lldb/Core/Module.h"
13 #include "lldb/Core/ValueObjectList.h"
14
15 #include "lldb/Symbol/ClangASTType.h"
16 #include "lldb/Symbol/ObjectFile.h"
17 #include "lldb/Symbol/SymbolContext.h"
18 #include "lldb/Symbol/Type.h"
19 #include "lldb/Symbol/Variable.h"
20
21 #include "lldb/Target/ExecutionContext.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/Target.h"
24
25 using namespace lldb_private;
26
ValueObjectChild(ValueObject & parent,const ClangASTType & clang_type,const ConstString & name,uint64_t byte_size,int32_t byte_offset,uint32_t bitfield_bit_size,uint32_t bitfield_bit_offset,bool is_base_class,bool is_deref_of_parent,AddressType child_ptr_or_ref_addr_type)27 ValueObjectChild::ValueObjectChild
28 (
29 ValueObject &parent,
30 const ClangASTType &clang_type,
31 const ConstString &name,
32 uint64_t byte_size,
33 int32_t byte_offset,
34 uint32_t bitfield_bit_size,
35 uint32_t bitfield_bit_offset,
36 bool is_base_class,
37 bool is_deref_of_parent,
38 AddressType child_ptr_or_ref_addr_type
39 ) :
40 ValueObject (parent),
41 m_clang_type (clang_type),
42 m_byte_size (byte_size),
43 m_byte_offset (byte_offset),
44 m_bitfield_bit_size (bitfield_bit_size),
45 m_bitfield_bit_offset (bitfield_bit_offset),
46 m_is_base_class (is_base_class),
47 m_is_deref_of_parent (is_deref_of_parent)
48 {
49 m_name = name;
50 SetAddressTypeOfChildren(child_ptr_or_ref_addr_type);
51 }
52
~ValueObjectChild()53 ValueObjectChild::~ValueObjectChild()
54 {
55 }
56
57 lldb::ValueType
GetValueType() const58 ValueObjectChild::GetValueType() const
59 {
60 return m_parent->GetValueType();
61 }
62
63 size_t
CalculateNumChildren()64 ValueObjectChild::CalculateNumChildren()
65 {
66 return GetClangType().GetNumChildren (true);
67 }
68
69 ConstString
GetTypeName()70 ValueObjectChild::GetTypeName()
71 {
72 if (m_type_name.IsEmpty())
73 {
74 m_type_name = GetClangType().GetConstTypeName ();
75 if (m_type_name)
76 {
77 if (m_bitfield_bit_size > 0)
78 {
79 const char *clang_type_name = m_type_name.AsCString();
80 if (clang_type_name)
81 {
82 std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
83 ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size);
84 m_type_name.SetCString(&bitfield_type_name.front());
85 }
86 }
87 }
88 }
89 return m_type_name;
90 }
91
92 ConstString
GetQualifiedTypeName()93 ValueObjectChild::GetQualifiedTypeName()
94 {
95 ConstString qualified_name = GetClangType().GetConstTypeName();
96 if (qualified_name)
97 {
98 if (m_bitfield_bit_size > 0)
99 {
100 const char *clang_type_name = qualified_name.AsCString();
101 if (clang_type_name)
102 {
103 std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
104 ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size);
105 qualified_name.SetCString(&bitfield_type_name.front());
106 }
107 }
108 }
109 return qualified_name;
110 }
111
112 bool
UpdateValue()113 ValueObjectChild::UpdateValue ()
114 {
115 m_error.Clear();
116 SetValueIsValid (false);
117 ValueObject* parent = m_parent;
118 if (parent)
119 {
120 if (parent->UpdateValueIfNeeded(false))
121 {
122 m_value.SetClangType(GetClangType());
123
124 // Copy the parent scalar value and the scalar value type
125 m_value.GetScalar() = parent->GetValue().GetScalar();
126 Value::ValueType value_type = parent->GetValue().GetValueType();
127 m_value.SetValueType (value_type);
128
129 if (parent->GetClangType().IsPointerOrReferenceType ())
130 {
131 lldb::addr_t addr = parent->GetPointerValue ();
132 m_value.GetScalar() = addr;
133
134 if (addr == LLDB_INVALID_ADDRESS)
135 {
136 m_error.SetErrorString ("parent address is invalid.");
137 }
138 else if (addr == 0)
139 {
140 m_error.SetErrorString ("parent is NULL");
141 }
142 else
143 {
144 m_value.GetScalar() += m_byte_offset;
145 AddressType addr_type = parent->GetAddressTypeOfChildren();
146
147 switch (addr_type)
148 {
149 case eAddressTypeFile:
150 {
151 lldb::ProcessSP process_sp (GetProcessSP());
152 if (process_sp && process_sp->IsAlive() == true)
153 m_value.SetValueType (Value::eValueTypeLoadAddress);
154 else
155 m_value.SetValueType(Value::eValueTypeFileAddress);
156 }
157 break;
158 case eAddressTypeLoad:
159 m_value.SetValueType (Value::eValueTypeLoadAddress);
160 break;
161 case eAddressTypeHost:
162 m_value.SetValueType(Value::eValueTypeHostAddress);
163 break;
164 case eAddressTypeInvalid:
165 // TODO: does this make sense?
166 m_value.SetValueType(Value::eValueTypeScalar);
167 break;
168 }
169 }
170 }
171 else
172 {
173 switch (value_type)
174 {
175 case Value::eValueTypeLoadAddress:
176 case Value::eValueTypeFileAddress:
177 case Value::eValueTypeHostAddress:
178 {
179 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
180 if (addr == LLDB_INVALID_ADDRESS)
181 {
182 m_error.SetErrorString ("parent address is invalid.");
183 }
184 else if (addr == 0)
185 {
186 m_error.SetErrorString ("parent is NULL");
187 }
188 else
189 {
190 // Set this object's scalar value to the address of its
191 // value by adding its byte offset to the parent address
192 m_value.GetScalar() += GetByteOffset();
193 }
194 }
195 break;
196
197 case Value::eValueTypeScalar:
198 // TODO: What if this is a register value? Do we try and
199 // extract the child value from within the parent data?
200 // Probably...
201 default:
202 m_error.SetErrorString ("parent has invalid value.");
203 break;
204 }
205 }
206
207 if (m_error.Success())
208 {
209 ExecutionContext exe_ctx (GetExecutionContextRef().Lock());
210 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
211 }
212 }
213 else
214 {
215 m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString());
216 }
217 }
218 else
219 {
220 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
221 }
222
223 return m_error.Success();
224 }
225
226
227 bool
IsInScope()228 ValueObjectChild::IsInScope ()
229 {
230 ValueObject* root(GetRoot());
231 if (root)
232 return root->IsInScope ();
233 return false;
234 }
235