blob: 47e781e711566fceb0cf5c8f959cd21712aa0db4 [file] [log] [blame]
Jim Ingham78a685a2011-04-16 00:01:13 +00001//===-- ValueObjectDynamicValue.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
11#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"
19#include "lldb/Core/ValueObjectList.h"
20#include "lldb/Core/Value.h"
21#include "lldb/Core/ValueObject.h"
22
Enrico Granata21fd13f2012-10-27 02:05:48 +000023#include "lldb/Symbol/ClangASTType.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
Jim Ingham2837b762011-05-04 03:43:18 +000038ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
Jim Ingham78a685a2011-04-16 00:01:13 +000039 ValueObject(parent),
40 m_address (),
Enrico Granataf7b1a342013-01-23 01:17:27 +000041 m_dynamic_type_info(),
Jim Ingham2837b762011-05-04 03:43:18 +000042 m_use_dynamic (use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +000043{
Enrico Granata6f3533f2011-07-29 19:53:35 +000044 SetName (parent.GetName());
Jim Ingham78a685a2011-04-16 00:01:13 +000045}
46
47ValueObjectDynamicValue::~ValueObjectDynamicValue()
48{
49 m_owning_valobj_sp.reset();
50}
51
Greg Clayton57ee3062013-07-11 22:46:58 +000052ClangASTType
Sean Callanan72772842012-02-22 23:57:45 +000053ValueObjectDynamicValue::GetClangTypeImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +000054{
Enrico Granatadc4db5a2013-10-29 00:28:35 +000055 const bool success = UpdateValueIfNeeded(false);
56 if (success)
57 {
58 if (m_dynamic_type_info.HasType())
59 return m_value.GetClangType();
60 else
61 return m_parent->GetClangType();
62 }
63 return m_parent->GetClangType();
Jim Ingham78a685a2011-04-16 00:01:13 +000064}
65
66ConstString
67ValueObjectDynamicValue::GetTypeName()
68{
Enrico Granatac3e320a2011-08-02 17:27:39 +000069 const bool success = UpdateValueIfNeeded(false);
Enrico Granataf7b1a342013-01-23 01:17:27 +000070 if (success)
71 {
Enrico Granataf7b1a342013-01-23 01:17:27 +000072 if (m_dynamic_type_info.HasName())
73 return m_dynamic_type_info.GetName();
Enrico Granatafcf0c4e2013-10-31 22:42:00 +000074 if (m_dynamic_type_info.HasType())
75 return GetClangType().GetConstTypeName();
Enrico Granataf7b1a342013-01-23 01:17:27 +000076 }
77 return m_parent->GetTypeName();
78}
79
Enrico Granatadc4db5a2013-10-29 00:28:35 +000080TypeImpl
81ValueObjectDynamicValue::GetTypeImpl ()
82{
83 const bool success = UpdateValueIfNeeded(false);
Enrico Granatadf7c7f92013-10-29 17:42:02 +000084 if (success && m_type_impl.IsValid())
Enrico Granatadc4db5a2013-10-29 00:28:35 +000085 {
86 return m_type_impl;
87 }
88 return m_parent->GetTypeImpl();
89}
90
Enrico Granataf7b1a342013-01-23 01:17:27 +000091ConstString
92ValueObjectDynamicValue::GetQualifiedTypeName()
93{
94 const bool success = UpdateValueIfNeeded(false);
95 if (success)
96 {
Enrico Granataf7b1a342013-01-23 01:17:27 +000097 if (m_dynamic_type_info.HasName())
98 return m_dynamic_type_info.GetName();
Enrico Granatafcf0c4e2013-10-31 22:42:00 +000099 if (m_dynamic_type_info.HasType())
100 return GetClangType().GetConstQualifiedTypeName ();
Enrico Granataf7b1a342013-01-23 01:17:27 +0000101 }
102 return m_parent->GetTypeName();
Jim Ingham78a685a2011-04-16 00:01:13 +0000103}
104
Greg Claytonc7bece562013-01-25 18:06:21 +0000105size_t
Jim Ingham78a685a2011-04-16 00:01:13 +0000106ValueObjectDynamicValue::CalculateNumChildren()
107{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000108 const bool success = UpdateValueIfNeeded(false);
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000109 if (success && m_dynamic_type_info.HasType())
Greg Clayton57ee3062013-07-11 22:46:58 +0000110 return GetClangType().GetNumChildren (true);
Jim Ingham78a685a2011-04-16 00:01:13 +0000111 else
112 return m_parent->GetNumChildren();
113}
114
Greg Claytonfaac1112013-03-14 18:31:44 +0000115uint64_t
Jim Ingham78a685a2011-04-16 00:01:13 +0000116ValueObjectDynamicValue::GetByteSize()
117{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000118 const bool success = UpdateValueIfNeeded(false);
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000119 if (success && m_dynamic_type_info.HasType())
Greg Clayton57ee3062013-07-11 22:46:58 +0000120 return m_value.GetValueByteSize(NULL);
Jim Ingham78a685a2011-04-16 00:01:13 +0000121 else
122 return m_parent->GetByteSize();
123}
124
125lldb::ValueType
126ValueObjectDynamicValue::GetValueType() const
127{
128 return m_parent->GetValueType();
129}
130
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000131
132static TypeAndOrName
133FixupTypeAndOrName (const TypeAndOrName& type_andor_name,
134 ValueObject& parent)
135{
136 TypeAndOrName ret(type_andor_name);
137 if (type_andor_name.HasType())
138 {
139 // The type will always be the type of the dynamic object. If our parent's type was a pointer,
140 // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
141 // should be okay...
142 ClangASTType orig_type = type_andor_name.GetClangASTType();
143 ClangASTType corrected_type = orig_type;
144 if (parent.IsPointerType())
145 corrected_type = orig_type.GetPointerType ();
146 else if (parent.IsPointerOrReferenceType())
147 corrected_type = orig_type.GetLValueReferenceType ();
148 ret.SetClangASTType(corrected_type);
149 }
150 else /*if (m_dynamic_type_info.HasName())*/
151 {
152 // If we are here we need to adjust our dynamic type name to include the correct & or * symbol
153 std::string corrected_name (type_andor_name.GetName().GetCString());
154 if (parent.IsPointerType())
155 corrected_name.append(" *");
156 else if (parent.IsPointerOrReferenceType())
157 corrected_name.append(" &");
Enrico Granatafcf0c4e2013-10-31 22:42:00 +0000158 // the parent type should be a correctly pointer'ed or referenc'ed type
159 ret.SetClangASTType(parent.GetClangType());
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000160 ret.SetName(corrected_name.c_str());
161 }
162 return ret;
163}
164
Jim Ingham78a685a2011-04-16 00:01:13 +0000165bool
166ValueObjectDynamicValue::UpdateValue ()
167{
168 SetValueIsValid (false);
169 m_error.Clear();
170
Enrico Granatac3e320a2011-08-02 17:27:39 +0000171 if (!m_parent->UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +0000172 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000173 // The dynamic value failed to get an error, pass the error along
174 if (m_error.Success() && m_parent->GetError().Fail())
175 m_error = m_parent->GetError();
Jim Ingham78a685a2011-04-16 00:01:13 +0000176 return false;
177 }
178
Jim Ingham2837b762011-05-04 03:43:18 +0000179 // Setting our type_sp to NULL will route everything back through our
180 // parent which is equivalent to not using dynamic values.
181 if (m_use_dynamic == lldb::eNoDynamicValues)
182 {
Enrico Granataf7b1a342013-01-23 01:17:27 +0000183 m_dynamic_type_info.Clear();
Jim Ingham2837b762011-05-04 03:43:18 +0000184 return true;
185 }
186
Greg Claytoncc4d0142012-02-17 07:49:44 +0000187 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytonc14ee322011-09-22 04:58:26 +0000188 Target *target = exe_ctx.GetTargetPtr();
189 if (target)
Jim Ingham78a685a2011-04-16 00:01:13 +0000190 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000191 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
192 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
Jim Ingham78a685a2011-04-16 00:01:13 +0000193 }
194
195 // First make sure our Type and/or Address haven't changed:
Greg Claytoncc4d0142012-02-17 07:49:44 +0000196 Process *process = exe_ctx.GetProcessPtr();
Jim Ingham78a685a2011-04-16 00:01:13 +0000197 if (!process)
198 return false;
199
Jim Ingham61be0902011-05-02 18:13:59 +0000200 TypeAndOrName class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000201 Address dynamic_address;
202 bool found_dynamic_type = false;
203
204 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
205 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
206 {
207 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
208 if (runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000209 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000210 }
211 else
212 {
213 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
214 if (cpp_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000215 found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000216
217 if (!found_dynamic_type)
218 {
219 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
220 if (objc_runtime)
Enrico Granata9910bc82011-08-03 02:18:51 +0000221 found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000222 }
223 }
224
Jim Ingham61be0902011-05-02 18:13:59 +0000225 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
226 // don't...
227
228 m_update_point.SetUpdated();
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000229
Enrico Granatadf7c7f92013-10-29 17:42:02 +0000230 if (found_dynamic_type)
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000231 {
Enrico Granatadf7c7f92013-10-29 17:42:02 +0000232 if (class_type_or_name.HasType())
233 {
234 // TypeSP are always generated from debug info
235 if (!class_type_or_name.HasTypeSP() && class_type_or_name.GetClangASTType().IsRuntimeGeneratedType())
236 {
237 m_type_impl = TypeImpl(m_parent->GetClangType(),FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType());
238 class_type_or_name.SetClangASTType(ClangASTType());
239 }
240 else
241 {
242 m_type_impl = TypeImpl(FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType());
243 }
244 }
245 else
246 {
247 m_type_impl.Clear();
248 }
249 }
250 else
251 {
252 m_type_impl.Clear();
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000253 }
Jim Ingham61be0902011-05-02 18:13:59 +0000254
Jim Ingham78a685a2011-04-16 00:01:13 +0000255 // If we don't have a dynamic type, then make ourselves just a echo of our parent.
256 // Or we could return false, and make ourselves an echo of our parent?
257 if (!found_dynamic_type)
258 {
Enrico Granataf7b1a342013-01-23 01:17:27 +0000259 if (m_dynamic_type_info)
Enrico Granata75badc42012-11-27 23:50:00 +0000260 SetValueDidChange(true);
Enrico Granatabd83b872012-11-27 23:28:32 +0000261 ClearDynamicTypeInformation();
Enrico Granataf7b1a342013-01-23 01:17:27 +0000262 m_dynamic_type_info.Clear();
Jim Ingham78a685a2011-04-16 00:01:13 +0000263 m_value = m_parent->GetValue();
Greg Clayton57ee3062013-07-11 22:46:58 +0000264 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000265 return m_error.Success();
266 }
267
268 Value old_value(m_value);
269
Greg Clayton5160ce52013-03-27 23:08:40 +0000270 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granatad2284832012-10-17 22:23:56 +0000271
Enrico Granatae3e91512012-10-22 18:18:36 +0000272 bool has_changed_type = false;
273
Enrico Granataf7b1a342013-01-23 01:17:27 +0000274 if (!m_dynamic_type_info)
Jim Ingham78a685a2011-04-16 00:01:13 +0000275 {
Enrico Granataf7b1a342013-01-23 01:17:27 +0000276 m_dynamic_type_info = class_type_or_name;
Enrico Granatae3e91512012-10-22 18:18:36 +0000277 has_changed_type = true;
Jim Ingham78a685a2011-04-16 00:01:13 +0000278 }
Enrico Granataf7b1a342013-01-23 01:17:27 +0000279 else if (class_type_or_name != m_dynamic_type_info)
Jim Ingham78a685a2011-04-16 00:01:13 +0000280 {
281 // We are another type, we need to tear down our children...
Enrico Granataf7b1a342013-01-23 01:17:27 +0000282 m_dynamic_type_info = class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000283 SetValueDidChange (true);
Enrico Granatae3e91512012-10-22 18:18:36 +0000284 has_changed_type = true;
Jim Ingham78a685a2011-04-16 00:01:13 +0000285 }
286
Enrico Granatae3e91512012-10-22 18:18:36 +0000287 if (has_changed_type)
288 ClearDynamicTypeInformation ();
289
Jim Ingham78a685a2011-04-16 00:01:13 +0000290 if (!m_address.IsValid() || m_address != dynamic_address)
291 {
292 if (m_address.IsValid())
293 SetValueDidChange (true);
294
295 // We've moved, so we should be fine...
296 m_address = dynamic_address;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000297 lldb::TargetSP target_sp (GetTargetSP());
298 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000299 m_value.GetScalar() = load_address;
300 }
301
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000302 m_dynamic_type_info = FixupTypeAndOrName(m_dynamic_type_info, *m_parent);
Enrico Granataf7b1a342013-01-23 01:17:27 +0000303
Greg Clayton57ee3062013-07-11 22:46:58 +0000304 //m_value.SetContext (Value::eContextTypeClangType, corrected_type);
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000305 m_value.SetClangType (m_dynamic_type_info.GetClangASTType());
Jim Ingham78a685a2011-04-16 00:01:13 +0000306
307 // Our address is the location of the dynamic type stored in memory. It isn't a load address,
308 // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
309 m_value.SetValueType(Value::eValueTypeScalar);
310
Enrico Granatae3e91512012-10-22 18:18:36 +0000311 if (has_changed_type && log)
312 log->Printf("[%s %p] has a new dynamic type %s",
313 GetName().GetCString(),
314 this,
315 GetTypeName().GetCString());
316
Enrico Granataf7b1a342013-01-23 01:17:27 +0000317 if (m_address.IsValid() && m_dynamic_type_info)
Jim Ingham78a685a2011-04-16 00:01:13 +0000318 {
319 // The variable value is in the Scalar value inside the m_value.
320 // We can point our m_data right to it.
Greg Clayton57ee3062013-07-11 22:46:58 +0000321 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000322 if (m_error.Success())
323 {
Greg Clayton57ee3062013-07-11 22:46:58 +0000324 if (GetClangType().IsAggregateType ())
Jim Ingham78a685a2011-04-16 00:01:13 +0000325 {
326 // this value object represents an aggregate type whose
327 // children have values, but this object does not. So we
328 // say we are changed if our location has changed.
329 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
330 }
331
332 SetValueIsValid (true);
333 return true;
334 }
335 }
336
337 // We get here if we've failed above...
338 SetValueIsValid (false);
339 return false;
340}
341
342
343
344bool
345ValueObjectDynamicValue::IsInScope ()
346{
347 return m_parent->IsInScope();
348}
349
Enrico Granata07a4ac22012-05-08 21:25:06 +0000350bool
351ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
352{
353 if (!UpdateValueIfNeeded(false))
354 {
355 error.SetErrorString("unable to read value");
356 return false;
357 }
358
359 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
360 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
361
362 if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
363 {
364 error.SetErrorString("unable to read value");
365 return false;
366 }
367
368 // if we are at an offset from our parent, in order to set ourselves correctly we would need
369 // to change the new value so that it refers to the correct dynamic type. we choose not to deal
370 // with that - if anything more than a value overwrite is required, you should be using the
371 // expression parser instead of the value editing facility
372 if (my_value != parent_value)
373 {
374 // but NULL'ing out a value should always be allowed
375 if (strcmp(value_str,"0"))
376 {
377 error.SetErrorString("unable to modify dynamic value, use 'expression' command");
378 return false;
379 }
380 }
381
382 bool ret_val = m_parent->SetValueFromCString(value_str,error);
383 SetNeedsUpdate();
384 return ret_val;
385}
Sean Callanan389823e2013-04-13 01:21:23 +0000386
387bool
388ValueObjectDynamicValue::SetData (DataExtractor &data, Error &error)
389{
390 if (!UpdateValueIfNeeded(false))
391 {
392 error.SetErrorString("unable to read value");
393 return false;
394 }
395
396 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
397 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
398
399 if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
400 {
401 error.SetErrorString("unable to read value");
402 return false;
403 }
404
405 // if we are at an offset from our parent, in order to set ourselves correctly we would need
406 // to change the new value so that it refers to the correct dynamic type. we choose not to deal
407 // with that - if anything more than a value overwrite is required, you should be using the
408 // expression parser instead of the value editing facility
409 if (my_value != parent_value)
410 {
411 // but NULL'ing out a value should always be allowed
412 lldb::offset_t offset = 0;
413
414 if (data.GetPointer(&offset) != 0)
415 {
416 error.SetErrorString("unable to modify dynamic value, use 'expression' command");
417 return false;
418 }
419 }
420
421 bool ret_val = m_parent->SetData(data, error);
422 SetNeedsUpdate();
423 return ret_val;
424}