blob: e0816309708d899b878d4e09576e40fc287e99c4 [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"
Enrico Granata4becb372011-06-29 22:27:15 +000022#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/StreamString.h"
24#include "lldb/Core/ValueObjectChild.h"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000025#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000026#include "lldb/Core/ValueObjectDynamicValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/ValueObjectList.h"
Greg Claytonb2dcc362011-05-05 23:32:56 +000028#include "lldb/Core/ValueObjectMemory.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029
Greg Clayton7fb56d02011-02-01 01:31:41 +000030#include "lldb/Host/Endian.h"
31
Greg Claytone1a916a2010-07-21 22:12:05 +000032#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Symbol/ClangASTContext.h"
34#include "lldb/Symbol/Type.h"
35
Jim Ingham53c47f12010-09-10 23:12:17 +000036#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000037#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038#include "lldb/Target/Process.h"
39#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000040#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042
43using namespace lldb;
44using namespace lldb_private;
45
46static lldb::user_id_t g_value_obj_uid = 0;
47
48//----------------------------------------------------------------------
49// ValueObject constructor
50//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000051ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000053 m_parent (&parent),
Stephen Wilson71c21d12011-04-11 19:41:40 +000054 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055 m_name (),
56 m_data (),
57 m_value (),
58 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000059 m_value_str (),
60 m_old_value_str (),
61 m_location_str (),
62 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000063 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000064 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000065 m_children (),
66 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000067 m_dynamic_value (NULL),
68 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000069 m_format (eFormatDefault),
Greg Clayton288bdf92010-09-02 02:59:18 +000070 m_value_is_valid (false),
71 m_value_did_change (false),
72 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000073 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000074 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +000075 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +000076 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +000077 m_is_bitfield_for_scalar(false),
Enrico Granata4becb372011-06-29 22:27:15 +000078 m_last_format_mgr_revision(0),
79 m_last_summary_format(),
80 m_last_value_format()
Jim Ingham6035b672011-03-31 00:19:25 +000081{
Jim Ingham58b59f92011-04-22 23:53:53 +000082 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +000083}
84
85//----------------------------------------------------------------------
86// ValueObject constructor
87//----------------------------------------------------------------------
88ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
89 UserID (++g_value_obj_uid), // Unique identifier for every value object
90 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +000091 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +000092 m_name (),
93 m_data (),
94 m_value (),
95 m_error (),
96 m_value_str (),
97 m_old_value_str (),
98 m_location_str (),
99 m_summary_str (),
100 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000101 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +0000102 m_children (),
103 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000104 m_dynamic_value (NULL),
105 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +0000106 m_format (eFormatDefault),
107 m_value_is_valid (false),
108 m_value_did_change (false),
109 m_children_count_valid (false),
110 m_old_value_valid (false),
111 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +0000112 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +0000113 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +0000114 m_is_bitfield_for_scalar(false),
Enrico Granata4becb372011-06-29 22:27:15 +0000115 m_last_format_mgr_revision(0),
116 m_last_summary_format(),
117 m_last_value_format()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118{
Jim Ingham58b59f92011-04-22 23:53:53 +0000119 m_manager = new ValueObjectManager();
120 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121}
122
123//----------------------------------------------------------------------
124// Destructor
125//----------------------------------------------------------------------
126ValueObject::~ValueObject ()
127{
128}
129
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130bool
Enrico Granata0a3958e2011-07-02 00:25:22 +0000131ValueObject::UpdateValueIfNeeded (bool update_format)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132{
Enrico Granata4becb372011-06-29 22:27:15 +0000133
Enrico Granata0a3958e2011-07-02 00:25:22 +0000134 if (update_format)
135 UpdateFormatsIfNeeded();
Enrico Granata4becb372011-06-29 22:27:15 +0000136
Greg Claytonb71f3842010-10-05 03:13:51 +0000137 // If this is a constant value, then our success is predicated on whether
138 // we have an error or not
139 if (GetIsConstant())
140 return m_error.Success();
141
Jim Ingham6035b672011-03-31 00:19:25 +0000142 bool first_update = m_update_point.IsFirstEvaluation();
143
144 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145 {
Jim Ingham6035b672011-03-31 00:19:25 +0000146 m_update_point.SetUpdated();
147
148 // Save the old value using swap to avoid a string copy which
149 // also will clear our m_value_str
150 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151 {
Jim Ingham6035b672011-03-31 00:19:25 +0000152 m_old_value_valid = false;
153 }
154 else
155 {
156 m_old_value_valid = true;
157 m_old_value_str.swap (m_value_str);
158 m_value_str.clear();
159 }
160 m_location_str.clear();
161 m_summary_str.clear();
162 m_object_desc_str.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163
Jim Ingham6035b672011-03-31 00:19:25 +0000164 const bool value_was_valid = GetValueIsValid();
165 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000166
Jim Ingham6035b672011-03-31 00:19:25 +0000167 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000168
Jim Ingham6035b672011-03-31 00:19:25 +0000169 // Call the pure virtual function to update the value
170 bool success = UpdateValue ();
171
172 SetValueIsValid (success);
173
174 if (first_update)
175 SetValueDidChange (false);
176 else if (!m_value_did_change && success == false)
177 {
178 // The value wasn't gotten successfully, so we mark this
179 // as changed if the value used to be valid and now isn't
180 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181 }
182 }
183 return m_error.Success();
184}
185
Enrico Granata4becb372011-06-29 22:27:15 +0000186void
187ValueObject::UpdateFormatsIfNeeded()
188{
189 /*printf("CHECKING FOR UPDATES. I am at revision %d, while the format manager is at revision %d\n",
190 m_last_format_mgr_revision,
191 Debugger::ValueFormats::GetCurrentRevision());*/
192 if (m_last_format_mgr_revision != Debugger::ValueFormats::GetCurrentRevision())
193 {
194 if (m_last_summary_format.get())
195 m_last_summary_format.reset((SummaryFormat*)NULL);
196 if (m_last_value_format.get())
197 m_last_value_format.reset((ValueFormat*)NULL);
198 Debugger::ValueFormats::Get(*this, m_last_value_format);
Enrico Granata0a3958e2011-07-02 00:25:22 +0000199 if (!Debugger::SummaryFormats::Get(*this, m_last_summary_format))
200 Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format);
Enrico Granata4becb372011-06-29 22:27:15 +0000201 m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision();
202 m_value_str.clear();
203 m_summary_str.clear();
204 }
205}
206
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207DataExtractor &
208ValueObject::GetDataExtractor ()
209{
Jim Ingham78a685a2011-04-16 00:01:13 +0000210 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211 return m_data;
212}
213
214const Error &
215ValueObject::GetError() const
216{
217 return m_error;
218}
219
220const ConstString &
221ValueObject::GetName() const
222{
223 return m_name;
224}
225
226const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000227ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228{
Jim Ingham6035b672011-03-31 00:19:25 +0000229 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000230 {
231 if (m_location_str.empty())
232 {
233 StreamString sstr;
234
235 switch (m_value.GetValueType())
236 {
237 default:
238 break;
239
240 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000241 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242 {
243 RegisterInfo *reg_info = m_value.GetRegisterInfo();
244 if (reg_info)
245 {
246 if (reg_info->name)
247 m_location_str = reg_info->name;
248 else if (reg_info->alt_name)
249 m_location_str = reg_info->alt_name;
250 break;
251 }
252 }
253 m_location_str = "scalar";
254 break;
255
256 case Value::eValueTypeLoadAddress:
257 case Value::eValueTypeFileAddress:
258 case Value::eValueTypeHostAddress:
259 {
260 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
261 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
262 m_location_str.swap(sstr.GetString());
263 }
264 break;
265 }
266 }
267 }
268 return m_location_str.c_str();
269}
270
271Value &
272ValueObject::GetValue()
273{
274 return m_value;
275}
276
277const Value &
278ValueObject::GetValue() const
279{
280 return m_value;
281}
282
283bool
Jim Ingham6035b672011-03-31 00:19:25 +0000284ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000285{
286 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000287 ExecutionContextScope *exe_scope = GetExecutionContextScope();
288 if (exe_scope)
289 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000290 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
291 return scalar.IsValid();
292}
293
294bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000295ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296{
Greg Clayton288bdf92010-09-02 02:59:18 +0000297 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298}
299
300
301void
302ValueObject::SetValueIsValid (bool b)
303{
Greg Clayton288bdf92010-09-02 02:59:18 +0000304 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000305}
306
307bool
Jim Ingham6035b672011-03-31 00:19:25 +0000308ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000309{
Jim Ingham6035b672011-03-31 00:19:25 +0000310 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000311 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312}
313
314void
315ValueObject::SetValueDidChange (bool value_changed)
316{
Greg Clayton288bdf92010-09-02 02:59:18 +0000317 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318}
319
320ValueObjectSP
321ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
322{
323 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000324 // We may need to update our value if we are dynamic
325 if (IsPossibleDynamicType ())
326 UpdateValueIfNeeded();
327 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000329 // Check if we have already made the child value object?
330 if (can_create && m_children[idx] == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000332 // No we haven't created the child at this index, so lets have our
333 // subclass do it and cache the result for quick future access.
334 m_children[idx] = CreateChildAtIndex (idx, false, 0);
Jim Ingham78a685a2011-04-16 00:01:13 +0000335 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000336
337 if (m_children[idx] != NULL)
338 return m_children[idx]->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339 }
340 return child_sp;
341}
342
343uint32_t
344ValueObject::GetIndexOfChildWithName (const ConstString &name)
345{
346 bool omit_empty_base_classes = true;
347 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000348 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000349 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350 omit_empty_base_classes);
351}
352
353ValueObjectSP
354ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
355{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000356 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357 // classes (which really aren't part of the expression path), so we
358 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000360
Greg Claytondea8cb42011-06-29 22:09:02 +0000361 // We may need to update our value if we are dynamic
362 if (IsPossibleDynamicType ())
363 UpdateValueIfNeeded();
364
365 std::vector<uint32_t> child_indexes;
366 clang::ASTContext *clang_ast = GetClangAST();
367 void *clang_type = GetClangType();
368 bool omit_empty_base_classes = true;
369 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
370 clang_type,
371 name.GetCString(),
372 omit_empty_base_classes,
373 child_indexes);
374 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000376 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
377 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
378
379 child_sp = GetChildAtIndex(*pos, can_create);
380 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000382 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000383 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000384 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
385 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000386 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000387 else
388 {
389 child_sp.reset();
390 }
391
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392 }
393 }
394 return child_sp;
395}
396
397
398uint32_t
399ValueObject::GetNumChildren ()
400{
Greg Clayton288bdf92010-09-02 02:59:18 +0000401 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402 {
403 SetNumChildren (CalculateNumChildren());
404 }
405 return m_children.size();
406}
407void
408ValueObject::SetNumChildren (uint32_t num_children)
409{
Greg Clayton288bdf92010-09-02 02:59:18 +0000410 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411 m_children.resize(num_children);
412}
413
414void
415ValueObject::SetName (const char *name)
416{
417 m_name.SetCString(name);
418}
419
420void
421ValueObject::SetName (const ConstString &name)
422{
423 m_name = name;
424}
425
Jim Ingham58b59f92011-04-22 23:53:53 +0000426ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
428{
Jim Ingham2eec4872011-05-07 00:10:58 +0000429 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000430
Greg Claytondea8cb42011-06-29 22:09:02 +0000431 bool omit_empty_base_classes = true;
432
433 std::string child_name_str;
434 uint32_t child_byte_size = 0;
435 int32_t child_byte_offset = 0;
436 uint32_t child_bitfield_bit_size = 0;
437 uint32_t child_bitfield_bit_offset = 0;
438 bool child_is_base_class = false;
439 bool child_is_deref_of_parent = false;
440
441 const bool transparent_pointers = synthetic_array_member == false;
442 clang::ASTContext *clang_ast = GetClangAST();
443 clang_type_t clang_type = GetClangType();
444 clang_type_t child_clang_type;
445
446 ExecutionContext exe_ctx;
447 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
448
449 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
450 clang_ast,
451 GetName().GetCString(),
452 clang_type,
453 idx,
454 transparent_pointers,
455 omit_empty_base_classes,
456 child_name_str,
457 child_byte_size,
458 child_byte_offset,
459 child_bitfield_bit_size,
460 child_bitfield_bit_offset,
461 child_is_base_class,
462 child_is_deref_of_parent);
463 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000465 if (synthetic_index)
466 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467
Greg Claytondea8cb42011-06-29 22:09:02 +0000468 ConstString child_name;
469 if (!child_name_str.empty())
470 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000471
Greg Claytondea8cb42011-06-29 22:09:02 +0000472 valobj = new ValueObjectChild (*this,
473 clang_ast,
474 child_clang_type,
475 child_name,
476 child_byte_size,
477 child_byte_offset,
478 child_bitfield_bit_size,
479 child_bitfield_bit_offset,
480 child_is_base_class,
481 child_is_deref_of_parent);
482 if (m_pointers_point_to_load_addrs)
483 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000485
Jim Ingham58b59f92011-04-22 23:53:53 +0000486 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487}
488
489const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000490ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491{
Jim Ingham6035b672011-03-31 00:19:25 +0000492 if (UpdateValueIfNeeded ())
Enrico Granata4becb372011-06-29 22:27:15 +0000493 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494 if (m_summary_str.empty())
495 {
Enrico Granata4becb372011-06-29 22:27:15 +0000496 if (m_last_summary_format.get())
497 {
498 StreamString s;
499 ExecutionContext exe_ctx;
500 this->GetExecutionContextScope()->CalculateExecutionContext(exe_ctx);
501 SymbolContext sc = exe_ctx.frame->GetSymbolContext(eSymbolContextEverything);
Enrico Granata0a3958e2011-07-02 00:25:22 +0000502
503 if (m_last_summary_format->m_show_members_oneliner)
Enrico Granata4becb372011-06-29 22:27:15 +0000504 {
Enrico Granata0a3958e2011-07-02 00:25:22 +0000505 const uint32_t num_children = GetNumChildren();
506 if (num_children)
507 {
508
509 s.PutChar('(');
510
511 for (uint32_t idx=0; idx<num_children; ++idx)
512 {
513 ValueObjectSP child_sp(GetChildAtIndex(idx, true));
514 if (child_sp.get())
515 {
516 if (idx)
517 s.PutCString(", ");
518 s.PutCString(child_sp.get()->GetName().AsCString());
519 s.PutChar('=');
Enrico Granata9fc19442011-07-06 02:13:41 +0000520 s.PutCString(child_sp.get()->GetPrintableRepresentation());
Enrico Granata0a3958e2011-07-02 00:25:22 +0000521 }
522 }
523
524 s.PutChar(')');
525
526 m_summary_str.swap(s.GetString());
527 return m_summary_str.c_str();
528 }
529 else
530 return "()";
531
Enrico Granata4becb372011-06-29 22:27:15 +0000532 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000533 else
534 {
535 if (Debugger::FormatPrompt(m_last_summary_format->m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, this))
536 {
537 m_summary_str.swap(s.GetString());
538 return m_summary_str.c_str();
539 }
540 else
541 return NULL;
542 }
Enrico Granata4becb372011-06-29 22:27:15 +0000543 }
544
Greg Clayton73b472d2010-10-27 03:32:59 +0000545 clang_type_t clang_type = GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000546
547 // See if this is a pointer to a C string?
Greg Clayton737b9322010-09-13 03:32:57 +0000548 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000549 {
Greg Clayton737b9322010-09-13 03:32:57 +0000550 StreamString sstr;
Greg Clayton73b472d2010-10-27 03:32:59 +0000551 clang_type_t elem_or_pointee_clang_type;
552 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000553 GetClangAST(),
554 &elem_or_pointee_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +0000555
Jim Ingham6035b672011-03-31 00:19:25 +0000556 ExecutionContextScope *exe_scope = GetExecutionContextScope();
557 if (exe_scope)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000558 {
Jim Ingham6035b672011-03-31 00:19:25 +0000559 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
560 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000561 {
Jim Ingham6035b672011-03-31 00:19:25 +0000562 Process *process = exe_scope->CalculateProcess();
563 if (process != NULL)
564 {
565 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
566 AddressType cstr_address_type = eAddressTypeInvalid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000567
Jim Ingham6035b672011-03-31 00:19:25 +0000568 size_t cstr_len = 0;
569 if (type_flags.Test (ClangASTContext::eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000570 {
Jim Ingham6035b672011-03-31 00:19:25 +0000571 // We have an array
572 cstr_len = ClangASTContext::GetArraySize (clang_type);
573 cstr_address = GetAddressOf (cstr_address_type, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574 }
Greg Clayton737b9322010-09-13 03:32:57 +0000575 else
576 {
Jim Ingham6035b672011-03-31 00:19:25 +0000577 // We have a pointer
578 cstr_address = GetPointerValue (cstr_address_type, true);
Greg Clayton737b9322010-09-13 03:32:57 +0000579 }
Jim Ingham6035b672011-03-31 00:19:25 +0000580 if (cstr_address != LLDB_INVALID_ADDRESS)
Greg Clayton737b9322010-09-13 03:32:57 +0000581 {
Jim Ingham6035b672011-03-31 00:19:25 +0000582 DataExtractor data;
583 size_t bytes_read = 0;
584 std::vector<char> data_buffer;
585 Error error;
586 if (cstr_len > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000587 {
Jim Ingham6035b672011-03-31 00:19:25 +0000588 data_buffer.resize(cstr_len);
589 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
590 bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error);
591 if (bytes_read > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000592 {
Jim Ingham6035b672011-03-31 00:19:25 +0000593 sstr << '"';
594 data.Dump (&sstr,
595 0, // Start offset in "data"
Greg Clayton4e4294b2011-06-17 23:50:44 +0000596 eFormatCharArray, // Print as characters
Jim Ingham6035b672011-03-31 00:19:25 +0000597 1, // Size of item (1 byte for a char!)
598 bytes_read, // How many bytes to print?
599 UINT32_MAX, // num per line
600 LLDB_INVALID_ADDRESS,// base address
601 0, // bitfield bit size
602 0); // bitfield bit offset
603 sstr << '"';
Greg Clayton737b9322010-09-13 03:32:57 +0000604 }
605 }
Jim Ingham6035b672011-03-31 00:19:25 +0000606 else
607 {
608 const size_t k_max_buf_size = 256;
609 data_buffer.resize (k_max_buf_size + 1);
610 // NULL terminate in case we don't get the entire C string
611 data_buffer.back() = '\0';
Greg Clayton737b9322010-09-13 03:32:57 +0000612
Jim Ingham6035b672011-03-31 00:19:25 +0000613 sstr << '"';
614
615 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
616 while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0)
617 {
618 size_t len = strlen(&data_buffer.front());
619 if (len == 0)
620 break;
621 if (len > bytes_read)
622 len = bytes_read;
623
624 data.Dump (&sstr,
625 0, // Start offset in "data"
Greg Clayton4e4294b2011-06-17 23:50:44 +0000626 eFormatCharArray, // Print as characters
Jim Ingham6035b672011-03-31 00:19:25 +0000627 1, // Size of item (1 byte for a char!)
628 len, // How many bytes to print?
629 UINT32_MAX, // num per line
630 LLDB_INVALID_ADDRESS,// base address
631 0, // bitfield bit size
632 0); // bitfield bit offset
633
634 if (len < k_max_buf_size)
635 break;
636 cstr_address += k_max_buf_size;
637 }
638 sstr << '"';
639 }
640 }
Greg Clayton737b9322010-09-13 03:32:57 +0000641 }
Jim Ingham6035b672011-03-31 00:19:25 +0000642
643 if (sstr.GetSize() > 0)
644 m_summary_str.assign (sstr.GetData(), sstr.GetSize());
Greg Clayton737b9322010-09-13 03:32:57 +0000645 }
Jim Ingham6035b672011-03-31 00:19:25 +0000646 else if (ClangASTContext::IsFunctionPointerType (clang_type))
Greg Clayton737b9322010-09-13 03:32:57 +0000647 {
Jim Ingham6035b672011-03-31 00:19:25 +0000648 AddressType func_ptr_address_type = eAddressTypeInvalid;
649 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
650
651 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
652 {
653 switch (func_ptr_address_type)
654 {
655 case eAddressTypeInvalid:
656 case eAddressTypeFile:
657 break;
658
659 case eAddressTypeLoad:
660 {
661 Address so_addr;
662 Target *target = exe_scope->CalculateTarget();
663 if (target && target->GetSectionLoadList().IsEmpty() == false)
664 {
665 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
666 {
667 so_addr.Dump (&sstr,
668 exe_scope,
669 Address::DumpStyleResolvedDescription,
670 Address::DumpStyleSectionNameOffset);
671 }
672 }
673 }
674 break;
675
676 case eAddressTypeHost:
677 break;
678 }
679 }
680 if (sstr.GetSize() > 0)
681 {
682 m_summary_str.assign (1, '(');
683 m_summary_str.append (sstr.GetData(), sstr.GetSize());
684 m_summary_str.append (1, ')');
685 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000686 }
687 }
688 }
689 }
690 }
691 if (m_summary_str.empty())
692 return NULL;
693 return m_summary_str.c_str();
694}
695
Jim Ingham53c47f12010-09-10 23:12:17 +0000696const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000697ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000698{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000699
Jim Ingham6035b672011-03-31 00:19:25 +0000700 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000701 return NULL;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000702
703 if (!m_object_desc_str.empty())
704 return m_object_desc_str.c_str();
705
Jim Ingham6035b672011-03-31 00:19:25 +0000706 ExecutionContextScope *exe_scope = GetExecutionContextScope();
707 if (exe_scope == NULL)
708 return NULL;
709
Jim Ingham53c47f12010-09-10 23:12:17 +0000710 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000711 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000712 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000713
Jim Ingham53c47f12010-09-10 23:12:17 +0000714 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000715
716 lldb::LanguageType language = GetObjectRuntimeLanguage();
717 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
718
Jim Inghama2cf2632010-12-23 02:29:54 +0000719 if (runtime == NULL)
720 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000721 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000722 clang_type_t opaque_qual_type = GetClangType();
723 if (opaque_qual_type != NULL)
724 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000725 bool is_signed;
726 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
727 || ClangASTContext::IsPointerType (opaque_qual_type))
728 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000729 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000730 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000731 }
732 }
733
Jim Ingham8d543de2011-03-31 23:01:21 +0000734 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000735 {
736 m_object_desc_str.append (s.GetData());
737 }
Sean Callanan672ad942010-10-23 00:18:49 +0000738
739 if (m_object_desc_str.empty())
740 return NULL;
741 else
742 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000743}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000744
745const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000746ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000747{
748 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000749 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000750 {
Jim Ingham6035b672011-03-31 00:19:25 +0000751 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000752 {
753 if (m_value_str.empty())
754 {
755 const Value::ContextType context_type = m_value.GetContextType();
756
757 switch (context_type)
758 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000759 case Value::eContextTypeClangType:
760 case Value::eContextTypeLLDBType:
761 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000762 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000763 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000764 if (clang_type)
765 {
766 StreamString sstr;
Greg Clayton68ebae62011-04-28 20:55:26 +0000767 Format format = GetFormat();
Enrico Granata4becb372011-06-29 22:27:15 +0000768 if (format == eFormatDefault)
769 {
770 if (m_last_value_format)
771 format = m_last_value_format->m_format;
772 else
Enrico Granata9fc19442011-07-06 02:13:41 +0000773 // force the system into using unsigned integers for bitfields
774 format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
775 ClangASTType::GetFormat(clang_type));
Enrico Granata4becb372011-06-29 22:27:15 +0000776 }
Greg Clayton32c40852010-10-06 03:09:11 +0000777
778 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
779 clang_type, // The clang type to display
780 &sstr,
Enrico Granata4becb372011-06-29 22:27:15 +0000781 format, // Format to display this type with
Greg Clayton32c40852010-10-06 03:09:11 +0000782 m_data, // Data to extract from
783 0, // Byte offset into "m_data"
784 GetByteSize(), // Byte size of item in "m_data"
785 GetBitfieldBitSize(), // Bitfield bit size
786 GetBitfieldBitOffset())) // Bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000787 m_value_str.swap(sstr.GetString());
788 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000789 {
790 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
791 m_data.GetByteSize(),
792 GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000793 m_value_str.clear();
Greg Clayton007d5be2011-05-30 00:49:24 +0000794 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000795 }
796 }
797 break;
798
Greg Clayton526e5af2010-11-13 03:52:47 +0000799 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800 {
801 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
802 if (reg_info)
803 {
804 StreamString reg_sstr;
805 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
806 m_value_str.swap(reg_sstr.GetString());
807 }
808 }
809 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000810
811 default:
812 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000813 }
814 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000815
816 if (!m_value_did_change && m_old_value_valid)
817 {
818 // The value was gotten successfully, so we consider the
819 // value as changed if the value string differs
820 SetValueDidChange (m_old_value_str != m_value_str);
821 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000822 }
823 }
824 if (m_value_str.empty())
825 return NULL;
826 return m_value_str.c_str();
827}
828
Enrico Granata0a3958e2011-07-02 00:25:22 +0000829const char *
830ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
831 lldb::Format custom_format)
832{
833 if(custom_format != lldb::eFormatInvalid)
834 SetFormat(custom_format);
835
836 const char * return_value;
837
838 switch(val_obj_display)
839 {
840 case eDisplayValue:
841 return_value = GetValueAsCString();
842 break;
843 case eDisplaySummary:
844 return_value = GetSummaryAsCString();
845 break;
846 case eDisplayLanguageSpecific:
847 return_value = GetObjectDescription();
848 break;
849 }
850
Enrico Granata9fc19442011-07-06 02:13:41 +0000851 if (!return_value)
852 {
853 // try to pick the other choice
854 if (val_obj_display == eDisplayValue)
855 return_value = GetSummaryAsCString();
856 else if (val_obj_display == eDisplaySummary)
857 return_value = GetValueAsCString();
858 else
859 return_value = "";
860 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000861
Enrico Granata9fc19442011-07-06 02:13:41 +0000862 return (return_value ? return_value : "");
Enrico Granata0a3958e2011-07-02 00:25:22 +0000863
864}
865
Enrico Granata9fc19442011-07-06 02:13:41 +0000866bool
867ValueObject::DumpPrintableRepresentation(Stream& s,
868 ValueObjectRepresentationStyle val_obj_display,
869 lldb::Format custom_format)
870{
871 const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
872 if(targetvalue)
873 s.PutCString(targetvalue);
874 bool var_success = (targetvalue != NULL);
875 if(custom_format != eFormatInvalid)
876 SetFormat(eFormatDefault);
877 return var_success;
878}
879
Greg Clayton737b9322010-09-13 03:32:57 +0000880addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000881ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +0000882{
Jim Ingham78a685a2011-04-16 00:01:13 +0000883 if (!UpdateValueIfNeeded())
884 return LLDB_INVALID_ADDRESS;
885
Greg Clayton73b472d2010-10-27 03:32:59 +0000886 switch (m_value.GetValueType())
887 {
888 case Value::eValueTypeScalar:
889 if (scalar_is_load_address)
890 {
891 address_type = eAddressTypeLoad;
892 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
893 }
894 break;
895
896 case Value::eValueTypeLoadAddress:
897 case Value::eValueTypeFileAddress:
898 case Value::eValueTypeHostAddress:
899 {
900 address_type = m_value.GetValueAddressType ();
901 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
902 }
903 break;
904 }
905 address_type = eAddressTypeInvalid;
906 return LLDB_INVALID_ADDRESS;
907}
908
909addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000910ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +0000911{
912 lldb::addr_t address = LLDB_INVALID_ADDRESS;
913 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +0000914
915 if (!UpdateValueIfNeeded())
916 return address;
917
Greg Clayton73b472d2010-10-27 03:32:59 +0000918 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +0000919 {
920 case Value::eValueTypeScalar:
921 if (scalar_is_load_address)
922 {
923 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
924 address_type = eAddressTypeLoad;
925 }
926 break;
927
928 case Value::eValueTypeLoadAddress:
929 case Value::eValueTypeFileAddress:
930 case Value::eValueTypeHostAddress:
931 {
932 uint32_t data_offset = 0;
933 address = m_data.GetPointer(&data_offset);
934 address_type = m_value.GetValueAddressType();
935 if (address_type == eAddressTypeInvalid)
936 address_type = eAddressTypeLoad;
937 }
938 break;
939 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000940
941 if (m_pointers_point_to_load_addrs)
942 address_type = eAddressTypeLoad;
943
Greg Clayton737b9322010-09-13 03:32:57 +0000944 return address;
945}
946
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000947bool
Jim Ingham6035b672011-03-31 00:19:25 +0000948ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000949{
950 // Make sure our value is up to date first so that our location and location
951 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +0000952 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000953 return false;
954
955 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +0000956 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000957
958 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +0000959 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000960 switch (encoding)
961 {
962 case eEncodingInvalid:
963 return false;
964
965 case eEncodingUint:
966 if (byte_size > sizeof(unsigned long long))
967 {
968 return false;
969 }
970 else
971 {
972 unsigned long long ull_val = strtoull(value_str, &end, 0);
973 if (end && *end != '\0')
974 return false;
975 m_value = ull_val;
976 // Limit the bytes in our m_data appropriately.
977 m_value.GetScalar().GetData (m_data, byte_size);
978 }
979 break;
980
981 case eEncodingSint:
982 if (byte_size > sizeof(long long))
983 {
984 return false;
985 }
986 else
987 {
988 long long sll_val = strtoll(value_str, &end, 0);
989 if (end && *end != '\0')
990 return false;
991 m_value = sll_val;
992 // Limit the bytes in our m_data appropriately.
993 m_value.GetScalar().GetData (m_data, byte_size);
994 }
995 break;
996
997 case eEncodingIEEE754:
998 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000999 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +00001000 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001 if (dst != NULL)
1002 {
1003 // We are decoding a float into host byte order below, so make
1004 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +00001005 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001006 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
1007 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +00001008 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009 value_str,
1010 dst,
1011 byte_size);
1012
1013 if (converted_byte_size == byte_size)
1014 {
1015 }
1016 }
1017 }
1018 break;
1019
1020 case eEncodingVector:
1021 return false;
1022
1023 default:
1024 return false;
1025 }
1026
1027 // If we have made it here the value is in m_data and we should write it
1028 // out to the target
1029 return Write ();
1030}
1031
1032bool
1033ValueObject::Write ()
1034{
1035 // Clear the update ID so the next time we try and read the value
1036 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +00001037 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001038
1039 // TODO: when Value has a method to write a value back, call it from here.
1040 return false;
1041
1042}
1043
Jim Ingham5a369122010-09-28 01:25:32 +00001044lldb::LanguageType
1045ValueObject::GetObjectRuntimeLanguage ()
1046{
Greg Clayton73b472d2010-10-27 03:32:59 +00001047 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +00001048 if (opaque_qual_type == NULL)
1049 return lldb::eLanguageTypeC;
1050
1051 // If the type is a reference, then resolve it to what it refers to first:
1052 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
1053 if (qual_type->isAnyPointerType())
1054 {
1055 if (qual_type->isObjCObjectPointerType())
1056 return lldb::eLanguageTypeObjC;
1057
1058 clang::QualType pointee_type (qual_type->getPointeeType());
1059 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
1060 return lldb::eLanguageTypeC_plus_plus;
1061 if (pointee_type->isObjCObjectOrInterfaceType())
1062 return lldb::eLanguageTypeObjC;
1063 if (pointee_type->isObjCClassType())
1064 return lldb::eLanguageTypeObjC;
1065 }
1066 else
1067 {
1068 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
1069 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +00001070 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +00001071 return lldb::eLanguageTypeC_plus_plus;
1072 }
1073
1074 return lldb::eLanguageTypeC;
1075}
1076
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001077void
Jim Ingham58b59f92011-04-22 23:53:53 +00001078ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001079{
Jim Ingham58b59f92011-04-22 23:53:53 +00001080 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081}
1082
1083ValueObjectSP
1084ValueObject::GetSyntheticChild (const ConstString &key) const
1085{
1086 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +00001087 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001088 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +00001089 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001090 return synthetic_child_sp;
1091}
1092
1093bool
1094ValueObject::IsPointerType ()
1095{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001096 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097}
1098
Jim Inghamb7603bb2011-03-18 00:05:18 +00001099bool
Enrico Granata9fc19442011-07-06 02:13:41 +00001100ValueObject::IsScalarType ()
1101{
1102 return ClangASTContext::IsScalarType (GetClangType());
1103}
1104
1105bool
Jim Inghamb7603bb2011-03-18 00:05:18 +00001106ValueObject::IsIntegerType (bool &is_signed)
1107{
1108 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
1109}
Greg Clayton73b472d2010-10-27 03:32:59 +00001110
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001111bool
1112ValueObject::IsPointerOrReferenceType ()
1113{
Greg Clayton007d5be2011-05-30 00:49:24 +00001114 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
1115}
1116
1117bool
1118ValueObject::IsPossibleCPlusPlusDynamicType ()
1119{
1120 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001121}
1122
Greg Claytondea8cb42011-06-29 22:09:02 +00001123bool
1124ValueObject::IsPossibleDynamicType ()
1125{
1126 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
1127}
1128
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129ValueObjectSP
1130ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
1131{
1132 ValueObjectSP synthetic_child_sp;
1133 if (IsPointerType ())
1134 {
1135 char index_str[64];
1136 snprintf(index_str, sizeof(index_str), "[%i]", index);
1137 ConstString index_const_str(index_str);
1138 // Check if we have already created a synthetic array member in this
1139 // valid object. If we have we will re-use it.
1140 synthetic_child_sp = GetSyntheticChild (index_const_str);
1141 if (!synthetic_child_sp)
1142 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001143 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001144 // We haven't made a synthetic array member for INDEX yet, so
1145 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001146 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001147
1148 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001149 if (synthetic_child)
1150 {
1151 AddSyntheticChild(index_const_str, synthetic_child);
1152 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata0a3958e2011-07-02 00:25:22 +00001153 synthetic_child_sp->SetName(index_str);
1154 synthetic_child_sp->m_is_array_item_for_pointer = true;
Jim Ingham58b59f92011-04-22 23:53:53 +00001155 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001156 }
1157 }
1158 return synthetic_child_sp;
1159}
Jim Ingham22777012010-09-23 02:01:19 +00001160
Enrico Granata9fc19442011-07-06 02:13:41 +00001161ValueObjectSP
1162ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
1163{
1164 ValueObjectSP synthetic_child_sp;
1165 if (IsScalarType ())
1166 {
1167 char index_str[64];
1168 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1169 ConstString index_const_str(index_str);
1170 // Check if we have already created a synthetic array member in this
1171 // valid object. If we have we will re-use it.
1172 synthetic_child_sp = GetSyntheticChild (index_const_str);
1173 if (!synthetic_child_sp)
1174 {
1175 ValueObjectChild *synthetic_child;
1176 // We haven't made a synthetic array member for INDEX yet, so
1177 // lets make one and cache it for any future reference.
1178 synthetic_child = new ValueObjectChild(*this,
1179 GetClangAST(),
1180 GetClangType(),
1181 index_const_str,
1182 GetByteSize(),
1183 0,
1184 to-from+1,
1185 from,
1186 false,
1187 false);
1188
1189 // Cache the value if we got one back...
1190 if (synthetic_child)
1191 {
1192 AddSyntheticChild(index_const_str, synthetic_child);
1193 synthetic_child_sp = synthetic_child->GetSP();
1194 synthetic_child_sp->SetName(index_str);
1195 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1196 }
1197 }
1198 }
1199 return synthetic_child_sp;
1200}
1201
Jim Ingham78a685a2011-04-16 00:01:13 +00001202void
Jim Ingham2837b762011-05-04 03:43:18 +00001203ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001204{
Jim Ingham2837b762011-05-04 03:43:18 +00001205 if (use_dynamic == lldb::eNoDynamicValues)
1206 return;
1207
Jim Ingham58b59f92011-04-22 23:53:53 +00001208 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001209 {
1210 Process *process = m_update_point.GetProcess();
1211 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001212
Jim Ingham78a685a2011-04-16 00:01:13 +00001213
1214 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1215 // hard code this everywhere.
1216 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1217 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1218 {
1219 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1220 if (runtime)
1221 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1222 }
1223 else
1224 {
1225 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1226 if (cpp_runtime)
1227 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1228
1229 if (!worth_having_dynamic_value)
1230 {
1231 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1232 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001233 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001234 }
1235 }
1236
1237 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001238 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001239
1240// if (worth_having_dynamic_value)
1241// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1242
Jim Ingham78a685a2011-04-16 00:01:13 +00001243 }
1244}
1245
Jim Ingham58b59f92011-04-22 23:53:53 +00001246ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001247ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001248{
Jim Ingham2837b762011-05-04 03:43:18 +00001249 if (use_dynamic == lldb::eNoDynamicValues)
1250 return ValueObjectSP();
1251
1252 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001253 {
Jim Ingham2837b762011-05-04 03:43:18 +00001254 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001255 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001256 if (m_dynamic_value)
1257 return m_dynamic_value->GetSP();
1258 else
1259 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001260}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001261
Greg Claytone221f822011-01-21 01:59:00 +00001262bool
1263ValueObject::GetBaseClassPath (Stream &s)
1264{
1265 if (IsBaseClass())
1266 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001267 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001268 clang_type_t clang_type = GetClangType();
1269 std::string cxx_class_name;
1270 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1271 if (this_had_base_class)
1272 {
1273 if (parent_had_base_class)
1274 s.PutCString("::");
1275 s.PutCString(cxx_class_name.c_str());
1276 }
1277 return parent_had_base_class || this_had_base_class;
1278 }
1279 return false;
1280}
1281
1282
1283ValueObject *
1284ValueObject::GetNonBaseClassParent()
1285{
Jim Ingham78a685a2011-04-16 00:01:13 +00001286 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001287 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001288 if (GetParent()->IsBaseClass())
1289 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001290 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001291 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001292 }
1293 return NULL;
1294}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001295
1296void
Enrico Granata4becb372011-06-29 22:27:15 +00001297ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001298{
Greg Claytone221f822011-01-21 01:59:00 +00001299 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00001300
Enrico Granata4becb372011-06-29 22:27:15 +00001301 if(is_deref_of_parent && epformat == eDereferencePointers) {
1302 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
1303 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
1304 // the eHonorPointers mode is meant to produce strings in this latter format
1305 s.PutCString("*(");
1306 }
Greg Claytone221f822011-01-21 01:59:00 +00001307
Enrico Granata4becb372011-06-29 22:27:15 +00001308 ValueObject* parent = GetParent();
1309
1310 if (parent)
1311 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
Enrico Granata0a3958e2011-07-02 00:25:22 +00001312
1313 // if we are a deref_of_parent just because we are synthetic array
1314 // members made up to allow ptr[%d] syntax to work in variable
1315 // printing, then add our name ([%d]) to the expression path
1316 if(m_is_array_item_for_pointer && epformat == eHonorPointers)
1317 s.PutCString(m_name.AsCString());
Enrico Granata4becb372011-06-29 22:27:15 +00001318
Greg Claytone221f822011-01-21 01:59:00 +00001319 if (!IsBaseClass())
1320 {
1321 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001322 {
Greg Claytone221f822011-01-21 01:59:00 +00001323 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1324 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001325 {
Greg Claytone221f822011-01-21 01:59:00 +00001326 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1327 if (non_base_class_parent_clang_type)
1328 {
1329 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1330
Enrico Granata4becb372011-06-29 22:27:15 +00001331 if(parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00001332 {
1333 s.PutCString("->");
1334 }
Enrico Granata4becb372011-06-29 22:27:15 +00001335 else
1336 {
1337 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1338 {
1339 s.PutCString("->");
1340 }
1341 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1342 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1343 {
1344 s.PutChar('.');
1345 }
Greg Claytone221f822011-01-21 01:59:00 +00001346 }
1347 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001348 }
Greg Claytone221f822011-01-21 01:59:00 +00001349
1350 const char *name = GetName().GetCString();
1351 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001352 {
Greg Claytone221f822011-01-21 01:59:00 +00001353 if (qualify_cxx_base_classes)
1354 {
1355 if (GetBaseClassPath (s))
1356 s.PutCString("::");
1357 }
1358 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001359 }
1360 }
1361 }
1362
Enrico Granata4becb372011-06-29 22:27:15 +00001363 if (is_deref_of_parent && epformat == eDereferencePointers) {
Greg Claytone221f822011-01-21 01:59:00 +00001364 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00001365 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001366}
1367
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001368void
Greg Clayton1d3afba2010-10-05 00:00:42 +00001369ValueObject::DumpValueObject
1370(
1371 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00001372 ValueObject *valobj,
1373 const char *root_valobj_name,
1374 uint32_t ptr_depth,
1375 uint32_t curr_depth,
1376 uint32_t max_depth,
1377 bool show_types,
1378 bool show_location,
1379 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00001380 lldb::DynamicValueType use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001381 bool scope_already_checked,
1382 bool flat_output
Greg Clayton1d3afba2010-10-05 00:00:42 +00001383)
1384{
Greg Clayton007d5be2011-05-30 00:49:24 +00001385 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001386 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001387 bool update_success = valobj->UpdateValueIfNeeded ();
1388
1389 if (update_success && use_dynamic != lldb::eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00001390 {
Jim Ingham2837b762011-05-04 03:43:18 +00001391 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00001392 if (dynamic_value)
1393 valobj = dynamic_value;
1394 }
1395
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001396 clang_type_t clang_type = valobj->GetClangType();
1397
Greg Clayton73b472d2010-10-27 03:32:59 +00001398 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001399 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00001400 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
1401 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001402
1403 const bool print_valobj = flat_output == false || has_value;
1404
1405 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001406 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001407 if (show_location)
1408 {
Jim Ingham6035b672011-03-31 00:19:25 +00001409 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001410 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001411
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001412 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001413
Greg Clayton7c8a9662010-11-02 01:50:16 +00001414 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00001415 if (show_types || (curr_depth == 0 && !flat_output))
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001416 s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
Greg Clayton1d3afba2010-10-05 00:00:42 +00001417
Greg Clayton1d3afba2010-10-05 00:00:42 +00001418
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001419 if (flat_output)
1420 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001421 // If we are showing types, also qualify the C++ base classes
1422 const bool qualify_cxx_base_classes = show_types;
1423 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001424 s.PutCString(" =");
1425 }
1426 else
1427 {
1428 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
1429 s.Printf ("%s =", name_cstr);
1430 }
1431
Jim Ingham6035b672011-03-31 00:19:25 +00001432 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001433 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001434 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001435 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001436 }
1437
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001438 const char *val_cstr = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00001439 const char *sum_cstr = NULL;
1440 SummaryFormat* entry = valobj->m_last_summary_format.get();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001441
1442 if (err_cstr == NULL)
1443 {
Jim Ingham6035b672011-03-31 00:19:25 +00001444 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001445 err_cstr = valobj->GetError().AsCString();
1446 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001447
1448 if (err_cstr)
1449 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001450 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00001451 }
1452 else
1453 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001454 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001455 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001456 {
Enrico Granata4becb372011-06-29 22:27:15 +00001457
1458 sum_cstr = valobj->GetSummaryAsCString();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001459
Enrico Granata4becb372011-06-29 22:27:15 +00001460 // We must calculate this value in realtime because entry might alter this variable's value
1461 // (e.g. by saying ${var%fmt}) and render precached values useless
1462 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
1463 s.Printf(" %s", valobj->GetValueAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001464
Enrico Granata0a3958e2011-07-02 00:25:22 +00001465 if(sum_cstr)
1466 {
1467 // for some reason, using %@ (ObjC description) in a summary string, makes
1468 // us believe we need to reset ourselves, thus invalidating the content of
1469 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty
1470 // let us recalculate it!
1471 if (sum_cstr[0] == '\0')
1472 s.Printf(" %s", valobj->GetSummaryAsCString());
1473 else
1474 s.Printf(" %s", sum_cstr);
1475 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001476
1477 if (use_objc)
1478 {
Jim Ingham6035b672011-03-31 00:19:25 +00001479 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001480 if (object_desc)
1481 s.Printf(" %s\n", object_desc);
1482 else
Sean Callanan672ad942010-10-23 00:18:49 +00001483 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001484 return;
Enrico Granata0a3958e2011-07-02 00:25:22 +00001485 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001486 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001487
1488 if (curr_depth < max_depth)
1489 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001490 // We will show children for all concrete types. We won't show
1491 // pointer contents unless a pointer depth has been specified.
1492 // We won't reference contents unless the reference is the
1493 // root object (depth of zero).
1494 bool print_children = true;
1495
1496 // Use a new temporary pointer depth in case we override the
1497 // current pointer depth below...
1498 uint32_t curr_ptr_depth = ptr_depth;
1499
1500 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
1501 if (is_ptr || is_ref)
1502 {
1503 // We have a pointer or reference whose value is an address.
1504 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00001505 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00001506 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
1507 print_children = false;
1508
1509 else if (is_ref && curr_depth == 0)
1510 {
1511 // If this is the root object (depth is zero) that we are showing
1512 // and it is a reference, and no pointer depth has been supplied
1513 // print out what it references. Don't do this at deeper depths
1514 // otherwise we can end up with infinite recursion...
1515 curr_ptr_depth = 1;
1516 }
1517
1518 if (curr_ptr_depth == 0)
1519 print_children = false;
1520 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001521
Enrico Granata0a3958e2011-07-02 00:25:22 +00001522 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00001523 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001524 const uint32_t num_children = valobj->GetNumChildren();
1525 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001526 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001527 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001528 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001529 if (print_valobj)
1530 s.EOL();
1531 }
1532 else
1533 {
1534 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00001535 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001536 s.IndentMore();
1537 }
1538
1539 for (uint32_t idx=0; idx<num_children; ++idx)
1540 {
1541 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
1542 if (child_sp.get())
1543 {
1544 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001545 child_sp.get(),
1546 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00001547 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001548 curr_depth + 1,
1549 max_depth,
1550 show_types,
1551 show_location,
1552 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00001553 use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001554 true,
1555 flat_output);
1556 }
1557 }
1558
1559 if (!flat_output)
1560 {
1561 s.IndentLess();
1562 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001563 }
1564 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001565 else if (has_children)
1566 {
1567 // Aggregate, no children...
1568 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00001569 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001570 }
1571 else
1572 {
1573 if (print_valobj)
1574 s.EOL();
1575 }
1576
Greg Clayton1d3afba2010-10-05 00:00:42 +00001577 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001578 else
1579 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00001580 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001581 }
1582 }
1583 else
1584 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001585 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001586 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001587 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001588 }
1589 }
1590 }
1591 }
1592}
1593
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001594
1595ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00001596ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001597{
1598 ValueObjectSP valobj_sp;
1599
Jim Ingham6035b672011-03-31 00:19:25 +00001600 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001601 {
Jim Ingham6035b672011-03-31 00:19:25 +00001602 ExecutionContextScope *exe_scope = GetExecutionContextScope();
1603 if (exe_scope)
1604 {
1605 ExecutionContext exe_ctx;
1606 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001607
Jim Ingham6035b672011-03-31 00:19:25 +00001608 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001609
Jim Ingham6035b672011-03-31 00:19:25 +00001610 DataExtractor data;
1611 data.SetByteOrder (m_data.GetByteOrder());
1612 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001613
Jim Ingham6035b672011-03-31 00:19:25 +00001614 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001615
Jim Ingham58b59f92011-04-22 23:53:53 +00001616 valobj_sp = ValueObjectConstResult::Create (exe_scope,
1617 ast,
1618 GetClangType(),
1619 name,
1620 data);
Jim Ingham6035b672011-03-31 00:19:25 +00001621 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001622 }
Jim Ingham6035b672011-03-31 00:19:25 +00001623
1624 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001625 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001626 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001627 }
1628 return valobj_sp;
1629}
1630
1631lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00001632ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001633{
Jim Ingham58b59f92011-04-22 23:53:53 +00001634 if (m_deref_valobj)
1635 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00001636
Greg Clayton54979cd2010-12-15 05:08:08 +00001637 const bool is_pointer_type = IsPointerType();
1638 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001639 {
1640 bool omit_empty_base_classes = true;
1641
1642 std::string child_name_str;
1643 uint32_t child_byte_size = 0;
1644 int32_t child_byte_offset = 0;
1645 uint32_t child_bitfield_bit_size = 0;
1646 uint32_t child_bitfield_bit_offset = 0;
1647 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00001648 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001649 const bool transparent_pointers = false;
1650 clang::ASTContext *clang_ast = GetClangAST();
1651 clang_type_t clang_type = GetClangType();
1652 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00001653
1654 ExecutionContext exe_ctx;
1655 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
1656
1657 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
1658 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001659 GetName().GetCString(),
1660 clang_type,
1661 0,
1662 transparent_pointers,
1663 omit_empty_base_classes,
1664 child_name_str,
1665 child_byte_size,
1666 child_byte_offset,
1667 child_bitfield_bit_size,
1668 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00001669 child_is_base_class,
1670 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00001671 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001672 {
1673 ConstString child_name;
1674 if (!child_name_str.empty())
1675 child_name.SetCString (child_name_str.c_str());
1676
Jim Ingham58b59f92011-04-22 23:53:53 +00001677 m_deref_valobj = new ValueObjectChild (*this,
1678 clang_ast,
1679 child_clang_type,
1680 child_name,
1681 child_byte_size,
1682 child_byte_offset,
1683 child_bitfield_bit_size,
1684 child_bitfield_bit_offset,
1685 child_is_base_class,
1686 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001687 }
1688 }
Greg Clayton54979cd2010-12-15 05:08:08 +00001689
Jim Ingham58b59f92011-04-22 23:53:53 +00001690 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00001691 {
1692 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00001693 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00001694 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001695 else
1696 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001697 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001698 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001699
1700 if (is_pointer_type)
1701 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
1702 else
1703 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00001704 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001705 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001706}
1707
Jim Ingham78a685a2011-04-16 00:01:13 +00001708lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00001709ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001710{
Jim Ingham78a685a2011-04-16 00:01:13 +00001711 if (m_addr_of_valobj_sp)
1712 return m_addr_of_valobj_sp;
1713
Greg Claytone0d378b2011-03-24 21:19:54 +00001714 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001715 const bool scalar_is_load_address = false;
1716 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00001717 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001718 if (addr != LLDB_INVALID_ADDRESS)
1719 {
1720 switch (address_type)
1721 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001722 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001723 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00001724 {
1725 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001726 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001727 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
1728 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001729 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00001730
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001731 case eAddressTypeFile:
1732 case eAddressTypeLoad:
1733 case eAddressTypeHost:
1734 {
1735 clang::ASTContext *ast = GetClangAST();
1736 clang_type_t clang_type = GetClangType();
1737 if (ast && clang_type)
1738 {
1739 std::string name (1, '&');
1740 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00001741 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
1742 ast,
1743 ClangASTContext::CreatePointerType (ast, clang_type),
1744 ConstString (name.c_str()),
1745 addr,
1746 eAddressTypeInvalid,
1747 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001748 }
1749 }
1750 break;
1751 }
1752 }
Jim Ingham78a685a2011-04-16 00:01:13 +00001753 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001754}
1755
Greg Claytonb2dcc362011-05-05 23:32:56 +00001756
1757lldb::ValueObjectSP
1758ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
1759{
1760 lldb::ValueObjectSP valobj_sp;
1761 AddressType address_type;
1762 const bool scalar_is_load_address = true;
1763 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
1764
1765 if (ptr_value != LLDB_INVALID_ADDRESS)
1766 {
1767 Address ptr_addr (NULL, ptr_value);
1768
1769 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
1770 name,
1771 ptr_addr,
1772 clang_ast_type);
1773 }
1774 return valobj_sp;
1775}
1776
1777lldb::ValueObjectSP
1778ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
1779{
1780 lldb::ValueObjectSP valobj_sp;
1781 AddressType address_type;
1782 const bool scalar_is_load_address = true;
1783 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
1784
1785 if (ptr_value != LLDB_INVALID_ADDRESS)
1786 {
1787 Address ptr_addr (NULL, ptr_value);
1788
1789 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
1790 name,
1791 ptr_addr,
1792 type_sp);
1793 }
1794 return valobj_sp;
1795}
1796
1797
Jim Ingham6035b672011-03-31 00:19:25 +00001798ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00001799 m_thread_id (LLDB_INVALID_UID),
1800 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00001801{
1802}
1803
1804ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00001805 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00001806 m_first_update (true),
1807 m_thread_id (LLDB_INVALID_UID),
1808 m_stop_id (0)
1809
Jim Ingham6035b672011-03-31 00:19:25 +00001810{
1811 ExecutionContext exe_ctx;
1812 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
1813 // and if so we want to cache that not the original.
1814 if (exe_scope)
1815 exe_scope->CalculateExecutionContext(exe_ctx);
1816 if (exe_ctx.target != NULL)
1817 {
1818 m_target_sp = exe_ctx.target->GetSP();
1819
1820 if (exe_ctx.process == NULL)
1821 m_process_sp = exe_ctx.target->GetProcessSP();
1822 else
1823 m_process_sp = exe_ctx.process->GetSP();
1824
1825 if (m_process_sp != NULL)
1826 {
1827 m_stop_id = m_process_sp->GetStopID();
1828 Thread *thread = NULL;
1829
1830 if (exe_ctx.thread == NULL)
1831 {
1832 if (use_selected)
1833 {
1834 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
1835 if (thread)
1836 computed_exe_scope = thread;
1837 }
1838 }
1839 else
1840 thread = exe_ctx.thread;
1841
1842 if (thread != NULL)
1843 {
1844 m_thread_id = thread->GetIndexID();
1845 if (exe_ctx.frame == NULL)
1846 {
1847 if (use_selected)
1848 {
1849 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
1850 if (frame)
1851 {
1852 m_stack_id = frame->GetStackID();
1853 computed_exe_scope = frame;
1854 }
1855 }
1856 }
1857 else
1858 m_stack_id = exe_ctx.frame->GetStackID();
1859 }
1860 }
1861 }
1862 m_exe_scope = computed_exe_scope;
1863}
1864
1865ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
1866 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00001867 m_needs_update(true),
1868 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00001869 m_target_sp (rhs.m_target_sp),
1870 m_process_sp (rhs.m_process_sp),
1871 m_thread_id (rhs.m_thread_id),
1872 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00001873 m_stop_id (0)
1874{
1875}
1876
1877ValueObject::EvaluationPoint::~EvaluationPoint ()
1878{
1879}
1880
1881ExecutionContextScope *
1882ValueObject::EvaluationPoint::GetExecutionContextScope ()
1883{
1884 // We have to update before giving out the scope, or we could be handing out stale pointers.
1885 SyncWithProcessState();
1886
1887 return m_exe_scope;
1888}
1889
1890// This function checks the EvaluationPoint against the current process state. If the current
1891// state matches the evaluation point, or the evaluation point is already invalid, then we return
1892// false, meaning "no change". If the current state is different, we update our state, and return
1893// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
1894// future calls to NeedsUpdate will return true.
1895
1896bool
1897ValueObject::EvaluationPoint::SyncWithProcessState()
1898{
1899 // If we're already invalid, we don't need to do anything, and nothing has changed:
1900 if (m_stop_id == LLDB_INVALID_UID)
1901 {
1902 // Can't update with an invalid state.
1903 m_needs_update = false;
1904 return false;
1905 }
1906
1907 // If we don't have a process nothing can change.
1908 if (!m_process_sp)
1909 return false;
1910
1911 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00001912 uint32_t cur_stop_id = m_process_sp->GetStopID();
1913 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00001914 return false;
1915
Jim Ingham78a685a2011-04-16 00:01:13 +00001916 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
1917 // In either case, we aren't going to be able to sync with the process state.
1918 if (cur_stop_id == 0)
1919 return false;
1920
1921 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00001922 m_needs_update = true;
1923 m_exe_scope = m_process_sp.get();
1924
1925 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
1926 // doesn't, mark ourselves as invalid.
1927
1928 if (m_thread_id != LLDB_INVALID_THREAD_ID)
1929 {
1930 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
1931 if (our_thread == NULL)
1932 SetInvalid();
1933 else
1934 {
1935 m_exe_scope = our_thread;
1936
1937 if (m_stack_id.IsValid())
1938 {
1939 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
1940 if (our_frame == NULL)
1941 SetInvalid();
1942 else
1943 m_exe_scope = our_frame;
1944 }
1945 }
1946 }
1947 return true;
1948}
1949
Jim Ingham61be0902011-05-02 18:13:59 +00001950void
1951ValueObject::EvaluationPoint::SetUpdated ()
1952{
1953 m_first_update = false;
1954 m_needs_update = false;
1955 if (m_process_sp)
1956 m_stop_id = m_process_sp->GetStopID();
1957}
1958
1959
Jim Ingham6035b672011-03-31 00:19:25 +00001960bool
1961ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
1962{
1963 if (!IsValid())
1964 return false;
1965
1966 bool needs_update = false;
1967 m_exe_scope = NULL;
1968
1969 // The target has to be non-null, and the
1970 Target *target = exe_scope->CalculateTarget();
1971 if (target != NULL)
1972 {
1973 Target *old_target = m_target_sp.get();
1974 assert (target == old_target);
1975 Process *process = exe_scope->CalculateProcess();
1976 if (process != NULL)
1977 {
1978 // FOR NOW - assume you can't update variable objects across process boundaries.
1979 Process *old_process = m_process_sp.get();
1980 assert (process == old_process);
1981
1982 lldb::user_id_t stop_id = process->GetStopID();
1983 if (stop_id != m_stop_id)
1984 {
1985 needs_update = true;
1986 m_stop_id = stop_id;
1987 }
1988 // See if we're switching the thread or stack context. If no thread is given, this is
1989 // being evaluated in a global context.
1990 Thread *thread = exe_scope->CalculateThread();
1991 if (thread != NULL)
1992 {
1993 lldb::user_id_t new_thread_index = thread->GetIndexID();
1994 if (new_thread_index != m_thread_id)
1995 {
1996 needs_update = true;
1997 m_thread_id = new_thread_index;
1998 m_stack_id.Clear();
1999 }
2000
2001 StackFrame *new_frame = exe_scope->CalculateStackFrame();
2002 if (new_frame != NULL)
2003 {
2004 if (new_frame->GetStackID() != m_stack_id)
2005 {
2006 needs_update = true;
2007 m_stack_id = new_frame->GetStackID();
2008 }
2009 }
2010 else
2011 {
2012 m_stack_id.Clear();
2013 needs_update = true;
2014 }
2015 }
2016 else
2017 {
2018 // If this had been given a thread, and now there is none, we should update.
2019 // Otherwise we don't have to do anything.
2020 if (m_thread_id != LLDB_INVALID_UID)
2021 {
2022 m_thread_id = LLDB_INVALID_UID;
2023 m_stack_id.Clear();
2024 needs_update = true;
2025 }
2026 }
2027 }
2028 else
2029 {
2030 // If there is no process, then we don't need to update anything.
2031 // But if we're switching from having a process to not, we should try to update.
2032 if (m_process_sp.get() != NULL)
2033 {
2034 needs_update = true;
2035 m_process_sp.reset();
2036 m_thread_id = LLDB_INVALID_UID;
2037 m_stack_id.Clear();
2038 }
2039 }
2040 }
2041 else
2042 {
2043 // If there's no target, nothing can change so we don't need to update anything.
2044 // But if we're switching from having a target to not, we should try to update.
2045 if (m_target_sp.get() != NULL)
2046 {
2047 needs_update = true;
2048 m_target_sp.reset();
2049 m_process_sp.reset();
2050 m_thread_id = LLDB_INVALID_UID;
2051 m_stack_id.Clear();
2052 }
2053 }
2054 if (!m_needs_update)
2055 m_needs_update = needs_update;
2056
2057 return needs_update;
2058}