blob: 1f443e81502b96bafc6726b804ea8a94e56b3b1a [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"
27
Greg Clayton7fb56d02011-02-01 01:31:41 +000028#include "lldb/Host/Endian.h"
29
Greg Claytone1a916a2010-07-21 22:12:05 +000030#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Symbol/ClangASTContext.h"
32#include "lldb/Symbol/Type.h"
33
Jim Ingham53c47f12010-09-10 23:12:17 +000034#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000035#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036#include "lldb/Target/Process.h"
37#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000038#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040
41using namespace lldb;
42using namespace lldb_private;
43
44static lldb::user_id_t g_value_obj_uid = 0;
45
46//----------------------------------------------------------------------
47// ValueObject constructor
48//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000049ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000051 m_parent (&parent),
Stephen Wilson71c21d12011-04-11 19:41:40 +000052 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053 m_name (),
54 m_data (),
55 m_value (),
56 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000057 m_value_str (),
58 m_old_value_str (),
59 m_location_str (),
60 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000061 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000062 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000063 m_children (),
64 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000065 m_dynamic_value (NULL),
66 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000067 m_format (eFormatDefault),
Greg Clayton288bdf92010-09-02 02:59:18 +000068 m_value_is_valid (false),
69 m_value_did_change (false),
70 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000071 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000072 m_pointers_point_to_load_addrs (false),
Stephen Wilson71c21d12011-04-11 19:41:40 +000073 m_is_deref_of_parent (false)
Jim Ingham6035b672011-03-31 00:19:25 +000074{
Jim Ingham58b59f92011-04-22 23:53:53 +000075 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +000076}
77
78//----------------------------------------------------------------------
79// ValueObject constructor
80//----------------------------------------------------------------------
81ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
82 UserID (++g_value_obj_uid), // Unique identifier for every value object
83 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +000084 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +000085 m_name (),
86 m_data (),
87 m_value (),
88 m_error (),
89 m_value_str (),
90 m_old_value_str (),
91 m_location_str (),
92 m_summary_str (),
93 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000094 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +000095 m_children (),
96 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000097 m_dynamic_value (NULL),
98 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +000099 m_format (eFormatDefault),
100 m_value_is_valid (false),
101 m_value_did_change (false),
102 m_children_count_valid (false),
103 m_old_value_valid (false),
104 m_pointers_point_to_load_addrs (false),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000105 m_is_deref_of_parent (false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106{
Jim Ingham58b59f92011-04-22 23:53:53 +0000107 m_manager = new ValueObjectManager();
108 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109}
110
111//----------------------------------------------------------------------
112// Destructor
113//----------------------------------------------------------------------
114ValueObject::~ValueObject ()
115{
116}
117
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118bool
Jim Ingham6035b672011-03-31 00:19:25 +0000119ValueObject::UpdateValueIfNeeded ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000120{
Greg Claytonb71f3842010-10-05 03:13:51 +0000121 // If this is a constant value, then our success is predicated on whether
122 // we have an error or not
123 if (GetIsConstant())
124 return m_error.Success();
125
Jim Ingham6035b672011-03-31 00:19:25 +0000126 bool first_update = m_update_point.IsFirstEvaluation();
127
128 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129 {
Jim Ingham6035b672011-03-31 00:19:25 +0000130 m_update_point.SetUpdated();
131
132 // Save the old value using swap to avoid a string copy which
133 // also will clear our m_value_str
134 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135 {
Jim Ingham6035b672011-03-31 00:19:25 +0000136 m_old_value_valid = false;
137 }
138 else
139 {
140 m_old_value_valid = true;
141 m_old_value_str.swap (m_value_str);
142 m_value_str.clear();
143 }
144 m_location_str.clear();
145 m_summary_str.clear();
146 m_object_desc_str.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147
Jim Ingham6035b672011-03-31 00:19:25 +0000148 const bool value_was_valid = GetValueIsValid();
149 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000150
Jim Ingham6035b672011-03-31 00:19:25 +0000151 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000152
Jim Ingham6035b672011-03-31 00:19:25 +0000153 // Call the pure virtual function to update the value
154 bool success = UpdateValue ();
155
156 SetValueIsValid (success);
157
158 if (first_update)
159 SetValueDidChange (false);
160 else if (!m_value_did_change && success == false)
161 {
162 // The value wasn't gotten successfully, so we mark this
163 // as changed if the value used to be valid and now isn't
164 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165 }
166 }
167 return m_error.Success();
168}
169
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170DataExtractor &
171ValueObject::GetDataExtractor ()
172{
Jim Ingham78a685a2011-04-16 00:01:13 +0000173 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174 return m_data;
175}
176
177const Error &
178ValueObject::GetError() const
179{
180 return m_error;
181}
182
183const ConstString &
184ValueObject::GetName() const
185{
186 return m_name;
187}
188
189const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000190ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191{
Jim Ingham6035b672011-03-31 00:19:25 +0000192 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193 {
194 if (m_location_str.empty())
195 {
196 StreamString sstr;
197
198 switch (m_value.GetValueType())
199 {
200 default:
201 break;
202
203 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000204 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205 {
206 RegisterInfo *reg_info = m_value.GetRegisterInfo();
207 if (reg_info)
208 {
209 if (reg_info->name)
210 m_location_str = reg_info->name;
211 else if (reg_info->alt_name)
212 m_location_str = reg_info->alt_name;
213 break;
214 }
215 }
216 m_location_str = "scalar";
217 break;
218
219 case Value::eValueTypeLoadAddress:
220 case Value::eValueTypeFileAddress:
221 case Value::eValueTypeHostAddress:
222 {
223 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
224 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
225 m_location_str.swap(sstr.GetString());
226 }
227 break;
228 }
229 }
230 }
231 return m_location_str.c_str();
232}
233
234Value &
235ValueObject::GetValue()
236{
237 return m_value;
238}
239
240const Value &
241ValueObject::GetValue() const
242{
243 return m_value;
244}
245
246bool
Jim Ingham6035b672011-03-31 00:19:25 +0000247ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000248{
249 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000250 ExecutionContextScope *exe_scope = GetExecutionContextScope();
251 if (exe_scope)
252 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000253 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
254 return scalar.IsValid();
255}
256
257bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000258ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259{
Greg Clayton288bdf92010-09-02 02:59:18 +0000260 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261}
262
263
264void
265ValueObject::SetValueIsValid (bool b)
266{
Greg Clayton288bdf92010-09-02 02:59:18 +0000267 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268}
269
270bool
Jim Ingham6035b672011-03-31 00:19:25 +0000271ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000272{
Jim Ingham6035b672011-03-31 00:19:25 +0000273 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000274 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275}
276
277void
278ValueObject::SetValueDidChange (bool value_changed)
279{
Greg Clayton288bdf92010-09-02 02:59:18 +0000280 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281}
282
283ValueObjectSP
284ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
285{
286 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000287 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000289 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000291 // Check if we have already made the child value object?
Jim Ingham58b59f92011-04-22 23:53:53 +0000292 if (can_create && m_children[idx] == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +0000293 {
294 // No we haven't created the child at this index, so lets have our
295 // subclass do it and cache the result for quick future access.
296 m_children[idx] = CreateChildAtIndex (idx, false, 0);
297 }
Jim Ingham58b59f92011-04-22 23:53:53 +0000298
299 if (m_children[idx] != NULL)
300 return m_children[idx]->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +0000301 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000302 }
303 return child_sp;
304}
305
306uint32_t
307ValueObject::GetIndexOfChildWithName (const ConstString &name)
308{
309 bool omit_empty_base_classes = true;
310 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000311 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000312 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 omit_empty_base_classes);
314}
315
316ValueObjectSP
317ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
318{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000319 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000320 // classes (which really aren't part of the expression path), so we
321 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000323
324 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000326 std::vector<uint32_t> child_indexes;
327 clang::ASTContext *clang_ast = GetClangAST();
328 void *clang_type = GetClangType();
329 bool omit_empty_base_classes = true;
330 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
331 clang_type,
332 name.GetCString(),
333 omit_empty_base_classes,
334 child_indexes);
335 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000337 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
338 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339
Jim Ingham78a685a2011-04-16 00:01:13 +0000340 child_sp = GetChildAtIndex(*pos, can_create);
341 for (++pos; pos != end; ++pos)
342 {
343 if (child_sp)
344 {
345 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
346 child_sp = new_child_sp;
347 }
348 else
349 {
350 child_sp.reset();
351 }
352
353 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000354 }
355 }
356 return child_sp;
357}
358
359
360uint32_t
361ValueObject::GetNumChildren ()
362{
Greg Clayton288bdf92010-09-02 02:59:18 +0000363 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364 {
365 SetNumChildren (CalculateNumChildren());
366 }
367 return m_children.size();
368}
369void
370ValueObject::SetNumChildren (uint32_t num_children)
371{
Greg Clayton288bdf92010-09-02 02:59:18 +0000372 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373 m_children.resize(num_children);
374}
375
376void
377ValueObject::SetName (const char *name)
378{
379 m_name.SetCString(name);
380}
381
382void
383ValueObject::SetName (const ConstString &name)
384{
385 m_name = name;
386}
387
Jim Ingham58b59f92011-04-22 23:53:53 +0000388ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
390{
Jim Ingham58b59f92011-04-22 23:53:53 +0000391 ValueObject *valobj;
Jim Ingham78a685a2011-04-16 00:01:13 +0000392
393 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000395 bool omit_empty_base_classes = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396
Jim Ingham78a685a2011-04-16 00:01:13 +0000397 std::string child_name_str;
398 uint32_t child_byte_size = 0;
399 int32_t child_byte_offset = 0;
400 uint32_t child_bitfield_bit_size = 0;
401 uint32_t child_bitfield_bit_offset = 0;
402 bool child_is_base_class = false;
403 bool child_is_deref_of_parent = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404
Jim Ingham78a685a2011-04-16 00:01:13 +0000405 const bool transparent_pointers = synthetic_array_member == false;
406 clang::ASTContext *clang_ast = GetClangAST();
407 clang_type_t clang_type = GetClangType();
408 clang_type_t child_clang_type;
409 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast,
410 GetName().GetCString(),
411 clang_type,
412 idx,
413 transparent_pointers,
414 omit_empty_base_classes,
415 child_name_str,
416 child_byte_size,
417 child_byte_offset,
418 child_bitfield_bit_size,
419 child_bitfield_bit_offset,
420 child_is_base_class,
421 child_is_deref_of_parent);
422 if (child_clang_type && child_byte_size)
423 {
424 if (synthetic_index)
425 child_byte_offset += child_byte_size * synthetic_index;
426
427 ConstString child_name;
428 if (!child_name_str.empty())
429 child_name.SetCString (child_name_str.c_str());
430
Jim Ingham58b59f92011-04-22 23:53:53 +0000431 valobj = new ValueObjectChild (*this,
432 clang_ast,
433 child_clang_type,
434 child_name,
435 child_byte_size,
436 child_byte_offset,
437 child_bitfield_bit_size,
438 child_bitfield_bit_offset,
439 child_is_base_class,
440 child_is_deref_of_parent);
Jim Ingham78a685a2011-04-16 00:01:13 +0000441 if (m_pointers_point_to_load_addrs)
Jim Ingham58b59f92011-04-22 23:53:53 +0000442 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Jim Ingham78a685a2011-04-16 00:01:13 +0000443 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000444 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000445
Jim Ingham58b59f92011-04-22 23:53:53 +0000446 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447}
448
449const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000450ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451{
Jim Ingham6035b672011-03-31 00:19:25 +0000452 if (UpdateValueIfNeeded ())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453 {
454 if (m_summary_str.empty())
455 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000456 clang_type_t clang_type = GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457
458 // See if this is a pointer to a C string?
Greg Clayton737b9322010-09-13 03:32:57 +0000459 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000460 {
Greg Clayton737b9322010-09-13 03:32:57 +0000461 StreamString sstr;
Greg Clayton73b472d2010-10-27 03:32:59 +0000462 clang_type_t elem_or_pointee_clang_type;
463 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000464 GetClangAST(),
465 &elem_or_pointee_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +0000466
Jim Ingham6035b672011-03-31 00:19:25 +0000467 ExecutionContextScope *exe_scope = GetExecutionContextScope();
468 if (exe_scope)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469 {
Jim Ingham6035b672011-03-31 00:19:25 +0000470 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
471 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472 {
Jim Ingham6035b672011-03-31 00:19:25 +0000473 Process *process = exe_scope->CalculateProcess();
474 if (process != NULL)
475 {
476 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
477 AddressType cstr_address_type = eAddressTypeInvalid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478
Jim Ingham6035b672011-03-31 00:19:25 +0000479 size_t cstr_len = 0;
480 if (type_flags.Test (ClangASTContext::eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481 {
Jim Ingham6035b672011-03-31 00:19:25 +0000482 // We have an array
483 cstr_len = ClangASTContext::GetArraySize (clang_type);
484 cstr_address = GetAddressOf (cstr_address_type, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000485 }
Greg Clayton737b9322010-09-13 03:32:57 +0000486 else
487 {
Jim Ingham6035b672011-03-31 00:19:25 +0000488 // We have a pointer
489 cstr_address = GetPointerValue (cstr_address_type, true);
Greg Clayton737b9322010-09-13 03:32:57 +0000490 }
Jim Ingham6035b672011-03-31 00:19:25 +0000491 if (cstr_address != LLDB_INVALID_ADDRESS)
Greg Clayton737b9322010-09-13 03:32:57 +0000492 {
Jim Ingham6035b672011-03-31 00:19:25 +0000493 DataExtractor data;
494 size_t bytes_read = 0;
495 std::vector<char> data_buffer;
496 Error error;
497 if (cstr_len > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000498 {
Jim Ingham6035b672011-03-31 00:19:25 +0000499 data_buffer.resize(cstr_len);
500 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
501 bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error);
502 if (bytes_read > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000503 {
Jim Ingham6035b672011-03-31 00:19:25 +0000504 sstr << '"';
505 data.Dump (&sstr,
506 0, // Start offset in "data"
507 eFormatChar, // Print as characters
508 1, // Size of item (1 byte for a char!)
509 bytes_read, // How many bytes to print?
510 UINT32_MAX, // num per line
511 LLDB_INVALID_ADDRESS,// base address
512 0, // bitfield bit size
513 0); // bitfield bit offset
514 sstr << '"';
Greg Clayton737b9322010-09-13 03:32:57 +0000515 }
516 }
Jim Ingham6035b672011-03-31 00:19:25 +0000517 else
518 {
519 const size_t k_max_buf_size = 256;
520 data_buffer.resize (k_max_buf_size + 1);
521 // NULL terminate in case we don't get the entire C string
522 data_buffer.back() = '\0';
Greg Clayton737b9322010-09-13 03:32:57 +0000523
Jim Ingham6035b672011-03-31 00:19:25 +0000524 sstr << '"';
525
526 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
527 while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0)
528 {
529 size_t len = strlen(&data_buffer.front());
530 if (len == 0)
531 break;
532 if (len > bytes_read)
533 len = bytes_read;
534
535 data.Dump (&sstr,
536 0, // Start offset in "data"
537 eFormatChar, // Print as characters
538 1, // Size of item (1 byte for a char!)
539 len, // How many bytes to print?
540 UINT32_MAX, // num per line
541 LLDB_INVALID_ADDRESS,// base address
542 0, // bitfield bit size
543 0); // bitfield bit offset
544
545 if (len < k_max_buf_size)
546 break;
547 cstr_address += k_max_buf_size;
548 }
549 sstr << '"';
550 }
551 }
Greg Clayton737b9322010-09-13 03:32:57 +0000552 }
Jim Ingham6035b672011-03-31 00:19:25 +0000553
554 if (sstr.GetSize() > 0)
555 m_summary_str.assign (sstr.GetData(), sstr.GetSize());
Greg Clayton737b9322010-09-13 03:32:57 +0000556 }
Jim Ingham6035b672011-03-31 00:19:25 +0000557 else if (ClangASTContext::IsFunctionPointerType (clang_type))
Greg Clayton737b9322010-09-13 03:32:57 +0000558 {
Jim Ingham6035b672011-03-31 00:19:25 +0000559 AddressType func_ptr_address_type = eAddressTypeInvalid;
560 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
561
562 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
563 {
564 switch (func_ptr_address_type)
565 {
566 case eAddressTypeInvalid:
567 case eAddressTypeFile:
568 break;
569
570 case eAddressTypeLoad:
571 {
572 Address so_addr;
573 Target *target = exe_scope->CalculateTarget();
574 if (target && target->GetSectionLoadList().IsEmpty() == false)
575 {
576 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
577 {
578 so_addr.Dump (&sstr,
579 exe_scope,
580 Address::DumpStyleResolvedDescription,
581 Address::DumpStyleSectionNameOffset);
582 }
583 }
584 }
585 break;
586
587 case eAddressTypeHost:
588 break;
589 }
590 }
591 if (sstr.GetSize() > 0)
592 {
593 m_summary_str.assign (1, '(');
594 m_summary_str.append (sstr.GetData(), sstr.GetSize());
595 m_summary_str.append (1, ')');
596 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000597 }
598 }
599 }
600 }
601 }
602 if (m_summary_str.empty())
603 return NULL;
604 return m_summary_str.c_str();
605}
606
Jim Ingham53c47f12010-09-10 23:12:17 +0000607const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000608ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000609{
610 if (!m_object_desc_str.empty())
611 return m_object_desc_str.c_str();
612
Jim Ingham6035b672011-03-31 00:19:25 +0000613 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000614 return NULL;
Jim Ingham6035b672011-03-31 00:19:25 +0000615
616 ExecutionContextScope *exe_scope = GetExecutionContextScope();
617 if (exe_scope == NULL)
618 return NULL;
619
Jim Ingham53c47f12010-09-10 23:12:17 +0000620 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000621 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000622 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000623
Jim Ingham53c47f12010-09-10 23:12:17 +0000624 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000625
626 lldb::LanguageType language = GetObjectRuntimeLanguage();
627 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
628
Jim Inghama2cf2632010-12-23 02:29:54 +0000629 if (runtime == NULL)
630 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000631 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000632 clang_type_t opaque_qual_type = GetClangType();
633 if (opaque_qual_type != NULL)
634 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000635 bool is_signed;
636 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
637 || ClangASTContext::IsPointerType (opaque_qual_type))
638 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000639 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000640 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000641 }
642 }
643
Jim Ingham8d543de2011-03-31 23:01:21 +0000644 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000645 {
646 m_object_desc_str.append (s.GetData());
647 }
Sean Callanan672ad942010-10-23 00:18:49 +0000648
649 if (m_object_desc_str.empty())
650 return NULL;
651 else
652 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000653}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000654
655const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000656ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000657{
658 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000659 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000660 {
Jim Ingham6035b672011-03-31 00:19:25 +0000661 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000662 {
663 if (m_value_str.empty())
664 {
665 const Value::ContextType context_type = m_value.GetContextType();
666
667 switch (context_type)
668 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000669 case Value::eContextTypeClangType:
670 case Value::eContextTypeLLDBType:
671 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000673 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000674 if (clang_type)
675 {
676 StreamString sstr;
Greg Clayton68ebae62011-04-28 20:55:26 +0000677 Format format = GetFormat();
678 if (format == eFormatDefault)
679 format = ClangASTType::GetFormat(clang_type);
Greg Clayton32c40852010-10-06 03:09:11 +0000680
681 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
682 clang_type, // The clang type to display
683 &sstr,
Greg Clayton68ebae62011-04-28 20:55:26 +0000684 format, // Format to display this type with
Greg Clayton32c40852010-10-06 03:09:11 +0000685 m_data, // Data to extract from
686 0, // Byte offset into "m_data"
687 GetByteSize(), // Byte size of item in "m_data"
688 GetBitfieldBitSize(), // Bitfield bit size
689 GetBitfieldBitOffset())) // Bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000690 m_value_str.swap(sstr.GetString());
691 else
692 m_value_str.clear();
693 }
694 }
695 break;
696
Greg Clayton526e5af2010-11-13 03:52:47 +0000697 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000698 {
699 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
700 if (reg_info)
701 {
702 StreamString reg_sstr;
703 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
704 m_value_str.swap(reg_sstr.GetString());
705 }
706 }
707 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000708
709 default:
710 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711 }
712 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000713
714 if (!m_value_did_change && m_old_value_valid)
715 {
716 // The value was gotten successfully, so we consider the
717 // value as changed if the value string differs
718 SetValueDidChange (m_old_value_str != m_value_str);
719 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000720 }
721 }
722 if (m_value_str.empty())
723 return NULL;
724 return m_value_str.c_str();
725}
726
Greg Clayton737b9322010-09-13 03:32:57 +0000727addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000728ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +0000729{
Jim Ingham78a685a2011-04-16 00:01:13 +0000730 if (!UpdateValueIfNeeded())
731 return LLDB_INVALID_ADDRESS;
732
Greg Clayton73b472d2010-10-27 03:32:59 +0000733 switch (m_value.GetValueType())
734 {
735 case Value::eValueTypeScalar:
736 if (scalar_is_load_address)
737 {
738 address_type = eAddressTypeLoad;
739 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
740 }
741 break;
742
743 case Value::eValueTypeLoadAddress:
744 case Value::eValueTypeFileAddress:
745 case Value::eValueTypeHostAddress:
746 {
747 address_type = m_value.GetValueAddressType ();
748 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
749 }
750 break;
751 }
752 address_type = eAddressTypeInvalid;
753 return LLDB_INVALID_ADDRESS;
754}
755
756addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000757ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +0000758{
759 lldb::addr_t address = LLDB_INVALID_ADDRESS;
760 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +0000761
762 if (!UpdateValueIfNeeded())
763 return address;
764
Greg Clayton73b472d2010-10-27 03:32:59 +0000765 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +0000766 {
767 case Value::eValueTypeScalar:
768 if (scalar_is_load_address)
769 {
770 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
771 address_type = eAddressTypeLoad;
772 }
773 break;
774
775 case Value::eValueTypeLoadAddress:
776 case Value::eValueTypeFileAddress:
777 case Value::eValueTypeHostAddress:
778 {
779 uint32_t data_offset = 0;
780 address = m_data.GetPointer(&data_offset);
781 address_type = m_value.GetValueAddressType();
782 if (address_type == eAddressTypeInvalid)
783 address_type = eAddressTypeLoad;
784 }
785 break;
786 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000787
788 if (m_pointers_point_to_load_addrs)
789 address_type = eAddressTypeLoad;
790
Greg Clayton737b9322010-09-13 03:32:57 +0000791 return address;
792}
793
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000794bool
Jim Ingham6035b672011-03-31 00:19:25 +0000795ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000796{
797 // Make sure our value is up to date first so that our location and location
798 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +0000799 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800 return false;
801
802 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +0000803 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000804
805 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +0000806 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000807 switch (encoding)
808 {
809 case eEncodingInvalid:
810 return false;
811
812 case eEncodingUint:
813 if (byte_size > sizeof(unsigned long long))
814 {
815 return false;
816 }
817 else
818 {
819 unsigned long long ull_val = strtoull(value_str, &end, 0);
820 if (end && *end != '\0')
821 return false;
822 m_value = ull_val;
823 // Limit the bytes in our m_data appropriately.
824 m_value.GetScalar().GetData (m_data, byte_size);
825 }
826 break;
827
828 case eEncodingSint:
829 if (byte_size > sizeof(long long))
830 {
831 return false;
832 }
833 else
834 {
835 long long sll_val = strtoll(value_str, &end, 0);
836 if (end && *end != '\0')
837 return false;
838 m_value = sll_val;
839 // Limit the bytes in our m_data appropriately.
840 m_value.GetScalar().GetData (m_data, byte_size);
841 }
842 break;
843
844 case eEncodingIEEE754:
845 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000846 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +0000847 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000848 if (dst != NULL)
849 {
850 // We are decoding a float into host byte order below, so make
851 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +0000852 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
854 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000855 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000856 value_str,
857 dst,
858 byte_size);
859
860 if (converted_byte_size == byte_size)
861 {
862 }
863 }
864 }
865 break;
866
867 case eEncodingVector:
868 return false;
869
870 default:
871 return false;
872 }
873
874 // If we have made it here the value is in m_data and we should write it
875 // out to the target
876 return Write ();
877}
878
879bool
880ValueObject::Write ()
881{
882 // Clear the update ID so the next time we try and read the value
883 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +0000884 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000885
886 // TODO: when Value has a method to write a value back, call it from here.
887 return false;
888
889}
890
Jim Ingham5a369122010-09-28 01:25:32 +0000891lldb::LanguageType
892ValueObject::GetObjectRuntimeLanguage ()
893{
Greg Clayton73b472d2010-10-27 03:32:59 +0000894 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +0000895 if (opaque_qual_type == NULL)
896 return lldb::eLanguageTypeC;
897
898 // If the type is a reference, then resolve it to what it refers to first:
899 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
900 if (qual_type->isAnyPointerType())
901 {
902 if (qual_type->isObjCObjectPointerType())
903 return lldb::eLanguageTypeObjC;
904
905 clang::QualType pointee_type (qual_type->getPointeeType());
906 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
907 return lldb::eLanguageTypeC_plus_plus;
908 if (pointee_type->isObjCObjectOrInterfaceType())
909 return lldb::eLanguageTypeObjC;
910 if (pointee_type->isObjCClassType())
911 return lldb::eLanguageTypeObjC;
912 }
913 else
914 {
915 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
916 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +0000917 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +0000918 return lldb::eLanguageTypeC_plus_plus;
919 }
920
921 return lldb::eLanguageTypeC;
922}
923
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924void
Jim Ingham58b59f92011-04-22 23:53:53 +0000925ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000926{
Jim Ingham58b59f92011-04-22 23:53:53 +0000927 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000928}
929
930ValueObjectSP
931ValueObject::GetSyntheticChild (const ConstString &key) const
932{
933 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +0000934 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000935 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +0000936 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000937 return synthetic_child_sp;
938}
939
940bool
941ValueObject::IsPointerType ()
942{
Greg Clayton1be10fc2010-09-29 01:12:09 +0000943 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000944}
945
Jim Inghamb7603bb2011-03-18 00:05:18 +0000946bool
947ValueObject::IsIntegerType (bool &is_signed)
948{
949 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
950}
Greg Clayton73b472d2010-10-27 03:32:59 +0000951
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000952bool
953ValueObject::IsPointerOrReferenceType ()
954{
Greg Clayton1be10fc2010-09-29 01:12:09 +0000955 return ClangASTContext::IsPointerOrReferenceType(GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000956}
957
958ValueObjectSP
959ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
960{
961 ValueObjectSP synthetic_child_sp;
962 if (IsPointerType ())
963 {
964 char index_str[64];
965 snprintf(index_str, sizeof(index_str), "[%i]", index);
966 ConstString index_const_str(index_str);
967 // Check if we have already created a synthetic array member in this
968 // valid object. If we have we will re-use it.
969 synthetic_child_sp = GetSyntheticChild (index_const_str);
970 if (!synthetic_child_sp)
971 {
Jim Ingham58b59f92011-04-22 23:53:53 +0000972 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000973 // We haven't made a synthetic array member for INDEX yet, so
974 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +0000975 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000976
977 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +0000978 if (synthetic_child)
979 {
980 AddSyntheticChild(index_const_str, synthetic_child);
981 synthetic_child_sp = synthetic_child->GetSP();
982 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000983 }
984 }
985 return synthetic_child_sp;
986}
Jim Ingham22777012010-09-23 02:01:19 +0000987
Jim Ingham78a685a2011-04-16 00:01:13 +0000988void
989ValueObject::CalculateDynamicValue ()
Jim Ingham22777012010-09-23 02:01:19 +0000990{
Jim Ingham58b59f92011-04-22 23:53:53 +0000991 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +0000992 {
993 Process *process = m_update_point.GetProcess();
994 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +0000995
Jim Ingham78a685a2011-04-16 00:01:13 +0000996
997 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
998 // hard code this everywhere.
999 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1000 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1001 {
1002 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1003 if (runtime)
1004 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1005 }
1006 else
1007 {
1008 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1009 if (cpp_runtime)
1010 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1011
1012 if (!worth_having_dynamic_value)
1013 {
1014 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1015 if (objc_runtime)
1016 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1017 }
1018 }
1019
1020 if (worth_having_dynamic_value)
Jim Ingham58b59f92011-04-22 23:53:53 +00001021 m_dynamic_value = new ValueObjectDynamicValue (*this);
1022
1023// if (worth_having_dynamic_value)
1024// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1025
Jim Ingham78a685a2011-04-16 00:01:13 +00001026 }
1027}
1028
Jim Ingham58b59f92011-04-22 23:53:53 +00001029ValueObjectSP
Jim Ingham78a685a2011-04-16 00:01:13 +00001030ValueObject::GetDynamicValue (bool can_create)
1031{
Jim Ingham58b59f92011-04-22 23:53:53 +00001032 if (!IsDynamic() && m_dynamic_value == NULL && can_create)
Jim Ingham78a685a2011-04-16 00:01:13 +00001033 {
1034 CalculateDynamicValue();
1035 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001036 if (m_dynamic_value)
1037 return m_dynamic_value->GetSP();
1038 else
1039 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001040}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001041
Greg Claytone221f822011-01-21 01:59:00 +00001042bool
1043ValueObject::GetBaseClassPath (Stream &s)
1044{
1045 if (IsBaseClass())
1046 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001047 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001048 clang_type_t clang_type = GetClangType();
1049 std::string cxx_class_name;
1050 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1051 if (this_had_base_class)
1052 {
1053 if (parent_had_base_class)
1054 s.PutCString("::");
1055 s.PutCString(cxx_class_name.c_str());
1056 }
1057 return parent_had_base_class || this_had_base_class;
1058 }
1059 return false;
1060}
1061
1062
1063ValueObject *
1064ValueObject::GetNonBaseClassParent()
1065{
Jim Ingham78a685a2011-04-16 00:01:13 +00001066 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001067 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001068 if (GetParent()->IsBaseClass())
1069 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001070 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001071 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001072 }
1073 return NULL;
1074}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001075
1076void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001077ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001078{
Greg Claytone221f822011-01-21 01:59:00 +00001079 const bool is_deref_of_parent = IsDereferenceOfParent ();
1080
1081 if (is_deref_of_parent)
1082 s.PutCString("*(");
1083
Jim Ingham78a685a2011-04-16 00:01:13 +00001084 if (GetParent())
1085 GetParent()->GetExpressionPath (s, qualify_cxx_base_classes);
Greg Claytone221f822011-01-21 01:59:00 +00001086
1087 if (!IsBaseClass())
1088 {
1089 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001090 {
Greg Claytone221f822011-01-21 01:59:00 +00001091 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1092 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001093 {
Greg Claytone221f822011-01-21 01:59:00 +00001094 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1095 if (non_base_class_parent_clang_type)
1096 {
1097 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1098
1099 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1100 {
1101 s.PutCString("->");
1102 }
1103 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1104 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1105 {
1106 s.PutChar('.');
1107 }
1108 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001109 }
Greg Claytone221f822011-01-21 01:59:00 +00001110
1111 const char *name = GetName().GetCString();
1112 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001113 {
Greg Claytone221f822011-01-21 01:59:00 +00001114 if (qualify_cxx_base_classes)
1115 {
1116 if (GetBaseClassPath (s))
1117 s.PutCString("::");
1118 }
1119 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001120 }
1121 }
1122 }
1123
Greg Claytone221f822011-01-21 01:59:00 +00001124 if (is_deref_of_parent)
1125 s.PutChar(')');
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001126}
1127
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001128void
Greg Clayton1d3afba2010-10-05 00:00:42 +00001129ValueObject::DumpValueObject
1130(
1131 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00001132 ValueObject *valobj,
1133 const char *root_valobj_name,
1134 uint32_t ptr_depth,
1135 uint32_t curr_depth,
1136 uint32_t max_depth,
1137 bool show_types,
1138 bool show_location,
1139 bool use_objc,
Jim Ingham78a685a2011-04-16 00:01:13 +00001140 bool use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001141 bool scope_already_checked,
1142 bool flat_output
Greg Clayton1d3afba2010-10-05 00:00:42 +00001143)
1144{
Jim Ingham6035b672011-03-31 00:19:25 +00001145 if (valobj && valobj->UpdateValueIfNeeded ())
Greg Clayton1d3afba2010-10-05 00:00:42 +00001146 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001147 if (use_dynamic)
1148 {
1149 ValueObject *dynamic_value = valobj->GetDynamicValue(true).get();
1150 if (dynamic_value)
1151 valobj = dynamic_value;
1152 }
1153
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001154 clang_type_t clang_type = valobj->GetClangType();
1155
Greg Clayton73b472d2010-10-27 03:32:59 +00001156 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001157 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00001158 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
1159 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001160
1161 const bool print_valobj = flat_output == false || has_value;
1162
1163 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001164 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001165 if (show_location)
1166 {
Jim Ingham6035b672011-03-31 00:19:25 +00001167 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001168 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001169
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001170 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001171
Greg Clayton7c8a9662010-11-02 01:50:16 +00001172 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00001173 if (show_types || (curr_depth == 0 && !flat_output))
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001174 s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
Greg Clayton1d3afba2010-10-05 00:00:42 +00001175
Greg Clayton1d3afba2010-10-05 00:00:42 +00001176
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001177 if (flat_output)
1178 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001179 // If we are showing types, also qualify the C++ base classes
1180 const bool qualify_cxx_base_classes = show_types;
1181 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001182 s.PutCString(" =");
1183 }
1184 else
1185 {
1186 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
1187 s.Printf ("%s =", name_cstr);
1188 }
1189
Jim Ingham6035b672011-03-31 00:19:25 +00001190 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001191 {
1192 err_cstr = "error: out of scope";
1193 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001194 }
1195
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001196 const char *val_cstr = NULL;
1197
1198 if (err_cstr == NULL)
1199 {
Jim Ingham6035b672011-03-31 00:19:25 +00001200 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001201 err_cstr = valobj->GetError().AsCString();
1202 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001203
1204 if (err_cstr)
1205 {
Greg Clayton7c8a9662010-11-02 01:50:16 +00001206 s.Printf (" error: %s\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00001207 }
1208 else
1209 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001210 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001211 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001212 {
Jim Ingham6035b672011-03-31 00:19:25 +00001213 const char *sum_cstr = valobj->GetSummaryAsCString();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001214
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001215 if (val_cstr)
1216 s.Printf(" %s", val_cstr);
1217
1218 if (sum_cstr)
1219 s.Printf(" %s", sum_cstr);
1220
1221 if (use_objc)
1222 {
Jim Ingham6035b672011-03-31 00:19:25 +00001223 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001224 if (object_desc)
1225 s.Printf(" %s\n", object_desc);
1226 else
Sean Callanan672ad942010-10-23 00:18:49 +00001227 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001228 return;
1229 }
1230 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001231
1232 if (curr_depth < max_depth)
1233 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001234 // We will show children for all concrete types. We won't show
1235 // pointer contents unless a pointer depth has been specified.
1236 // We won't reference contents unless the reference is the
1237 // root object (depth of zero).
1238 bool print_children = true;
1239
1240 // Use a new temporary pointer depth in case we override the
1241 // current pointer depth below...
1242 uint32_t curr_ptr_depth = ptr_depth;
1243
1244 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
1245 if (is_ptr || is_ref)
1246 {
1247 // We have a pointer or reference whose value is an address.
1248 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00001249 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00001250 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
1251 print_children = false;
1252
1253 else if (is_ref && curr_depth == 0)
1254 {
1255 // If this is the root object (depth is zero) that we are showing
1256 // and it is a reference, and no pointer depth has been supplied
1257 // print out what it references. Don't do this at deeper depths
1258 // otherwise we can end up with infinite recursion...
1259 curr_ptr_depth = 1;
1260 }
1261
1262 if (curr_ptr_depth == 0)
1263 print_children = false;
1264 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001265
Greg Clayton73b472d2010-10-27 03:32:59 +00001266 if (print_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001267 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001268 const uint32_t num_children = valobj->GetNumChildren();
1269 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001270 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001271 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001272 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001273 if (print_valobj)
1274 s.EOL();
1275 }
1276 else
1277 {
1278 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00001279 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001280 s.IndentMore();
1281 }
1282
1283 for (uint32_t idx=0; idx<num_children; ++idx)
1284 {
1285 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
1286 if (child_sp.get())
1287 {
1288 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001289 child_sp.get(),
1290 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00001291 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001292 curr_depth + 1,
1293 max_depth,
1294 show_types,
1295 show_location,
1296 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00001297 use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001298 true,
1299 flat_output);
1300 }
1301 }
1302
1303 if (!flat_output)
1304 {
1305 s.IndentLess();
1306 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001307 }
1308 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001309 else if (has_children)
1310 {
1311 // Aggregate, no children...
1312 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00001313 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001314 }
1315 else
1316 {
1317 if (print_valobj)
1318 s.EOL();
1319 }
1320
Greg Clayton1d3afba2010-10-05 00:00:42 +00001321 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001322 else
1323 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00001324 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001325 }
1326 }
1327 else
1328 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001329 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001330 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001331 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001332 }
1333 }
1334 }
1335 }
1336}
1337
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001338
1339ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00001340ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001341{
1342 ValueObjectSP valobj_sp;
1343
Jim Ingham6035b672011-03-31 00:19:25 +00001344 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001345 {
Jim Ingham6035b672011-03-31 00:19:25 +00001346 ExecutionContextScope *exe_scope = GetExecutionContextScope();
1347 if (exe_scope)
1348 {
1349 ExecutionContext exe_ctx;
1350 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001351
Jim Ingham6035b672011-03-31 00:19:25 +00001352 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001353
Jim Ingham6035b672011-03-31 00:19:25 +00001354 DataExtractor data;
1355 data.SetByteOrder (m_data.GetByteOrder());
1356 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001357
Jim Ingham6035b672011-03-31 00:19:25 +00001358 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001359
Jim Ingham58b59f92011-04-22 23:53:53 +00001360 valobj_sp = ValueObjectConstResult::Create (exe_scope,
1361 ast,
1362 GetClangType(),
1363 name,
1364 data);
Jim Ingham6035b672011-03-31 00:19:25 +00001365 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001366 }
Jim Ingham6035b672011-03-31 00:19:25 +00001367
1368 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001369 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001370 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001371 }
1372 return valobj_sp;
1373}
1374
1375lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00001376ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001377{
Jim Ingham58b59f92011-04-22 23:53:53 +00001378 if (m_deref_valobj)
1379 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00001380
Greg Clayton54979cd2010-12-15 05:08:08 +00001381 const bool is_pointer_type = IsPointerType();
1382 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001383 {
1384 bool omit_empty_base_classes = true;
1385
1386 std::string child_name_str;
1387 uint32_t child_byte_size = 0;
1388 int32_t child_byte_offset = 0;
1389 uint32_t child_bitfield_bit_size = 0;
1390 uint32_t child_bitfield_bit_offset = 0;
1391 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00001392 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001393 const bool transparent_pointers = false;
1394 clang::ASTContext *clang_ast = GetClangAST();
1395 clang_type_t clang_type = GetClangType();
1396 clang_type_t child_clang_type;
1397 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast,
1398 GetName().GetCString(),
1399 clang_type,
1400 0,
1401 transparent_pointers,
1402 omit_empty_base_classes,
1403 child_name_str,
1404 child_byte_size,
1405 child_byte_offset,
1406 child_bitfield_bit_size,
1407 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00001408 child_is_base_class,
1409 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00001410 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001411 {
1412 ConstString child_name;
1413 if (!child_name_str.empty())
1414 child_name.SetCString (child_name_str.c_str());
1415
Jim Ingham58b59f92011-04-22 23:53:53 +00001416 m_deref_valobj = new ValueObjectChild (*this,
1417 clang_ast,
1418 child_clang_type,
1419 child_name,
1420 child_byte_size,
1421 child_byte_offset,
1422 child_bitfield_bit_size,
1423 child_bitfield_bit_offset,
1424 child_is_base_class,
1425 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001426 }
1427 }
Greg Clayton54979cd2010-12-15 05:08:08 +00001428
Jim Ingham58b59f92011-04-22 23:53:53 +00001429 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00001430 {
1431 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00001432 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00001433 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001434 else
1435 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001436 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001437 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001438
1439 if (is_pointer_type)
1440 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
1441 else
1442 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00001443 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001444 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001445}
1446
Jim Ingham78a685a2011-04-16 00:01:13 +00001447lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00001448ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001449{
Jim Ingham78a685a2011-04-16 00:01:13 +00001450 if (m_addr_of_valobj_sp)
1451 return m_addr_of_valobj_sp;
1452
Greg Claytone0d378b2011-03-24 21:19:54 +00001453 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001454 const bool scalar_is_load_address = false;
1455 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00001456 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001457 if (addr != LLDB_INVALID_ADDRESS)
1458 {
1459 switch (address_type)
1460 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001461 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001462 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00001463 {
1464 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001465 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001466 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
1467 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001468 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00001469
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001470 case eAddressTypeFile:
1471 case eAddressTypeLoad:
1472 case eAddressTypeHost:
1473 {
1474 clang::ASTContext *ast = GetClangAST();
1475 clang_type_t clang_type = GetClangType();
1476 if (ast && clang_type)
1477 {
1478 std::string name (1, '&');
1479 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00001480 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
1481 ast,
1482 ClangASTContext::CreatePointerType (ast, clang_type),
1483 ConstString (name.c_str()),
1484 addr,
1485 eAddressTypeInvalid,
1486 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001487 }
1488 }
1489 break;
1490 }
1491 }
Jim Ingham78a685a2011-04-16 00:01:13 +00001492 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001493}
1494
Jim Ingham6035b672011-03-31 00:19:25 +00001495ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00001496 m_thread_id (LLDB_INVALID_UID),
1497 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00001498{
1499}
1500
1501ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00001502 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00001503 m_first_update (true),
1504 m_thread_id (LLDB_INVALID_UID),
1505 m_stop_id (0)
1506
Jim Ingham6035b672011-03-31 00:19:25 +00001507{
1508 ExecutionContext exe_ctx;
1509 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
1510 // and if so we want to cache that not the original.
1511 if (exe_scope)
1512 exe_scope->CalculateExecutionContext(exe_ctx);
1513 if (exe_ctx.target != NULL)
1514 {
1515 m_target_sp = exe_ctx.target->GetSP();
1516
1517 if (exe_ctx.process == NULL)
1518 m_process_sp = exe_ctx.target->GetProcessSP();
1519 else
1520 m_process_sp = exe_ctx.process->GetSP();
1521
1522 if (m_process_sp != NULL)
1523 {
1524 m_stop_id = m_process_sp->GetStopID();
1525 Thread *thread = NULL;
1526
1527 if (exe_ctx.thread == NULL)
1528 {
1529 if (use_selected)
1530 {
1531 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
1532 if (thread)
1533 computed_exe_scope = thread;
1534 }
1535 }
1536 else
1537 thread = exe_ctx.thread;
1538
1539 if (thread != NULL)
1540 {
1541 m_thread_id = thread->GetIndexID();
1542 if (exe_ctx.frame == NULL)
1543 {
1544 if (use_selected)
1545 {
1546 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
1547 if (frame)
1548 {
1549 m_stack_id = frame->GetStackID();
1550 computed_exe_scope = frame;
1551 }
1552 }
1553 }
1554 else
1555 m_stack_id = exe_ctx.frame->GetStackID();
1556 }
1557 }
1558 }
1559 m_exe_scope = computed_exe_scope;
1560}
1561
1562ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
1563 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00001564 m_needs_update(true),
1565 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00001566 m_target_sp (rhs.m_target_sp),
1567 m_process_sp (rhs.m_process_sp),
1568 m_thread_id (rhs.m_thread_id),
1569 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00001570 m_stop_id (0)
1571{
1572}
1573
1574ValueObject::EvaluationPoint::~EvaluationPoint ()
1575{
1576}
1577
1578ExecutionContextScope *
1579ValueObject::EvaluationPoint::GetExecutionContextScope ()
1580{
1581 // We have to update before giving out the scope, or we could be handing out stale pointers.
1582 SyncWithProcessState();
1583
1584 return m_exe_scope;
1585}
1586
1587// This function checks the EvaluationPoint against the current process state. If the current
1588// state matches the evaluation point, or the evaluation point is already invalid, then we return
1589// false, meaning "no change". If the current state is different, we update our state, and return
1590// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
1591// future calls to NeedsUpdate will return true.
1592
1593bool
1594ValueObject::EvaluationPoint::SyncWithProcessState()
1595{
1596 // If we're already invalid, we don't need to do anything, and nothing has changed:
1597 if (m_stop_id == LLDB_INVALID_UID)
1598 {
1599 // Can't update with an invalid state.
1600 m_needs_update = false;
1601 return false;
1602 }
1603
1604 // If we don't have a process nothing can change.
1605 if (!m_process_sp)
1606 return false;
1607
1608 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00001609 uint32_t cur_stop_id = m_process_sp->GetStopID();
1610 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00001611 return false;
1612
Jim Ingham78a685a2011-04-16 00:01:13 +00001613 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
1614 // In either case, we aren't going to be able to sync with the process state.
1615 if (cur_stop_id == 0)
1616 return false;
1617
1618 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00001619 m_needs_update = true;
1620 m_exe_scope = m_process_sp.get();
1621
1622 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
1623 // doesn't, mark ourselves as invalid.
1624
1625 if (m_thread_id != LLDB_INVALID_THREAD_ID)
1626 {
1627 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
1628 if (our_thread == NULL)
1629 SetInvalid();
1630 else
1631 {
1632 m_exe_scope = our_thread;
1633
1634 if (m_stack_id.IsValid())
1635 {
1636 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
1637 if (our_frame == NULL)
1638 SetInvalid();
1639 else
1640 m_exe_scope = our_frame;
1641 }
1642 }
1643 }
1644 return true;
1645}
1646
1647bool
1648ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
1649{
1650 if (!IsValid())
1651 return false;
1652
1653 bool needs_update = false;
1654 m_exe_scope = NULL;
1655
1656 // The target has to be non-null, and the
1657 Target *target = exe_scope->CalculateTarget();
1658 if (target != NULL)
1659 {
1660 Target *old_target = m_target_sp.get();
1661 assert (target == old_target);
1662 Process *process = exe_scope->CalculateProcess();
1663 if (process != NULL)
1664 {
1665 // FOR NOW - assume you can't update variable objects across process boundaries.
1666 Process *old_process = m_process_sp.get();
1667 assert (process == old_process);
1668
1669 lldb::user_id_t stop_id = process->GetStopID();
1670 if (stop_id != m_stop_id)
1671 {
1672 needs_update = true;
1673 m_stop_id = stop_id;
1674 }
1675 // See if we're switching the thread or stack context. If no thread is given, this is
1676 // being evaluated in a global context.
1677 Thread *thread = exe_scope->CalculateThread();
1678 if (thread != NULL)
1679 {
1680 lldb::user_id_t new_thread_index = thread->GetIndexID();
1681 if (new_thread_index != m_thread_id)
1682 {
1683 needs_update = true;
1684 m_thread_id = new_thread_index;
1685 m_stack_id.Clear();
1686 }
1687
1688 StackFrame *new_frame = exe_scope->CalculateStackFrame();
1689 if (new_frame != NULL)
1690 {
1691 if (new_frame->GetStackID() != m_stack_id)
1692 {
1693 needs_update = true;
1694 m_stack_id = new_frame->GetStackID();
1695 }
1696 }
1697 else
1698 {
1699 m_stack_id.Clear();
1700 needs_update = true;
1701 }
1702 }
1703 else
1704 {
1705 // If this had been given a thread, and now there is none, we should update.
1706 // Otherwise we don't have to do anything.
1707 if (m_thread_id != LLDB_INVALID_UID)
1708 {
1709 m_thread_id = LLDB_INVALID_UID;
1710 m_stack_id.Clear();
1711 needs_update = true;
1712 }
1713 }
1714 }
1715 else
1716 {
1717 // If there is no process, then we don't need to update anything.
1718 // But if we're switching from having a process to not, we should try to update.
1719 if (m_process_sp.get() != NULL)
1720 {
1721 needs_update = true;
1722 m_process_sp.reset();
1723 m_thread_id = LLDB_INVALID_UID;
1724 m_stack_id.Clear();
1725 }
1726 }
1727 }
1728 else
1729 {
1730 // If there's no target, nothing can change so we don't need to update anything.
1731 // But if we're switching from having a target to not, we should try to update.
1732 if (m_target_sp.get() != NULL)
1733 {
1734 needs_update = true;
1735 m_target_sp.reset();
1736 m_process_sp.reset();
1737 m_thread_id = LLDB_INVALID_UID;
1738 m_stack_id.Clear();
1739 }
1740 }
1741 if (!m_needs_update)
1742 m_needs_update = needs_update;
1743
1744 return needs_update;
1745}