blob: b336a7fa27478dada4a501ff943b0443c41eb7c7 [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
69ConstString
70ValueObjectCast::GetTypeName()
71{
72 return ClangASTType::GetConstTypeName (GetClangType());
73}
74
75uint32_t
76ValueObjectCast::CalculateNumChildren()
77{
78 return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
79}
80
81clang::ASTContext *
Sean Callanan72772842012-02-22 23:57:45 +000082ValueObjectCast::GetClangASTImpl ()
Greg Clayton9a142cf2012-02-03 05:34:10 +000083{
84 return m_cast_type.GetASTContext();
85}
86
87size_t
88ValueObjectCast::GetByteSize()
89{
90 return m_value.GetValueByteSize(GetClangAST(), NULL);
91}
92
93lldb::ValueType
94ValueObjectCast::GetValueType() const
95{
96 // Let our parent answer global, local, argument, etc...
97 return m_parent->GetValueType();
98}
99
100bool
101ValueObjectCast::UpdateValue ()
102{
103 SetValueIsValid (false);
104 m_error.Clear();
105
106 if (m_parent->UpdateValueIfNeeded(false))
107 {
108 Value old_value(m_value);
109 m_update_point.SetUpdated();
110 m_value = m_parent->GetValue();
111 m_value.SetContext (Value::eContextTypeClangType, GetClangType());
112 SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
113 if (ClangASTContext::IsAggregateType (GetClangType()))
114 {
115 // this value object represents an aggregate type whose
116 // children have values, but this object does not. So we
117 // say we are changed if our location has changed.
118 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
119 }
Greg Claytoncc4d0142012-02-17 07:49:44 +0000120 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Clayton9a142cf2012-02-03 05:34:10 +0000121 m_error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule());
122 SetValueDidChange (m_parent->GetValueDidChange());
123 return true;
124 }
125
126 // The dynamic value failed to get an error, pass the error along
127 if (m_error.Success() && m_parent->GetError().Fail())
128 m_error = m_parent->GetError();
129 SetValueIsValid (false);
130 return false;
131}
132
133
134
135bool
136ValueObjectCast::IsInScope ()
137{
138 return m_parent->IsInScope();
139}
140
141//----------------------------------------------------------------------
142
143
144
145
Jim Ingham2837b762011-05-04 03:43:18 +0000146ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
Jim Ingham78a685a2011-04-16 00:01:13 +0000147 ValueObject(parent),
148 m_address (),
Jim Ingham2837b762011-05-04 03:43:18 +0000149 m_type_sp(),
150 m_use_dynamic (use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +0000151{
Enrico Granatad8b5fce2011-08-02 23:12:24 +0000152 m_last_format_mgr_dynamic = use_dynamic;
Enrico Granata6f3533f2011-07-29 19:53:35 +0000153 SetName (parent.GetName());
Jim Ingham78a685a2011-04-16 00:01:13 +0000154}
155
156ValueObjectDynamicValue::~ValueObjectDynamicValue()
157{
158 m_owning_valobj_sp.reset();
159}
160
161lldb::clang_type_t
Sean Callanan72772842012-02-22 23:57:45 +0000162ValueObjectDynamicValue::GetClangTypeImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +0000163{
164 if (m_type_sp)
165 return m_value.GetClangType();
166 else
167 return m_parent->GetClangType();
168}
169
170ConstString
171ValueObjectDynamicValue::GetTypeName()
172{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000173 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000174 if (success && m_type_sp)
Greg Claytone3055942011-06-30 02:28:26 +0000175 return ClangASTType::GetConstTypeName (GetClangType());
Jim Ingham78a685a2011-04-16 00:01:13 +0000176 else
177 return m_parent->GetTypeName();
178}
179
180uint32_t
181ValueObjectDynamicValue::CalculateNumChildren()
182{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000183 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000184 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000185 return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
186 else
187 return m_parent->GetNumChildren();
188}
189
190clang::ASTContext *
Sean Callanan72772842012-02-22 23:57:45 +0000191ValueObjectDynamicValue::GetClangASTImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +0000192{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000193 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000194 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000195 return m_type_sp->GetClangAST();
196 else
197 return m_parent->GetClangAST ();
198}
199
200size_t
201ValueObjectDynamicValue::GetByteSize()
202{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000203 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +0000204 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000205 return m_value.GetValueByteSize(GetClangAST(), NULL);
206 else
207 return m_parent->GetByteSize();
208}
209
210lldb::ValueType
211ValueObjectDynamicValue::GetValueType() const
212{
213 return m_parent->GetValueType();
214}
215
216bool
217ValueObjectDynamicValue::UpdateValue ()
218{
219 SetValueIsValid (false);
220 m_error.Clear();
221
Enrico Granatac3e320a2011-08-02 17:27:39 +0000222 if (!m_parent->UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +0000223 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000224 // The dynamic value failed to get an error, pass the error along
225 if (m_error.Success() && m_parent->GetError().Fail())
226 m_error = m_parent->GetError();
Jim Ingham78a685a2011-04-16 00:01:13 +0000227 return false;
228 }
229
Jim Ingham2837b762011-05-04 03:43:18 +0000230 // Setting our type_sp to NULL will route everything back through our
231 // parent which is equivalent to not using dynamic values.
232 if (m_use_dynamic == lldb::eNoDynamicValues)
233 {
234 m_type_sp.reset();
235 return true;
236 }
237
Greg Claytoncc4d0142012-02-17 07:49:44 +0000238 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytonc14ee322011-09-22 04:58:26 +0000239 Target *target = exe_ctx.GetTargetPtr();
240 if (target)
Jim Ingham78a685a2011-04-16 00:01:13 +0000241 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000242 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
243 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
Jim Ingham78a685a2011-04-16 00:01:13 +0000244 }
245
246 // First make sure our Type and/or Address haven't changed:
Greg Claytoncc4d0142012-02-17 07:49:44 +0000247 Process *process = exe_ctx.GetProcessPtr();
Jim Ingham78a685a2011-04-16 00:01:13 +0000248 if (!process)
249 return false;
250
Jim Ingham61be0902011-05-02 18:13:59 +0000251 TypeAndOrName class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000252 Address dynamic_address;
253 bool found_dynamic_type = false;
254
255 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
256 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
257 {
258 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
259 if (runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000260 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000261 }
262 else
263 {
264 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
265 if (cpp_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000266 found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000267
268 if (!found_dynamic_type)
269 {
270 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
271 if (objc_runtime)
Enrico Granata9910bc82011-08-03 02:18:51 +0000272 found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000273 }
274 }
275
Jim Ingham61be0902011-05-02 18:13:59 +0000276 lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP();
277
278 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
279 // don't...
280
281 m_update_point.SetUpdated();
282
Jim Ingham78a685a2011-04-16 00:01:13 +0000283 // If we don't have a dynamic type, then make ourselves just a echo of our parent.
284 // Or we could return false, and make ourselves an echo of our parent?
285 if (!found_dynamic_type)
286 {
287 if (m_type_sp)
288 SetValueDidChange(true);
289 m_value = m_parent->GetValue();
Greg Clayton644247c2011-07-07 01:59:51 +0000290 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule());
Jim Ingham78a685a2011-04-16 00:01:13 +0000291 return m_error.Success();
292 }
293
294 Value old_value(m_value);
295
296 if (!m_type_sp)
297 {
298 m_type_sp = dynamic_type_sp;
299 }
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);
305 }
306
307 if (!m_address.IsValid() || m_address != dynamic_address)
308 {
309 if (m_address.IsValid())
310 SetValueDidChange (true);
311
312 // We've moved, so we should be fine...
313 m_address = dynamic_address;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000314 lldb::TargetSP target_sp (GetTargetSP());
315 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000316 m_value.GetScalar() = load_address;
317 }
318
319 // The type will always be the type of the dynamic object. If our parent's type was a pointer,
320 // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
321 // should be okay...
322 lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType();
323 lldb::clang_type_t corrected_type = orig_type;
324 if (m_parent->IsPointerType())
325 corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type);
326 else if (m_parent->IsPointerOrReferenceType())
327 corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type);
328
329 m_value.SetContext (Value::eContextTypeClangType, corrected_type);
330
331 // Our address is the location of the dynamic type stored in memory. It isn't a load address,
332 // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
333 m_value.SetValueType(Value::eValueTypeScalar);
334
335 if (m_address.IsValid() && m_type_sp)
336 {
337 // The variable value is in the Scalar value inside the m_value.
338 // We can point our m_data right to it.
Greg Clayton644247c2011-07-07 01:59:51 +0000339 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule());
Jim Ingham78a685a2011-04-16 00:01:13 +0000340 if (m_error.Success())
341 {
342 if (ClangASTContext::IsAggregateType (GetClangType()))
343 {
344 // this value object represents an aggregate type whose
345 // children have values, but this object does not. So we
346 // say we are changed if our location has changed.
347 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
348 }
349
350 SetValueIsValid (true);
351 return true;
352 }
353 }
354
355 // We get here if we've failed above...
356 SetValueIsValid (false);
357 return false;
358}
359
360
361
362bool
363ValueObjectDynamicValue::IsInScope ()
364{
365 return m_parent->IsInScope();
366}
367