blob: b55d927b760547843e6125ed85dbe4ec2afb03bb [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 Clayton9a142cf2012-02-03 05:34:10 +000037
38ValueObjectCast::ValueObjectCast
39(
40 ValueObject &parent,
41 const ConstString &name,
42 const ClangASTType &cast_type
43) :
44 ValueObject(parent),
45 m_cast_type (cast_type)
46{
47 SetName (name);
48 m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType());
49}
50
51ValueObjectCast::~ValueObjectCast()
52{
53}
54
55lldb::clang_type_t
56ValueObjectCast::GetClangType ()
57{
58 return m_cast_type.GetOpaqueQualType();
59}
60
61ConstString
62ValueObjectCast::GetTypeName()
63{
64 return ClangASTType::GetConstTypeName (GetClangType());
65}
66
67uint32_t
68ValueObjectCast::CalculateNumChildren()
69{
70 return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
71}
72
73clang::ASTContext *
74ValueObjectCast::GetClangAST ()
75{
76 return m_cast_type.GetASTContext();
77}
78
79size_t
80ValueObjectCast::GetByteSize()
81{
82 return m_value.GetValueByteSize(GetClangAST(), NULL);
83}
84
85lldb::ValueType
86ValueObjectCast::GetValueType() const
87{
88 // Let our parent answer global, local, argument, etc...
89 return m_parent->GetValueType();
90}
91
92bool
93ValueObjectCast::UpdateValue ()
94{
95 SetValueIsValid (false);
96 m_error.Clear();
97
98 if (m_parent->UpdateValueIfNeeded(false))
99 {
100 Value old_value(m_value);
101 m_update_point.SetUpdated();
102 m_value = m_parent->GetValue();
103 m_value.SetContext (Value::eContextTypeClangType, GetClangType());
104 SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
105 if (ClangASTContext::IsAggregateType (GetClangType()))
106 {
107 // this value object represents an aggregate type whose
108 // children have values, but this object does not. So we
109 // say we are changed if our location has changed.
110 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
111 }
112 ExecutionContext exe_ctx (GetExecutionContextScope());
113 m_error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule());
114 SetValueDidChange (m_parent->GetValueDidChange());
115 return true;
116 }
117
118 // The dynamic value failed to get an error, pass the error along
119 if (m_error.Success() && m_parent->GetError().Fail())
120 m_error = m_parent->GetError();
121 SetValueIsValid (false);
122 return false;
123}
124
125
126
127bool
128ValueObjectCast::IsInScope ()
129{
130 return m_parent->IsInScope();
131}
132
133//----------------------------------------------------------------------
134
135
136
137
Jim Ingham2837b762011-05-04 03:43:18 +0000138ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
Jim Ingham78a685a2011-04-16 00:01:13 +0000139 ValueObject(parent),
140 m_address (),
Jim Ingham2837b762011-05-04 03:43:18 +0000141 m_type_sp(),
142 m_use_dynamic (use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +0000143{
Enrico Granatad8b5fce2011-08-02 23:12:24 +0000144 m_last_format_mgr_dynamic = use_dynamic;
Enrico Granata6f3533f2011-07-29 19:53:35 +0000145 SetName (parent.GetName());
Jim Ingham78a685a2011-04-16 00:01:13 +0000146}
147
148ValueObjectDynamicValue::~ValueObjectDynamicValue()
149{
150 m_owning_valobj_sp.reset();
151}
152
153lldb::clang_type_t
154ValueObjectDynamicValue::GetClangType ()
155{
156 if (m_type_sp)
157 return m_value.GetClangType();
158 else
159 return m_parent->GetClangType();
160}
161
162ConstString
163ValueObjectDynamicValue::GetTypeName()
164{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000165 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000166 if (success && m_type_sp)
Greg Claytone3055942011-06-30 02:28:26 +0000167 return ClangASTType::GetConstTypeName (GetClangType());
Jim Ingham78a685a2011-04-16 00:01:13 +0000168 else
169 return m_parent->GetTypeName();
170}
171
172uint32_t
173ValueObjectDynamicValue::CalculateNumChildren()
174{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000175 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000176 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000177 return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
178 else
179 return m_parent->GetNumChildren();
180}
181
182clang::ASTContext *
183ValueObjectDynamicValue::GetClangAST ()
184{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000185 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000186 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000187 return m_type_sp->GetClangAST();
188 else
189 return m_parent->GetClangAST ();
190}
191
192size_t
193ValueObjectDynamicValue::GetByteSize()
194{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000195 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000196 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000197 return m_value.GetValueByteSize(GetClangAST(), NULL);
198 else
199 return m_parent->GetByteSize();
200}
201
202lldb::ValueType
203ValueObjectDynamicValue::GetValueType() const
204{
205 return m_parent->GetValueType();
206}
207
208bool
209ValueObjectDynamicValue::UpdateValue ()
210{
211 SetValueIsValid (false);
212 m_error.Clear();
213
Enrico Granatac3e320a2011-08-02 17:27:39 +0000214 if (!m_parent->UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +0000215 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000216 // The dynamic value failed to get an error, pass the error along
217 if (m_error.Success() && m_parent->GetError().Fail())
218 m_error = m_parent->GetError();
Jim Ingham78a685a2011-04-16 00:01:13 +0000219 return false;
220 }
221
Jim Ingham2837b762011-05-04 03:43:18 +0000222 // Setting our type_sp to NULL will route everything back through our
223 // parent which is equivalent to not using dynamic values.
224 if (m_use_dynamic == lldb::eNoDynamicValues)
225 {
226 m_type_sp.reset();
227 return true;
228 }
229
Jim Ingham78a685a2011-04-16 00:01:13 +0000230 ExecutionContext exe_ctx (GetExecutionContextScope());
Greg Claytonc14ee322011-09-22 04:58:26 +0000231 Target *target = exe_ctx.GetTargetPtr();
232 if (target)
Jim Ingham78a685a2011-04-16 00:01:13 +0000233 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000234 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
235 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
Jim Ingham78a685a2011-04-16 00:01:13 +0000236 }
237
238 // First make sure our Type and/or Address haven't changed:
Enrico Granata6f3533f2011-07-29 19:53:35 +0000239 Process *process = m_update_point.GetProcessSP().get();
Jim Ingham78a685a2011-04-16 00:01:13 +0000240 if (!process)
241 return false;
242
Jim Ingham61be0902011-05-02 18:13:59 +0000243 TypeAndOrName class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000244 Address dynamic_address;
245 bool found_dynamic_type = false;
246
247 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
248 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
249 {
250 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
251 if (runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000252 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000253 }
254 else
255 {
256 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
257 if (cpp_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000258 found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000259
260 if (!found_dynamic_type)
261 {
262 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
263 if (objc_runtime)
Enrico Granata9910bc82011-08-03 02:18:51 +0000264 found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000265 }
266 }
267
Jim Ingham61be0902011-05-02 18:13:59 +0000268 lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP();
269
270 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
271 // don't...
272
273 m_update_point.SetUpdated();
274
Jim Ingham78a685a2011-04-16 00:01:13 +0000275 // If we don't have a dynamic type, then make ourselves just a echo of our parent.
276 // Or we could return false, and make ourselves an echo of our parent?
277 if (!found_dynamic_type)
278 {
279 if (m_type_sp)
280 SetValueDidChange(true);
281 m_value = m_parent->GetValue();
Greg Clayton644247c2011-07-07 01:59:51 +0000282 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule());
Jim Ingham78a685a2011-04-16 00:01:13 +0000283 return m_error.Success();
284 }
285
286 Value old_value(m_value);
287
288 if (!m_type_sp)
289 {
290 m_type_sp = dynamic_type_sp;
291 }
292 else if (dynamic_type_sp != m_type_sp)
293 {
294 // We are another type, we need to tear down our children...
295 m_type_sp = dynamic_type_sp;
296 SetValueDidChange (true);
297 }
298
299 if (!m_address.IsValid() || m_address != dynamic_address)
300 {
301 if (m_address.IsValid())
302 SetValueDidChange (true);
303
304 // We've moved, so we should be fine...
305 m_address = dynamic_address;
Enrico Granata6f3533f2011-07-29 19:53:35 +0000306 lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTargetSP().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000307 m_value.GetScalar() = load_address;
308 }
309
310 // The type will always be the type of the dynamic object. If our parent's type was a pointer,
311 // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
312 // should be okay...
313 lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType();
314 lldb::clang_type_t corrected_type = orig_type;
315 if (m_parent->IsPointerType())
316 corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type);
317 else if (m_parent->IsPointerOrReferenceType())
318 corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type);
319
320 m_value.SetContext (Value::eContextTypeClangType, corrected_type);
321
322 // Our address is the location of the dynamic type stored in memory. It isn't a load address,
323 // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
324 m_value.SetValueType(Value::eValueTypeScalar);
325
326 if (m_address.IsValid() && m_type_sp)
327 {
328 // The variable value is in the Scalar value inside the m_value.
329 // We can point our m_data right to it.
Greg Clayton644247c2011-07-07 01:59:51 +0000330 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule());
Jim Ingham78a685a2011-04-16 00:01:13 +0000331 if (m_error.Success())
332 {
333 if (ClangASTContext::IsAggregateType (GetClangType()))
334 {
335 // this value object represents an aggregate type whose
336 // children have values, but this object does not. So we
337 // say we are changed if our location has changed.
338 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
339 }
340
341 SetValueIsValid (true);
342 return true;
343 }
344 }
345
346 // We get here if we've failed above...
347 SetValueIsValid (false);
348 return false;
349}
350
351
352
353bool
354ValueObjectDynamicValue::IsInScope ()
355{
356 return m_parent->IsInScope();
357}
358