1 //===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "lldb/Core/ValueObjectDynamicValue.h"
15 // Other libraries and framework includes
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/ValueObjectList.h"
20 #include "lldb/Core/Value.h"
21 #include "lldb/Core/ValueObject.h"
23 #include "lldb/Symbol/CompilerType.h"
24 #include "lldb/Symbol/ObjectFile.h"
25 #include "lldb/Symbol/SymbolContext.h"
26 #include "lldb/Symbol/Type.h"
27 #include "lldb/Symbol/Variable.h"
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"
36 using namespace lldb_private;
38 ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
41 m_dynamic_type_info(),
42 m_use_dynamic (use_dynamic)
44 SetName (parent.GetName());
47 ValueObjectDynamicValue::~ValueObjectDynamicValue()
49 m_owning_valobj_sp.reset();
53 ValueObjectDynamicValue::GetCompilerTypeImpl ()
55 const bool success = UpdateValueIfNeeded(false);
58 if (m_dynamic_type_info.HasType())
59 return m_value.GetCompilerType();
61 return m_parent->GetCompilerType();
63 return m_parent->GetCompilerType();
67 ValueObjectDynamicValue::GetTypeName()
69 const bool success = UpdateValueIfNeeded(false);
72 if (m_dynamic_type_info.HasName())
73 return m_dynamic_type_info.GetName();
75 return m_parent->GetTypeName();
79 ValueObjectDynamicValue::GetTypeImpl ()
81 const bool success = UpdateValueIfNeeded(false);
82 if (success && m_type_impl.IsValid())
86 return m_parent->GetTypeImpl();
90 ValueObjectDynamicValue::GetQualifiedTypeName()
92 const bool success = UpdateValueIfNeeded(false);
95 if (m_dynamic_type_info.HasName())
96 return m_dynamic_type_info.GetName();
98 return m_parent->GetQualifiedTypeName();
102 ValueObjectDynamicValue::GetDisplayTypeName()
104 const bool success = UpdateValueIfNeeded(false);
107 if (m_dynamic_type_info.HasType())
108 return GetCompilerType().GetDisplayTypeName();
109 if (m_dynamic_type_info.HasName())
110 return m_dynamic_type_info.GetName();
112 return m_parent->GetDisplayTypeName();
116 ValueObjectDynamicValue::CalculateNumChildren(uint32_t max)
118 const bool success = UpdateValueIfNeeded(false);
119 if (success && m_dynamic_type_info.HasType())
121 auto children_count = GetCompilerType().GetNumChildren (true);
122 return children_count <= max ? children_count : max;
125 return m_parent->GetNumChildren(max);
129 ValueObjectDynamicValue::GetByteSize()
131 const bool success = UpdateValueIfNeeded(false);
132 if (success && m_dynamic_type_info.HasType())
134 ExecutionContext exe_ctx (GetExecutionContextRef());
135 return m_value.GetValueByteSize(nullptr, &exe_ctx);
138 return m_parent->GetByteSize();
142 ValueObjectDynamicValue::GetValueType() const
144 return m_parent->GetValueType();
148 ValueObjectDynamicValue::UpdateValue ()
150 SetValueIsValid (false);
153 if (!m_parent->UpdateValueIfNeeded(false))
155 // The dynamic value failed to get an error, pass the error along
156 if (m_error.Success() && m_parent->GetError().Fail())
157 m_error = m_parent->GetError();
161 // Setting our type_sp to NULL will route everything back through our
162 // parent which is equivalent to not using dynamic values.
163 if (m_use_dynamic == lldb::eNoDynamicValues)
165 m_dynamic_type_info.Clear();
169 ExecutionContext exe_ctx (GetExecutionContextRef());
170 Target *target = exe_ctx.GetTargetPtr();
173 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
174 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
177 // First make sure our Type and/or Address haven't changed:
178 Process *process = exe_ctx.GetProcessPtr();
182 TypeAndOrName class_type_or_name;
183 Address dynamic_address;
184 bool found_dynamic_type = false;
185 Value::ValueType value_type;
187 LanguageRuntime *runtime = nullptr;
189 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
190 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
192 runtime = process->GetLanguageRuntime (known_type);
194 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type);
198 runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
200 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type);
202 if (!found_dynamic_type)
204 runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
206 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type);
210 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
213 m_update_point.SetUpdated();
215 if (runtime && found_dynamic_type)
217 if (class_type_or_name.HasType())
219 m_type_impl = TypeImpl(m_parent->GetCompilerType(),
220 runtime->FixUpDynamicType(class_type_or_name, *m_parent).GetCompilerType());
232 // If we don't have a dynamic type, then make ourselves just a echo of our parent.
233 // Or we could return false, and make ourselves an echo of our parent?
234 if (!found_dynamic_type)
236 if (m_dynamic_type_info)
237 SetValueDidChange(true);
238 ClearDynamicTypeInformation();
239 m_dynamic_type_info.Clear();
240 m_value = m_parent->GetValue();
241 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
242 return m_error.Success();
245 Value old_value(m_value);
247 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
249 bool has_changed_type = false;
251 if (!m_dynamic_type_info)
253 m_dynamic_type_info = class_type_or_name;
254 has_changed_type = true;
256 else if (class_type_or_name != m_dynamic_type_info)
258 // We are another type, we need to tear down our children...
259 m_dynamic_type_info = class_type_or_name;
260 SetValueDidChange (true);
261 has_changed_type = true;
264 if (has_changed_type)
265 ClearDynamicTypeInformation ();
267 if (!m_address.IsValid() || m_address != dynamic_address)
269 if (m_address.IsValid())
270 SetValueDidChange (true);
272 // We've moved, so we should be fine...
273 m_address = dynamic_address;
274 lldb::TargetSP target_sp (GetTargetSP());
275 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
276 m_value.GetScalar() = load_address;
280 m_dynamic_type_info = runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
282 //m_value.SetContext (Value::eContextTypeClangType, corrected_type);
283 m_value.SetCompilerType (m_dynamic_type_info.GetCompilerType());
285 m_value.SetValueType(value_type);
287 if (has_changed_type && log)
288 log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
289 static_cast<void*>(this), GetTypeName().GetCString());
291 if (m_address.IsValid() && m_dynamic_type_info)
293 // The variable value is in the Scalar value inside the m_value.
294 // We can point our m_data right to it.
295 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
296 if (m_error.Success())
298 if (!CanProvideValue())
300 // this value object represents an aggregate type whose
301 // children have values, but this object does not. So we
302 // say we are changed if our location has changed.
303 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
306 SetValueIsValid (true);
311 // We get here if we've failed above...
312 SetValueIsValid (false);
319 ValueObjectDynamicValue::IsInScope ()
321 return m_parent->IsInScope();
325 ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
327 if (!UpdateValueIfNeeded(false))
329 error.SetErrorString("unable to read value");
333 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
334 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
336 if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
338 error.SetErrorString("unable to read value");
342 // if we are at an offset from our parent, in order to set ourselves correctly we would need
343 // to change the new value so that it refers to the correct dynamic type. we choose not to deal
344 // with that - if anything more than a value overwrite is required, you should be using the
345 // expression parser instead of the value editing facility
346 if (my_value != parent_value)
348 // but NULL'ing out a value should always be allowed
349 if (strcmp(value_str,"0"))
351 error.SetErrorString("unable to modify dynamic value, use 'expression' command");
356 bool ret_val = m_parent->SetValueFromCString(value_str,error);
362 ValueObjectDynamicValue::SetData (DataExtractor &data, Error &error)
364 if (!UpdateValueIfNeeded(false))
366 error.SetErrorString("unable to read value");
370 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
371 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
373 if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
375 error.SetErrorString("unable to read value");
379 // if we are at an offset from our parent, in order to set ourselves correctly we would need
380 // to change the new value so that it refers to the correct dynamic type. we choose not to deal
381 // with that - if anything more than a value overwrite is required, you should be using the
382 // expression parser instead of the value editing facility
383 if (my_value != parent_value)
385 // but NULL'ing out a value should always be allowed
386 lldb::offset_t offset = 0;
388 if (data.GetPointer(&offset) != 0)
390 error.SetErrorString("unable to modify dynamic value, use 'expression' command");
395 bool ret_val = m_parent->SetData(data, error);
401 ValueObjectDynamicValue::SetPreferredDisplayLanguage (lldb::LanguageType lang)
403 this->ValueObject::SetPreferredDisplayLanguage(lang);
405 m_parent->SetPreferredDisplayLanguage(lang);
409 ValueObjectDynamicValue::GetPreferredDisplayLanguage ()
411 if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
414 return m_parent->GetPreferredDisplayLanguage();
415 return lldb::eLanguageTypeUnknown;
418 return m_preferred_display_language;
422 ValueObjectDynamicValue::IsSyntheticChildrenGenerated ()
425 return m_parent->IsSyntheticChildrenGenerated();
430 ValueObjectDynamicValue::SetSyntheticChildrenGenerated (bool b)
433 m_parent->SetSyntheticChildrenGenerated(b);
434 this->ValueObject::SetSyntheticChildrenGenerated(b);
438 ValueObjectDynamicValue::GetDeclaration (Declaration &decl)
441 return m_parent->GetDeclaration(decl);
443 return ValueObject::GetDeclaration(decl);
447 ValueObjectDynamicValue::GetLanguageFlags ()
450 return m_parent->GetLanguageFlags();
451 return this->ValueObject::GetLanguageFlags();
455 ValueObjectDynamicValue::SetLanguageFlags (uint64_t flags)
458 m_parent->SetLanguageFlags(flags);
460 this->ValueObject::SetLanguageFlags(flags);