blob: fc89f0fd4a4af39b9f89310ade82e8260bad1dd0 [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 Granata1490c6f2011-07-19 02:34:21 +0000205 if (m_last_format_mgr_revision != Debugger::Formatting::ValueFormats::GetCurrentRevision())
Enrico Granata4becb372011-06-29 22:27:15 +0000206 {
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);
Enrico Granata1490c6f2011-07-19 02:34:21 +0000211 Debugger::Formatting::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 Granata1490c6f2011-07-19 02:34:21 +0000216
217 Debugger::Formatting::GetSummaryFormat(*this, m_last_summary_format);
218
219 m_last_format_mgr_revision = Debugger::Formatting::ValueFormats::GetCurrentRevision();
Enrico Granataf2bbf712011-07-15 02:26:42 +0000220
221 ClearUserVisibleData();
Enrico Granata4becb372011-06-29 22:27:15 +0000222 }
223}
224
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000225DataExtractor &
226ValueObject::GetDataExtractor ()
227{
Jim Ingham78a685a2011-04-16 00:01:13 +0000228 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229 return m_data;
230}
231
232const Error &
Greg Clayton262f80d2011-07-06 16:49:27 +0000233ValueObject::GetError()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000234{
Greg Clayton262f80d2011-07-06 16:49:27 +0000235 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236 return m_error;
237}
238
239const ConstString &
240ValueObject::GetName() const
241{
242 return m_name;
243}
244
245const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000246ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000247{
Jim Ingham6035b672011-03-31 00:19:25 +0000248 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249 {
250 if (m_location_str.empty())
251 {
252 StreamString sstr;
253
254 switch (m_value.GetValueType())
255 {
256 default:
257 break;
258
259 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000260 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261 {
262 RegisterInfo *reg_info = m_value.GetRegisterInfo();
263 if (reg_info)
264 {
265 if (reg_info->name)
266 m_location_str = reg_info->name;
267 else if (reg_info->alt_name)
268 m_location_str = reg_info->alt_name;
269 break;
270 }
271 }
272 m_location_str = "scalar";
273 break;
274
275 case Value::eValueTypeLoadAddress:
276 case Value::eValueTypeFileAddress:
277 case Value::eValueTypeHostAddress:
278 {
279 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
280 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
281 m_location_str.swap(sstr.GetString());
282 }
283 break;
284 }
285 }
286 }
287 return m_location_str.c_str();
288}
289
290Value &
291ValueObject::GetValue()
292{
293 return m_value;
294}
295
296const Value &
297ValueObject::GetValue() const
298{
299 return m_value;
300}
301
302bool
Jim Ingham6035b672011-03-31 00:19:25 +0000303ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000304{
305 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000306 ExecutionContextScope *exe_scope = GetExecutionContextScope();
307 if (exe_scope)
308 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000309 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
310 return scalar.IsValid();
311}
312
313bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000314ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315{
Greg Clayton288bdf92010-09-02 02:59:18 +0000316 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317}
318
319
320void
321ValueObject::SetValueIsValid (bool b)
322{
Greg Clayton288bdf92010-09-02 02:59:18 +0000323 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000324}
325
326bool
Jim Ingham6035b672011-03-31 00:19:25 +0000327ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328{
Jim Ingham6035b672011-03-31 00:19:25 +0000329 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000330 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331}
332
333void
334ValueObject::SetValueDidChange (bool value_changed)
335{
Greg Clayton288bdf92010-09-02 02:59:18 +0000336 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337}
338
339ValueObjectSP
340ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
341{
342 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000343 // We may need to update our value if we are dynamic
344 if (IsPossibleDynamicType ())
345 UpdateValueIfNeeded();
346 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000348 // Check if we have already made the child value object?
349 if (can_create && m_children[idx] == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000351 // No we haven't created the child at this index, so lets have our
352 // subclass do it and cache the result for quick future access.
353 m_children[idx] = CreateChildAtIndex (idx, false, 0);
Jim Ingham78a685a2011-04-16 00:01:13 +0000354 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000355
356 if (m_children[idx] != NULL)
357 return m_children[idx]->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358 }
359 return child_sp;
360}
361
362uint32_t
363ValueObject::GetIndexOfChildWithName (const ConstString &name)
364{
365 bool omit_empty_base_classes = true;
366 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000367 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000368 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369 omit_empty_base_classes);
370}
371
372ValueObjectSP
373ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
374{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000375 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376 // classes (which really aren't part of the expression path), so we
377 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000379
Greg Claytondea8cb42011-06-29 22:09:02 +0000380 // We may need to update our value if we are dynamic
381 if (IsPossibleDynamicType ())
382 UpdateValueIfNeeded();
383
384 std::vector<uint32_t> child_indexes;
385 clang::ASTContext *clang_ast = GetClangAST();
386 void *clang_type = GetClangType();
387 bool omit_empty_base_classes = true;
388 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
389 clang_type,
390 name.GetCString(),
391 omit_empty_base_classes,
392 child_indexes);
393 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000395 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
396 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
397
398 child_sp = GetChildAtIndex(*pos, can_create);
399 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000401 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000402 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000403 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
404 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000405 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000406 else
407 {
408 child_sp.reset();
409 }
410
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411 }
412 }
413 return child_sp;
414}
415
416
417uint32_t
418ValueObject::GetNumChildren ()
419{
Greg Clayton288bdf92010-09-02 02:59:18 +0000420 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421 {
422 SetNumChildren (CalculateNumChildren());
423 }
424 return m_children.size();
425}
426void
427ValueObject::SetNumChildren (uint32_t num_children)
428{
Greg Clayton288bdf92010-09-02 02:59:18 +0000429 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000430 m_children.resize(num_children);
431}
432
433void
434ValueObject::SetName (const char *name)
435{
436 m_name.SetCString(name);
437}
438
439void
440ValueObject::SetName (const ConstString &name)
441{
442 m_name = name;
443}
444
Jim Ingham58b59f92011-04-22 23:53:53 +0000445ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
447{
Jim Ingham2eec4872011-05-07 00:10:58 +0000448 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000449
Greg Claytondea8cb42011-06-29 22:09:02 +0000450 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +0000451 bool ignore_array_bounds = synthetic_array_member;
Greg Claytondea8cb42011-06-29 22:09:02 +0000452 std::string child_name_str;
453 uint32_t child_byte_size = 0;
454 int32_t child_byte_offset = 0;
455 uint32_t child_bitfield_bit_size = 0;
456 uint32_t child_bitfield_bit_offset = 0;
457 bool child_is_base_class = false;
458 bool child_is_deref_of_parent = false;
459
460 const bool transparent_pointers = synthetic_array_member == false;
461 clang::ASTContext *clang_ast = GetClangAST();
462 clang_type_t clang_type = GetClangType();
463 clang_type_t child_clang_type;
464
465 ExecutionContext exe_ctx;
466 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
467
468 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
469 clang_ast,
470 GetName().GetCString(),
471 clang_type,
472 idx,
473 transparent_pointers,
474 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +0000475 ignore_array_bounds,
Greg Claytondea8cb42011-06-29 22:09:02 +0000476 child_name_str,
477 child_byte_size,
478 child_byte_offset,
479 child_bitfield_bit_size,
480 child_bitfield_bit_offset,
481 child_is_base_class,
482 child_is_deref_of_parent);
483 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000485 if (synthetic_index)
486 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487
Greg Claytondea8cb42011-06-29 22:09:02 +0000488 ConstString child_name;
489 if (!child_name_str.empty())
490 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491
Greg Claytondea8cb42011-06-29 22:09:02 +0000492 valobj = new ValueObjectChild (*this,
493 clang_ast,
494 child_clang_type,
495 child_name,
496 child_byte_size,
497 child_byte_offset,
498 child_bitfield_bit_size,
499 child_bitfield_bit_offset,
500 child_is_base_class,
501 child_is_deref_of_parent);
502 if (m_pointers_point_to_load_addrs)
503 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000504 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000505
Jim Ingham58b59f92011-04-22 23:53:53 +0000506 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000507}
508
509const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000510ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511{
Jim Ingham6035b672011-03-31 00:19:25 +0000512 if (UpdateValueIfNeeded ())
Enrico Granata4becb372011-06-29 22:27:15 +0000513 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514 if (m_summary_str.empty())
515 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000516 SummaryFormat *summary_format = GetSummaryFormat().get();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000517
518 if (summary_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000519 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000520 m_summary_str = summary_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000521 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000522 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000524 clang_type_t clang_type = GetClangType();
Greg Clayton737b9322010-09-13 03:32:57 +0000525
Enrico Granata9dd75c82011-07-15 23:30:15 +0000526 // Do some default printout for function pointers
Enrico Granataf2bbf712011-07-15 02:26:42 +0000527 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000529 StreamString sstr;
530 clang_type_t elem_or_pointee_clang_type;
531 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
532 GetClangAST(),
533 &elem_or_pointee_clang_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534
Enrico Granataf2bbf712011-07-15 02:26:42 +0000535 ExecutionContextScope *exe_scope = GetExecutionContextScope();
536 if (exe_scope)
537 {
Enrico Granata9dd75c82011-07-15 23:30:15 +0000538 if (ClangASTContext::IsFunctionPointerType (clang_type))
Jim Ingham6035b672011-03-31 00:19:25 +0000539 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000540 AddressType func_ptr_address_type = eAddressTypeInvalid;
541 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
542
543 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
544 {
545 switch (func_ptr_address_type)
546 {
547 case eAddressTypeInvalid:
548 case eAddressTypeFile:
549 break;
550
551 case eAddressTypeLoad:
552 {
553 Address so_addr;
554 Target *target = exe_scope->CalculateTarget();
555 if (target && target->GetSectionLoadList().IsEmpty() == false)
556 {
557 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
558 {
559 so_addr.Dump (&sstr,
560 exe_scope,
561 Address::DumpStyleResolvedDescription,
562 Address::DumpStyleSectionNameOffset);
563 }
564 }
565 }
566 break;
567
568 case eAddressTypeHost:
569 break;
570 }
571 }
572 if (sstr.GetSize() > 0)
573 {
574 m_summary_str.assign (1, '(');
575 m_summary_str.append (sstr.GetData(), sstr.GetSize());
576 m_summary_str.append (1, ')');
577 }
Jim Ingham6035b672011-03-31 00:19:25 +0000578 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000579 }
580 }
581 }
582 }
583 }
584 if (m_summary_str.empty())
585 return NULL;
586 return m_summary_str.c_str();
587}
588
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000589bool
590ValueObject::IsCStringContainer(bool check_pointer)
591{
592 clang_type_t elem_or_pointee_clang_type;
593 const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(),
594 GetClangAST(),
595 &elem_or_pointee_clang_type));
596 bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
597 ClangASTContext::IsCharType (elem_or_pointee_clang_type));
598 if (!is_char_arr_ptr)
599 return false;
600 if (!check_pointer)
601 return true;
602 if (type_flags.Test(ClangASTContext::eTypeIsArray))
603 return true;
604 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
605 AddressType cstr_address_type = eAddressTypeInvalid;
606 cstr_address = GetAddressOf (cstr_address_type, true);
607 return (cstr_address != LLDB_INVALID_ADDRESS);
608}
609
610void
611ValueObject::ReadPointedString(Stream& s,
612 Error& error,
Enrico Granataf4efecd2011-07-12 22:56:10 +0000613 uint32_t max_length,
614 bool honor_array,
615 lldb::Format item_format)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000616{
617
618 if (max_length == 0)
Enrico Granataf4efecd2011-07-12 22:56:10 +0000619 max_length = 128; // FIXME this should be a setting, or a formatting parameter
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000620
621 clang_type_t clang_type = GetClangType();
622 clang_type_t elem_or_pointee_clang_type;
623 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
624 GetClangAST(),
625 &elem_or_pointee_clang_type));
626 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
627 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
628 {
629 ExecutionContextScope *exe_scope = GetExecutionContextScope();
630 if (exe_scope)
631 {
632 Target *target = exe_scope->CalculateTarget();
633 if (target != NULL)
634 {
635 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
636 AddressType cstr_address_type = eAddressTypeInvalid;
637
638 size_t cstr_len = 0;
639 bool capped_data = false;
640 if (type_flags.Test (ClangASTContext::eTypeIsArray))
641 {
642 // We have an array
643 cstr_len = ClangASTContext::GetArraySize (clang_type);
Enrico Granataf4efecd2011-07-12 22:56:10 +0000644 if (cstr_len > max_length)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000645 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000646 capped_data = true;
647 cstr_len = max_length;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000648 }
649 cstr_address = GetAddressOf (cstr_address_type, true);
650 }
651 else
652 {
653 // We have a pointer
654 cstr_address = GetPointerValue (cstr_address_type, true);
655 }
656 if (cstr_address != LLDB_INVALID_ADDRESS)
657 {
658 Address cstr_so_addr (NULL, cstr_address);
659 DataExtractor data;
660 size_t bytes_read = 0;
661 std::vector<char> data_buffer;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000662 bool prefer_file_cache = false;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000663 if (cstr_len > 0 && honor_array)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000664 {
665 data_buffer.resize(cstr_len);
666 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
667 bytes_read = target->ReadMemory (cstr_so_addr,
668 prefer_file_cache,
669 &data_buffer.front(),
670 cstr_len,
671 error);
672 if (bytes_read > 0)
673 {
674 s << '"';
675 data.Dump (&s,
676 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000677 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000678 1, // Size of item (1 byte for a char!)
679 bytes_read, // How many bytes to print?
680 UINT32_MAX, // num per line
681 LLDB_INVALID_ADDRESS,// base address
682 0, // bitfield bit size
683 0); // bitfield bit offset
684 if (capped_data)
685 s << "...";
686 s << '"';
687 }
688 }
689 else
690 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000691 cstr_len = max_length;
692 const size_t k_max_buf_size = 64;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000693 data_buffer.resize (k_max_buf_size + 1);
694 // NULL terminate in case we don't get the entire C string
695 data_buffer.back() = '\0';
696
697 s << '"';
698
699 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
700 while ((bytes_read = target->ReadMemory (cstr_so_addr,
701 prefer_file_cache,
702 &data_buffer.front(),
703 k_max_buf_size,
704 error)) > 0)
705 {
706 size_t len = strlen(&data_buffer.front());
707 if (len == 0)
708 break;
709 if (len > bytes_read)
710 len = bytes_read;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000711 if (len > cstr_len)
712 len = cstr_len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000713
714 data.Dump (&s,
715 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000716 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000717 1, // Size of item (1 byte for a char!)
718 len, // How many bytes to print?
719 UINT32_MAX, // num per line
720 LLDB_INVALID_ADDRESS,// base address
721 0, // bitfield bit size
722 0); // bitfield bit offset
723
724 if (len < k_max_buf_size)
725 break;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000726 if (len >= cstr_len)
727 {
728 s << "...";
729 break;
730 }
731 cstr_len -= len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000732 cstr_so_addr.Slide (k_max_buf_size);
733 }
734 s << '"';
735 }
736 }
737 }
738 }
739 }
740 else
741 {
742 error.SetErrorString("impossible to read a string from this object");
743 }
744}
745
Jim Ingham53c47f12010-09-10 23:12:17 +0000746const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000747ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000748{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000749
Jim Ingham6035b672011-03-31 00:19:25 +0000750 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000751 return NULL;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000752
753 if (!m_object_desc_str.empty())
754 return m_object_desc_str.c_str();
755
Jim Ingham6035b672011-03-31 00:19:25 +0000756 ExecutionContextScope *exe_scope = GetExecutionContextScope();
757 if (exe_scope == NULL)
758 return NULL;
759
Jim Ingham53c47f12010-09-10 23:12:17 +0000760 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000761 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000762 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000763
Jim Ingham53c47f12010-09-10 23:12:17 +0000764 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000765
766 lldb::LanguageType language = GetObjectRuntimeLanguage();
767 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
768
Jim Inghama2cf2632010-12-23 02:29:54 +0000769 if (runtime == NULL)
770 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000771 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000772 clang_type_t opaque_qual_type = GetClangType();
773 if (opaque_qual_type != NULL)
774 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000775 bool is_signed;
776 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
777 || ClangASTContext::IsPointerType (opaque_qual_type))
778 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000779 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000780 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000781 }
782 }
783
Jim Ingham8d543de2011-03-31 23:01:21 +0000784 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000785 {
786 m_object_desc_str.append (s.GetData());
787 }
Sean Callanan672ad942010-10-23 00:18:49 +0000788
789 if (m_object_desc_str.empty())
790 return NULL;
791 else
792 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000793}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000794
795const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000796ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000797{
798 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000799 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800 {
Jim Ingham6035b672011-03-31 00:19:25 +0000801 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000802 {
803 if (m_value_str.empty())
804 {
805 const Value::ContextType context_type = m_value.GetContextType();
806
807 switch (context_type)
808 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000809 case Value::eContextTypeClangType:
810 case Value::eContextTypeLLDBType:
811 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000812 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000813 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000814 if (clang_type)
815 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000816 if (m_last_value_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000817 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000818 m_value_str = m_last_value_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000819 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000820 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000821 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000822 StreamString sstr;
823 Format format = GetFormat();
824 if (format == eFormatDefault)
825 format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
826 ClangASTType::GetFormat(clang_type));
827
828 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
829 clang_type, // The clang type to display
830 &sstr,
831 format, // Format to display this type with
832 m_data, // Data to extract from
833 0, // Byte offset into "m_data"
834 GetByteSize(), // Byte size of item in "m_data"
835 GetBitfieldBitSize(), // Bitfield bit size
836 GetBitfieldBitOffset())) // Bitfield bit offset
837 m_value_str.swap(sstr.GetString());
838 else
839 {
840 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
841 m_data.GetByteSize(),
842 GetByteSize());
843 m_value_str.clear();
844 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000845 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000846 }
847 }
848 break;
849
Greg Clayton526e5af2010-11-13 03:52:47 +0000850 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851 {
852 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
853 if (reg_info)
854 {
855 StreamString reg_sstr;
856 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
857 m_value_str.swap(reg_sstr.GetString());
858 }
859 }
860 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000861
862 default:
863 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000864 }
865 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000866
867 if (!m_value_did_change && m_old_value_valid)
868 {
869 // The value was gotten successfully, so we consider the
870 // value as changed if the value string differs
871 SetValueDidChange (m_old_value_str != m_value_str);
872 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000873 }
874 }
875 if (m_value_str.empty())
876 return NULL;
877 return m_value_str.c_str();
878}
879
Enrico Granata0a3958e2011-07-02 00:25:22 +0000880const char *
881ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
882 lldb::Format custom_format)
883{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000884
885 RefCounter ref(&m_dump_printable_counter);
886
Enrico Granata9dd75c82011-07-15 23:30:15 +0000887 if (custom_format != lldb::eFormatInvalid)
Enrico Granata0a3958e2011-07-02 00:25:22 +0000888 SetFormat(custom_format);
889
890 const char * return_value;
891
892 switch(val_obj_display)
893 {
894 case eDisplayValue:
895 return_value = GetValueAsCString();
896 break;
897 case eDisplaySummary:
898 return_value = GetSummaryAsCString();
899 break;
900 case eDisplayLanguageSpecific:
901 return_value = GetObjectDescription();
902 break;
Enrico Granataf2bbf712011-07-15 02:26:42 +0000903 case eDisplayLocation:
904 return_value = GetLocationAsCString();
905 break;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000906 }
907
Enrico Granataf4efecd2011-07-12 22:56:10 +0000908 // this code snippet might lead to endless recursion, thus we use a RefCounter here to
909 // check that we are not looping endlessly
910 if (!return_value && (m_dump_printable_counter < 3))
Enrico Granata9fc19442011-07-06 02:13:41 +0000911 {
912 // try to pick the other choice
913 if (val_obj_display == eDisplayValue)
914 return_value = GetSummaryAsCString();
915 else if (val_obj_display == eDisplaySummary)
916 return_value = GetValueAsCString();
Enrico Granata9fc19442011-07-06 02:13:41 +0000917 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000918
Enrico Granataf4efecd2011-07-12 22:56:10 +0000919 return (return_value ? return_value : "<error>");
Enrico Granata0a3958e2011-07-02 00:25:22 +0000920
921}
922
Enrico Granata9fc19442011-07-06 02:13:41 +0000923bool
924ValueObject::DumpPrintableRepresentation(Stream& s,
925 ValueObjectRepresentationStyle val_obj_display,
926 lldb::Format custom_format)
927{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000928
929 clang_type_t elem_or_pointee_type;
930 Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000931
Enrico Granataf4efecd2011-07-12 22:56:10 +0000932 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
933 && val_obj_display == ValueObject::eDisplayValue)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000934 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000935 // when being asked to get a printable display an array or pointer type directly,
936 // try to "do the right thing"
937
938 if (IsCStringContainer(true) &&
939 (custom_format == lldb::eFormatCString ||
940 custom_format == lldb::eFormatCharArray ||
941 custom_format == lldb::eFormatChar ||
942 custom_format == lldb::eFormatVectorOfChar)) // print char[] & char* directly
943 {
944 Error error;
945 ReadPointedString(s,
946 error,
947 0,
948 (custom_format == lldb::eFormatVectorOfChar) ||
949 (custom_format == lldb::eFormatCharArray));
950 return !error.Fail();
951 }
952
953 if (custom_format == lldb::eFormatEnum)
954 return false;
955
956 // this only works for arrays, because I have no way to know when
957 // the pointed memory ends, and no special \0 end of data marker
958 if (flags.Test(ClangASTContext::eTypeIsArray))
959 {
960 if ((custom_format == lldb::eFormatBytes) ||
961 (custom_format == lldb::eFormatBytesWithASCII))
962 {
963 uint32_t count = GetNumChildren();
964
965 s << '[';
966 for (uint32_t low = 0; low < count; low++)
967 {
968
969 if (low)
970 s << ',';
971
972 ValueObjectSP child = GetChildAtIndex(low,true);
973 if (!child.get())
974 {
975 s << "<error>";
976 continue;
977 }
978 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format);
979 }
980
981 s << ']';
982
983 return true;
984 }
985
986 if ((custom_format == lldb::eFormatVectorOfChar) ||
987 (custom_format == lldb::eFormatVectorOfFloat32) ||
988 (custom_format == lldb::eFormatVectorOfFloat64) ||
989 (custom_format == lldb::eFormatVectorOfSInt16) ||
990 (custom_format == lldb::eFormatVectorOfSInt32) ||
991 (custom_format == lldb::eFormatVectorOfSInt64) ||
992 (custom_format == lldb::eFormatVectorOfSInt8) ||
993 (custom_format == lldb::eFormatVectorOfUInt128) ||
994 (custom_format == lldb::eFormatVectorOfUInt16) ||
995 (custom_format == lldb::eFormatVectorOfUInt32) ||
996 (custom_format == lldb::eFormatVectorOfUInt64) ||
997 (custom_format == lldb::eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
998 {
999 uint32_t count = GetNumChildren();
1000
1001 lldb::Format format = FormatManager::GetSingleItemFormat(custom_format);
1002
1003 s << '[';
1004 for (uint32_t low = 0; low < count; low++)
1005 {
1006
1007 if (low)
1008 s << ',';
1009
1010 ValueObjectSP child = GetChildAtIndex(low,true);
1011 if (!child.get())
1012 {
1013 s << "<error>";
1014 continue;
1015 }
1016 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format);
1017 }
1018
1019 s << ']';
1020
1021 return true;
1022 }
1023 }
1024
1025 if ((custom_format == lldb::eFormatBoolean) ||
1026 (custom_format == lldb::eFormatBinary) ||
1027 (custom_format == lldb::eFormatChar) ||
1028 (custom_format == lldb::eFormatCharPrintable) ||
1029 (custom_format == lldb::eFormatComplexFloat) ||
1030 (custom_format == lldb::eFormatDecimal) ||
1031 (custom_format == lldb::eFormatHex) ||
1032 (custom_format == lldb::eFormatFloat) ||
1033 (custom_format == lldb::eFormatOctal) ||
1034 (custom_format == lldb::eFormatOSType) ||
1035 (custom_format == lldb::eFormatUnicode16) ||
1036 (custom_format == lldb::eFormatUnicode32) ||
1037 (custom_format == lldb::eFormatUnsigned) ||
1038 (custom_format == lldb::eFormatPointer) ||
1039 (custom_format == lldb::eFormatComplexInteger) ||
1040 (custom_format == lldb::eFormatComplex) ||
1041 (custom_format == lldb::eFormatDefault)) // use the [] operator
1042 return false;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001043 }
Enrico Granataf4efecd2011-07-12 22:56:10 +00001044 const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
Enrico Granata9dd75c82011-07-15 23:30:15 +00001045 if (targetvalue)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001046 s.PutCString(targetvalue);
1047 bool var_success = (targetvalue != NULL);
Enrico Granata9dd75c82011-07-15 23:30:15 +00001048 if (custom_format != eFormatInvalid)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001049 SetFormat(eFormatDefault);
1050 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001051}
1052
Greg Clayton737b9322010-09-13 03:32:57 +00001053addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001054ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +00001055{
Jim Ingham78a685a2011-04-16 00:01:13 +00001056 if (!UpdateValueIfNeeded())
1057 return LLDB_INVALID_ADDRESS;
1058
Greg Clayton73b472d2010-10-27 03:32:59 +00001059 switch (m_value.GetValueType())
1060 {
1061 case Value::eValueTypeScalar:
1062 if (scalar_is_load_address)
1063 {
1064 address_type = eAddressTypeLoad;
1065 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1066 }
1067 break;
1068
1069 case Value::eValueTypeLoadAddress:
1070 case Value::eValueTypeFileAddress:
1071 case Value::eValueTypeHostAddress:
1072 {
1073 address_type = m_value.GetValueAddressType ();
1074 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1075 }
1076 break;
1077 }
1078 address_type = eAddressTypeInvalid;
1079 return LLDB_INVALID_ADDRESS;
1080}
1081
1082addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001083ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +00001084{
1085 lldb::addr_t address = LLDB_INVALID_ADDRESS;
1086 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +00001087
1088 if (!UpdateValueIfNeeded())
1089 return address;
1090
Greg Clayton73b472d2010-10-27 03:32:59 +00001091 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +00001092 {
1093 case Value::eValueTypeScalar:
1094 if (scalar_is_load_address)
1095 {
1096 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1097 address_type = eAddressTypeLoad;
1098 }
1099 break;
1100
1101 case Value::eValueTypeLoadAddress:
1102 case Value::eValueTypeFileAddress:
1103 case Value::eValueTypeHostAddress:
1104 {
1105 uint32_t data_offset = 0;
1106 address = m_data.GetPointer(&data_offset);
1107 address_type = m_value.GetValueAddressType();
1108 if (address_type == eAddressTypeInvalid)
1109 address_type = eAddressTypeLoad;
1110 }
1111 break;
1112 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001113
1114 if (m_pointers_point_to_load_addrs)
1115 address_type = eAddressTypeLoad;
1116
Greg Clayton737b9322010-09-13 03:32:57 +00001117 return address;
1118}
1119
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001120bool
Jim Ingham6035b672011-03-31 00:19:25 +00001121ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001122{
1123 // Make sure our value is up to date first so that our location and location
1124 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +00001125 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001126 return false;
1127
1128 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001129 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001130
1131 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +00001132 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133 switch (encoding)
1134 {
1135 case eEncodingInvalid:
1136 return false;
1137
1138 case eEncodingUint:
1139 if (byte_size > sizeof(unsigned long long))
1140 {
1141 return false;
1142 }
1143 else
1144 {
1145 unsigned long long ull_val = strtoull(value_str, &end, 0);
1146 if (end && *end != '\0')
1147 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001148 m_value.GetScalar() = ull_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001149 // Limit the bytes in our m_data appropriately.
1150 m_value.GetScalar().GetData (m_data, byte_size);
1151 }
1152 break;
1153
1154 case eEncodingSint:
1155 if (byte_size > sizeof(long long))
1156 {
1157 return false;
1158 }
1159 else
1160 {
1161 long long sll_val = strtoll(value_str, &end, 0);
1162 if (end && *end != '\0')
1163 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001164 m_value.GetScalar() = sll_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001165 // Limit the bytes in our m_data appropriately.
1166 m_value.GetScalar().GetData (m_data, byte_size);
1167 }
1168 break;
1169
1170 case eEncodingIEEE754:
1171 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +00001173 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001174 if (dst != NULL)
1175 {
1176 // We are decoding a float into host byte order below, so make
1177 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +00001178 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
1180 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +00001181 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001182 value_str,
1183 dst,
1184 byte_size);
1185
1186 if (converted_byte_size == byte_size)
1187 {
1188 }
1189 }
1190 }
1191 break;
1192
1193 case eEncodingVector:
1194 return false;
1195
1196 default:
1197 return false;
1198 }
1199
1200 // If we have made it here the value is in m_data and we should write it
1201 // out to the target
1202 return Write ();
1203}
1204
1205bool
1206ValueObject::Write ()
1207{
1208 // Clear the update ID so the next time we try and read the value
1209 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +00001210 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001211
1212 // TODO: when Value has a method to write a value back, call it from here.
1213 return false;
1214
1215}
1216
Jim Ingham5a369122010-09-28 01:25:32 +00001217lldb::LanguageType
1218ValueObject::GetObjectRuntimeLanguage ()
1219{
Greg Clayton73b472d2010-10-27 03:32:59 +00001220 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +00001221 if (opaque_qual_type == NULL)
1222 return lldb::eLanguageTypeC;
1223
1224 // If the type is a reference, then resolve it to what it refers to first:
1225 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
1226 if (qual_type->isAnyPointerType())
1227 {
1228 if (qual_type->isObjCObjectPointerType())
1229 return lldb::eLanguageTypeObjC;
1230
1231 clang::QualType pointee_type (qual_type->getPointeeType());
1232 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
1233 return lldb::eLanguageTypeC_plus_plus;
1234 if (pointee_type->isObjCObjectOrInterfaceType())
1235 return lldb::eLanguageTypeObjC;
1236 if (pointee_type->isObjCClassType())
1237 return lldb::eLanguageTypeObjC;
1238 }
1239 else
1240 {
1241 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
1242 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +00001243 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +00001244 return lldb::eLanguageTypeC_plus_plus;
1245 }
1246
1247 return lldb::eLanguageTypeC;
1248}
1249
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001250void
Jim Ingham58b59f92011-04-22 23:53:53 +00001251ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001252{
Jim Ingham58b59f92011-04-22 23:53:53 +00001253 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001254}
1255
1256ValueObjectSP
1257ValueObject::GetSyntheticChild (const ConstString &key) const
1258{
1259 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +00001260 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001261 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +00001262 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001263 return synthetic_child_sp;
1264}
1265
1266bool
1267ValueObject::IsPointerType ()
1268{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001269 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001270}
1271
Jim Inghamb7603bb2011-03-18 00:05:18 +00001272bool
Greg Claytondaf515f2011-07-09 20:12:33 +00001273ValueObject::IsArrayType ()
1274{
1275 return ClangASTContext::IsArrayType (GetClangType());
1276}
1277
1278bool
Enrico Granata9fc19442011-07-06 02:13:41 +00001279ValueObject::IsScalarType ()
1280{
1281 return ClangASTContext::IsScalarType (GetClangType());
1282}
1283
1284bool
Jim Inghamb7603bb2011-03-18 00:05:18 +00001285ValueObject::IsIntegerType (bool &is_signed)
1286{
1287 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
1288}
Greg Clayton73b472d2010-10-27 03:32:59 +00001289
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001290bool
1291ValueObject::IsPointerOrReferenceType ()
1292{
Greg Clayton007d5be2011-05-30 00:49:24 +00001293 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
1294}
1295
1296bool
1297ValueObject::IsPossibleCPlusPlusDynamicType ()
1298{
1299 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001300}
1301
Greg Claytondea8cb42011-06-29 22:09:02 +00001302bool
1303ValueObject::IsPossibleDynamicType ()
1304{
1305 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
1306}
1307
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001308ValueObjectSP
1309ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
1310{
1311 ValueObjectSP synthetic_child_sp;
1312 if (IsPointerType ())
1313 {
1314 char index_str[64];
1315 snprintf(index_str, sizeof(index_str), "[%i]", index);
1316 ConstString index_const_str(index_str);
1317 // Check if we have already created a synthetic array member in this
1318 // valid object. If we have we will re-use it.
1319 synthetic_child_sp = GetSyntheticChild (index_const_str);
1320 if (!synthetic_child_sp)
1321 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001322 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001323 // We haven't made a synthetic array member for INDEX yet, so
1324 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001325 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001326
1327 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001328 if (synthetic_child)
1329 {
1330 AddSyntheticChild(index_const_str, synthetic_child);
1331 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata0a3958e2011-07-02 00:25:22 +00001332 synthetic_child_sp->SetName(index_str);
1333 synthetic_child_sp->m_is_array_item_for_pointer = true;
Jim Ingham58b59f92011-04-22 23:53:53 +00001334 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001335 }
1336 }
1337 return synthetic_child_sp;
1338}
Jim Ingham22777012010-09-23 02:01:19 +00001339
Greg Claytondaf515f2011-07-09 20:12:33 +00001340// This allows you to create an array member using and index
1341// that doesn't not fall in the normal bounds of the array.
1342// Many times structure can be defined as:
1343// struct Collection
1344// {
1345// uint32_t item_count;
1346// Item item_array[0];
1347// };
1348// The size of the "item_array" is 1, but many times in practice
1349// there are more items in "item_array".
1350
1351ValueObjectSP
1352ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create)
1353{
1354 ValueObjectSP synthetic_child_sp;
1355 if (IsArrayType ())
1356 {
1357 char index_str[64];
1358 snprintf(index_str, sizeof(index_str), "[%i]", index);
1359 ConstString index_const_str(index_str);
1360 // Check if we have already created a synthetic array member in this
1361 // valid object. If we have we will re-use it.
1362 synthetic_child_sp = GetSyntheticChild (index_const_str);
1363 if (!synthetic_child_sp)
1364 {
1365 ValueObject *synthetic_child;
1366 // We haven't made a synthetic array member for INDEX yet, so
1367 // lets make one and cache it for any future reference.
1368 synthetic_child = CreateChildAtIndex(0, true, index);
1369
1370 // Cache the value if we got one back...
1371 if (synthetic_child)
1372 {
1373 AddSyntheticChild(index_const_str, synthetic_child);
1374 synthetic_child_sp = synthetic_child->GetSP();
1375 synthetic_child_sp->SetName(index_str);
1376 synthetic_child_sp->m_is_array_item_for_pointer = true;
1377 }
1378 }
1379 }
1380 return synthetic_child_sp;
1381}
1382
Enrico Granata9fc19442011-07-06 02:13:41 +00001383ValueObjectSP
1384ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
1385{
1386 ValueObjectSP synthetic_child_sp;
1387 if (IsScalarType ())
1388 {
1389 char index_str[64];
1390 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1391 ConstString index_const_str(index_str);
1392 // Check if we have already created a synthetic array member in this
1393 // valid object. If we have we will re-use it.
1394 synthetic_child_sp = GetSyntheticChild (index_const_str);
1395 if (!synthetic_child_sp)
1396 {
1397 ValueObjectChild *synthetic_child;
1398 // We haven't made a synthetic array member for INDEX yet, so
1399 // lets make one and cache it for any future reference.
1400 synthetic_child = new ValueObjectChild(*this,
1401 GetClangAST(),
1402 GetClangType(),
1403 index_const_str,
1404 GetByteSize(),
1405 0,
1406 to-from+1,
1407 from,
1408 false,
1409 false);
1410
1411 // Cache the value if we got one back...
1412 if (synthetic_child)
1413 {
1414 AddSyntheticChild(index_const_str, synthetic_child);
1415 synthetic_child_sp = synthetic_child->GetSP();
1416 synthetic_child_sp->SetName(index_str);
1417 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1418 }
1419 }
1420 }
1421 return synthetic_child_sp;
1422}
1423
Jim Ingham78a685a2011-04-16 00:01:13 +00001424void
Jim Ingham2837b762011-05-04 03:43:18 +00001425ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001426{
Jim Ingham2837b762011-05-04 03:43:18 +00001427 if (use_dynamic == lldb::eNoDynamicValues)
1428 return;
1429
Jim Ingham58b59f92011-04-22 23:53:53 +00001430 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001431 {
1432 Process *process = m_update_point.GetProcess();
1433 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001434
Jim Ingham78a685a2011-04-16 00:01:13 +00001435
1436 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1437 // hard code this everywhere.
1438 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1439 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1440 {
1441 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1442 if (runtime)
1443 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1444 }
1445 else
1446 {
1447 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1448 if (cpp_runtime)
1449 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1450
1451 if (!worth_having_dynamic_value)
1452 {
1453 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1454 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001455 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001456 }
1457 }
1458
1459 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001460 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001461
1462// if (worth_having_dynamic_value)
1463// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1464
Jim Ingham78a685a2011-04-16 00:01:13 +00001465 }
1466}
1467
Jim Ingham58b59f92011-04-22 23:53:53 +00001468ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001469ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001470{
Jim Ingham2837b762011-05-04 03:43:18 +00001471 if (use_dynamic == lldb::eNoDynamicValues)
1472 return ValueObjectSP();
1473
1474 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001475 {
Jim Ingham2837b762011-05-04 03:43:18 +00001476 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001477 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001478 if (m_dynamic_value)
1479 return m_dynamic_value->GetSP();
1480 else
1481 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001482}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001483
Greg Claytone221f822011-01-21 01:59:00 +00001484bool
1485ValueObject::GetBaseClassPath (Stream &s)
1486{
1487 if (IsBaseClass())
1488 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001489 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001490 clang_type_t clang_type = GetClangType();
1491 std::string cxx_class_name;
1492 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1493 if (this_had_base_class)
1494 {
1495 if (parent_had_base_class)
1496 s.PutCString("::");
1497 s.PutCString(cxx_class_name.c_str());
1498 }
1499 return parent_had_base_class || this_had_base_class;
1500 }
1501 return false;
1502}
1503
1504
1505ValueObject *
1506ValueObject::GetNonBaseClassParent()
1507{
Jim Ingham78a685a2011-04-16 00:01:13 +00001508 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001509 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001510 if (GetParent()->IsBaseClass())
1511 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001512 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001513 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001514 }
1515 return NULL;
1516}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001517
1518void
Enrico Granata4becb372011-06-29 22:27:15 +00001519ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001520{
Greg Claytone221f822011-01-21 01:59:00 +00001521 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00001522
Enrico Granata9dd75c82011-07-15 23:30:15 +00001523 if (is_deref_of_parent && epformat == eDereferencePointers) {
Enrico Granata4becb372011-06-29 22:27:15 +00001524 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
1525 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
1526 // the eHonorPointers mode is meant to produce strings in this latter format
1527 s.PutCString("*(");
1528 }
Greg Claytone221f822011-01-21 01:59:00 +00001529
Enrico Granata4becb372011-06-29 22:27:15 +00001530 ValueObject* parent = GetParent();
1531
1532 if (parent)
1533 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
Enrico Granata0a3958e2011-07-02 00:25:22 +00001534
1535 // if we are a deref_of_parent just because we are synthetic array
1536 // members made up to allow ptr[%d] syntax to work in variable
1537 // printing, then add our name ([%d]) to the expression path
Enrico Granata9dd75c82011-07-15 23:30:15 +00001538 if (m_is_array_item_for_pointer && epformat == eHonorPointers)
Enrico Granata0a3958e2011-07-02 00:25:22 +00001539 s.PutCString(m_name.AsCString());
Enrico Granata4becb372011-06-29 22:27:15 +00001540
Greg Claytone221f822011-01-21 01:59:00 +00001541 if (!IsBaseClass())
1542 {
1543 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001544 {
Greg Claytone221f822011-01-21 01:59:00 +00001545 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1546 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001547 {
Greg Claytone221f822011-01-21 01:59:00 +00001548 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1549 if (non_base_class_parent_clang_type)
1550 {
1551 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1552
Enrico Granata9dd75c82011-07-15 23:30:15 +00001553 if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00001554 {
1555 s.PutCString("->");
1556 }
Enrico Granata4becb372011-06-29 22:27:15 +00001557 else
1558 {
1559 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1560 {
1561 s.PutCString("->");
1562 }
1563 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1564 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1565 {
1566 s.PutChar('.');
1567 }
Greg Claytone221f822011-01-21 01:59:00 +00001568 }
1569 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001570 }
Greg Claytone221f822011-01-21 01:59:00 +00001571
1572 const char *name = GetName().GetCString();
1573 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001574 {
Greg Claytone221f822011-01-21 01:59:00 +00001575 if (qualify_cxx_base_classes)
1576 {
1577 if (GetBaseClassPath (s))
1578 s.PutCString("::");
1579 }
1580 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001581 }
1582 }
1583 }
1584
Enrico Granata4becb372011-06-29 22:27:15 +00001585 if (is_deref_of_parent && epformat == eDereferencePointers) {
Greg Claytone221f822011-01-21 01:59:00 +00001586 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00001587 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001588}
1589
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001590lldb::ValueObjectSP
1591ValueObject::GetValueForExpressionPath(const char* expression,
1592 const char** first_unparsed,
1593 ExpressionPathScanEndReason* reason_to_stop,
1594 ExpressionPathEndResultType* final_value_type,
1595 const GetValueForExpressionPathOptions& options,
1596 ExpressionPathAftermath* final_task_on_target)
1597{
1598
1599 const char* dummy_first_unparsed;
1600 ExpressionPathScanEndReason dummy_reason_to_stop;
1601 ExpressionPathEndResultType dummy_final_value_type;
1602 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1603
1604 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1605 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1606 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1607 final_value_type ? final_value_type : &dummy_final_value_type,
1608 options,
1609 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1610
1611 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1612 {
1613 return ret_val;
1614 }
1615 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1616 {
1617 if (*final_task_on_target == ValueObject::eDereference)
1618 {
1619 Error error;
1620 ValueObjectSP final_value = ret_val->Dereference(error);
1621 if (error.Fail() || !final_value.get())
1622 {
1623 *reason_to_stop = ValueObject::eDereferencingFailed;
1624 *final_value_type = ValueObject::eInvalid;
1625 return ValueObjectSP();
1626 }
1627 else
1628 {
1629 *final_task_on_target = ValueObject::eNothing;
1630 return final_value;
1631 }
1632 }
1633 if (*final_task_on_target == ValueObject::eTakeAddress)
1634 {
1635 Error error;
1636 ValueObjectSP final_value = ret_val->AddressOf(error);
1637 if (error.Fail() || !final_value.get())
1638 {
1639 *reason_to_stop = ValueObject::eTakingAddressFailed;
1640 *final_value_type = ValueObject::eInvalid;
1641 return ValueObjectSP();
1642 }
1643 else
1644 {
1645 *final_task_on_target = ValueObject::eNothing;
1646 return final_value;
1647 }
1648 }
1649 }
1650 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
1651}
1652
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001653int
1654ValueObject::GetValuesForExpressionPath(const char* expression,
1655 lldb::ValueObjectListSP& list,
1656 const char** first_unparsed,
1657 ExpressionPathScanEndReason* reason_to_stop,
1658 ExpressionPathEndResultType* final_value_type,
1659 const GetValueForExpressionPathOptions& options,
1660 ExpressionPathAftermath* final_task_on_target)
1661{
1662 const char* dummy_first_unparsed;
1663 ExpressionPathScanEndReason dummy_reason_to_stop;
1664 ExpressionPathEndResultType dummy_final_value_type;
1665 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1666
1667 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1668 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1669 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1670 final_value_type ? final_value_type : &dummy_final_value_type,
1671 options,
1672 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1673
1674 if (!ret_val.get()) // if there are errors, I add nothing to the list
1675 return 0;
1676
1677 if (*reason_to_stop != eArrayRangeOperatorMet)
1678 {
1679 // I need not expand a range, just post-process the final value and return
1680 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1681 {
1682 list->Append(ret_val);
1683 return 1;
1684 }
1685 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1686 {
1687 if (*final_task_on_target == ValueObject::eDereference)
1688 {
1689 Error error;
1690 ValueObjectSP final_value = ret_val->Dereference(error);
1691 if (error.Fail() || !final_value.get())
1692 {
1693 *reason_to_stop = ValueObject::eDereferencingFailed;
1694 *final_value_type = ValueObject::eInvalid;
1695 return 0;
1696 }
1697 else
1698 {
1699 *final_task_on_target = ValueObject::eNothing;
1700 list->Append(final_value);
1701 return 1;
1702 }
1703 }
1704 if (*final_task_on_target == ValueObject::eTakeAddress)
1705 {
1706 Error error;
1707 ValueObjectSP final_value = ret_val->AddressOf(error);
1708 if (error.Fail() || !final_value.get())
1709 {
1710 *reason_to_stop = ValueObject::eTakingAddressFailed;
1711 *final_value_type = ValueObject::eInvalid;
1712 return 0;
1713 }
1714 else
1715 {
1716 *final_task_on_target = ValueObject::eNothing;
1717 list->Append(final_value);
1718 return 1;
1719 }
1720 }
1721 }
1722 }
1723 else
1724 {
1725 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
1726 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1727 ret_val,
1728 list,
1729 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1730 final_value_type ? final_value_type : &dummy_final_value_type,
1731 options,
1732 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1733 }
1734 // in any non-covered case, just do the obviously right thing
1735 list->Append(ret_val);
1736 return 1;
1737}
1738
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001739lldb::ValueObjectSP
1740ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
1741 const char** first_unparsed,
1742 ExpressionPathScanEndReason* reason_to_stop,
1743 ExpressionPathEndResultType* final_result,
1744 const GetValueForExpressionPathOptions& options,
1745 ExpressionPathAftermath* what_next)
1746{
1747 ValueObjectSP root = GetSP();
1748
1749 if (!root.get())
1750 return ValueObjectSP();
1751
1752 *first_unparsed = expression_cstr;
1753
1754 while (true)
1755 {
1756
1757 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
1758
1759 lldb::clang_type_t root_clang_type = root->GetClangType();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001760 lldb::clang_type_t pointee_clang_type;
1761 Flags root_clang_type_info,pointee_clang_type_info;
1762
1763 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
1764 if (pointee_clang_type)
1765 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001766
1767 if (!expression_cstr || *expression_cstr == '\0')
1768 {
1769 *reason_to_stop = ValueObject::eEndOfString;
1770 return root;
1771 }
1772
1773 switch (*expression_cstr)
1774 {
1775 case '-':
1776 {
1777 if (options.m_check_dot_vs_arrow_syntax &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001778 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 +00001779 {
1780 *first_unparsed = expression_cstr;
1781 *reason_to_stop = ValueObject::eArrowInsteadOfDot;
1782 *final_result = ValueObject::eInvalid;
1783 return ValueObjectSP();
1784 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001785 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
1786 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) &&
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001787 options.m_no_fragile_ivar)
1788 {
1789 *first_unparsed = expression_cstr;
1790 *reason_to_stop = ValueObject::eFragileIVarNotAllowed;
1791 *final_result = ValueObject::eInvalid;
1792 return ValueObjectSP();
1793 }
1794 if (expression_cstr[1] != '>')
1795 {
1796 *first_unparsed = expression_cstr;
1797 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1798 *final_result = ValueObject::eInvalid;
1799 return ValueObjectSP();
1800 }
1801 expression_cstr++; // skip the -
1802 }
1803 case '.': // or fallthrough from ->
1804 {
1805 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001806 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 +00001807 {
1808 *first_unparsed = expression_cstr;
1809 *reason_to_stop = ValueObject::eDotInsteadOfArrow;
1810 *final_result = ValueObject::eInvalid;
1811 return ValueObjectSP();
1812 }
1813 expression_cstr++; // skip .
1814 const char *next_separator = strpbrk(expression_cstr+1,"-.[");
1815 ConstString child_name;
1816 if (!next_separator) // if no other separator just expand this last layer
1817 {
1818 child_name.SetCString (expression_cstr);
1819 root = root->GetChildMemberWithName(child_name, true);
1820 if (root.get()) // we know we are done, so just return
1821 {
1822 *first_unparsed = '\0';
1823 *reason_to_stop = ValueObject::eEndOfString;
1824 *final_result = ValueObject::ePlain;
1825 return root;
1826 }
1827 else
1828 {
1829 *first_unparsed = expression_cstr;
1830 *reason_to_stop = ValueObject::eNoSuchChild;
1831 *final_result = ValueObject::eInvalid;
1832 return ValueObjectSP();
1833 }
1834 }
1835 else // other layers do expand
1836 {
1837 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
1838 root = root->GetChildMemberWithName(child_name, true);
1839 if (root.get()) // store the new root and move on
1840 {
1841 *first_unparsed = next_separator;
1842 *final_result = ValueObject::ePlain;
1843 continue;
1844 }
1845 else
1846 {
1847 *first_unparsed = expression_cstr;
1848 *reason_to_stop = ValueObject::eNoSuchChild;
1849 *final_result = ValueObject::eInvalid;
1850 return ValueObjectSP();
1851 }
1852 }
1853 break;
1854 }
1855 case '[':
1856 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001857 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 +00001858 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001859 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 +00001860 {
1861 *first_unparsed = expression_cstr;
1862 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
1863 *final_result = ValueObject::eInvalid;
1864 return ValueObjectSP();
1865 }
1866 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
1867 {
1868 *first_unparsed = expression_cstr;
1869 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
1870 *final_result = ValueObject::eInvalid;
1871 return ValueObjectSP();
1872 }
1873 }
1874 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
1875 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001876 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001877 {
1878 *first_unparsed = expression_cstr;
1879 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
1880 *final_result = ValueObject::eInvalid;
1881 return ValueObjectSP();
1882 }
1883 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
1884 {
1885 *first_unparsed = expression_cstr+2;
1886 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
1887 *final_result = ValueObject::eUnboundedRange;
1888 return root;
1889 }
1890 }
1891 const char *separator_position = ::strchr(expression_cstr+1,'-');
1892 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
1893 if (!close_bracket_position) // if there is no ], this is a syntax error
1894 {
1895 *first_unparsed = expression_cstr;
1896 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1897 *final_result = ValueObject::eInvalid;
1898 return ValueObjectSP();
1899 }
1900 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
1901 {
1902 char *end = NULL;
1903 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
1904 if (!end || end != close_bracket_position) // if something weird is in our way return an error
1905 {
1906 *first_unparsed = expression_cstr;
1907 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1908 *final_result = ValueObject::eInvalid;
1909 return ValueObjectSP();
1910 }
1911 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
1912 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001913 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001914 {
1915 *first_unparsed = expression_cstr+2;
1916 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
1917 *final_result = ValueObject::eUnboundedRange;
1918 return root;
1919 }
1920 else
1921 {
1922 *first_unparsed = expression_cstr;
1923 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
1924 *final_result = ValueObject::eInvalid;
1925 return ValueObjectSP();
1926 }
1927 }
1928 // from here on we do have a valid index
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001929 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001930 {
Greg Claytondaf515f2011-07-09 20:12:33 +00001931 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
1932 if (!child_valobj_sp)
1933 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
1934 if (child_valobj_sp)
1935 {
1936 root = child_valobj_sp;
1937 *first_unparsed = end+1; // skip ]
1938 *final_result = ValueObject::ePlain;
1939 continue;
1940 }
1941 else
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001942 {
1943 *first_unparsed = expression_cstr;
1944 *reason_to_stop = ValueObject::eNoSuchChild;
1945 *final_result = ValueObject::eInvalid;
1946 return ValueObjectSP();
1947 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001948 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001949 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001950 {
1951 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 +00001952 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001953 {
1954 Error error;
1955 root = root->Dereference(error);
1956 if (error.Fail() || !root.get())
1957 {
1958 *first_unparsed = expression_cstr;
1959 *reason_to_stop = ValueObject::eDereferencingFailed;
1960 *final_result = ValueObject::eInvalid;
1961 return ValueObjectSP();
1962 }
1963 else
1964 {
1965 *what_next = eNothing;
1966 continue;
1967 }
1968 }
1969 else
1970 {
1971 root = root->GetSyntheticArrayMemberFromPointer(index, true);
1972 if (!root.get())
1973 {
1974 *first_unparsed = expression_cstr;
1975 *reason_to_stop = ValueObject::eNoSuchChild;
1976 *final_result = ValueObject::eInvalid;
1977 return ValueObjectSP();
1978 }
1979 else
1980 {
1981 *first_unparsed = end+1; // skip ]
1982 *final_result = ValueObject::ePlain;
1983 continue;
1984 }
1985 }
1986 }
1987 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
1988 {
1989 root = root->GetSyntheticBitFieldChild(index, index, true);
1990 if (!root.get())
1991 {
1992 *first_unparsed = expression_cstr;
1993 *reason_to_stop = ValueObject::eNoSuchChild;
1994 *final_result = ValueObject::eInvalid;
1995 return ValueObjectSP();
1996 }
1997 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
1998 {
1999 *first_unparsed = end+1; // skip ]
2000 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2001 *final_result = ValueObject::eBitfield;
2002 return root;
2003 }
2004 }
2005 }
2006 else // we have a low and a high index
2007 {
2008 char *end = NULL;
2009 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2010 if (!end || end != separator_position) // if something weird is in our way return an error
2011 {
2012 *first_unparsed = expression_cstr;
2013 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2014 *final_result = ValueObject::eInvalid;
2015 return ValueObjectSP();
2016 }
2017 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2018 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2019 {
2020 *first_unparsed = expression_cstr;
2021 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2022 *final_result = ValueObject::eInvalid;
2023 return ValueObjectSP();
2024 }
2025 if (index_lower > index_higher) // swap indices if required
2026 {
2027 unsigned long temp = index_lower;
2028 index_lower = index_higher;
2029 index_higher = temp;
2030 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002031 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002032 {
2033 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2034 if (!root.get())
2035 {
2036 *first_unparsed = expression_cstr;
2037 *reason_to_stop = ValueObject::eNoSuchChild;
2038 *final_result = ValueObject::eInvalid;
2039 return ValueObjectSP();
2040 }
2041 else
2042 {
2043 *first_unparsed = end+1; // skip ]
2044 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2045 *final_result = ValueObject::eBitfield;
2046 return root;
2047 }
2048 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002049 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 +00002050 *what_next == ValueObject::eDereference &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002051 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002052 {
2053 Error error;
2054 root = root->Dereference(error);
2055 if (error.Fail() || !root.get())
2056 {
2057 *first_unparsed = expression_cstr;
2058 *reason_to_stop = ValueObject::eDereferencingFailed;
2059 *final_result = ValueObject::eInvalid;
2060 return ValueObjectSP();
2061 }
2062 else
2063 {
2064 *what_next = ValueObject::eNothing;
2065 continue;
2066 }
2067 }
2068 else
2069 {
2070 *first_unparsed = expression_cstr;
2071 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2072 *final_result = ValueObject::eBoundedRange;
2073 return root;
2074 }
2075 }
2076 break;
2077 }
2078 default: // some non-separator is in the way
2079 {
2080 *first_unparsed = expression_cstr;
2081 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2082 *final_result = ValueObject::eInvalid;
2083 return ValueObjectSP();
2084 break;
2085 }
2086 }
2087 }
2088}
2089
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002090int
2091ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
2092 const char** first_unparsed,
2093 lldb::ValueObjectSP root,
2094 lldb::ValueObjectListSP& list,
2095 ExpressionPathScanEndReason* reason_to_stop,
2096 ExpressionPathEndResultType* final_result,
2097 const GetValueForExpressionPathOptions& options,
2098 ExpressionPathAftermath* what_next)
2099{
2100 if (!root.get())
2101 return 0;
2102
2103 *first_unparsed = expression_cstr;
2104
2105 while (true)
2106 {
2107
2108 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
2109
2110 lldb::clang_type_t root_clang_type = root->GetClangType();
2111 lldb::clang_type_t pointee_clang_type;
2112 Flags root_clang_type_info,pointee_clang_type_info;
2113
2114 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
2115 if (pointee_clang_type)
2116 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
2117
2118 if (!expression_cstr || *expression_cstr == '\0')
2119 {
2120 *reason_to_stop = ValueObject::eEndOfString;
2121 list->Append(root);
2122 return 1;
2123 }
2124
2125 switch (*expression_cstr)
2126 {
2127 case '[':
2128 {
2129 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
2130 {
2131 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
2132 {
2133 *first_unparsed = expression_cstr;
2134 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2135 *final_result = ValueObject::eInvalid;
2136 return 0;
2137 }
2138 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2139 {
2140 *first_unparsed = expression_cstr;
2141 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2142 *final_result = ValueObject::eInvalid;
2143 return 0;
2144 }
2145 }
2146 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2147 {
2148 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2149 {
2150 *first_unparsed = expression_cstr;
2151 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2152 *final_result = ValueObject::eInvalid;
2153 return 0;
2154 }
2155 else // expand this into list
2156 {
2157 int max_index = root->GetNumChildren() - 1;
2158 for (int index = 0; index < max_index; index++)
2159 {
2160 ValueObjectSP child =
2161 root->GetChildAtIndex(index, true);
2162 list->Append(child);
2163 }
2164 *first_unparsed = expression_cstr+2;
2165 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2166 *final_result = ValueObject::eValueObjectList;
2167 return max_index; // tell me number of items I added to the VOList
2168 }
2169 }
2170 const char *separator_position = ::strchr(expression_cstr+1,'-');
2171 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2172 if (!close_bracket_position) // if there is no ], this is a syntax error
2173 {
2174 *first_unparsed = expression_cstr;
2175 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2176 *final_result = ValueObject::eInvalid;
2177 return 0;
2178 }
2179 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2180 {
2181 char *end = NULL;
2182 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2183 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2184 {
2185 *first_unparsed = expression_cstr;
2186 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2187 *final_result = ValueObject::eInvalid;
2188 return 0;
2189 }
2190 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2191 {
2192 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2193 {
2194 int max_index = root->GetNumChildren() - 1;
2195 for (int index = 0; index < max_index; index++)
2196 {
2197 ValueObjectSP child =
2198 root->GetChildAtIndex(index, true);
2199 list->Append(child);
2200 }
2201 *first_unparsed = expression_cstr+2;
2202 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2203 *final_result = ValueObject::eValueObjectList;
2204 return max_index; // tell me number of items I added to the VOList
2205 }
2206 else
2207 {
2208 *first_unparsed = expression_cstr;
2209 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2210 *final_result = ValueObject::eInvalid;
2211 return 0;
2212 }
2213 }
2214 // from here on we do have a valid index
2215 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2216 {
2217 root = root->GetChildAtIndex(index, true);
2218 if (!root.get())
2219 {
2220 *first_unparsed = expression_cstr;
2221 *reason_to_stop = ValueObject::eNoSuchChild;
2222 *final_result = ValueObject::eInvalid;
2223 return 0;
2224 }
2225 else
2226 {
2227 list->Append(root);
2228 *first_unparsed = end+1; // skip ]
2229 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2230 *final_result = ValueObject::eValueObjectList;
2231 return 1;
2232 }
2233 }
2234 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
2235 {
2236 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
2237 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2238 {
2239 Error error;
2240 root = root->Dereference(error);
2241 if (error.Fail() || !root.get())
2242 {
2243 *first_unparsed = expression_cstr;
2244 *reason_to_stop = ValueObject::eDereferencingFailed;
2245 *final_result = ValueObject::eInvalid;
2246 return 0;
2247 }
2248 else
2249 {
2250 *what_next = eNothing;
2251 continue;
2252 }
2253 }
2254 else
2255 {
2256 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2257 if (!root.get())
2258 {
2259 *first_unparsed = expression_cstr;
2260 *reason_to_stop = ValueObject::eNoSuchChild;
2261 *final_result = ValueObject::eInvalid;
2262 return 0;
2263 }
2264 else
2265 {
2266 list->Append(root);
2267 *first_unparsed = end+1; // skip ]
2268 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2269 *final_result = ValueObject::eValueObjectList;
2270 return 1;
2271 }
2272 }
2273 }
2274 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
2275 {
2276 root = root->GetSyntheticBitFieldChild(index, index, true);
2277 if (!root.get())
2278 {
2279 *first_unparsed = expression_cstr;
2280 *reason_to_stop = ValueObject::eNoSuchChild;
2281 *final_result = ValueObject::eInvalid;
2282 return 0;
2283 }
2284 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2285 {
2286 list->Append(root);
2287 *first_unparsed = end+1; // skip ]
2288 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2289 *final_result = ValueObject::eValueObjectList;
2290 return 1;
2291 }
2292 }
2293 }
2294 else // we have a low and a high index
2295 {
2296 char *end = NULL;
2297 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2298 if (!end || end != separator_position) // if something weird is in our way return an error
2299 {
2300 *first_unparsed = expression_cstr;
2301 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2302 *final_result = ValueObject::eInvalid;
2303 return 0;
2304 }
2305 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2306 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2307 {
2308 *first_unparsed = expression_cstr;
2309 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2310 *final_result = ValueObject::eInvalid;
2311 return 0;
2312 }
2313 if (index_lower > index_higher) // swap indices if required
2314 {
2315 unsigned long temp = index_lower;
2316 index_lower = index_higher;
2317 index_higher = temp;
2318 }
2319 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
2320 {
2321 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2322 if (!root.get())
2323 {
2324 *first_unparsed = expression_cstr;
2325 *reason_to_stop = ValueObject::eNoSuchChild;
2326 *final_result = ValueObject::eInvalid;
2327 return 0;
2328 }
2329 else
2330 {
2331 list->Append(root);
2332 *first_unparsed = end+1; // skip ]
2333 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2334 *final_result = ValueObject::eValueObjectList;
2335 return 1;
2336 }
2337 }
2338 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
2339 *what_next == ValueObject::eDereference &&
2340 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2341 {
2342 Error error;
2343 root = root->Dereference(error);
2344 if (error.Fail() || !root.get())
2345 {
2346 *first_unparsed = expression_cstr;
2347 *reason_to_stop = ValueObject::eDereferencingFailed;
2348 *final_result = ValueObject::eInvalid;
2349 return 0;
2350 }
2351 else
2352 {
2353 *what_next = ValueObject::eNothing;
2354 continue;
2355 }
2356 }
2357 else
2358 {
2359 for (int index = index_lower;
2360 index <= index_higher; index++)
2361 {
2362 ValueObjectSP child =
2363 root->GetChildAtIndex(index, true);
2364 list->Append(child);
2365 }
2366 *first_unparsed = end+1;
2367 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2368 *final_result = ValueObject::eValueObjectList;
2369 return index_higher-index_lower+1; // tell me number of items I added to the VOList
2370 }
2371 }
2372 break;
2373 }
2374 default: // some non-[ separator, or something entirely wrong, is in the way
2375 {
2376 *first_unparsed = expression_cstr;
2377 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2378 *final_result = ValueObject::eInvalid;
2379 return 0;
2380 break;
2381 }
2382 }
2383 }
2384}
2385
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002386void
Greg Clayton1d3afba2010-10-05 00:00:42 +00002387ValueObject::DumpValueObject
2388(
2389 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00002390 ValueObject *valobj,
2391 const char *root_valobj_name,
2392 uint32_t ptr_depth,
2393 uint32_t curr_depth,
2394 uint32_t max_depth,
2395 bool show_types,
2396 bool show_location,
2397 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00002398 lldb::DynamicValueType use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002399 bool scope_already_checked,
Enrico Granata0c5ef692011-07-16 01:22:04 +00002400 bool flat_output,
2401 uint32_t omit_summary_depth
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
Enrico Granata0c5ef692011-07-16 01:22:04 +00002461 if (omit_summary_depth > 0)
2462 entry = NULL;
2463
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002464 if (err_cstr == NULL)
2465 {
Jim Ingham6035b672011-03-31 00:19:25 +00002466 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002467 err_cstr = valobj->GetError().AsCString();
2468 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002469
2470 if (err_cstr)
2471 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002472 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00002473 }
2474 else
2475 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002476 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002477 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002478 {
Enrico Granata4becb372011-06-29 22:27:15 +00002479
Enrico Granata0c5ef692011-07-16 01:22:04 +00002480 sum_cstr = (omit_summary_depth == 0) ? valobj->GetSummaryAsCString() : NULL;
Greg Clayton1d3afba2010-10-05 00:00:42 +00002481
Enrico Granata4becb372011-06-29 22:27:15 +00002482 // We must calculate this value in realtime because entry might alter this variable's value
2483 // (e.g. by saying ${var%fmt}) and render precached values useless
2484 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
2485 s.Printf(" %s", valobj->GetValueAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002486
Enrico Granata9dd75c82011-07-15 23:30:15 +00002487 if (sum_cstr)
Enrico Granata0a3958e2011-07-02 00:25:22 +00002488 {
2489 // for some reason, using %@ (ObjC description) in a summary string, makes
2490 // us believe we need to reset ourselves, thus invalidating the content of
2491 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty
2492 // let us recalculate it!
2493 if (sum_cstr[0] == '\0')
2494 s.Printf(" %s", valobj->GetSummaryAsCString());
2495 else
2496 s.Printf(" %s", sum_cstr);
2497 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002498
2499 if (use_objc)
2500 {
Jim Ingham6035b672011-03-31 00:19:25 +00002501 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002502 if (object_desc)
2503 s.Printf(" %s\n", object_desc);
2504 else
Sean Callanan672ad942010-10-23 00:18:49 +00002505 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002506 return;
Enrico Granata0a3958e2011-07-02 00:25:22 +00002507 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002508 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002509
2510 if (curr_depth < max_depth)
2511 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002512 // We will show children for all concrete types. We won't show
2513 // pointer contents unless a pointer depth has been specified.
2514 // We won't reference contents unless the reference is the
2515 // root object (depth of zero).
2516 bool print_children = true;
2517
2518 // Use a new temporary pointer depth in case we override the
2519 // current pointer depth below...
2520 uint32_t curr_ptr_depth = ptr_depth;
2521
2522 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
2523 if (is_ptr || is_ref)
2524 {
2525 // We have a pointer or reference whose value is an address.
2526 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00002527 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00002528 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
2529 print_children = false;
2530
2531 else if (is_ref && curr_depth == 0)
2532 {
2533 // If this is the root object (depth is zero) that we are showing
2534 // and it is a reference, and no pointer depth has been supplied
2535 // print out what it references. Don't do this at deeper depths
2536 // otherwise we can end up with infinite recursion...
2537 curr_ptr_depth = 1;
2538 }
2539
2540 if (curr_ptr_depth == 0)
2541 print_children = false;
2542 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002543
Enrico Granata0a3958e2011-07-02 00:25:22 +00002544 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00002545 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002546 const uint32_t num_children = valobj->GetNumChildren();
2547 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002548 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002549 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002550 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002551 if (print_valobj)
2552 s.EOL();
2553 }
2554 else
2555 {
2556 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00002557 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002558 s.IndentMore();
2559 }
2560
2561 for (uint32_t idx=0; idx<num_children; ++idx)
2562 {
2563 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
2564 if (child_sp.get())
2565 {
2566 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002567 child_sp.get(),
2568 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00002569 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002570 curr_depth + 1,
2571 max_depth,
2572 show_types,
2573 show_location,
2574 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00002575 use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002576 true,
Enrico Granata0c5ef692011-07-16 01:22:04 +00002577 flat_output,
2578 omit_summary_depth > 1 ? omit_summary_depth - 1 : 0);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002579 }
2580 }
2581
2582 if (!flat_output)
2583 {
2584 s.IndentLess();
2585 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002586 }
2587 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002588 else if (has_children)
2589 {
2590 // Aggregate, no children...
2591 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00002592 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002593 }
2594 else
2595 {
2596 if (print_valobj)
2597 s.EOL();
2598 }
2599
Greg Clayton1d3afba2010-10-05 00:00:42 +00002600 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002601 else
2602 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00002603 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002604 }
2605 }
2606 else
2607 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002608 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002609 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002610 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002611 }
2612 }
2613 }
2614 }
2615}
2616
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002617
2618ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00002619ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002620{
2621 ValueObjectSP valobj_sp;
2622
Jim Ingham6035b672011-03-31 00:19:25 +00002623 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002624 {
Jim Ingham6035b672011-03-31 00:19:25 +00002625 ExecutionContextScope *exe_scope = GetExecutionContextScope();
2626 if (exe_scope)
2627 {
2628 ExecutionContext exe_ctx;
2629 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002630
Jim Ingham6035b672011-03-31 00:19:25 +00002631 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002632
Jim Ingham6035b672011-03-31 00:19:25 +00002633 DataExtractor data;
2634 data.SetByteOrder (m_data.GetByteOrder());
2635 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002636
Greg Clayton644247c2011-07-07 01:59:51 +00002637 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002638
Jim Ingham58b59f92011-04-22 23:53:53 +00002639 valobj_sp = ValueObjectConstResult::Create (exe_scope,
2640 ast,
2641 GetClangType(),
2642 name,
2643 data);
Jim Ingham6035b672011-03-31 00:19:25 +00002644 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002645 }
Jim Ingham6035b672011-03-31 00:19:25 +00002646
2647 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002648 {
Jim Ingham58b59f92011-04-22 23:53:53 +00002649 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002650 }
2651 return valobj_sp;
2652}
2653
2654lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00002655ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002656{
Jim Ingham58b59f92011-04-22 23:53:53 +00002657 if (m_deref_valobj)
2658 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00002659
Greg Clayton54979cd2010-12-15 05:08:08 +00002660 const bool is_pointer_type = IsPointerType();
2661 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002662 {
2663 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +00002664 bool ignore_array_bounds = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002665
2666 std::string child_name_str;
2667 uint32_t child_byte_size = 0;
2668 int32_t child_byte_offset = 0;
2669 uint32_t child_bitfield_bit_size = 0;
2670 uint32_t child_bitfield_bit_offset = 0;
2671 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00002672 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002673 const bool transparent_pointers = false;
2674 clang::ASTContext *clang_ast = GetClangAST();
2675 clang_type_t clang_type = GetClangType();
2676 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00002677
2678 ExecutionContext exe_ctx;
2679 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
2680
2681 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
2682 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002683 GetName().GetCString(),
2684 clang_type,
2685 0,
2686 transparent_pointers,
2687 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00002688 ignore_array_bounds,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002689 child_name_str,
2690 child_byte_size,
2691 child_byte_offset,
2692 child_bitfield_bit_size,
2693 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002694 child_is_base_class,
2695 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00002696 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002697 {
2698 ConstString child_name;
2699 if (!child_name_str.empty())
2700 child_name.SetCString (child_name_str.c_str());
2701
Jim Ingham58b59f92011-04-22 23:53:53 +00002702 m_deref_valobj = new ValueObjectChild (*this,
2703 clang_ast,
2704 child_clang_type,
2705 child_name,
2706 child_byte_size,
2707 child_byte_offset,
2708 child_bitfield_bit_size,
2709 child_bitfield_bit_offset,
2710 child_is_base_class,
2711 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002712 }
2713 }
Greg Clayton54979cd2010-12-15 05:08:08 +00002714
Jim Ingham58b59f92011-04-22 23:53:53 +00002715 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00002716 {
2717 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00002718 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00002719 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002720 else
2721 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002722 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002723 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002724
2725 if (is_pointer_type)
2726 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
2727 else
2728 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00002729 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002730 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002731}
2732
Jim Ingham78a685a2011-04-16 00:01:13 +00002733lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00002734ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002735{
Jim Ingham78a685a2011-04-16 00:01:13 +00002736 if (m_addr_of_valobj_sp)
2737 return m_addr_of_valobj_sp;
2738
Greg Claytone0d378b2011-03-24 21:19:54 +00002739 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002740 const bool scalar_is_load_address = false;
2741 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00002742 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002743 if (addr != LLDB_INVALID_ADDRESS)
2744 {
2745 switch (address_type)
2746 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002747 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002748 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00002749 {
2750 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002751 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002752 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
2753 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002754 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002755
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002756 case eAddressTypeFile:
2757 case eAddressTypeLoad:
2758 case eAddressTypeHost:
2759 {
2760 clang::ASTContext *ast = GetClangAST();
2761 clang_type_t clang_type = GetClangType();
2762 if (ast && clang_type)
2763 {
2764 std::string name (1, '&');
2765 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00002766 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
2767 ast,
2768 ClangASTContext::CreatePointerType (ast, clang_type),
2769 ConstString (name.c_str()),
2770 addr,
2771 eAddressTypeInvalid,
2772 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002773 }
2774 }
2775 break;
2776 }
2777 }
Jim Ingham78a685a2011-04-16 00:01:13 +00002778 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002779}
2780
Greg Claytonb2dcc362011-05-05 23:32:56 +00002781
2782lldb::ValueObjectSP
2783ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
2784{
2785 lldb::ValueObjectSP valobj_sp;
2786 AddressType address_type;
2787 const bool scalar_is_load_address = true;
2788 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2789
2790 if (ptr_value != LLDB_INVALID_ADDRESS)
2791 {
2792 Address ptr_addr (NULL, ptr_value);
2793
2794 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2795 name,
2796 ptr_addr,
2797 clang_ast_type);
2798 }
2799 return valobj_sp;
2800}
2801
2802lldb::ValueObjectSP
2803ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
2804{
2805 lldb::ValueObjectSP valobj_sp;
2806 AddressType address_type;
2807 const bool scalar_is_load_address = true;
2808 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2809
2810 if (ptr_value != LLDB_INVALID_ADDRESS)
2811 {
2812 Address ptr_addr (NULL, ptr_value);
2813
2814 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2815 name,
2816 ptr_addr,
2817 type_sp);
2818 }
2819 return valobj_sp;
2820}
2821
2822
Jim Ingham6035b672011-03-31 00:19:25 +00002823ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00002824 m_thread_id (LLDB_INVALID_UID),
2825 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00002826{
2827}
2828
2829ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00002830 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002831 m_first_update (true),
Jim Ingham89b61092011-07-06 17:42:14 +00002832 m_thread_id (LLDB_INVALID_THREAD_ID),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002833 m_stop_id (0)
2834
Jim Ingham6035b672011-03-31 00:19:25 +00002835{
2836 ExecutionContext exe_ctx;
2837 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
2838 // and if so we want to cache that not the original.
2839 if (exe_scope)
2840 exe_scope->CalculateExecutionContext(exe_ctx);
2841 if (exe_ctx.target != NULL)
2842 {
2843 m_target_sp = exe_ctx.target->GetSP();
2844
2845 if (exe_ctx.process == NULL)
2846 m_process_sp = exe_ctx.target->GetProcessSP();
2847 else
2848 m_process_sp = exe_ctx.process->GetSP();
2849
2850 if (m_process_sp != NULL)
2851 {
2852 m_stop_id = m_process_sp->GetStopID();
2853 Thread *thread = NULL;
2854
2855 if (exe_ctx.thread == NULL)
2856 {
2857 if (use_selected)
2858 {
2859 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
2860 if (thread)
2861 computed_exe_scope = thread;
2862 }
2863 }
2864 else
2865 thread = exe_ctx.thread;
2866
2867 if (thread != NULL)
2868 {
2869 m_thread_id = thread->GetIndexID();
2870 if (exe_ctx.frame == NULL)
2871 {
2872 if (use_selected)
2873 {
2874 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
2875 if (frame)
2876 {
2877 m_stack_id = frame->GetStackID();
2878 computed_exe_scope = frame;
2879 }
2880 }
2881 }
2882 else
2883 m_stack_id = exe_ctx.frame->GetStackID();
2884 }
2885 }
2886 }
2887 m_exe_scope = computed_exe_scope;
2888}
2889
2890ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
2891 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002892 m_needs_update(true),
2893 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00002894 m_target_sp (rhs.m_target_sp),
2895 m_process_sp (rhs.m_process_sp),
2896 m_thread_id (rhs.m_thread_id),
2897 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00002898 m_stop_id (0)
2899{
2900}
2901
2902ValueObject::EvaluationPoint::~EvaluationPoint ()
2903{
2904}
2905
2906ExecutionContextScope *
2907ValueObject::EvaluationPoint::GetExecutionContextScope ()
2908{
2909 // We have to update before giving out the scope, or we could be handing out stale pointers.
2910 SyncWithProcessState();
2911
2912 return m_exe_scope;
2913}
2914
2915// This function checks the EvaluationPoint against the current process state. If the current
2916// state matches the evaluation point, or the evaluation point is already invalid, then we return
2917// false, meaning "no change". If the current state is different, we update our state, and return
2918// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
2919// future calls to NeedsUpdate will return true.
2920
2921bool
2922ValueObject::EvaluationPoint::SyncWithProcessState()
2923{
2924 // If we're already invalid, we don't need to do anything, and nothing has changed:
2925 if (m_stop_id == LLDB_INVALID_UID)
2926 {
2927 // Can't update with an invalid state.
2928 m_needs_update = false;
2929 return false;
2930 }
2931
2932 // If we don't have a process nothing can change.
2933 if (!m_process_sp)
2934 return false;
2935
2936 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00002937 uint32_t cur_stop_id = m_process_sp->GetStopID();
2938 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00002939 return false;
2940
Jim Ingham78a685a2011-04-16 00:01:13 +00002941 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
2942 // In either case, we aren't going to be able to sync with the process state.
2943 if (cur_stop_id == 0)
2944 return false;
2945
2946 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00002947 m_needs_update = true;
2948 m_exe_scope = m_process_sp.get();
2949
2950 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
2951 // doesn't, mark ourselves as invalid.
2952
2953 if (m_thread_id != LLDB_INVALID_THREAD_ID)
2954 {
2955 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
2956 if (our_thread == NULL)
Greg Clayton262f80d2011-07-06 16:49:27 +00002957 {
Jim Ingham89b61092011-07-06 17:42:14 +00002958 SetInvalid();
Greg Clayton262f80d2011-07-06 16:49:27 +00002959 }
Jim Ingham6035b672011-03-31 00:19:25 +00002960 else
2961 {
2962 m_exe_scope = our_thread;
2963
2964 if (m_stack_id.IsValid())
2965 {
2966 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
2967 if (our_frame == NULL)
2968 SetInvalid();
2969 else
2970 m_exe_scope = our_frame;
2971 }
2972 }
2973 }
2974 return true;
2975}
2976
Jim Ingham61be0902011-05-02 18:13:59 +00002977void
2978ValueObject::EvaluationPoint::SetUpdated ()
2979{
2980 m_first_update = false;
2981 m_needs_update = false;
2982 if (m_process_sp)
2983 m_stop_id = m_process_sp->GetStopID();
2984}
2985
2986
Jim Ingham6035b672011-03-31 00:19:25 +00002987bool
2988ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
2989{
2990 if (!IsValid())
2991 return false;
2992
2993 bool needs_update = false;
2994 m_exe_scope = NULL;
2995
2996 // The target has to be non-null, and the
2997 Target *target = exe_scope->CalculateTarget();
2998 if (target != NULL)
2999 {
3000 Target *old_target = m_target_sp.get();
3001 assert (target == old_target);
3002 Process *process = exe_scope->CalculateProcess();
3003 if (process != NULL)
3004 {
3005 // FOR NOW - assume you can't update variable objects across process boundaries.
3006 Process *old_process = m_process_sp.get();
3007 assert (process == old_process);
3008
3009 lldb::user_id_t stop_id = process->GetStopID();
3010 if (stop_id != m_stop_id)
3011 {
3012 needs_update = true;
3013 m_stop_id = stop_id;
3014 }
3015 // See if we're switching the thread or stack context. If no thread is given, this is
3016 // being evaluated in a global context.
3017 Thread *thread = exe_scope->CalculateThread();
3018 if (thread != NULL)
3019 {
3020 lldb::user_id_t new_thread_index = thread->GetIndexID();
3021 if (new_thread_index != m_thread_id)
3022 {
3023 needs_update = true;
3024 m_thread_id = new_thread_index;
3025 m_stack_id.Clear();
3026 }
3027
3028 StackFrame *new_frame = exe_scope->CalculateStackFrame();
3029 if (new_frame != NULL)
3030 {
3031 if (new_frame->GetStackID() != m_stack_id)
3032 {
3033 needs_update = true;
3034 m_stack_id = new_frame->GetStackID();
3035 }
3036 }
3037 else
3038 {
3039 m_stack_id.Clear();
3040 needs_update = true;
3041 }
3042 }
3043 else
3044 {
3045 // If this had been given a thread, and now there is none, we should update.
3046 // Otherwise we don't have to do anything.
3047 if (m_thread_id != LLDB_INVALID_UID)
3048 {
3049 m_thread_id = LLDB_INVALID_UID;
3050 m_stack_id.Clear();
3051 needs_update = true;
3052 }
3053 }
3054 }
3055 else
3056 {
3057 // If there is no process, then we don't need to update anything.
3058 // But if we're switching from having a process to not, we should try to update.
3059 if (m_process_sp.get() != NULL)
3060 {
3061 needs_update = true;
3062 m_process_sp.reset();
3063 m_thread_id = LLDB_INVALID_UID;
3064 m_stack_id.Clear();
3065 }
3066 }
3067 }
3068 else
3069 {
3070 // If there's no target, nothing can change so we don't need to update anything.
3071 // But if we're switching from having a target to not, we should try to update.
3072 if (m_target_sp.get() != NULL)
3073 {
3074 needs_update = true;
3075 m_target_sp.reset();
3076 m_process_sp.reset();
3077 m_thread_id = LLDB_INVALID_UID;
3078 m_stack_id.Clear();
3079 }
3080 }
3081 if (!m_needs_update)
3082 m_needs_update = needs_update;
3083
3084 return needs_update;
3085}
Enrico Granataf2bbf712011-07-15 02:26:42 +00003086
3087void
3088ValueObject::ClearUserVisibleData()
3089{
3090 m_location_str.clear();
3091 m_value_str.clear();
3092 m_summary_str.clear();
3093 m_object_desc_str.clear();
3094}