blob: 6471972ad99df5b2898d6c672de03ffd0994a0b0 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ValueObject.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#include "lldb/Core/ValueObject.h"
11
12// C Includes
Greg Claytonf5e56de2010-09-14 23:36:40 +000013#include <stdlib.h>
14
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015// C++ Includes
16// Other libraries and framework includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "llvm/Support/raw_ostream.h"
Jim Ingham5a369122010-09-28 01:25:32 +000018#include "clang/AST/Type.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019
20// Project includes
21#include "lldb/Core/DataBufferHeap.h"
22#include "lldb/Core/StreamString.h"
23#include "lldb/Core/ValueObjectChild.h"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000024#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000025#include "lldb/Core/ValueObjectDynamicValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Core/ValueObjectList.h"
Greg Claytonb2dcc362011-05-05 23:32:56 +000027#include "lldb/Core/ValueObjectMemory.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028
Greg Clayton7fb56d02011-02-01 01:31:41 +000029#include "lldb/Host/Endian.h"
30
Greg Claytone1a916a2010-07-21 22:12:05 +000031#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Symbol/ClangASTContext.h"
33#include "lldb/Symbol/Type.h"
34
Jim Ingham53c47f12010-09-10 23:12:17 +000035#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000036#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037#include "lldb/Target/Process.h"
38#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000039#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041
42using namespace lldb;
43using namespace lldb_private;
44
45static lldb::user_id_t g_value_obj_uid = 0;
46
47//----------------------------------------------------------------------
48// ValueObject constructor
49//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000050ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000052 m_parent (&parent),
Stephen Wilson71c21d12011-04-11 19:41:40 +000053 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054 m_name (),
55 m_data (),
56 m_value (),
57 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000058 m_value_str (),
59 m_old_value_str (),
60 m_location_str (),
61 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000062 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000063 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000064 m_children (),
65 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000066 m_dynamic_value (NULL),
67 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000068 m_format (eFormatDefault),
Greg Clayton288bdf92010-09-02 02:59:18 +000069 m_value_is_valid (false),
70 m_value_did_change (false),
71 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000072 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000073 m_pointers_point_to_load_addrs (false),
Stephen Wilson71c21d12011-04-11 19:41:40 +000074 m_is_deref_of_parent (false)
Jim Ingham6035b672011-03-31 00:19:25 +000075{
Jim Ingham58b59f92011-04-22 23:53:53 +000076 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +000077}
78
79//----------------------------------------------------------------------
80// ValueObject constructor
81//----------------------------------------------------------------------
82ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
83 UserID (++g_value_obj_uid), // Unique identifier for every value object
84 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +000085 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +000086 m_name (),
87 m_data (),
88 m_value (),
89 m_error (),
90 m_value_str (),
91 m_old_value_str (),
92 m_location_str (),
93 m_summary_str (),
94 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000095 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +000096 m_children (),
97 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000098 m_dynamic_value (NULL),
99 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +0000100 m_format (eFormatDefault),
101 m_value_is_valid (false),
102 m_value_did_change (false),
103 m_children_count_valid (false),
104 m_old_value_valid (false),
105 m_pointers_point_to_load_addrs (false),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000106 m_is_deref_of_parent (false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107{
Jim Ingham58b59f92011-04-22 23:53:53 +0000108 m_manager = new ValueObjectManager();
109 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110}
111
112//----------------------------------------------------------------------
113// Destructor
114//----------------------------------------------------------------------
115ValueObject::~ValueObject ()
116{
117}
118
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119bool
Jim Ingham6035b672011-03-31 00:19:25 +0000120ValueObject::UpdateValueIfNeeded ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121{
Greg Claytonb71f3842010-10-05 03:13:51 +0000122 // If this is a constant value, then our success is predicated on whether
123 // we have an error or not
124 if (GetIsConstant())
125 return m_error.Success();
126
Jim Ingham6035b672011-03-31 00:19:25 +0000127 bool first_update = m_update_point.IsFirstEvaluation();
128
129 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130 {
Jim Ingham6035b672011-03-31 00:19:25 +0000131 m_update_point.SetUpdated();
132
133 // Save the old value using swap to avoid a string copy which
134 // also will clear our m_value_str
135 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000136 {
Jim Ingham6035b672011-03-31 00:19:25 +0000137 m_old_value_valid = false;
138 }
139 else
140 {
141 m_old_value_valid = true;
142 m_old_value_str.swap (m_value_str);
143 m_value_str.clear();
144 }
145 m_location_str.clear();
146 m_summary_str.clear();
147 m_object_desc_str.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148
Jim Ingham6035b672011-03-31 00:19:25 +0000149 const bool value_was_valid = GetValueIsValid();
150 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000151
Jim Ingham6035b672011-03-31 00:19:25 +0000152 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000153
Jim Ingham6035b672011-03-31 00:19:25 +0000154 // Call the pure virtual function to update the value
155 bool success = UpdateValue ();
156
157 SetValueIsValid (success);
158
159 if (first_update)
160 SetValueDidChange (false);
161 else if (!m_value_did_change && success == false)
162 {
163 // The value wasn't gotten successfully, so we mark this
164 // as changed if the value used to be valid and now isn't
165 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166 }
167 }
168 return m_error.Success();
169}
170
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171DataExtractor &
172ValueObject::GetDataExtractor ()
173{
Jim Ingham78a685a2011-04-16 00:01:13 +0000174 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175 return m_data;
176}
177
178const Error &
179ValueObject::GetError() const
180{
181 return m_error;
182}
183
184const ConstString &
185ValueObject::GetName() const
186{
187 return m_name;
188}
189
190const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000191ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000192{
Jim Ingham6035b672011-03-31 00:19:25 +0000193 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000194 {
195 if (m_location_str.empty())
196 {
197 StreamString sstr;
198
199 switch (m_value.GetValueType())
200 {
201 default:
202 break;
203
204 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000205 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206 {
207 RegisterInfo *reg_info = m_value.GetRegisterInfo();
208 if (reg_info)
209 {
210 if (reg_info->name)
211 m_location_str = reg_info->name;
212 else if (reg_info->alt_name)
213 m_location_str = reg_info->alt_name;
214 break;
215 }
216 }
217 m_location_str = "scalar";
218 break;
219
220 case Value::eValueTypeLoadAddress:
221 case Value::eValueTypeFileAddress:
222 case Value::eValueTypeHostAddress:
223 {
224 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
225 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
226 m_location_str.swap(sstr.GetString());
227 }
228 break;
229 }
230 }
231 }
232 return m_location_str.c_str();
233}
234
235Value &
236ValueObject::GetValue()
237{
238 return m_value;
239}
240
241const Value &
242ValueObject::GetValue() const
243{
244 return m_value;
245}
246
247bool
Jim Ingham6035b672011-03-31 00:19:25 +0000248ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000249{
250 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000251 ExecutionContextScope *exe_scope = GetExecutionContextScope();
252 if (exe_scope)
253 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000254 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
255 return scalar.IsValid();
256}
257
258bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000259ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260{
Greg Clayton288bdf92010-09-02 02:59:18 +0000261 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262}
263
264
265void
266ValueObject::SetValueIsValid (bool b)
267{
Greg Clayton288bdf92010-09-02 02:59:18 +0000268 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269}
270
271bool
Jim Ingham6035b672011-03-31 00:19:25 +0000272ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273{
Jim Ingham6035b672011-03-31 00:19:25 +0000274 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000275 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276}
277
278void
279ValueObject::SetValueDidChange (bool value_changed)
280{
Greg Clayton288bdf92010-09-02 02:59:18 +0000281 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282}
283
284ValueObjectSP
285ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
286{
287 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000288 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000290 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000292 // Check if we have already made the child value object?
Jim Ingham58b59f92011-04-22 23:53:53 +0000293 if (can_create && m_children[idx] == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +0000294 {
295 // No we haven't created the child at this index, so lets have our
296 // subclass do it and cache the result for quick future access.
297 m_children[idx] = CreateChildAtIndex (idx, false, 0);
298 }
Jim Ingham58b59f92011-04-22 23:53:53 +0000299
300 if (m_children[idx] != NULL)
301 return m_children[idx]->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +0000302 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303 }
304 return child_sp;
305}
306
307uint32_t
308ValueObject::GetIndexOfChildWithName (const ConstString &name)
309{
310 bool omit_empty_base_classes = true;
311 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000312 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000313 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 omit_empty_base_classes);
315}
316
317ValueObjectSP
318ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
319{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000320 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321 // classes (which really aren't part of the expression path), so we
322 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000323 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000324
325 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000327 std::vector<uint32_t> child_indexes;
328 clang::ASTContext *clang_ast = GetClangAST();
329 void *clang_type = GetClangType();
330 bool omit_empty_base_classes = true;
331 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
332 clang_type,
333 name.GetCString(),
334 omit_empty_base_classes,
335 child_indexes);
336 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000338 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
339 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340
Jim Ingham78a685a2011-04-16 00:01:13 +0000341 child_sp = GetChildAtIndex(*pos, can_create);
342 for (++pos; pos != end; ++pos)
343 {
344 if (child_sp)
345 {
346 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
347 child_sp = new_child_sp;
348 }
349 else
350 {
351 child_sp.reset();
352 }
353
354 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355 }
356 }
357 return child_sp;
358}
359
360
361uint32_t
362ValueObject::GetNumChildren ()
363{
Greg Clayton288bdf92010-09-02 02:59:18 +0000364 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000365 {
366 SetNumChildren (CalculateNumChildren());
367 }
368 return m_children.size();
369}
370void
371ValueObject::SetNumChildren (uint32_t num_children)
372{
Greg Clayton288bdf92010-09-02 02:59:18 +0000373 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374 m_children.resize(num_children);
375}
376
377void
378ValueObject::SetName (const char *name)
379{
380 m_name.SetCString(name);
381}
382
383void
384ValueObject::SetName (const ConstString &name)
385{
386 m_name = name;
387}
388
Jim Ingham58b59f92011-04-22 23:53:53 +0000389ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
391{
Jim Ingham2eec4872011-05-07 00:10:58 +0000392 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000393
394 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000396 bool omit_empty_base_classes = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397
Jim Ingham78a685a2011-04-16 00:01:13 +0000398 std::string child_name_str;
399 uint32_t child_byte_size = 0;
400 int32_t child_byte_offset = 0;
401 uint32_t child_bitfield_bit_size = 0;
402 uint32_t child_bitfield_bit_offset = 0;
403 bool child_is_base_class = false;
404 bool child_is_deref_of_parent = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405
Jim Ingham78a685a2011-04-16 00:01:13 +0000406 const bool transparent_pointers = synthetic_array_member == false;
407 clang::ASTContext *clang_ast = GetClangAST();
408 clang_type_t clang_type = GetClangType();
409 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +0000410
411 ExecutionContext exe_ctx;
412 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
413
414 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
415 clang_ast,
Jim Ingham78a685a2011-04-16 00:01:13 +0000416 GetName().GetCString(),
417 clang_type,
418 idx,
419 transparent_pointers,
420 omit_empty_base_classes,
421 child_name_str,
422 child_byte_size,
423 child_byte_offset,
424 child_bitfield_bit_size,
425 child_bitfield_bit_offset,
426 child_is_base_class,
427 child_is_deref_of_parent);
428 if (child_clang_type && child_byte_size)
429 {
430 if (synthetic_index)
431 child_byte_offset += child_byte_size * synthetic_index;
432
433 ConstString child_name;
434 if (!child_name_str.empty())
435 child_name.SetCString (child_name_str.c_str());
436
Jim Ingham58b59f92011-04-22 23:53:53 +0000437 valobj = new ValueObjectChild (*this,
438 clang_ast,
439 child_clang_type,
440 child_name,
441 child_byte_size,
442 child_byte_offset,
443 child_bitfield_bit_size,
444 child_bitfield_bit_offset,
445 child_is_base_class,
446 child_is_deref_of_parent);
Jim Ingham78a685a2011-04-16 00:01:13 +0000447 if (m_pointers_point_to_load_addrs)
Jim Ingham58b59f92011-04-22 23:53:53 +0000448 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Jim Ingham78a685a2011-04-16 00:01:13 +0000449 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000451
Jim Ingham58b59f92011-04-22 23:53:53 +0000452 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453}
454
455const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000456ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457{
Jim Ingham6035b672011-03-31 00:19:25 +0000458 if (UpdateValueIfNeeded ())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459 {
460 if (m_summary_str.empty())
461 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000462 clang_type_t clang_type = GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463
464 // See if this is a pointer to a C string?
Greg Clayton737b9322010-09-13 03:32:57 +0000465 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466 {
Greg Clayton737b9322010-09-13 03:32:57 +0000467 StreamString sstr;
Greg Clayton73b472d2010-10-27 03:32:59 +0000468 clang_type_t elem_or_pointee_clang_type;
469 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000470 GetClangAST(),
471 &elem_or_pointee_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +0000472
Jim Ingham6035b672011-03-31 00:19:25 +0000473 ExecutionContextScope *exe_scope = GetExecutionContextScope();
474 if (exe_scope)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475 {
Jim Ingham6035b672011-03-31 00:19:25 +0000476 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
477 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478 {
Jim Ingham6035b672011-03-31 00:19:25 +0000479 Process *process = exe_scope->CalculateProcess();
480 if (process != NULL)
481 {
482 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
483 AddressType cstr_address_type = eAddressTypeInvalid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484
Jim Ingham6035b672011-03-31 00:19:25 +0000485 size_t cstr_len = 0;
486 if (type_flags.Test (ClangASTContext::eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487 {
Jim Ingham6035b672011-03-31 00:19:25 +0000488 // We have an array
489 cstr_len = ClangASTContext::GetArraySize (clang_type);
490 cstr_address = GetAddressOf (cstr_address_type, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491 }
Greg Clayton737b9322010-09-13 03:32:57 +0000492 else
493 {
Jim Ingham6035b672011-03-31 00:19:25 +0000494 // We have a pointer
495 cstr_address = GetPointerValue (cstr_address_type, true);
Greg Clayton737b9322010-09-13 03:32:57 +0000496 }
Jim Ingham6035b672011-03-31 00:19:25 +0000497 if (cstr_address != LLDB_INVALID_ADDRESS)
Greg Clayton737b9322010-09-13 03:32:57 +0000498 {
Jim Ingham6035b672011-03-31 00:19:25 +0000499 DataExtractor data;
500 size_t bytes_read = 0;
501 std::vector<char> data_buffer;
502 Error error;
503 if (cstr_len > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000504 {
Jim Ingham6035b672011-03-31 00:19:25 +0000505 data_buffer.resize(cstr_len);
506 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
507 bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error);
508 if (bytes_read > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000509 {
Jim Ingham6035b672011-03-31 00:19:25 +0000510 sstr << '"';
511 data.Dump (&sstr,
512 0, // Start offset in "data"
Greg Clayton4e4294b2011-06-17 23:50:44 +0000513 eFormatCharArray, // Print as characters
Jim Ingham6035b672011-03-31 00:19:25 +0000514 1, // Size of item (1 byte for a char!)
515 bytes_read, // How many bytes to print?
516 UINT32_MAX, // num per line
517 LLDB_INVALID_ADDRESS,// base address
518 0, // bitfield bit size
519 0); // bitfield bit offset
520 sstr << '"';
Greg Clayton737b9322010-09-13 03:32:57 +0000521 }
522 }
Jim Ingham6035b672011-03-31 00:19:25 +0000523 else
524 {
525 const size_t k_max_buf_size = 256;
526 data_buffer.resize (k_max_buf_size + 1);
527 // NULL terminate in case we don't get the entire C string
528 data_buffer.back() = '\0';
Greg Clayton737b9322010-09-13 03:32:57 +0000529
Jim Ingham6035b672011-03-31 00:19:25 +0000530 sstr << '"';
531
532 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
533 while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0)
534 {
535 size_t len = strlen(&data_buffer.front());
536 if (len == 0)
537 break;
538 if (len > bytes_read)
539 len = bytes_read;
540
541 data.Dump (&sstr,
542 0, // Start offset in "data"
Greg Clayton4e4294b2011-06-17 23:50:44 +0000543 eFormatCharArray, // Print as characters
Jim Ingham6035b672011-03-31 00:19:25 +0000544 1, // Size of item (1 byte for a char!)
545 len, // How many bytes to print?
546 UINT32_MAX, // num per line
547 LLDB_INVALID_ADDRESS,// base address
548 0, // bitfield bit size
549 0); // bitfield bit offset
550
551 if (len < k_max_buf_size)
552 break;
553 cstr_address += k_max_buf_size;
554 }
555 sstr << '"';
556 }
557 }
Greg Clayton737b9322010-09-13 03:32:57 +0000558 }
Jim Ingham6035b672011-03-31 00:19:25 +0000559
560 if (sstr.GetSize() > 0)
561 m_summary_str.assign (sstr.GetData(), sstr.GetSize());
Greg Clayton737b9322010-09-13 03:32:57 +0000562 }
Jim Ingham6035b672011-03-31 00:19:25 +0000563 else if (ClangASTContext::IsFunctionPointerType (clang_type))
Greg Clayton737b9322010-09-13 03:32:57 +0000564 {
Jim Ingham6035b672011-03-31 00:19:25 +0000565 AddressType func_ptr_address_type = eAddressTypeInvalid;
566 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
567
568 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
569 {
570 switch (func_ptr_address_type)
571 {
572 case eAddressTypeInvalid:
573 case eAddressTypeFile:
574 break;
575
576 case eAddressTypeLoad:
577 {
578 Address so_addr;
579 Target *target = exe_scope->CalculateTarget();
580 if (target && target->GetSectionLoadList().IsEmpty() == false)
581 {
582 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
583 {
584 so_addr.Dump (&sstr,
585 exe_scope,
586 Address::DumpStyleResolvedDescription,
587 Address::DumpStyleSectionNameOffset);
588 }
589 }
590 }
591 break;
592
593 case eAddressTypeHost:
594 break;
595 }
596 }
597 if (sstr.GetSize() > 0)
598 {
599 m_summary_str.assign (1, '(');
600 m_summary_str.append (sstr.GetData(), sstr.GetSize());
601 m_summary_str.append (1, ')');
602 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000603 }
604 }
605 }
606 }
607 }
608 if (m_summary_str.empty())
609 return NULL;
610 return m_summary_str.c_str();
611}
612
Jim Ingham53c47f12010-09-10 23:12:17 +0000613const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000614ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000615{
616 if (!m_object_desc_str.empty())
617 return m_object_desc_str.c_str();
618
Jim Ingham6035b672011-03-31 00:19:25 +0000619 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000620 return NULL;
Jim Ingham6035b672011-03-31 00:19:25 +0000621
622 ExecutionContextScope *exe_scope = GetExecutionContextScope();
623 if (exe_scope == NULL)
624 return NULL;
625
Jim Ingham53c47f12010-09-10 23:12:17 +0000626 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000627 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000628 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000629
Jim Ingham53c47f12010-09-10 23:12:17 +0000630 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000631
632 lldb::LanguageType language = GetObjectRuntimeLanguage();
633 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
634
Jim Inghama2cf2632010-12-23 02:29:54 +0000635 if (runtime == NULL)
636 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000637 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000638 clang_type_t opaque_qual_type = GetClangType();
639 if (opaque_qual_type != NULL)
640 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000641 bool is_signed;
642 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
643 || ClangASTContext::IsPointerType (opaque_qual_type))
644 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000645 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000646 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000647 }
648 }
649
Jim Ingham8d543de2011-03-31 23:01:21 +0000650 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000651 {
652 m_object_desc_str.append (s.GetData());
653 }
Sean Callanan672ad942010-10-23 00:18:49 +0000654
655 if (m_object_desc_str.empty())
656 return NULL;
657 else
658 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000659}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000660
661const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000662ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000663{
664 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000665 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666 {
Jim Ingham6035b672011-03-31 00:19:25 +0000667 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000668 {
Greg Claytonf60f3752011-06-23 18:38:25 +0000669 /*
670 this is a quick fix for the case in which we display a variable, then change its format with
671 type format add and the old display string keeps showing until one steps through the code
672 */
673 {
674 const Value::ContextType context_type = m_value.GetContextType();
675 switch (context_type)
676 {
677 case Value::eContextTypeClangType:
678 case Value::eContextTypeLLDBType:
679 case Value::eContextTypeVariable:
Greg Claytonbb7f31f2011-06-23 21:22:24 +0000680 {
681 Format format = GetFormat();
682 if (format != m_last_format)
683 m_value_str.clear();
684 }
685 break;
686
687 default:
Greg Claytonf60f3752011-06-23 18:38:25 +0000688 break;
689 }
690 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000691 if (m_value_str.empty())
692 {
693 const Value::ContextType context_type = m_value.GetContextType();
694
695 switch (context_type)
696 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000697 case Value::eContextTypeClangType:
698 case Value::eContextTypeLLDBType:
699 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000700 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000701 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000702 if (clang_type)
703 {
704 StreamString sstr;
Greg Clayton68ebae62011-04-28 20:55:26 +0000705 Format format = GetFormat();
706 if (format == eFormatDefault)
707 format = ClangASTType::GetFormat(clang_type);
Greg Clayton32c40852010-10-06 03:09:11 +0000708
709 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
710 clang_type, // The clang type to display
711 &sstr,
Greg Claytonf60f3752011-06-23 18:38:25 +0000712 m_last_format = format, // Format to display this type with
Greg Clayton32c40852010-10-06 03:09:11 +0000713 m_data, // Data to extract from
714 0, // Byte offset into "m_data"
715 GetByteSize(), // Byte size of item in "m_data"
716 GetBitfieldBitSize(), // Bitfield bit size
717 GetBitfieldBitOffset())) // Bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 m_value_str.swap(sstr.GetString());
719 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000720 {
721 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
722 m_data.GetByteSize(),
723 GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000724 m_value_str.clear();
Greg Clayton007d5be2011-05-30 00:49:24 +0000725 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000726 }
727 }
728 break;
729
Greg Clayton526e5af2010-11-13 03:52:47 +0000730 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731 {
732 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
733 if (reg_info)
734 {
735 StreamString reg_sstr;
736 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
737 m_value_str.swap(reg_sstr.GetString());
738 }
739 }
740 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000741
742 default:
743 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000744 }
745 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000746
747 if (!m_value_did_change && m_old_value_valid)
748 {
749 // The value was gotten successfully, so we consider the
750 // value as changed if the value string differs
751 SetValueDidChange (m_old_value_str != m_value_str);
752 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000753 }
754 }
755 if (m_value_str.empty())
756 return NULL;
757 return m_value_str.c_str();
758}
759
Greg Clayton737b9322010-09-13 03:32:57 +0000760addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000761ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +0000762{
Jim Ingham78a685a2011-04-16 00:01:13 +0000763 if (!UpdateValueIfNeeded())
764 return LLDB_INVALID_ADDRESS;
765
Greg Clayton73b472d2010-10-27 03:32:59 +0000766 switch (m_value.GetValueType())
767 {
768 case Value::eValueTypeScalar:
769 if (scalar_is_load_address)
770 {
771 address_type = eAddressTypeLoad;
772 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
773 }
774 break;
775
776 case Value::eValueTypeLoadAddress:
777 case Value::eValueTypeFileAddress:
778 case Value::eValueTypeHostAddress:
779 {
780 address_type = m_value.GetValueAddressType ();
781 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
782 }
783 break;
784 }
785 address_type = eAddressTypeInvalid;
786 return LLDB_INVALID_ADDRESS;
787}
788
789addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000790ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +0000791{
792 lldb::addr_t address = LLDB_INVALID_ADDRESS;
793 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +0000794
795 if (!UpdateValueIfNeeded())
796 return address;
797
Greg Clayton73b472d2010-10-27 03:32:59 +0000798 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +0000799 {
800 case Value::eValueTypeScalar:
801 if (scalar_is_load_address)
802 {
803 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
804 address_type = eAddressTypeLoad;
805 }
806 break;
807
808 case Value::eValueTypeLoadAddress:
809 case Value::eValueTypeFileAddress:
810 case Value::eValueTypeHostAddress:
811 {
812 uint32_t data_offset = 0;
813 address = m_data.GetPointer(&data_offset);
814 address_type = m_value.GetValueAddressType();
815 if (address_type == eAddressTypeInvalid)
816 address_type = eAddressTypeLoad;
817 }
818 break;
819 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000820
821 if (m_pointers_point_to_load_addrs)
822 address_type = eAddressTypeLoad;
823
Greg Clayton737b9322010-09-13 03:32:57 +0000824 return address;
825}
826
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000827bool
Jim Ingham6035b672011-03-31 00:19:25 +0000828ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829{
830 // Make sure our value is up to date first so that our location and location
831 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +0000832 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000833 return false;
834
835 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +0000836 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837
838 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +0000839 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000840 switch (encoding)
841 {
842 case eEncodingInvalid:
843 return false;
844
845 case eEncodingUint:
846 if (byte_size > sizeof(unsigned long long))
847 {
848 return false;
849 }
850 else
851 {
852 unsigned long long ull_val = strtoull(value_str, &end, 0);
853 if (end && *end != '\0')
854 return false;
855 m_value = ull_val;
856 // Limit the bytes in our m_data appropriately.
857 m_value.GetScalar().GetData (m_data, byte_size);
858 }
859 break;
860
861 case eEncodingSint:
862 if (byte_size > sizeof(long long))
863 {
864 return false;
865 }
866 else
867 {
868 long long sll_val = strtoll(value_str, &end, 0);
869 if (end && *end != '\0')
870 return false;
871 m_value = sll_val;
872 // Limit the bytes in our m_data appropriately.
873 m_value.GetScalar().GetData (m_data, byte_size);
874 }
875 break;
876
877 case eEncodingIEEE754:
878 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000879 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +0000880 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000881 if (dst != NULL)
882 {
883 // We are decoding a float into host byte order below, so make
884 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +0000885 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000886 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
887 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000888 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000889 value_str,
890 dst,
891 byte_size);
892
893 if (converted_byte_size == byte_size)
894 {
895 }
896 }
897 }
898 break;
899
900 case eEncodingVector:
901 return false;
902
903 default:
904 return false;
905 }
906
907 // If we have made it here the value is in m_data and we should write it
908 // out to the target
909 return Write ();
910}
911
912bool
913ValueObject::Write ()
914{
915 // Clear the update ID so the next time we try and read the value
916 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +0000917 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000918
919 // TODO: when Value has a method to write a value back, call it from here.
920 return false;
921
922}
923
Jim Ingham5a369122010-09-28 01:25:32 +0000924lldb::LanguageType
925ValueObject::GetObjectRuntimeLanguage ()
926{
Greg Clayton73b472d2010-10-27 03:32:59 +0000927 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +0000928 if (opaque_qual_type == NULL)
929 return lldb::eLanguageTypeC;
930
931 // If the type is a reference, then resolve it to what it refers to first:
932 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
933 if (qual_type->isAnyPointerType())
934 {
935 if (qual_type->isObjCObjectPointerType())
936 return lldb::eLanguageTypeObjC;
937
938 clang::QualType pointee_type (qual_type->getPointeeType());
939 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
940 return lldb::eLanguageTypeC_plus_plus;
941 if (pointee_type->isObjCObjectOrInterfaceType())
942 return lldb::eLanguageTypeObjC;
943 if (pointee_type->isObjCClassType())
944 return lldb::eLanguageTypeObjC;
945 }
946 else
947 {
948 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
949 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +0000950 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +0000951 return lldb::eLanguageTypeC_plus_plus;
952 }
953
954 return lldb::eLanguageTypeC;
955}
956
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000957void
Jim Ingham58b59f92011-04-22 23:53:53 +0000958ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000959{
Jim Ingham58b59f92011-04-22 23:53:53 +0000960 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000961}
962
963ValueObjectSP
964ValueObject::GetSyntheticChild (const ConstString &key) const
965{
966 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +0000967 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000968 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +0000969 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000970 return synthetic_child_sp;
971}
972
973bool
974ValueObject::IsPointerType ()
975{
Greg Clayton1be10fc2010-09-29 01:12:09 +0000976 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977}
978
Jim Inghamb7603bb2011-03-18 00:05:18 +0000979bool
980ValueObject::IsIntegerType (bool &is_signed)
981{
982 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
983}
Greg Clayton73b472d2010-10-27 03:32:59 +0000984
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000985bool
986ValueObject::IsPointerOrReferenceType ()
987{
Greg Clayton007d5be2011-05-30 00:49:24 +0000988 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
989}
990
991bool
992ValueObject::IsPossibleCPlusPlusDynamicType ()
993{
994 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000995}
996
997ValueObjectSP
998ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
999{
1000 ValueObjectSP synthetic_child_sp;
1001 if (IsPointerType ())
1002 {
1003 char index_str[64];
1004 snprintf(index_str, sizeof(index_str), "[%i]", index);
1005 ConstString index_const_str(index_str);
1006 // Check if we have already created a synthetic array member in this
1007 // valid object. If we have we will re-use it.
1008 synthetic_child_sp = GetSyntheticChild (index_const_str);
1009 if (!synthetic_child_sp)
1010 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001011 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001012 // We haven't made a synthetic array member for INDEX yet, so
1013 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001014 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015
1016 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001017 if (synthetic_child)
1018 {
1019 AddSyntheticChild(index_const_str, synthetic_child);
1020 synthetic_child_sp = synthetic_child->GetSP();
1021 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001022 }
1023 }
1024 return synthetic_child_sp;
1025}
Jim Ingham22777012010-09-23 02:01:19 +00001026
Jim Ingham78a685a2011-04-16 00:01:13 +00001027void
Jim Ingham2837b762011-05-04 03:43:18 +00001028ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001029{
Jim Ingham2837b762011-05-04 03:43:18 +00001030 if (use_dynamic == lldb::eNoDynamicValues)
1031 return;
1032
Jim Ingham58b59f92011-04-22 23:53:53 +00001033 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001034 {
1035 Process *process = m_update_point.GetProcess();
1036 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001037
Jim Ingham78a685a2011-04-16 00:01:13 +00001038
1039 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1040 // hard code this everywhere.
1041 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1042 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1043 {
1044 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1045 if (runtime)
1046 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1047 }
1048 else
1049 {
1050 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1051 if (cpp_runtime)
1052 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1053
1054 if (!worth_having_dynamic_value)
1055 {
1056 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1057 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001058 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001059 }
1060 }
1061
1062 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001063 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001064
1065// if (worth_having_dynamic_value)
1066// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1067
Jim Ingham78a685a2011-04-16 00:01:13 +00001068 }
1069}
1070
Jim Ingham58b59f92011-04-22 23:53:53 +00001071ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001072ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001073{
Jim Ingham2837b762011-05-04 03:43:18 +00001074 if (use_dynamic == lldb::eNoDynamicValues)
1075 return ValueObjectSP();
1076
1077 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001078 {
Jim Ingham2837b762011-05-04 03:43:18 +00001079 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001080 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001081 if (m_dynamic_value)
1082 return m_dynamic_value->GetSP();
1083 else
1084 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001085}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001086
Greg Claytone221f822011-01-21 01:59:00 +00001087bool
1088ValueObject::GetBaseClassPath (Stream &s)
1089{
1090 if (IsBaseClass())
1091 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001092 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001093 clang_type_t clang_type = GetClangType();
1094 std::string cxx_class_name;
1095 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1096 if (this_had_base_class)
1097 {
1098 if (parent_had_base_class)
1099 s.PutCString("::");
1100 s.PutCString(cxx_class_name.c_str());
1101 }
1102 return parent_had_base_class || this_had_base_class;
1103 }
1104 return false;
1105}
1106
1107
1108ValueObject *
1109ValueObject::GetNonBaseClassParent()
1110{
Jim Ingham78a685a2011-04-16 00:01:13 +00001111 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001112 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001113 if (GetParent()->IsBaseClass())
1114 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001115 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001116 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001117 }
1118 return NULL;
1119}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001120
1121void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001122ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001123{
Greg Claytone221f822011-01-21 01:59:00 +00001124 const bool is_deref_of_parent = IsDereferenceOfParent ();
1125
1126 if (is_deref_of_parent)
1127 s.PutCString("*(");
1128
Jim Ingham78a685a2011-04-16 00:01:13 +00001129 if (GetParent())
1130 GetParent()->GetExpressionPath (s, qualify_cxx_base_classes);
Greg Claytone221f822011-01-21 01:59:00 +00001131
1132 if (!IsBaseClass())
1133 {
1134 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001135 {
Greg Claytone221f822011-01-21 01:59:00 +00001136 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1137 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001138 {
Greg Claytone221f822011-01-21 01:59:00 +00001139 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1140 if (non_base_class_parent_clang_type)
1141 {
1142 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1143
1144 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1145 {
1146 s.PutCString("->");
1147 }
1148 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1149 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1150 {
1151 s.PutChar('.');
1152 }
1153 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001154 }
Greg Claytone221f822011-01-21 01:59:00 +00001155
1156 const char *name = GetName().GetCString();
1157 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001158 {
Greg Claytone221f822011-01-21 01:59:00 +00001159 if (qualify_cxx_base_classes)
1160 {
1161 if (GetBaseClassPath (s))
1162 s.PutCString("::");
1163 }
1164 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001165 }
1166 }
1167 }
1168
Greg Claytone221f822011-01-21 01:59:00 +00001169 if (is_deref_of_parent)
1170 s.PutChar(')');
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001171}
1172
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001173void
Greg Clayton1d3afba2010-10-05 00:00:42 +00001174ValueObject::DumpValueObject
1175(
1176 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00001177 ValueObject *valobj,
1178 const char *root_valobj_name,
1179 uint32_t ptr_depth,
1180 uint32_t curr_depth,
1181 uint32_t max_depth,
1182 bool show_types,
1183 bool show_location,
1184 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00001185 lldb::DynamicValueType use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001186 bool scope_already_checked,
1187 bool flat_output
Greg Clayton1d3afba2010-10-05 00:00:42 +00001188)
1189{
Greg Clayton007d5be2011-05-30 00:49:24 +00001190 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001191 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001192 bool update_success = valobj->UpdateValueIfNeeded ();
1193
1194 if (update_success && use_dynamic != lldb::eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00001195 {
Jim Ingham2837b762011-05-04 03:43:18 +00001196 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00001197 if (dynamic_value)
1198 valobj = dynamic_value;
1199 }
1200
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001201 clang_type_t clang_type = valobj->GetClangType();
1202
Greg Clayton73b472d2010-10-27 03:32:59 +00001203 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001204 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00001205 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
1206 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001207
1208 const bool print_valobj = flat_output == false || has_value;
1209
1210 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001211 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001212 if (show_location)
1213 {
Jim Ingham6035b672011-03-31 00:19:25 +00001214 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001215 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001216
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001217 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001218
Greg Clayton7c8a9662010-11-02 01:50:16 +00001219 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00001220 if (show_types || (curr_depth == 0 && !flat_output))
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001221 s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
Greg Clayton1d3afba2010-10-05 00:00:42 +00001222
Greg Clayton1d3afba2010-10-05 00:00:42 +00001223
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001224 if (flat_output)
1225 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001226 // If we are showing types, also qualify the C++ base classes
1227 const bool qualify_cxx_base_classes = show_types;
1228 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001229 s.PutCString(" =");
1230 }
1231 else
1232 {
1233 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
1234 s.Printf ("%s =", name_cstr);
1235 }
1236
Jim Ingham6035b672011-03-31 00:19:25 +00001237 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001238 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001239 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001240 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001241 }
1242
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001243 const char *val_cstr = NULL;
1244
1245 if (err_cstr == NULL)
1246 {
Jim Ingham6035b672011-03-31 00:19:25 +00001247 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001248 err_cstr = valobj->GetError().AsCString();
1249 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001250
1251 if (err_cstr)
1252 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001253 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00001254 }
1255 else
1256 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001257 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001258 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001259 {
Jim Ingham6035b672011-03-31 00:19:25 +00001260 const char *sum_cstr = valobj->GetSummaryAsCString();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001261
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001262 if (val_cstr)
1263 s.Printf(" %s", val_cstr);
1264
1265 if (sum_cstr)
1266 s.Printf(" %s", sum_cstr);
1267
1268 if (use_objc)
1269 {
Jim Ingham6035b672011-03-31 00:19:25 +00001270 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001271 if (object_desc)
1272 s.Printf(" %s\n", object_desc);
1273 else
Sean Callanan672ad942010-10-23 00:18:49 +00001274 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001275 return;
1276 }
1277 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001278
1279 if (curr_depth < max_depth)
1280 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001281 // We will show children for all concrete types. We won't show
1282 // pointer contents unless a pointer depth has been specified.
1283 // We won't reference contents unless the reference is the
1284 // root object (depth of zero).
1285 bool print_children = true;
1286
1287 // Use a new temporary pointer depth in case we override the
1288 // current pointer depth below...
1289 uint32_t curr_ptr_depth = ptr_depth;
1290
1291 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
1292 if (is_ptr || is_ref)
1293 {
1294 // We have a pointer or reference whose value is an address.
1295 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00001296 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00001297 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
1298 print_children = false;
1299
1300 else if (is_ref && curr_depth == 0)
1301 {
1302 // If this is the root object (depth is zero) that we are showing
1303 // and it is a reference, and no pointer depth has been supplied
1304 // print out what it references. Don't do this at deeper depths
1305 // otherwise we can end up with infinite recursion...
1306 curr_ptr_depth = 1;
1307 }
1308
1309 if (curr_ptr_depth == 0)
1310 print_children = false;
1311 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001312
Greg Clayton73b472d2010-10-27 03:32:59 +00001313 if (print_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001314 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001315 const uint32_t num_children = valobj->GetNumChildren();
1316 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001317 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001318 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001319 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001320 if (print_valobj)
1321 s.EOL();
1322 }
1323 else
1324 {
1325 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00001326 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001327 s.IndentMore();
1328 }
1329
1330 for (uint32_t idx=0; idx<num_children; ++idx)
1331 {
1332 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
1333 if (child_sp.get())
1334 {
1335 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001336 child_sp.get(),
1337 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00001338 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001339 curr_depth + 1,
1340 max_depth,
1341 show_types,
1342 show_location,
1343 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00001344 use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001345 true,
1346 flat_output);
1347 }
1348 }
1349
1350 if (!flat_output)
1351 {
1352 s.IndentLess();
1353 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001354 }
1355 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001356 else if (has_children)
1357 {
1358 // Aggregate, no children...
1359 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00001360 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001361 }
1362 else
1363 {
1364 if (print_valobj)
1365 s.EOL();
1366 }
1367
Greg Clayton1d3afba2010-10-05 00:00:42 +00001368 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001369 else
1370 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00001371 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001372 }
1373 }
1374 else
1375 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001376 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001377 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001378 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001379 }
1380 }
1381 }
1382 }
1383}
1384
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001385
1386ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00001387ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001388{
1389 ValueObjectSP valobj_sp;
1390
Jim Ingham6035b672011-03-31 00:19:25 +00001391 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001392 {
Jim Ingham6035b672011-03-31 00:19:25 +00001393 ExecutionContextScope *exe_scope = GetExecutionContextScope();
1394 if (exe_scope)
1395 {
1396 ExecutionContext exe_ctx;
1397 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001398
Jim Ingham6035b672011-03-31 00:19:25 +00001399 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001400
Jim Ingham6035b672011-03-31 00:19:25 +00001401 DataExtractor data;
1402 data.SetByteOrder (m_data.GetByteOrder());
1403 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001404
Jim Ingham6035b672011-03-31 00:19:25 +00001405 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001406
Jim Ingham58b59f92011-04-22 23:53:53 +00001407 valobj_sp = ValueObjectConstResult::Create (exe_scope,
1408 ast,
1409 GetClangType(),
1410 name,
1411 data);
Jim Ingham6035b672011-03-31 00:19:25 +00001412 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001413 }
Jim Ingham6035b672011-03-31 00:19:25 +00001414
1415 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001416 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001417 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001418 }
1419 return valobj_sp;
1420}
1421
1422lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00001423ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001424{
Jim Ingham58b59f92011-04-22 23:53:53 +00001425 if (m_deref_valobj)
1426 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00001427
Greg Clayton54979cd2010-12-15 05:08:08 +00001428 const bool is_pointer_type = IsPointerType();
1429 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001430 {
1431 bool omit_empty_base_classes = true;
1432
1433 std::string child_name_str;
1434 uint32_t child_byte_size = 0;
1435 int32_t child_byte_offset = 0;
1436 uint32_t child_bitfield_bit_size = 0;
1437 uint32_t child_bitfield_bit_offset = 0;
1438 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00001439 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001440 const bool transparent_pointers = false;
1441 clang::ASTContext *clang_ast = GetClangAST();
1442 clang_type_t clang_type = GetClangType();
1443 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00001444
1445 ExecutionContext exe_ctx;
1446 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
1447
1448 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
1449 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001450 GetName().GetCString(),
1451 clang_type,
1452 0,
1453 transparent_pointers,
1454 omit_empty_base_classes,
1455 child_name_str,
1456 child_byte_size,
1457 child_byte_offset,
1458 child_bitfield_bit_size,
1459 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00001460 child_is_base_class,
1461 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00001462 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001463 {
1464 ConstString child_name;
1465 if (!child_name_str.empty())
1466 child_name.SetCString (child_name_str.c_str());
1467
Jim Ingham58b59f92011-04-22 23:53:53 +00001468 m_deref_valobj = new ValueObjectChild (*this,
1469 clang_ast,
1470 child_clang_type,
1471 child_name,
1472 child_byte_size,
1473 child_byte_offset,
1474 child_bitfield_bit_size,
1475 child_bitfield_bit_offset,
1476 child_is_base_class,
1477 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001478 }
1479 }
Greg Clayton54979cd2010-12-15 05:08:08 +00001480
Jim Ingham58b59f92011-04-22 23:53:53 +00001481 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00001482 {
1483 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00001484 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00001485 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001486 else
1487 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001488 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001489 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001490
1491 if (is_pointer_type)
1492 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
1493 else
1494 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00001495 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001496 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001497}
1498
Jim Ingham78a685a2011-04-16 00:01:13 +00001499lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00001500ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001501{
Jim Ingham78a685a2011-04-16 00:01:13 +00001502 if (m_addr_of_valobj_sp)
1503 return m_addr_of_valobj_sp;
1504
Greg Claytone0d378b2011-03-24 21:19:54 +00001505 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001506 const bool scalar_is_load_address = false;
1507 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00001508 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001509 if (addr != LLDB_INVALID_ADDRESS)
1510 {
1511 switch (address_type)
1512 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001513 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001514 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00001515 {
1516 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001517 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001518 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
1519 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001520 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00001521
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001522 case eAddressTypeFile:
1523 case eAddressTypeLoad:
1524 case eAddressTypeHost:
1525 {
1526 clang::ASTContext *ast = GetClangAST();
1527 clang_type_t clang_type = GetClangType();
1528 if (ast && clang_type)
1529 {
1530 std::string name (1, '&');
1531 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00001532 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
1533 ast,
1534 ClangASTContext::CreatePointerType (ast, clang_type),
1535 ConstString (name.c_str()),
1536 addr,
1537 eAddressTypeInvalid,
1538 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001539 }
1540 }
1541 break;
1542 }
1543 }
Jim Ingham78a685a2011-04-16 00:01:13 +00001544 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001545}
1546
Greg Claytonb2dcc362011-05-05 23:32:56 +00001547
1548lldb::ValueObjectSP
1549ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
1550{
1551 lldb::ValueObjectSP valobj_sp;
1552 AddressType address_type;
1553 const bool scalar_is_load_address = true;
1554 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
1555
1556 if (ptr_value != LLDB_INVALID_ADDRESS)
1557 {
1558 Address ptr_addr (NULL, ptr_value);
1559
1560 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
1561 name,
1562 ptr_addr,
1563 clang_ast_type);
1564 }
1565 return valobj_sp;
1566}
1567
1568lldb::ValueObjectSP
1569ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
1570{
1571 lldb::ValueObjectSP valobj_sp;
1572 AddressType address_type;
1573 const bool scalar_is_load_address = true;
1574 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
1575
1576 if (ptr_value != LLDB_INVALID_ADDRESS)
1577 {
1578 Address ptr_addr (NULL, ptr_value);
1579
1580 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
1581 name,
1582 ptr_addr,
1583 type_sp);
1584 }
1585 return valobj_sp;
1586}
1587
1588
Jim Ingham6035b672011-03-31 00:19:25 +00001589ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00001590 m_thread_id (LLDB_INVALID_UID),
1591 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00001592{
1593}
1594
1595ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00001596 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00001597 m_first_update (true),
1598 m_thread_id (LLDB_INVALID_UID),
1599 m_stop_id (0)
1600
Jim Ingham6035b672011-03-31 00:19:25 +00001601{
1602 ExecutionContext exe_ctx;
1603 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
1604 // and if so we want to cache that not the original.
1605 if (exe_scope)
1606 exe_scope->CalculateExecutionContext(exe_ctx);
1607 if (exe_ctx.target != NULL)
1608 {
1609 m_target_sp = exe_ctx.target->GetSP();
1610
1611 if (exe_ctx.process == NULL)
1612 m_process_sp = exe_ctx.target->GetProcessSP();
1613 else
1614 m_process_sp = exe_ctx.process->GetSP();
1615
1616 if (m_process_sp != NULL)
1617 {
1618 m_stop_id = m_process_sp->GetStopID();
1619 Thread *thread = NULL;
1620
1621 if (exe_ctx.thread == NULL)
1622 {
1623 if (use_selected)
1624 {
1625 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
1626 if (thread)
1627 computed_exe_scope = thread;
1628 }
1629 }
1630 else
1631 thread = exe_ctx.thread;
1632
1633 if (thread != NULL)
1634 {
1635 m_thread_id = thread->GetIndexID();
1636 if (exe_ctx.frame == NULL)
1637 {
1638 if (use_selected)
1639 {
1640 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
1641 if (frame)
1642 {
1643 m_stack_id = frame->GetStackID();
1644 computed_exe_scope = frame;
1645 }
1646 }
1647 }
1648 else
1649 m_stack_id = exe_ctx.frame->GetStackID();
1650 }
1651 }
1652 }
1653 m_exe_scope = computed_exe_scope;
1654}
1655
1656ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
1657 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00001658 m_needs_update(true),
1659 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00001660 m_target_sp (rhs.m_target_sp),
1661 m_process_sp (rhs.m_process_sp),
1662 m_thread_id (rhs.m_thread_id),
1663 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00001664 m_stop_id (0)
1665{
1666}
1667
1668ValueObject::EvaluationPoint::~EvaluationPoint ()
1669{
1670}
1671
1672ExecutionContextScope *
1673ValueObject::EvaluationPoint::GetExecutionContextScope ()
1674{
1675 // We have to update before giving out the scope, or we could be handing out stale pointers.
1676 SyncWithProcessState();
1677
1678 return m_exe_scope;
1679}
1680
1681// This function checks the EvaluationPoint against the current process state. If the current
1682// state matches the evaluation point, or the evaluation point is already invalid, then we return
1683// false, meaning "no change". If the current state is different, we update our state, and return
1684// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
1685// future calls to NeedsUpdate will return true.
1686
1687bool
1688ValueObject::EvaluationPoint::SyncWithProcessState()
1689{
1690 // If we're already invalid, we don't need to do anything, and nothing has changed:
1691 if (m_stop_id == LLDB_INVALID_UID)
1692 {
1693 // Can't update with an invalid state.
1694 m_needs_update = false;
1695 return false;
1696 }
1697
1698 // If we don't have a process nothing can change.
1699 if (!m_process_sp)
1700 return false;
1701
1702 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00001703 uint32_t cur_stop_id = m_process_sp->GetStopID();
1704 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00001705 return false;
1706
Jim Ingham78a685a2011-04-16 00:01:13 +00001707 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
1708 // In either case, we aren't going to be able to sync with the process state.
1709 if (cur_stop_id == 0)
1710 return false;
1711
1712 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00001713 m_needs_update = true;
1714 m_exe_scope = m_process_sp.get();
1715
1716 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
1717 // doesn't, mark ourselves as invalid.
1718
1719 if (m_thread_id != LLDB_INVALID_THREAD_ID)
1720 {
1721 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
1722 if (our_thread == NULL)
1723 SetInvalid();
1724 else
1725 {
1726 m_exe_scope = our_thread;
1727
1728 if (m_stack_id.IsValid())
1729 {
1730 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
1731 if (our_frame == NULL)
1732 SetInvalid();
1733 else
1734 m_exe_scope = our_frame;
1735 }
1736 }
1737 }
1738 return true;
1739}
1740
Jim Ingham61be0902011-05-02 18:13:59 +00001741void
1742ValueObject::EvaluationPoint::SetUpdated ()
1743{
1744 m_first_update = false;
1745 m_needs_update = false;
1746 if (m_process_sp)
1747 m_stop_id = m_process_sp->GetStopID();
1748}
1749
1750
Jim Ingham6035b672011-03-31 00:19:25 +00001751bool
1752ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
1753{
1754 if (!IsValid())
1755 return false;
1756
1757 bool needs_update = false;
1758 m_exe_scope = NULL;
1759
1760 // The target has to be non-null, and the
1761 Target *target = exe_scope->CalculateTarget();
1762 if (target != NULL)
1763 {
1764 Target *old_target = m_target_sp.get();
1765 assert (target == old_target);
1766 Process *process = exe_scope->CalculateProcess();
1767 if (process != NULL)
1768 {
1769 // FOR NOW - assume you can't update variable objects across process boundaries.
1770 Process *old_process = m_process_sp.get();
1771 assert (process == old_process);
1772
1773 lldb::user_id_t stop_id = process->GetStopID();
1774 if (stop_id != m_stop_id)
1775 {
1776 needs_update = true;
1777 m_stop_id = stop_id;
1778 }
1779 // See if we're switching the thread or stack context. If no thread is given, this is
1780 // being evaluated in a global context.
1781 Thread *thread = exe_scope->CalculateThread();
1782 if (thread != NULL)
1783 {
1784 lldb::user_id_t new_thread_index = thread->GetIndexID();
1785 if (new_thread_index != m_thread_id)
1786 {
1787 needs_update = true;
1788 m_thread_id = new_thread_index;
1789 m_stack_id.Clear();
1790 }
1791
1792 StackFrame *new_frame = exe_scope->CalculateStackFrame();
1793 if (new_frame != NULL)
1794 {
1795 if (new_frame->GetStackID() != m_stack_id)
1796 {
1797 needs_update = true;
1798 m_stack_id = new_frame->GetStackID();
1799 }
1800 }
1801 else
1802 {
1803 m_stack_id.Clear();
1804 needs_update = true;
1805 }
1806 }
1807 else
1808 {
1809 // If this had been given a thread, and now there is none, we should update.
1810 // Otherwise we don't have to do anything.
1811 if (m_thread_id != LLDB_INVALID_UID)
1812 {
1813 m_thread_id = LLDB_INVALID_UID;
1814 m_stack_id.Clear();
1815 needs_update = true;
1816 }
1817 }
1818 }
1819 else
1820 {
1821 // If there is no process, then we don't need to update anything.
1822 // But if we're switching from having a process to not, we should try to update.
1823 if (m_process_sp.get() != NULL)
1824 {
1825 needs_update = true;
1826 m_process_sp.reset();
1827 m_thread_id = LLDB_INVALID_UID;
1828 m_stack_id.Clear();
1829 }
1830 }
1831 }
1832 else
1833 {
1834 // If there's no target, nothing can change so we don't need to update anything.
1835 // But if we're switching from having a target to not, we should try to update.
1836 if (m_target_sp.get() != NULL)
1837 {
1838 needs_update = true;
1839 m_target_sp.reset();
1840 m_process_sp.reset();
1841 m_thread_id = LLDB_INVALID_UID;
1842 m_stack_id.Clear();
1843 }
1844 }
1845 if (!m_needs_update)
1846 m_needs_update = needs_update;
1847
1848 return needs_update;
1849}