blob: 78e0cfca7a5a02648143a519881419a538442cf8 [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"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/ValueObjectList.h"
26
Greg Clayton7fb56d02011-02-01 01:31:41 +000027#include "lldb/Host/Endian.h"
28
Greg Claytone1a916a2010-07-21 22:12:05 +000029#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Symbol/ClangASTContext.h"
31#include "lldb/Symbol/Type.h"
32
Jim Ingham53c47f12010-09-10 23:12:17 +000033#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000034#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Target/Process.h"
36#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000037#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039
40using namespace lldb;
41using namespace lldb_private;
42
43static lldb::user_id_t g_value_obj_uid = 0;
44
45//----------------------------------------------------------------------
46// ValueObject constructor
47//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000048ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000050 m_parent (&parent),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051 m_name (),
52 m_data (),
53 m_value (),
54 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000055 m_value_str (),
56 m_old_value_str (),
57 m_location_str (),
58 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000059 m_object_desc_str (),
Greg Clayton288bdf92010-09-02 02:59:18 +000060 m_children (),
61 m_synthetic_children (),
Greg Clayton32c40852010-10-06 03:09:11 +000062 m_dynamic_value_sp (),
63 m_format (eFormatDefault),
Greg Clayton288bdf92010-09-02 02:59:18 +000064 m_value_is_valid (false),
65 m_value_did_change (false),
66 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000067 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000068 m_pointers_point_to_load_addrs (false),
Jim Ingham6035b672011-03-31 00:19:25 +000069 m_is_deref_of_parent (false),
70 m_update_point (parent.GetUpdatePoint ())
71{
72}
73
74//----------------------------------------------------------------------
75// ValueObject constructor
76//----------------------------------------------------------------------
77ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
78 UserID (++g_value_obj_uid), // Unique identifier for every value object
79 m_parent (NULL),
80 m_name (),
81 m_data (),
82 m_value (),
83 m_error (),
84 m_value_str (),
85 m_old_value_str (),
86 m_location_str (),
87 m_summary_str (),
88 m_object_desc_str (),
89 m_children (),
90 m_synthetic_children (),
91 m_dynamic_value_sp (),
92 m_format (eFormatDefault),
93 m_value_is_valid (false),
94 m_value_did_change (false),
95 m_children_count_valid (false),
96 m_old_value_valid (false),
97 m_pointers_point_to_load_addrs (false),
98 m_is_deref_of_parent (false),
99 m_update_point (exe_scope)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100{
101}
102
103//----------------------------------------------------------------------
104// Destructor
105//----------------------------------------------------------------------
106ValueObject::~ValueObject ()
107{
108}
109
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110bool
Jim Ingham6035b672011-03-31 00:19:25 +0000111ValueObject::UpdateValueIfNeeded ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112{
Greg Claytonb71f3842010-10-05 03:13:51 +0000113 // If this is a constant value, then our success is predicated on whether
114 // we have an error or not
115 if (GetIsConstant())
116 return m_error.Success();
117
Jim Ingham6035b672011-03-31 00:19:25 +0000118 bool first_update = m_update_point.IsFirstEvaluation();
119
120 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121 {
Jim Ingham6035b672011-03-31 00:19:25 +0000122 m_update_point.SetUpdated();
123
124 // Save the old value using swap to avoid a string copy which
125 // also will clear our m_value_str
126 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127 {
Jim Ingham6035b672011-03-31 00:19:25 +0000128 m_old_value_valid = false;
129 }
130 else
131 {
132 m_old_value_valid = true;
133 m_old_value_str.swap (m_value_str);
134 m_value_str.clear();
135 }
136 m_location_str.clear();
137 m_summary_str.clear();
138 m_object_desc_str.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139
Jim Ingham6035b672011-03-31 00:19:25 +0000140 const bool value_was_valid = GetValueIsValid();
141 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000142
Jim Ingham6035b672011-03-31 00:19:25 +0000143 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000144
Jim Ingham6035b672011-03-31 00:19:25 +0000145 // Call the pure virtual function to update the value
146 bool success = UpdateValue ();
147
148 SetValueIsValid (success);
149
150 if (first_update)
151 SetValueDidChange (false);
152 else if (!m_value_did_change && success == false)
153 {
154 // The value wasn't gotten successfully, so we mark this
155 // as changed if the value used to be valid and now isn't
156 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157 }
158 }
159 return m_error.Success();
160}
161
162const DataExtractor &
163ValueObject::GetDataExtractor () const
164{
165 return m_data;
166}
167
168DataExtractor &
169ValueObject::GetDataExtractor ()
170{
171 return m_data;
172}
173
174const Error &
175ValueObject::GetError() const
176{
177 return m_error;
178}
179
180const ConstString &
181ValueObject::GetName() const
182{
183 return m_name;
184}
185
186const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000187ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188{
Jim Ingham6035b672011-03-31 00:19:25 +0000189 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000190 {
191 if (m_location_str.empty())
192 {
193 StreamString sstr;
194
195 switch (m_value.GetValueType())
196 {
197 default:
198 break;
199
200 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000201 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000202 {
203 RegisterInfo *reg_info = m_value.GetRegisterInfo();
204 if (reg_info)
205 {
206 if (reg_info->name)
207 m_location_str = reg_info->name;
208 else if (reg_info->alt_name)
209 m_location_str = reg_info->alt_name;
210 break;
211 }
212 }
213 m_location_str = "scalar";
214 break;
215
216 case Value::eValueTypeLoadAddress:
217 case Value::eValueTypeFileAddress:
218 case Value::eValueTypeHostAddress:
219 {
220 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
221 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
222 m_location_str.swap(sstr.GetString());
223 }
224 break;
225 }
226 }
227 }
228 return m_location_str.c_str();
229}
230
231Value &
232ValueObject::GetValue()
233{
234 return m_value;
235}
236
237const Value &
238ValueObject::GetValue() const
239{
240 return m_value;
241}
242
243bool
Jim Ingham6035b672011-03-31 00:19:25 +0000244ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000245{
246 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000247 ExecutionContextScope *exe_scope = GetExecutionContextScope();
248 if (exe_scope)
249 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000250 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
251 return scalar.IsValid();
252}
253
254bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000255ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000256{
Greg Clayton288bdf92010-09-02 02:59:18 +0000257 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258}
259
260
261void
262ValueObject::SetValueIsValid (bool b)
263{
Greg Clayton288bdf92010-09-02 02:59:18 +0000264 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265}
266
267bool
Jim Ingham6035b672011-03-31 00:19:25 +0000268ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269{
Jim Ingham6035b672011-03-31 00:19:25 +0000270 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000271 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000272}
273
274void
275ValueObject::SetValueDidChange (bool value_changed)
276{
Greg Clayton288bdf92010-09-02 02:59:18 +0000277 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000278}
279
280ValueObjectSP
281ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
282{
283 ValueObjectSP child_sp;
284 if (idx < GetNumChildren())
285 {
286 // Check if we have already made the child value object?
287 if (can_create && m_children[idx].get() == NULL)
288 {
289 // No we haven't created the child at this index, so lets have our
290 // subclass do it and cache the result for quick future access.
291 m_children[idx] = CreateChildAtIndex (idx, false, 0);
292 }
293
294 child_sp = m_children[idx];
295 }
296 return child_sp;
297}
298
299uint32_t
300ValueObject::GetIndexOfChildWithName (const ConstString &name)
301{
302 bool omit_empty_base_classes = true;
303 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000304 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000305 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306 omit_empty_base_classes);
307}
308
309ValueObjectSP
310ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
311{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000312 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 // classes (which really aren't part of the expression path), so we
314 // need a vector of indexes that can get us down to the correct child
315 std::vector<uint32_t> child_indexes;
316 clang::ASTContext *clang_ast = GetClangAST();
Greg Clayton1be10fc2010-09-29 01:12:09 +0000317 void *clang_type = GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318 bool omit_empty_base_classes = true;
319 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
320 clang_type,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000321 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322 omit_empty_base_classes,
323 child_indexes);
324 ValueObjectSP child_sp;
325 if (num_child_indexes > 0)
326 {
327 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
328 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
329
330 child_sp = GetChildAtIndex(*pos, can_create);
331 for (++pos; pos != end; ++pos)
332 {
333 if (child_sp)
334 {
335 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
336 child_sp = new_child_sp;
337 }
338 else
339 {
340 child_sp.reset();
341 }
342
343 }
344 }
345 return child_sp;
346}
347
348
349uint32_t
350ValueObject::GetNumChildren ()
351{
Greg Clayton288bdf92010-09-02 02:59:18 +0000352 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353 {
354 SetNumChildren (CalculateNumChildren());
355 }
356 return m_children.size();
357}
358void
359ValueObject::SetNumChildren (uint32_t num_children)
360{
Greg Clayton288bdf92010-09-02 02:59:18 +0000361 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362 m_children.resize(num_children);
363}
364
365void
366ValueObject::SetName (const char *name)
367{
368 m_name.SetCString(name);
369}
370
371void
372ValueObject::SetName (const ConstString &name)
373{
374 m_name = name;
375}
376
377ValueObjectSP
378ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
379{
380 ValueObjectSP valobj_sp;
381 bool omit_empty_base_classes = true;
382
383 std::string child_name_str;
384 uint32_t child_byte_size = 0;
385 int32_t child_byte_offset = 0;
386 uint32_t child_bitfield_bit_size = 0;
387 uint32_t child_bitfield_bit_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +0000388 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +0000389 bool child_is_deref_of_parent = false;
390
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391 const bool transparent_pointers = synthetic_array_member == false;
392 clang::ASTContext *clang_ast = GetClangAST();
Greg Clayton73b472d2010-10-27 03:32:59 +0000393 clang_type_t clang_type = GetClangType();
394 clang_type_t child_clang_type;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000396 GetName().GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397 clang_type,
398 idx,
399 transparent_pointers,
400 omit_empty_base_classes,
401 child_name_str,
402 child_byte_size,
403 child_byte_offset,
404 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +0000405 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +0000406 child_is_base_class,
407 child_is_deref_of_parent);
Greg Clayton97a43712011-01-08 22:26:47 +0000408 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000409 {
410 if (synthetic_index)
411 child_byte_offset += child_byte_size * synthetic_index;
412
413 ConstString child_name;
414 if (!child_name_str.empty())
415 child_name.SetCString (child_name_str.c_str());
416
Jim Ingham6035b672011-03-31 00:19:25 +0000417 valobj_sp.reset (new ValueObjectChild (*this,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000418 clang_ast,
419 child_clang_type,
420 child_name,
421 child_byte_size,
422 child_byte_offset,
423 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +0000424 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +0000425 child_is_base_class,
426 child_is_deref_of_parent));
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000427 if (m_pointers_point_to_load_addrs)
428 valobj_sp->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429 }
430 return valobj_sp;
431}
432
433const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000434ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435{
Jim Ingham6035b672011-03-31 00:19:25 +0000436 if (UpdateValueIfNeeded ())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437 {
438 if (m_summary_str.empty())
439 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000440 clang_type_t clang_type = GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441
442 // See if this is a pointer to a C string?
Greg Clayton737b9322010-09-13 03:32:57 +0000443 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000444 {
Greg Clayton737b9322010-09-13 03:32:57 +0000445 StreamString sstr;
Greg Clayton73b472d2010-10-27 03:32:59 +0000446 clang_type_t elem_or_pointee_clang_type;
447 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000448 GetClangAST(),
449 &elem_or_pointee_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +0000450
Jim Ingham6035b672011-03-31 00:19:25 +0000451 ExecutionContextScope *exe_scope = GetExecutionContextScope();
452 if (exe_scope)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453 {
Jim Ingham6035b672011-03-31 00:19:25 +0000454 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
455 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456 {
Jim Ingham6035b672011-03-31 00:19:25 +0000457 Process *process = exe_scope->CalculateProcess();
458 if (process != NULL)
459 {
460 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
461 AddressType cstr_address_type = eAddressTypeInvalid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462
Jim Ingham6035b672011-03-31 00:19:25 +0000463 size_t cstr_len = 0;
464 if (type_flags.Test (ClangASTContext::eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465 {
Jim Ingham6035b672011-03-31 00:19:25 +0000466 // We have an array
467 cstr_len = ClangASTContext::GetArraySize (clang_type);
468 cstr_address = GetAddressOf (cstr_address_type, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469 }
Greg Clayton737b9322010-09-13 03:32:57 +0000470 else
471 {
Jim Ingham6035b672011-03-31 00:19:25 +0000472 // We have a pointer
473 cstr_address = GetPointerValue (cstr_address_type, true);
Greg Clayton737b9322010-09-13 03:32:57 +0000474 }
Jim Ingham6035b672011-03-31 00:19:25 +0000475 if (cstr_address != LLDB_INVALID_ADDRESS)
Greg Clayton737b9322010-09-13 03:32:57 +0000476 {
Jim Ingham6035b672011-03-31 00:19:25 +0000477 DataExtractor data;
478 size_t bytes_read = 0;
479 std::vector<char> data_buffer;
480 Error error;
481 if (cstr_len > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000482 {
Jim Ingham6035b672011-03-31 00:19:25 +0000483 data_buffer.resize(cstr_len);
484 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
485 bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error);
486 if (bytes_read > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000487 {
Jim Ingham6035b672011-03-31 00:19:25 +0000488 sstr << '"';
489 data.Dump (&sstr,
490 0, // Start offset in "data"
491 eFormatChar, // Print as characters
492 1, // Size of item (1 byte for a char!)
493 bytes_read, // How many bytes to print?
494 UINT32_MAX, // num per line
495 LLDB_INVALID_ADDRESS,// base address
496 0, // bitfield bit size
497 0); // bitfield bit offset
498 sstr << '"';
Greg Clayton737b9322010-09-13 03:32:57 +0000499 }
500 }
Jim Ingham6035b672011-03-31 00:19:25 +0000501 else
502 {
503 const size_t k_max_buf_size = 256;
504 data_buffer.resize (k_max_buf_size + 1);
505 // NULL terminate in case we don't get the entire C string
506 data_buffer.back() = '\0';
Greg Clayton737b9322010-09-13 03:32:57 +0000507
Jim Ingham6035b672011-03-31 00:19:25 +0000508 sstr << '"';
509
510 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
511 while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0)
512 {
513 size_t len = strlen(&data_buffer.front());
514 if (len == 0)
515 break;
516 if (len > bytes_read)
517 len = bytes_read;
518
519 data.Dump (&sstr,
520 0, // Start offset in "data"
521 eFormatChar, // Print as characters
522 1, // Size of item (1 byte for a char!)
523 len, // How many bytes to print?
524 UINT32_MAX, // num per line
525 LLDB_INVALID_ADDRESS,// base address
526 0, // bitfield bit size
527 0); // bitfield bit offset
528
529 if (len < k_max_buf_size)
530 break;
531 cstr_address += k_max_buf_size;
532 }
533 sstr << '"';
534 }
535 }
Greg Clayton737b9322010-09-13 03:32:57 +0000536 }
Jim Ingham6035b672011-03-31 00:19:25 +0000537
538 if (sstr.GetSize() > 0)
539 m_summary_str.assign (sstr.GetData(), sstr.GetSize());
Greg Clayton737b9322010-09-13 03:32:57 +0000540 }
Jim Ingham6035b672011-03-31 00:19:25 +0000541 else if (ClangASTContext::IsFunctionPointerType (clang_type))
Greg Clayton737b9322010-09-13 03:32:57 +0000542 {
Jim Ingham6035b672011-03-31 00:19:25 +0000543 AddressType func_ptr_address_type = eAddressTypeInvalid;
544 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
545
546 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
547 {
548 switch (func_ptr_address_type)
549 {
550 case eAddressTypeInvalid:
551 case eAddressTypeFile:
552 break;
553
554 case eAddressTypeLoad:
555 {
556 Address so_addr;
557 Target *target = exe_scope->CalculateTarget();
558 if (target && target->GetSectionLoadList().IsEmpty() == false)
559 {
560 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
561 {
562 so_addr.Dump (&sstr,
563 exe_scope,
564 Address::DumpStyleResolvedDescription,
565 Address::DumpStyleSectionNameOffset);
566 }
567 }
568 }
569 break;
570
571 case eAddressTypeHost:
572 break;
573 }
574 }
575 if (sstr.GetSize() > 0)
576 {
577 m_summary_str.assign (1, '(');
578 m_summary_str.append (sstr.GetData(), sstr.GetSize());
579 m_summary_str.append (1, ')');
580 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000581 }
582 }
583 }
584 }
585 }
586 if (m_summary_str.empty())
587 return NULL;
588 return m_summary_str.c_str();
589}
590
Jim Ingham53c47f12010-09-10 23:12:17 +0000591const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000592ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000593{
594 if (!m_object_desc_str.empty())
595 return m_object_desc_str.c_str();
596
Jim Ingham6035b672011-03-31 00:19:25 +0000597 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000598 return NULL;
Jim Ingham6035b672011-03-31 00:19:25 +0000599
600 ExecutionContextScope *exe_scope = GetExecutionContextScope();
601 if (exe_scope == NULL)
602 return NULL;
603
Jim Ingham53c47f12010-09-10 23:12:17 +0000604 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000605 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000606 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000607
Jim Ingham53c47f12010-09-10 23:12:17 +0000608 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000609
610 lldb::LanguageType language = GetObjectRuntimeLanguage();
611 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
612
Jim Inghama2cf2632010-12-23 02:29:54 +0000613 if (runtime == NULL)
614 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000615 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000616 clang_type_t opaque_qual_type = GetClangType();
617 if (opaque_qual_type != NULL)
618 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000619 bool is_signed;
620 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
621 || ClangASTContext::IsPointerType (opaque_qual_type))
622 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000623 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000624 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000625 }
626 }
627
Jim Ingham8d543de2011-03-31 23:01:21 +0000628 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000629 {
630 m_object_desc_str.append (s.GetData());
631 }
Sean Callanan672ad942010-10-23 00:18:49 +0000632
633 if (m_object_desc_str.empty())
634 return NULL;
635 else
636 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000637}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000638
639const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000640ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641{
642 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000643 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000644 {
Jim Ingham6035b672011-03-31 00:19:25 +0000645 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000646 {
647 if (m_value_str.empty())
648 {
649 const Value::ContextType context_type = m_value.GetContextType();
650
651 switch (context_type)
652 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000653 case Value::eContextTypeClangType:
654 case Value::eContextTypeLLDBType:
655 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000656 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000657 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000658 if (clang_type)
659 {
660 StreamString sstr;
Greg Clayton32c40852010-10-06 03:09:11 +0000661 if (m_format == eFormatDefault)
662 m_format = ClangASTType::GetFormat(clang_type);
663
664 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
665 clang_type, // The clang type to display
666 &sstr,
667 m_format, // Format to display this type with
668 m_data, // Data to extract from
669 0, // Byte offset into "m_data"
670 GetByteSize(), // Byte size of item in "m_data"
671 GetBitfieldBitSize(), // Bitfield bit size
672 GetBitfieldBitOffset())) // Bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000673 m_value_str.swap(sstr.GetString());
674 else
675 m_value_str.clear();
676 }
677 }
678 break;
679
Greg Clayton526e5af2010-11-13 03:52:47 +0000680 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681 {
682 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
683 if (reg_info)
684 {
685 StreamString reg_sstr;
686 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
687 m_value_str.swap(reg_sstr.GetString());
688 }
689 }
690 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000691
692 default:
693 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000694 }
695 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000696
697 if (!m_value_did_change && m_old_value_valid)
698 {
699 // The value was gotten successfully, so we consider the
700 // value as changed if the value string differs
701 SetValueDidChange (m_old_value_str != m_value_str);
702 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703 }
704 }
705 if (m_value_str.empty())
706 return NULL;
707 return m_value_str.c_str();
708}
709
Greg Clayton737b9322010-09-13 03:32:57 +0000710addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000711ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +0000712{
713 switch (m_value.GetValueType())
714 {
715 case Value::eValueTypeScalar:
716 if (scalar_is_load_address)
717 {
718 address_type = eAddressTypeLoad;
719 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
720 }
721 break;
722
723 case Value::eValueTypeLoadAddress:
724 case Value::eValueTypeFileAddress:
725 case Value::eValueTypeHostAddress:
726 {
727 address_type = m_value.GetValueAddressType ();
728 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
729 }
730 break;
731 }
732 address_type = eAddressTypeInvalid;
733 return LLDB_INVALID_ADDRESS;
734}
735
736addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000737ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +0000738{
739 lldb::addr_t address = LLDB_INVALID_ADDRESS;
740 address_type = eAddressTypeInvalid;
Greg Clayton73b472d2010-10-27 03:32:59 +0000741 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +0000742 {
743 case Value::eValueTypeScalar:
744 if (scalar_is_load_address)
745 {
746 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
747 address_type = eAddressTypeLoad;
748 }
749 break;
750
751 case Value::eValueTypeLoadAddress:
752 case Value::eValueTypeFileAddress:
753 case Value::eValueTypeHostAddress:
754 {
755 uint32_t data_offset = 0;
756 address = m_data.GetPointer(&data_offset);
757 address_type = m_value.GetValueAddressType();
758 if (address_type == eAddressTypeInvalid)
759 address_type = eAddressTypeLoad;
760 }
761 break;
762 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000763
764 if (m_pointers_point_to_load_addrs)
765 address_type = eAddressTypeLoad;
766
Greg Clayton737b9322010-09-13 03:32:57 +0000767 return address;
768}
769
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000770bool
Jim Ingham6035b672011-03-31 00:19:25 +0000771ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000772{
773 // Make sure our value is up to date first so that our location and location
774 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +0000775 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000776 return false;
777
778 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +0000779 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000780
781 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +0000782 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000783 switch (encoding)
784 {
785 case eEncodingInvalid:
786 return false;
787
788 case eEncodingUint:
789 if (byte_size > sizeof(unsigned long long))
790 {
791 return false;
792 }
793 else
794 {
795 unsigned long long ull_val = strtoull(value_str, &end, 0);
796 if (end && *end != '\0')
797 return false;
798 m_value = ull_val;
799 // Limit the bytes in our m_data appropriately.
800 m_value.GetScalar().GetData (m_data, byte_size);
801 }
802 break;
803
804 case eEncodingSint:
805 if (byte_size > sizeof(long long))
806 {
807 return false;
808 }
809 else
810 {
811 long long sll_val = strtoll(value_str, &end, 0);
812 if (end && *end != '\0')
813 return false;
814 m_value = sll_val;
815 // Limit the bytes in our m_data appropriately.
816 m_value.GetScalar().GetData (m_data, byte_size);
817 }
818 break;
819
820 case eEncodingIEEE754:
821 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000822 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +0000823 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000824 if (dst != NULL)
825 {
826 // We are decoding a float into host byte order below, so make
827 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +0000828 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
830 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000831 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000832 value_str,
833 dst,
834 byte_size);
835
836 if (converted_byte_size == byte_size)
837 {
838 }
839 }
840 }
841 break;
842
843 case eEncodingVector:
844 return false;
845
846 default:
847 return false;
848 }
849
850 // If we have made it here the value is in m_data and we should write it
851 // out to the target
852 return Write ();
853}
854
855bool
856ValueObject::Write ()
857{
858 // Clear the update ID so the next time we try and read the value
859 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +0000860 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000861
862 // TODO: when Value has a method to write a value back, call it from here.
863 return false;
864
865}
866
Jim Ingham5a369122010-09-28 01:25:32 +0000867lldb::LanguageType
868ValueObject::GetObjectRuntimeLanguage ()
869{
Greg Clayton73b472d2010-10-27 03:32:59 +0000870 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +0000871 if (opaque_qual_type == NULL)
872 return lldb::eLanguageTypeC;
873
874 // If the type is a reference, then resolve it to what it refers to first:
875 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
876 if (qual_type->isAnyPointerType())
877 {
878 if (qual_type->isObjCObjectPointerType())
879 return lldb::eLanguageTypeObjC;
880
881 clang::QualType pointee_type (qual_type->getPointeeType());
882 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
883 return lldb::eLanguageTypeC_plus_plus;
884 if (pointee_type->isObjCObjectOrInterfaceType())
885 return lldb::eLanguageTypeObjC;
886 if (pointee_type->isObjCClassType())
887 return lldb::eLanguageTypeObjC;
888 }
889 else
890 {
891 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
892 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +0000893 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +0000894 return lldb::eLanguageTypeC_plus_plus;
895 }
896
897 return lldb::eLanguageTypeC;
898}
899
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000900void
901ValueObject::AddSyntheticChild (const ConstString &key, ValueObjectSP& valobj_sp)
902{
903 m_synthetic_children[key] = valobj_sp;
904}
905
906ValueObjectSP
907ValueObject::GetSyntheticChild (const ConstString &key) const
908{
909 ValueObjectSP synthetic_child_sp;
910 std::map<ConstString, ValueObjectSP>::const_iterator pos = m_synthetic_children.find (key);
911 if (pos != m_synthetic_children.end())
912 synthetic_child_sp = pos->second;
913 return synthetic_child_sp;
914}
915
916bool
917ValueObject::IsPointerType ()
918{
Greg Clayton1be10fc2010-09-29 01:12:09 +0000919 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000920}
921
Jim Inghamb7603bb2011-03-18 00:05:18 +0000922bool
923ValueObject::IsIntegerType (bool &is_signed)
924{
925 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
926}
Greg Clayton73b472d2010-10-27 03:32:59 +0000927
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000928bool
929ValueObject::IsPointerOrReferenceType ()
930{
Greg Clayton1be10fc2010-09-29 01:12:09 +0000931 return ClangASTContext::IsPointerOrReferenceType(GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000932}
933
934ValueObjectSP
935ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
936{
937 ValueObjectSP synthetic_child_sp;
938 if (IsPointerType ())
939 {
940 char index_str[64];
941 snprintf(index_str, sizeof(index_str), "[%i]", index);
942 ConstString index_const_str(index_str);
943 // Check if we have already created a synthetic array member in this
944 // valid object. If we have we will re-use it.
945 synthetic_child_sp = GetSyntheticChild (index_const_str);
946 if (!synthetic_child_sp)
947 {
948 // We haven't made a synthetic array member for INDEX yet, so
949 // lets make one and cache it for any future reference.
950 synthetic_child_sp = CreateChildAtIndex(0, true, index);
951
952 // Cache the value if we got one back...
953 if (synthetic_child_sp)
954 AddSyntheticChild(index_const_str, synthetic_child_sp);
955 }
956 }
957 return synthetic_child_sp;
958}
Jim Ingham22777012010-09-23 02:01:19 +0000959
960bool
961ValueObject::SetDynamicValue ()
962{
963 if (!IsPointerOrReferenceType())
964 return false;
965
966 // Check that the runtime class is correct for determining the most specific class.
967 // If it is a C++ class, see if it is dynamic:
Jim Ingham5a369122010-09-28 01:25:32 +0000968
Jim Ingham22777012010-09-23 02:01:19 +0000969 return true;
970}
Greg Clayton1d3afba2010-10-05 00:00:42 +0000971
Greg Claytone221f822011-01-21 01:59:00 +0000972bool
973ValueObject::GetBaseClassPath (Stream &s)
974{
975 if (IsBaseClass())
976 {
977 bool parent_had_base_class = m_parent && m_parent->GetBaseClassPath (s);
978 clang_type_t clang_type = GetClangType();
979 std::string cxx_class_name;
980 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
981 if (this_had_base_class)
982 {
983 if (parent_had_base_class)
984 s.PutCString("::");
985 s.PutCString(cxx_class_name.c_str());
986 }
987 return parent_had_base_class || this_had_base_class;
988 }
989 return false;
990}
991
992
993ValueObject *
994ValueObject::GetNonBaseClassParent()
995{
996 if (m_parent)
997 {
998 if (m_parent->IsBaseClass())
999 return m_parent->GetNonBaseClassParent();
1000 else
1001 return m_parent;
1002 }
1003 return NULL;
1004}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001005
1006void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001007ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001008{
Greg Claytone221f822011-01-21 01:59:00 +00001009 const bool is_deref_of_parent = IsDereferenceOfParent ();
1010
1011 if (is_deref_of_parent)
1012 s.PutCString("*(");
1013
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001014 if (m_parent)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001015 m_parent->GetExpressionPath (s, qualify_cxx_base_classes);
Greg Claytone221f822011-01-21 01:59:00 +00001016
1017 if (!IsBaseClass())
1018 {
1019 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001020 {
Greg Claytone221f822011-01-21 01:59:00 +00001021 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1022 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001023 {
Greg Claytone221f822011-01-21 01:59:00 +00001024 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1025 if (non_base_class_parent_clang_type)
1026 {
1027 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1028
1029 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1030 {
1031 s.PutCString("->");
1032 }
1033 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1034 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1035 {
1036 s.PutChar('.');
1037 }
1038 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001039 }
Greg Claytone221f822011-01-21 01:59:00 +00001040
1041 const char *name = GetName().GetCString();
1042 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001043 {
Greg Claytone221f822011-01-21 01:59:00 +00001044 if (qualify_cxx_base_classes)
1045 {
1046 if (GetBaseClassPath (s))
1047 s.PutCString("::");
1048 }
1049 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001050 }
1051 }
1052 }
1053
Greg Claytone221f822011-01-21 01:59:00 +00001054 if (is_deref_of_parent)
1055 s.PutChar(')');
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001056}
1057
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001058void
Greg Clayton1d3afba2010-10-05 00:00:42 +00001059ValueObject::DumpValueObject
1060(
1061 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00001062 ValueObject *valobj,
1063 const char *root_valobj_name,
1064 uint32_t ptr_depth,
1065 uint32_t curr_depth,
1066 uint32_t max_depth,
1067 bool show_types,
1068 bool show_location,
1069 bool use_objc,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001070 bool scope_already_checked,
1071 bool flat_output
Greg Clayton1d3afba2010-10-05 00:00:42 +00001072)
1073{
Jim Ingham6035b672011-03-31 00:19:25 +00001074 if (valobj && valobj->UpdateValueIfNeeded ())
Greg Clayton1d3afba2010-10-05 00:00:42 +00001075 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001076 clang_type_t clang_type = valobj->GetClangType();
1077
Greg Clayton73b472d2010-10-27 03:32:59 +00001078 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001079 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00001080 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
1081 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001082
1083 const bool print_valobj = flat_output == false || has_value;
1084
1085 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001086 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001087 if (show_location)
1088 {
Jim Ingham6035b672011-03-31 00:19:25 +00001089 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001090 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001091
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001092 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001093
Greg Clayton7c8a9662010-11-02 01:50:16 +00001094 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00001095 if (show_types || (curr_depth == 0 && !flat_output))
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001096 s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
Greg Clayton1d3afba2010-10-05 00:00:42 +00001097
Greg Clayton1d3afba2010-10-05 00:00:42 +00001098
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001099 if (flat_output)
1100 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001101 // If we are showing types, also qualify the C++ base classes
1102 const bool qualify_cxx_base_classes = show_types;
1103 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001104 s.PutCString(" =");
1105 }
1106 else
1107 {
1108 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
1109 s.Printf ("%s =", name_cstr);
1110 }
1111
Jim Ingham6035b672011-03-31 00:19:25 +00001112 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001113 {
1114 err_cstr = "error: out of scope";
1115 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001116 }
1117
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001118 const char *val_cstr = NULL;
1119
1120 if (err_cstr == NULL)
1121 {
Jim Ingham6035b672011-03-31 00:19:25 +00001122 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001123 err_cstr = valobj->GetError().AsCString();
1124 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001125
1126 if (err_cstr)
1127 {
Greg Clayton7c8a9662010-11-02 01:50:16 +00001128 s.Printf (" error: %s\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00001129 }
1130 else
1131 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001132 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001133 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001134 {
Jim Ingham6035b672011-03-31 00:19:25 +00001135 const char *sum_cstr = valobj->GetSummaryAsCString();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001136
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001137 if (val_cstr)
1138 s.Printf(" %s", val_cstr);
1139
1140 if (sum_cstr)
1141 s.Printf(" %s", sum_cstr);
1142
1143 if (use_objc)
1144 {
Jim Ingham6035b672011-03-31 00:19:25 +00001145 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001146 if (object_desc)
1147 s.Printf(" %s\n", object_desc);
1148 else
Sean Callanan672ad942010-10-23 00:18:49 +00001149 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001150 return;
1151 }
1152 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001153
1154 if (curr_depth < max_depth)
1155 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001156 // We will show children for all concrete types. We won't show
1157 // pointer contents unless a pointer depth has been specified.
1158 // We won't reference contents unless the reference is the
1159 // root object (depth of zero).
1160 bool print_children = true;
1161
1162 // Use a new temporary pointer depth in case we override the
1163 // current pointer depth below...
1164 uint32_t curr_ptr_depth = ptr_depth;
1165
1166 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
1167 if (is_ptr || is_ref)
1168 {
1169 // We have a pointer or reference whose value is an address.
1170 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00001171 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00001172 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
1173 print_children = false;
1174
1175 else if (is_ref && curr_depth == 0)
1176 {
1177 // If this is the root object (depth is zero) that we are showing
1178 // and it is a reference, and no pointer depth has been supplied
1179 // print out what it references. Don't do this at deeper depths
1180 // otherwise we can end up with infinite recursion...
1181 curr_ptr_depth = 1;
1182 }
1183
1184 if (curr_ptr_depth == 0)
1185 print_children = false;
1186 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001187
Greg Clayton73b472d2010-10-27 03:32:59 +00001188 if (print_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001189 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001190 const uint32_t num_children = valobj->GetNumChildren();
1191 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001192 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001193 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001194 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001195 if (print_valobj)
1196 s.EOL();
1197 }
1198 else
1199 {
1200 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00001201 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001202 s.IndentMore();
1203 }
1204
1205 for (uint32_t idx=0; idx<num_children; ++idx)
1206 {
1207 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
1208 if (child_sp.get())
1209 {
1210 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001211 child_sp.get(),
1212 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00001213 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001214 curr_depth + 1,
1215 max_depth,
1216 show_types,
1217 show_location,
1218 false,
1219 true,
1220 flat_output);
1221 }
1222 }
1223
1224 if (!flat_output)
1225 {
1226 s.IndentLess();
1227 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001228 }
1229 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001230 else if (has_children)
1231 {
1232 // Aggregate, no children...
1233 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00001234 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001235 }
1236 else
1237 {
1238 if (print_valobj)
1239 s.EOL();
1240 }
1241
Greg Clayton1d3afba2010-10-05 00:00:42 +00001242 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001243 else
1244 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00001245 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001246 }
1247 }
1248 else
1249 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001250 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001251 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001252 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001253 }
1254 }
1255 }
1256 }
1257}
1258
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001259
1260ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00001261ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001262{
1263 ValueObjectSP valobj_sp;
1264
Jim Ingham6035b672011-03-31 00:19:25 +00001265 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001266 {
Jim Ingham6035b672011-03-31 00:19:25 +00001267 ExecutionContextScope *exe_scope = GetExecutionContextScope();
1268 if (exe_scope)
1269 {
1270 ExecutionContext exe_ctx;
1271 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001272
Jim Ingham6035b672011-03-31 00:19:25 +00001273 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001274
Jim Ingham6035b672011-03-31 00:19:25 +00001275 DataExtractor data;
1276 data.SetByteOrder (m_data.GetByteOrder());
1277 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001278
Jim Ingham6035b672011-03-31 00:19:25 +00001279 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001280
Jim Ingham6035b672011-03-31 00:19:25 +00001281 valobj_sp.reset (new ValueObjectConstResult (exe_scope,
1282 ast,
1283 GetClangType(),
1284 name,
1285 data));
1286 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001287 }
Jim Ingham6035b672011-03-31 00:19:25 +00001288
1289 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001290 {
Jim Ingham6035b672011-03-31 00:19:25 +00001291 valobj_sp.reset (new ValueObjectConstResult (NULL, m_error));
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001292 }
1293 return valobj_sp;
1294}
1295
1296lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00001297ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001298{
1299 lldb::ValueObjectSP valobj_sp;
Greg Clayton54979cd2010-12-15 05:08:08 +00001300 const bool is_pointer_type = IsPointerType();
1301 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001302 {
1303 bool omit_empty_base_classes = true;
1304
1305 std::string child_name_str;
1306 uint32_t child_byte_size = 0;
1307 int32_t child_byte_offset = 0;
1308 uint32_t child_bitfield_bit_size = 0;
1309 uint32_t child_bitfield_bit_offset = 0;
1310 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00001311 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001312 const bool transparent_pointers = false;
1313 clang::ASTContext *clang_ast = GetClangAST();
1314 clang_type_t clang_type = GetClangType();
1315 clang_type_t child_clang_type;
1316 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast,
1317 GetName().GetCString(),
1318 clang_type,
1319 0,
1320 transparent_pointers,
1321 omit_empty_base_classes,
1322 child_name_str,
1323 child_byte_size,
1324 child_byte_offset,
1325 child_bitfield_bit_size,
1326 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00001327 child_is_base_class,
1328 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00001329 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001330 {
1331 ConstString child_name;
1332 if (!child_name_str.empty())
1333 child_name.SetCString (child_name_str.c_str());
1334
Jim Ingham6035b672011-03-31 00:19:25 +00001335 valobj_sp.reset (new ValueObjectChild (*this,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001336 clang_ast,
1337 child_clang_type,
1338 child_name,
1339 child_byte_size,
1340 child_byte_offset,
1341 child_bitfield_bit_size,
1342 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00001343 child_is_base_class,
1344 child_is_deref_of_parent));
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001345 }
1346 }
Greg Clayton54979cd2010-12-15 05:08:08 +00001347
1348 if (valobj_sp)
1349 {
1350 error.Clear();
1351 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001352 else
1353 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001354 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001355 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001356
1357 if (is_pointer_type)
1358 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
1359 else
1360 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001361 }
1362
1363 return valobj_sp;
1364}
1365
Greg Clayton54979cd2010-12-15 05:08:08 +00001366 lldb::ValueObjectSP
1367ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001368{
1369 lldb::ValueObjectSP valobj_sp;
Greg Claytone0d378b2011-03-24 21:19:54 +00001370 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001371 const bool scalar_is_load_address = false;
1372 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00001373 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001374 if (addr != LLDB_INVALID_ADDRESS)
1375 {
1376 switch (address_type)
1377 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001378 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001379 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00001380 {
1381 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001382 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001383 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
1384 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001385 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00001386
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001387 case eAddressTypeFile:
1388 case eAddressTypeLoad:
1389 case eAddressTypeHost:
1390 {
1391 clang::ASTContext *ast = GetClangAST();
1392 clang_type_t clang_type = GetClangType();
1393 if (ast && clang_type)
1394 {
1395 std::string name (1, '&');
1396 name.append (m_name.AsCString(""));
Jim Ingham6035b672011-03-31 00:19:25 +00001397 valobj_sp.reset (new ValueObjectConstResult (GetExecutionContextScope(),
1398 ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001399 ClangASTContext::CreatePointerType (ast, clang_type),
1400 ConstString (name.c_str()),
1401 addr,
Sean Callanan92adcac2011-01-13 08:53:35 +00001402 eAddressTypeInvalid,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001403 m_data.GetAddressByteSize()));
1404 }
1405 }
1406 break;
1407 }
1408 }
1409 return valobj_sp;
1410}
1411
Jim Ingham6035b672011-03-31 00:19:25 +00001412ValueObject::EvaluationPoint::EvaluationPoint () :
1413 m_stop_id (0),
1414 m_thread_id (LLDB_INVALID_UID)
1415{
1416}
1417
1418ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
1419 m_stop_id (0),
1420 m_thread_id (LLDB_INVALID_UID),
1421 m_needs_update (true),
1422 m_first_update (true)
1423{
1424 ExecutionContext exe_ctx;
1425 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
1426 // and if so we want to cache that not the original.
1427 if (exe_scope)
1428 exe_scope->CalculateExecutionContext(exe_ctx);
1429 if (exe_ctx.target != NULL)
1430 {
1431 m_target_sp = exe_ctx.target->GetSP();
1432
1433 if (exe_ctx.process == NULL)
1434 m_process_sp = exe_ctx.target->GetProcessSP();
1435 else
1436 m_process_sp = exe_ctx.process->GetSP();
1437
1438 if (m_process_sp != NULL)
1439 {
1440 m_stop_id = m_process_sp->GetStopID();
1441 Thread *thread = NULL;
1442
1443 if (exe_ctx.thread == NULL)
1444 {
1445 if (use_selected)
1446 {
1447 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
1448 if (thread)
1449 computed_exe_scope = thread;
1450 }
1451 }
1452 else
1453 thread = exe_ctx.thread;
1454
1455 if (thread != NULL)
1456 {
1457 m_thread_id = thread->GetIndexID();
1458 if (exe_ctx.frame == NULL)
1459 {
1460 if (use_selected)
1461 {
1462 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
1463 if (frame)
1464 {
1465 m_stack_id = frame->GetStackID();
1466 computed_exe_scope = frame;
1467 }
1468 }
1469 }
1470 else
1471 m_stack_id = exe_ctx.frame->GetStackID();
1472 }
1473 }
1474 }
1475 m_exe_scope = computed_exe_scope;
1476}
1477
1478ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
1479 m_exe_scope (rhs.m_exe_scope),
1480 m_target_sp (rhs.m_target_sp),
1481 m_process_sp (rhs.m_process_sp),
1482 m_thread_id (rhs.m_thread_id),
1483 m_stack_id (rhs.m_stack_id),
1484 m_needs_update(true),
1485 m_first_update(true),
1486 m_stop_id (0)
1487{
1488}
1489
1490ValueObject::EvaluationPoint::~EvaluationPoint ()
1491{
1492}
1493
1494ExecutionContextScope *
1495ValueObject::EvaluationPoint::GetExecutionContextScope ()
1496{
1497 // We have to update before giving out the scope, or we could be handing out stale pointers.
1498 SyncWithProcessState();
1499
1500 return m_exe_scope;
1501}
1502
1503// This function checks the EvaluationPoint against the current process state. If the current
1504// state matches the evaluation point, or the evaluation point is already invalid, then we return
1505// false, meaning "no change". If the current state is different, we update our state, and return
1506// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
1507// future calls to NeedsUpdate will return true.
1508
1509bool
1510ValueObject::EvaluationPoint::SyncWithProcessState()
1511{
1512 // If we're already invalid, we don't need to do anything, and nothing has changed:
1513 if (m_stop_id == LLDB_INVALID_UID)
1514 {
1515 // Can't update with an invalid state.
1516 m_needs_update = false;
1517 return false;
1518 }
1519
1520 // If we don't have a process nothing can change.
1521 if (!m_process_sp)
1522 return false;
1523
1524 // If our stop id is the current stop ID, nothing has changed:
1525 if (m_stop_id == m_process_sp->GetStopID())
1526 return false;
1527
1528 m_stop_id = m_process_sp->GetStopID();
1529 m_needs_update = true;
1530 m_exe_scope = m_process_sp.get();
1531
1532 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
1533 // doesn't, mark ourselves as invalid.
1534
1535 if (m_thread_id != LLDB_INVALID_THREAD_ID)
1536 {
1537 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
1538 if (our_thread == NULL)
1539 SetInvalid();
1540 else
1541 {
1542 m_exe_scope = our_thread;
1543
1544 if (m_stack_id.IsValid())
1545 {
1546 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
1547 if (our_frame == NULL)
1548 SetInvalid();
1549 else
1550 m_exe_scope = our_frame;
1551 }
1552 }
1553 }
1554 return true;
1555}
1556
1557bool
1558ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
1559{
1560 if (!IsValid())
1561 return false;
1562
1563 bool needs_update = false;
1564 m_exe_scope = NULL;
1565
1566 // The target has to be non-null, and the
1567 Target *target = exe_scope->CalculateTarget();
1568 if (target != NULL)
1569 {
1570 Target *old_target = m_target_sp.get();
1571 assert (target == old_target);
1572 Process *process = exe_scope->CalculateProcess();
1573 if (process != NULL)
1574 {
1575 // FOR NOW - assume you can't update variable objects across process boundaries.
1576 Process *old_process = m_process_sp.get();
1577 assert (process == old_process);
1578
1579 lldb::user_id_t stop_id = process->GetStopID();
1580 if (stop_id != m_stop_id)
1581 {
1582 needs_update = true;
1583 m_stop_id = stop_id;
1584 }
1585 // See if we're switching the thread or stack context. If no thread is given, this is
1586 // being evaluated in a global context.
1587 Thread *thread = exe_scope->CalculateThread();
1588 if (thread != NULL)
1589 {
1590 lldb::user_id_t new_thread_index = thread->GetIndexID();
1591 if (new_thread_index != m_thread_id)
1592 {
1593 needs_update = true;
1594 m_thread_id = new_thread_index;
1595 m_stack_id.Clear();
1596 }
1597
1598 StackFrame *new_frame = exe_scope->CalculateStackFrame();
1599 if (new_frame != NULL)
1600 {
1601 if (new_frame->GetStackID() != m_stack_id)
1602 {
1603 needs_update = true;
1604 m_stack_id = new_frame->GetStackID();
1605 }
1606 }
1607 else
1608 {
1609 m_stack_id.Clear();
1610 needs_update = true;
1611 }
1612 }
1613 else
1614 {
1615 // If this had been given a thread, and now there is none, we should update.
1616 // Otherwise we don't have to do anything.
1617 if (m_thread_id != LLDB_INVALID_UID)
1618 {
1619 m_thread_id = LLDB_INVALID_UID;
1620 m_stack_id.Clear();
1621 needs_update = true;
1622 }
1623 }
1624 }
1625 else
1626 {
1627 // If there is no process, then we don't need to update anything.
1628 // But if we're switching from having a process to not, we should try to update.
1629 if (m_process_sp.get() != NULL)
1630 {
1631 needs_update = true;
1632 m_process_sp.reset();
1633 m_thread_id = LLDB_INVALID_UID;
1634 m_stack_id.Clear();
1635 }
1636 }
1637 }
1638 else
1639 {
1640 // If there's no target, nothing can change so we don't need to update anything.
1641 // But if we're switching from having a target to not, we should try to update.
1642 if (m_target_sp.get() != NULL)
1643 {
1644 needs_update = true;
1645 m_target_sp.reset();
1646 m_process_sp.reset();
1647 m_thread_id = LLDB_INVALID_UID;
1648 m_stack_id.Clear();
1649 }
1650 }
1651 if (!m_needs_update)
1652 m_needs_update = needs_update;
1653
1654 return needs_update;
1655}