blob: f82c66602ba42b7490f29897082f8d122cccf5fd [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 (),
Enrico Granataf7b1a342013-01-23 01:17:27 +000041 m_dynamic_type_info(),
Jim Ingham2837b762011-05-04 03:43:18 +000042 m_use_dynamic (use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +000043{
Enrico Granata6f3533f2011-07-29 19:53:35 +000044 SetName (parent.GetName());
Jim Ingham78a685a2011-04-16 00:01:13 +000045}
46
47ValueObjectDynamicValue::~ValueObjectDynamicValue()
48{
49 m_owning_valobj_sp.reset();
50}
51
52lldb::clang_type_t
Sean Callanan72772842012-02-22 23:57:45 +000053ValueObjectDynamicValue::GetClangTypeImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +000054{
Enrico Granataf7b1a342013-01-23 01:17:27 +000055 if (m_dynamic_type_info.HasTypeSP())
Jim Ingham78a685a2011-04-16 00:01:13 +000056 return m_value.GetClangType();
57 else
58 return m_parent->GetClangType();
59}
60
61ConstString
62ValueObjectDynamicValue::GetTypeName()
63{
Enrico Granatac3e320a2011-08-02 17:27:39 +000064 const bool success = UpdateValueIfNeeded(false);
Enrico Granataf7b1a342013-01-23 01:17:27 +000065 if (success)
66 {
67 if (m_dynamic_type_info.HasTypeSP())
68 return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
69 if (m_dynamic_type_info.HasName())
70 return m_dynamic_type_info.GetName();
71 }
72 return m_parent->GetTypeName();
73}
74
75ConstString
76ValueObjectDynamicValue::GetQualifiedTypeName()
77{
78 const bool success = UpdateValueIfNeeded(false);
79 if (success)
80 {
81 if (m_dynamic_type_info.HasTypeSP())
82 return ClangASTType::GetConstQualifiedTypeName (GetClangAST(), GetClangType());
83 if (m_dynamic_type_info.HasName())
84 return m_dynamic_type_info.GetName();
85 }
86 return m_parent->GetTypeName();
Jim Ingham78a685a2011-04-16 00:01:13 +000087}
88
Greg Claytonc7bece562013-01-25 18:06:21 +000089size_t
Jim Ingham78a685a2011-04-16 00:01:13 +000090ValueObjectDynamicValue::CalculateNumChildren()
91{
Enrico Granatac3e320a2011-08-02 17:27:39 +000092 const bool success = UpdateValueIfNeeded(false);
Enrico Granataf7b1a342013-01-23 01:17:27 +000093 if (success && m_dynamic_type_info.HasTypeSP())
Jim Ingham78a685a2011-04-16 00:01:13 +000094 return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
95 else
96 return m_parent->GetNumChildren();
97}
98
99clang::ASTContext *
Sean Callanan72772842012-02-22 23:57:45 +0000100ValueObjectDynamicValue::GetClangASTImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +0000101{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000102 const bool success = UpdateValueIfNeeded(false);
Enrico Granataf7b1a342013-01-23 01:17:27 +0000103 if (success && m_dynamic_type_info.HasTypeSP())
104 return m_dynamic_type_info.GetTypeSP()->GetClangAST();
Jim Ingham78a685a2011-04-16 00:01:13 +0000105 else
106 return m_parent->GetClangAST ();
107}
108
Greg Claytonfaac1112013-03-14 18:31:44 +0000109uint64_t
Jim Ingham78a685a2011-04-16 00:01:13 +0000110ValueObjectDynamicValue::GetByteSize()
111{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000112 const bool success = UpdateValueIfNeeded(false);
Enrico Granataf7b1a342013-01-23 01:17:27 +0000113 if (success && m_dynamic_type_info.HasTypeSP())
Jim Ingham78a685a2011-04-16 00:01:13 +0000114 return m_value.GetValueByteSize(GetClangAST(), NULL);
115 else
116 return m_parent->GetByteSize();
117}
118
119lldb::ValueType
120ValueObjectDynamicValue::GetValueType() const
121{
122 return m_parent->GetValueType();
123}
124
125bool
126ValueObjectDynamicValue::UpdateValue ()
127{
128 SetValueIsValid (false);
129 m_error.Clear();
130
Enrico Granatac3e320a2011-08-02 17:27:39 +0000131 if (!m_parent->UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +0000132 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000133 // The dynamic value failed to get an error, pass the error along
134 if (m_error.Success() && m_parent->GetError().Fail())
135 m_error = m_parent->GetError();
Jim Ingham78a685a2011-04-16 00:01:13 +0000136 return false;
137 }
138
Jim Ingham2837b762011-05-04 03:43:18 +0000139 // Setting our type_sp to NULL will route everything back through our
140 // parent which is equivalent to not using dynamic values.
141 if (m_use_dynamic == lldb::eNoDynamicValues)
142 {
Enrico Granataf7b1a342013-01-23 01:17:27 +0000143 m_dynamic_type_info.Clear();
Jim Ingham2837b762011-05-04 03:43:18 +0000144 return true;
145 }
146
Greg Claytoncc4d0142012-02-17 07:49:44 +0000147 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytonc14ee322011-09-22 04:58:26 +0000148 Target *target = exe_ctx.GetTargetPtr();
149 if (target)
Jim Ingham78a685a2011-04-16 00:01:13 +0000150 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000151 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
152 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
Jim Ingham78a685a2011-04-16 00:01:13 +0000153 }
154
155 // First make sure our Type and/or Address haven't changed:
Greg Claytoncc4d0142012-02-17 07:49:44 +0000156 Process *process = exe_ctx.GetProcessPtr();
Jim Ingham78a685a2011-04-16 00:01:13 +0000157 if (!process)
158 return false;
159
Jim Ingham61be0902011-05-02 18:13:59 +0000160 TypeAndOrName class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000161 Address dynamic_address;
162 bool found_dynamic_type = false;
163
164 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
165 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
166 {
167 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
168 if (runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000169 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000170 }
171 else
172 {
173 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
174 if (cpp_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +0000175 found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000176
177 if (!found_dynamic_type)
178 {
179 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
180 if (objc_runtime)
Enrico Granata9910bc82011-08-03 02:18:51 +0000181 found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
Jim Ingham78a685a2011-04-16 00:01:13 +0000182 }
183 }
184
Jim Ingham61be0902011-05-02 18:13:59 +0000185 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
186 // don't...
187
188 m_update_point.SetUpdated();
189
Jim Ingham78a685a2011-04-16 00:01:13 +0000190 // If we don't have a dynamic type, then make ourselves just a echo of our parent.
191 // Or we could return false, and make ourselves an echo of our parent?
192 if (!found_dynamic_type)
193 {
Enrico Granataf7b1a342013-01-23 01:17:27 +0000194 if (m_dynamic_type_info)
Enrico Granata75badc42012-11-27 23:50:00 +0000195 SetValueDidChange(true);
Enrico Granatabd83b872012-11-27 23:28:32 +0000196 ClearDynamicTypeInformation();
Enrico Granataf7b1a342013-01-23 01:17:27 +0000197 m_dynamic_type_info.Clear();
Jim Ingham78a685a2011-04-16 00:01:13 +0000198 m_value = m_parent->GetValue();
Greg Claytone72dfb32012-02-24 01:59:29 +0000199 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000200 return m_error.Success();
201 }
202
203 Value old_value(m_value);
204
Greg Clayton5160ce52013-03-27 23:08:40 +0000205 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granatad2284832012-10-17 22:23:56 +0000206
Enrico Granatae3e91512012-10-22 18:18:36 +0000207 bool has_changed_type = false;
208
Enrico Granataf7b1a342013-01-23 01:17:27 +0000209 if (!m_dynamic_type_info)
Jim Ingham78a685a2011-04-16 00:01:13 +0000210 {
Enrico Granataf7b1a342013-01-23 01:17:27 +0000211 m_dynamic_type_info = class_type_or_name;
Enrico Granatae3e91512012-10-22 18:18:36 +0000212 has_changed_type = true;
Jim Ingham78a685a2011-04-16 00:01:13 +0000213 }
Enrico Granataf7b1a342013-01-23 01:17:27 +0000214 else if (class_type_or_name != m_dynamic_type_info)
Jim Ingham78a685a2011-04-16 00:01:13 +0000215 {
216 // We are another type, we need to tear down our children...
Enrico Granataf7b1a342013-01-23 01:17:27 +0000217 m_dynamic_type_info = class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000218 SetValueDidChange (true);
Enrico Granatae3e91512012-10-22 18:18:36 +0000219 has_changed_type = true;
Jim Ingham78a685a2011-04-16 00:01:13 +0000220 }
221
Enrico Granatae3e91512012-10-22 18:18:36 +0000222 if (has_changed_type)
223 ClearDynamicTypeInformation ();
224
Jim Ingham78a685a2011-04-16 00:01:13 +0000225 if (!m_address.IsValid() || m_address != dynamic_address)
226 {
227 if (m_address.IsValid())
228 SetValueDidChange (true);
229
230 // We've moved, so we should be fine...
231 m_address = dynamic_address;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000232 lldb::TargetSP target_sp (GetTargetSP());
233 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000234 m_value.GetScalar() = load_address;
235 }
236
Enrico Granataf7b1a342013-01-23 01:17:27 +0000237 lldb::clang_type_t corrected_type;
238 if (m_dynamic_type_info.HasTypeSP())
239 {
240 // The type will always be the type of the dynamic object. If our parent's type was a pointer,
241 // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
242 // should be okay...
243 lldb::clang_type_t orig_type;
244 clang::ASTContext* ast;
245 orig_type = m_dynamic_type_info.GetTypeSP()->GetClangForwardType();
246 ast = m_dynamic_type_info.GetTypeSP()->GetClangAST();
247 corrected_type = orig_type;
248 if (m_parent->IsPointerType())
249 corrected_type = ClangASTContext::CreatePointerType (ast, orig_type);
250 else if (m_parent->IsPointerOrReferenceType())
251 corrected_type = ClangASTContext::CreateLValueReferenceType (ast, orig_type);
252 }
253 else /*if (m_dynamic_type_info.HasName())*/
254 {
255 // If we are here we need to adjust our dynamic type name to include the correct & or * symbol
256 std::string type_name_buf (m_dynamic_type_info.GetName().GetCString());
257 if (m_parent->IsPointerType())
258 type_name_buf.append(" *");
259 else if (m_parent->IsPointerOrReferenceType())
260 type_name_buf.append(" &");
261 corrected_type = m_parent->GetClangType();
262 m_dynamic_type_info.SetName(type_name_buf.c_str());
263 }
264
Jim Ingham78a685a2011-04-16 00:01:13 +0000265 m_value.SetContext (Value::eContextTypeClangType, corrected_type);
266
267 // Our address is the location of the dynamic type stored in memory. It isn't a load address,
268 // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
269 m_value.SetValueType(Value::eValueTypeScalar);
270
Enrico Granatae3e91512012-10-22 18:18:36 +0000271 if (has_changed_type && log)
272 log->Printf("[%s %p] has a new dynamic type %s",
273 GetName().GetCString(),
274 this,
275 GetTypeName().GetCString());
276
Enrico Granataf7b1a342013-01-23 01:17:27 +0000277 if (m_address.IsValid() && m_dynamic_type_info)
Jim Ingham78a685a2011-04-16 00:01:13 +0000278 {
279 // The variable value is in the Scalar value inside the m_value.
280 // We can point our m_data right to it.
Greg Claytone72dfb32012-02-24 01:59:29 +0000281 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000282 if (m_error.Success())
283 {
284 if (ClangASTContext::IsAggregateType (GetClangType()))
285 {
286 // this value object represents an aggregate type whose
287 // children have values, but this object does not. So we
288 // say we are changed if our location has changed.
289 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
290 }
291
292 SetValueIsValid (true);
293 return true;
294 }
295 }
296
297 // We get here if we've failed above...
298 SetValueIsValid (false);
299 return false;
300}
301
302
303
304bool
305ValueObjectDynamicValue::IsInScope ()
306{
307 return m_parent->IsInScope();
308}
309
Enrico Granata07a4ac22012-05-08 21:25:06 +0000310bool
311ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
312{
313 if (!UpdateValueIfNeeded(false))
314 {
315 error.SetErrorString("unable to read value");
316 return false;
317 }
318
319 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
320 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
321
322 if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
323 {
324 error.SetErrorString("unable to read value");
325 return false;
326 }
327
328 // if we are at an offset from our parent, in order to set ourselves correctly we would need
329 // to change the new value so that it refers to the correct dynamic type. we choose not to deal
330 // with that - if anything more than a value overwrite is required, you should be using the
331 // expression parser instead of the value editing facility
332 if (my_value != parent_value)
333 {
334 // but NULL'ing out a value should always be allowed
335 if (strcmp(value_str,"0"))
336 {
337 error.SetErrorString("unable to modify dynamic value, use 'expression' command");
338 return false;
339 }
340 }
341
342 bool ret_val = m_parent->SetValueFromCString(value_str,error);
343 SetNeedsUpdate();
344 return ret_val;
345}