blob: 6fd4ee88592829d819b7f0a8ea782739b86923ee [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
17#include "lldb/Core/Module.h"
18#include "lldb/Core/ValueObjectList.h"
19#include "lldb/Core/Value.h"
20#include "lldb/Core/ValueObject.h"
21
22#include "lldb/Symbol/ObjectFile.h"
23#include "lldb/Symbol/SymbolContext.h"
24#include "lldb/Symbol/Type.h"
25#include "lldb/Symbol/Variable.h"
26
27#include "lldb/Target/ExecutionContext.h"
28#include "lldb/Target/LanguageRuntime.h"
29#include "lldb/Target/Process.h"
30#include "lldb/Target/RegisterContext.h"
31#include "lldb/Target/Target.h"
32#include "lldb/Target/Thread.h"
33
34
35using namespace lldb_private;
36
Greg Clayton81e871e2012-02-04 02:27:34 +000037lldb::ValueObjectSP
38ValueObjectCast::Create (ValueObject &parent,
39 const ConstString &name,
40 const ClangASTType &cast_type)
41{
42 ValueObjectCast *cast_valobj_ptr = new ValueObjectCast (parent, name, cast_type);
43 return cast_valobj_ptr->GetSP();
44}
Greg Clayton9a142cf2012-02-03 05:34:10 +000045
46ValueObjectCast::ValueObjectCast
47(
48 ValueObject &parent,
49 const ConstString &name,
50 const ClangASTType &cast_type
51) :
52 ValueObject(parent),
53 m_cast_type (cast_type)
54{
55 SetName (name);
56 m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType());
57}
58
59ValueObjectCast::~ValueObjectCast()
60{
61}
62
63lldb::clang_type_t
Sean Callanan72772842012-02-22 23:57:45 +000064ValueObjectCast::GetClangTypeImpl ()
Greg Clayton9a142cf2012-02-03 05:34:10 +000065{
66 return m_cast_type.GetOpaqueQualType();
67}
68
Greg Clayton9a142cf2012-02-03 05:34:10 +000069uint32_t
70ValueObjectCast::CalculateNumChildren()
71{
72 return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
73}
74
75clang::ASTContext *
Sean Callanan72772842012-02-22 23:57:45 +000076ValueObjectCast::GetClangASTImpl ()
Greg Clayton9a142cf2012-02-03 05:34:10 +000077{
78 return m_cast_type.GetASTContext();
79}
80
81size_t
82ValueObjectCast::GetByteSize()
83{
84 return m_value.GetValueByteSize(GetClangAST(), NULL);
85}
86
87lldb::ValueType
88ValueObjectCast::GetValueType() const
89{
90 // Let our parent answer global, local, argument, etc...
91 return m_parent->GetValueType();
92}
93
94bool
95ValueObjectCast::UpdateValue ()
96{
97 SetValueIsValid (false);
98 m_error.Clear();
99
100 if (m_parent->UpdateValueIfNeeded(false))
101 {
102 Value old_value(m_value);
103 m_update_point.SetUpdated();
104 m_value = m_parent->GetValue();
105 m_value.SetContext (Value::eContextTypeClangType, GetClangType());
106 SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
107 if (ClangASTContext::IsAggregateType (GetClangType()))
108 {
109 // this value object represents an aggregate type whose
110 // children have values, but this object does not. So we
111 // say we are changed if our location has changed.
112 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
113 }
Greg Claytoncc4d0142012-02-17 07:49:44 +0000114 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytone72dfb32012-02-24 01:59:29 +0000115 m_error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Greg Clayton9a142cf2012-02-03 05:34:10 +0000116 SetValueDidChange (m_parent->GetValueDidChange());
117 return true;
118 }
119
120 // The dynamic value failed to get an error, pass the error along
121 if (m_error.Success() && m_parent->GetError().Fail())
122 m_error = m_parent->GetError();
123 SetValueIsValid (false);
124 return false;
125}
126
127
128
129bool
130ValueObjectCast::IsInScope ()
131{
132 return m_parent->IsInScope();
133}
134
135//----------------------------------------------------------------------
136
137
138
139
Jim Ingham2837b762011-05-04 03:43:18 +0000140ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
Jim Ingham78a685a2011-04-16 00:01:13 +0000141 ValueObject(parent),
142 m_address (),
Jim Ingham2837b762011-05-04 03:43:18 +0000143 m_type_sp(),
144 m_use_dynamic (use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +0000145{
Enrico Granatad8b5fce2011-08-02 23:12:24 +0000146 m_last_format_mgr_dynamic = use_dynamic;
Enrico Granata6f3533f2011-07-29 19:53:35 +0000147 SetName (parent.GetName());
Jim Ingham78a685a2011-04-16 00:01:13 +0000148}
149
150ValueObjectDynamicValue::~ValueObjectDynamicValue()
151{
152 m_owning_valobj_sp.reset();
153}
154
155lldb::clang_type_t
Sean Callanan72772842012-02-22 23:57:45 +0000156ValueObjectDynamicValue::GetClangTypeImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +0000157{
158 if (m_type_sp)
159 return m_value.GetClangType();
160 else
161 return m_parent->GetClangType();
162}
163
164ConstString
165ValueObjectDynamicValue::GetTypeName()
166{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000167 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000168 if (success && m_type_sp)
Greg Clayton84db9102012-03-26 23:03:23 +0000169 return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
Jim Ingham78a685a2011-04-16 00:01:13 +0000170 else
171 return m_parent->GetTypeName();
172}
173
174uint32_t
175ValueObjectDynamicValue::CalculateNumChildren()
176{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000177 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000178 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000179 return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
180 else
181 return m_parent->GetNumChildren();
182}
183
184clang::ASTContext *
Sean Callanan72772842012-02-22 23:57:45 +0000185ValueObjectDynamicValue::GetClangASTImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +0000186{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000187 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000188 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000189 return m_type_sp->GetClangAST();
190 else
191 return m_parent->GetClangAST ();
192}
193
194size_t
195ValueObjectDynamicValue::GetByteSize()
196{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000197 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000198 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000199 return m_value.GetValueByteSize(GetClangAST(), NULL);
200 else
201 return m_parent->GetByteSize();
202}
203
204lldb::ValueType
205ValueObjectDynamicValue::GetValueType() const
206{
207 return m_parent->GetValueType();
208}
209
210bool
211ValueObjectDynamicValue::UpdateValue ()
212{
213 SetValueIsValid (false);
214 m_error.Clear();
215
Enrico Granatac3e320a2011-08-02 17:27:39 +0000216 if (!m_parent->UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +0000217 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000218 // The dynamic value failed to get an error, pass the error along
219 if (m_error.Success() && m_parent->GetError().Fail())
220 m_error = m_parent->GetError();
Jim Ingham78a685a2011-04-16 00:01:13 +0000221 return false;
222 }
223
Jim Ingham2837b762011-05-04 03:43:18 +0000224 // Setting our type_sp to NULL will route everything back through our
225 // parent which is equivalent to not using dynamic values.
226 if (m_use_dynamic == lldb::eNoDynamicValues)
227 {
228 m_type_sp.reset();
229 return true;
230 }
231
Greg Claytoncc4d0142012-02-17 07:49:44 +0000232 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytonc14ee322011-09-22 04:58:26 +0000233 Target *target = exe_ctx.GetTargetPtr();
234 if (target)
Jim Ingham78a685a2011-04-16 00:01:13 +0000235 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000236 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
237 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
Jim Ingham78a685a2011-04-16 00:01:13 +0000238 }
239
240 // First make sure our Type and/or Address haven't changed:
Greg Claytoncc4d0142012-02-17 07:49:44 +0000241 Process *process = exe_ctx.GetProcessPtr();
Jim Ingham78a685a2011-04-16 00:01:13 +0000242 if (!process)
243 return false;
244
Jim Ingham61be0902011-05-02 18:13:59 +0000245 TypeAndOrName class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000246 Address dynamic_address;
247 bool found_dynamic_type = false;
248
249 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
250 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
251 {
252 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
253 if (runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000254 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000255 }
256 else
257 {
258 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
259 if (cpp_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000260 found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000261
262 if (!found_dynamic_type)
263 {
264 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
265 if (objc_runtime)
Enrico Granata9910bc82011-08-03 02:18:51 +0000266 found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000267 }
268 }
269
Jim Ingham61be0902011-05-02 18:13:59 +0000270 lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP();
271
272 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
273 // don't...
274
275 m_update_point.SetUpdated();
276
Jim Ingham78a685a2011-04-16 00:01:13 +0000277 // If we don't have a dynamic type, then make ourselves just a echo of our parent.
278 // Or we could return false, and make ourselves an echo of our parent?
279 if (!found_dynamic_type)
280 {
281 if (m_type_sp)
282 SetValueDidChange(true);
283 m_value = m_parent->GetValue();
Greg Claytone72dfb32012-02-24 01:59:29 +0000284 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000285 return m_error.Success();
286 }
287
288 Value old_value(m_value);
289
290 if (!m_type_sp)
291 {
292 m_type_sp = dynamic_type_sp;
293 }
294 else if (dynamic_type_sp != m_type_sp)
295 {
296 // We are another type, we need to tear down our children...
297 m_type_sp = dynamic_type_sp;
298 SetValueDidChange (true);
299 }
300
301 if (!m_address.IsValid() || m_address != dynamic_address)
302 {
303 if (m_address.IsValid())
304 SetValueDidChange (true);
305
306 // We've moved, so we should be fine...
307 m_address = dynamic_address;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000308 lldb::TargetSP target_sp (GetTargetSP());
309 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000310 m_value.GetScalar() = load_address;
311 }
312
313 // The type will always be the type of the dynamic object. If our parent's type was a pointer,
314 // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
315 // should be okay...
316 lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType();
317 lldb::clang_type_t corrected_type = orig_type;
318 if (m_parent->IsPointerType())
319 corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type);
320 else if (m_parent->IsPointerOrReferenceType())
321 corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type);
322
323 m_value.SetContext (Value::eContextTypeClangType, corrected_type);
324
325 // Our address is the location of the dynamic type stored in memory. It isn't a load address,
326 // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
327 m_value.SetValueType(Value::eValueTypeScalar);
328
329 if (m_address.IsValid() && m_type_sp)
330 {
331 // The variable value is in the Scalar value inside the m_value.
332 // We can point our m_data right to it.
Greg Claytone72dfb32012-02-24 01:59:29 +0000333 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000334 if (m_error.Success())
335 {
336 if (ClangASTContext::IsAggregateType (GetClangType()))
337 {
338 // this value object represents an aggregate type whose
339 // children have values, but this object does not. So we
340 // say we are changed if our location has changed.
341 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
342 }
343
344 SetValueIsValid (true);
345 return true;
346 }
347 }
348
349 // We get here if we've failed above...
350 SetValueIsValid (false);
351 return false;
352}
353
354
355
356bool
357ValueObjectDynamicValue::IsInScope ()
358{
359 return m_parent->IsInScope();
360}
361