blob: 5264db2c4cbdaf863726707c0ff6130f2d05cdbc [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
Enrico Granataf2bbf712011-07-15 02:26:42 +000032#include "lldb/Interpreter/ScriptInterpreterPython.h"
33
Greg Claytone1a916a2010-07-21 22:12:05 +000034#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Symbol/ClangASTContext.h"
36#include "lldb/Symbol/Type.h"
37
Jim Ingham53c47f12010-09-10 23:12:17 +000038#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000039#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040#include "lldb/Target/Process.h"
41#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000042#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044
Enrico Granataf4efecd2011-07-12 22:56:10 +000045#include "lldb/Utility/RefCounter.h"
46
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047using namespace lldb;
48using namespace lldb_private;
Enrico Granataf4efecd2011-07-12 22:56:10 +000049using namespace lldb_utility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050
51static lldb::user_id_t g_value_obj_uid = 0;
52
53//----------------------------------------------------------------------
54// ValueObject constructor
55//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000056ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000058 m_parent (&parent),
Stephen Wilson71c21d12011-04-11 19:41:40 +000059 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060 m_name (),
61 m_data (),
62 m_value (),
63 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000064 m_value_str (),
65 m_old_value_str (),
66 m_location_str (),
67 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000068 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000069 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000070 m_children (),
71 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000072 m_dynamic_value (NULL),
73 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000074 m_format (eFormatDefault),
Greg Clayton288bdf92010-09-02 02:59:18 +000075 m_value_is_valid (false),
76 m_value_did_change (false),
77 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000078 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000079 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +000080 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +000081 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +000082 m_is_bitfield_for_scalar(false),
Enrico Granata4becb372011-06-29 22:27:15 +000083 m_last_format_mgr_revision(0),
Enrico Granataf9fa6ee2011-07-12 00:18:11 +000084 m_last_value_format(),
Enrico Granataf2bbf712011-07-15 02:26:42 +000085 m_last_summary_format(),
Enrico Granataf4efecd2011-07-12 22:56:10 +000086 m_forced_summary_format(),
87 m_dump_printable_counter(0)
Jim Ingham6035b672011-03-31 00:19:25 +000088{
Jim Ingham58b59f92011-04-22 23:53:53 +000089 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +000090}
91
92//----------------------------------------------------------------------
93// ValueObject constructor
94//----------------------------------------------------------------------
95ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
96 UserID (++g_value_obj_uid), // Unique identifier for every value object
97 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +000098 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +000099 m_name (),
100 m_data (),
101 m_value (),
102 m_error (),
103 m_value_str (),
104 m_old_value_str (),
105 m_location_str (),
106 m_summary_str (),
107 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000108 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +0000109 m_children (),
110 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000111 m_dynamic_value (NULL),
112 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +0000113 m_format (eFormatDefault),
114 m_value_is_valid (false),
115 m_value_did_change (false),
116 m_children_count_valid (false),
117 m_old_value_valid (false),
118 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +0000119 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +0000120 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +0000121 m_is_bitfield_for_scalar(false),
Enrico Granata4becb372011-06-29 22:27:15 +0000122 m_last_format_mgr_revision(0),
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000123 m_last_value_format(),
Enrico Granataf2bbf712011-07-15 02:26:42 +0000124 m_last_summary_format(),
Enrico Granataf4efecd2011-07-12 22:56:10 +0000125 m_forced_summary_format(),
126 m_dump_printable_counter(0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127{
Jim Ingham58b59f92011-04-22 23:53:53 +0000128 m_manager = new ValueObjectManager();
129 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130}
131
132//----------------------------------------------------------------------
133// Destructor
134//----------------------------------------------------------------------
135ValueObject::~ValueObject ()
136{
137}
138
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139bool
Enrico Granata0a3958e2011-07-02 00:25:22 +0000140ValueObject::UpdateValueIfNeeded (bool update_format)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141{
Enrico Granata4becb372011-06-29 22:27:15 +0000142
Enrico Granata0a3958e2011-07-02 00:25:22 +0000143 if (update_format)
144 UpdateFormatsIfNeeded();
Enrico Granata4becb372011-06-29 22:27:15 +0000145
Greg Claytonb71f3842010-10-05 03:13:51 +0000146 // If this is a constant value, then our success is predicated on whether
147 // we have an error or not
148 if (GetIsConstant())
149 return m_error.Success();
150
Jim Ingham6035b672011-03-31 00:19:25 +0000151 bool first_update = m_update_point.IsFirstEvaluation();
152
153 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000154 {
Jim Ingham6035b672011-03-31 00:19:25 +0000155 m_update_point.SetUpdated();
156
157 // Save the old value using swap to avoid a string copy which
158 // also will clear our m_value_str
159 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 {
Jim Ingham6035b672011-03-31 00:19:25 +0000161 m_old_value_valid = false;
162 }
163 else
164 {
165 m_old_value_valid = true;
166 m_old_value_str.swap (m_value_str);
167 m_value_str.clear();
168 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169
Enrico Granataf2bbf712011-07-15 02:26:42 +0000170 ClearUserVisibleData();
171
Jim Ingham6035b672011-03-31 00:19:25 +0000172 const bool value_was_valid = GetValueIsValid();
173 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000174
Jim Ingham6035b672011-03-31 00:19:25 +0000175 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000176
Jim Ingham6035b672011-03-31 00:19:25 +0000177 // Call the pure virtual function to update the value
178 bool success = UpdateValue ();
179
180 SetValueIsValid (success);
181
182 if (first_update)
183 SetValueDidChange (false);
184 else if (!m_value_did_change && success == false)
185 {
186 // The value wasn't gotten successfully, so we mark this
187 // as changed if the value used to be valid and now isn't
188 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189 }
190 }
191 return m_error.Success();
192}
193
Enrico Granata4becb372011-06-29 22:27:15 +0000194void
195ValueObject::UpdateFormatsIfNeeded()
196{
197 /*printf("CHECKING FOR UPDATES. I am at revision %d, while the format manager is at revision %d\n",
198 m_last_format_mgr_revision,
199 Debugger::ValueFormats::GetCurrentRevision());*/
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000200 if (HasCustomSummaryFormat() && m_update_point.GetUpdateID() != m_user_id_of_forced_summary)
201 {
202 ClearCustomSummaryFormat();
203 m_summary_str.clear();
204 }
Enrico Granata4becb372011-06-29 22:27:15 +0000205 if (m_last_format_mgr_revision != Debugger::ValueFormats::GetCurrentRevision())
206 {
207 if (m_last_summary_format.get())
Enrico Granataf2bbf712011-07-15 02:26:42 +0000208 m_last_summary_format.reset((StringSummaryFormat*)NULL);
Enrico Granata4becb372011-06-29 22:27:15 +0000209 if (m_last_value_format.get())
210 m_last_value_format.reset((ValueFormat*)NULL);
211 Debugger::ValueFormats::Get(*this, m_last_value_format);
Enrico Granata9dd75c82011-07-15 23:30:15 +0000212 // to find a summary we look for a direct summary, then if there is none
213 // we look for a regex summary. if there is none we look for a system
214 // summary (direct), and if also that fails, we look for a system
215 // regex summary
Enrico Granata0a3958e2011-07-02 00:25:22 +0000216 if (!Debugger::SummaryFormats::Get(*this, m_last_summary_format))
Enrico Granata9dd75c82011-07-15 23:30:15 +0000217 if (!Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format))
218 if (!Debugger::SystemSummaryFormats::Get(*this, m_last_summary_format))
219 Debugger::SystemRegexSummaryFormats::Get(*this, m_last_summary_format);
Enrico Granata4becb372011-06-29 22:27:15 +0000220 m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision();
Enrico Granataf2bbf712011-07-15 02:26:42 +0000221
222 ClearUserVisibleData();
Enrico Granata4becb372011-06-29 22:27:15 +0000223 }
224}
225
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226DataExtractor &
227ValueObject::GetDataExtractor ()
228{
Jim Ingham78a685a2011-04-16 00:01:13 +0000229 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000230 return m_data;
231}
232
233const Error &
Greg Clayton262f80d2011-07-06 16:49:27 +0000234ValueObject::GetError()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235{
Greg Clayton262f80d2011-07-06 16:49:27 +0000236 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237 return m_error;
238}
239
240const ConstString &
241ValueObject::GetName() const
242{
243 return m_name;
244}
245
246const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000247ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248{
Jim Ingham6035b672011-03-31 00:19:25 +0000249 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250 {
251 if (m_location_str.empty())
252 {
253 StreamString sstr;
254
255 switch (m_value.GetValueType())
256 {
257 default:
258 break;
259
260 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000261 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262 {
263 RegisterInfo *reg_info = m_value.GetRegisterInfo();
264 if (reg_info)
265 {
266 if (reg_info->name)
267 m_location_str = reg_info->name;
268 else if (reg_info->alt_name)
269 m_location_str = reg_info->alt_name;
270 break;
271 }
272 }
273 m_location_str = "scalar";
274 break;
275
276 case Value::eValueTypeLoadAddress:
277 case Value::eValueTypeFileAddress:
278 case Value::eValueTypeHostAddress:
279 {
280 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
281 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
282 m_location_str.swap(sstr.GetString());
283 }
284 break;
285 }
286 }
287 }
288 return m_location_str.c_str();
289}
290
291Value &
292ValueObject::GetValue()
293{
294 return m_value;
295}
296
297const Value &
298ValueObject::GetValue() const
299{
300 return m_value;
301}
302
303bool
Jim Ingham6035b672011-03-31 00:19:25 +0000304ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000305{
306 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000307 ExecutionContextScope *exe_scope = GetExecutionContextScope();
308 if (exe_scope)
309 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000310 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
311 return scalar.IsValid();
312}
313
314bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000315ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316{
Greg Clayton288bdf92010-09-02 02:59:18 +0000317 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318}
319
320
321void
322ValueObject::SetValueIsValid (bool b)
323{
Greg Clayton288bdf92010-09-02 02:59:18 +0000324 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325}
326
327bool
Jim Ingham6035b672011-03-31 00:19:25 +0000328ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000329{
Jim Ingham6035b672011-03-31 00:19:25 +0000330 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000331 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332}
333
334void
335ValueObject::SetValueDidChange (bool value_changed)
336{
Greg Clayton288bdf92010-09-02 02:59:18 +0000337 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000338}
339
340ValueObjectSP
341ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
342{
343 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000344 // We may need to update our value if we are dynamic
345 if (IsPossibleDynamicType ())
346 UpdateValueIfNeeded();
347 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000349 // Check if we have already made the child value object?
350 if (can_create && m_children[idx] == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000352 // No we haven't created the child at this index, so lets have our
353 // subclass do it and cache the result for quick future access.
354 m_children[idx] = CreateChildAtIndex (idx, false, 0);
Jim Ingham78a685a2011-04-16 00:01:13 +0000355 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000356
357 if (m_children[idx] != NULL)
358 return m_children[idx]->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359 }
360 return child_sp;
361}
362
363uint32_t
364ValueObject::GetIndexOfChildWithName (const ConstString &name)
365{
366 bool omit_empty_base_classes = true;
367 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000368 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000369 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370 omit_empty_base_classes);
371}
372
373ValueObjectSP
374ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
375{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000376 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000377 // classes (which really aren't part of the expression path), so we
378 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000379 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000380
Greg Claytondea8cb42011-06-29 22:09:02 +0000381 // We may need to update our value if we are dynamic
382 if (IsPossibleDynamicType ())
383 UpdateValueIfNeeded();
384
385 std::vector<uint32_t> child_indexes;
386 clang::ASTContext *clang_ast = GetClangAST();
387 void *clang_type = GetClangType();
388 bool omit_empty_base_classes = true;
389 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
390 clang_type,
391 name.GetCString(),
392 omit_empty_base_classes,
393 child_indexes);
394 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000396 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
397 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
398
399 child_sp = GetChildAtIndex(*pos, can_create);
400 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000401 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000402 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000403 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000404 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
405 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000406 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000407 else
408 {
409 child_sp.reset();
410 }
411
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412 }
413 }
414 return child_sp;
415}
416
417
418uint32_t
419ValueObject::GetNumChildren ()
420{
Greg Clayton288bdf92010-09-02 02:59:18 +0000421 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422 {
423 SetNumChildren (CalculateNumChildren());
424 }
425 return m_children.size();
426}
427void
428ValueObject::SetNumChildren (uint32_t num_children)
429{
Greg Clayton288bdf92010-09-02 02:59:18 +0000430 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431 m_children.resize(num_children);
432}
433
434void
435ValueObject::SetName (const char *name)
436{
437 m_name.SetCString(name);
438}
439
440void
441ValueObject::SetName (const ConstString &name)
442{
443 m_name = name;
444}
445
Jim Ingham58b59f92011-04-22 23:53:53 +0000446ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
448{
Jim Ingham2eec4872011-05-07 00:10:58 +0000449 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000450
Greg Claytondea8cb42011-06-29 22:09:02 +0000451 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +0000452 bool ignore_array_bounds = synthetic_array_member;
Greg Claytondea8cb42011-06-29 22:09:02 +0000453 std::string child_name_str;
454 uint32_t child_byte_size = 0;
455 int32_t child_byte_offset = 0;
456 uint32_t child_bitfield_bit_size = 0;
457 uint32_t child_bitfield_bit_offset = 0;
458 bool child_is_base_class = false;
459 bool child_is_deref_of_parent = false;
460
461 const bool transparent_pointers = synthetic_array_member == false;
462 clang::ASTContext *clang_ast = GetClangAST();
463 clang_type_t clang_type = GetClangType();
464 clang_type_t child_clang_type;
465
466 ExecutionContext exe_ctx;
467 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
468
469 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
470 clang_ast,
471 GetName().GetCString(),
472 clang_type,
473 idx,
474 transparent_pointers,
475 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +0000476 ignore_array_bounds,
Greg Claytondea8cb42011-06-29 22:09:02 +0000477 child_name_str,
478 child_byte_size,
479 child_byte_offset,
480 child_bitfield_bit_size,
481 child_bitfield_bit_offset,
482 child_is_base_class,
483 child_is_deref_of_parent);
484 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000485 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000486 if (synthetic_index)
487 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488
Greg Claytondea8cb42011-06-29 22:09:02 +0000489 ConstString child_name;
490 if (!child_name_str.empty())
491 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492
Greg Claytondea8cb42011-06-29 22:09:02 +0000493 valobj = new ValueObjectChild (*this,
494 clang_ast,
495 child_clang_type,
496 child_name,
497 child_byte_size,
498 child_byte_offset,
499 child_bitfield_bit_size,
500 child_bitfield_bit_offset,
501 child_is_base_class,
502 child_is_deref_of_parent);
503 if (m_pointers_point_to_load_addrs)
504 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000505 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000506
Jim Ingham58b59f92011-04-22 23:53:53 +0000507 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000508}
509
510const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000511ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512{
Jim Ingham6035b672011-03-31 00:19:25 +0000513 if (UpdateValueIfNeeded ())
Enrico Granata4becb372011-06-29 22:27:15 +0000514 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515 if (m_summary_str.empty())
516 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000517 SummaryFormat *summary_format = GetSummaryFormat().get();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000518
519 if (summary_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000520 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000521 m_summary_str = summary_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000522 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000523 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000525 clang_type_t clang_type = GetClangType();
Greg Clayton737b9322010-09-13 03:32:57 +0000526
Enrico Granata9dd75c82011-07-15 23:30:15 +0000527 // Do some default printout for function pointers
Enrico Granataf2bbf712011-07-15 02:26:42 +0000528 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000530 StreamString sstr;
531 clang_type_t elem_or_pointee_clang_type;
532 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
533 GetClangAST(),
534 &elem_or_pointee_clang_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000535
Enrico Granataf2bbf712011-07-15 02:26:42 +0000536 ExecutionContextScope *exe_scope = GetExecutionContextScope();
537 if (exe_scope)
538 {
Enrico Granata9dd75c82011-07-15 23:30:15 +0000539 if (ClangASTContext::IsFunctionPointerType (clang_type))
Jim Ingham6035b672011-03-31 00:19:25 +0000540 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000541 AddressType func_ptr_address_type = eAddressTypeInvalid;
542 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
543
544 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
545 {
546 switch (func_ptr_address_type)
547 {
548 case eAddressTypeInvalid:
549 case eAddressTypeFile:
550 break;
551
552 case eAddressTypeLoad:
553 {
554 Address so_addr;
555 Target *target = exe_scope->CalculateTarget();
556 if (target && target->GetSectionLoadList().IsEmpty() == false)
557 {
558 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
559 {
560 so_addr.Dump (&sstr,
561 exe_scope,
562 Address::DumpStyleResolvedDescription,
563 Address::DumpStyleSectionNameOffset);
564 }
565 }
566 }
567 break;
568
569 case eAddressTypeHost:
570 break;
571 }
572 }
573 if (sstr.GetSize() > 0)
574 {
575 m_summary_str.assign (1, '(');
576 m_summary_str.append (sstr.GetData(), sstr.GetSize());
577 m_summary_str.append (1, ')');
578 }
Jim Ingham6035b672011-03-31 00:19:25 +0000579 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580 }
581 }
582 }
583 }
584 }
585 if (m_summary_str.empty())
586 return NULL;
587 return m_summary_str.c_str();
588}
589
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000590bool
591ValueObject::IsCStringContainer(bool check_pointer)
592{
593 clang_type_t elem_or_pointee_clang_type;
594 const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(),
595 GetClangAST(),
596 &elem_or_pointee_clang_type));
597 bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
598 ClangASTContext::IsCharType (elem_or_pointee_clang_type));
599 if (!is_char_arr_ptr)
600 return false;
601 if (!check_pointer)
602 return true;
603 if (type_flags.Test(ClangASTContext::eTypeIsArray))
604 return true;
605 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
606 AddressType cstr_address_type = eAddressTypeInvalid;
607 cstr_address = GetAddressOf (cstr_address_type, true);
608 return (cstr_address != LLDB_INVALID_ADDRESS);
609}
610
611void
612ValueObject::ReadPointedString(Stream& s,
613 Error& error,
Enrico Granataf4efecd2011-07-12 22:56:10 +0000614 uint32_t max_length,
615 bool honor_array,
616 lldb::Format item_format)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000617{
618
619 if (max_length == 0)
Enrico Granataf4efecd2011-07-12 22:56:10 +0000620 max_length = 128; // FIXME this should be a setting, or a formatting parameter
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000621
622 clang_type_t clang_type = GetClangType();
623 clang_type_t elem_or_pointee_clang_type;
624 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
625 GetClangAST(),
626 &elem_or_pointee_clang_type));
627 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
628 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
629 {
630 ExecutionContextScope *exe_scope = GetExecutionContextScope();
631 if (exe_scope)
632 {
633 Target *target = exe_scope->CalculateTarget();
634 if (target != NULL)
635 {
636 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
637 AddressType cstr_address_type = eAddressTypeInvalid;
638
639 size_t cstr_len = 0;
640 bool capped_data = false;
641 if (type_flags.Test (ClangASTContext::eTypeIsArray))
642 {
643 // We have an array
644 cstr_len = ClangASTContext::GetArraySize (clang_type);
Enrico Granataf4efecd2011-07-12 22:56:10 +0000645 if (cstr_len > max_length)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000646 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000647 capped_data = true;
648 cstr_len = max_length;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000649 }
650 cstr_address = GetAddressOf (cstr_address_type, true);
651 }
652 else
653 {
654 // We have a pointer
655 cstr_address = GetPointerValue (cstr_address_type, true);
656 }
657 if (cstr_address != LLDB_INVALID_ADDRESS)
658 {
659 Address cstr_so_addr (NULL, cstr_address);
660 DataExtractor data;
661 size_t bytes_read = 0;
662 std::vector<char> data_buffer;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000663 bool prefer_file_cache = false;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000664 if (cstr_len > 0 && honor_array)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000665 {
666 data_buffer.resize(cstr_len);
667 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
668 bytes_read = target->ReadMemory (cstr_so_addr,
669 prefer_file_cache,
670 &data_buffer.front(),
671 cstr_len,
672 error);
673 if (bytes_read > 0)
674 {
675 s << '"';
676 data.Dump (&s,
677 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000678 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000679 1, // Size of item (1 byte for a char!)
680 bytes_read, // How many bytes to print?
681 UINT32_MAX, // num per line
682 LLDB_INVALID_ADDRESS,// base address
683 0, // bitfield bit size
684 0); // bitfield bit offset
685 if (capped_data)
686 s << "...";
687 s << '"';
688 }
689 }
690 else
691 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000692 cstr_len = max_length;
693 const size_t k_max_buf_size = 64;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000694 data_buffer.resize (k_max_buf_size + 1);
695 // NULL terminate in case we don't get the entire C string
696 data_buffer.back() = '\0';
697
698 s << '"';
699
700 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
701 while ((bytes_read = target->ReadMemory (cstr_so_addr,
702 prefer_file_cache,
703 &data_buffer.front(),
704 k_max_buf_size,
705 error)) > 0)
706 {
707 size_t len = strlen(&data_buffer.front());
708 if (len == 0)
709 break;
710 if (len > bytes_read)
711 len = bytes_read;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000712 if (len > cstr_len)
713 len = cstr_len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000714
715 data.Dump (&s,
716 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000717 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000718 1, // Size of item (1 byte for a char!)
719 len, // How many bytes to print?
720 UINT32_MAX, // num per line
721 LLDB_INVALID_ADDRESS,// base address
722 0, // bitfield bit size
723 0); // bitfield bit offset
724
725 if (len < k_max_buf_size)
726 break;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000727 if (len >= cstr_len)
728 {
729 s << "...";
730 break;
731 }
732 cstr_len -= len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000733 cstr_so_addr.Slide (k_max_buf_size);
734 }
735 s << '"';
736 }
737 }
738 }
739 }
740 }
741 else
742 {
743 error.SetErrorString("impossible to read a string from this object");
744 }
745}
746
Jim Ingham53c47f12010-09-10 23:12:17 +0000747const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000748ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000749{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000750
Jim Ingham6035b672011-03-31 00:19:25 +0000751 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000752 return NULL;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000753
754 if (!m_object_desc_str.empty())
755 return m_object_desc_str.c_str();
756
Jim Ingham6035b672011-03-31 00:19:25 +0000757 ExecutionContextScope *exe_scope = GetExecutionContextScope();
758 if (exe_scope == NULL)
759 return NULL;
760
Jim Ingham53c47f12010-09-10 23:12:17 +0000761 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000762 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000763 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000764
Jim Ingham53c47f12010-09-10 23:12:17 +0000765 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000766
767 lldb::LanguageType language = GetObjectRuntimeLanguage();
768 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
769
Jim Inghama2cf2632010-12-23 02:29:54 +0000770 if (runtime == NULL)
771 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000772 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000773 clang_type_t opaque_qual_type = GetClangType();
774 if (opaque_qual_type != NULL)
775 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000776 bool is_signed;
777 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
778 || ClangASTContext::IsPointerType (opaque_qual_type))
779 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000780 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000781 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000782 }
783 }
784
Jim Ingham8d543de2011-03-31 23:01:21 +0000785 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000786 {
787 m_object_desc_str.append (s.GetData());
788 }
Sean Callanan672ad942010-10-23 00:18:49 +0000789
790 if (m_object_desc_str.empty())
791 return NULL;
792 else
793 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000794}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000795
796const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000797ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000798{
799 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000800 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000801 {
Jim Ingham6035b672011-03-31 00:19:25 +0000802 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000803 {
804 if (m_value_str.empty())
805 {
806 const Value::ContextType context_type = m_value.GetContextType();
807
808 switch (context_type)
809 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000810 case Value::eContextTypeClangType:
811 case Value::eContextTypeLLDBType:
812 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000813 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000814 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000815 if (clang_type)
816 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000817 if (m_last_value_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000818 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000819 m_value_str = m_last_value_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000820 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000821 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000822 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000823 StreamString sstr;
824 Format format = GetFormat();
825 if (format == eFormatDefault)
826 format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
827 ClangASTType::GetFormat(clang_type));
828
829 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
830 clang_type, // The clang type to display
831 &sstr,
832 format, // Format to display this type with
833 m_data, // Data to extract from
834 0, // Byte offset into "m_data"
835 GetByteSize(), // Byte size of item in "m_data"
836 GetBitfieldBitSize(), // Bitfield bit size
837 GetBitfieldBitOffset())) // Bitfield bit offset
838 m_value_str.swap(sstr.GetString());
839 else
840 {
841 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
842 m_data.GetByteSize(),
843 GetByteSize());
844 m_value_str.clear();
845 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000846 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000847 }
848 }
849 break;
850
Greg Clayton526e5af2010-11-13 03:52:47 +0000851 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000852 {
853 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
854 if (reg_info)
855 {
856 StreamString reg_sstr;
857 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
858 m_value_str.swap(reg_sstr.GetString());
859 }
860 }
861 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000862
863 default:
864 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865 }
866 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000867
868 if (!m_value_did_change && m_old_value_valid)
869 {
870 // The value was gotten successfully, so we consider the
871 // value as changed if the value string differs
872 SetValueDidChange (m_old_value_str != m_value_str);
873 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874 }
875 }
876 if (m_value_str.empty())
877 return NULL;
878 return m_value_str.c_str();
879}
880
Enrico Granata0a3958e2011-07-02 00:25:22 +0000881const char *
882ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
883 lldb::Format custom_format)
884{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000885
886 RefCounter ref(&m_dump_printable_counter);
887
Enrico Granata9dd75c82011-07-15 23:30:15 +0000888 if (custom_format != lldb::eFormatInvalid)
Enrico Granata0a3958e2011-07-02 00:25:22 +0000889 SetFormat(custom_format);
890
891 const char * return_value;
892
893 switch(val_obj_display)
894 {
895 case eDisplayValue:
896 return_value = GetValueAsCString();
897 break;
898 case eDisplaySummary:
899 return_value = GetSummaryAsCString();
900 break;
901 case eDisplayLanguageSpecific:
902 return_value = GetObjectDescription();
903 break;
Enrico Granataf2bbf712011-07-15 02:26:42 +0000904 case eDisplayLocation:
905 return_value = GetLocationAsCString();
906 break;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000907 }
908
Enrico Granataf4efecd2011-07-12 22:56:10 +0000909 // this code snippet might lead to endless recursion, thus we use a RefCounter here to
910 // check that we are not looping endlessly
911 if (!return_value && (m_dump_printable_counter < 3))
Enrico Granata9fc19442011-07-06 02:13:41 +0000912 {
913 // try to pick the other choice
914 if (val_obj_display == eDisplayValue)
915 return_value = GetSummaryAsCString();
916 else if (val_obj_display == eDisplaySummary)
917 return_value = GetValueAsCString();
Enrico Granata9fc19442011-07-06 02:13:41 +0000918 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000919
Enrico Granataf4efecd2011-07-12 22:56:10 +0000920 return (return_value ? return_value : "<error>");
Enrico Granata0a3958e2011-07-02 00:25:22 +0000921
922}
923
Enrico Granata9fc19442011-07-06 02:13:41 +0000924bool
925ValueObject::DumpPrintableRepresentation(Stream& s,
926 ValueObjectRepresentationStyle val_obj_display,
927 lldb::Format custom_format)
928{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000929
930 clang_type_t elem_or_pointee_type;
931 Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000932
Enrico Granataf4efecd2011-07-12 22:56:10 +0000933 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
934 && val_obj_display == ValueObject::eDisplayValue)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000935 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000936 // when being asked to get a printable display an array or pointer type directly,
937 // try to "do the right thing"
938
939 if (IsCStringContainer(true) &&
940 (custom_format == lldb::eFormatCString ||
941 custom_format == lldb::eFormatCharArray ||
942 custom_format == lldb::eFormatChar ||
943 custom_format == lldb::eFormatVectorOfChar)) // print char[] & char* directly
944 {
945 Error error;
946 ReadPointedString(s,
947 error,
948 0,
949 (custom_format == lldb::eFormatVectorOfChar) ||
950 (custom_format == lldb::eFormatCharArray));
951 return !error.Fail();
952 }
953
954 if (custom_format == lldb::eFormatEnum)
955 return false;
956
957 // this only works for arrays, because I have no way to know when
958 // the pointed memory ends, and no special \0 end of data marker
959 if (flags.Test(ClangASTContext::eTypeIsArray))
960 {
961 if ((custom_format == lldb::eFormatBytes) ||
962 (custom_format == lldb::eFormatBytesWithASCII))
963 {
964 uint32_t count = GetNumChildren();
965
966 s << '[';
967 for (uint32_t low = 0; low < count; low++)
968 {
969
970 if (low)
971 s << ',';
972
973 ValueObjectSP child = GetChildAtIndex(low,true);
974 if (!child.get())
975 {
976 s << "<error>";
977 continue;
978 }
979 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format);
980 }
981
982 s << ']';
983
984 return true;
985 }
986
987 if ((custom_format == lldb::eFormatVectorOfChar) ||
988 (custom_format == lldb::eFormatVectorOfFloat32) ||
989 (custom_format == lldb::eFormatVectorOfFloat64) ||
990 (custom_format == lldb::eFormatVectorOfSInt16) ||
991 (custom_format == lldb::eFormatVectorOfSInt32) ||
992 (custom_format == lldb::eFormatVectorOfSInt64) ||
993 (custom_format == lldb::eFormatVectorOfSInt8) ||
994 (custom_format == lldb::eFormatVectorOfUInt128) ||
995 (custom_format == lldb::eFormatVectorOfUInt16) ||
996 (custom_format == lldb::eFormatVectorOfUInt32) ||
997 (custom_format == lldb::eFormatVectorOfUInt64) ||
998 (custom_format == lldb::eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
999 {
1000 uint32_t count = GetNumChildren();
1001
1002 lldb::Format format = FormatManager::GetSingleItemFormat(custom_format);
1003
1004 s << '[';
1005 for (uint32_t low = 0; low < count; low++)
1006 {
1007
1008 if (low)
1009 s << ',';
1010
1011 ValueObjectSP child = GetChildAtIndex(low,true);
1012 if (!child.get())
1013 {
1014 s << "<error>";
1015 continue;
1016 }
1017 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format);
1018 }
1019
1020 s << ']';
1021
1022 return true;
1023 }
1024 }
1025
1026 if ((custom_format == lldb::eFormatBoolean) ||
1027 (custom_format == lldb::eFormatBinary) ||
1028 (custom_format == lldb::eFormatChar) ||
1029 (custom_format == lldb::eFormatCharPrintable) ||
1030 (custom_format == lldb::eFormatComplexFloat) ||
1031 (custom_format == lldb::eFormatDecimal) ||
1032 (custom_format == lldb::eFormatHex) ||
1033 (custom_format == lldb::eFormatFloat) ||
1034 (custom_format == lldb::eFormatOctal) ||
1035 (custom_format == lldb::eFormatOSType) ||
1036 (custom_format == lldb::eFormatUnicode16) ||
1037 (custom_format == lldb::eFormatUnicode32) ||
1038 (custom_format == lldb::eFormatUnsigned) ||
1039 (custom_format == lldb::eFormatPointer) ||
1040 (custom_format == lldb::eFormatComplexInteger) ||
1041 (custom_format == lldb::eFormatComplex) ||
1042 (custom_format == lldb::eFormatDefault)) // use the [] operator
1043 return false;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001044 }
Enrico Granataf4efecd2011-07-12 22:56:10 +00001045 const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
Enrico Granata9dd75c82011-07-15 23:30:15 +00001046 if (targetvalue)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001047 s.PutCString(targetvalue);
1048 bool var_success = (targetvalue != NULL);
Enrico Granata9dd75c82011-07-15 23:30:15 +00001049 if (custom_format != eFormatInvalid)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001050 SetFormat(eFormatDefault);
1051 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001052}
1053
Greg Clayton737b9322010-09-13 03:32:57 +00001054addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001055ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +00001056{
Jim Ingham78a685a2011-04-16 00:01:13 +00001057 if (!UpdateValueIfNeeded())
1058 return LLDB_INVALID_ADDRESS;
1059
Greg Clayton73b472d2010-10-27 03:32:59 +00001060 switch (m_value.GetValueType())
1061 {
1062 case Value::eValueTypeScalar:
1063 if (scalar_is_load_address)
1064 {
1065 address_type = eAddressTypeLoad;
1066 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1067 }
1068 break;
1069
1070 case Value::eValueTypeLoadAddress:
1071 case Value::eValueTypeFileAddress:
1072 case Value::eValueTypeHostAddress:
1073 {
1074 address_type = m_value.GetValueAddressType ();
1075 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1076 }
1077 break;
1078 }
1079 address_type = eAddressTypeInvalid;
1080 return LLDB_INVALID_ADDRESS;
1081}
1082
1083addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001084ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +00001085{
1086 lldb::addr_t address = LLDB_INVALID_ADDRESS;
1087 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +00001088
1089 if (!UpdateValueIfNeeded())
1090 return address;
1091
Greg Clayton73b472d2010-10-27 03:32:59 +00001092 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +00001093 {
1094 case Value::eValueTypeScalar:
1095 if (scalar_is_load_address)
1096 {
1097 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1098 address_type = eAddressTypeLoad;
1099 }
1100 break;
1101
1102 case Value::eValueTypeLoadAddress:
1103 case Value::eValueTypeFileAddress:
1104 case Value::eValueTypeHostAddress:
1105 {
1106 uint32_t data_offset = 0;
1107 address = m_data.GetPointer(&data_offset);
1108 address_type = m_value.GetValueAddressType();
1109 if (address_type == eAddressTypeInvalid)
1110 address_type = eAddressTypeLoad;
1111 }
1112 break;
1113 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001114
1115 if (m_pointers_point_to_load_addrs)
1116 address_type = eAddressTypeLoad;
1117
Greg Clayton737b9322010-09-13 03:32:57 +00001118 return address;
1119}
1120
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001121bool
Jim Ingham6035b672011-03-31 00:19:25 +00001122ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001123{
1124 // Make sure our value is up to date first so that our location and location
1125 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +00001126 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001127 return false;
1128
1129 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001130 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001131
1132 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +00001133 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001134 switch (encoding)
1135 {
1136 case eEncodingInvalid:
1137 return false;
1138
1139 case eEncodingUint:
1140 if (byte_size > sizeof(unsigned long long))
1141 {
1142 return false;
1143 }
1144 else
1145 {
1146 unsigned long long ull_val = strtoull(value_str, &end, 0);
1147 if (end && *end != '\0')
1148 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001149 m_value.GetScalar() = ull_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001150 // Limit the bytes in our m_data appropriately.
1151 m_value.GetScalar().GetData (m_data, byte_size);
1152 }
1153 break;
1154
1155 case eEncodingSint:
1156 if (byte_size > sizeof(long long))
1157 {
1158 return false;
1159 }
1160 else
1161 {
1162 long long sll_val = strtoll(value_str, &end, 0);
1163 if (end && *end != '\0')
1164 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001165 m_value.GetScalar() = sll_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001166 // Limit the bytes in our m_data appropriately.
1167 m_value.GetScalar().GetData (m_data, byte_size);
1168 }
1169 break;
1170
1171 case eEncodingIEEE754:
1172 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001173 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +00001174 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001175 if (dst != NULL)
1176 {
1177 // We are decoding a float into host byte order below, so make
1178 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +00001179 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
1181 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +00001182 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001183 value_str,
1184 dst,
1185 byte_size);
1186
1187 if (converted_byte_size == byte_size)
1188 {
1189 }
1190 }
1191 }
1192 break;
1193
1194 case eEncodingVector:
1195 return false;
1196
1197 default:
1198 return false;
1199 }
1200
1201 // If we have made it here the value is in m_data and we should write it
1202 // out to the target
1203 return Write ();
1204}
1205
1206bool
1207ValueObject::Write ()
1208{
1209 // Clear the update ID so the next time we try and read the value
1210 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +00001211 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001212
1213 // TODO: when Value has a method to write a value back, call it from here.
1214 return false;
1215
1216}
1217
Jim Ingham5a369122010-09-28 01:25:32 +00001218lldb::LanguageType
1219ValueObject::GetObjectRuntimeLanguage ()
1220{
Greg Clayton73b472d2010-10-27 03:32:59 +00001221 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +00001222 if (opaque_qual_type == NULL)
1223 return lldb::eLanguageTypeC;
1224
1225 // If the type is a reference, then resolve it to what it refers to first:
1226 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
1227 if (qual_type->isAnyPointerType())
1228 {
1229 if (qual_type->isObjCObjectPointerType())
1230 return lldb::eLanguageTypeObjC;
1231
1232 clang::QualType pointee_type (qual_type->getPointeeType());
1233 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
1234 return lldb::eLanguageTypeC_plus_plus;
1235 if (pointee_type->isObjCObjectOrInterfaceType())
1236 return lldb::eLanguageTypeObjC;
1237 if (pointee_type->isObjCClassType())
1238 return lldb::eLanguageTypeObjC;
1239 }
1240 else
1241 {
1242 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
1243 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +00001244 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +00001245 return lldb::eLanguageTypeC_plus_plus;
1246 }
1247
1248 return lldb::eLanguageTypeC;
1249}
1250
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001251void
Jim Ingham58b59f92011-04-22 23:53:53 +00001252ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001253{
Jim Ingham58b59f92011-04-22 23:53:53 +00001254 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255}
1256
1257ValueObjectSP
1258ValueObject::GetSyntheticChild (const ConstString &key) const
1259{
1260 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +00001261 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001262 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +00001263 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001264 return synthetic_child_sp;
1265}
1266
1267bool
1268ValueObject::IsPointerType ()
1269{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001270 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001271}
1272
Jim Inghamb7603bb2011-03-18 00:05:18 +00001273bool
Greg Claytondaf515f2011-07-09 20:12:33 +00001274ValueObject::IsArrayType ()
1275{
1276 return ClangASTContext::IsArrayType (GetClangType());
1277}
1278
1279bool
Enrico Granata9fc19442011-07-06 02:13:41 +00001280ValueObject::IsScalarType ()
1281{
1282 return ClangASTContext::IsScalarType (GetClangType());
1283}
1284
1285bool
Jim Inghamb7603bb2011-03-18 00:05:18 +00001286ValueObject::IsIntegerType (bool &is_signed)
1287{
1288 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
1289}
Greg Clayton73b472d2010-10-27 03:32:59 +00001290
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001291bool
1292ValueObject::IsPointerOrReferenceType ()
1293{
Greg Clayton007d5be2011-05-30 00:49:24 +00001294 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
1295}
1296
1297bool
1298ValueObject::IsPossibleCPlusPlusDynamicType ()
1299{
1300 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001301}
1302
Greg Claytondea8cb42011-06-29 22:09:02 +00001303bool
1304ValueObject::IsPossibleDynamicType ()
1305{
1306 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
1307}
1308
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001309ValueObjectSP
1310ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
1311{
1312 ValueObjectSP synthetic_child_sp;
1313 if (IsPointerType ())
1314 {
1315 char index_str[64];
1316 snprintf(index_str, sizeof(index_str), "[%i]", index);
1317 ConstString index_const_str(index_str);
1318 // Check if we have already created a synthetic array member in this
1319 // valid object. If we have we will re-use it.
1320 synthetic_child_sp = GetSyntheticChild (index_const_str);
1321 if (!synthetic_child_sp)
1322 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001323 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001324 // We haven't made a synthetic array member for INDEX yet, so
1325 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001326 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001327
1328 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001329 if (synthetic_child)
1330 {
1331 AddSyntheticChild(index_const_str, synthetic_child);
1332 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata0a3958e2011-07-02 00:25:22 +00001333 synthetic_child_sp->SetName(index_str);
1334 synthetic_child_sp->m_is_array_item_for_pointer = true;
Jim Ingham58b59f92011-04-22 23:53:53 +00001335 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001336 }
1337 }
1338 return synthetic_child_sp;
1339}
Jim Ingham22777012010-09-23 02:01:19 +00001340
Greg Claytondaf515f2011-07-09 20:12:33 +00001341// This allows you to create an array member using and index
1342// that doesn't not fall in the normal bounds of the array.
1343// Many times structure can be defined as:
1344// struct Collection
1345// {
1346// uint32_t item_count;
1347// Item item_array[0];
1348// };
1349// The size of the "item_array" is 1, but many times in practice
1350// there are more items in "item_array".
1351
1352ValueObjectSP
1353ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create)
1354{
1355 ValueObjectSP synthetic_child_sp;
1356 if (IsArrayType ())
1357 {
1358 char index_str[64];
1359 snprintf(index_str, sizeof(index_str), "[%i]", index);
1360 ConstString index_const_str(index_str);
1361 // Check if we have already created a synthetic array member in this
1362 // valid object. If we have we will re-use it.
1363 synthetic_child_sp = GetSyntheticChild (index_const_str);
1364 if (!synthetic_child_sp)
1365 {
1366 ValueObject *synthetic_child;
1367 // We haven't made a synthetic array member for INDEX yet, so
1368 // lets make one and cache it for any future reference.
1369 synthetic_child = CreateChildAtIndex(0, true, index);
1370
1371 // Cache the value if we got one back...
1372 if (synthetic_child)
1373 {
1374 AddSyntheticChild(index_const_str, synthetic_child);
1375 synthetic_child_sp = synthetic_child->GetSP();
1376 synthetic_child_sp->SetName(index_str);
1377 synthetic_child_sp->m_is_array_item_for_pointer = true;
1378 }
1379 }
1380 }
1381 return synthetic_child_sp;
1382}
1383
Enrico Granata9fc19442011-07-06 02:13:41 +00001384ValueObjectSP
1385ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
1386{
1387 ValueObjectSP synthetic_child_sp;
1388 if (IsScalarType ())
1389 {
1390 char index_str[64];
1391 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1392 ConstString index_const_str(index_str);
1393 // Check if we have already created a synthetic array member in this
1394 // valid object. If we have we will re-use it.
1395 synthetic_child_sp = GetSyntheticChild (index_const_str);
1396 if (!synthetic_child_sp)
1397 {
1398 ValueObjectChild *synthetic_child;
1399 // We haven't made a synthetic array member for INDEX yet, so
1400 // lets make one and cache it for any future reference.
1401 synthetic_child = new ValueObjectChild(*this,
1402 GetClangAST(),
1403 GetClangType(),
1404 index_const_str,
1405 GetByteSize(),
1406 0,
1407 to-from+1,
1408 from,
1409 false,
1410 false);
1411
1412 // Cache the value if we got one back...
1413 if (synthetic_child)
1414 {
1415 AddSyntheticChild(index_const_str, synthetic_child);
1416 synthetic_child_sp = synthetic_child->GetSP();
1417 synthetic_child_sp->SetName(index_str);
1418 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1419 }
1420 }
1421 }
1422 return synthetic_child_sp;
1423}
1424
Jim Ingham78a685a2011-04-16 00:01:13 +00001425void
Jim Ingham2837b762011-05-04 03:43:18 +00001426ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001427{
Jim Ingham2837b762011-05-04 03:43:18 +00001428 if (use_dynamic == lldb::eNoDynamicValues)
1429 return;
1430
Jim Ingham58b59f92011-04-22 23:53:53 +00001431 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001432 {
1433 Process *process = m_update_point.GetProcess();
1434 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001435
Jim Ingham78a685a2011-04-16 00:01:13 +00001436
1437 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1438 // hard code this everywhere.
1439 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1440 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1441 {
1442 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1443 if (runtime)
1444 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1445 }
1446 else
1447 {
1448 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1449 if (cpp_runtime)
1450 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1451
1452 if (!worth_having_dynamic_value)
1453 {
1454 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1455 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001456 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001457 }
1458 }
1459
1460 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001461 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001462
1463// if (worth_having_dynamic_value)
1464// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1465
Jim Ingham78a685a2011-04-16 00:01:13 +00001466 }
1467}
1468
Jim Ingham58b59f92011-04-22 23:53:53 +00001469ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001470ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001471{
Jim Ingham2837b762011-05-04 03:43:18 +00001472 if (use_dynamic == lldb::eNoDynamicValues)
1473 return ValueObjectSP();
1474
1475 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001476 {
Jim Ingham2837b762011-05-04 03:43:18 +00001477 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001478 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001479 if (m_dynamic_value)
1480 return m_dynamic_value->GetSP();
1481 else
1482 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001483}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001484
Greg Claytone221f822011-01-21 01:59:00 +00001485bool
1486ValueObject::GetBaseClassPath (Stream &s)
1487{
1488 if (IsBaseClass())
1489 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001490 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001491 clang_type_t clang_type = GetClangType();
1492 std::string cxx_class_name;
1493 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1494 if (this_had_base_class)
1495 {
1496 if (parent_had_base_class)
1497 s.PutCString("::");
1498 s.PutCString(cxx_class_name.c_str());
1499 }
1500 return parent_had_base_class || this_had_base_class;
1501 }
1502 return false;
1503}
1504
1505
1506ValueObject *
1507ValueObject::GetNonBaseClassParent()
1508{
Jim Ingham78a685a2011-04-16 00:01:13 +00001509 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001510 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001511 if (GetParent()->IsBaseClass())
1512 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001513 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001514 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001515 }
1516 return NULL;
1517}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001518
1519void
Enrico Granata4becb372011-06-29 22:27:15 +00001520ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001521{
Greg Claytone221f822011-01-21 01:59:00 +00001522 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00001523
Enrico Granata9dd75c82011-07-15 23:30:15 +00001524 if (is_deref_of_parent && epformat == eDereferencePointers) {
Enrico Granata4becb372011-06-29 22:27:15 +00001525 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
1526 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
1527 // the eHonorPointers mode is meant to produce strings in this latter format
1528 s.PutCString("*(");
1529 }
Greg Claytone221f822011-01-21 01:59:00 +00001530
Enrico Granata4becb372011-06-29 22:27:15 +00001531 ValueObject* parent = GetParent();
1532
1533 if (parent)
1534 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
Enrico Granata0a3958e2011-07-02 00:25:22 +00001535
1536 // if we are a deref_of_parent just because we are synthetic array
1537 // members made up to allow ptr[%d] syntax to work in variable
1538 // printing, then add our name ([%d]) to the expression path
Enrico Granata9dd75c82011-07-15 23:30:15 +00001539 if (m_is_array_item_for_pointer && epformat == eHonorPointers)
Enrico Granata0a3958e2011-07-02 00:25:22 +00001540 s.PutCString(m_name.AsCString());
Enrico Granata4becb372011-06-29 22:27:15 +00001541
Greg Claytone221f822011-01-21 01:59:00 +00001542 if (!IsBaseClass())
1543 {
1544 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001545 {
Greg Claytone221f822011-01-21 01:59:00 +00001546 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1547 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001548 {
Greg Claytone221f822011-01-21 01:59:00 +00001549 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1550 if (non_base_class_parent_clang_type)
1551 {
1552 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1553
Enrico Granata9dd75c82011-07-15 23:30:15 +00001554 if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00001555 {
1556 s.PutCString("->");
1557 }
Enrico Granata4becb372011-06-29 22:27:15 +00001558 else
1559 {
1560 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1561 {
1562 s.PutCString("->");
1563 }
1564 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1565 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1566 {
1567 s.PutChar('.');
1568 }
Greg Claytone221f822011-01-21 01:59:00 +00001569 }
1570 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001571 }
Greg Claytone221f822011-01-21 01:59:00 +00001572
1573 const char *name = GetName().GetCString();
1574 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001575 {
Greg Claytone221f822011-01-21 01:59:00 +00001576 if (qualify_cxx_base_classes)
1577 {
1578 if (GetBaseClassPath (s))
1579 s.PutCString("::");
1580 }
1581 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001582 }
1583 }
1584 }
1585
Enrico Granata4becb372011-06-29 22:27:15 +00001586 if (is_deref_of_parent && epformat == eDereferencePointers) {
Greg Claytone221f822011-01-21 01:59:00 +00001587 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00001588 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001589}
1590
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001591lldb::ValueObjectSP
1592ValueObject::GetValueForExpressionPath(const char* expression,
1593 const char** first_unparsed,
1594 ExpressionPathScanEndReason* reason_to_stop,
1595 ExpressionPathEndResultType* final_value_type,
1596 const GetValueForExpressionPathOptions& options,
1597 ExpressionPathAftermath* final_task_on_target)
1598{
1599
1600 const char* dummy_first_unparsed;
1601 ExpressionPathScanEndReason dummy_reason_to_stop;
1602 ExpressionPathEndResultType dummy_final_value_type;
1603 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1604
1605 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1606 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1607 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1608 final_value_type ? final_value_type : &dummy_final_value_type,
1609 options,
1610 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1611
1612 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1613 {
1614 return ret_val;
1615 }
1616 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1617 {
1618 if (*final_task_on_target == ValueObject::eDereference)
1619 {
1620 Error error;
1621 ValueObjectSP final_value = ret_val->Dereference(error);
1622 if (error.Fail() || !final_value.get())
1623 {
1624 *reason_to_stop = ValueObject::eDereferencingFailed;
1625 *final_value_type = ValueObject::eInvalid;
1626 return ValueObjectSP();
1627 }
1628 else
1629 {
1630 *final_task_on_target = ValueObject::eNothing;
1631 return final_value;
1632 }
1633 }
1634 if (*final_task_on_target == ValueObject::eTakeAddress)
1635 {
1636 Error error;
1637 ValueObjectSP final_value = ret_val->AddressOf(error);
1638 if (error.Fail() || !final_value.get())
1639 {
1640 *reason_to_stop = ValueObject::eTakingAddressFailed;
1641 *final_value_type = ValueObject::eInvalid;
1642 return ValueObjectSP();
1643 }
1644 else
1645 {
1646 *final_task_on_target = ValueObject::eNothing;
1647 return final_value;
1648 }
1649 }
1650 }
1651 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
1652}
1653
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001654int
1655ValueObject::GetValuesForExpressionPath(const char* expression,
1656 lldb::ValueObjectListSP& list,
1657 const char** first_unparsed,
1658 ExpressionPathScanEndReason* reason_to_stop,
1659 ExpressionPathEndResultType* final_value_type,
1660 const GetValueForExpressionPathOptions& options,
1661 ExpressionPathAftermath* final_task_on_target)
1662{
1663 const char* dummy_first_unparsed;
1664 ExpressionPathScanEndReason dummy_reason_to_stop;
1665 ExpressionPathEndResultType dummy_final_value_type;
1666 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1667
1668 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1669 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1670 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1671 final_value_type ? final_value_type : &dummy_final_value_type,
1672 options,
1673 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1674
1675 if (!ret_val.get()) // if there are errors, I add nothing to the list
1676 return 0;
1677
1678 if (*reason_to_stop != eArrayRangeOperatorMet)
1679 {
1680 // I need not expand a range, just post-process the final value and return
1681 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1682 {
1683 list->Append(ret_val);
1684 return 1;
1685 }
1686 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1687 {
1688 if (*final_task_on_target == ValueObject::eDereference)
1689 {
1690 Error error;
1691 ValueObjectSP final_value = ret_val->Dereference(error);
1692 if (error.Fail() || !final_value.get())
1693 {
1694 *reason_to_stop = ValueObject::eDereferencingFailed;
1695 *final_value_type = ValueObject::eInvalid;
1696 return 0;
1697 }
1698 else
1699 {
1700 *final_task_on_target = ValueObject::eNothing;
1701 list->Append(final_value);
1702 return 1;
1703 }
1704 }
1705 if (*final_task_on_target == ValueObject::eTakeAddress)
1706 {
1707 Error error;
1708 ValueObjectSP final_value = ret_val->AddressOf(error);
1709 if (error.Fail() || !final_value.get())
1710 {
1711 *reason_to_stop = ValueObject::eTakingAddressFailed;
1712 *final_value_type = ValueObject::eInvalid;
1713 return 0;
1714 }
1715 else
1716 {
1717 *final_task_on_target = ValueObject::eNothing;
1718 list->Append(final_value);
1719 return 1;
1720 }
1721 }
1722 }
1723 }
1724 else
1725 {
1726 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
1727 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1728 ret_val,
1729 list,
1730 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1731 final_value_type ? final_value_type : &dummy_final_value_type,
1732 options,
1733 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1734 }
1735 // in any non-covered case, just do the obviously right thing
1736 list->Append(ret_val);
1737 return 1;
1738}
1739
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001740lldb::ValueObjectSP
1741ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
1742 const char** first_unparsed,
1743 ExpressionPathScanEndReason* reason_to_stop,
1744 ExpressionPathEndResultType* final_result,
1745 const GetValueForExpressionPathOptions& options,
1746 ExpressionPathAftermath* what_next)
1747{
1748 ValueObjectSP root = GetSP();
1749
1750 if (!root.get())
1751 return ValueObjectSP();
1752
1753 *first_unparsed = expression_cstr;
1754
1755 while (true)
1756 {
1757
1758 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
1759
1760 lldb::clang_type_t root_clang_type = root->GetClangType();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001761 lldb::clang_type_t pointee_clang_type;
1762 Flags root_clang_type_info,pointee_clang_type_info;
1763
1764 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
1765 if (pointee_clang_type)
1766 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001767
1768 if (!expression_cstr || *expression_cstr == '\0')
1769 {
1770 *reason_to_stop = ValueObject::eEndOfString;
1771 return root;
1772 }
1773
1774 switch (*expression_cstr)
1775 {
1776 case '-':
1777 {
1778 if (options.m_check_dot_vs_arrow_syntax &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001779 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001780 {
1781 *first_unparsed = expression_cstr;
1782 *reason_to_stop = ValueObject::eArrowInsteadOfDot;
1783 *final_result = ValueObject::eInvalid;
1784 return ValueObjectSP();
1785 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001786 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
1787 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) &&
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001788 options.m_no_fragile_ivar)
1789 {
1790 *first_unparsed = expression_cstr;
1791 *reason_to_stop = ValueObject::eFragileIVarNotAllowed;
1792 *final_result = ValueObject::eInvalid;
1793 return ValueObjectSP();
1794 }
1795 if (expression_cstr[1] != '>')
1796 {
1797 *first_unparsed = expression_cstr;
1798 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1799 *final_result = ValueObject::eInvalid;
1800 return ValueObjectSP();
1801 }
1802 expression_cstr++; // skip the -
1803 }
1804 case '.': // or fallthrough from ->
1805 {
1806 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001807 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001808 {
1809 *first_unparsed = expression_cstr;
1810 *reason_to_stop = ValueObject::eDotInsteadOfArrow;
1811 *final_result = ValueObject::eInvalid;
1812 return ValueObjectSP();
1813 }
1814 expression_cstr++; // skip .
1815 const char *next_separator = strpbrk(expression_cstr+1,"-.[");
1816 ConstString child_name;
1817 if (!next_separator) // if no other separator just expand this last layer
1818 {
1819 child_name.SetCString (expression_cstr);
1820 root = root->GetChildMemberWithName(child_name, true);
1821 if (root.get()) // we know we are done, so just return
1822 {
1823 *first_unparsed = '\0';
1824 *reason_to_stop = ValueObject::eEndOfString;
1825 *final_result = ValueObject::ePlain;
1826 return root;
1827 }
1828 else
1829 {
1830 *first_unparsed = expression_cstr;
1831 *reason_to_stop = ValueObject::eNoSuchChild;
1832 *final_result = ValueObject::eInvalid;
1833 return ValueObjectSP();
1834 }
1835 }
1836 else // other layers do expand
1837 {
1838 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
1839 root = root->GetChildMemberWithName(child_name, true);
1840 if (root.get()) // store the new root and move on
1841 {
1842 *first_unparsed = next_separator;
1843 *final_result = ValueObject::ePlain;
1844 continue;
1845 }
1846 else
1847 {
1848 *first_unparsed = expression_cstr;
1849 *reason_to_stop = ValueObject::eNoSuchChild;
1850 *final_result = ValueObject::eInvalid;
1851 return ValueObjectSP();
1852 }
1853 }
1854 break;
1855 }
1856 case '[':
1857 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001858 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001859 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001860 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001861 {
1862 *first_unparsed = expression_cstr;
1863 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
1864 *final_result = ValueObject::eInvalid;
1865 return ValueObjectSP();
1866 }
1867 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
1868 {
1869 *first_unparsed = expression_cstr;
1870 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
1871 *final_result = ValueObject::eInvalid;
1872 return ValueObjectSP();
1873 }
1874 }
1875 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
1876 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001877 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001878 {
1879 *first_unparsed = expression_cstr;
1880 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
1881 *final_result = ValueObject::eInvalid;
1882 return ValueObjectSP();
1883 }
1884 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
1885 {
1886 *first_unparsed = expression_cstr+2;
1887 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
1888 *final_result = ValueObject::eUnboundedRange;
1889 return root;
1890 }
1891 }
1892 const char *separator_position = ::strchr(expression_cstr+1,'-');
1893 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
1894 if (!close_bracket_position) // if there is no ], this is a syntax error
1895 {
1896 *first_unparsed = expression_cstr;
1897 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1898 *final_result = ValueObject::eInvalid;
1899 return ValueObjectSP();
1900 }
1901 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
1902 {
1903 char *end = NULL;
1904 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
1905 if (!end || end != close_bracket_position) // if something weird is in our way return an error
1906 {
1907 *first_unparsed = expression_cstr;
1908 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1909 *final_result = ValueObject::eInvalid;
1910 return ValueObjectSP();
1911 }
1912 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
1913 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001914 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001915 {
1916 *first_unparsed = expression_cstr+2;
1917 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
1918 *final_result = ValueObject::eUnboundedRange;
1919 return root;
1920 }
1921 else
1922 {
1923 *first_unparsed = expression_cstr;
1924 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
1925 *final_result = ValueObject::eInvalid;
1926 return ValueObjectSP();
1927 }
1928 }
1929 // from here on we do have a valid index
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001930 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001931 {
Greg Claytondaf515f2011-07-09 20:12:33 +00001932 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
1933 if (!child_valobj_sp)
1934 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
1935 if (child_valobj_sp)
1936 {
1937 root = child_valobj_sp;
1938 *first_unparsed = end+1; // skip ]
1939 *final_result = ValueObject::ePlain;
1940 continue;
1941 }
1942 else
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001943 {
1944 *first_unparsed = expression_cstr;
1945 *reason_to_stop = ValueObject::eNoSuchChild;
1946 *final_result = ValueObject::eInvalid;
1947 return ValueObjectSP();
1948 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001949 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001950 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001951 {
1952 if (*what_next == ValueObject::eDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001953 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001954 {
1955 Error error;
1956 root = root->Dereference(error);
1957 if (error.Fail() || !root.get())
1958 {
1959 *first_unparsed = expression_cstr;
1960 *reason_to_stop = ValueObject::eDereferencingFailed;
1961 *final_result = ValueObject::eInvalid;
1962 return ValueObjectSP();
1963 }
1964 else
1965 {
1966 *what_next = eNothing;
1967 continue;
1968 }
1969 }
1970 else
1971 {
1972 root = root->GetSyntheticArrayMemberFromPointer(index, true);
1973 if (!root.get())
1974 {
1975 *first_unparsed = expression_cstr;
1976 *reason_to_stop = ValueObject::eNoSuchChild;
1977 *final_result = ValueObject::eInvalid;
1978 return ValueObjectSP();
1979 }
1980 else
1981 {
1982 *first_unparsed = end+1; // skip ]
1983 *final_result = ValueObject::ePlain;
1984 continue;
1985 }
1986 }
1987 }
1988 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
1989 {
1990 root = root->GetSyntheticBitFieldChild(index, index, true);
1991 if (!root.get())
1992 {
1993 *first_unparsed = expression_cstr;
1994 *reason_to_stop = ValueObject::eNoSuchChild;
1995 *final_result = ValueObject::eInvalid;
1996 return ValueObjectSP();
1997 }
1998 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
1999 {
2000 *first_unparsed = end+1; // skip ]
2001 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2002 *final_result = ValueObject::eBitfield;
2003 return root;
2004 }
2005 }
2006 }
2007 else // we have a low and a high index
2008 {
2009 char *end = NULL;
2010 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2011 if (!end || end != separator_position) // if something weird is in our way return an error
2012 {
2013 *first_unparsed = expression_cstr;
2014 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2015 *final_result = ValueObject::eInvalid;
2016 return ValueObjectSP();
2017 }
2018 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2019 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2020 {
2021 *first_unparsed = expression_cstr;
2022 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2023 *final_result = ValueObject::eInvalid;
2024 return ValueObjectSP();
2025 }
2026 if (index_lower > index_higher) // swap indices if required
2027 {
2028 unsigned long temp = index_lower;
2029 index_lower = index_higher;
2030 index_higher = temp;
2031 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002032 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002033 {
2034 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2035 if (!root.get())
2036 {
2037 *first_unparsed = expression_cstr;
2038 *reason_to_stop = ValueObject::eNoSuchChild;
2039 *final_result = ValueObject::eInvalid;
2040 return ValueObjectSP();
2041 }
2042 else
2043 {
2044 *first_unparsed = end+1; // skip ]
2045 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2046 *final_result = ValueObject::eBitfield;
2047 return root;
2048 }
2049 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002050 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002051 *what_next == ValueObject::eDereference &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002052 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002053 {
2054 Error error;
2055 root = root->Dereference(error);
2056 if (error.Fail() || !root.get())
2057 {
2058 *first_unparsed = expression_cstr;
2059 *reason_to_stop = ValueObject::eDereferencingFailed;
2060 *final_result = ValueObject::eInvalid;
2061 return ValueObjectSP();
2062 }
2063 else
2064 {
2065 *what_next = ValueObject::eNothing;
2066 continue;
2067 }
2068 }
2069 else
2070 {
2071 *first_unparsed = expression_cstr;
2072 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2073 *final_result = ValueObject::eBoundedRange;
2074 return root;
2075 }
2076 }
2077 break;
2078 }
2079 default: // some non-separator is in the way
2080 {
2081 *first_unparsed = expression_cstr;
2082 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2083 *final_result = ValueObject::eInvalid;
2084 return ValueObjectSP();
2085 break;
2086 }
2087 }
2088 }
2089}
2090
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002091int
2092ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
2093 const char** first_unparsed,
2094 lldb::ValueObjectSP root,
2095 lldb::ValueObjectListSP& list,
2096 ExpressionPathScanEndReason* reason_to_stop,
2097 ExpressionPathEndResultType* final_result,
2098 const GetValueForExpressionPathOptions& options,
2099 ExpressionPathAftermath* what_next)
2100{
2101 if (!root.get())
2102 return 0;
2103
2104 *first_unparsed = expression_cstr;
2105
2106 while (true)
2107 {
2108
2109 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
2110
2111 lldb::clang_type_t root_clang_type = root->GetClangType();
2112 lldb::clang_type_t pointee_clang_type;
2113 Flags root_clang_type_info,pointee_clang_type_info;
2114
2115 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
2116 if (pointee_clang_type)
2117 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
2118
2119 if (!expression_cstr || *expression_cstr == '\0')
2120 {
2121 *reason_to_stop = ValueObject::eEndOfString;
2122 list->Append(root);
2123 return 1;
2124 }
2125
2126 switch (*expression_cstr)
2127 {
2128 case '[':
2129 {
2130 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
2131 {
2132 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
2133 {
2134 *first_unparsed = expression_cstr;
2135 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2136 *final_result = ValueObject::eInvalid;
2137 return 0;
2138 }
2139 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2140 {
2141 *first_unparsed = expression_cstr;
2142 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2143 *final_result = ValueObject::eInvalid;
2144 return 0;
2145 }
2146 }
2147 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2148 {
2149 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2150 {
2151 *first_unparsed = expression_cstr;
2152 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2153 *final_result = ValueObject::eInvalid;
2154 return 0;
2155 }
2156 else // expand this into list
2157 {
2158 int max_index = root->GetNumChildren() - 1;
2159 for (int index = 0; index < max_index; index++)
2160 {
2161 ValueObjectSP child =
2162 root->GetChildAtIndex(index, true);
2163 list->Append(child);
2164 }
2165 *first_unparsed = expression_cstr+2;
2166 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2167 *final_result = ValueObject::eValueObjectList;
2168 return max_index; // tell me number of items I added to the VOList
2169 }
2170 }
2171 const char *separator_position = ::strchr(expression_cstr+1,'-');
2172 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2173 if (!close_bracket_position) // if there is no ], this is a syntax error
2174 {
2175 *first_unparsed = expression_cstr;
2176 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2177 *final_result = ValueObject::eInvalid;
2178 return 0;
2179 }
2180 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2181 {
2182 char *end = NULL;
2183 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2184 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2185 {
2186 *first_unparsed = expression_cstr;
2187 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2188 *final_result = ValueObject::eInvalid;
2189 return 0;
2190 }
2191 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2192 {
2193 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2194 {
2195 int max_index = root->GetNumChildren() - 1;
2196 for (int index = 0; index < max_index; index++)
2197 {
2198 ValueObjectSP child =
2199 root->GetChildAtIndex(index, true);
2200 list->Append(child);
2201 }
2202 *first_unparsed = expression_cstr+2;
2203 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2204 *final_result = ValueObject::eValueObjectList;
2205 return max_index; // tell me number of items I added to the VOList
2206 }
2207 else
2208 {
2209 *first_unparsed = expression_cstr;
2210 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2211 *final_result = ValueObject::eInvalid;
2212 return 0;
2213 }
2214 }
2215 // from here on we do have a valid index
2216 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2217 {
2218 root = root->GetChildAtIndex(index, true);
2219 if (!root.get())
2220 {
2221 *first_unparsed = expression_cstr;
2222 *reason_to_stop = ValueObject::eNoSuchChild;
2223 *final_result = ValueObject::eInvalid;
2224 return 0;
2225 }
2226 else
2227 {
2228 list->Append(root);
2229 *first_unparsed = end+1; // skip ]
2230 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2231 *final_result = ValueObject::eValueObjectList;
2232 return 1;
2233 }
2234 }
2235 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
2236 {
2237 if (*what_next == ValueObject::eDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
2238 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2239 {
2240 Error error;
2241 root = root->Dereference(error);
2242 if (error.Fail() || !root.get())
2243 {
2244 *first_unparsed = expression_cstr;
2245 *reason_to_stop = ValueObject::eDereferencingFailed;
2246 *final_result = ValueObject::eInvalid;
2247 return 0;
2248 }
2249 else
2250 {
2251 *what_next = eNothing;
2252 continue;
2253 }
2254 }
2255 else
2256 {
2257 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2258 if (!root.get())
2259 {
2260 *first_unparsed = expression_cstr;
2261 *reason_to_stop = ValueObject::eNoSuchChild;
2262 *final_result = ValueObject::eInvalid;
2263 return 0;
2264 }
2265 else
2266 {
2267 list->Append(root);
2268 *first_unparsed = end+1; // skip ]
2269 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2270 *final_result = ValueObject::eValueObjectList;
2271 return 1;
2272 }
2273 }
2274 }
2275 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
2276 {
2277 root = root->GetSyntheticBitFieldChild(index, index, true);
2278 if (!root.get())
2279 {
2280 *first_unparsed = expression_cstr;
2281 *reason_to_stop = ValueObject::eNoSuchChild;
2282 *final_result = ValueObject::eInvalid;
2283 return 0;
2284 }
2285 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2286 {
2287 list->Append(root);
2288 *first_unparsed = end+1; // skip ]
2289 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2290 *final_result = ValueObject::eValueObjectList;
2291 return 1;
2292 }
2293 }
2294 }
2295 else // we have a low and a high index
2296 {
2297 char *end = NULL;
2298 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2299 if (!end || end != separator_position) // if something weird is in our way return an error
2300 {
2301 *first_unparsed = expression_cstr;
2302 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2303 *final_result = ValueObject::eInvalid;
2304 return 0;
2305 }
2306 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2307 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2308 {
2309 *first_unparsed = expression_cstr;
2310 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2311 *final_result = ValueObject::eInvalid;
2312 return 0;
2313 }
2314 if (index_lower > index_higher) // swap indices if required
2315 {
2316 unsigned long temp = index_lower;
2317 index_lower = index_higher;
2318 index_higher = temp;
2319 }
2320 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
2321 {
2322 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2323 if (!root.get())
2324 {
2325 *first_unparsed = expression_cstr;
2326 *reason_to_stop = ValueObject::eNoSuchChild;
2327 *final_result = ValueObject::eInvalid;
2328 return 0;
2329 }
2330 else
2331 {
2332 list->Append(root);
2333 *first_unparsed = end+1; // skip ]
2334 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2335 *final_result = ValueObject::eValueObjectList;
2336 return 1;
2337 }
2338 }
2339 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
2340 *what_next == ValueObject::eDereference &&
2341 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2342 {
2343 Error error;
2344 root = root->Dereference(error);
2345 if (error.Fail() || !root.get())
2346 {
2347 *first_unparsed = expression_cstr;
2348 *reason_to_stop = ValueObject::eDereferencingFailed;
2349 *final_result = ValueObject::eInvalid;
2350 return 0;
2351 }
2352 else
2353 {
2354 *what_next = ValueObject::eNothing;
2355 continue;
2356 }
2357 }
2358 else
2359 {
2360 for (int index = index_lower;
2361 index <= index_higher; index++)
2362 {
2363 ValueObjectSP child =
2364 root->GetChildAtIndex(index, true);
2365 list->Append(child);
2366 }
2367 *first_unparsed = end+1;
2368 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2369 *final_result = ValueObject::eValueObjectList;
2370 return index_higher-index_lower+1; // tell me number of items I added to the VOList
2371 }
2372 }
2373 break;
2374 }
2375 default: // some non-[ separator, or something entirely wrong, is in the way
2376 {
2377 *first_unparsed = expression_cstr;
2378 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2379 *final_result = ValueObject::eInvalid;
2380 return 0;
2381 break;
2382 }
2383 }
2384 }
2385}
2386
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002387void
Greg Clayton1d3afba2010-10-05 00:00:42 +00002388ValueObject::DumpValueObject
2389(
2390 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00002391 ValueObject *valobj,
2392 const char *root_valobj_name,
2393 uint32_t ptr_depth,
2394 uint32_t curr_depth,
2395 uint32_t max_depth,
2396 bool show_types,
2397 bool show_location,
2398 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00002399 lldb::DynamicValueType use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002400 bool scope_already_checked,
2401 bool flat_output
Greg Clayton1d3afba2010-10-05 00:00:42 +00002402)
2403{
Greg Clayton007d5be2011-05-30 00:49:24 +00002404 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002405 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002406 bool update_success = valobj->UpdateValueIfNeeded ();
2407
2408 if (update_success && use_dynamic != lldb::eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00002409 {
Jim Ingham2837b762011-05-04 03:43:18 +00002410 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00002411 if (dynamic_value)
2412 valobj = dynamic_value;
2413 }
2414
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002415 clang_type_t clang_type = valobj->GetClangType();
2416
Greg Clayton73b472d2010-10-27 03:32:59 +00002417 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002418 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00002419 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
2420 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002421
2422 const bool print_valobj = flat_output == false || has_value;
2423
2424 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002425 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002426 if (show_location)
2427 {
Jim Ingham6035b672011-03-31 00:19:25 +00002428 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002429 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002430
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002431 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002432
Greg Clayton7c8a9662010-11-02 01:50:16 +00002433 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00002434 if (show_types || (curr_depth == 0 && !flat_output))
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002435 s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
Greg Clayton1d3afba2010-10-05 00:00:42 +00002436
Greg Clayton1d3afba2010-10-05 00:00:42 +00002437
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002438 if (flat_output)
2439 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002440 // If we are showing types, also qualify the C++ base classes
2441 const bool qualify_cxx_base_classes = show_types;
2442 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002443 s.PutCString(" =");
2444 }
2445 else
2446 {
2447 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
2448 s.Printf ("%s =", name_cstr);
2449 }
2450
Jim Ingham6035b672011-03-31 00:19:25 +00002451 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002452 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002453 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002454 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002455 }
2456
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002457 const char *val_cstr = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00002458 const char *sum_cstr = NULL;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002459 SummaryFormat* entry = valobj->GetSummaryFormat().get();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002460
2461 if (err_cstr == NULL)
2462 {
Jim Ingham6035b672011-03-31 00:19:25 +00002463 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002464 err_cstr = valobj->GetError().AsCString();
2465 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002466
2467 if (err_cstr)
2468 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002469 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00002470 }
2471 else
2472 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002473 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002474 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002475 {
Enrico Granata4becb372011-06-29 22:27:15 +00002476
2477 sum_cstr = valobj->GetSummaryAsCString();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002478
Enrico Granata4becb372011-06-29 22:27:15 +00002479 // We must calculate this value in realtime because entry might alter this variable's value
2480 // (e.g. by saying ${var%fmt}) and render precached values useless
2481 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
2482 s.Printf(" %s", valobj->GetValueAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002483
Enrico Granata9dd75c82011-07-15 23:30:15 +00002484 if (sum_cstr)
Enrico Granata0a3958e2011-07-02 00:25:22 +00002485 {
2486 // for some reason, using %@ (ObjC description) in a summary string, makes
2487 // us believe we need to reset ourselves, thus invalidating the content of
2488 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty
2489 // let us recalculate it!
2490 if (sum_cstr[0] == '\0')
2491 s.Printf(" %s", valobj->GetSummaryAsCString());
2492 else
2493 s.Printf(" %s", sum_cstr);
2494 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002495
2496 if (use_objc)
2497 {
Jim Ingham6035b672011-03-31 00:19:25 +00002498 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002499 if (object_desc)
2500 s.Printf(" %s\n", object_desc);
2501 else
Sean Callanan672ad942010-10-23 00:18:49 +00002502 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002503 return;
Enrico Granata0a3958e2011-07-02 00:25:22 +00002504 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002505 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002506
2507 if (curr_depth < max_depth)
2508 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002509 // We will show children for all concrete types. We won't show
2510 // pointer contents unless a pointer depth has been specified.
2511 // We won't reference contents unless the reference is the
2512 // root object (depth of zero).
2513 bool print_children = true;
2514
2515 // Use a new temporary pointer depth in case we override the
2516 // current pointer depth below...
2517 uint32_t curr_ptr_depth = ptr_depth;
2518
2519 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
2520 if (is_ptr || is_ref)
2521 {
2522 // We have a pointer or reference whose value is an address.
2523 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00002524 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00002525 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
2526 print_children = false;
2527
2528 else if (is_ref && curr_depth == 0)
2529 {
2530 // If this is the root object (depth is zero) that we are showing
2531 // and it is a reference, and no pointer depth has been supplied
2532 // print out what it references. Don't do this at deeper depths
2533 // otherwise we can end up with infinite recursion...
2534 curr_ptr_depth = 1;
2535 }
2536
2537 if (curr_ptr_depth == 0)
2538 print_children = false;
2539 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002540
Enrico Granata0a3958e2011-07-02 00:25:22 +00002541 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00002542 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002543 const uint32_t num_children = valobj->GetNumChildren();
2544 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002545 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002546 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002547 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002548 if (print_valobj)
2549 s.EOL();
2550 }
2551 else
2552 {
2553 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00002554 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002555 s.IndentMore();
2556 }
2557
2558 for (uint32_t idx=0; idx<num_children; ++idx)
2559 {
2560 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
2561 if (child_sp.get())
2562 {
2563 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002564 child_sp.get(),
2565 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00002566 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002567 curr_depth + 1,
2568 max_depth,
2569 show_types,
2570 show_location,
2571 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00002572 use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002573 true,
2574 flat_output);
2575 }
2576 }
2577
2578 if (!flat_output)
2579 {
2580 s.IndentLess();
2581 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002582 }
2583 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002584 else if (has_children)
2585 {
2586 // Aggregate, no children...
2587 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00002588 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002589 }
2590 else
2591 {
2592 if (print_valobj)
2593 s.EOL();
2594 }
2595
Greg Clayton1d3afba2010-10-05 00:00:42 +00002596 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002597 else
2598 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00002599 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002600 }
2601 }
2602 else
2603 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002604 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002605 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002606 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002607 }
2608 }
2609 }
2610 }
2611}
2612
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002613
2614ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00002615ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002616{
2617 ValueObjectSP valobj_sp;
2618
Jim Ingham6035b672011-03-31 00:19:25 +00002619 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002620 {
Jim Ingham6035b672011-03-31 00:19:25 +00002621 ExecutionContextScope *exe_scope = GetExecutionContextScope();
2622 if (exe_scope)
2623 {
2624 ExecutionContext exe_ctx;
2625 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002626
Jim Ingham6035b672011-03-31 00:19:25 +00002627 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002628
Jim Ingham6035b672011-03-31 00:19:25 +00002629 DataExtractor data;
2630 data.SetByteOrder (m_data.GetByteOrder());
2631 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002632
Greg Clayton644247c2011-07-07 01:59:51 +00002633 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002634
Jim Ingham58b59f92011-04-22 23:53:53 +00002635 valobj_sp = ValueObjectConstResult::Create (exe_scope,
2636 ast,
2637 GetClangType(),
2638 name,
2639 data);
Jim Ingham6035b672011-03-31 00:19:25 +00002640 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002641 }
Jim Ingham6035b672011-03-31 00:19:25 +00002642
2643 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002644 {
Jim Ingham58b59f92011-04-22 23:53:53 +00002645 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002646 }
2647 return valobj_sp;
2648}
2649
2650lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00002651ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002652{
Jim Ingham58b59f92011-04-22 23:53:53 +00002653 if (m_deref_valobj)
2654 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00002655
Greg Clayton54979cd2010-12-15 05:08:08 +00002656 const bool is_pointer_type = IsPointerType();
2657 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002658 {
2659 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +00002660 bool ignore_array_bounds = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002661
2662 std::string child_name_str;
2663 uint32_t child_byte_size = 0;
2664 int32_t child_byte_offset = 0;
2665 uint32_t child_bitfield_bit_size = 0;
2666 uint32_t child_bitfield_bit_offset = 0;
2667 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00002668 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002669 const bool transparent_pointers = false;
2670 clang::ASTContext *clang_ast = GetClangAST();
2671 clang_type_t clang_type = GetClangType();
2672 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00002673
2674 ExecutionContext exe_ctx;
2675 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
2676
2677 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
2678 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002679 GetName().GetCString(),
2680 clang_type,
2681 0,
2682 transparent_pointers,
2683 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00002684 ignore_array_bounds,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002685 child_name_str,
2686 child_byte_size,
2687 child_byte_offset,
2688 child_bitfield_bit_size,
2689 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002690 child_is_base_class,
2691 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00002692 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002693 {
2694 ConstString child_name;
2695 if (!child_name_str.empty())
2696 child_name.SetCString (child_name_str.c_str());
2697
Jim Ingham58b59f92011-04-22 23:53:53 +00002698 m_deref_valobj = new ValueObjectChild (*this,
2699 clang_ast,
2700 child_clang_type,
2701 child_name,
2702 child_byte_size,
2703 child_byte_offset,
2704 child_bitfield_bit_size,
2705 child_bitfield_bit_offset,
2706 child_is_base_class,
2707 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002708 }
2709 }
Greg Clayton54979cd2010-12-15 05:08:08 +00002710
Jim Ingham58b59f92011-04-22 23:53:53 +00002711 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00002712 {
2713 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00002714 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00002715 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002716 else
2717 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002718 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002719 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002720
2721 if (is_pointer_type)
2722 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
2723 else
2724 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00002725 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002726 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002727}
2728
Jim Ingham78a685a2011-04-16 00:01:13 +00002729lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00002730ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002731{
Jim Ingham78a685a2011-04-16 00:01:13 +00002732 if (m_addr_of_valobj_sp)
2733 return m_addr_of_valobj_sp;
2734
Greg Claytone0d378b2011-03-24 21:19:54 +00002735 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002736 const bool scalar_is_load_address = false;
2737 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00002738 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002739 if (addr != LLDB_INVALID_ADDRESS)
2740 {
2741 switch (address_type)
2742 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002743 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002744 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00002745 {
2746 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002747 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002748 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
2749 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002750 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002751
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002752 case eAddressTypeFile:
2753 case eAddressTypeLoad:
2754 case eAddressTypeHost:
2755 {
2756 clang::ASTContext *ast = GetClangAST();
2757 clang_type_t clang_type = GetClangType();
2758 if (ast && clang_type)
2759 {
2760 std::string name (1, '&');
2761 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00002762 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
2763 ast,
2764 ClangASTContext::CreatePointerType (ast, clang_type),
2765 ConstString (name.c_str()),
2766 addr,
2767 eAddressTypeInvalid,
2768 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002769 }
2770 }
2771 break;
2772 }
2773 }
Jim Ingham78a685a2011-04-16 00:01:13 +00002774 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002775}
2776
Greg Claytonb2dcc362011-05-05 23:32:56 +00002777
2778lldb::ValueObjectSP
2779ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
2780{
2781 lldb::ValueObjectSP valobj_sp;
2782 AddressType address_type;
2783 const bool scalar_is_load_address = true;
2784 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2785
2786 if (ptr_value != LLDB_INVALID_ADDRESS)
2787 {
2788 Address ptr_addr (NULL, ptr_value);
2789
2790 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2791 name,
2792 ptr_addr,
2793 clang_ast_type);
2794 }
2795 return valobj_sp;
2796}
2797
2798lldb::ValueObjectSP
2799ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
2800{
2801 lldb::ValueObjectSP valobj_sp;
2802 AddressType address_type;
2803 const bool scalar_is_load_address = true;
2804 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2805
2806 if (ptr_value != LLDB_INVALID_ADDRESS)
2807 {
2808 Address ptr_addr (NULL, ptr_value);
2809
2810 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2811 name,
2812 ptr_addr,
2813 type_sp);
2814 }
2815 return valobj_sp;
2816}
2817
2818
Jim Ingham6035b672011-03-31 00:19:25 +00002819ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00002820 m_thread_id (LLDB_INVALID_UID),
2821 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00002822{
2823}
2824
2825ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00002826 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002827 m_first_update (true),
Jim Ingham89b61092011-07-06 17:42:14 +00002828 m_thread_id (LLDB_INVALID_THREAD_ID),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002829 m_stop_id (0)
2830
Jim Ingham6035b672011-03-31 00:19:25 +00002831{
2832 ExecutionContext exe_ctx;
2833 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
2834 // and if so we want to cache that not the original.
2835 if (exe_scope)
2836 exe_scope->CalculateExecutionContext(exe_ctx);
2837 if (exe_ctx.target != NULL)
2838 {
2839 m_target_sp = exe_ctx.target->GetSP();
2840
2841 if (exe_ctx.process == NULL)
2842 m_process_sp = exe_ctx.target->GetProcessSP();
2843 else
2844 m_process_sp = exe_ctx.process->GetSP();
2845
2846 if (m_process_sp != NULL)
2847 {
2848 m_stop_id = m_process_sp->GetStopID();
2849 Thread *thread = NULL;
2850
2851 if (exe_ctx.thread == NULL)
2852 {
2853 if (use_selected)
2854 {
2855 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
2856 if (thread)
2857 computed_exe_scope = thread;
2858 }
2859 }
2860 else
2861 thread = exe_ctx.thread;
2862
2863 if (thread != NULL)
2864 {
2865 m_thread_id = thread->GetIndexID();
2866 if (exe_ctx.frame == NULL)
2867 {
2868 if (use_selected)
2869 {
2870 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
2871 if (frame)
2872 {
2873 m_stack_id = frame->GetStackID();
2874 computed_exe_scope = frame;
2875 }
2876 }
2877 }
2878 else
2879 m_stack_id = exe_ctx.frame->GetStackID();
2880 }
2881 }
2882 }
2883 m_exe_scope = computed_exe_scope;
2884}
2885
2886ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
2887 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002888 m_needs_update(true),
2889 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00002890 m_target_sp (rhs.m_target_sp),
2891 m_process_sp (rhs.m_process_sp),
2892 m_thread_id (rhs.m_thread_id),
2893 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00002894 m_stop_id (0)
2895{
2896}
2897
2898ValueObject::EvaluationPoint::~EvaluationPoint ()
2899{
2900}
2901
2902ExecutionContextScope *
2903ValueObject::EvaluationPoint::GetExecutionContextScope ()
2904{
2905 // We have to update before giving out the scope, or we could be handing out stale pointers.
2906 SyncWithProcessState();
2907
2908 return m_exe_scope;
2909}
2910
2911// This function checks the EvaluationPoint against the current process state. If the current
2912// state matches the evaluation point, or the evaluation point is already invalid, then we return
2913// false, meaning "no change". If the current state is different, we update our state, and return
2914// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
2915// future calls to NeedsUpdate will return true.
2916
2917bool
2918ValueObject::EvaluationPoint::SyncWithProcessState()
2919{
2920 // If we're already invalid, we don't need to do anything, and nothing has changed:
2921 if (m_stop_id == LLDB_INVALID_UID)
2922 {
2923 // Can't update with an invalid state.
2924 m_needs_update = false;
2925 return false;
2926 }
2927
2928 // If we don't have a process nothing can change.
2929 if (!m_process_sp)
2930 return false;
2931
2932 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00002933 uint32_t cur_stop_id = m_process_sp->GetStopID();
2934 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00002935 return false;
2936
Jim Ingham78a685a2011-04-16 00:01:13 +00002937 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
2938 // In either case, we aren't going to be able to sync with the process state.
2939 if (cur_stop_id == 0)
2940 return false;
2941
2942 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00002943 m_needs_update = true;
2944 m_exe_scope = m_process_sp.get();
2945
2946 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
2947 // doesn't, mark ourselves as invalid.
2948
2949 if (m_thread_id != LLDB_INVALID_THREAD_ID)
2950 {
2951 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
2952 if (our_thread == NULL)
Greg Clayton262f80d2011-07-06 16:49:27 +00002953 {
Jim Ingham89b61092011-07-06 17:42:14 +00002954 SetInvalid();
Greg Clayton262f80d2011-07-06 16:49:27 +00002955 }
Jim Ingham6035b672011-03-31 00:19:25 +00002956 else
2957 {
2958 m_exe_scope = our_thread;
2959
2960 if (m_stack_id.IsValid())
2961 {
2962 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
2963 if (our_frame == NULL)
2964 SetInvalid();
2965 else
2966 m_exe_scope = our_frame;
2967 }
2968 }
2969 }
2970 return true;
2971}
2972
Jim Ingham61be0902011-05-02 18:13:59 +00002973void
2974ValueObject::EvaluationPoint::SetUpdated ()
2975{
2976 m_first_update = false;
2977 m_needs_update = false;
2978 if (m_process_sp)
2979 m_stop_id = m_process_sp->GetStopID();
2980}
2981
2982
Jim Ingham6035b672011-03-31 00:19:25 +00002983bool
2984ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
2985{
2986 if (!IsValid())
2987 return false;
2988
2989 bool needs_update = false;
2990 m_exe_scope = NULL;
2991
2992 // The target has to be non-null, and the
2993 Target *target = exe_scope->CalculateTarget();
2994 if (target != NULL)
2995 {
2996 Target *old_target = m_target_sp.get();
2997 assert (target == old_target);
2998 Process *process = exe_scope->CalculateProcess();
2999 if (process != NULL)
3000 {
3001 // FOR NOW - assume you can't update variable objects across process boundaries.
3002 Process *old_process = m_process_sp.get();
3003 assert (process == old_process);
3004
3005 lldb::user_id_t stop_id = process->GetStopID();
3006 if (stop_id != m_stop_id)
3007 {
3008 needs_update = true;
3009 m_stop_id = stop_id;
3010 }
3011 // See if we're switching the thread or stack context. If no thread is given, this is
3012 // being evaluated in a global context.
3013 Thread *thread = exe_scope->CalculateThread();
3014 if (thread != NULL)
3015 {
3016 lldb::user_id_t new_thread_index = thread->GetIndexID();
3017 if (new_thread_index != m_thread_id)
3018 {
3019 needs_update = true;
3020 m_thread_id = new_thread_index;
3021 m_stack_id.Clear();
3022 }
3023
3024 StackFrame *new_frame = exe_scope->CalculateStackFrame();
3025 if (new_frame != NULL)
3026 {
3027 if (new_frame->GetStackID() != m_stack_id)
3028 {
3029 needs_update = true;
3030 m_stack_id = new_frame->GetStackID();
3031 }
3032 }
3033 else
3034 {
3035 m_stack_id.Clear();
3036 needs_update = true;
3037 }
3038 }
3039 else
3040 {
3041 // If this had been given a thread, and now there is none, we should update.
3042 // Otherwise we don't have to do anything.
3043 if (m_thread_id != LLDB_INVALID_UID)
3044 {
3045 m_thread_id = LLDB_INVALID_UID;
3046 m_stack_id.Clear();
3047 needs_update = true;
3048 }
3049 }
3050 }
3051 else
3052 {
3053 // If there is no process, then we don't need to update anything.
3054 // But if we're switching from having a process to not, we should try to update.
3055 if (m_process_sp.get() != NULL)
3056 {
3057 needs_update = true;
3058 m_process_sp.reset();
3059 m_thread_id = LLDB_INVALID_UID;
3060 m_stack_id.Clear();
3061 }
3062 }
3063 }
3064 else
3065 {
3066 // If there's no target, nothing can change so we don't need to update anything.
3067 // But if we're switching from having a target to not, we should try to update.
3068 if (m_target_sp.get() != NULL)
3069 {
3070 needs_update = true;
3071 m_target_sp.reset();
3072 m_process_sp.reset();
3073 m_thread_id = LLDB_INVALID_UID;
3074 m_stack_id.Clear();
3075 }
3076 }
3077 if (!m_needs_update)
3078 m_needs_update = needs_update;
3079
3080 return needs_update;
3081}
Enrico Granataf2bbf712011-07-15 02:26:42 +00003082
3083void
3084ValueObject::ClearUserVisibleData()
3085{
3086 m_location_str.clear();
3087 m_value_str.clear();
3088 m_summary_str.clear();
3089 m_object_desc_str.clear();
3090}