blob: 1fb32d4e86a3076ae5536ae9ef82cd94e18d7757 [file] [log] [blame]
Kate Stoneb9c1b512016-09-06 20:57:50 +00001//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++
2//-*-===//
Jim Ingham78a685a2011-04-16 00:01:13 +00003//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
Jim Ingham78a685a2011-04-16 00:01:13 +000011#include "lldb/Core/ValueObjectDynamicValue.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16// Project includes
Enrico Granatad2284832012-10-17 22:23:56 +000017#include "lldb/Core/Log.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000018#include "lldb/Core/Module.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000019#include "lldb/Core/Value.h"
20#include "lldb/Core/ValueObject.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000021#include "lldb/Core/ValueObjectList.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000022
Greg Claytona1e5dc82015-08-11 22:53:00 +000023#include "lldb/Symbol/CompilerType.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000024#include "lldb/Symbol/ObjectFile.h"
25#include "lldb/Symbol/SymbolContext.h"
26#include "lldb/Symbol/Type.h"
27#include "lldb/Symbol/Variable.h"
28
29#include "lldb/Target/ExecutionContext.h"
30#include "lldb/Target/LanguageRuntime.h"
31#include "lldb/Target/Process.h"
32#include "lldb/Target/RegisterContext.h"
33#include "lldb/Target/Target.h"
34#include "lldb/Target/Thread.h"
35
Jim Ingham78a685a2011-04-16 00:01:13 +000036using namespace lldb_private;
37
Kate Stoneb9c1b512016-09-06 20:57:50 +000038ValueObjectDynamicValue::ValueObjectDynamicValue(
39 ValueObject &parent, lldb::DynamicValueType use_dynamic)
40 : ValueObject(parent), m_address(), m_dynamic_type_info(),
41 m_use_dynamic(use_dynamic) {
42 SetName(parent.GetName());
Jim Ingham78a685a2011-04-16 00:01:13 +000043}
44
Kate Stoneb9c1b512016-09-06 20:57:50 +000045ValueObjectDynamicValue::~ValueObjectDynamicValue() {
46 m_owning_valobj_sp.reset();
Jim Ingham78a685a2011-04-16 00:01:13 +000047}
48
Kate Stoneb9c1b512016-09-06 20:57:50 +000049CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
50 const bool success = UpdateValueIfNeeded(false);
51 if (success) {
52 if (m_dynamic_type_info.HasType())
53 return m_value.GetCompilerType();
Jim Ingham78a685a2011-04-16 00:01:13 +000054 else
Kate Stoneb9c1b512016-09-06 20:57:50 +000055 return m_parent->GetCompilerType();
56 }
57 return m_parent->GetCompilerType();
Jim Ingham78a685a2011-04-16 00:01:13 +000058}
59
Kate Stoneb9c1b512016-09-06 20:57:50 +000060ConstString ValueObjectDynamicValue::GetTypeName() {
61 const bool success = UpdateValueIfNeeded(false);
62 if (success) {
63 if (m_dynamic_type_info.HasName())
64 return m_dynamic_type_info.GetName();
65 }
66 return m_parent->GetTypeName();
Jim Ingham78a685a2011-04-16 00:01:13 +000067}
68
Kate Stoneb9c1b512016-09-06 20:57:50 +000069TypeImpl ValueObjectDynamicValue::GetTypeImpl() {
70 const bool success = UpdateValueIfNeeded(false);
71 if (success && m_type_impl.IsValid()) {
72 return m_type_impl;
73 }
74 return m_parent->GetTypeImpl();
Jim Ingham78a685a2011-04-16 00:01:13 +000075}
76
Kate Stoneb9c1b512016-09-06 20:57:50 +000077ConstString ValueObjectDynamicValue::GetQualifiedTypeName() {
78 const bool success = UpdateValueIfNeeded(false);
79 if (success) {
80 if (m_dynamic_type_info.HasName())
81 return m_dynamic_type_info.GetName();
82 }
83 return m_parent->GetQualifiedTypeName();
84}
Jim Ingham78a685a2011-04-16 00:01:13 +000085
Kate Stoneb9c1b512016-09-06 20:57:50 +000086ConstString ValueObjectDynamicValue::GetDisplayTypeName() {
87 const bool success = UpdateValueIfNeeded(false);
88 if (success) {
89 if (m_dynamic_type_info.HasType())
90 return GetCompilerType().GetDisplayTypeName();
91 if (m_dynamic_type_info.HasName())
92 return m_dynamic_type_info.GetName();
93 }
94 return m_parent->GetDisplayTypeName();
95}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000096
Kate Stoneb9c1b512016-09-06 20:57:50 +000097size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) {
98 const bool success = UpdateValueIfNeeded(false);
99 if (success && m_dynamic_type_info.HasType()) {
100 auto children_count = GetCompilerType().GetNumChildren(true);
101 return children_count <= max ? children_count : max;
102 } else
103 return m_parent->GetNumChildren(max);
104}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000105
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106uint64_t ValueObjectDynamicValue::GetByteSize() {
107 const bool success = UpdateValueIfNeeded(false);
108 if (success && m_dynamic_type_info.HasType()) {
109 ExecutionContext exe_ctx(GetExecutionContextRef());
110 return m_value.GetValueByteSize(nullptr, &exe_ctx);
111 } else
112 return m_parent->GetByteSize();
113}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000114
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115lldb::ValueType ValueObjectDynamicValue::GetValueType() const {
116 return m_parent->GetValueType();
117}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000118
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119bool ValueObjectDynamicValue::UpdateValue() {
120 SetValueIsValid(false);
121 m_error.Clear();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000122
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123 if (!m_parent->UpdateValueIfNeeded(false)) {
124 // The dynamic value failed to get an error, pass the error along
125 if (m_error.Success() && m_parent->GetError().Fail())
126 m_error = m_parent->GetError();
127 return false;
128 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000129
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130 // Setting our type_sp to NULL will route everything back through our
131 // parent which is equivalent to not using dynamic values.
132 if (m_use_dynamic == lldb::eNoDynamicValues) {
133 m_dynamic_type_info.Clear();
134 return true;
135 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000136
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 ExecutionContext exe_ctx(GetExecutionContextRef());
138 Target *target = exe_ctx.GetTargetPtr();
139 if (target) {
140 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
141 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
142 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 // First make sure our Type and/or Address haven't changed:
145 Process *process = exe_ctx.GetProcessPtr();
146 if (!process)
147 return false;
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000148
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149 TypeAndOrName class_type_or_name;
150 Address dynamic_address;
151 bool found_dynamic_type = false;
152 Value::ValueType value_type;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000153
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 LanguageRuntime *runtime = nullptr;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000155
Kate Stoneb9c1b512016-09-06 20:57:50 +0000156 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
157 if (known_type != lldb::eLanguageTypeUnknown &&
158 known_type != lldb::eLanguageTypeC) {
159 runtime = process->GetLanguageRuntime(known_type);
Enrico Granatac74275b2015-09-22 19:45:52 +0000160 if (runtime)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 found_dynamic_type = runtime->GetDynamicTypeAndAddress(
162 *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
163 value_type);
164 } else {
165 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
166 if (runtime)
167 found_dynamic_type = runtime->GetDynamicTypeAndAddress(
168 *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
169 value_type);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000170
Kate Stoneb9c1b512016-09-06 20:57:50 +0000171 if (!found_dynamic_type) {
172 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
173 if (runtime)
174 found_dynamic_type = runtime->GetDynamicTypeAndAddress(
175 *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
176 value_type);
Jim Ingham78a685a2011-04-16 00:01:13 +0000177 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000179
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 // Getting the dynamic value may have run the program a bit, and so marked us
181 // as needing updating, but we really
182 // don't...
183
184 m_update_point.SetUpdated();
185
186 if (runtime && found_dynamic_type) {
187 if (class_type_or_name.HasType()) {
188 m_type_impl =
189 TypeImpl(m_parent->GetCompilerType(),
190 runtime->FixUpDynamicType(class_type_or_name, *m_parent)
191 .GetCompilerType());
192 } else {
193 m_type_impl.Clear();
194 }
195 } else {
196 m_type_impl.Clear();
197 }
198
199 // If we don't have a dynamic type, then make ourselves just a echo of our
200 // parent.
201 // Or we could return false, and make ourselves an echo of our parent?
202 if (!found_dynamic_type) {
203 if (m_dynamic_type_info)
204 SetValueDidChange(true);
205 ClearDynamicTypeInformation();
206 m_dynamic_type_info.Clear();
207 m_value = m_parent->GetValue();
208 m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
209 return m_error.Success();
210 }
211
212 Value old_value(m_value);
213
214 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
215
216 bool has_changed_type = false;
217
218 if (!m_dynamic_type_info) {
219 m_dynamic_type_info = class_type_or_name;
220 has_changed_type = true;
221 } else if (class_type_or_name != m_dynamic_type_info) {
222 // We are another type, we need to tear down our children...
223 m_dynamic_type_info = class_type_or_name;
224 SetValueDidChange(true);
225 has_changed_type = true;
226 }
227
228 if (has_changed_type)
229 ClearDynamicTypeInformation();
230
231 if (!m_address.IsValid() || m_address != dynamic_address) {
232 if (m_address.IsValid())
233 SetValueDidChange(true);
234
235 // We've moved, so we should be fine...
236 m_address = dynamic_address;
237 lldb::TargetSP target_sp(GetTargetSP());
238 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
239 m_value.GetScalar() = load_address;
240 }
241
242 if (runtime)
243 m_dynamic_type_info =
244 runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
245
246 // m_value.SetContext (Value::eContextTypeClangType, corrected_type);
247 m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType());
248
249 m_value.SetValueType(value_type);
250
251 if (has_changed_type && log)
252 log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
253 static_cast<void *>(this), GetTypeName().GetCString());
254
255 if (m_address.IsValid() && m_dynamic_type_info) {
256 // The variable value is in the Scalar value inside the m_value.
257 // We can point our m_data right to it.
258 m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
259 if (m_error.Success()) {
260 if (!CanProvideValue()) {
261 // this value object represents an aggregate type whose
262 // children have values, but this object does not. So we
263 // say we are changed if our location has changed.
264 SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
265 m_value.GetScalar() != old_value.GetScalar());
266 }
267
268 SetValueIsValid(true);
269 return true;
270 }
271 }
272
273 // We get here if we've failed above...
274 SetValueIsValid(false);
275 return false;
276}
277
278bool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); }
279
280bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str,
281 Error &error) {
282 if (!UpdateValueIfNeeded(false)) {
283 error.SetErrorString("unable to read value");
Jim Ingham78a685a2011-04-16 00:01:13 +0000284 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000285 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000286
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
288 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
Jim Ingham78a685a2011-04-16 00:01:13 +0000289
Kate Stoneb9c1b512016-09-06 20:57:50 +0000290 if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
291 error.SetErrorString("unable to read value");
Enrico Granata3b207c62016-07-08 18:39:36 +0000292 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000293 }
294
295 // if we are at an offset from our parent, in order to set ourselves correctly
296 // we would need
297 // to change the new value so that it refers to the correct dynamic type. we
298 // choose not to deal
299 // with that - if anything more than a value overwrite is required, you should
300 // be using the
301 // expression parser instead of the value editing facility
302 if (my_value != parent_value) {
303 // but NULL'ing out a value should always be allowed
304 if (strcmp(value_str, "0")) {
305 error.SetErrorString(
306 "unable to modify dynamic value, use 'expression' command");
307 return false;
308 }
309 }
310
311 bool ret_val = m_parent->SetValueFromCString(value_str, error);
312 SetNeedsUpdate();
313 return ret_val;
Enrico Granata3b207c62016-07-08 18:39:36 +0000314}
315
Kate Stoneb9c1b512016-09-06 20:57:50 +0000316bool ValueObjectDynamicValue::SetData(DataExtractor &data, Error &error) {
317 if (!UpdateValueIfNeeded(false)) {
318 error.SetErrorString("unable to read value");
319 return false;
320 }
321
322 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
323 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
324
325 if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
326 error.SetErrorString("unable to read value");
327 return false;
328 }
329
330 // if we are at an offset from our parent, in order to set ourselves correctly
331 // we would need
332 // to change the new value so that it refers to the correct dynamic type. we
333 // choose not to deal
334 // with that - if anything more than a value overwrite is required, you should
335 // be using the
336 // expression parser instead of the value editing facility
337 if (my_value != parent_value) {
338 // but NULL'ing out a value should always be allowed
339 lldb::offset_t offset = 0;
340
341 if (data.GetPointer(&offset) != 0) {
342 error.SetErrorString(
343 "unable to modify dynamic value, use 'expression' command");
344 return false;
345 }
346 }
347
348 bool ret_val = m_parent->SetData(data, error);
349 SetNeedsUpdate();
350 return ret_val;
Enrico Granata3b207c62016-07-08 18:39:36 +0000351}
352
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353void ValueObjectDynamicValue::SetPreferredDisplayLanguage(
354 lldb::LanguageType lang) {
355 this->ValueObject::SetPreferredDisplayLanguage(lang);
356 if (m_parent)
357 m_parent->SetPreferredDisplayLanguage(lang);
Siva Chandra9851b1f2015-08-18 17:56:06 +0000358}
Enrico Granatadc62ffd2015-11-09 19:27:34 +0000359
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360lldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() {
361 if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
Enrico Granatadc62ffd2015-11-09 19:27:34 +0000362 if (m_parent)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000363 return m_parent->GetPreferredDisplayLanguage();
364 return lldb::eLanguageTypeUnknown;
365 } else
366 return m_preferred_display_language;
Enrico Granatadc62ffd2015-11-09 19:27:34 +0000367}
368
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369bool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() {
370 if (m_parent)
371 return m_parent->IsSyntheticChildrenGenerated();
372 return false;
373}
374
375void ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) {
376 if (m_parent)
377 m_parent->SetSyntheticChildrenGenerated(b);
378 this->ValueObject::SetSyntheticChildrenGenerated(b);
379}
380
381bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) {
382 if (m_parent)
383 return m_parent->GetDeclaration(decl);
384
385 return ValueObject::GetDeclaration(decl);
386}
387
388uint64_t ValueObjectDynamicValue::GetLanguageFlags() {
389 if (m_parent)
390 return m_parent->GetLanguageFlags();
391 return this->ValueObject::GetLanguageFlags();
392}
393
394void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) {
395 if (m_parent)
396 m_parent->SetLanguageFlags(flags);
397 else
398 this->ValueObject::SetLanguageFlags(flags);
Enrico Granatadc62ffd2015-11-09 19:27:34 +0000399}