blob: e02dda7f7e3a79e9878df73bd914e650a30e09d0 [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"
Enrico Granata6f3533f2011-07-29 19:53:35 +000023#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Core/StreamString.h"
25#include "lldb/Core/ValueObjectChild.h"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000026#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000027#include "lldb/Core/ValueObjectDynamicValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Core/ValueObjectList.h"
Greg Claytonb2dcc362011-05-05 23:32:56 +000029#include "lldb/Core/ValueObjectMemory.h"
Enrico Granatad55546b2011-07-22 00:16:08 +000030#include "lldb/Core/ValueObjectSyntheticFilter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031
Greg Clayton7fb56d02011-02-01 01:31:41 +000032#include "lldb/Host/Endian.h"
33
Enrico Granata61a80ba2011-08-12 16:42:31 +000034#include "lldb/Interpreter/CommandInterpreter.h"
Enrico Granataf2bbf712011-07-15 02:26:42 +000035#include "lldb/Interpreter/ScriptInterpreterPython.h"
36
Greg Claytone1a916a2010-07-21 22:12:05 +000037#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038#include "lldb/Symbol/ClangASTContext.h"
39#include "lldb/Symbol/Type.h"
40
Jim Ingham53c47f12010-09-10 23:12:17 +000041#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000042#include "lldb/Target/LanguageRuntime.h"
Enrico Granatac3e320a2011-08-02 17:27:39 +000043#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044#include "lldb/Target/Process.h"
45#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000046#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048
Enrico Granataf4efecd2011-07-12 22:56:10 +000049#include "lldb/Utility/RefCounter.h"
50
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051using namespace lldb;
52using namespace lldb_private;
Enrico Granataf4efecd2011-07-12 22:56:10 +000053using namespace lldb_utility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054
55static lldb::user_id_t g_value_obj_uid = 0;
56
57//----------------------------------------------------------------------
58// ValueObject constructor
59//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000060ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000062 m_parent (&parent),
Stephen Wilson71c21d12011-04-11 19:41:40 +000063 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064 m_name (),
65 m_data (),
66 m_value (),
67 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000068 m_value_str (),
69 m_old_value_str (),
70 m_location_str (),
71 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000072 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000073 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000074 m_children (),
75 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000076 m_dynamic_value (NULL),
Enrico Granatad55546b2011-07-22 00:16:08 +000077 m_synthetic_value(NULL),
Jim Ingham58b59f92011-04-22 23:53:53 +000078 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000079 m_format (eFormatDefault),
Enrico Granata9df29e32011-07-19 20:57:44 +000080 m_last_format_mgr_revision(0),
Enrico Granatad8b5fce2011-08-02 23:12:24 +000081 m_last_format_mgr_dynamic(parent.m_last_format_mgr_dynamic),
Enrico Granata9df29e32011-07-19 20:57:44 +000082 m_last_summary_format(),
83 m_forced_summary_format(),
84 m_last_value_format(),
Enrico Granatad55546b2011-07-22 00:16:08 +000085 m_last_synthetic_filter(),
Jim Ingham4b536182011-08-09 02:12:22 +000086 m_user_id_of_forced_summary(),
Greg Clayton288bdf92010-09-02 02:59:18 +000087 m_value_is_valid (false),
88 m_value_did_change (false),
89 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000090 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000091 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +000092 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +000093 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +000094 m_is_bitfield_for_scalar(false),
Enrico Granatad55546b2011-07-22 00:16:08 +000095 m_is_expression_path_child(false),
Enrico Granata6f3533f2011-07-29 19:53:35 +000096 m_is_child_at_offset(false),
Enrico Granata9910bc82011-08-03 02:18:51 +000097 m_is_expression_result(parent.m_is_expression_result),
Enrico Granataf4efecd2011-07-12 22:56:10 +000098 m_dump_printable_counter(0)
Jim Ingham6035b672011-03-31 00:19:25 +000099{
Jim Ingham58b59f92011-04-22 23:53:53 +0000100 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +0000101}
102
103//----------------------------------------------------------------------
104// ValueObject constructor
105//----------------------------------------------------------------------
106ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
107 UserID (++g_value_obj_uid), // Unique identifier for every value object
108 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000109 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +0000110 m_name (),
111 m_data (),
112 m_value (),
113 m_error (),
114 m_value_str (),
115 m_old_value_str (),
116 m_location_str (),
117 m_summary_str (),
118 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000119 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +0000120 m_children (),
121 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000122 m_dynamic_value (NULL),
Enrico Granatad55546b2011-07-22 00:16:08 +0000123 m_synthetic_value(NULL),
Jim Ingham58b59f92011-04-22 23:53:53 +0000124 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +0000125 m_format (eFormatDefault),
Enrico Granata9df29e32011-07-19 20:57:44 +0000126 m_last_format_mgr_revision(0),
Enrico Granatac3e320a2011-08-02 17:27:39 +0000127 m_last_format_mgr_dynamic(lldb::eNoDynamicValues),
Enrico Granata9df29e32011-07-19 20:57:44 +0000128 m_last_summary_format(),
129 m_forced_summary_format(),
130 m_last_value_format(),
Enrico Granatad55546b2011-07-22 00:16:08 +0000131 m_last_synthetic_filter(),
Jim Ingham4b536182011-08-09 02:12:22 +0000132 m_user_id_of_forced_summary(),
Jim Ingham6035b672011-03-31 00:19:25 +0000133 m_value_is_valid (false),
134 m_value_did_change (false),
135 m_children_count_valid (false),
136 m_old_value_valid (false),
137 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +0000138 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +0000139 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +0000140 m_is_bitfield_for_scalar(false),
Enrico Granatad55546b2011-07-22 00:16:08 +0000141 m_is_expression_path_child(false),
Enrico Granata6f3533f2011-07-29 19:53:35 +0000142 m_is_child_at_offset(false),
Enrico Granatac3e320a2011-08-02 17:27:39 +0000143 m_is_expression_result(false),
Enrico Granataf4efecd2011-07-12 22:56:10 +0000144 m_dump_printable_counter(0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145{
Jim Ingham58b59f92011-04-22 23:53:53 +0000146 m_manager = new ValueObjectManager();
147 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148}
149
150//----------------------------------------------------------------------
151// Destructor
152//----------------------------------------------------------------------
153ValueObject::~ValueObject ()
154{
155}
156
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157bool
Enrico Granata0a3958e2011-07-02 00:25:22 +0000158ValueObject::UpdateValueIfNeeded (bool update_format)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000160 return UpdateValueIfNeeded(m_last_format_mgr_dynamic, update_format);
161}
162
163bool
164ValueObject::UpdateValueIfNeeded (lldb::DynamicValueType use_dynamic, bool update_format)
165{
Enrico Granata4becb372011-06-29 22:27:15 +0000166
Enrico Granata0a3958e2011-07-02 00:25:22 +0000167 if (update_format)
Enrico Granatac3e320a2011-08-02 17:27:39 +0000168 UpdateFormatsIfNeeded(use_dynamic);
Enrico Granata4becb372011-06-29 22:27:15 +0000169
Greg Claytonb71f3842010-10-05 03:13:51 +0000170 // If this is a constant value, then our success is predicated on whether
171 // we have an error or not
172 if (GetIsConstant())
173 return m_error.Success();
174
Jim Ingham6035b672011-03-31 00:19:25 +0000175 bool first_update = m_update_point.IsFirstEvaluation();
176
177 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178 {
Jim Ingham6035b672011-03-31 00:19:25 +0000179 m_update_point.SetUpdated();
180
181 // Save the old value using swap to avoid a string copy which
182 // also will clear our m_value_str
183 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184 {
Jim Ingham6035b672011-03-31 00:19:25 +0000185 m_old_value_valid = false;
186 }
187 else
188 {
189 m_old_value_valid = true;
190 m_old_value_str.swap (m_value_str);
191 m_value_str.clear();
192 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193
Enrico Granataf2bbf712011-07-15 02:26:42 +0000194 ClearUserVisibleData();
195
Jim Ingham6035b672011-03-31 00:19:25 +0000196 const bool value_was_valid = GetValueIsValid();
197 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000198
Jim Ingham6035b672011-03-31 00:19:25 +0000199 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000200
Jim Ingham6035b672011-03-31 00:19:25 +0000201 // Call the pure virtual function to update the value
202 bool success = UpdateValue ();
203
204 SetValueIsValid (success);
205
206 if (first_update)
207 SetValueDidChange (false);
208 else if (!m_value_did_change && success == false)
209 {
210 // The value wasn't gotten successfully, so we mark this
211 // as changed if the value used to be valid and now isn't
212 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213 }
214 }
215 return m_error.Success();
216}
217
Enrico Granata4becb372011-06-29 22:27:15 +0000218void
Enrico Granatac3e320a2011-08-02 17:27:39 +0000219ValueObject::UpdateFormatsIfNeeded(lldb::DynamicValueType use_dynamic)
Enrico Granata4becb372011-06-29 22:27:15 +0000220{
Enrico Granata6f3533f2011-07-29 19:53:35 +0000221 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
222 if (log)
223 log->Printf("checking for FormatManager revisions. VO named %s is at revision %d, while the format manager is at revision %d",
224 GetName().GetCString(),
Enrico Granata4becb372011-06-29 22:27:15 +0000225 m_last_format_mgr_revision,
Enrico Granata6f3533f2011-07-29 19:53:35 +0000226 Debugger::Formatting::ValueFormats::GetCurrentRevision());
Jim Ingham4b536182011-08-09 02:12:22 +0000227 if (HasCustomSummaryFormat() && m_update_point.GetModID() != m_user_id_of_forced_summary)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000228 {
229 ClearCustomSummaryFormat();
230 m_summary_str.clear();
231 }
Enrico Granatac3e320a2011-08-02 17:27:39 +0000232 if ( (m_last_format_mgr_revision != Debugger::Formatting::ValueFormats::GetCurrentRevision()) ||
233 m_last_format_mgr_dynamic != use_dynamic)
Enrico Granata4becb372011-06-29 22:27:15 +0000234 {
235 if (m_last_summary_format.get())
Enrico Granataf2bbf712011-07-15 02:26:42 +0000236 m_last_summary_format.reset((StringSummaryFormat*)NULL);
Enrico Granata4becb372011-06-29 22:27:15 +0000237 if (m_last_value_format.get())
Enrico Granatad55546b2011-07-22 00:16:08 +0000238 m_last_value_format.reset(/*(ValueFormat*)NULL*/);
239 if (m_last_synthetic_filter.get())
240 m_last_synthetic_filter.reset(/*(SyntheticFilter*)NULL*/);
Enrico Granataa37a0652011-07-24 00:14:56 +0000241
242 m_synthetic_value = NULL;
Enrico Granata1490c6f2011-07-19 02:34:21 +0000243
Enrico Granata9910bc82011-08-03 02:18:51 +0000244 Debugger::Formatting::ValueFormats::Get(*this, lldb::eNoDynamicValues, m_last_value_format);
Enrico Granatac3e320a2011-08-02 17:27:39 +0000245 Debugger::Formatting::GetSummaryFormat(*this, use_dynamic, m_last_summary_format);
Enrico Granata68eb4bb2011-08-12 19:14:27 +0000246 Debugger::Formatting::GetSyntheticChildren(*this, use_dynamic, m_last_synthetic_filter);
Enrico Granata1490c6f2011-07-19 02:34:21 +0000247
248 m_last_format_mgr_revision = Debugger::Formatting::ValueFormats::GetCurrentRevision();
Enrico Granatac3e320a2011-08-02 17:27:39 +0000249 m_last_format_mgr_dynamic = use_dynamic;
Enrico Granataf2bbf712011-07-15 02:26:42 +0000250
251 ClearUserVisibleData();
Enrico Granata4becb372011-06-29 22:27:15 +0000252 }
253}
254
Jim Ingham16e0c682011-08-12 23:34:31 +0000255void
256ValueObject::SetNeedsUpdate ()
257{
258 m_update_point.SetNeedsUpdate();
259 // We have to clear the value string here so ConstResult children will notice if their values are
260 // changed by hand (i.e. with SetValueAsCString).
261 m_value_str.clear();
262}
263
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264DataExtractor &
265ValueObject::GetDataExtractor ()
266{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000267 UpdateValueIfNeeded(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268 return m_data;
269}
270
271const Error &
Greg Clayton262f80d2011-07-06 16:49:27 +0000272ValueObject::GetError()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000274 UpdateValueIfNeeded(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275 return m_error;
276}
277
278const ConstString &
279ValueObject::GetName() const
280{
281 return m_name;
282}
283
284const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000285ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000286{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000287 if (UpdateValueIfNeeded(false))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288 {
289 if (m_location_str.empty())
290 {
291 StreamString sstr;
292
293 switch (m_value.GetValueType())
294 {
295 default:
296 break;
297
298 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000299 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300 {
301 RegisterInfo *reg_info = m_value.GetRegisterInfo();
302 if (reg_info)
303 {
304 if (reg_info->name)
305 m_location_str = reg_info->name;
306 else if (reg_info->alt_name)
307 m_location_str = reg_info->alt_name;
308 break;
309 }
310 }
311 m_location_str = "scalar";
312 break;
313
314 case Value::eValueTypeLoadAddress:
315 case Value::eValueTypeFileAddress:
316 case Value::eValueTypeHostAddress:
317 {
318 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
319 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
320 m_location_str.swap(sstr.GetString());
321 }
322 break;
323 }
324 }
325 }
326 return m_location_str.c_str();
327}
328
329Value &
330ValueObject::GetValue()
331{
332 return m_value;
333}
334
335const Value &
336ValueObject::GetValue() const
337{
338 return m_value;
339}
340
341bool
Jim Ingham6035b672011-03-31 00:19:25 +0000342ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000343{
Enrico Granata6fd87d52011-08-04 01:41:02 +0000344 if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
345 {
346 ExecutionContext exe_ctx;
347 ExecutionContextScope *exe_scope = GetExecutionContextScope();
348 if (exe_scope)
349 exe_scope->CalculateExecutionContext(exe_ctx);
Jim Ingham16e0c682011-08-12 23:34:31 +0000350 Value tmp_value(m_value);
351 scalar = tmp_value.ResolveValue(&exe_ctx, GetClangAST ());
Enrico Granata6fd87d52011-08-04 01:41:02 +0000352 return scalar.IsValid();
353 }
354 else
355 return false;
Greg Clayton8f343b02010-11-04 01:54:29 +0000356}
357
358bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000359ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360{
Greg Clayton288bdf92010-09-02 02:59:18 +0000361 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362}
363
364
365void
366ValueObject::SetValueIsValid (bool b)
367{
Greg Clayton288bdf92010-09-02 02:59:18 +0000368 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369}
370
371bool
Jim Ingham6035b672011-03-31 00:19:25 +0000372ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373{
Jim Ingham6035b672011-03-31 00:19:25 +0000374 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000375 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376}
377
378void
379ValueObject::SetValueDidChange (bool value_changed)
380{
Greg Clayton288bdf92010-09-02 02:59:18 +0000381 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382}
383
384ValueObjectSP
385ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
386{
387 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000388 // We may need to update our value if we are dynamic
389 if (IsPossibleDynamicType ())
Enrico Granatac3e320a2011-08-02 17:27:39 +0000390 UpdateValueIfNeeded(false);
Greg Claytondea8cb42011-06-29 22:09:02 +0000391 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000393 // Check if we have already made the child value object?
394 if (can_create && m_children[idx] == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000396 // No we haven't created the child at this index, so lets have our
397 // subclass do it and cache the result for quick future access.
398 m_children[idx] = CreateChildAtIndex (idx, false, 0);
Jim Ingham78a685a2011-04-16 00:01:13 +0000399 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000400
401 if (m_children[idx] != NULL)
402 return m_children[idx]->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403 }
404 return child_sp;
405}
406
407uint32_t
408ValueObject::GetIndexOfChildWithName (const ConstString &name)
409{
410 bool omit_empty_base_classes = true;
411 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000412 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000413 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000414 omit_empty_base_classes);
415}
416
417ValueObjectSP
418ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
419{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000420 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421 // classes (which really aren't part of the expression path), so we
422 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000424
Greg Claytondea8cb42011-06-29 22:09:02 +0000425 // We may need to update our value if we are dynamic
426 if (IsPossibleDynamicType ())
Enrico Granatac3e320a2011-08-02 17:27:39 +0000427 UpdateValueIfNeeded(false);
Greg Claytondea8cb42011-06-29 22:09:02 +0000428
429 std::vector<uint32_t> child_indexes;
430 clang::ASTContext *clang_ast = GetClangAST();
431 void *clang_type = GetClangType();
432 bool omit_empty_base_classes = true;
433 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
434 clang_type,
435 name.GetCString(),
436 omit_empty_base_classes,
437 child_indexes);
438 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000440 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
441 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
442
443 child_sp = GetChildAtIndex(*pos, can_create);
444 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000446 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000447 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000448 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
449 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000450 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000451 else
452 {
453 child_sp.reset();
454 }
455
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456 }
457 }
458 return child_sp;
459}
460
461
462uint32_t
463ValueObject::GetNumChildren ()
464{
Greg Clayton288bdf92010-09-02 02:59:18 +0000465 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466 {
467 SetNumChildren (CalculateNumChildren());
468 }
469 return m_children.size();
470}
471void
472ValueObject::SetNumChildren (uint32_t num_children)
473{
Greg Clayton288bdf92010-09-02 02:59:18 +0000474 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475 m_children.resize(num_children);
476}
477
478void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000479ValueObject::SetName (const ConstString &name)
480{
481 m_name = name;
482}
483
Jim Ingham58b59f92011-04-22 23:53:53 +0000484ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000485ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
486{
Jim Ingham2eec4872011-05-07 00:10:58 +0000487 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000488
Greg Claytondea8cb42011-06-29 22:09:02 +0000489 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +0000490 bool ignore_array_bounds = synthetic_array_member;
Greg Claytondea8cb42011-06-29 22:09:02 +0000491 std::string child_name_str;
492 uint32_t child_byte_size = 0;
493 int32_t child_byte_offset = 0;
494 uint32_t child_bitfield_bit_size = 0;
495 uint32_t child_bitfield_bit_offset = 0;
496 bool child_is_base_class = false;
497 bool child_is_deref_of_parent = false;
498
499 const bool transparent_pointers = synthetic_array_member == false;
500 clang::ASTContext *clang_ast = GetClangAST();
501 clang_type_t clang_type = GetClangType();
502 clang_type_t child_clang_type;
503
504 ExecutionContext exe_ctx;
505 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
506
507 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
508 clang_ast,
509 GetName().GetCString(),
510 clang_type,
511 idx,
512 transparent_pointers,
513 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +0000514 ignore_array_bounds,
Greg Claytondea8cb42011-06-29 22:09:02 +0000515 child_name_str,
516 child_byte_size,
517 child_byte_offset,
518 child_bitfield_bit_size,
519 child_bitfield_bit_offset,
520 child_is_base_class,
521 child_is_deref_of_parent);
522 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000524 if (synthetic_index)
525 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526
Greg Claytondea8cb42011-06-29 22:09:02 +0000527 ConstString child_name;
528 if (!child_name_str.empty())
529 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000530
Greg Claytondea8cb42011-06-29 22:09:02 +0000531 valobj = new ValueObjectChild (*this,
532 clang_ast,
533 child_clang_type,
534 child_name,
535 child_byte_size,
536 child_byte_offset,
537 child_bitfield_bit_size,
538 child_bitfield_bit_offset,
539 child_is_base_class,
540 child_is_deref_of_parent);
541 if (m_pointers_point_to_load_addrs)
542 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000543 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000544
Jim Ingham58b59f92011-04-22 23:53:53 +0000545 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000546}
547
548const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000549ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550{
Enrico Granatad8b5fce2011-08-02 23:12:24 +0000551 if (UpdateValueIfNeeded (true))
Enrico Granata4becb372011-06-29 22:27:15 +0000552 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000553 if (m_summary_str.empty())
554 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000555 SummaryFormat *summary_format = GetSummaryFormat().get();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000556
557 if (summary_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000558 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000559 m_summary_str = summary_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000560 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000561 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000563 clang_type_t clang_type = GetClangType();
Greg Clayton737b9322010-09-13 03:32:57 +0000564
Enrico Granata9dd75c82011-07-15 23:30:15 +0000565 // Do some default printout for function pointers
Enrico Granataf2bbf712011-07-15 02:26:42 +0000566 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000567 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000568 StreamString sstr;
569 clang_type_t elem_or_pointee_clang_type;
570 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
571 GetClangAST(),
572 &elem_or_pointee_clang_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000573
Enrico Granataf2bbf712011-07-15 02:26:42 +0000574 ExecutionContextScope *exe_scope = GetExecutionContextScope();
575 if (exe_scope)
576 {
Enrico Granata9dd75c82011-07-15 23:30:15 +0000577 if (ClangASTContext::IsFunctionPointerType (clang_type))
Jim Ingham6035b672011-03-31 00:19:25 +0000578 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000579 AddressType func_ptr_address_type = eAddressTypeInvalid;
580 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
581
582 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
583 {
584 switch (func_ptr_address_type)
585 {
586 case eAddressTypeInvalid:
587 case eAddressTypeFile:
588 break;
589
590 case eAddressTypeLoad:
591 {
592 Address so_addr;
593 Target *target = exe_scope->CalculateTarget();
594 if (target && target->GetSectionLoadList().IsEmpty() == false)
595 {
596 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
597 {
598 so_addr.Dump (&sstr,
599 exe_scope,
600 Address::DumpStyleResolvedDescription,
601 Address::DumpStyleSectionNameOffset);
602 }
603 }
604 }
605 break;
606
607 case eAddressTypeHost:
608 break;
609 }
610 }
611 if (sstr.GetSize() > 0)
612 {
613 m_summary_str.assign (1, '(');
614 m_summary_str.append (sstr.GetData(), sstr.GetSize());
615 m_summary_str.append (1, ')');
616 }
Jim Ingham6035b672011-03-31 00:19:25 +0000617 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618 }
619 }
620 }
621 }
622 }
623 if (m_summary_str.empty())
624 return NULL;
625 return m_summary_str.c_str();
626}
627
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000628bool
629ValueObject::IsCStringContainer(bool check_pointer)
630{
631 clang_type_t elem_or_pointee_clang_type;
632 const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(),
633 GetClangAST(),
634 &elem_or_pointee_clang_type));
635 bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
636 ClangASTContext::IsCharType (elem_or_pointee_clang_type));
637 if (!is_char_arr_ptr)
638 return false;
639 if (!check_pointer)
640 return true;
641 if (type_flags.Test(ClangASTContext::eTypeIsArray))
642 return true;
643 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
644 AddressType cstr_address_type = eAddressTypeInvalid;
645 cstr_address = GetAddressOf (cstr_address_type, true);
646 return (cstr_address != LLDB_INVALID_ADDRESS);
647}
648
649void
650ValueObject::ReadPointedString(Stream& s,
651 Error& error,
Enrico Granataf4efecd2011-07-12 22:56:10 +0000652 uint32_t max_length,
653 bool honor_array,
654 lldb::Format item_format)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000655{
656
657 if (max_length == 0)
Enrico Granataf4efecd2011-07-12 22:56:10 +0000658 max_length = 128; // FIXME this should be a setting, or a formatting parameter
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000659
660 clang_type_t clang_type = GetClangType();
661 clang_type_t elem_or_pointee_clang_type;
662 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
663 GetClangAST(),
664 &elem_or_pointee_clang_type));
665 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
666 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
667 {
668 ExecutionContextScope *exe_scope = GetExecutionContextScope();
669 if (exe_scope)
670 {
671 Target *target = exe_scope->CalculateTarget();
Enrico Granata6f3533f2011-07-29 19:53:35 +0000672 if (target == NULL)
673 {
674 s << "<no target to read from>";
675 }
676 else
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000677 {
678 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
679 AddressType cstr_address_type = eAddressTypeInvalid;
680
681 size_t cstr_len = 0;
682 bool capped_data = false;
683 if (type_flags.Test (ClangASTContext::eTypeIsArray))
684 {
685 // We have an array
686 cstr_len = ClangASTContext::GetArraySize (clang_type);
Enrico Granataf4efecd2011-07-12 22:56:10 +0000687 if (cstr_len > max_length)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000688 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000689 capped_data = true;
690 cstr_len = max_length;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000691 }
692 cstr_address = GetAddressOf (cstr_address_type, true);
693 }
694 else
695 {
696 // We have a pointer
697 cstr_address = GetPointerValue (cstr_address_type, true);
698 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000699 if (cstr_address == LLDB_INVALID_ADDRESS)
700 {
701 s << "<invalid address for data>";
702 }
703 else
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000704 {
705 Address cstr_so_addr (NULL, cstr_address);
706 DataExtractor data;
707 size_t bytes_read = 0;
708 std::vector<char> data_buffer;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000709 bool prefer_file_cache = false;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000710 if (cstr_len > 0 && honor_array)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000711 {
712 data_buffer.resize(cstr_len);
713 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
714 bytes_read = target->ReadMemory (cstr_so_addr,
715 prefer_file_cache,
716 &data_buffer.front(),
717 cstr_len,
718 error);
719 if (bytes_read > 0)
720 {
721 s << '"';
722 data.Dump (&s,
723 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000724 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000725 1, // Size of item (1 byte for a char!)
726 bytes_read, // How many bytes to print?
727 UINT32_MAX, // num per line
728 LLDB_INVALID_ADDRESS,// base address
729 0, // bitfield bit size
730 0); // bitfield bit offset
731 if (capped_data)
732 s << "...";
733 s << '"';
734 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000735 else
736 s << "\"<data not available>\"";
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000737 }
738 else
739 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000740 cstr_len = max_length;
741 const size_t k_max_buf_size = 64;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000742 data_buffer.resize (k_max_buf_size + 1);
743 // NULL terminate in case we don't get the entire C string
744 data_buffer.back() = '\0';
745
746 s << '"';
747
Enrico Granata6f3533f2011-07-29 19:53:35 +0000748 bool any_data = false;
749
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000750 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
751 while ((bytes_read = target->ReadMemory (cstr_so_addr,
752 prefer_file_cache,
753 &data_buffer.front(),
754 k_max_buf_size,
755 error)) > 0)
756 {
Enrico Granata6f3533f2011-07-29 19:53:35 +0000757 any_data = true;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000758 size_t len = strlen(&data_buffer.front());
759 if (len == 0)
760 break;
761 if (len > bytes_read)
762 len = bytes_read;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000763 if (len > cstr_len)
764 len = cstr_len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000765
766 data.Dump (&s,
767 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000768 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000769 1, // Size of item (1 byte for a char!)
770 len, // How many bytes to print?
771 UINT32_MAX, // num per line
772 LLDB_INVALID_ADDRESS,// base address
773 0, // bitfield bit size
774 0); // bitfield bit offset
775
776 if (len < k_max_buf_size)
777 break;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000778 if (len >= cstr_len)
779 {
780 s << "...";
781 break;
782 }
783 cstr_len -= len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000784 cstr_so_addr.Slide (k_max_buf_size);
785 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000786
787 if (any_data == false)
788 s << "<data not available>";
789
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000790 s << '"';
791 }
792 }
793 }
794 }
795 }
796 else
797 {
798 error.SetErrorString("impossible to read a string from this object");
Enrico Granata6f3533f2011-07-29 19:53:35 +0000799 s << "<not a string object>";
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000800 }
801}
802
Jim Ingham53c47f12010-09-10 23:12:17 +0000803const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000804ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000805{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000806
Enrico Granatad8b5fce2011-08-02 23:12:24 +0000807 if (!UpdateValueIfNeeded (true))
Jim Ingham53c47f12010-09-10 23:12:17 +0000808 return NULL;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000809
810 if (!m_object_desc_str.empty())
811 return m_object_desc_str.c_str();
812
Jim Ingham6035b672011-03-31 00:19:25 +0000813 ExecutionContextScope *exe_scope = GetExecutionContextScope();
814 if (exe_scope == NULL)
815 return NULL;
816
Jim Ingham53c47f12010-09-10 23:12:17 +0000817 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000818 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000819 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000820
Jim Ingham53c47f12010-09-10 23:12:17 +0000821 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000822
823 lldb::LanguageType language = GetObjectRuntimeLanguage();
824 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
825
Jim Inghama2cf2632010-12-23 02:29:54 +0000826 if (runtime == NULL)
827 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000828 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000829 clang_type_t opaque_qual_type = GetClangType();
830 if (opaque_qual_type != NULL)
831 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000832 bool is_signed;
833 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
834 || ClangASTContext::IsPointerType (opaque_qual_type))
835 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000836 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000837 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000838 }
839 }
840
Jim Ingham8d543de2011-03-31 23:01:21 +0000841 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000842 {
843 m_object_desc_str.append (s.GetData());
844 }
Sean Callanan672ad942010-10-23 00:18:49 +0000845
846 if (m_object_desc_str.empty())
847 return NULL;
848 else
849 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000850}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851
852const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000853ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000854{
855 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000856 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857 {
Enrico Granatac3e320a2011-08-02 17:27:39 +0000858 if (UpdateValueIfNeeded(true))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000859 {
860 if (m_value_str.empty())
861 {
862 const Value::ContextType context_type = m_value.GetContextType();
863
864 switch (context_type)
865 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000866 case Value::eContextTypeClangType:
867 case Value::eContextTypeLLDBType:
868 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000869 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000870 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000871 if (clang_type)
872 {
Enrico Granatac3e320a2011-08-02 17:27:39 +0000873 if (m_format == lldb::eFormatDefault && m_last_value_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000874 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000875 m_value_str = m_last_value_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000876 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000877 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000878 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000879 StreamString sstr;
880 Format format = GetFormat();
881 if (format == eFormatDefault)
882 format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
883 ClangASTType::GetFormat(clang_type));
884
885 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
886 clang_type, // The clang type to display
887 &sstr,
888 format, // Format to display this type with
889 m_data, // Data to extract from
890 0, // Byte offset into "m_data"
891 GetByteSize(), // Byte size of item in "m_data"
892 GetBitfieldBitSize(), // Bitfield bit size
893 GetBitfieldBitOffset())) // Bitfield bit offset
894 m_value_str.swap(sstr.GetString());
895 else
896 {
897 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
898 m_data.GetByteSize(),
899 GetByteSize());
900 m_value_str.clear();
901 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000902 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000903 }
904 }
905 break;
906
Greg Clayton526e5af2010-11-13 03:52:47 +0000907 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000908 {
909 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
910 if (reg_info)
911 {
912 StreamString reg_sstr;
913 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
914 m_value_str.swap(reg_sstr.GetString());
915 }
916 }
917 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000918
919 default:
920 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000921 }
922 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000923
924 if (!m_value_did_change && m_old_value_valid)
925 {
926 // The value was gotten successfully, so we consider the
927 // value as changed if the value string differs
928 SetValueDidChange (m_old_value_str != m_value_str);
929 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000930 }
931 }
932 if (m_value_str.empty())
933 return NULL;
934 return m_value_str.c_str();
935}
936
Enrico Granatac3e320a2011-08-02 17:27:39 +0000937// if > 8bytes, 0 is returned. this method should mostly be used
938// to read address values out of pointers
939unsigned long long
940ValueObject::GetValueAsUnsigned()
941{
942 // If our byte size is zero this is an aggregate type that has children
943 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
944 {
945 if (UpdateValueIfNeeded(true))
946 {
947 uint32_t offset = 0;
948 return m_data.GetMaxU64(&offset,
949 m_data.GetByteSize());
950 }
951 }
952 return 0;
953}
954
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000955bool
956ValueObject::GetPrintableRepresentation(Stream& s,
957 ValueObjectRepresentationStyle val_obj_display,
Enrico Granata0a3958e2011-07-02 00:25:22 +0000958 lldb::Format custom_format)
959{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000960
961 RefCounter ref(&m_dump_printable_counter);
962
Enrico Granata9dd75c82011-07-15 23:30:15 +0000963 if (custom_format != lldb::eFormatInvalid)
Enrico Granata0a3958e2011-07-02 00:25:22 +0000964 SetFormat(custom_format);
965
966 const char * return_value;
Enrico Granatacd1c0232011-08-04 23:37:18 +0000967 std::string alloc_mem;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000968
969 switch(val_obj_display)
970 {
971 case eDisplayValue:
972 return_value = GetValueAsCString();
973 break;
974 case eDisplaySummary:
975 return_value = GetSummaryAsCString();
976 break;
977 case eDisplayLanguageSpecific:
978 return_value = GetObjectDescription();
979 break;
Enrico Granataf2bbf712011-07-15 02:26:42 +0000980 case eDisplayLocation:
981 return_value = GetLocationAsCString();
982 break;
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000983 case eDisplayChildrenCount:
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000984 {
Enrico Granatacd1c0232011-08-04 23:37:18 +0000985 alloc_mem.resize(512);
986 return_value = &alloc_mem[0];
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000987 int count = GetNumChildren();
Enrico Granatacd1c0232011-08-04 23:37:18 +0000988 snprintf((char*)return_value, 512, "%d", count);
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000989 break;
990 }
991 default:
992 break;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000993 }
994
Enrico Granataf4efecd2011-07-12 22:56:10 +0000995 // this code snippet might lead to endless recursion, thus we use a RefCounter here to
996 // check that we are not looping endlessly
997 if (!return_value && (m_dump_printable_counter < 3))
Enrico Granata9fc19442011-07-06 02:13:41 +0000998 {
999 // try to pick the other choice
1000 if (val_obj_display == eDisplayValue)
1001 return_value = GetSummaryAsCString();
1002 else if (val_obj_display == eDisplaySummary)
Enrico Granatae992a082011-07-22 17:03:19 +00001003 {
1004 if (ClangASTContext::IsAggregateType (GetClangType()) == true)
1005 {
Enrico Granata5dfd49c2011-08-04 02:34:29 +00001006 // this thing has no value, and it seems to have no summary
1007 // some combination of unitialized data and other factors can also
1008 // raise this condition, so let's print a nice generic error message
1009 return_value = "<no available summary>";
Enrico Granatae992a082011-07-22 17:03:19 +00001010 }
1011 else
1012 return_value = GetValueAsCString();
1013 }
Enrico Granata9fc19442011-07-06 02:13:41 +00001014 }
Enrico Granata0a3958e2011-07-02 00:25:22 +00001015
Enrico Granata5dfd49c2011-08-04 02:34:29 +00001016 if (return_value)
1017 s.PutCString(return_value);
1018 else
1019 s.PutCString("<no printable representation>");
1020
1021 // we should only return false here if we could not do *anything*
1022 // even if we have an error message as output, that's a success
1023 // from our callers' perspective, so return true
1024 return true;
1025
Enrico Granata0a3958e2011-07-02 00:25:22 +00001026}
1027
Enrico Granata9fc19442011-07-06 02:13:41 +00001028bool
1029ValueObject::DumpPrintableRepresentation(Stream& s,
1030 ValueObjectRepresentationStyle val_obj_display,
1031 lldb::Format custom_format)
1032{
Enrico Granataf4efecd2011-07-12 22:56:10 +00001033
1034 clang_type_t elem_or_pointee_type;
1035 Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001036
Enrico Granataf4efecd2011-07-12 22:56:10 +00001037 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
1038 && val_obj_display == ValueObject::eDisplayValue)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001039 {
Enrico Granataf4efecd2011-07-12 22:56:10 +00001040 // when being asked to get a printable display an array or pointer type directly,
1041 // try to "do the right thing"
1042
1043 if (IsCStringContainer(true) &&
1044 (custom_format == lldb::eFormatCString ||
1045 custom_format == lldb::eFormatCharArray ||
1046 custom_format == lldb::eFormatChar ||
1047 custom_format == lldb::eFormatVectorOfChar)) // print char[] & char* directly
1048 {
1049 Error error;
1050 ReadPointedString(s,
1051 error,
1052 0,
1053 (custom_format == lldb::eFormatVectorOfChar) ||
1054 (custom_format == lldb::eFormatCharArray));
1055 return !error.Fail();
1056 }
1057
1058 if (custom_format == lldb::eFormatEnum)
1059 return false;
1060
1061 // this only works for arrays, because I have no way to know when
1062 // the pointed memory ends, and no special \0 end of data marker
1063 if (flags.Test(ClangASTContext::eTypeIsArray))
1064 {
1065 if ((custom_format == lldb::eFormatBytes) ||
1066 (custom_format == lldb::eFormatBytesWithASCII))
1067 {
1068 uint32_t count = GetNumChildren();
1069
1070 s << '[';
1071 for (uint32_t low = 0; low < count; low++)
1072 {
1073
1074 if (low)
1075 s << ',';
1076
1077 ValueObjectSP child = GetChildAtIndex(low,true);
1078 if (!child.get())
1079 {
Enrico Granatae992a082011-07-22 17:03:19 +00001080 s << "<invalid child>";
Enrico Granataf4efecd2011-07-12 22:56:10 +00001081 continue;
1082 }
1083 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format);
1084 }
1085
1086 s << ']';
1087
1088 return true;
1089 }
1090
1091 if ((custom_format == lldb::eFormatVectorOfChar) ||
1092 (custom_format == lldb::eFormatVectorOfFloat32) ||
1093 (custom_format == lldb::eFormatVectorOfFloat64) ||
1094 (custom_format == lldb::eFormatVectorOfSInt16) ||
1095 (custom_format == lldb::eFormatVectorOfSInt32) ||
1096 (custom_format == lldb::eFormatVectorOfSInt64) ||
1097 (custom_format == lldb::eFormatVectorOfSInt8) ||
1098 (custom_format == lldb::eFormatVectorOfUInt128) ||
1099 (custom_format == lldb::eFormatVectorOfUInt16) ||
1100 (custom_format == lldb::eFormatVectorOfUInt32) ||
1101 (custom_format == lldb::eFormatVectorOfUInt64) ||
1102 (custom_format == lldb::eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
1103 {
1104 uint32_t count = GetNumChildren();
1105
1106 lldb::Format format = FormatManager::GetSingleItemFormat(custom_format);
1107
1108 s << '[';
1109 for (uint32_t low = 0; low < count; low++)
1110 {
1111
1112 if (low)
1113 s << ',';
1114
1115 ValueObjectSP child = GetChildAtIndex(low,true);
1116 if (!child.get())
1117 {
Enrico Granatae992a082011-07-22 17:03:19 +00001118 s << "<invalid child>";
Enrico Granataf4efecd2011-07-12 22:56:10 +00001119 continue;
1120 }
1121 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format);
1122 }
1123
1124 s << ']';
1125
1126 return true;
1127 }
1128 }
1129
1130 if ((custom_format == lldb::eFormatBoolean) ||
1131 (custom_format == lldb::eFormatBinary) ||
1132 (custom_format == lldb::eFormatChar) ||
1133 (custom_format == lldb::eFormatCharPrintable) ||
1134 (custom_format == lldb::eFormatComplexFloat) ||
1135 (custom_format == lldb::eFormatDecimal) ||
1136 (custom_format == lldb::eFormatHex) ||
1137 (custom_format == lldb::eFormatFloat) ||
1138 (custom_format == lldb::eFormatOctal) ||
1139 (custom_format == lldb::eFormatOSType) ||
1140 (custom_format == lldb::eFormatUnicode16) ||
1141 (custom_format == lldb::eFormatUnicode32) ||
1142 (custom_format == lldb::eFormatUnsigned) ||
1143 (custom_format == lldb::eFormatPointer) ||
1144 (custom_format == lldb::eFormatComplexInteger) ||
1145 (custom_format == lldb::eFormatComplex) ||
1146 (custom_format == lldb::eFormatDefault)) // use the [] operator
1147 return false;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001148 }
Enrico Granata5dfd49c2011-08-04 02:34:29 +00001149 bool var_success = GetPrintableRepresentation(s, val_obj_display, custom_format);
Enrico Granata9dd75c82011-07-15 23:30:15 +00001150 if (custom_format != eFormatInvalid)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001151 SetFormat(eFormatDefault);
1152 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001153}
1154
Greg Clayton737b9322010-09-13 03:32:57 +00001155addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001156ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +00001157{
Enrico Granatac3e320a2011-08-02 17:27:39 +00001158 if (!UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +00001159 return LLDB_INVALID_ADDRESS;
1160
Greg Clayton73b472d2010-10-27 03:32:59 +00001161 switch (m_value.GetValueType())
1162 {
1163 case Value::eValueTypeScalar:
1164 if (scalar_is_load_address)
1165 {
1166 address_type = eAddressTypeLoad;
1167 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1168 }
1169 break;
1170
1171 case Value::eValueTypeLoadAddress:
1172 case Value::eValueTypeFileAddress:
1173 case Value::eValueTypeHostAddress:
1174 {
1175 address_type = m_value.GetValueAddressType ();
1176 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1177 }
1178 break;
1179 }
1180 address_type = eAddressTypeInvalid;
1181 return LLDB_INVALID_ADDRESS;
1182}
1183
1184addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001185ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +00001186{
1187 lldb::addr_t address = LLDB_INVALID_ADDRESS;
1188 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +00001189
Enrico Granatac3e320a2011-08-02 17:27:39 +00001190 if (!UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +00001191 return address;
1192
Greg Clayton73b472d2010-10-27 03:32:59 +00001193 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +00001194 {
1195 case Value::eValueTypeScalar:
1196 if (scalar_is_load_address)
1197 {
1198 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1199 address_type = eAddressTypeLoad;
1200 }
1201 break;
1202
1203 case Value::eValueTypeLoadAddress:
1204 case Value::eValueTypeFileAddress:
1205 case Value::eValueTypeHostAddress:
1206 {
1207 uint32_t data_offset = 0;
1208 address = m_data.GetPointer(&data_offset);
1209 address_type = m_value.GetValueAddressType();
1210 if (address_type == eAddressTypeInvalid)
1211 address_type = eAddressTypeLoad;
1212 }
1213 break;
1214 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001215
1216 if (m_pointers_point_to_load_addrs)
1217 address_type = eAddressTypeLoad;
1218
Greg Clayton737b9322010-09-13 03:32:57 +00001219 return address;
1220}
1221
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001222bool
Jim Ingham6035b672011-03-31 00:19:25 +00001223ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001224{
1225 // Make sure our value is up to date first so that our location and location
1226 // type is valid.
Enrico Granatac3e320a2011-08-02 17:27:39 +00001227 if (!UpdateValueIfNeeded(false))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001228 return false;
1229
1230 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001231 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001232
Greg Claytonb1320972010-07-14 00:18:15 +00001233 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001234
Jim Ingham16e0c682011-08-12 23:34:31 +00001235 Value::ValueType value_type = m_value.GetValueType();
1236
1237 if (value_type == Value::eValueTypeScalar)
1238 {
1239 // If the value is already a scalar, then let the scalar change itself:
1240 m_value.GetScalar().SetValueFromCString (value_str, encoding, byte_size);
1241 }
1242 else if (byte_size <= Scalar::GetMaxByteSize())
1243 {
1244 // If the value fits in a scalar, then make a new scalar and again let the
1245 // scalar code do the conversion, then figure out where to put the new value.
1246 Scalar new_scalar;
1247 Error error;
1248 error = new_scalar.SetValueFromCString (value_str, encoding, byte_size);
1249 if (error.Success())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001250 {
Jim Ingham4b536182011-08-09 02:12:22 +00001251 switch (value_type)
1252 {
Jim Ingham16e0c682011-08-12 23:34:31 +00001253 case Value::eValueTypeLoadAddress:
1254 {
1255 // If it is a load address, then the scalar value is the storage location
1256 // of the data, and we have to shove this value down to that load location.
1257 ProcessSP process_sp = GetUpdatePoint().GetProcessSP();
1258 if (process_sp)
1259 {
1260 lldb::addr_t target_addr = m_value.GetScalar().GetRawBits64(LLDB_INVALID_ADDRESS);
1261 size_t bytes_written = process_sp->WriteScalarToMemory (target_addr,
1262 new_scalar,
1263 byte_size,
1264 error);
1265 if (!error.Success() || bytes_written != byte_size)
1266 return false;
1267 }
1268 }
Jim Ingham4b536182011-08-09 02:12:22 +00001269 break;
Jim Ingham16e0c682011-08-12 23:34:31 +00001270 case Value::eValueTypeHostAddress:
1271 {
1272 // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
1273 DataExtractor new_data;
1274 new_data.SetByteOrder (m_data.GetByteOrder());
1275
1276 DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0));
1277 m_data.SetData(buffer_sp, 0);
1278 bool success = new_scalar.GetData(new_data);
1279 if (success)
1280 {
1281 new_data.CopyByteOrderedData(0,
1282 byte_size,
1283 const_cast<uint8_t *>(m_data.GetDataStart()),
1284 byte_size,
1285 m_data.GetByteOrder());
1286 }
1287 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1288
1289 }
Jim Ingham4b536182011-08-09 02:12:22 +00001290 break;
Jim Ingham16e0c682011-08-12 23:34:31 +00001291 case Value::eValueTypeFileAddress:
1292 case Value::eValueTypeScalar:
1293 break;
Jim Ingham4b536182011-08-09 02:12:22 +00001294 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001295 }
1296 else
1297 {
Jim Ingham16e0c682011-08-12 23:34:31 +00001298 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001299 }
Jim Ingham16e0c682011-08-12 23:34:31 +00001300 }
1301 else
1302 {
1303 // We don't support setting things bigger than a scalar at present.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001304 return false;
1305 }
Jim Ingham16e0c682011-08-12 23:34:31 +00001306
1307 // If we have reached this point, then we have successfully changed the value.
1308 SetNeedsUpdate();
1309 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001310}
1311
Jim Ingham5a369122010-09-28 01:25:32 +00001312lldb::LanguageType
1313ValueObject::GetObjectRuntimeLanguage ()
1314{
Enrico Granatac3e320a2011-08-02 17:27:39 +00001315 return ClangASTType::GetMinimumLanguage (GetClangAST(),
1316 GetClangType());
Jim Ingham5a369122010-09-28 01:25:32 +00001317}
1318
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001319void
Jim Ingham58b59f92011-04-22 23:53:53 +00001320ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001321{
Jim Ingham58b59f92011-04-22 23:53:53 +00001322 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001323}
1324
1325ValueObjectSP
1326ValueObject::GetSyntheticChild (const ConstString &key) const
1327{
1328 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +00001329 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001330 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +00001331 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001332 return synthetic_child_sp;
1333}
1334
1335bool
1336ValueObject::IsPointerType ()
1337{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001338 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001339}
1340
Jim Inghamb7603bb2011-03-18 00:05:18 +00001341bool
Greg Claytondaf515f2011-07-09 20:12:33 +00001342ValueObject::IsArrayType ()
1343{
1344 return ClangASTContext::IsArrayType (GetClangType());
1345}
1346
1347bool
Enrico Granata9fc19442011-07-06 02:13:41 +00001348ValueObject::IsScalarType ()
1349{
1350 return ClangASTContext::IsScalarType (GetClangType());
1351}
1352
1353bool
Jim Inghamb7603bb2011-03-18 00:05:18 +00001354ValueObject::IsIntegerType (bool &is_signed)
1355{
1356 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
1357}
Greg Clayton73b472d2010-10-27 03:32:59 +00001358
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001359bool
1360ValueObject::IsPointerOrReferenceType ()
1361{
Greg Clayton007d5be2011-05-30 00:49:24 +00001362 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
1363}
1364
1365bool
1366ValueObject::IsPossibleCPlusPlusDynamicType ()
1367{
1368 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001369}
1370
Greg Claytondea8cb42011-06-29 22:09:02 +00001371bool
1372ValueObject::IsPossibleDynamicType ()
1373{
1374 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
1375}
1376
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001377ValueObjectSP
1378ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
1379{
1380 ValueObjectSP synthetic_child_sp;
1381 if (IsPointerType ())
1382 {
1383 char index_str[64];
1384 snprintf(index_str, sizeof(index_str), "[%i]", index);
1385 ConstString index_const_str(index_str);
1386 // Check if we have already created a synthetic array member in this
1387 // valid object. If we have we will re-use it.
1388 synthetic_child_sp = GetSyntheticChild (index_const_str);
1389 if (!synthetic_child_sp)
1390 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001391 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001392 // We haven't made a synthetic array member for INDEX yet, so
1393 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001394 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001395
1396 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001397 if (synthetic_child)
1398 {
1399 AddSyntheticChild(index_const_str, synthetic_child);
1400 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001401 synthetic_child_sp->SetName(ConstString(index_str));
Enrico Granata0a3958e2011-07-02 00:25:22 +00001402 synthetic_child_sp->m_is_array_item_for_pointer = true;
Jim Ingham58b59f92011-04-22 23:53:53 +00001403 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001404 }
1405 }
1406 return synthetic_child_sp;
1407}
Jim Ingham22777012010-09-23 02:01:19 +00001408
Greg Claytondaf515f2011-07-09 20:12:33 +00001409// This allows you to create an array member using and index
1410// that doesn't not fall in the normal bounds of the array.
1411// Many times structure can be defined as:
1412// struct Collection
1413// {
1414// uint32_t item_count;
1415// Item item_array[0];
1416// };
1417// The size of the "item_array" is 1, but many times in practice
1418// there are more items in "item_array".
1419
1420ValueObjectSP
1421ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create)
1422{
1423 ValueObjectSP synthetic_child_sp;
1424 if (IsArrayType ())
1425 {
1426 char index_str[64];
1427 snprintf(index_str, sizeof(index_str), "[%i]", index);
1428 ConstString index_const_str(index_str);
1429 // Check if we have already created a synthetic array member in this
1430 // valid object. If we have we will re-use it.
1431 synthetic_child_sp = GetSyntheticChild (index_const_str);
1432 if (!synthetic_child_sp)
1433 {
1434 ValueObject *synthetic_child;
1435 // We haven't made a synthetic array member for INDEX yet, so
1436 // lets make one and cache it for any future reference.
1437 synthetic_child = CreateChildAtIndex(0, true, index);
1438
1439 // Cache the value if we got one back...
1440 if (synthetic_child)
1441 {
1442 AddSyntheticChild(index_const_str, synthetic_child);
1443 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001444 synthetic_child_sp->SetName(ConstString(index_str));
Greg Claytondaf515f2011-07-09 20:12:33 +00001445 synthetic_child_sp->m_is_array_item_for_pointer = true;
1446 }
1447 }
1448 }
1449 return synthetic_child_sp;
1450}
1451
Enrico Granata9fc19442011-07-06 02:13:41 +00001452ValueObjectSP
1453ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
1454{
1455 ValueObjectSP synthetic_child_sp;
1456 if (IsScalarType ())
1457 {
1458 char index_str[64];
1459 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1460 ConstString index_const_str(index_str);
1461 // Check if we have already created a synthetic array member in this
1462 // valid object. If we have we will re-use it.
1463 synthetic_child_sp = GetSyntheticChild (index_const_str);
1464 if (!synthetic_child_sp)
1465 {
1466 ValueObjectChild *synthetic_child;
1467 // We haven't made a synthetic array member for INDEX yet, so
1468 // lets make one and cache it for any future reference.
1469 synthetic_child = new ValueObjectChild(*this,
1470 GetClangAST(),
1471 GetClangType(),
1472 index_const_str,
1473 GetByteSize(),
1474 0,
1475 to-from+1,
1476 from,
1477 false,
1478 false);
1479
1480 // Cache the value if we got one back...
1481 if (synthetic_child)
1482 {
1483 AddSyntheticChild(index_const_str, synthetic_child);
1484 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001485 synthetic_child_sp->SetName(ConstString(index_str));
Enrico Granata9fc19442011-07-06 02:13:41 +00001486 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1487 }
1488 }
1489 }
1490 return synthetic_child_sp;
1491}
1492
Enrico Granata6f3533f2011-07-29 19:53:35 +00001493lldb::ValueObjectSP
1494ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
1495{
1496
1497 ValueObjectSP synthetic_child_sp;
1498
1499 char name_str[64];
1500 snprintf(name_str, sizeof(name_str), "@%i", offset);
1501 ConstString name_const_str(name_str);
1502
1503 // Check if we have already created a synthetic array member in this
1504 // valid object. If we have we will re-use it.
1505 synthetic_child_sp = GetSyntheticChild (name_const_str);
1506
1507 if (synthetic_child_sp.get())
1508 return synthetic_child_sp;
1509
1510 if (!can_create)
1511 return lldb::ValueObjectSP();
1512
1513 ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
1514 type.GetASTContext(),
1515 type.GetOpaqueQualType(),
1516 name_const_str,
1517 type.GetTypeByteSize(),
1518 offset,
1519 0,
1520 0,
1521 false,
1522 false);
1523 if (synthetic_child)
1524 {
1525 AddSyntheticChild(name_const_str, synthetic_child);
1526 synthetic_child_sp = synthetic_child->GetSP();
1527 synthetic_child_sp->SetName(name_const_str);
1528 synthetic_child_sp->m_is_child_at_offset = true;
1529 }
1530 return synthetic_child_sp;
1531}
1532
Enrico Granatad55546b2011-07-22 00:16:08 +00001533// your expression path needs to have a leading . or ->
1534// (unless it somehow "looks like" an array, in which case it has
1535// a leading [ symbol). while the [ is meaningful and should be shown
1536// to the user, . and -> are just parser design, but by no means
1537// added information for the user.. strip them off
1538static const char*
1539SkipLeadingExpressionPathSeparators(const char* expression)
1540{
1541 if (!expression || !expression[0])
1542 return expression;
1543 if (expression[0] == '.')
1544 return expression+1;
1545 if (expression[0] == '-' && expression[1] == '>')
1546 return expression+2;
1547 return expression;
1548}
1549
1550lldb::ValueObjectSP
1551ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_create)
1552{
1553 ValueObjectSP synthetic_child_sp;
1554 ConstString name_const_string(expression);
1555 // Check if we have already created a synthetic array member in this
1556 // valid object. If we have we will re-use it.
1557 synthetic_child_sp = GetSyntheticChild (name_const_string);
1558 if (!synthetic_child_sp)
1559 {
1560 // We haven't made a synthetic array member for expression yet, so
1561 // lets make one and cache it for any future reference.
1562 synthetic_child_sp = GetValueForExpressionPath(expression);
1563
1564 // Cache the value if we got one back...
1565 if (synthetic_child_sp.get())
1566 {
1567 AddSyntheticChild(name_const_string, synthetic_child_sp.get());
Enrico Granata6f3533f2011-07-29 19:53:35 +00001568 synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression)));
Enrico Granatad55546b2011-07-22 00:16:08 +00001569 synthetic_child_sp->m_is_expression_path_child = true;
1570 }
1571 }
1572 return synthetic_child_sp;
1573}
1574
1575void
1576ValueObject::CalculateSyntheticValue (lldb::SyntheticValueType use_synthetic)
1577{
1578 if (use_synthetic == lldb::eNoSyntheticFilter)
1579 return;
1580
Enrico Granatac3e320a2011-08-02 17:27:39 +00001581 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
Enrico Granatad55546b2011-07-22 00:16:08 +00001582
1583 if (m_last_synthetic_filter.get() == NULL)
1584 return;
1585
Enrico Granataa37a0652011-07-24 00:14:56 +00001586 if (m_synthetic_value == NULL)
1587 m_synthetic_value = new ValueObjectSynthetic(*this, m_last_synthetic_filter);
Enrico Granatad55546b2011-07-22 00:16:08 +00001588
1589}
1590
Jim Ingham78a685a2011-04-16 00:01:13 +00001591void
Jim Ingham2837b762011-05-04 03:43:18 +00001592ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001593{
Jim Ingham2837b762011-05-04 03:43:18 +00001594 if (use_dynamic == lldb::eNoDynamicValues)
1595 return;
1596
Jim Ingham58b59f92011-04-22 23:53:53 +00001597 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001598 {
Enrico Granata6f3533f2011-07-29 19:53:35 +00001599 Process *process = m_update_point.GetProcessSP().get();
Jim Ingham78a685a2011-04-16 00:01:13 +00001600 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001601
Jim Ingham78a685a2011-04-16 00:01:13 +00001602
1603 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1604 // hard code this everywhere.
1605 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1606 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1607 {
1608 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1609 if (runtime)
1610 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1611 }
1612 else
1613 {
1614 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1615 if (cpp_runtime)
1616 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1617
1618 if (!worth_having_dynamic_value)
1619 {
1620 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1621 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001622 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001623 }
1624 }
1625
1626 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001627 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001628
1629// if (worth_having_dynamic_value)
1630// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1631
Jim Ingham78a685a2011-04-16 00:01:13 +00001632 }
1633}
1634
Jim Ingham58b59f92011-04-22 23:53:53 +00001635ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001636ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001637{
Jim Ingham2837b762011-05-04 03:43:18 +00001638 if (use_dynamic == lldb::eNoDynamicValues)
1639 return ValueObjectSP();
1640
1641 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001642 {
Jim Ingham2837b762011-05-04 03:43:18 +00001643 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001644 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001645 if (m_dynamic_value)
1646 return m_dynamic_value->GetSP();
1647 else
1648 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001649}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001650
Enrico Granatad55546b2011-07-22 00:16:08 +00001651// GetDynamicValue() returns a NULL SharedPointer if the object is not dynamic
1652// or we do not really want a dynamic VO. this method instead returns this object
1653// itself when making it synthetic has no meaning. this makes it much simpler
1654// to replace the SyntheticValue for the ValueObject
1655ValueObjectSP
1656ValueObject::GetSyntheticValue (SyntheticValueType use_synthetic)
1657{
1658 if (use_synthetic == lldb::eNoSyntheticFilter)
1659 return GetSP();
1660
Enrico Granatac3e320a2011-08-02 17:27:39 +00001661 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
Enrico Granatad55546b2011-07-22 00:16:08 +00001662
1663 if (m_last_synthetic_filter.get() == NULL)
1664 return GetSP();
1665
1666 CalculateSyntheticValue(use_synthetic);
1667
1668 if (m_synthetic_value)
1669 return m_synthetic_value->GetSP();
1670 else
1671 return GetSP();
1672}
1673
Greg Claytone221f822011-01-21 01:59:00 +00001674bool
Enrico Granata27b625e2011-08-09 01:04:56 +00001675ValueObject::HasSyntheticValue()
1676{
1677 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
1678
1679 if (m_last_synthetic_filter.get() == NULL)
1680 return false;
1681
1682 CalculateSyntheticValue(lldb::eUseSyntheticFilter);
1683
1684 if (m_synthetic_value)
1685 return true;
1686 else
1687 return false;
1688}
1689
1690bool
Greg Claytone221f822011-01-21 01:59:00 +00001691ValueObject::GetBaseClassPath (Stream &s)
1692{
1693 if (IsBaseClass())
1694 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001695 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001696 clang_type_t clang_type = GetClangType();
1697 std::string cxx_class_name;
1698 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1699 if (this_had_base_class)
1700 {
1701 if (parent_had_base_class)
1702 s.PutCString("::");
1703 s.PutCString(cxx_class_name.c_str());
1704 }
1705 return parent_had_base_class || this_had_base_class;
1706 }
1707 return false;
1708}
1709
1710
1711ValueObject *
1712ValueObject::GetNonBaseClassParent()
1713{
Jim Ingham78a685a2011-04-16 00:01:13 +00001714 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001715 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001716 if (GetParent()->IsBaseClass())
1717 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001718 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001719 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001720 }
1721 return NULL;
1722}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001723
1724void
Enrico Granata4becb372011-06-29 22:27:15 +00001725ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001726{
Greg Claytone221f822011-01-21 01:59:00 +00001727 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00001728
Enrico Granata9dd75c82011-07-15 23:30:15 +00001729 if (is_deref_of_parent && epformat == eDereferencePointers) {
Enrico Granata4becb372011-06-29 22:27:15 +00001730 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
1731 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
1732 // the eHonorPointers mode is meant to produce strings in this latter format
1733 s.PutCString("*(");
1734 }
Greg Claytone221f822011-01-21 01:59:00 +00001735
Enrico Granata4becb372011-06-29 22:27:15 +00001736 ValueObject* parent = GetParent();
1737
1738 if (parent)
1739 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
Enrico Granata0a3958e2011-07-02 00:25:22 +00001740
1741 // if we are a deref_of_parent just because we are synthetic array
1742 // members made up to allow ptr[%d] syntax to work in variable
1743 // printing, then add our name ([%d]) to the expression path
Enrico Granata9dd75c82011-07-15 23:30:15 +00001744 if (m_is_array_item_for_pointer && epformat == eHonorPointers)
Enrico Granata0a3958e2011-07-02 00:25:22 +00001745 s.PutCString(m_name.AsCString());
Enrico Granata4becb372011-06-29 22:27:15 +00001746
Greg Claytone221f822011-01-21 01:59:00 +00001747 if (!IsBaseClass())
1748 {
1749 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001750 {
Greg Claytone221f822011-01-21 01:59:00 +00001751 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1752 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001753 {
Greg Claytone221f822011-01-21 01:59:00 +00001754 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1755 if (non_base_class_parent_clang_type)
1756 {
1757 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1758
Enrico Granata9dd75c82011-07-15 23:30:15 +00001759 if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00001760 {
1761 s.PutCString("->");
1762 }
Enrico Granata4becb372011-06-29 22:27:15 +00001763 else
1764 {
1765 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1766 {
1767 s.PutCString("->");
1768 }
1769 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1770 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1771 {
1772 s.PutChar('.');
1773 }
Greg Claytone221f822011-01-21 01:59:00 +00001774 }
1775 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001776 }
Greg Claytone221f822011-01-21 01:59:00 +00001777
1778 const char *name = GetName().GetCString();
1779 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001780 {
Greg Claytone221f822011-01-21 01:59:00 +00001781 if (qualify_cxx_base_classes)
1782 {
1783 if (GetBaseClassPath (s))
1784 s.PutCString("::");
1785 }
1786 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001787 }
1788 }
1789 }
1790
Enrico Granata4becb372011-06-29 22:27:15 +00001791 if (is_deref_of_parent && epformat == eDereferencePointers) {
Greg Claytone221f822011-01-21 01:59:00 +00001792 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00001793 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001794}
1795
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001796lldb::ValueObjectSP
1797ValueObject::GetValueForExpressionPath(const char* expression,
1798 const char** first_unparsed,
1799 ExpressionPathScanEndReason* reason_to_stop,
1800 ExpressionPathEndResultType* final_value_type,
1801 const GetValueForExpressionPathOptions& options,
1802 ExpressionPathAftermath* final_task_on_target)
1803{
1804
1805 const char* dummy_first_unparsed;
1806 ExpressionPathScanEndReason dummy_reason_to_stop;
1807 ExpressionPathEndResultType dummy_final_value_type;
1808 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1809
1810 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1811 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1812 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1813 final_value_type ? final_value_type : &dummy_final_value_type,
1814 options,
1815 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1816
1817 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1818 {
1819 return ret_val;
1820 }
1821 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1822 {
1823 if (*final_task_on_target == ValueObject::eDereference)
1824 {
1825 Error error;
1826 ValueObjectSP final_value = ret_val->Dereference(error);
1827 if (error.Fail() || !final_value.get())
1828 {
1829 *reason_to_stop = ValueObject::eDereferencingFailed;
1830 *final_value_type = ValueObject::eInvalid;
1831 return ValueObjectSP();
1832 }
1833 else
1834 {
1835 *final_task_on_target = ValueObject::eNothing;
1836 return final_value;
1837 }
1838 }
1839 if (*final_task_on_target == ValueObject::eTakeAddress)
1840 {
1841 Error error;
1842 ValueObjectSP final_value = ret_val->AddressOf(error);
1843 if (error.Fail() || !final_value.get())
1844 {
1845 *reason_to_stop = ValueObject::eTakingAddressFailed;
1846 *final_value_type = ValueObject::eInvalid;
1847 return ValueObjectSP();
1848 }
1849 else
1850 {
1851 *final_task_on_target = ValueObject::eNothing;
1852 return final_value;
1853 }
1854 }
1855 }
1856 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
1857}
1858
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001859int
1860ValueObject::GetValuesForExpressionPath(const char* expression,
1861 lldb::ValueObjectListSP& list,
1862 const char** first_unparsed,
1863 ExpressionPathScanEndReason* reason_to_stop,
1864 ExpressionPathEndResultType* final_value_type,
1865 const GetValueForExpressionPathOptions& options,
1866 ExpressionPathAftermath* final_task_on_target)
1867{
1868 const char* dummy_first_unparsed;
1869 ExpressionPathScanEndReason dummy_reason_to_stop;
1870 ExpressionPathEndResultType dummy_final_value_type;
1871 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1872
1873 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1874 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1875 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1876 final_value_type ? final_value_type : &dummy_final_value_type,
1877 options,
1878 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1879
1880 if (!ret_val.get()) // if there are errors, I add nothing to the list
1881 return 0;
1882
1883 if (*reason_to_stop != eArrayRangeOperatorMet)
1884 {
1885 // I need not expand a range, just post-process the final value and return
1886 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1887 {
1888 list->Append(ret_val);
1889 return 1;
1890 }
1891 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1892 {
1893 if (*final_task_on_target == ValueObject::eDereference)
1894 {
1895 Error error;
1896 ValueObjectSP final_value = ret_val->Dereference(error);
1897 if (error.Fail() || !final_value.get())
1898 {
1899 *reason_to_stop = ValueObject::eDereferencingFailed;
1900 *final_value_type = ValueObject::eInvalid;
1901 return 0;
1902 }
1903 else
1904 {
1905 *final_task_on_target = ValueObject::eNothing;
1906 list->Append(final_value);
1907 return 1;
1908 }
1909 }
1910 if (*final_task_on_target == ValueObject::eTakeAddress)
1911 {
1912 Error error;
1913 ValueObjectSP final_value = ret_val->AddressOf(error);
1914 if (error.Fail() || !final_value.get())
1915 {
1916 *reason_to_stop = ValueObject::eTakingAddressFailed;
1917 *final_value_type = ValueObject::eInvalid;
1918 return 0;
1919 }
1920 else
1921 {
1922 *final_task_on_target = ValueObject::eNothing;
1923 list->Append(final_value);
1924 return 1;
1925 }
1926 }
1927 }
1928 }
1929 else
1930 {
1931 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
1932 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1933 ret_val,
1934 list,
1935 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1936 final_value_type ? final_value_type : &dummy_final_value_type,
1937 options,
1938 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1939 }
1940 // in any non-covered case, just do the obviously right thing
1941 list->Append(ret_val);
1942 return 1;
1943}
1944
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001945lldb::ValueObjectSP
1946ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
1947 const char** first_unparsed,
1948 ExpressionPathScanEndReason* reason_to_stop,
1949 ExpressionPathEndResultType* final_result,
1950 const GetValueForExpressionPathOptions& options,
1951 ExpressionPathAftermath* what_next)
1952{
1953 ValueObjectSP root = GetSP();
1954
1955 if (!root.get())
1956 return ValueObjectSP();
1957
1958 *first_unparsed = expression_cstr;
1959
1960 while (true)
1961 {
1962
1963 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
1964
1965 lldb::clang_type_t root_clang_type = root->GetClangType();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001966 lldb::clang_type_t pointee_clang_type;
1967 Flags root_clang_type_info,pointee_clang_type_info;
1968
1969 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
1970 if (pointee_clang_type)
1971 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001972
1973 if (!expression_cstr || *expression_cstr == '\0')
1974 {
1975 *reason_to_stop = ValueObject::eEndOfString;
1976 return root;
1977 }
1978
1979 switch (*expression_cstr)
1980 {
1981 case '-':
1982 {
1983 if (options.m_check_dot_vs_arrow_syntax &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001984 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 +00001985 {
1986 *first_unparsed = expression_cstr;
1987 *reason_to_stop = ValueObject::eArrowInsteadOfDot;
1988 *final_result = ValueObject::eInvalid;
1989 return ValueObjectSP();
1990 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001991 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
1992 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) &&
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001993 options.m_no_fragile_ivar)
1994 {
1995 *first_unparsed = expression_cstr;
1996 *reason_to_stop = ValueObject::eFragileIVarNotAllowed;
1997 *final_result = ValueObject::eInvalid;
1998 return ValueObjectSP();
1999 }
2000 if (expression_cstr[1] != '>')
2001 {
2002 *first_unparsed = expression_cstr;
2003 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2004 *final_result = ValueObject::eInvalid;
2005 return ValueObjectSP();
2006 }
2007 expression_cstr++; // skip the -
2008 }
2009 case '.': // or fallthrough from ->
2010 {
2011 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002012 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 +00002013 {
2014 *first_unparsed = expression_cstr;
2015 *reason_to_stop = ValueObject::eDotInsteadOfArrow;
2016 *final_result = ValueObject::eInvalid;
2017 return ValueObjectSP();
2018 }
2019 expression_cstr++; // skip .
2020 const char *next_separator = strpbrk(expression_cstr+1,"-.[");
2021 ConstString child_name;
2022 if (!next_separator) // if no other separator just expand this last layer
2023 {
2024 child_name.SetCString (expression_cstr);
Enrico Granata8c9d3562011-08-11 17:08:01 +00002025 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
2026
2027 if (child_valobj_sp.get()) // we know we are done, so just return
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002028 {
2029 *first_unparsed = '\0';
2030 *reason_to_stop = ValueObject::eEndOfString;
2031 *final_result = ValueObject::ePlain;
Enrico Granata8c9d3562011-08-11 17:08:01 +00002032 return child_valobj_sp;
2033 }
2034 else if (options.m_no_synthetic_children == false) // let's try with synthetic children
2035 {
2036 child_valobj_sp = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildMemberWithName(child_name, true);
2037 }
2038
2039 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
2040 // so we hit the "else" branch, and return an error
2041 if(child_valobj_sp.get()) // if it worked, just return
2042 {
2043 *first_unparsed = '\0';
2044 *reason_to_stop = ValueObject::eEndOfString;
2045 *final_result = ValueObject::ePlain;
2046 return child_valobj_sp;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002047 }
2048 else
2049 {
2050 *first_unparsed = expression_cstr;
2051 *reason_to_stop = ValueObject::eNoSuchChild;
2052 *final_result = ValueObject::eInvalid;
2053 return ValueObjectSP();
2054 }
2055 }
2056 else // other layers do expand
2057 {
2058 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
Enrico Granata8c9d3562011-08-11 17:08:01 +00002059 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
2060 if (child_valobj_sp.get()) // store the new root and move on
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002061 {
Enrico Granata8c9d3562011-08-11 17:08:01 +00002062 root = child_valobj_sp;
2063 *first_unparsed = next_separator;
2064 *final_result = ValueObject::ePlain;
2065 continue;
2066 }
2067 else if (options.m_no_synthetic_children == false) // let's try with synthetic children
2068 {
2069 child_valobj_sp = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildMemberWithName(child_name, true);
2070 }
2071
2072 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
2073 // so we hit the "else" branch, and return an error
2074 if(child_valobj_sp.get()) // if it worked, move on
2075 {
2076 root = child_valobj_sp;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002077 *first_unparsed = next_separator;
2078 *final_result = ValueObject::ePlain;
2079 continue;
2080 }
2081 else
2082 {
2083 *first_unparsed = expression_cstr;
2084 *reason_to_stop = ValueObject::eNoSuchChild;
2085 *final_result = ValueObject::eInvalid;
2086 return ValueObjectSP();
2087 }
2088 }
2089 break;
2090 }
2091 case '[':
2092 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002093 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 +00002094 {
Enrico Granata27b625e2011-08-09 01:04:56 +00002095 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar...
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002096 {
Enrico Granata27b625e2011-08-09 01:04:56 +00002097 if (options.m_no_synthetic_children) // ...only chance left is synthetic
2098 {
2099 *first_unparsed = expression_cstr;
2100 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2101 *final_result = ValueObject::eInvalid;
2102 return ValueObjectSP();
2103 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002104 }
2105 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2106 {
2107 *first_unparsed = expression_cstr;
2108 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2109 *final_result = ValueObject::eInvalid;
2110 return ValueObjectSP();
2111 }
2112 }
2113 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2114 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002115 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002116 {
2117 *first_unparsed = expression_cstr;
2118 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2119 *final_result = ValueObject::eInvalid;
2120 return ValueObjectSP();
2121 }
2122 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
2123 {
2124 *first_unparsed = expression_cstr+2;
2125 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2126 *final_result = ValueObject::eUnboundedRange;
2127 return root;
2128 }
2129 }
2130 const char *separator_position = ::strchr(expression_cstr+1,'-');
2131 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2132 if (!close_bracket_position) // if there is no ], this is a syntax error
2133 {
2134 *first_unparsed = expression_cstr;
2135 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2136 *final_result = ValueObject::eInvalid;
2137 return ValueObjectSP();
2138 }
2139 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2140 {
2141 char *end = NULL;
2142 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2143 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2144 {
2145 *first_unparsed = expression_cstr;
2146 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2147 *final_result = ValueObject::eInvalid;
2148 return ValueObjectSP();
2149 }
2150 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2151 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002152 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002153 {
2154 *first_unparsed = expression_cstr+2;
2155 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2156 *final_result = ValueObject::eUnboundedRange;
2157 return root;
2158 }
2159 else
2160 {
2161 *first_unparsed = expression_cstr;
2162 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2163 *final_result = ValueObject::eInvalid;
2164 return ValueObjectSP();
2165 }
2166 }
2167 // from here on we do have a valid index
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002168 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002169 {
Greg Claytondaf515f2011-07-09 20:12:33 +00002170 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2171 if (!child_valobj_sp)
2172 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
Enrico Granata27b625e2011-08-09 01:04:56 +00002173 if (!child_valobj_sp)
2174 if (root->HasSyntheticValue() && root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetNumChildren() > index)
2175 child_valobj_sp = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildAtIndex(index, true);
Greg Claytondaf515f2011-07-09 20:12:33 +00002176 if (child_valobj_sp)
2177 {
2178 root = child_valobj_sp;
2179 *first_unparsed = end+1; // skip ]
2180 *final_result = ValueObject::ePlain;
2181 continue;
2182 }
2183 else
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002184 {
2185 *first_unparsed = expression_cstr;
2186 *reason_to_stop = ValueObject::eNoSuchChild;
2187 *final_result = ValueObject::eInvalid;
2188 return ValueObjectSP();
2189 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002190 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002191 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002192 {
2193 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 +00002194 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002195 {
2196 Error error;
2197 root = root->Dereference(error);
2198 if (error.Fail() || !root.get())
2199 {
2200 *first_unparsed = expression_cstr;
2201 *reason_to_stop = ValueObject::eDereferencingFailed;
2202 *final_result = ValueObject::eInvalid;
2203 return ValueObjectSP();
2204 }
2205 else
2206 {
2207 *what_next = eNothing;
2208 continue;
2209 }
2210 }
2211 else
2212 {
Enrico Granata27b625e2011-08-09 01:04:56 +00002213 if (ClangASTType::GetMinimumLanguage(root->GetClangAST(),
2214 root->GetClangType()) == lldb::eLanguageTypeObjC
2215 &&
2216 ClangASTContext::IsPointerType(ClangASTType::GetPointeeType(root->GetClangType())) == false
2217 &&
2218 root->HasSyntheticValue()
2219 &&
2220 options.m_no_synthetic_children == false)
2221 {
2222 root = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildAtIndex(index, true);
2223 }
2224 else
2225 root = root->GetSyntheticArrayMemberFromPointer(index, true);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002226 if (!root.get())
2227 {
2228 *first_unparsed = expression_cstr;
2229 *reason_to_stop = ValueObject::eNoSuchChild;
2230 *final_result = ValueObject::eInvalid;
2231 return ValueObjectSP();
2232 }
2233 else
2234 {
2235 *first_unparsed = end+1; // skip ]
2236 *final_result = ValueObject::ePlain;
2237 continue;
2238 }
2239 }
2240 }
Enrico Granata27b625e2011-08-09 01:04:56 +00002241 else if (ClangASTContext::IsScalarType(root_clang_type))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002242 {
2243 root = root->GetSyntheticBitFieldChild(index, index, true);
2244 if (!root.get())
2245 {
2246 *first_unparsed = expression_cstr;
2247 *reason_to_stop = ValueObject::eNoSuchChild;
2248 *final_result = ValueObject::eInvalid;
2249 return ValueObjectSP();
2250 }
2251 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2252 {
2253 *first_unparsed = end+1; // skip ]
2254 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2255 *final_result = ValueObject::eBitfield;
2256 return root;
2257 }
2258 }
Enrico Granata8c9d3562011-08-11 17:08:01 +00002259 else if (root->HasSyntheticValue() && options.m_no_synthetic_children == false)
Enrico Granata27b625e2011-08-09 01:04:56 +00002260 {
2261 root = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildAtIndex(index, true);
2262 if (!root.get())
2263 {
2264 *first_unparsed = expression_cstr;
2265 *reason_to_stop = ValueObject::eNoSuchChild;
2266 *final_result = ValueObject::eInvalid;
2267 return ValueObjectSP();
2268 }
Enrico Granata8c9d3562011-08-11 17:08:01 +00002269 else
2270 {
2271 *first_unparsed = end+1; // skip ]
2272 *final_result = ValueObject::ePlain;
2273 continue;
2274 }
Enrico Granata27b625e2011-08-09 01:04:56 +00002275 }
2276 else
2277 {
2278 *first_unparsed = expression_cstr;
2279 *reason_to_stop = ValueObject::eNoSuchChild;
2280 *final_result = ValueObject::eInvalid;
2281 return ValueObjectSP();
2282 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002283 }
2284 else // we have a low and a high index
2285 {
2286 char *end = NULL;
2287 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2288 if (!end || end != separator_position) // if something weird is in our way return an error
2289 {
2290 *first_unparsed = expression_cstr;
2291 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2292 *final_result = ValueObject::eInvalid;
2293 return ValueObjectSP();
2294 }
2295 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2296 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2297 {
2298 *first_unparsed = expression_cstr;
2299 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2300 *final_result = ValueObject::eInvalid;
2301 return ValueObjectSP();
2302 }
2303 if (index_lower > index_higher) // swap indices if required
2304 {
2305 unsigned long temp = index_lower;
2306 index_lower = index_higher;
2307 index_higher = temp;
2308 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002309 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002310 {
2311 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2312 if (!root.get())
2313 {
2314 *first_unparsed = expression_cstr;
2315 *reason_to_stop = ValueObject::eNoSuchChild;
2316 *final_result = ValueObject::eInvalid;
2317 return ValueObjectSP();
2318 }
2319 else
2320 {
2321 *first_unparsed = end+1; // skip ]
2322 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2323 *final_result = ValueObject::eBitfield;
2324 return root;
2325 }
2326 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002327 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 +00002328 *what_next == ValueObject::eDereference &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002329 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002330 {
2331 Error error;
2332 root = root->Dereference(error);
2333 if (error.Fail() || !root.get())
2334 {
2335 *first_unparsed = expression_cstr;
2336 *reason_to_stop = ValueObject::eDereferencingFailed;
2337 *final_result = ValueObject::eInvalid;
2338 return ValueObjectSP();
2339 }
2340 else
2341 {
2342 *what_next = ValueObject::eNothing;
2343 continue;
2344 }
2345 }
2346 else
2347 {
2348 *first_unparsed = expression_cstr;
2349 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2350 *final_result = ValueObject::eBoundedRange;
2351 return root;
2352 }
2353 }
2354 break;
2355 }
2356 default: // some non-separator is in the way
2357 {
2358 *first_unparsed = expression_cstr;
2359 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2360 *final_result = ValueObject::eInvalid;
2361 return ValueObjectSP();
2362 break;
2363 }
2364 }
2365 }
2366}
2367
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002368int
2369ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
2370 const char** first_unparsed,
2371 lldb::ValueObjectSP root,
2372 lldb::ValueObjectListSP& list,
2373 ExpressionPathScanEndReason* reason_to_stop,
2374 ExpressionPathEndResultType* final_result,
2375 const GetValueForExpressionPathOptions& options,
2376 ExpressionPathAftermath* what_next)
2377{
2378 if (!root.get())
2379 return 0;
2380
2381 *first_unparsed = expression_cstr;
2382
2383 while (true)
2384 {
2385
2386 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
2387
2388 lldb::clang_type_t root_clang_type = root->GetClangType();
2389 lldb::clang_type_t pointee_clang_type;
2390 Flags root_clang_type_info,pointee_clang_type_info;
2391
2392 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
2393 if (pointee_clang_type)
2394 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
2395
2396 if (!expression_cstr || *expression_cstr == '\0')
2397 {
2398 *reason_to_stop = ValueObject::eEndOfString;
2399 list->Append(root);
2400 return 1;
2401 }
2402
2403 switch (*expression_cstr)
2404 {
2405 case '[':
2406 {
2407 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
2408 {
2409 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
2410 {
2411 *first_unparsed = expression_cstr;
2412 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2413 *final_result = ValueObject::eInvalid;
2414 return 0;
2415 }
2416 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2417 {
2418 *first_unparsed = expression_cstr;
2419 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2420 *final_result = ValueObject::eInvalid;
2421 return 0;
2422 }
2423 }
2424 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2425 {
2426 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2427 {
2428 *first_unparsed = expression_cstr;
2429 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2430 *final_result = ValueObject::eInvalid;
2431 return 0;
2432 }
2433 else // expand this into list
2434 {
2435 int max_index = root->GetNumChildren() - 1;
2436 for (int index = 0; index < max_index; index++)
2437 {
2438 ValueObjectSP child =
2439 root->GetChildAtIndex(index, true);
2440 list->Append(child);
2441 }
2442 *first_unparsed = expression_cstr+2;
2443 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2444 *final_result = ValueObject::eValueObjectList;
2445 return max_index; // tell me number of items I added to the VOList
2446 }
2447 }
2448 const char *separator_position = ::strchr(expression_cstr+1,'-');
2449 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2450 if (!close_bracket_position) // if there is no ], this is a syntax error
2451 {
2452 *first_unparsed = expression_cstr;
2453 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2454 *final_result = ValueObject::eInvalid;
2455 return 0;
2456 }
2457 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2458 {
2459 char *end = NULL;
2460 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2461 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2462 {
2463 *first_unparsed = expression_cstr;
2464 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2465 *final_result = ValueObject::eInvalid;
2466 return 0;
2467 }
2468 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2469 {
2470 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2471 {
2472 int max_index = root->GetNumChildren() - 1;
2473 for (int index = 0; index < max_index; index++)
2474 {
2475 ValueObjectSP child =
2476 root->GetChildAtIndex(index, true);
2477 list->Append(child);
2478 }
2479 *first_unparsed = expression_cstr+2;
2480 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2481 *final_result = ValueObject::eValueObjectList;
2482 return max_index; // tell me number of items I added to the VOList
2483 }
2484 else
2485 {
2486 *first_unparsed = expression_cstr;
2487 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2488 *final_result = ValueObject::eInvalid;
2489 return 0;
2490 }
2491 }
2492 // from here on we do have a valid index
2493 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2494 {
2495 root = root->GetChildAtIndex(index, true);
2496 if (!root.get())
2497 {
2498 *first_unparsed = expression_cstr;
2499 *reason_to_stop = ValueObject::eNoSuchChild;
2500 *final_result = ValueObject::eInvalid;
2501 return 0;
2502 }
2503 else
2504 {
2505 list->Append(root);
2506 *first_unparsed = end+1; // skip ]
2507 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2508 *final_result = ValueObject::eValueObjectList;
2509 return 1;
2510 }
2511 }
2512 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
2513 {
2514 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
2515 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2516 {
2517 Error error;
2518 root = root->Dereference(error);
2519 if (error.Fail() || !root.get())
2520 {
2521 *first_unparsed = expression_cstr;
2522 *reason_to_stop = ValueObject::eDereferencingFailed;
2523 *final_result = ValueObject::eInvalid;
2524 return 0;
2525 }
2526 else
2527 {
2528 *what_next = eNothing;
2529 continue;
2530 }
2531 }
2532 else
2533 {
2534 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2535 if (!root.get())
2536 {
2537 *first_unparsed = expression_cstr;
2538 *reason_to_stop = ValueObject::eNoSuchChild;
2539 *final_result = ValueObject::eInvalid;
2540 return 0;
2541 }
2542 else
2543 {
2544 list->Append(root);
2545 *first_unparsed = end+1; // skip ]
2546 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2547 *final_result = ValueObject::eValueObjectList;
2548 return 1;
2549 }
2550 }
2551 }
2552 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
2553 {
2554 root = root->GetSyntheticBitFieldChild(index, index, true);
2555 if (!root.get())
2556 {
2557 *first_unparsed = expression_cstr;
2558 *reason_to_stop = ValueObject::eNoSuchChild;
2559 *final_result = ValueObject::eInvalid;
2560 return 0;
2561 }
2562 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2563 {
2564 list->Append(root);
2565 *first_unparsed = end+1; // skip ]
2566 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2567 *final_result = ValueObject::eValueObjectList;
2568 return 1;
2569 }
2570 }
2571 }
2572 else // we have a low and a high index
2573 {
2574 char *end = NULL;
2575 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2576 if (!end || end != separator_position) // if something weird is in our way return an error
2577 {
2578 *first_unparsed = expression_cstr;
2579 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2580 *final_result = ValueObject::eInvalid;
2581 return 0;
2582 }
2583 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2584 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2585 {
2586 *first_unparsed = expression_cstr;
2587 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2588 *final_result = ValueObject::eInvalid;
2589 return 0;
2590 }
2591 if (index_lower > index_higher) // swap indices if required
2592 {
2593 unsigned long temp = index_lower;
2594 index_lower = index_higher;
2595 index_higher = temp;
2596 }
2597 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
2598 {
2599 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2600 if (!root.get())
2601 {
2602 *first_unparsed = expression_cstr;
2603 *reason_to_stop = ValueObject::eNoSuchChild;
2604 *final_result = ValueObject::eInvalid;
2605 return 0;
2606 }
2607 else
2608 {
2609 list->Append(root);
2610 *first_unparsed = end+1; // skip ]
2611 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2612 *final_result = ValueObject::eValueObjectList;
2613 return 1;
2614 }
2615 }
2616 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
2617 *what_next == ValueObject::eDereference &&
2618 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2619 {
2620 Error error;
2621 root = root->Dereference(error);
2622 if (error.Fail() || !root.get())
2623 {
2624 *first_unparsed = expression_cstr;
2625 *reason_to_stop = ValueObject::eDereferencingFailed;
2626 *final_result = ValueObject::eInvalid;
2627 return 0;
2628 }
2629 else
2630 {
2631 *what_next = ValueObject::eNothing;
2632 continue;
2633 }
2634 }
2635 else
2636 {
Johnny Chen44805302011-07-19 19:48:13 +00002637 for (unsigned long index = index_lower;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002638 index <= index_higher; index++)
2639 {
2640 ValueObjectSP child =
2641 root->GetChildAtIndex(index, true);
2642 list->Append(child);
2643 }
2644 *first_unparsed = end+1;
2645 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2646 *final_result = ValueObject::eValueObjectList;
2647 return index_higher-index_lower+1; // tell me number of items I added to the VOList
2648 }
2649 }
2650 break;
2651 }
2652 default: // some non-[ separator, or something entirely wrong, is in the way
2653 {
2654 *first_unparsed = expression_cstr;
2655 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2656 *final_result = ValueObject::eInvalid;
2657 return 0;
2658 break;
2659 }
2660 }
2661 }
2662}
2663
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002664void
Greg Clayton1d3afba2010-10-05 00:00:42 +00002665ValueObject::DumpValueObject
2666(
2667 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00002668 ValueObject *valobj,
2669 const char *root_valobj_name,
2670 uint32_t ptr_depth,
2671 uint32_t curr_depth,
2672 uint32_t max_depth,
2673 bool show_types,
2674 bool show_location,
2675 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00002676 lldb::DynamicValueType use_dynamic,
Enrico Granatad55546b2011-07-22 00:16:08 +00002677 bool use_synth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002678 bool scope_already_checked,
Enrico Granata0c5ef692011-07-16 01:22:04 +00002679 bool flat_output,
Enrico Granata22c55d12011-08-12 02:00:06 +00002680 uint32_t omit_summary_depth,
2681 bool ignore_cap
Greg Clayton1d3afba2010-10-05 00:00:42 +00002682)
2683{
Greg Clayton007d5be2011-05-30 00:49:24 +00002684 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002685 {
Enrico Granatac3e320a2011-08-02 17:27:39 +00002686 bool update_success = valobj->UpdateValueIfNeeded (use_dynamic, true);
Greg Clayton007d5be2011-05-30 00:49:24 +00002687
2688 if (update_success && use_dynamic != lldb::eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00002689 {
Jim Ingham2837b762011-05-04 03:43:18 +00002690 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00002691 if (dynamic_value)
2692 valobj = dynamic_value;
2693 }
2694
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002695 clang_type_t clang_type = valobj->GetClangType();
2696
Greg Clayton73b472d2010-10-27 03:32:59 +00002697 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002698 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00002699 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
2700 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002701
2702 const bool print_valobj = flat_output == false || has_value;
2703
2704 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002705 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002706 if (show_location)
2707 {
Jim Ingham6035b672011-03-31 00:19:25 +00002708 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002709 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002710
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002711 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002712
Greg Clayton7c8a9662010-11-02 01:50:16 +00002713 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00002714 if (show_types || (curr_depth == 0 && !flat_output))
Enrico Granatac3e320a2011-08-02 17:27:39 +00002715 {
Enrico Granata9910bc82011-08-03 02:18:51 +00002716 const char* typeName = valobj->GetTypeName().AsCString("<invalid type>");
2717 s.Printf("(%s", typeName);
2718 // only show dynamic types if the user really wants to see types
2719 if (show_types && use_dynamic != lldb::eNoDynamicValues &&
2720 (/*strstr(typeName, "id") == typeName ||*/
2721 ClangASTType::GetMinimumLanguage(valobj->GetClangAST(), valobj->GetClangType()) == lldb::eLanguageTypeObjC))
Enrico Granatac3e320a2011-08-02 17:27:39 +00002722 {
2723 Process* process = valobj->GetUpdatePoint().GetProcessSP().get();
2724 if (process == NULL)
Enrico Granata9910bc82011-08-03 02:18:51 +00002725 s.Printf(", dynamic type: unknown) ");
Enrico Granatac3e320a2011-08-02 17:27:39 +00002726 else
2727 {
2728 ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
2729 if (runtime == NULL)
Enrico Granata9910bc82011-08-03 02:18:51 +00002730 s.Printf(", dynamic type: unknown) ");
Enrico Granatac3e320a2011-08-02 17:27:39 +00002731 else
2732 {
2733 ObjCLanguageRuntime::ObjCISA isa = runtime->GetISA(*valobj);
2734 if (!runtime->IsValidISA(isa))
Enrico Granata9910bc82011-08-03 02:18:51 +00002735 s.Printf(", dynamic type: unknown) ");
Enrico Granatac3e320a2011-08-02 17:27:39 +00002736 else
2737 s.Printf(", dynamic type: %s) ",
2738 runtime->GetActualTypeName(isa).GetCString());
2739 }
2740 }
2741 }
2742 else
2743 s.Printf(") ");
2744 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002745
Greg Clayton1d3afba2010-10-05 00:00:42 +00002746
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002747 if (flat_output)
2748 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002749 // If we are showing types, also qualify the C++ base classes
2750 const bool qualify_cxx_base_classes = show_types;
2751 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002752 s.PutCString(" =");
2753 }
2754 else
2755 {
2756 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
2757 s.Printf ("%s =", name_cstr);
2758 }
2759
Jim Ingham6035b672011-03-31 00:19:25 +00002760 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002761 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002762 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002763 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002764 }
2765
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002766 const char *val_cstr = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00002767 const char *sum_cstr = NULL;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002768 SummaryFormat* entry = valobj->GetSummaryFormat().get();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002769
Enrico Granata0c5ef692011-07-16 01:22:04 +00002770 if (omit_summary_depth > 0)
2771 entry = NULL;
2772
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002773 if (err_cstr == NULL)
2774 {
Jim Ingham6035b672011-03-31 00:19:25 +00002775 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002776 err_cstr = valobj->GetError().AsCString();
2777 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002778
2779 if (err_cstr)
2780 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002781 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00002782 }
2783 else
2784 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002785 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002786 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002787 {
Enrico Granata4becb372011-06-29 22:27:15 +00002788
Enrico Granata0c5ef692011-07-16 01:22:04 +00002789 sum_cstr = (omit_summary_depth == 0) ? valobj->GetSummaryAsCString() : NULL;
Greg Clayton1d3afba2010-10-05 00:00:42 +00002790
Enrico Granata4becb372011-06-29 22:27:15 +00002791 // We must calculate this value in realtime because entry might alter this variable's value
2792 // (e.g. by saying ${var%fmt}) and render precached values useless
2793 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
2794 s.Printf(" %s", valobj->GetValueAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002795
Enrico Granata9dd75c82011-07-15 23:30:15 +00002796 if (sum_cstr)
Enrico Granata0a3958e2011-07-02 00:25:22 +00002797 {
2798 // for some reason, using %@ (ObjC description) in a summary string, makes
2799 // us believe we need to reset ourselves, thus invalidating the content of
2800 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty
2801 // let us recalculate it!
2802 if (sum_cstr[0] == '\0')
2803 s.Printf(" %s", valobj->GetSummaryAsCString());
2804 else
2805 s.Printf(" %s", sum_cstr);
2806 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002807
2808 if (use_objc)
2809 {
Jim Ingham6035b672011-03-31 00:19:25 +00002810 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002811 if (object_desc)
2812 s.Printf(" %s\n", object_desc);
2813 else
Sean Callanan672ad942010-10-23 00:18:49 +00002814 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002815 return;
Enrico Granata0a3958e2011-07-02 00:25:22 +00002816 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002817 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002818
2819 if (curr_depth < max_depth)
2820 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002821 // We will show children for all concrete types. We won't show
2822 // pointer contents unless a pointer depth has been specified.
2823 // We won't reference contents unless the reference is the
2824 // root object (depth of zero).
2825 bool print_children = true;
2826
2827 // Use a new temporary pointer depth in case we override the
2828 // current pointer depth below...
2829 uint32_t curr_ptr_depth = ptr_depth;
2830
2831 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
2832 if (is_ptr || is_ref)
2833 {
2834 // We have a pointer or reference whose value is an address.
2835 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00002836 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00002837 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
2838 print_children = false;
2839
2840 else if (is_ref && curr_depth == 0)
2841 {
2842 // If this is the root object (depth is zero) that we are showing
2843 // and it is a reference, and no pointer depth has been supplied
2844 // print out what it references. Don't do this at deeper depths
2845 // otherwise we can end up with infinite recursion...
2846 curr_ptr_depth = 1;
2847 }
2848
2849 if (curr_ptr_depth == 0)
2850 print_children = false;
2851 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002852
Enrico Granata0a3958e2011-07-02 00:25:22 +00002853 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00002854 {
Enrico Granatad55546b2011-07-22 00:16:08 +00002855 ValueObjectSP synth_vobj = valobj->GetSyntheticValue(use_synth ?
2856 lldb::eUseSyntheticFilter :
2857 lldb::eNoSyntheticFilter);
Enrico Granata22c55d12011-08-12 02:00:06 +00002858 uint32_t num_children = synth_vobj->GetNumChildren();
2859 bool print_dotdotdot = false;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002860 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002861 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002862 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002863 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002864 if (print_valobj)
2865 s.EOL();
2866 }
2867 else
2868 {
2869 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00002870 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002871 s.IndentMore();
2872 }
Enrico Granata22c55d12011-08-12 02:00:06 +00002873
2874 uint32_t max_num_children = valobj->GetUpdatePoint().GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
2875
2876 if (num_children > max_num_children && !ignore_cap)
2877 {
2878 num_children = max_num_children;
2879 print_dotdotdot = true;
2880 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002881
2882 for (uint32_t idx=0; idx<num_children; ++idx)
2883 {
Enrico Granatad55546b2011-07-22 00:16:08 +00002884 ValueObjectSP child_sp(synth_vobj->GetChildAtIndex(idx, true));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002885 if (child_sp.get())
2886 {
2887 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002888 child_sp.get(),
2889 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00002890 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002891 curr_depth + 1,
2892 max_depth,
2893 show_types,
2894 show_location,
2895 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00002896 use_dynamic,
Enrico Granatad55546b2011-07-22 00:16:08 +00002897 use_synth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002898 true,
Enrico Granata0c5ef692011-07-16 01:22:04 +00002899 flat_output,
Enrico Granata22c55d12011-08-12 02:00:06 +00002900 omit_summary_depth > 1 ? omit_summary_depth - 1 : 0,
2901 ignore_cap);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002902 }
2903 }
2904
2905 if (!flat_output)
2906 {
Enrico Granata22c55d12011-08-12 02:00:06 +00002907 if (print_dotdotdot)
Enrico Granata61a80ba2011-08-12 16:42:31 +00002908 {
2909 valobj->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
Enrico Granata22c55d12011-08-12 02:00:06 +00002910 s.Indent("...\n");
Enrico Granata61a80ba2011-08-12 16:42:31 +00002911 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002912 s.IndentLess();
2913 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002914 }
2915 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002916 else if (has_children)
2917 {
2918 // Aggregate, no children...
2919 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00002920 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002921 }
2922 else
2923 {
2924 if (print_valobj)
2925 s.EOL();
2926 }
2927
Greg Clayton1d3afba2010-10-05 00:00:42 +00002928 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002929 else
2930 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00002931 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002932 }
2933 }
2934 else
2935 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002936 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002937 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002938 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002939 }
2940 }
2941 }
2942 }
2943}
2944
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002945
2946ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00002947ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002948{
2949 ValueObjectSP valobj_sp;
2950
Enrico Granatac3e320a2011-08-02 17:27:39 +00002951 if (UpdateValueIfNeeded(false) && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002952 {
Jim Ingham6035b672011-03-31 00:19:25 +00002953 ExecutionContextScope *exe_scope = GetExecutionContextScope();
2954 if (exe_scope)
2955 {
2956 ExecutionContext exe_ctx;
2957 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002958
Jim Ingham6035b672011-03-31 00:19:25 +00002959 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002960
Jim Ingham6035b672011-03-31 00:19:25 +00002961 DataExtractor data;
2962 data.SetByteOrder (m_data.GetByteOrder());
2963 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002964
Greg Clayton644247c2011-07-07 01:59:51 +00002965 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002966
Jim Ingham58b59f92011-04-22 23:53:53 +00002967 valobj_sp = ValueObjectConstResult::Create (exe_scope,
2968 ast,
2969 GetClangType(),
2970 name,
2971 data);
Jim Ingham6035b672011-03-31 00:19:25 +00002972 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002973 }
Jim Ingham6035b672011-03-31 00:19:25 +00002974
2975 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002976 {
Jim Ingham58b59f92011-04-22 23:53:53 +00002977 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002978 }
2979 return valobj_sp;
2980}
2981
2982lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00002983ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002984{
Jim Ingham58b59f92011-04-22 23:53:53 +00002985 if (m_deref_valobj)
2986 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00002987
Greg Clayton54979cd2010-12-15 05:08:08 +00002988 const bool is_pointer_type = IsPointerType();
2989 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002990 {
2991 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +00002992 bool ignore_array_bounds = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002993
2994 std::string child_name_str;
2995 uint32_t child_byte_size = 0;
2996 int32_t child_byte_offset = 0;
2997 uint32_t child_bitfield_bit_size = 0;
2998 uint32_t child_bitfield_bit_offset = 0;
2999 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00003000 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003001 const bool transparent_pointers = false;
3002 clang::ASTContext *clang_ast = GetClangAST();
3003 clang_type_t clang_type = GetClangType();
3004 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00003005
3006 ExecutionContext exe_ctx;
3007 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
3008
3009 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
3010 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003011 GetName().GetCString(),
3012 clang_type,
3013 0,
3014 transparent_pointers,
3015 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003016 ignore_array_bounds,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003017 child_name_str,
3018 child_byte_size,
3019 child_byte_offset,
3020 child_bitfield_bit_size,
3021 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003022 child_is_base_class,
3023 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00003024 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003025 {
3026 ConstString child_name;
3027 if (!child_name_str.empty())
3028 child_name.SetCString (child_name_str.c_str());
3029
Jim Ingham58b59f92011-04-22 23:53:53 +00003030 m_deref_valobj = new ValueObjectChild (*this,
3031 clang_ast,
3032 child_clang_type,
3033 child_name,
3034 child_byte_size,
3035 child_byte_offset,
3036 child_bitfield_bit_size,
3037 child_bitfield_bit_offset,
3038 child_is_base_class,
3039 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003040 }
3041 }
Greg Clayton54979cd2010-12-15 05:08:08 +00003042
Jim Ingham58b59f92011-04-22 23:53:53 +00003043 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00003044 {
3045 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00003046 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00003047 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003048 else
3049 {
Greg Clayton54979cd2010-12-15 05:08:08 +00003050 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003051 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00003052
3053 if (is_pointer_type)
3054 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
3055 else
3056 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00003057 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003058 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003059}
3060
Jim Ingham78a685a2011-04-16 00:01:13 +00003061lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00003062ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003063{
Jim Ingham78a685a2011-04-16 00:01:13 +00003064 if (m_addr_of_valobj_sp)
3065 return m_addr_of_valobj_sp;
3066
Greg Claytone0d378b2011-03-24 21:19:54 +00003067 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003068 const bool scalar_is_load_address = false;
3069 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00003070 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003071 if (addr != LLDB_INVALID_ADDRESS)
3072 {
3073 switch (address_type)
3074 {
Greg Clayton54979cd2010-12-15 05:08:08 +00003075 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003076 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00003077 {
3078 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003079 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00003080 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
3081 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003082 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00003083
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003084 case eAddressTypeFile:
3085 case eAddressTypeLoad:
3086 case eAddressTypeHost:
3087 {
3088 clang::ASTContext *ast = GetClangAST();
3089 clang_type_t clang_type = GetClangType();
3090 if (ast && clang_type)
3091 {
3092 std::string name (1, '&');
3093 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00003094 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
3095 ast,
3096 ClangASTContext::CreatePointerType (ast, clang_type),
3097 ConstString (name.c_str()),
3098 addr,
3099 eAddressTypeInvalid,
3100 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003101 }
3102 }
3103 break;
3104 }
3105 }
Jim Ingham78a685a2011-04-16 00:01:13 +00003106 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003107}
3108
Greg Claytonb2dcc362011-05-05 23:32:56 +00003109
3110lldb::ValueObjectSP
3111ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
3112{
3113 lldb::ValueObjectSP valobj_sp;
3114 AddressType address_type;
3115 const bool scalar_is_load_address = true;
3116 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
3117
3118 if (ptr_value != LLDB_INVALID_ADDRESS)
3119 {
3120 Address ptr_addr (NULL, ptr_value);
3121
3122 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
3123 name,
3124 ptr_addr,
3125 clang_ast_type);
3126 }
3127 return valobj_sp;
3128}
3129
3130lldb::ValueObjectSP
3131ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
3132{
3133 lldb::ValueObjectSP valobj_sp;
3134 AddressType address_type;
3135 const bool scalar_is_load_address = true;
3136 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
3137
3138 if (ptr_value != LLDB_INVALID_ADDRESS)
3139 {
3140 Address ptr_addr (NULL, ptr_value);
3141
3142 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
3143 name,
3144 ptr_addr,
3145 type_sp);
3146 }
3147 return valobj_sp;
3148}
3149
Jim Ingham6035b672011-03-31 00:19:25 +00003150ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00003151 m_thread_id (LLDB_INVALID_UID),
Jim Ingham4b536182011-08-09 02:12:22 +00003152 m_mod_id ()
Jim Ingham6035b672011-03-31 00:19:25 +00003153{
3154}
3155
3156ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00003157 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00003158 m_first_update (true),
Jim Ingham89b61092011-07-06 17:42:14 +00003159 m_thread_id (LLDB_INVALID_THREAD_ID),
Jim Ingham4b536182011-08-09 02:12:22 +00003160 m_mod_id ()
Stephen Wilson71c21d12011-04-11 19:41:40 +00003161
Jim Ingham6035b672011-03-31 00:19:25 +00003162{
3163 ExecutionContext exe_ctx;
3164 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
3165 // and if so we want to cache that not the original.
3166 if (exe_scope)
3167 exe_scope->CalculateExecutionContext(exe_ctx);
3168 if (exe_ctx.target != NULL)
3169 {
3170 m_target_sp = exe_ctx.target->GetSP();
3171
3172 if (exe_ctx.process == NULL)
3173 m_process_sp = exe_ctx.target->GetProcessSP();
3174 else
3175 m_process_sp = exe_ctx.process->GetSP();
3176
3177 if (m_process_sp != NULL)
3178 {
Jim Ingham4b536182011-08-09 02:12:22 +00003179 m_mod_id = m_process_sp->GetModID();
3180
Jim Ingham6035b672011-03-31 00:19:25 +00003181 Thread *thread = NULL;
3182
3183 if (exe_ctx.thread == NULL)
3184 {
3185 if (use_selected)
3186 {
3187 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
3188 if (thread)
3189 computed_exe_scope = thread;
3190 }
3191 }
3192 else
3193 thread = exe_ctx.thread;
3194
3195 if (thread != NULL)
3196 {
3197 m_thread_id = thread->GetIndexID();
3198 if (exe_ctx.frame == NULL)
3199 {
3200 if (use_selected)
3201 {
3202 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
3203 if (frame)
3204 {
3205 m_stack_id = frame->GetStackID();
3206 computed_exe_scope = frame;
3207 }
3208 }
3209 }
3210 else
3211 m_stack_id = exe_ctx.frame->GetStackID();
3212 }
3213 }
3214 }
3215 m_exe_scope = computed_exe_scope;
3216}
3217
3218ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
3219 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00003220 m_needs_update(true),
3221 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00003222 m_target_sp (rhs.m_target_sp),
3223 m_process_sp (rhs.m_process_sp),
3224 m_thread_id (rhs.m_thread_id),
3225 m_stack_id (rhs.m_stack_id),
Jim Ingham4b536182011-08-09 02:12:22 +00003226 m_mod_id ()
Jim Ingham6035b672011-03-31 00:19:25 +00003227{
3228}
3229
3230ValueObject::EvaluationPoint::~EvaluationPoint ()
3231{
3232}
3233
3234ExecutionContextScope *
3235ValueObject::EvaluationPoint::GetExecutionContextScope ()
3236{
3237 // We have to update before giving out the scope, or we could be handing out stale pointers.
3238 SyncWithProcessState();
3239
3240 return m_exe_scope;
3241}
3242
3243// This function checks the EvaluationPoint against the current process state. If the current
3244// state matches the evaluation point, or the evaluation point is already invalid, then we return
3245// false, meaning "no change". If the current state is different, we update our state, and return
3246// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
3247// future calls to NeedsUpdate will return true.
3248
3249bool
3250ValueObject::EvaluationPoint::SyncWithProcessState()
3251{
Jim Ingham6035b672011-03-31 00:19:25 +00003252 // If we don't have a process nothing can change.
3253 if (!m_process_sp)
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003254 {
3255 m_exe_scope = m_target_sp.get();
Jim Ingham6035b672011-03-31 00:19:25 +00003256 return false;
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003257 }
Jim Ingham6035b672011-03-31 00:19:25 +00003258
3259 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham4b536182011-08-09 02:12:22 +00003260 ProcessModID current_mod_id = m_process_sp->GetModID();
3261
Jim Ingham78a685a2011-04-16 00:01:13 +00003262 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
3263 // In either case, we aren't going to be able to sync with the process state.
Jim Ingham4b536182011-08-09 02:12:22 +00003264 if (current_mod_id.GetStopID() == 0)
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003265 {
3266 m_exe_scope = m_target_sp.get();
Jim Ingham78a685a2011-04-16 00:01:13 +00003267 return false;
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003268 }
Jim Ingham78a685a2011-04-16 00:01:13 +00003269
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003270 if (m_mod_id.IsValid())
3271 {
3272 if (m_mod_id == current_mod_id)
3273 {
3274 // Everything is already up to date in this object, no need do
3275 // update the execution context scope.
3276 return false;
3277 }
3278 m_mod_id = current_mod_id;
3279 m_needs_update = true;
3280 }
Jim Ingham6035b672011-03-31 00:19:25 +00003281 m_exe_scope = m_process_sp.get();
3282
3283 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
3284 // doesn't, mark ourselves as invalid.
3285
3286 if (m_thread_id != LLDB_INVALID_THREAD_ID)
3287 {
3288 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
3289 if (our_thread == NULL)
Greg Clayton262f80d2011-07-06 16:49:27 +00003290 {
Jim Ingham89b61092011-07-06 17:42:14 +00003291 SetInvalid();
Greg Clayton262f80d2011-07-06 16:49:27 +00003292 }
Jim Ingham6035b672011-03-31 00:19:25 +00003293 else
3294 {
3295 m_exe_scope = our_thread;
3296
3297 if (m_stack_id.IsValid())
3298 {
3299 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
3300 if (our_frame == NULL)
3301 SetInvalid();
3302 else
3303 m_exe_scope = our_frame;
3304 }
3305 }
3306 }
3307 return true;
3308}
3309
Jim Ingham61be0902011-05-02 18:13:59 +00003310void
3311ValueObject::EvaluationPoint::SetUpdated ()
3312{
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003313 // this will update the execution context scope and the m_mod_id
3314 SyncWithProcessState();
Jim Ingham61be0902011-05-02 18:13:59 +00003315 m_first_update = false;
3316 m_needs_update = false;
Jim Ingham61be0902011-05-02 18:13:59 +00003317}
3318
3319
Jim Ingham6035b672011-03-31 00:19:25 +00003320bool
3321ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
3322{
3323 if (!IsValid())
3324 return false;
3325
3326 bool needs_update = false;
3327 m_exe_scope = NULL;
3328
3329 // The target has to be non-null, and the
3330 Target *target = exe_scope->CalculateTarget();
3331 if (target != NULL)
3332 {
3333 Target *old_target = m_target_sp.get();
3334 assert (target == old_target);
3335 Process *process = exe_scope->CalculateProcess();
3336 if (process != NULL)
3337 {
3338 // FOR NOW - assume you can't update variable objects across process boundaries.
3339 Process *old_process = m_process_sp.get();
3340 assert (process == old_process);
Jim Ingham4b536182011-08-09 02:12:22 +00003341 ProcessModID current_mod_id = process->GetModID();
3342 if (m_mod_id != current_mod_id)
Jim Ingham6035b672011-03-31 00:19:25 +00003343 {
3344 needs_update = true;
Jim Ingham4b536182011-08-09 02:12:22 +00003345 m_mod_id = current_mod_id;
Jim Ingham6035b672011-03-31 00:19:25 +00003346 }
3347 // See if we're switching the thread or stack context. If no thread is given, this is
3348 // being evaluated in a global context.
3349 Thread *thread = exe_scope->CalculateThread();
3350 if (thread != NULL)
3351 {
3352 lldb::user_id_t new_thread_index = thread->GetIndexID();
3353 if (new_thread_index != m_thread_id)
3354 {
3355 needs_update = true;
3356 m_thread_id = new_thread_index;
3357 m_stack_id.Clear();
3358 }
3359
3360 StackFrame *new_frame = exe_scope->CalculateStackFrame();
3361 if (new_frame != NULL)
3362 {
3363 if (new_frame->GetStackID() != m_stack_id)
3364 {
3365 needs_update = true;
3366 m_stack_id = new_frame->GetStackID();
3367 }
3368 }
3369 else
3370 {
3371 m_stack_id.Clear();
3372 needs_update = true;
3373 }
3374 }
3375 else
3376 {
3377 // If this had been given a thread, and now there is none, we should update.
3378 // Otherwise we don't have to do anything.
3379 if (m_thread_id != LLDB_INVALID_UID)
3380 {
3381 m_thread_id = LLDB_INVALID_UID;
3382 m_stack_id.Clear();
3383 needs_update = true;
3384 }
3385 }
3386 }
3387 else
3388 {
3389 // If there is no process, then we don't need to update anything.
3390 // But if we're switching from having a process to not, we should try to update.
3391 if (m_process_sp.get() != NULL)
3392 {
3393 needs_update = true;
3394 m_process_sp.reset();
3395 m_thread_id = LLDB_INVALID_UID;
3396 m_stack_id.Clear();
3397 }
3398 }
3399 }
3400 else
3401 {
3402 // If there's no target, nothing can change so we don't need to update anything.
3403 // But if we're switching from having a target to not, we should try to update.
3404 if (m_target_sp.get() != NULL)
3405 {
3406 needs_update = true;
3407 m_target_sp.reset();
3408 m_process_sp.reset();
3409 m_thread_id = LLDB_INVALID_UID;
3410 m_stack_id.Clear();
3411 }
3412 }
3413 if (!m_needs_update)
3414 m_needs_update = needs_update;
3415
3416 return needs_update;
3417}
Enrico Granataf2bbf712011-07-15 02:26:42 +00003418
3419void
3420ValueObject::ClearUserVisibleData()
3421{
3422 m_location_str.clear();
3423 m_value_str.clear();
3424 m_summary_str.clear();
3425 m_object_desc_str.clear();
Johnny Chen44805302011-07-19 19:48:13 +00003426}