blob: 4e038c55f38d30f8f2771ab6e6f7af11db0593d6 [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 (),
Jim Ingham2837b762011-05-04 03:43:18 +000041 m_type_sp(),
42 m_use_dynamic (use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +000043{
Enrico Granatad8b5fce2011-08-02 23:12:24 +000044 m_last_format_mgr_dynamic = use_dynamic;
Enrico Granata6f3533f2011-07-29 19:53:35 +000045 SetName (parent.GetName());
Jim Ingham78a685a2011-04-16 00:01:13 +000046}
47
48ValueObjectDynamicValue::~ValueObjectDynamicValue()
49{
50 m_owning_valobj_sp.reset();
51}
52
53lldb::clang_type_t
Sean Callanan72772842012-02-22 23:57:45 +000054ValueObjectDynamicValue::GetClangTypeImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +000055{
56 if (m_type_sp)
57 return m_value.GetClangType();
58 else
59 return m_parent->GetClangType();
60}
61
62ConstString
63ValueObjectDynamicValue::GetTypeName()
64{
Enrico Granatac3e320a2011-08-02 17:27:39 +000065 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +000066 if (success && m_type_sp)
Greg Clayton84db9102012-03-26 23:03:23 +000067 return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
Jim Ingham78a685a2011-04-16 00:01:13 +000068 else
69 return m_parent->GetTypeName();
70}
71
72uint32_t
73ValueObjectDynamicValue::CalculateNumChildren()
74{
Enrico Granatac3e320a2011-08-02 17:27:39 +000075 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +000076 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +000077 return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
78 else
79 return m_parent->GetNumChildren();
80}
81
82clang::ASTContext *
Sean Callanan72772842012-02-22 23:57:45 +000083ValueObjectDynamicValue::GetClangASTImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +000084{
Enrico Granata0a3958e2011-07-02 00:25:22 +000085 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +000086 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +000087 return m_type_sp->GetClangAST();
88 else
89 return m_parent->GetClangAST ();
90}
91
92size_t
93ValueObjectDynamicValue::GetByteSize()
94{
Enrico Granatac3e320a2011-08-02 17:27:39 +000095 const bool success = UpdateValueIfNeeded(false);
Greg Clayton5ad63942011-05-31 20:18:39 +000096 if (success && m_type_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +000097 return m_value.GetValueByteSize(GetClangAST(), NULL);
98 else
99 return m_parent->GetByteSize();
100}
101
102lldb::ValueType
103ValueObjectDynamicValue::GetValueType() const
104{
105 return m_parent->GetValueType();
106}
107
108bool
109ValueObjectDynamicValue::UpdateValue ()
110{
111 SetValueIsValid (false);
112 m_error.Clear();
113
Enrico Granatac3e320a2011-08-02 17:27:39 +0000114 if (!m_parent->UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +0000115 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000116 // The dynamic value failed to get an error, pass the error along
117 if (m_error.Success() && m_parent->GetError().Fail())
118 m_error = m_parent->GetError();
Jim Ingham78a685a2011-04-16 00:01:13 +0000119 return false;
120 }
121
Jim Ingham2837b762011-05-04 03:43:18 +0000122 // Setting our type_sp to NULL will route everything back through our
123 // parent which is equivalent to not using dynamic values.
124 if (m_use_dynamic == lldb::eNoDynamicValues)
125 {
126 m_type_sp.reset();
127 return true;
128 }
129
Greg Claytoncc4d0142012-02-17 07:49:44 +0000130 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytonc14ee322011-09-22 04:58:26 +0000131 Target *target = exe_ctx.GetTargetPtr();
132 if (target)
Jim Ingham78a685a2011-04-16 00:01:13 +0000133 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000134 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
135 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
Jim Ingham78a685a2011-04-16 00:01:13 +0000136 }
137
138 // First make sure our Type and/or Address haven't changed:
Greg Claytoncc4d0142012-02-17 07:49:44 +0000139 Process *process = exe_ctx.GetProcessPtr();
Jim Ingham78a685a2011-04-16 00:01:13 +0000140 if (!process)
141 return false;
142
Jim Ingham61be0902011-05-02 18:13:59 +0000143 TypeAndOrName class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000144 Address dynamic_address;
145 bool found_dynamic_type = false;
146
147 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
148 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
149 {
150 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
151 if (runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000152 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000153 }
154 else
155 {
156 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
157 if (cpp_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000158 found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000159
160 if (!found_dynamic_type)
161 {
162 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
163 if (objc_runtime)
Enrico Granata9910bc82011-08-03 02:18:51 +0000164 found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000165 }
166 }
167
Jim Ingham61be0902011-05-02 18:13:59 +0000168 lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP();
169
170 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
171 // don't...
172
173 m_update_point.SetUpdated();
174
Jim Ingham78a685a2011-04-16 00:01:13 +0000175 // If we don't have a dynamic type, then make ourselves just a echo of our parent.
176 // Or we could return false, and make ourselves an echo of our parent?
177 if (!found_dynamic_type)
178 {
Enrico Granatabd83b872012-11-27 23:28:32 +0000179 ClearDynamicTypeInformation();
180 m_type_sp.reset();
181 SetValueDidChange(true);
Jim Ingham78a685a2011-04-16 00:01:13 +0000182 m_value = m_parent->GetValue();
Greg Claytone72dfb32012-02-24 01:59:29 +0000183 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000184 return m_error.Success();
185 }
186
187 Value old_value(m_value);
188
Enrico Granatad2284832012-10-17 22:23:56 +0000189 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
190
Enrico Granatae3e91512012-10-22 18:18:36 +0000191 bool has_changed_type = false;
192
Jim Ingham78a685a2011-04-16 00:01:13 +0000193 if (!m_type_sp)
194 {
195 m_type_sp = dynamic_type_sp;
Enrico Granatae3e91512012-10-22 18:18:36 +0000196 has_changed_type = true;
Jim Ingham78a685a2011-04-16 00:01:13 +0000197 }
198 else if (dynamic_type_sp != m_type_sp)
199 {
200 // We are another type, we need to tear down our children...
201 m_type_sp = dynamic_type_sp;
202 SetValueDidChange (true);
Enrico Granatae3e91512012-10-22 18:18:36 +0000203 has_changed_type = true;
Jim Ingham78a685a2011-04-16 00:01:13 +0000204 }
205
Enrico Granatae3e91512012-10-22 18:18:36 +0000206 if (has_changed_type)
207 ClearDynamicTypeInformation ();
208
Jim Ingham78a685a2011-04-16 00:01:13 +0000209 if (!m_address.IsValid() || m_address != dynamic_address)
210 {
211 if (m_address.IsValid())
212 SetValueDidChange (true);
213
214 // We've moved, so we should be fine...
215 m_address = dynamic_address;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000216 lldb::TargetSP target_sp (GetTargetSP());
217 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000218 m_value.GetScalar() = load_address;
219 }
220
221 // The type will always be the type of the dynamic object. If our parent's type was a pointer,
222 // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
223 // should be okay...
224 lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType();
225 lldb::clang_type_t corrected_type = orig_type;
226 if (m_parent->IsPointerType())
227 corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type);
228 else if (m_parent->IsPointerOrReferenceType())
229 corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type);
230
231 m_value.SetContext (Value::eContextTypeClangType, corrected_type);
232
233 // Our address is the location of the dynamic type stored in memory. It isn't a load address,
234 // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
235 m_value.SetValueType(Value::eValueTypeScalar);
236
Enrico Granatae3e91512012-10-22 18:18:36 +0000237 if (has_changed_type && log)
238 log->Printf("[%s %p] has a new dynamic type %s",
239 GetName().GetCString(),
240 this,
241 GetTypeName().GetCString());
242
Jim Ingham78a685a2011-04-16 00:01:13 +0000243 if (m_address.IsValid() && m_type_sp)
244 {
245 // The variable value is in the Scalar value inside the m_value.
246 // We can point our m_data right to it.
Greg Claytone72dfb32012-02-24 01:59:29 +0000247 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000248 if (m_error.Success())
249 {
250 if (ClangASTContext::IsAggregateType (GetClangType()))
251 {
252 // this value object represents an aggregate type whose
253 // children have values, but this object does not. So we
254 // say we are changed if our location has changed.
255 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
256 }
257
258 SetValueIsValid (true);
259 return true;
260 }
261 }
262
263 // We get here if we've failed above...
264 SetValueIsValid (false);
265 return false;
266}
267
268
269
270bool
271ValueObjectDynamicValue::IsInScope ()
272{
273 return m_parent->IsInScope();
274}
275
Enrico Granata07a4ac22012-05-08 21:25:06 +0000276bool
277ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
278{
279 if (!UpdateValueIfNeeded(false))
280 {
281 error.SetErrorString("unable to read value");
282 return false;
283 }
284
285 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
286 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
287
288 if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
289 {
290 error.SetErrorString("unable to read value");
291 return false;
292 }
293
294 // if we are at an offset from our parent, in order to set ourselves correctly we would need
295 // to change the new value so that it refers to the correct dynamic type. we choose not to deal
296 // with that - if anything more than a value overwrite is required, you should be using the
297 // expression parser instead of the value editing facility
298 if (my_value != parent_value)
299 {
300 // but NULL'ing out a value should always be allowed
301 if (strcmp(value_str,"0"))
302 {
303 error.SetErrorString("unable to modify dynamic value, use 'expression' command");
304 return false;
305 }
306 }
307
308 bool ret_val = m_parent->SetValueFromCString(value_str,error);
309 SetNeedsUpdate();
310 return ret_val;
311}