blob: dfddbd97c9521f0164b29b189f0fcb0ad26ce230 [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
23#include "lldb/Symbol/ObjectFile.h"
24#include "lldb/Symbol/SymbolContext.h"
25#include "lldb/Symbol/Type.h"
26#include "lldb/Symbol/Variable.h"
27
28#include "lldb/Target/ExecutionContext.h"
29#include "lldb/Target/LanguageRuntime.h"
30#include "lldb/Target/Process.h"
31#include "lldb/Target/RegisterContext.h"
32#include "lldb/Target/Target.h"
33#include "lldb/Target/Thread.h"
34
35
36using namespace lldb_private;
37
Greg Clayton81e871e2012-02-04 02:27:34 +000038lldb::ValueObjectSP
39ValueObjectCast::Create (ValueObject &parent,
40 const ConstString &name,
41 const ClangASTType &cast_type)
42{
43 ValueObjectCast *cast_valobj_ptr = new ValueObjectCast (parent, name, cast_type);
44 return cast_valobj_ptr->GetSP();
45}
Greg Clayton9a142cf2012-02-03 05:34:10 +000046
47ValueObjectCast::ValueObjectCast
48(
49 ValueObject &parent,
50 const ConstString &name,
51 const ClangASTType &cast_type
52) :
53 ValueObject(parent),
54 m_cast_type (cast_type)
55{
56 SetName (name);
57 m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType());
58}
59
60ValueObjectCast::~ValueObjectCast()
61{
62}
63
64lldb::clang_type_t
Sean Callanan72772842012-02-22 23:57:45 +000065ValueObjectCast::GetClangTypeImpl ()
Greg Clayton9a142cf2012-02-03 05:34:10 +000066{
67 return m_cast_type.GetOpaqueQualType();
68}
69
Greg Clayton9a142cf2012-02-03 05:34:10 +000070uint32_t
71ValueObjectCast::CalculateNumChildren()
72{
73 return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
74}
75
76clang::ASTContext *
Sean Callanan72772842012-02-22 23:57:45 +000077ValueObjectCast::GetClangASTImpl ()
Greg Clayton9a142cf2012-02-03 05:34:10 +000078{
79 return m_cast_type.GetASTContext();
80}
81
82size_t
83ValueObjectCast::GetByteSize()
84{
85 return m_value.GetValueByteSize(GetClangAST(), NULL);
86}
87
88lldb::ValueType
89ValueObjectCast::GetValueType() const
90{
91 // Let our parent answer global, local, argument, etc...
92 return m_parent->GetValueType();
93}
94
95bool
96ValueObjectCast::UpdateValue ()
97{
98 SetValueIsValid (false);
99 m_error.Clear();
100
101 if (m_parent->UpdateValueIfNeeded(false))
102 {
103 Value old_value(m_value);
104 m_update_point.SetUpdated();
105 m_value = m_parent->GetValue();
106 m_value.SetContext (Value::eContextTypeClangType, GetClangType());
107 SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
108 if (ClangASTContext::IsAggregateType (GetClangType()))
109 {
110 // this value object represents an aggregate type whose
111 // children have values, but this object does not. So we
112 // say we are changed if our location has changed.
113 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
114 }
Greg Claytoncc4d0142012-02-17 07:49:44 +0000115 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytone72dfb32012-02-24 01:59:29 +0000116 m_error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Greg Clayton9a142cf2012-02-03 05:34:10 +0000117 SetValueDidChange (m_parent->GetValueDidChange());
118 return true;
119 }
120
121 // The dynamic value failed to get an error, pass the error along
122 if (m_error.Success() && m_parent->GetError().Fail())
123 m_error = m_parent->GetError();
124 SetValueIsValid (false);
125 return false;
126}
127
128
129
130bool
131ValueObjectCast::IsInScope ()
132{
133 return m_parent->IsInScope();
134}
135
136//----------------------------------------------------------------------
137
138
139
140
Jim Ingham2837b762011-05-04 03:43:18 +0000141ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
Jim Ingham78a685a2011-04-16 00:01:13 +0000142 ValueObject(parent),
143 m_address (),
Jim Ingham2837b762011-05-04 03:43:18 +0000144 m_type_sp(),
145 m_use_dynamic (use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +0000146{
Enrico Granatad8b5fce2011-08-02 23:12:24 +0000147 m_last_format_mgr_dynamic = use_dynamic;
Enrico Granata6f3533f2011-07-29 19:53:35 +0000148 SetName (parent.GetName());
Jim Ingham78a685a2011-04-16 00:01:13 +0000149}
150
151ValueObjectDynamicValue::~ValueObjectDynamicValue()
152{
153 m_owning_valobj_sp.reset();
154}
155
156lldb::clang_type_t
Sean Callanan72772842012-02-22 23:57:45 +0000157ValueObjectDynamicValue::GetClangTypeImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +0000158{
159 if (m_type_sp)
160 return m_value.GetClangType();
161 else
162 return m_parent->GetClangType();
163}
164
165ConstString
166ValueObjectDynamicValue::GetTypeName()
167{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000168 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000169 if (success && m_type_sp)
Greg Clayton84db9102012-03-26 23:03:23 +0000170 return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
Jim Ingham78a685a2011-04-16 00:01:13 +0000171 else
172 return m_parent->GetTypeName();
173}
174
175uint32_t
176ValueObjectDynamicValue::CalculateNumChildren()
177{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000178 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000179 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000180 return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
181 else
182 return m_parent->GetNumChildren();
183}
184
185clang::ASTContext *
Sean Callanan72772842012-02-22 23:57:45 +0000186ValueObjectDynamicValue::GetClangASTImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +0000187{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000188 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000189 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000190 return m_type_sp->GetClangAST();
191 else
192 return m_parent->GetClangAST ();
193}
194
195size_t
196ValueObjectDynamicValue::GetByteSize()
197{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000198 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000199 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000200 return m_value.GetValueByteSize(GetClangAST(), NULL);
201 else
202 return m_parent->GetByteSize();
203}
204
205lldb::ValueType
206ValueObjectDynamicValue::GetValueType() const
207{
208 return m_parent->GetValueType();
209}
210
211bool
212ValueObjectDynamicValue::UpdateValue ()
213{
214 SetValueIsValid (false);
215 m_error.Clear();
216
Enrico Granatac3e320a2011-08-02 17:27:39 +0000217 if (!m_parent->UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +0000218 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000219 // The dynamic value failed to get an error, pass the error along
220 if (m_error.Success() && m_parent->GetError().Fail())
221 m_error = m_parent->GetError();
Jim Ingham78a685a2011-04-16 00:01:13 +0000222 return false;
223 }
224
Jim Ingham2837b762011-05-04 03:43:18 +0000225 // Setting our type_sp to NULL will route everything back through our
226 // parent which is equivalent to not using dynamic values.
227 if (m_use_dynamic == lldb::eNoDynamicValues)
228 {
229 m_type_sp.reset();
230 return true;
231 }
232
Greg Claytoncc4d0142012-02-17 07:49:44 +0000233 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytonc14ee322011-09-22 04:58:26 +0000234 Target *target = exe_ctx.GetTargetPtr();
235 if (target)
Jim Ingham78a685a2011-04-16 00:01:13 +0000236 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000237 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
238 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
Jim Ingham78a685a2011-04-16 00:01:13 +0000239 }
240
241 // First make sure our Type and/or Address haven't changed:
Greg Claytoncc4d0142012-02-17 07:49:44 +0000242 Process *process = exe_ctx.GetProcessPtr();
Jim Ingham78a685a2011-04-16 00:01:13 +0000243 if (!process)
244 return false;
245
Jim Ingham61be0902011-05-02 18:13:59 +0000246 TypeAndOrName class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000247 Address dynamic_address;
248 bool found_dynamic_type = false;
249
250 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
251 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
252 {
253 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
254 if (runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000255 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000256 }
257 else
258 {
259 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
260 if (cpp_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000261 found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000262
263 if (!found_dynamic_type)
264 {
265 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
266 if (objc_runtime)
Enrico Granata9910bc82011-08-03 02:18:51 +0000267 found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000268 }
269 }
270
Jim Ingham61be0902011-05-02 18:13:59 +0000271 lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP();
272
273 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
274 // don't...
275
276 m_update_point.SetUpdated();
277
Jim Ingham78a685a2011-04-16 00:01:13 +0000278 // If we don't have a dynamic type, then make ourselves just a echo of our parent.
279 // Or we could return false, and make ourselves an echo of our parent?
280 if (!found_dynamic_type)
281 {
282 if (m_type_sp)
283 SetValueDidChange(true);
284 m_value = m_parent->GetValue();
Greg Claytone72dfb32012-02-24 01:59:29 +0000285 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000286 return m_error.Success();
287 }
288
289 Value old_value(m_value);
290
Enrico Granatad2284832012-10-17 22:23:56 +0000291 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
292
Enrico Granatae3e91512012-10-22 18:18:36 +0000293 bool has_changed_type = false;
294
Jim Ingham78a685a2011-04-16 00:01:13 +0000295 if (!m_type_sp)
296 {
297 m_type_sp = dynamic_type_sp;
Enrico Granatae3e91512012-10-22 18:18:36 +0000298 has_changed_type = true;
Jim Ingham78a685a2011-04-16 00:01:13 +0000299 }
300 else if (dynamic_type_sp != m_type_sp)
301 {
302 // We are another type, we need to tear down our children...
303 m_type_sp = dynamic_type_sp;
304 SetValueDidChange (true);
Enrico Granatae3e91512012-10-22 18:18:36 +0000305 has_changed_type = true;
Jim Ingham78a685a2011-04-16 00:01:13 +0000306 }
307
Enrico Granatae3e91512012-10-22 18:18:36 +0000308 if (has_changed_type)
309 ClearDynamicTypeInformation ();
310
Jim Ingham78a685a2011-04-16 00:01:13 +0000311 if (!m_address.IsValid() || m_address != dynamic_address)
312 {
313 if (m_address.IsValid())
314 SetValueDidChange (true);
315
316 // We've moved, so we should be fine...
317 m_address = dynamic_address;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000318 lldb::TargetSP target_sp (GetTargetSP());
319 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000320 m_value.GetScalar() = load_address;
321 }
322
323 // The type will always be the type of the dynamic object. If our parent's type was a pointer,
324 // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
325 // should be okay...
326 lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType();
327 lldb::clang_type_t corrected_type = orig_type;
328 if (m_parent->IsPointerType())
329 corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type);
330 else if (m_parent->IsPointerOrReferenceType())
331 corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type);
332
333 m_value.SetContext (Value::eContextTypeClangType, corrected_type);
334
335 // Our address is the location of the dynamic type stored in memory. It isn't a load address,
336 // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
337 m_value.SetValueType(Value::eValueTypeScalar);
338
Enrico Granatae3e91512012-10-22 18:18:36 +0000339 if (has_changed_type && log)
340 log->Printf("[%s %p] has a new dynamic type %s",
341 GetName().GetCString(),
342 this,
343 GetTypeName().GetCString());
344
Jim Ingham78a685a2011-04-16 00:01:13 +0000345 if (m_address.IsValid() && m_type_sp)
346 {
347 // The variable value is in the Scalar value inside the m_value.
348 // We can point our m_data right to it.
Greg Claytone72dfb32012-02-24 01:59:29 +0000349 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000350 if (m_error.Success())
351 {
352 if (ClangASTContext::IsAggregateType (GetClangType()))
353 {
354 // this value object represents an aggregate type whose
355 // children have values, but this object does not. So we
356 // say we are changed if our location has changed.
357 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
358 }
359
360 SetValueIsValid (true);
361 return true;
362 }
363 }
364
365 // We get here if we've failed above...
366 SetValueIsValid (false);
367 return false;
368}
369
370
371
372bool
373ValueObjectDynamicValue::IsInScope ()
374{
375 return m_parent->IsInScope();
376}
377
Enrico Granata07a4ac22012-05-08 21:25:06 +0000378bool
379ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
380{
381 if (!UpdateValueIfNeeded(false))
382 {
383 error.SetErrorString("unable to read value");
384 return false;
385 }
386
387 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
388 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
389
390 if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
391 {
392 error.SetErrorString("unable to read value");
393 return false;
394 }
395
396 // if we are at an offset from our parent, in order to set ourselves correctly we would need
397 // to change the new value so that it refers to the correct dynamic type. we choose not to deal
398 // with that - if anything more than a value overwrite is required, you should be using the
399 // expression parser instead of the value editing facility
400 if (my_value != parent_value)
401 {
402 // but NULL'ing out a value should always be allowed
403 if (strcmp(value_str,"0"))
404 {
405 error.SetErrorString("unable to modify dynamic value, use 'expression' command");
406 return false;
407 }
408 }
409
410 bool ret_val = m_parent->SetValueFromCString(value_str,error);
411 SetNeedsUpdate();
412 return ret_val;
413}