blob: d95806cf192924a267b0231c824c50eabe4e5c78 [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 (),
Greg Clayton288bdf92010-09-02 02:59:18 +000062 m_children (),
63 m_synthetic_children (),
Greg Clayton32c40852010-10-06 03:09:11 +000064 m_dynamic_value_sp (),
65 m_format (eFormatDefault),
Greg Clayton288bdf92010-09-02 02:59:18 +000066 m_value_is_valid (false),
67 m_value_did_change (false),
68 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000069 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000070 m_pointers_point_to_load_addrs (false),
Stephen Wilson71c21d12011-04-11 19:41:40 +000071 m_is_deref_of_parent (false)
Jim Ingham6035b672011-03-31 00:19:25 +000072{
73}
74
75//----------------------------------------------------------------------
76// ValueObject constructor
77//----------------------------------------------------------------------
78ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
79 UserID (++g_value_obj_uid), // Unique identifier for every value object
80 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +000081 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +000082 m_name (),
83 m_data (),
84 m_value (),
85 m_error (),
86 m_value_str (),
87 m_old_value_str (),
88 m_location_str (),
89 m_summary_str (),
90 m_object_desc_str (),
91 m_children (),
92 m_synthetic_children (),
93 m_dynamic_value_sp (),
94 m_format (eFormatDefault),
95 m_value_is_valid (false),
96 m_value_did_change (false),
97 m_children_count_valid (false),
98 m_old_value_valid (false),
99 m_pointers_point_to_load_addrs (false),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000100 m_is_deref_of_parent (false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101{
102}
103
104//----------------------------------------------------------------------
105// Destructor
106//----------------------------------------------------------------------
107ValueObject::~ValueObject ()
108{
109}
110
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111bool
Jim Ingham6035b672011-03-31 00:19:25 +0000112ValueObject::UpdateValueIfNeeded ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113{
Greg Claytonb71f3842010-10-05 03:13:51 +0000114 // If this is a constant value, then our success is predicated on whether
115 // we have an error or not
116 if (GetIsConstant())
117 return m_error.Success();
118
Jim Ingham6035b672011-03-31 00:19:25 +0000119 bool first_update = m_update_point.IsFirstEvaluation();
120
121 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000122 {
Jim Ingham6035b672011-03-31 00:19:25 +0000123 m_update_point.SetUpdated();
124
125 // Save the old value using swap to avoid a string copy which
126 // also will clear our m_value_str
127 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128 {
Jim Ingham6035b672011-03-31 00:19:25 +0000129 m_old_value_valid = false;
130 }
131 else
132 {
133 m_old_value_valid = true;
134 m_old_value_str.swap (m_value_str);
135 m_value_str.clear();
136 }
137 m_location_str.clear();
138 m_summary_str.clear();
139 m_object_desc_str.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140
Jim Ingham6035b672011-03-31 00:19:25 +0000141 const bool value_was_valid = GetValueIsValid();
142 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000143
Jim Ingham6035b672011-03-31 00:19:25 +0000144 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000145
Jim Ingham6035b672011-03-31 00:19:25 +0000146 // Call the pure virtual function to update the value
147 bool success = UpdateValue ();
148
149 SetValueIsValid (success);
150
151 if (first_update)
152 SetValueDidChange (false);
153 else if (!m_value_did_change && success == false)
154 {
155 // The value wasn't gotten successfully, so we mark this
156 // as changed if the value used to be valid and now isn't
157 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158 }
159 }
160 return m_error.Success();
161}
162
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163DataExtractor &
164ValueObject::GetDataExtractor ()
165{
Jim Ingham78a685a2011-04-16 00:01:13 +0000166 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 return m_data;
168}
169
170const Error &
171ValueObject::GetError() const
172{
173 return m_error;
174}
175
176const ConstString &
177ValueObject::GetName() const
178{
179 return m_name;
180}
181
182const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000183ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184{
Jim Ingham6035b672011-03-31 00:19:25 +0000185 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186 {
187 if (m_location_str.empty())
188 {
189 StreamString sstr;
190
191 switch (m_value.GetValueType())
192 {
193 default:
194 break;
195
196 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000197 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000198 {
199 RegisterInfo *reg_info = m_value.GetRegisterInfo();
200 if (reg_info)
201 {
202 if (reg_info->name)
203 m_location_str = reg_info->name;
204 else if (reg_info->alt_name)
205 m_location_str = reg_info->alt_name;
206 break;
207 }
208 }
209 m_location_str = "scalar";
210 break;
211
212 case Value::eValueTypeLoadAddress:
213 case Value::eValueTypeFileAddress:
214 case Value::eValueTypeHostAddress:
215 {
216 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
217 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
218 m_location_str.swap(sstr.GetString());
219 }
220 break;
221 }
222 }
223 }
224 return m_location_str.c_str();
225}
226
227Value &
228ValueObject::GetValue()
229{
230 return m_value;
231}
232
233const Value &
234ValueObject::GetValue() const
235{
236 return m_value;
237}
238
239bool
Jim Ingham6035b672011-03-31 00:19:25 +0000240ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000241{
242 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000243 ExecutionContextScope *exe_scope = GetExecutionContextScope();
244 if (exe_scope)
245 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000246 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
247 return scalar.IsValid();
248}
249
250bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000251ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252{
Greg Clayton288bdf92010-09-02 02:59:18 +0000253 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000254}
255
256
257void
258ValueObject::SetValueIsValid (bool b)
259{
Greg Clayton288bdf92010-09-02 02:59:18 +0000260 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261}
262
263bool
Jim Ingham6035b672011-03-31 00:19:25 +0000264ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265{
Jim Ingham6035b672011-03-31 00:19:25 +0000266 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000267 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268}
269
270void
271ValueObject::SetValueDidChange (bool value_changed)
272{
Greg Clayton288bdf92010-09-02 02:59:18 +0000273 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000274}
275
276ValueObjectSP
277ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
278{
279 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000280 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000282 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000284 // Check if we have already made the child value object?
285 if (can_create && m_children[idx].get() == NULL)
286 {
287 // No we haven't created the child at this index, so lets have our
288 // subclass do it and cache the result for quick future access.
289 m_children[idx] = CreateChildAtIndex (idx, false, 0);
290 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291
Jim Ingham78a685a2011-04-16 00:01:13 +0000292 child_sp = m_children[idx];
293 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294 }
295 return child_sp;
296}
297
298uint32_t
299ValueObject::GetIndexOfChildWithName (const ConstString &name)
300{
301 bool omit_empty_base_classes = true;
302 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000303 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000304 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000305 omit_empty_base_classes);
306}
307
308ValueObjectSP
309ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
310{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000311 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312 // classes (which really aren't part of the expression path), so we
313 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000315
316 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000318 std::vector<uint32_t> child_indexes;
319 clang::ASTContext *clang_ast = GetClangAST();
320 void *clang_type = GetClangType();
321 bool omit_empty_base_classes = true;
322 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
323 clang_type,
324 name.GetCString(),
325 omit_empty_base_classes,
326 child_indexes);
327 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000329 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
330 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331
Jim Ingham78a685a2011-04-16 00:01:13 +0000332 child_sp = GetChildAtIndex(*pos, can_create);
333 for (++pos; pos != end; ++pos)
334 {
335 if (child_sp)
336 {
337 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
338 child_sp = new_child_sp;
339 }
340 else
341 {
342 child_sp.reset();
343 }
344
345 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346 }
347 }
348 return child_sp;
349}
350
351
352uint32_t
353ValueObject::GetNumChildren ()
354{
Greg Clayton288bdf92010-09-02 02:59:18 +0000355 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356 {
357 SetNumChildren (CalculateNumChildren());
358 }
359 return m_children.size();
360}
361void
362ValueObject::SetNumChildren (uint32_t num_children)
363{
Greg Clayton288bdf92010-09-02 02:59:18 +0000364 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000365 m_children.resize(num_children);
366}
367
368void
369ValueObject::SetName (const char *name)
370{
371 m_name.SetCString(name);
372}
373
374void
375ValueObject::SetName (const ConstString &name)
376{
377 m_name = name;
378}
379
380ValueObjectSP
381ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
382{
383 ValueObjectSP valobj_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000384
385 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386 {
Jim Ingham78a685a2011-04-16 00:01:13 +0000387 bool omit_empty_base_classes = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388
Jim Ingham78a685a2011-04-16 00:01:13 +0000389 std::string child_name_str;
390 uint32_t child_byte_size = 0;
391 int32_t child_byte_offset = 0;
392 uint32_t child_bitfield_bit_size = 0;
393 uint32_t child_bitfield_bit_offset = 0;
394 bool child_is_base_class = false;
395 bool child_is_deref_of_parent = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396
Jim Ingham78a685a2011-04-16 00:01:13 +0000397 const bool transparent_pointers = synthetic_array_member == false;
398 clang::ASTContext *clang_ast = GetClangAST();
399 clang_type_t clang_type = GetClangType();
400 clang_type_t child_clang_type;
401 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast,
402 GetName().GetCString(),
403 clang_type,
404 idx,
405 transparent_pointers,
406 omit_empty_base_classes,
407 child_name_str,
408 child_byte_size,
409 child_byte_offset,
410 child_bitfield_bit_size,
411 child_bitfield_bit_offset,
412 child_is_base_class,
413 child_is_deref_of_parent);
414 if (child_clang_type && child_byte_size)
415 {
416 if (synthetic_index)
417 child_byte_offset += child_byte_size * synthetic_index;
418
419 ConstString child_name;
420 if (!child_name_str.empty())
421 child_name.SetCString (child_name_str.c_str());
422
423 valobj_sp.reset (new ValueObjectChild (*this,
424 clang_ast,
425 child_clang_type,
426 child_name,
427 child_byte_size,
428 child_byte_offset,
429 child_bitfield_bit_size,
430 child_bitfield_bit_offset,
431 child_is_base_class,
432 child_is_deref_of_parent));
433 if (m_pointers_point_to_load_addrs)
434 valobj_sp->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
435 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000436 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000437
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438 return valobj_sp;
439}
440
441const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000442ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443{
Jim Ingham6035b672011-03-31 00:19:25 +0000444 if (UpdateValueIfNeeded ())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445 {
446 if (m_summary_str.empty())
447 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000448 clang_type_t clang_type = GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000449
450 // See if this is a pointer to a C string?
Greg Clayton737b9322010-09-13 03:32:57 +0000451 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000452 {
Greg Clayton737b9322010-09-13 03:32:57 +0000453 StreamString sstr;
Greg Clayton73b472d2010-10-27 03:32:59 +0000454 clang_type_t elem_or_pointee_clang_type;
455 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000456 GetClangAST(),
457 &elem_or_pointee_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +0000458
Jim Ingham6035b672011-03-31 00:19:25 +0000459 ExecutionContextScope *exe_scope = GetExecutionContextScope();
460 if (exe_scope)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461 {
Jim Ingham6035b672011-03-31 00:19:25 +0000462 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
463 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464 {
Jim Ingham6035b672011-03-31 00:19:25 +0000465 Process *process = exe_scope->CalculateProcess();
466 if (process != NULL)
467 {
468 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
469 AddressType cstr_address_type = eAddressTypeInvalid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000470
Jim Ingham6035b672011-03-31 00:19:25 +0000471 size_t cstr_len = 0;
472 if (type_flags.Test (ClangASTContext::eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000473 {
Jim Ingham6035b672011-03-31 00:19:25 +0000474 // We have an array
475 cstr_len = ClangASTContext::GetArraySize (clang_type);
476 cstr_address = GetAddressOf (cstr_address_type, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000477 }
Greg Clayton737b9322010-09-13 03:32:57 +0000478 else
479 {
Jim Ingham6035b672011-03-31 00:19:25 +0000480 // We have a pointer
481 cstr_address = GetPointerValue (cstr_address_type, true);
Greg Clayton737b9322010-09-13 03:32:57 +0000482 }
Jim Ingham6035b672011-03-31 00:19:25 +0000483 if (cstr_address != LLDB_INVALID_ADDRESS)
Greg Clayton737b9322010-09-13 03:32:57 +0000484 {
Jim Ingham6035b672011-03-31 00:19:25 +0000485 DataExtractor data;
486 size_t bytes_read = 0;
487 std::vector<char> data_buffer;
488 Error error;
489 if (cstr_len > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000490 {
Jim Ingham6035b672011-03-31 00:19:25 +0000491 data_buffer.resize(cstr_len);
492 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
493 bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error);
494 if (bytes_read > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000495 {
Jim Ingham6035b672011-03-31 00:19:25 +0000496 sstr << '"';
497 data.Dump (&sstr,
498 0, // Start offset in "data"
499 eFormatChar, // Print as characters
500 1, // Size of item (1 byte for a char!)
501 bytes_read, // How many bytes to print?
502 UINT32_MAX, // num per line
503 LLDB_INVALID_ADDRESS,// base address
504 0, // bitfield bit size
505 0); // bitfield bit offset
506 sstr << '"';
Greg Clayton737b9322010-09-13 03:32:57 +0000507 }
508 }
Jim Ingham6035b672011-03-31 00:19:25 +0000509 else
510 {
511 const size_t k_max_buf_size = 256;
512 data_buffer.resize (k_max_buf_size + 1);
513 // NULL terminate in case we don't get the entire C string
514 data_buffer.back() = '\0';
Greg Clayton737b9322010-09-13 03:32:57 +0000515
Jim Ingham6035b672011-03-31 00:19:25 +0000516 sstr << '"';
517
518 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
519 while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0)
520 {
521 size_t len = strlen(&data_buffer.front());
522 if (len == 0)
523 break;
524 if (len > bytes_read)
525 len = bytes_read;
526
527 data.Dump (&sstr,
528 0, // Start offset in "data"
529 eFormatChar, // Print as characters
530 1, // Size of item (1 byte for a char!)
531 len, // How many bytes to print?
532 UINT32_MAX, // num per line
533 LLDB_INVALID_ADDRESS,// base address
534 0, // bitfield bit size
535 0); // bitfield bit offset
536
537 if (len < k_max_buf_size)
538 break;
539 cstr_address += k_max_buf_size;
540 }
541 sstr << '"';
542 }
543 }
Greg Clayton737b9322010-09-13 03:32:57 +0000544 }
Jim Ingham6035b672011-03-31 00:19:25 +0000545
546 if (sstr.GetSize() > 0)
547 m_summary_str.assign (sstr.GetData(), sstr.GetSize());
Greg Clayton737b9322010-09-13 03:32:57 +0000548 }
Jim Ingham6035b672011-03-31 00:19:25 +0000549 else if (ClangASTContext::IsFunctionPointerType (clang_type))
Greg Clayton737b9322010-09-13 03:32:57 +0000550 {
Jim Ingham6035b672011-03-31 00:19:25 +0000551 AddressType func_ptr_address_type = eAddressTypeInvalid;
552 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
553
554 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
555 {
556 switch (func_ptr_address_type)
557 {
558 case eAddressTypeInvalid:
559 case eAddressTypeFile:
560 break;
561
562 case eAddressTypeLoad:
563 {
564 Address so_addr;
565 Target *target = exe_scope->CalculateTarget();
566 if (target && target->GetSectionLoadList().IsEmpty() == false)
567 {
568 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
569 {
570 so_addr.Dump (&sstr,
571 exe_scope,
572 Address::DumpStyleResolvedDescription,
573 Address::DumpStyleSectionNameOffset);
574 }
575 }
576 }
577 break;
578
579 case eAddressTypeHost:
580 break;
581 }
582 }
583 if (sstr.GetSize() > 0)
584 {
585 m_summary_str.assign (1, '(');
586 m_summary_str.append (sstr.GetData(), sstr.GetSize());
587 m_summary_str.append (1, ')');
588 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000589 }
590 }
591 }
592 }
593 }
594 if (m_summary_str.empty())
595 return NULL;
596 return m_summary_str.c_str();
597}
598
Jim Ingham53c47f12010-09-10 23:12:17 +0000599const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000600ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000601{
602 if (!m_object_desc_str.empty())
603 return m_object_desc_str.c_str();
604
Jim Ingham6035b672011-03-31 00:19:25 +0000605 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000606 return NULL;
Jim Ingham6035b672011-03-31 00:19:25 +0000607
608 ExecutionContextScope *exe_scope = GetExecutionContextScope();
609 if (exe_scope == NULL)
610 return NULL;
611
Jim Ingham53c47f12010-09-10 23:12:17 +0000612 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000613 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000614 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000615
Jim Ingham53c47f12010-09-10 23:12:17 +0000616 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000617
618 lldb::LanguageType language = GetObjectRuntimeLanguage();
619 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
620
Jim Inghama2cf2632010-12-23 02:29:54 +0000621 if (runtime == NULL)
622 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000623 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000624 clang_type_t opaque_qual_type = GetClangType();
625 if (opaque_qual_type != NULL)
626 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000627 bool is_signed;
628 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
629 || ClangASTContext::IsPointerType (opaque_qual_type))
630 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000631 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000632 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000633 }
634 }
635
Jim Ingham8d543de2011-03-31 23:01:21 +0000636 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000637 {
638 m_object_desc_str.append (s.GetData());
639 }
Sean Callanan672ad942010-10-23 00:18:49 +0000640
641 if (m_object_desc_str.empty())
642 return NULL;
643 else
644 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000645}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000646
647const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000648ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649{
650 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000651 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652 {
Jim Ingham6035b672011-03-31 00:19:25 +0000653 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000654 {
655 if (m_value_str.empty())
656 {
657 const Value::ContextType context_type = m_value.GetContextType();
658
659 switch (context_type)
660 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000661 case Value::eContextTypeClangType:
662 case Value::eContextTypeLLDBType:
663 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000664 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000665 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666 if (clang_type)
667 {
668 StreamString sstr;
Greg Clayton32c40852010-10-06 03:09:11 +0000669 if (m_format == eFormatDefault)
670 m_format = ClangASTType::GetFormat(clang_type);
671
672 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
673 clang_type, // The clang type to display
674 &sstr,
675 m_format, // Format to display this type with
676 m_data, // Data to extract from
677 0, // Byte offset into "m_data"
678 GetByteSize(), // Byte size of item in "m_data"
679 GetBitfieldBitSize(), // Bitfield bit size
680 GetBitfieldBitOffset())) // Bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681 m_value_str.swap(sstr.GetString());
682 else
683 m_value_str.clear();
684 }
685 }
686 break;
687
Greg Clayton526e5af2010-11-13 03:52:47 +0000688 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000689 {
690 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
691 if (reg_info)
692 {
693 StreamString reg_sstr;
694 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
695 m_value_str.swap(reg_sstr.GetString());
696 }
697 }
698 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000699
700 default:
701 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000702 }
703 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000704
705 if (!m_value_did_change && m_old_value_valid)
706 {
707 // The value was gotten successfully, so we consider the
708 // value as changed if the value string differs
709 SetValueDidChange (m_old_value_str != m_value_str);
710 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711 }
712 }
713 if (m_value_str.empty())
714 return NULL;
715 return m_value_str.c_str();
716}
717
Greg Clayton737b9322010-09-13 03:32:57 +0000718addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000719ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +0000720{
Jim Ingham78a685a2011-04-16 00:01:13 +0000721 if (!UpdateValueIfNeeded())
722 return LLDB_INVALID_ADDRESS;
723
Greg Clayton73b472d2010-10-27 03:32:59 +0000724 switch (m_value.GetValueType())
725 {
726 case Value::eValueTypeScalar:
727 if (scalar_is_load_address)
728 {
729 address_type = eAddressTypeLoad;
730 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
731 }
732 break;
733
734 case Value::eValueTypeLoadAddress:
735 case Value::eValueTypeFileAddress:
736 case Value::eValueTypeHostAddress:
737 {
738 address_type = m_value.GetValueAddressType ();
739 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
740 }
741 break;
742 }
743 address_type = eAddressTypeInvalid;
744 return LLDB_INVALID_ADDRESS;
745}
746
747addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000748ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +0000749{
750 lldb::addr_t address = LLDB_INVALID_ADDRESS;
751 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +0000752
753 if (!UpdateValueIfNeeded())
754 return address;
755
Greg Clayton73b472d2010-10-27 03:32:59 +0000756 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +0000757 {
758 case Value::eValueTypeScalar:
759 if (scalar_is_load_address)
760 {
761 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
762 address_type = eAddressTypeLoad;
763 }
764 break;
765
766 case Value::eValueTypeLoadAddress:
767 case Value::eValueTypeFileAddress:
768 case Value::eValueTypeHostAddress:
769 {
770 uint32_t data_offset = 0;
771 address = m_data.GetPointer(&data_offset);
772 address_type = m_value.GetValueAddressType();
773 if (address_type == eAddressTypeInvalid)
774 address_type = eAddressTypeLoad;
775 }
776 break;
777 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000778
779 if (m_pointers_point_to_load_addrs)
780 address_type = eAddressTypeLoad;
781
Greg Clayton737b9322010-09-13 03:32:57 +0000782 return address;
783}
784
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785bool
Jim Ingham6035b672011-03-31 00:19:25 +0000786ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000787{
788 // Make sure our value is up to date first so that our location and location
789 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +0000790 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000791 return false;
792
793 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +0000794 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000795
796 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +0000797 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000798 switch (encoding)
799 {
800 case eEncodingInvalid:
801 return false;
802
803 case eEncodingUint:
804 if (byte_size > sizeof(unsigned long long))
805 {
806 return false;
807 }
808 else
809 {
810 unsigned long long ull_val = strtoull(value_str, &end, 0);
811 if (end && *end != '\0')
812 return false;
813 m_value = ull_val;
814 // Limit the bytes in our m_data appropriately.
815 m_value.GetScalar().GetData (m_data, byte_size);
816 }
817 break;
818
819 case eEncodingSint:
820 if (byte_size > sizeof(long long))
821 {
822 return false;
823 }
824 else
825 {
826 long long sll_val = strtoll(value_str, &end, 0);
827 if (end && *end != '\0')
828 return false;
829 m_value = sll_val;
830 // Limit the bytes in our m_data appropriately.
831 m_value.GetScalar().GetData (m_data, byte_size);
832 }
833 break;
834
835 case eEncodingIEEE754:
836 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +0000838 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000839 if (dst != NULL)
840 {
841 // We are decoding a float into host byte order below, so make
842 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +0000843 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000844 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
845 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000846 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000847 value_str,
848 dst,
849 byte_size);
850
851 if (converted_byte_size == byte_size)
852 {
853 }
854 }
855 }
856 break;
857
858 case eEncodingVector:
859 return false;
860
861 default:
862 return false;
863 }
864
865 // If we have made it here the value is in m_data and we should write it
866 // out to the target
867 return Write ();
868}
869
870bool
871ValueObject::Write ()
872{
873 // Clear the update ID so the next time we try and read the value
874 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +0000875 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000876
877 // TODO: when Value has a method to write a value back, call it from here.
878 return false;
879
880}
881
Jim Ingham5a369122010-09-28 01:25:32 +0000882lldb::LanguageType
883ValueObject::GetObjectRuntimeLanguage ()
884{
Greg Clayton73b472d2010-10-27 03:32:59 +0000885 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +0000886 if (opaque_qual_type == NULL)
887 return lldb::eLanguageTypeC;
888
889 // If the type is a reference, then resolve it to what it refers to first:
890 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
891 if (qual_type->isAnyPointerType())
892 {
893 if (qual_type->isObjCObjectPointerType())
894 return lldb::eLanguageTypeObjC;
895
896 clang::QualType pointee_type (qual_type->getPointeeType());
897 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
898 return lldb::eLanguageTypeC_plus_plus;
899 if (pointee_type->isObjCObjectOrInterfaceType())
900 return lldb::eLanguageTypeObjC;
901 if (pointee_type->isObjCClassType())
902 return lldb::eLanguageTypeObjC;
903 }
904 else
905 {
906 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
907 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +0000908 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +0000909 return lldb::eLanguageTypeC_plus_plus;
910 }
911
912 return lldb::eLanguageTypeC;
913}
914
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000915void
916ValueObject::AddSyntheticChild (const ConstString &key, ValueObjectSP& valobj_sp)
917{
918 m_synthetic_children[key] = valobj_sp;
919}
920
921ValueObjectSP
922ValueObject::GetSyntheticChild (const ConstString &key) const
923{
924 ValueObjectSP synthetic_child_sp;
925 std::map<ConstString, ValueObjectSP>::const_iterator pos = m_synthetic_children.find (key);
926 if (pos != m_synthetic_children.end())
927 synthetic_child_sp = pos->second;
928 return synthetic_child_sp;
929}
930
931bool
932ValueObject::IsPointerType ()
933{
Greg Clayton1be10fc2010-09-29 01:12:09 +0000934 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000935}
936
Jim Inghamb7603bb2011-03-18 00:05:18 +0000937bool
938ValueObject::IsIntegerType (bool &is_signed)
939{
940 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
941}
Greg Clayton73b472d2010-10-27 03:32:59 +0000942
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000943bool
944ValueObject::IsPointerOrReferenceType ()
945{
Greg Clayton1be10fc2010-09-29 01:12:09 +0000946 return ClangASTContext::IsPointerOrReferenceType(GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000947}
948
949ValueObjectSP
950ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
951{
952 ValueObjectSP synthetic_child_sp;
953 if (IsPointerType ())
954 {
955 char index_str[64];
956 snprintf(index_str, sizeof(index_str), "[%i]", index);
957 ConstString index_const_str(index_str);
958 // Check if we have already created a synthetic array member in this
959 // valid object. If we have we will re-use it.
960 synthetic_child_sp = GetSyntheticChild (index_const_str);
961 if (!synthetic_child_sp)
962 {
963 // We haven't made a synthetic array member for INDEX yet, so
964 // lets make one and cache it for any future reference.
965 synthetic_child_sp = CreateChildAtIndex(0, true, index);
966
967 // Cache the value if we got one back...
968 if (synthetic_child_sp)
969 AddSyntheticChild(index_const_str, synthetic_child_sp);
970 }
971 }
972 return synthetic_child_sp;
973}
Jim Ingham22777012010-09-23 02:01:19 +0000974
Jim Ingham78a685a2011-04-16 00:01:13 +0000975void
976ValueObject::CalculateDynamicValue ()
Jim Ingham22777012010-09-23 02:01:19 +0000977{
Jim Ingham78a685a2011-04-16 00:01:13 +0000978 if (!m_dynamic_value_sp && !IsDynamic())
979 {
980 Process *process = m_update_point.GetProcess();
981 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +0000982
Jim Ingham78a685a2011-04-16 00:01:13 +0000983
984 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
985 // hard code this everywhere.
986 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
987 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
988 {
989 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
990 if (runtime)
991 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
992 }
993 else
994 {
995 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
996 if (cpp_runtime)
997 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
998
999 if (!worth_having_dynamic_value)
1000 {
1001 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1002 if (objc_runtime)
1003 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1004 }
1005 }
1006
1007 if (worth_having_dynamic_value)
1008 m_dynamic_value_sp.reset (new ValueObjectDynamicValue (*this));
1009 }
1010}
1011
1012lldb::ValueObjectSP
1013ValueObject::GetDynamicValue (bool can_create)
1014{
1015 if (!IsDynamic() && m_dynamic_value_sp == NULL && can_create)
1016 {
1017 CalculateDynamicValue();
1018 }
1019 return m_dynamic_value_sp;
1020}
1021
1022lldb::ValueObjectSP
1023ValueObject::GetDynamicValue (bool can_create, lldb::ValueObjectSP &owning_valobj_sp)
1024{
1025 if (!IsDynamic() && m_dynamic_value_sp == NULL && can_create)
1026 {
1027 CalculateDynamicValue();
1028 if (m_dynamic_value_sp)
1029 {
1030 ValueObjectDynamicValue *as_dynamic_value = static_cast<ValueObjectDynamicValue *>(m_dynamic_value_sp.get());
1031 as_dynamic_value->SetOwningSP (owning_valobj_sp);
1032 }
1033 }
1034 return m_dynamic_value_sp;
Jim Ingham22777012010-09-23 02:01:19 +00001035}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001036
Greg Claytone221f822011-01-21 01:59:00 +00001037bool
1038ValueObject::GetBaseClassPath (Stream &s)
1039{
1040 if (IsBaseClass())
1041 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001042 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001043 clang_type_t clang_type = GetClangType();
1044 std::string cxx_class_name;
1045 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1046 if (this_had_base_class)
1047 {
1048 if (parent_had_base_class)
1049 s.PutCString("::");
1050 s.PutCString(cxx_class_name.c_str());
1051 }
1052 return parent_had_base_class || this_had_base_class;
1053 }
1054 return false;
1055}
1056
1057
1058ValueObject *
1059ValueObject::GetNonBaseClassParent()
1060{
Jim Ingham78a685a2011-04-16 00:01:13 +00001061 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001062 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001063 if (GetParent()->IsBaseClass())
1064 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001065 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001066 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001067 }
1068 return NULL;
1069}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001070
1071void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001072ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001073{
Greg Claytone221f822011-01-21 01:59:00 +00001074 const bool is_deref_of_parent = IsDereferenceOfParent ();
1075
1076 if (is_deref_of_parent)
1077 s.PutCString("*(");
1078
Jim Ingham78a685a2011-04-16 00:01:13 +00001079 if (GetParent())
1080 GetParent()->GetExpressionPath (s, qualify_cxx_base_classes);
Greg Claytone221f822011-01-21 01:59:00 +00001081
1082 if (!IsBaseClass())
1083 {
1084 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001085 {
Greg Claytone221f822011-01-21 01:59:00 +00001086 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1087 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001088 {
Greg Claytone221f822011-01-21 01:59:00 +00001089 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1090 if (non_base_class_parent_clang_type)
1091 {
1092 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1093
1094 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1095 {
1096 s.PutCString("->");
1097 }
1098 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1099 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1100 {
1101 s.PutChar('.');
1102 }
1103 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001104 }
Greg Claytone221f822011-01-21 01:59:00 +00001105
1106 const char *name = GetName().GetCString();
1107 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001108 {
Greg Claytone221f822011-01-21 01:59:00 +00001109 if (qualify_cxx_base_classes)
1110 {
1111 if (GetBaseClassPath (s))
1112 s.PutCString("::");
1113 }
1114 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001115 }
1116 }
1117 }
1118
Greg Claytone221f822011-01-21 01:59:00 +00001119 if (is_deref_of_parent)
1120 s.PutChar(')');
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001121}
1122
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001123void
Greg Clayton1d3afba2010-10-05 00:00:42 +00001124ValueObject::DumpValueObject
1125(
1126 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00001127 ValueObject *valobj,
1128 const char *root_valobj_name,
1129 uint32_t ptr_depth,
1130 uint32_t curr_depth,
1131 uint32_t max_depth,
1132 bool show_types,
1133 bool show_location,
1134 bool use_objc,
Jim Ingham78a685a2011-04-16 00:01:13 +00001135 bool use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001136 bool scope_already_checked,
1137 bool flat_output
Greg Clayton1d3afba2010-10-05 00:00:42 +00001138)
1139{
Jim Ingham6035b672011-03-31 00:19:25 +00001140 if (valobj && valobj->UpdateValueIfNeeded ())
Greg Clayton1d3afba2010-10-05 00:00:42 +00001141 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001142 if (use_dynamic)
1143 {
1144 ValueObject *dynamic_value = valobj->GetDynamicValue(true).get();
1145 if (dynamic_value)
1146 valobj = dynamic_value;
1147 }
1148
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001149 clang_type_t clang_type = valobj->GetClangType();
1150
Greg Clayton73b472d2010-10-27 03:32:59 +00001151 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001152 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00001153 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
1154 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001155
1156 const bool print_valobj = flat_output == false || has_value;
1157
1158 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001159 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001160 if (show_location)
1161 {
Jim Ingham6035b672011-03-31 00:19:25 +00001162 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001163 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001164
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001165 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001166
Greg Clayton7c8a9662010-11-02 01:50:16 +00001167 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00001168 if (show_types || (curr_depth == 0 && !flat_output))
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001169 s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
Greg Clayton1d3afba2010-10-05 00:00:42 +00001170
Greg Clayton1d3afba2010-10-05 00:00:42 +00001171
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001172 if (flat_output)
1173 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001174 // If we are showing types, also qualify the C++ base classes
1175 const bool qualify_cxx_base_classes = show_types;
1176 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001177 s.PutCString(" =");
1178 }
1179 else
1180 {
1181 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
1182 s.Printf ("%s =", name_cstr);
1183 }
1184
Jim Ingham6035b672011-03-31 00:19:25 +00001185 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001186 {
1187 err_cstr = "error: out of scope";
1188 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001189 }
1190
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001191 const char *val_cstr = NULL;
1192
1193 if (err_cstr == NULL)
1194 {
Jim Ingham6035b672011-03-31 00:19:25 +00001195 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001196 err_cstr = valobj->GetError().AsCString();
1197 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001198
1199 if (err_cstr)
1200 {
Greg Clayton7c8a9662010-11-02 01:50:16 +00001201 s.Printf (" error: %s\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00001202 }
1203 else
1204 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001205 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001206 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001207 {
Jim Ingham6035b672011-03-31 00:19:25 +00001208 const char *sum_cstr = valobj->GetSummaryAsCString();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001209
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001210 if (val_cstr)
1211 s.Printf(" %s", val_cstr);
1212
1213 if (sum_cstr)
1214 s.Printf(" %s", sum_cstr);
1215
1216 if (use_objc)
1217 {
Jim Ingham6035b672011-03-31 00:19:25 +00001218 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001219 if (object_desc)
1220 s.Printf(" %s\n", object_desc);
1221 else
Sean Callanan672ad942010-10-23 00:18:49 +00001222 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001223 return;
1224 }
1225 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001226
1227 if (curr_depth < max_depth)
1228 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001229 // We will show children for all concrete types. We won't show
1230 // pointer contents unless a pointer depth has been specified.
1231 // We won't reference contents unless the reference is the
1232 // root object (depth of zero).
1233 bool print_children = true;
1234
1235 // Use a new temporary pointer depth in case we override the
1236 // current pointer depth below...
1237 uint32_t curr_ptr_depth = ptr_depth;
1238
1239 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
1240 if (is_ptr || is_ref)
1241 {
1242 // We have a pointer or reference whose value is an address.
1243 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00001244 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00001245 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
1246 print_children = false;
1247
1248 else if (is_ref && curr_depth == 0)
1249 {
1250 // If this is the root object (depth is zero) that we are showing
1251 // and it is a reference, and no pointer depth has been supplied
1252 // print out what it references. Don't do this at deeper depths
1253 // otherwise we can end up with infinite recursion...
1254 curr_ptr_depth = 1;
1255 }
1256
1257 if (curr_ptr_depth == 0)
1258 print_children = false;
1259 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001260
Greg Clayton73b472d2010-10-27 03:32:59 +00001261 if (print_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001262 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001263 const uint32_t num_children = valobj->GetNumChildren();
1264 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001265 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001266 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001267 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001268 if (print_valobj)
1269 s.EOL();
1270 }
1271 else
1272 {
1273 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00001274 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001275 s.IndentMore();
1276 }
1277
1278 for (uint32_t idx=0; idx<num_children; ++idx)
1279 {
1280 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
1281 if (child_sp.get())
1282 {
1283 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001284 child_sp.get(),
1285 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00001286 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001287 curr_depth + 1,
1288 max_depth,
1289 show_types,
1290 show_location,
1291 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00001292 use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001293 true,
1294 flat_output);
1295 }
1296 }
1297
1298 if (!flat_output)
1299 {
1300 s.IndentLess();
1301 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001302 }
1303 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001304 else if (has_children)
1305 {
1306 // Aggregate, no children...
1307 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00001308 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001309 }
1310 else
1311 {
1312 if (print_valobj)
1313 s.EOL();
1314 }
1315
Greg Clayton1d3afba2010-10-05 00:00:42 +00001316 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001317 else
1318 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00001319 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001320 }
1321 }
1322 else
1323 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001324 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001325 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001326 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001327 }
1328 }
1329 }
1330 }
1331}
1332
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001333
1334ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00001335ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001336{
1337 ValueObjectSP valobj_sp;
1338
Jim Ingham6035b672011-03-31 00:19:25 +00001339 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001340 {
Jim Ingham6035b672011-03-31 00:19:25 +00001341 ExecutionContextScope *exe_scope = GetExecutionContextScope();
1342 if (exe_scope)
1343 {
1344 ExecutionContext exe_ctx;
1345 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001346
Jim Ingham6035b672011-03-31 00:19:25 +00001347 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001348
Jim Ingham6035b672011-03-31 00:19:25 +00001349 DataExtractor data;
1350 data.SetByteOrder (m_data.GetByteOrder());
1351 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001352
Jim Ingham6035b672011-03-31 00:19:25 +00001353 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001354
Jim Ingham6035b672011-03-31 00:19:25 +00001355 valobj_sp.reset (new ValueObjectConstResult (exe_scope,
1356 ast,
1357 GetClangType(),
1358 name,
1359 data));
1360 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001361 }
Jim Ingham6035b672011-03-31 00:19:25 +00001362
1363 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001364 {
Jim Ingham6035b672011-03-31 00:19:25 +00001365 valobj_sp.reset (new ValueObjectConstResult (NULL, m_error));
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001366 }
1367 return valobj_sp;
1368}
1369
1370lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00001371ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001372{
Jim Ingham78a685a2011-04-16 00:01:13 +00001373 if (m_deref_valobj_sp)
1374 return m_deref_valobj_sp;
1375
Greg Clayton54979cd2010-12-15 05:08:08 +00001376 const bool is_pointer_type = IsPointerType();
1377 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001378 {
1379 bool omit_empty_base_classes = true;
1380
1381 std::string child_name_str;
1382 uint32_t child_byte_size = 0;
1383 int32_t child_byte_offset = 0;
1384 uint32_t child_bitfield_bit_size = 0;
1385 uint32_t child_bitfield_bit_offset = 0;
1386 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00001387 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001388 const bool transparent_pointers = false;
1389 clang::ASTContext *clang_ast = GetClangAST();
1390 clang_type_t clang_type = GetClangType();
1391 clang_type_t child_clang_type;
1392 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast,
1393 GetName().GetCString(),
1394 clang_type,
1395 0,
1396 transparent_pointers,
1397 omit_empty_base_classes,
1398 child_name_str,
1399 child_byte_size,
1400 child_byte_offset,
1401 child_bitfield_bit_size,
1402 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00001403 child_is_base_class,
1404 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00001405 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001406 {
1407 ConstString child_name;
1408 if (!child_name_str.empty())
1409 child_name.SetCString (child_name_str.c_str());
1410
Jim Ingham78a685a2011-04-16 00:01:13 +00001411 m_deref_valobj_sp.reset (new ValueObjectChild (*this,
1412 clang_ast,
1413 child_clang_type,
1414 child_name,
1415 child_byte_size,
1416 child_byte_offset,
1417 child_bitfield_bit_size,
1418 child_bitfield_bit_offset,
1419 child_is_base_class,
1420 child_is_deref_of_parent));
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001421 }
1422 }
Greg Clayton54979cd2010-12-15 05:08:08 +00001423
Jim Ingham78a685a2011-04-16 00:01:13 +00001424 if (m_deref_valobj_sp)
Greg Clayton54979cd2010-12-15 05:08:08 +00001425 {
1426 error.Clear();
1427 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001428 else
1429 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001430 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001431 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001432
1433 if (is_pointer_type)
1434 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
1435 else
1436 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001437 }
1438
Jim Ingham78a685a2011-04-16 00:01:13 +00001439 return m_deref_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001440}
1441
Jim Ingham78a685a2011-04-16 00:01:13 +00001442lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00001443ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001444{
Jim Ingham78a685a2011-04-16 00:01:13 +00001445 if (m_addr_of_valobj_sp)
1446 return m_addr_of_valobj_sp;
1447
Greg Claytone0d378b2011-03-24 21:19:54 +00001448 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001449 const bool scalar_is_load_address = false;
1450 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00001451 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001452 if (addr != LLDB_INVALID_ADDRESS)
1453 {
1454 switch (address_type)
1455 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001456 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001457 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00001458 {
1459 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001460 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001461 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
1462 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001463 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00001464
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001465 case eAddressTypeFile:
1466 case eAddressTypeLoad:
1467 case eAddressTypeHost:
1468 {
1469 clang::ASTContext *ast = GetClangAST();
1470 clang_type_t clang_type = GetClangType();
1471 if (ast && clang_type)
1472 {
1473 std::string name (1, '&');
1474 name.append (m_name.AsCString(""));
Jim Ingham78a685a2011-04-16 00:01:13 +00001475 m_addr_of_valobj_sp.reset (new ValueObjectConstResult (GetExecutionContextScope(),
1476 ast,
1477 ClangASTContext::CreatePointerType (ast, clang_type),
1478 ConstString (name.c_str()),
1479 addr,
1480 eAddressTypeInvalid,
1481 m_data.GetAddressByteSize()));
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001482 }
1483 }
1484 break;
1485 }
1486 }
Jim Ingham78a685a2011-04-16 00:01:13 +00001487 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001488}
1489
Jim Ingham6035b672011-03-31 00:19:25 +00001490ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00001491 m_thread_id (LLDB_INVALID_UID),
1492 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00001493{
1494}
1495
1496ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00001497 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00001498 m_first_update (true),
1499 m_thread_id (LLDB_INVALID_UID),
1500 m_stop_id (0)
1501
Jim Ingham6035b672011-03-31 00:19:25 +00001502{
1503 ExecutionContext exe_ctx;
1504 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
1505 // and if so we want to cache that not the original.
1506 if (exe_scope)
1507 exe_scope->CalculateExecutionContext(exe_ctx);
1508 if (exe_ctx.target != NULL)
1509 {
1510 m_target_sp = exe_ctx.target->GetSP();
1511
1512 if (exe_ctx.process == NULL)
1513 m_process_sp = exe_ctx.target->GetProcessSP();
1514 else
1515 m_process_sp = exe_ctx.process->GetSP();
1516
1517 if (m_process_sp != NULL)
1518 {
1519 m_stop_id = m_process_sp->GetStopID();
1520 Thread *thread = NULL;
1521
1522 if (exe_ctx.thread == NULL)
1523 {
1524 if (use_selected)
1525 {
1526 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
1527 if (thread)
1528 computed_exe_scope = thread;
1529 }
1530 }
1531 else
1532 thread = exe_ctx.thread;
1533
1534 if (thread != NULL)
1535 {
1536 m_thread_id = thread->GetIndexID();
1537 if (exe_ctx.frame == NULL)
1538 {
1539 if (use_selected)
1540 {
1541 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
1542 if (frame)
1543 {
1544 m_stack_id = frame->GetStackID();
1545 computed_exe_scope = frame;
1546 }
1547 }
1548 }
1549 else
1550 m_stack_id = exe_ctx.frame->GetStackID();
1551 }
1552 }
1553 }
1554 m_exe_scope = computed_exe_scope;
1555}
1556
1557ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
1558 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00001559 m_needs_update(true),
1560 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00001561 m_target_sp (rhs.m_target_sp),
1562 m_process_sp (rhs.m_process_sp),
1563 m_thread_id (rhs.m_thread_id),
1564 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00001565 m_stop_id (0)
1566{
1567}
1568
1569ValueObject::EvaluationPoint::~EvaluationPoint ()
1570{
1571}
1572
1573ExecutionContextScope *
1574ValueObject::EvaluationPoint::GetExecutionContextScope ()
1575{
1576 // We have to update before giving out the scope, or we could be handing out stale pointers.
1577 SyncWithProcessState();
1578
1579 return m_exe_scope;
1580}
1581
1582// This function checks the EvaluationPoint against the current process state. If the current
1583// state matches the evaluation point, or the evaluation point is already invalid, then we return
1584// false, meaning "no change". If the current state is different, we update our state, and return
1585// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
1586// future calls to NeedsUpdate will return true.
1587
1588bool
1589ValueObject::EvaluationPoint::SyncWithProcessState()
1590{
1591 // If we're already invalid, we don't need to do anything, and nothing has changed:
1592 if (m_stop_id == LLDB_INVALID_UID)
1593 {
1594 // Can't update with an invalid state.
1595 m_needs_update = false;
1596 return false;
1597 }
1598
1599 // If we don't have a process nothing can change.
1600 if (!m_process_sp)
1601 return false;
1602
1603 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00001604 uint32_t cur_stop_id = m_process_sp->GetStopID();
1605 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00001606 return false;
1607
Jim Ingham78a685a2011-04-16 00:01:13 +00001608 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
1609 // In either case, we aren't going to be able to sync with the process state.
1610 if (cur_stop_id == 0)
1611 return false;
1612
1613 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00001614 m_needs_update = true;
1615 m_exe_scope = m_process_sp.get();
1616
1617 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
1618 // doesn't, mark ourselves as invalid.
1619
1620 if (m_thread_id != LLDB_INVALID_THREAD_ID)
1621 {
1622 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
1623 if (our_thread == NULL)
1624 SetInvalid();
1625 else
1626 {
1627 m_exe_scope = our_thread;
1628
1629 if (m_stack_id.IsValid())
1630 {
1631 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
1632 if (our_frame == NULL)
1633 SetInvalid();
1634 else
1635 m_exe_scope = our_frame;
1636 }
1637 }
1638 }
1639 return true;
1640}
1641
1642bool
1643ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
1644{
1645 if (!IsValid())
1646 return false;
1647
1648 bool needs_update = false;
1649 m_exe_scope = NULL;
1650
1651 // The target has to be non-null, and the
1652 Target *target = exe_scope->CalculateTarget();
1653 if (target != NULL)
1654 {
1655 Target *old_target = m_target_sp.get();
1656 assert (target == old_target);
1657 Process *process = exe_scope->CalculateProcess();
1658 if (process != NULL)
1659 {
1660 // FOR NOW - assume you can't update variable objects across process boundaries.
1661 Process *old_process = m_process_sp.get();
1662 assert (process == old_process);
1663
1664 lldb::user_id_t stop_id = process->GetStopID();
1665 if (stop_id != m_stop_id)
1666 {
1667 needs_update = true;
1668 m_stop_id = stop_id;
1669 }
1670 // See if we're switching the thread or stack context. If no thread is given, this is
1671 // being evaluated in a global context.
1672 Thread *thread = exe_scope->CalculateThread();
1673 if (thread != NULL)
1674 {
1675 lldb::user_id_t new_thread_index = thread->GetIndexID();
1676 if (new_thread_index != m_thread_id)
1677 {
1678 needs_update = true;
1679 m_thread_id = new_thread_index;
1680 m_stack_id.Clear();
1681 }
1682
1683 StackFrame *new_frame = exe_scope->CalculateStackFrame();
1684 if (new_frame != NULL)
1685 {
1686 if (new_frame->GetStackID() != m_stack_id)
1687 {
1688 needs_update = true;
1689 m_stack_id = new_frame->GetStackID();
1690 }
1691 }
1692 else
1693 {
1694 m_stack_id.Clear();
1695 needs_update = true;
1696 }
1697 }
1698 else
1699 {
1700 // If this had been given a thread, and now there is none, we should update.
1701 // Otherwise we don't have to do anything.
1702 if (m_thread_id != LLDB_INVALID_UID)
1703 {
1704 m_thread_id = LLDB_INVALID_UID;
1705 m_stack_id.Clear();
1706 needs_update = true;
1707 }
1708 }
1709 }
1710 else
1711 {
1712 // If there is no process, then we don't need to update anything.
1713 // But if we're switching from having a process to not, we should try to update.
1714 if (m_process_sp.get() != NULL)
1715 {
1716 needs_update = true;
1717 m_process_sp.reset();
1718 m_thread_id = LLDB_INVALID_UID;
1719 m_stack_id.Clear();
1720 }
1721 }
1722 }
1723 else
1724 {
1725 // If there's no target, nothing can change so we don't need to update anything.
1726 // But if we're switching from having a target to not, we should try to update.
1727 if (m_target_sp.get() != NULL)
1728 {
1729 needs_update = true;
1730 m_target_sp.reset();
1731 m_process_sp.reset();
1732 m_thread_id = LLDB_INVALID_UID;
1733 m_stack_id.Clear();
1734 }
1735 }
1736 if (!m_needs_update)
1737 m_needs_update = needs_update;
1738
1739 return needs_update;
1740}