blob: 46feb995573e062d473567246a0ada9b0f77bcbb [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
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255DataExtractor &
256ValueObject::GetDataExtractor ()
257{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000258 UpdateValueIfNeeded(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259 return m_data;
260}
261
262const Error &
Greg Clayton262f80d2011-07-06 16:49:27 +0000263ValueObject::GetError()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000265 UpdateValueIfNeeded(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266 return m_error;
267}
268
269const ConstString &
270ValueObject::GetName() const
271{
272 return m_name;
273}
274
275const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000276ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000278 if (UpdateValueIfNeeded(false))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279 {
280 if (m_location_str.empty())
281 {
282 StreamString sstr;
283
284 switch (m_value.GetValueType())
285 {
286 default:
287 break;
288
289 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000290 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291 {
292 RegisterInfo *reg_info = m_value.GetRegisterInfo();
293 if (reg_info)
294 {
295 if (reg_info->name)
296 m_location_str = reg_info->name;
297 else if (reg_info->alt_name)
298 m_location_str = reg_info->alt_name;
299 break;
300 }
301 }
302 m_location_str = "scalar";
303 break;
304
305 case Value::eValueTypeLoadAddress:
306 case Value::eValueTypeFileAddress:
307 case Value::eValueTypeHostAddress:
308 {
309 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
310 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
311 m_location_str.swap(sstr.GetString());
312 }
313 break;
314 }
315 }
316 }
317 return m_location_str.c_str();
318}
319
320Value &
321ValueObject::GetValue()
322{
323 return m_value;
324}
325
326const Value &
327ValueObject::GetValue() const
328{
329 return m_value;
330}
331
332bool
Jim Ingham6035b672011-03-31 00:19:25 +0000333ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000334{
Enrico Granata6fd87d52011-08-04 01:41:02 +0000335 if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
336 {
337 ExecutionContext exe_ctx;
338 ExecutionContextScope *exe_scope = GetExecutionContextScope();
339 if (exe_scope)
340 exe_scope->CalculateExecutionContext(exe_ctx);
341 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
342 return scalar.IsValid();
343 }
344 else
345 return false;
Greg Clayton8f343b02010-11-04 01:54:29 +0000346}
347
348bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000349ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350{
Greg Clayton288bdf92010-09-02 02:59:18 +0000351 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352}
353
354
355void
356ValueObject::SetValueIsValid (bool b)
357{
Greg Clayton288bdf92010-09-02 02:59:18 +0000358 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359}
360
361bool
Jim Ingham6035b672011-03-31 00:19:25 +0000362ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363{
Jim Ingham6035b672011-03-31 00:19:25 +0000364 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000365 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366}
367
368void
369ValueObject::SetValueDidChange (bool value_changed)
370{
Greg Clayton288bdf92010-09-02 02:59:18 +0000371 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372}
373
374ValueObjectSP
375ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
376{
377 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000378 // We may need to update our value if we are dynamic
379 if (IsPossibleDynamicType ())
Enrico Granatac3e320a2011-08-02 17:27:39 +0000380 UpdateValueIfNeeded(false);
Greg Claytondea8cb42011-06-29 22:09:02 +0000381 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000383 // Check if we have already made the child value object?
384 if (can_create && m_children[idx] == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000386 // No we haven't created the child at this index, so lets have our
387 // subclass do it and cache the result for quick future access.
388 m_children[idx] = CreateChildAtIndex (idx, false, 0);
Jim Ingham78a685a2011-04-16 00:01:13 +0000389 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000390
391 if (m_children[idx] != NULL)
392 return m_children[idx]->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000393 }
394 return child_sp;
395}
396
397uint32_t
398ValueObject::GetIndexOfChildWithName (const ConstString &name)
399{
400 bool omit_empty_base_classes = true;
401 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000402 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000403 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404 omit_empty_base_classes);
405}
406
407ValueObjectSP
408ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
409{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000410 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411 // classes (which really aren't part of the expression path), so we
412 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000413 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000414
Greg Claytondea8cb42011-06-29 22:09:02 +0000415 // We may need to update our value if we are dynamic
416 if (IsPossibleDynamicType ())
Enrico Granatac3e320a2011-08-02 17:27:39 +0000417 UpdateValueIfNeeded(false);
Greg Claytondea8cb42011-06-29 22:09:02 +0000418
419 std::vector<uint32_t> child_indexes;
420 clang::ASTContext *clang_ast = GetClangAST();
421 void *clang_type = GetClangType();
422 bool omit_empty_base_classes = true;
423 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
424 clang_type,
425 name.GetCString(),
426 omit_empty_base_classes,
427 child_indexes);
428 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000430 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
431 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
432
433 child_sp = GetChildAtIndex(*pos, can_create);
434 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000436 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000437 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000438 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
439 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000440 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000441 else
442 {
443 child_sp.reset();
444 }
445
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446 }
447 }
448 return child_sp;
449}
450
451
452uint32_t
453ValueObject::GetNumChildren ()
454{
Greg Clayton288bdf92010-09-02 02:59:18 +0000455 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456 {
457 SetNumChildren (CalculateNumChildren());
458 }
459 return m_children.size();
460}
461void
462ValueObject::SetNumChildren (uint32_t num_children)
463{
Greg Clayton288bdf92010-09-02 02:59:18 +0000464 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465 m_children.resize(num_children);
466}
467
468void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469ValueObject::SetName (const ConstString &name)
470{
471 m_name = name;
472}
473
Jim Ingham58b59f92011-04-22 23:53:53 +0000474ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
476{
Jim Ingham2eec4872011-05-07 00:10:58 +0000477 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000478
Greg Claytondea8cb42011-06-29 22:09:02 +0000479 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +0000480 bool ignore_array_bounds = synthetic_array_member;
Greg Claytondea8cb42011-06-29 22:09:02 +0000481 std::string child_name_str;
482 uint32_t child_byte_size = 0;
483 int32_t child_byte_offset = 0;
484 uint32_t child_bitfield_bit_size = 0;
485 uint32_t child_bitfield_bit_offset = 0;
486 bool child_is_base_class = false;
487 bool child_is_deref_of_parent = false;
488
489 const bool transparent_pointers = synthetic_array_member == false;
490 clang::ASTContext *clang_ast = GetClangAST();
491 clang_type_t clang_type = GetClangType();
492 clang_type_t child_clang_type;
493
494 ExecutionContext exe_ctx;
495 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
496
497 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
498 clang_ast,
499 GetName().GetCString(),
500 clang_type,
501 idx,
502 transparent_pointers,
503 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +0000504 ignore_array_bounds,
Greg Claytondea8cb42011-06-29 22:09:02 +0000505 child_name_str,
506 child_byte_size,
507 child_byte_offset,
508 child_bitfield_bit_size,
509 child_bitfield_bit_offset,
510 child_is_base_class,
511 child_is_deref_of_parent);
512 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000513 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000514 if (synthetic_index)
515 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000516
Greg Claytondea8cb42011-06-29 22:09:02 +0000517 ConstString child_name;
518 if (!child_name_str.empty())
519 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520
Greg Claytondea8cb42011-06-29 22:09:02 +0000521 valobj = new ValueObjectChild (*this,
522 clang_ast,
523 child_clang_type,
524 child_name,
525 child_byte_size,
526 child_byte_offset,
527 child_bitfield_bit_size,
528 child_bitfield_bit_offset,
529 child_is_base_class,
530 child_is_deref_of_parent);
531 if (m_pointers_point_to_load_addrs)
532 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000534
Jim Ingham58b59f92011-04-22 23:53:53 +0000535 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536}
537
538const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000539ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540{
Enrico Granatad8b5fce2011-08-02 23:12:24 +0000541 if (UpdateValueIfNeeded (true))
Enrico Granata4becb372011-06-29 22:27:15 +0000542 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000543 if (m_summary_str.empty())
544 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000545 SummaryFormat *summary_format = GetSummaryFormat().get();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000546
547 if (summary_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000548 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000549 m_summary_str = summary_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000550 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000551 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000552 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000553 clang_type_t clang_type = GetClangType();
Greg Clayton737b9322010-09-13 03:32:57 +0000554
Enrico Granata9dd75c82011-07-15 23:30:15 +0000555 // Do some default printout for function pointers
Enrico Granataf2bbf712011-07-15 02:26:42 +0000556 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000558 StreamString sstr;
559 clang_type_t elem_or_pointee_clang_type;
560 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
561 GetClangAST(),
562 &elem_or_pointee_clang_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000563
Enrico Granataf2bbf712011-07-15 02:26:42 +0000564 ExecutionContextScope *exe_scope = GetExecutionContextScope();
565 if (exe_scope)
566 {
Enrico Granata9dd75c82011-07-15 23:30:15 +0000567 if (ClangASTContext::IsFunctionPointerType (clang_type))
Jim Ingham6035b672011-03-31 00:19:25 +0000568 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000569 AddressType func_ptr_address_type = eAddressTypeInvalid;
570 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
571
572 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
573 {
574 switch (func_ptr_address_type)
575 {
576 case eAddressTypeInvalid:
577 case eAddressTypeFile:
578 break;
579
580 case eAddressTypeLoad:
581 {
582 Address so_addr;
583 Target *target = exe_scope->CalculateTarget();
584 if (target && target->GetSectionLoadList().IsEmpty() == false)
585 {
586 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
587 {
588 so_addr.Dump (&sstr,
589 exe_scope,
590 Address::DumpStyleResolvedDescription,
591 Address::DumpStyleSectionNameOffset);
592 }
593 }
594 }
595 break;
596
597 case eAddressTypeHost:
598 break;
599 }
600 }
601 if (sstr.GetSize() > 0)
602 {
603 m_summary_str.assign (1, '(');
604 m_summary_str.append (sstr.GetData(), sstr.GetSize());
605 m_summary_str.append (1, ')');
606 }
Jim Ingham6035b672011-03-31 00:19:25 +0000607 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000608 }
609 }
610 }
611 }
612 }
613 if (m_summary_str.empty())
614 return NULL;
615 return m_summary_str.c_str();
616}
617
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000618bool
619ValueObject::IsCStringContainer(bool check_pointer)
620{
621 clang_type_t elem_or_pointee_clang_type;
622 const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(),
623 GetClangAST(),
624 &elem_or_pointee_clang_type));
625 bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
626 ClangASTContext::IsCharType (elem_or_pointee_clang_type));
627 if (!is_char_arr_ptr)
628 return false;
629 if (!check_pointer)
630 return true;
631 if (type_flags.Test(ClangASTContext::eTypeIsArray))
632 return true;
633 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
634 AddressType cstr_address_type = eAddressTypeInvalid;
635 cstr_address = GetAddressOf (cstr_address_type, true);
636 return (cstr_address != LLDB_INVALID_ADDRESS);
637}
638
639void
640ValueObject::ReadPointedString(Stream& s,
641 Error& error,
Enrico Granataf4efecd2011-07-12 22:56:10 +0000642 uint32_t max_length,
643 bool honor_array,
644 lldb::Format item_format)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000645{
646
647 if (max_length == 0)
Enrico Granataf4efecd2011-07-12 22:56:10 +0000648 max_length = 128; // FIXME this should be a setting, or a formatting parameter
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000649
650 clang_type_t clang_type = GetClangType();
651 clang_type_t elem_or_pointee_clang_type;
652 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
653 GetClangAST(),
654 &elem_or_pointee_clang_type));
655 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
656 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
657 {
658 ExecutionContextScope *exe_scope = GetExecutionContextScope();
659 if (exe_scope)
660 {
661 Target *target = exe_scope->CalculateTarget();
Enrico Granata6f3533f2011-07-29 19:53:35 +0000662 if (target == NULL)
663 {
664 s << "<no target to read from>";
665 }
666 else
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000667 {
668 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
669 AddressType cstr_address_type = eAddressTypeInvalid;
670
671 size_t cstr_len = 0;
672 bool capped_data = false;
673 if (type_flags.Test (ClangASTContext::eTypeIsArray))
674 {
675 // We have an array
676 cstr_len = ClangASTContext::GetArraySize (clang_type);
Enrico Granataf4efecd2011-07-12 22:56:10 +0000677 if (cstr_len > max_length)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000678 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000679 capped_data = true;
680 cstr_len = max_length;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000681 }
682 cstr_address = GetAddressOf (cstr_address_type, true);
683 }
684 else
685 {
686 // We have a pointer
687 cstr_address = GetPointerValue (cstr_address_type, true);
688 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000689 if (cstr_address == LLDB_INVALID_ADDRESS)
690 {
691 s << "<invalid address for data>";
692 }
693 else
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000694 {
695 Address cstr_so_addr (NULL, cstr_address);
696 DataExtractor data;
697 size_t bytes_read = 0;
698 std::vector<char> data_buffer;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000699 bool prefer_file_cache = false;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000700 if (cstr_len > 0 && honor_array)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000701 {
702 data_buffer.resize(cstr_len);
703 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
704 bytes_read = target->ReadMemory (cstr_so_addr,
705 prefer_file_cache,
706 &data_buffer.front(),
707 cstr_len,
708 error);
709 if (bytes_read > 0)
710 {
711 s << '"';
712 data.Dump (&s,
713 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000714 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000715 1, // Size of item (1 byte for a char!)
716 bytes_read, // How many bytes to print?
717 UINT32_MAX, // num per line
718 LLDB_INVALID_ADDRESS,// base address
719 0, // bitfield bit size
720 0); // bitfield bit offset
721 if (capped_data)
722 s << "...";
723 s << '"';
724 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000725 else
726 s << "\"<data not available>\"";
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000727 }
728 else
729 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000730 cstr_len = max_length;
731 const size_t k_max_buf_size = 64;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000732 data_buffer.resize (k_max_buf_size + 1);
733 // NULL terminate in case we don't get the entire C string
734 data_buffer.back() = '\0';
735
736 s << '"';
737
Enrico Granata6f3533f2011-07-29 19:53:35 +0000738 bool any_data = false;
739
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000740 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
741 while ((bytes_read = target->ReadMemory (cstr_so_addr,
742 prefer_file_cache,
743 &data_buffer.front(),
744 k_max_buf_size,
745 error)) > 0)
746 {
Enrico Granata6f3533f2011-07-29 19:53:35 +0000747 any_data = true;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000748 size_t len = strlen(&data_buffer.front());
749 if (len == 0)
750 break;
751 if (len > bytes_read)
752 len = bytes_read;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000753 if (len > cstr_len)
754 len = cstr_len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000755
756 data.Dump (&s,
757 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000758 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000759 1, // Size of item (1 byte for a char!)
760 len, // How many bytes to print?
761 UINT32_MAX, // num per line
762 LLDB_INVALID_ADDRESS,// base address
763 0, // bitfield bit size
764 0); // bitfield bit offset
765
766 if (len < k_max_buf_size)
767 break;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000768 if (len >= cstr_len)
769 {
770 s << "...";
771 break;
772 }
773 cstr_len -= len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000774 cstr_so_addr.Slide (k_max_buf_size);
775 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000776
777 if (any_data == false)
778 s << "<data not available>";
779
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000780 s << '"';
781 }
782 }
783 }
784 }
785 }
786 else
787 {
788 error.SetErrorString("impossible to read a string from this object");
Enrico Granata6f3533f2011-07-29 19:53:35 +0000789 s << "<not a string object>";
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000790 }
791}
792
Jim Ingham53c47f12010-09-10 23:12:17 +0000793const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000794ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000795{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000796
Enrico Granatad8b5fce2011-08-02 23:12:24 +0000797 if (!UpdateValueIfNeeded (true))
Jim Ingham53c47f12010-09-10 23:12:17 +0000798 return NULL;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000799
800 if (!m_object_desc_str.empty())
801 return m_object_desc_str.c_str();
802
Jim Ingham6035b672011-03-31 00:19:25 +0000803 ExecutionContextScope *exe_scope = GetExecutionContextScope();
804 if (exe_scope == NULL)
805 return NULL;
806
Jim Ingham53c47f12010-09-10 23:12:17 +0000807 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000808 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000809 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000810
Jim Ingham53c47f12010-09-10 23:12:17 +0000811 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000812
813 lldb::LanguageType language = GetObjectRuntimeLanguage();
814 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
815
Jim Inghama2cf2632010-12-23 02:29:54 +0000816 if (runtime == NULL)
817 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000818 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000819 clang_type_t opaque_qual_type = GetClangType();
820 if (opaque_qual_type != NULL)
821 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000822 bool is_signed;
823 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
824 || ClangASTContext::IsPointerType (opaque_qual_type))
825 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000826 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000827 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000828 }
829 }
830
Jim Ingham8d543de2011-03-31 23:01:21 +0000831 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000832 {
833 m_object_desc_str.append (s.GetData());
834 }
Sean Callanan672ad942010-10-23 00:18:49 +0000835
836 if (m_object_desc_str.empty())
837 return NULL;
838 else
839 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000840}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000841
842const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000843ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000844{
845 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000846 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000847 {
Enrico Granatac3e320a2011-08-02 17:27:39 +0000848 if (UpdateValueIfNeeded(true))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000849 {
850 if (m_value_str.empty())
851 {
852 const Value::ContextType context_type = m_value.GetContextType();
853
854 switch (context_type)
855 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000856 case Value::eContextTypeClangType:
857 case Value::eContextTypeLLDBType:
858 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000859 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000860 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000861 if (clang_type)
862 {
Enrico Granatac3e320a2011-08-02 17:27:39 +0000863 if (m_format == lldb::eFormatDefault && m_last_value_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000864 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000865 m_value_str = m_last_value_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000866 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000867 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000868 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000869 StreamString sstr;
870 Format format = GetFormat();
871 if (format == eFormatDefault)
872 format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
873 ClangASTType::GetFormat(clang_type));
874
875 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
876 clang_type, // The clang type to display
877 &sstr,
878 format, // Format to display this type with
879 m_data, // Data to extract from
880 0, // Byte offset into "m_data"
881 GetByteSize(), // Byte size of item in "m_data"
882 GetBitfieldBitSize(), // Bitfield bit size
883 GetBitfieldBitOffset())) // Bitfield bit offset
884 m_value_str.swap(sstr.GetString());
885 else
886 {
887 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
888 m_data.GetByteSize(),
889 GetByteSize());
890 m_value_str.clear();
891 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000892 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000893 }
894 }
895 break;
896
Greg Clayton526e5af2010-11-13 03:52:47 +0000897 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000898 {
899 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
900 if (reg_info)
901 {
902 StreamString reg_sstr;
903 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
904 m_value_str.swap(reg_sstr.GetString());
905 }
906 }
907 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000908
909 default:
910 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911 }
912 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000913
914 if (!m_value_did_change && m_old_value_valid)
915 {
916 // The value was gotten successfully, so we consider the
917 // value as changed if the value string differs
918 SetValueDidChange (m_old_value_str != m_value_str);
919 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000920 }
921 }
922 if (m_value_str.empty())
923 return NULL;
924 return m_value_str.c_str();
925}
926
Enrico Granatac3e320a2011-08-02 17:27:39 +0000927// if > 8bytes, 0 is returned. this method should mostly be used
928// to read address values out of pointers
929unsigned long long
930ValueObject::GetValueAsUnsigned()
931{
932 // If our byte size is zero this is an aggregate type that has children
933 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
934 {
935 if (UpdateValueIfNeeded(true))
936 {
937 uint32_t offset = 0;
938 return m_data.GetMaxU64(&offset,
939 m_data.GetByteSize());
940 }
941 }
942 return 0;
943}
944
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000945bool
946ValueObject::GetPrintableRepresentation(Stream& s,
947 ValueObjectRepresentationStyle val_obj_display,
Enrico Granata0a3958e2011-07-02 00:25:22 +0000948 lldb::Format custom_format)
949{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000950
951 RefCounter ref(&m_dump_printable_counter);
952
Enrico Granata9dd75c82011-07-15 23:30:15 +0000953 if (custom_format != lldb::eFormatInvalid)
Enrico Granata0a3958e2011-07-02 00:25:22 +0000954 SetFormat(custom_format);
955
956 const char * return_value;
Enrico Granatacd1c0232011-08-04 23:37:18 +0000957 std::string alloc_mem;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000958
959 switch(val_obj_display)
960 {
961 case eDisplayValue:
962 return_value = GetValueAsCString();
963 break;
964 case eDisplaySummary:
965 return_value = GetSummaryAsCString();
966 break;
967 case eDisplayLanguageSpecific:
968 return_value = GetObjectDescription();
969 break;
Enrico Granataf2bbf712011-07-15 02:26:42 +0000970 case eDisplayLocation:
971 return_value = GetLocationAsCString();
972 break;
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000973 case eDisplayChildrenCount:
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000974 {
Enrico Granatacd1c0232011-08-04 23:37:18 +0000975 alloc_mem.resize(512);
976 return_value = &alloc_mem[0];
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000977 int count = GetNumChildren();
Enrico Granatacd1c0232011-08-04 23:37:18 +0000978 snprintf((char*)return_value, 512, "%d", count);
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000979 break;
980 }
981 default:
982 break;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000983 }
984
Enrico Granataf4efecd2011-07-12 22:56:10 +0000985 // this code snippet might lead to endless recursion, thus we use a RefCounter here to
986 // check that we are not looping endlessly
987 if (!return_value && (m_dump_printable_counter < 3))
Enrico Granata9fc19442011-07-06 02:13:41 +0000988 {
989 // try to pick the other choice
990 if (val_obj_display == eDisplayValue)
991 return_value = GetSummaryAsCString();
992 else if (val_obj_display == eDisplaySummary)
Enrico Granatae992a082011-07-22 17:03:19 +0000993 {
994 if (ClangASTContext::IsAggregateType (GetClangType()) == true)
995 {
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000996 // this thing has no value, and it seems to have no summary
997 // some combination of unitialized data and other factors can also
998 // raise this condition, so let's print a nice generic error message
999 return_value = "<no available summary>";
Enrico Granatae992a082011-07-22 17:03:19 +00001000 }
1001 else
1002 return_value = GetValueAsCString();
1003 }
Enrico Granata9fc19442011-07-06 02:13:41 +00001004 }
Enrico Granata0a3958e2011-07-02 00:25:22 +00001005
Enrico Granata5dfd49c2011-08-04 02:34:29 +00001006 if (return_value)
1007 s.PutCString(return_value);
1008 else
1009 s.PutCString("<no printable representation>");
1010
1011 // we should only return false here if we could not do *anything*
1012 // even if we have an error message as output, that's a success
1013 // from our callers' perspective, so return true
1014 return true;
1015
Enrico Granata0a3958e2011-07-02 00:25:22 +00001016}
1017
Enrico Granata9fc19442011-07-06 02:13:41 +00001018bool
1019ValueObject::DumpPrintableRepresentation(Stream& s,
1020 ValueObjectRepresentationStyle val_obj_display,
1021 lldb::Format custom_format)
1022{
Enrico Granataf4efecd2011-07-12 22:56:10 +00001023
1024 clang_type_t elem_or_pointee_type;
1025 Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001026
Enrico Granataf4efecd2011-07-12 22:56:10 +00001027 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
1028 && val_obj_display == ValueObject::eDisplayValue)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001029 {
Enrico Granataf4efecd2011-07-12 22:56:10 +00001030 // when being asked to get a printable display an array or pointer type directly,
1031 // try to "do the right thing"
1032
1033 if (IsCStringContainer(true) &&
1034 (custom_format == lldb::eFormatCString ||
1035 custom_format == lldb::eFormatCharArray ||
1036 custom_format == lldb::eFormatChar ||
1037 custom_format == lldb::eFormatVectorOfChar)) // print char[] & char* directly
1038 {
1039 Error error;
1040 ReadPointedString(s,
1041 error,
1042 0,
1043 (custom_format == lldb::eFormatVectorOfChar) ||
1044 (custom_format == lldb::eFormatCharArray));
1045 return !error.Fail();
1046 }
1047
1048 if (custom_format == lldb::eFormatEnum)
1049 return false;
1050
1051 // this only works for arrays, because I have no way to know when
1052 // the pointed memory ends, and no special \0 end of data marker
1053 if (flags.Test(ClangASTContext::eTypeIsArray))
1054 {
1055 if ((custom_format == lldb::eFormatBytes) ||
1056 (custom_format == lldb::eFormatBytesWithASCII))
1057 {
1058 uint32_t count = GetNumChildren();
1059
1060 s << '[';
1061 for (uint32_t low = 0; low < count; low++)
1062 {
1063
1064 if (low)
1065 s << ',';
1066
1067 ValueObjectSP child = GetChildAtIndex(low,true);
1068 if (!child.get())
1069 {
Enrico Granatae992a082011-07-22 17:03:19 +00001070 s << "<invalid child>";
Enrico Granataf4efecd2011-07-12 22:56:10 +00001071 continue;
1072 }
1073 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format);
1074 }
1075
1076 s << ']';
1077
1078 return true;
1079 }
1080
1081 if ((custom_format == lldb::eFormatVectorOfChar) ||
1082 (custom_format == lldb::eFormatVectorOfFloat32) ||
1083 (custom_format == lldb::eFormatVectorOfFloat64) ||
1084 (custom_format == lldb::eFormatVectorOfSInt16) ||
1085 (custom_format == lldb::eFormatVectorOfSInt32) ||
1086 (custom_format == lldb::eFormatVectorOfSInt64) ||
1087 (custom_format == lldb::eFormatVectorOfSInt8) ||
1088 (custom_format == lldb::eFormatVectorOfUInt128) ||
1089 (custom_format == lldb::eFormatVectorOfUInt16) ||
1090 (custom_format == lldb::eFormatVectorOfUInt32) ||
1091 (custom_format == lldb::eFormatVectorOfUInt64) ||
1092 (custom_format == lldb::eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
1093 {
1094 uint32_t count = GetNumChildren();
1095
1096 lldb::Format format = FormatManager::GetSingleItemFormat(custom_format);
1097
1098 s << '[';
1099 for (uint32_t low = 0; low < count; low++)
1100 {
1101
1102 if (low)
1103 s << ',';
1104
1105 ValueObjectSP child = GetChildAtIndex(low,true);
1106 if (!child.get())
1107 {
Enrico Granatae992a082011-07-22 17:03:19 +00001108 s << "<invalid child>";
Enrico Granataf4efecd2011-07-12 22:56:10 +00001109 continue;
1110 }
1111 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format);
1112 }
1113
1114 s << ']';
1115
1116 return true;
1117 }
1118 }
1119
1120 if ((custom_format == lldb::eFormatBoolean) ||
1121 (custom_format == lldb::eFormatBinary) ||
1122 (custom_format == lldb::eFormatChar) ||
1123 (custom_format == lldb::eFormatCharPrintable) ||
1124 (custom_format == lldb::eFormatComplexFloat) ||
1125 (custom_format == lldb::eFormatDecimal) ||
1126 (custom_format == lldb::eFormatHex) ||
1127 (custom_format == lldb::eFormatFloat) ||
1128 (custom_format == lldb::eFormatOctal) ||
1129 (custom_format == lldb::eFormatOSType) ||
1130 (custom_format == lldb::eFormatUnicode16) ||
1131 (custom_format == lldb::eFormatUnicode32) ||
1132 (custom_format == lldb::eFormatUnsigned) ||
1133 (custom_format == lldb::eFormatPointer) ||
1134 (custom_format == lldb::eFormatComplexInteger) ||
1135 (custom_format == lldb::eFormatComplex) ||
1136 (custom_format == lldb::eFormatDefault)) // use the [] operator
1137 return false;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001138 }
Enrico Granata5dfd49c2011-08-04 02:34:29 +00001139 bool var_success = GetPrintableRepresentation(s, val_obj_display, custom_format);
Enrico Granata9dd75c82011-07-15 23:30:15 +00001140 if (custom_format != eFormatInvalid)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001141 SetFormat(eFormatDefault);
1142 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001143}
1144
Greg Clayton737b9322010-09-13 03:32:57 +00001145addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001146ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +00001147{
Enrico Granatac3e320a2011-08-02 17:27:39 +00001148 if (!UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +00001149 return LLDB_INVALID_ADDRESS;
1150
Greg Clayton73b472d2010-10-27 03:32:59 +00001151 switch (m_value.GetValueType())
1152 {
1153 case Value::eValueTypeScalar:
1154 if (scalar_is_load_address)
1155 {
1156 address_type = eAddressTypeLoad;
1157 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1158 }
1159 break;
1160
1161 case Value::eValueTypeLoadAddress:
1162 case Value::eValueTypeFileAddress:
1163 case Value::eValueTypeHostAddress:
1164 {
1165 address_type = m_value.GetValueAddressType ();
1166 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1167 }
1168 break;
1169 }
1170 address_type = eAddressTypeInvalid;
1171 return LLDB_INVALID_ADDRESS;
1172}
1173
1174addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001175ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +00001176{
1177 lldb::addr_t address = LLDB_INVALID_ADDRESS;
1178 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +00001179
Enrico Granatac3e320a2011-08-02 17:27:39 +00001180 if (!UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +00001181 return address;
1182
Greg Clayton73b472d2010-10-27 03:32:59 +00001183 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +00001184 {
1185 case Value::eValueTypeScalar:
1186 if (scalar_is_load_address)
1187 {
1188 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1189 address_type = eAddressTypeLoad;
1190 }
1191 break;
1192
1193 case Value::eValueTypeLoadAddress:
1194 case Value::eValueTypeFileAddress:
1195 case Value::eValueTypeHostAddress:
1196 {
1197 uint32_t data_offset = 0;
1198 address = m_data.GetPointer(&data_offset);
1199 address_type = m_value.GetValueAddressType();
1200 if (address_type == eAddressTypeInvalid)
1201 address_type = eAddressTypeLoad;
1202 }
1203 break;
1204 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001205
1206 if (m_pointers_point_to_load_addrs)
1207 address_type = eAddressTypeLoad;
1208
Greg Clayton737b9322010-09-13 03:32:57 +00001209 return address;
1210}
1211
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001212bool
Jim Ingham6035b672011-03-31 00:19:25 +00001213ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001214{
1215 // Make sure our value is up to date first so that our location and location
1216 // type is valid.
Enrico Granatac3e320a2011-08-02 17:27:39 +00001217 if (!UpdateValueIfNeeded(false))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001218 return false;
1219
1220 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001221 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001222
1223 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +00001224 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001225 switch (encoding)
1226 {
1227 case eEncodingInvalid:
1228 return false;
1229
1230 case eEncodingUint:
1231 if (byte_size > sizeof(unsigned long long))
1232 {
1233 return false;
1234 }
1235 else
1236 {
1237 unsigned long long ull_val = strtoull(value_str, &end, 0);
1238 if (end && *end != '\0')
1239 return false;
Jim Ingham4b536182011-08-09 02:12:22 +00001240 Value::ValueType value_type = m_value.GetValueType();
1241 switch (value_type)
1242 {
1243 case Value::eValueTypeLoadAddress:
1244 case Value::eValueTypeHostAddress:
1245 // The value in these cases lives in the data. So update the data:
1246
1247 break;
1248 case Value::eValueTypeScalar:
1249 m_value.GetScalar() = ull_val;
1250 break;
1251 case Value::eValueTypeFileAddress:
1252 // Try to convert the file address to a load address and then write the new value there.
1253 break;
1254 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255 // Limit the bytes in our m_data appropriately.
1256 m_value.GetScalar().GetData (m_data, byte_size);
1257 }
1258 break;
1259
1260 case eEncodingSint:
1261 if (byte_size > sizeof(long long))
1262 {
1263 return false;
1264 }
1265 else
1266 {
1267 long long sll_val = strtoll(value_str, &end, 0);
1268 if (end && *end != '\0')
1269 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001270 m_value.GetScalar() = sll_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001271 // Limit the bytes in our m_data appropriately.
1272 m_value.GetScalar().GetData (m_data, byte_size);
1273 }
1274 break;
1275
1276 case eEncodingIEEE754:
1277 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001278 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +00001279 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001280 if (dst != NULL)
1281 {
1282 // We are decoding a float into host byte order below, so make
1283 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +00001284 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001285 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
1286 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +00001287 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001288 value_str,
1289 dst,
1290 byte_size);
1291
1292 if (converted_byte_size == byte_size)
1293 {
1294 }
1295 }
1296 }
1297 break;
1298
1299 case eEncodingVector:
1300 return false;
1301
1302 default:
1303 return false;
1304 }
1305
1306 // If we have made it here the value is in m_data and we should write it
1307 // out to the target
1308 return Write ();
1309}
1310
1311bool
1312ValueObject::Write ()
1313{
1314 // Clear the update ID so the next time we try and read the value
1315 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +00001316 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001317
1318 // TODO: when Value has a method to write a value back, call it from here.
1319 return false;
1320
1321}
1322
Jim Ingham5a369122010-09-28 01:25:32 +00001323lldb::LanguageType
1324ValueObject::GetObjectRuntimeLanguage ()
1325{
Enrico Granatac3e320a2011-08-02 17:27:39 +00001326 return ClangASTType::GetMinimumLanguage (GetClangAST(),
1327 GetClangType());
Jim Ingham5a369122010-09-28 01:25:32 +00001328}
1329
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001330void
Jim Ingham58b59f92011-04-22 23:53:53 +00001331ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001332{
Jim Ingham58b59f92011-04-22 23:53:53 +00001333 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001334}
1335
1336ValueObjectSP
1337ValueObject::GetSyntheticChild (const ConstString &key) const
1338{
1339 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +00001340 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001341 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +00001342 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001343 return synthetic_child_sp;
1344}
1345
1346bool
1347ValueObject::IsPointerType ()
1348{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001349 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001350}
1351
Jim Inghamb7603bb2011-03-18 00:05:18 +00001352bool
Greg Claytondaf515f2011-07-09 20:12:33 +00001353ValueObject::IsArrayType ()
1354{
1355 return ClangASTContext::IsArrayType (GetClangType());
1356}
1357
1358bool
Enrico Granata9fc19442011-07-06 02:13:41 +00001359ValueObject::IsScalarType ()
1360{
1361 return ClangASTContext::IsScalarType (GetClangType());
1362}
1363
1364bool
Jim Inghamb7603bb2011-03-18 00:05:18 +00001365ValueObject::IsIntegerType (bool &is_signed)
1366{
1367 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
1368}
Greg Clayton73b472d2010-10-27 03:32:59 +00001369
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001370bool
1371ValueObject::IsPointerOrReferenceType ()
1372{
Greg Clayton007d5be2011-05-30 00:49:24 +00001373 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
1374}
1375
1376bool
1377ValueObject::IsPossibleCPlusPlusDynamicType ()
1378{
1379 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001380}
1381
Greg Claytondea8cb42011-06-29 22:09:02 +00001382bool
1383ValueObject::IsPossibleDynamicType ()
1384{
1385 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
1386}
1387
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001388ValueObjectSP
1389ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
1390{
1391 ValueObjectSP synthetic_child_sp;
1392 if (IsPointerType ())
1393 {
1394 char index_str[64];
1395 snprintf(index_str, sizeof(index_str), "[%i]", index);
1396 ConstString index_const_str(index_str);
1397 // Check if we have already created a synthetic array member in this
1398 // valid object. If we have we will re-use it.
1399 synthetic_child_sp = GetSyntheticChild (index_const_str);
1400 if (!synthetic_child_sp)
1401 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001402 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001403 // We haven't made a synthetic array member for INDEX yet, so
1404 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001405 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001406
1407 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001408 if (synthetic_child)
1409 {
1410 AddSyntheticChild(index_const_str, synthetic_child);
1411 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001412 synthetic_child_sp->SetName(ConstString(index_str));
Enrico Granata0a3958e2011-07-02 00:25:22 +00001413 synthetic_child_sp->m_is_array_item_for_pointer = true;
Jim Ingham58b59f92011-04-22 23:53:53 +00001414 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001415 }
1416 }
1417 return synthetic_child_sp;
1418}
Jim Ingham22777012010-09-23 02:01:19 +00001419
Greg Claytondaf515f2011-07-09 20:12:33 +00001420// This allows you to create an array member using and index
1421// that doesn't not fall in the normal bounds of the array.
1422// Many times structure can be defined as:
1423// struct Collection
1424// {
1425// uint32_t item_count;
1426// Item item_array[0];
1427// };
1428// The size of the "item_array" is 1, but many times in practice
1429// there are more items in "item_array".
1430
1431ValueObjectSP
1432ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create)
1433{
1434 ValueObjectSP synthetic_child_sp;
1435 if (IsArrayType ())
1436 {
1437 char index_str[64];
1438 snprintf(index_str, sizeof(index_str), "[%i]", index);
1439 ConstString index_const_str(index_str);
1440 // Check if we have already created a synthetic array member in this
1441 // valid object. If we have we will re-use it.
1442 synthetic_child_sp = GetSyntheticChild (index_const_str);
1443 if (!synthetic_child_sp)
1444 {
1445 ValueObject *synthetic_child;
1446 // We haven't made a synthetic array member for INDEX yet, so
1447 // lets make one and cache it for any future reference.
1448 synthetic_child = CreateChildAtIndex(0, true, index);
1449
1450 // Cache the value if we got one back...
1451 if (synthetic_child)
1452 {
1453 AddSyntheticChild(index_const_str, synthetic_child);
1454 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001455 synthetic_child_sp->SetName(ConstString(index_str));
Greg Claytondaf515f2011-07-09 20:12:33 +00001456 synthetic_child_sp->m_is_array_item_for_pointer = true;
1457 }
1458 }
1459 }
1460 return synthetic_child_sp;
1461}
1462
Enrico Granata9fc19442011-07-06 02:13:41 +00001463ValueObjectSP
1464ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
1465{
1466 ValueObjectSP synthetic_child_sp;
1467 if (IsScalarType ())
1468 {
1469 char index_str[64];
1470 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1471 ConstString index_const_str(index_str);
1472 // Check if we have already created a synthetic array member in this
1473 // valid object. If we have we will re-use it.
1474 synthetic_child_sp = GetSyntheticChild (index_const_str);
1475 if (!synthetic_child_sp)
1476 {
1477 ValueObjectChild *synthetic_child;
1478 // We haven't made a synthetic array member for INDEX yet, so
1479 // lets make one and cache it for any future reference.
1480 synthetic_child = new ValueObjectChild(*this,
1481 GetClangAST(),
1482 GetClangType(),
1483 index_const_str,
1484 GetByteSize(),
1485 0,
1486 to-from+1,
1487 from,
1488 false,
1489 false);
1490
1491 // Cache the value if we got one back...
1492 if (synthetic_child)
1493 {
1494 AddSyntheticChild(index_const_str, synthetic_child);
1495 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001496 synthetic_child_sp->SetName(ConstString(index_str));
Enrico Granata9fc19442011-07-06 02:13:41 +00001497 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1498 }
1499 }
1500 }
1501 return synthetic_child_sp;
1502}
1503
Enrico Granata6f3533f2011-07-29 19:53:35 +00001504lldb::ValueObjectSP
1505ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
1506{
1507
1508 ValueObjectSP synthetic_child_sp;
1509
1510 char name_str[64];
1511 snprintf(name_str, sizeof(name_str), "@%i", offset);
1512 ConstString name_const_str(name_str);
1513
1514 // Check if we have already created a synthetic array member in this
1515 // valid object. If we have we will re-use it.
1516 synthetic_child_sp = GetSyntheticChild (name_const_str);
1517
1518 if (synthetic_child_sp.get())
1519 return synthetic_child_sp;
1520
1521 if (!can_create)
1522 return lldb::ValueObjectSP();
1523
1524 ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
1525 type.GetASTContext(),
1526 type.GetOpaqueQualType(),
1527 name_const_str,
1528 type.GetTypeByteSize(),
1529 offset,
1530 0,
1531 0,
1532 false,
1533 false);
1534 if (synthetic_child)
1535 {
1536 AddSyntheticChild(name_const_str, synthetic_child);
1537 synthetic_child_sp = synthetic_child->GetSP();
1538 synthetic_child_sp->SetName(name_const_str);
1539 synthetic_child_sp->m_is_child_at_offset = true;
1540 }
1541 return synthetic_child_sp;
1542}
1543
Enrico Granatad55546b2011-07-22 00:16:08 +00001544// your expression path needs to have a leading . or ->
1545// (unless it somehow "looks like" an array, in which case it has
1546// a leading [ symbol). while the [ is meaningful and should be shown
1547// to the user, . and -> are just parser design, but by no means
1548// added information for the user.. strip them off
1549static const char*
1550SkipLeadingExpressionPathSeparators(const char* expression)
1551{
1552 if (!expression || !expression[0])
1553 return expression;
1554 if (expression[0] == '.')
1555 return expression+1;
1556 if (expression[0] == '-' && expression[1] == '>')
1557 return expression+2;
1558 return expression;
1559}
1560
1561lldb::ValueObjectSP
1562ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_create)
1563{
1564 ValueObjectSP synthetic_child_sp;
1565 ConstString name_const_string(expression);
1566 // Check if we have already created a synthetic array member in this
1567 // valid object. If we have we will re-use it.
1568 synthetic_child_sp = GetSyntheticChild (name_const_string);
1569 if (!synthetic_child_sp)
1570 {
1571 // We haven't made a synthetic array member for expression yet, so
1572 // lets make one and cache it for any future reference.
1573 synthetic_child_sp = GetValueForExpressionPath(expression);
1574
1575 // Cache the value if we got one back...
1576 if (synthetic_child_sp.get())
1577 {
1578 AddSyntheticChild(name_const_string, synthetic_child_sp.get());
Enrico Granata6f3533f2011-07-29 19:53:35 +00001579 synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression)));
Enrico Granatad55546b2011-07-22 00:16:08 +00001580 synthetic_child_sp->m_is_expression_path_child = true;
1581 }
1582 }
1583 return synthetic_child_sp;
1584}
1585
1586void
1587ValueObject::CalculateSyntheticValue (lldb::SyntheticValueType use_synthetic)
1588{
1589 if (use_synthetic == lldb::eNoSyntheticFilter)
1590 return;
1591
Enrico Granatac3e320a2011-08-02 17:27:39 +00001592 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
Enrico Granatad55546b2011-07-22 00:16:08 +00001593
1594 if (m_last_synthetic_filter.get() == NULL)
1595 return;
1596
Enrico Granataa37a0652011-07-24 00:14:56 +00001597 if (m_synthetic_value == NULL)
1598 m_synthetic_value = new ValueObjectSynthetic(*this, m_last_synthetic_filter);
Enrico Granatad55546b2011-07-22 00:16:08 +00001599
1600}
1601
Jim Ingham78a685a2011-04-16 00:01:13 +00001602void
Jim Ingham2837b762011-05-04 03:43:18 +00001603ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001604{
Jim Ingham2837b762011-05-04 03:43:18 +00001605 if (use_dynamic == lldb::eNoDynamicValues)
1606 return;
1607
Jim Ingham58b59f92011-04-22 23:53:53 +00001608 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001609 {
Enrico Granata6f3533f2011-07-29 19:53:35 +00001610 Process *process = m_update_point.GetProcessSP().get();
Jim Ingham78a685a2011-04-16 00:01:13 +00001611 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001612
Jim Ingham78a685a2011-04-16 00:01:13 +00001613
1614 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1615 // hard code this everywhere.
1616 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1617 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1618 {
1619 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1620 if (runtime)
1621 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1622 }
1623 else
1624 {
1625 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1626 if (cpp_runtime)
1627 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1628
1629 if (!worth_having_dynamic_value)
1630 {
1631 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1632 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001633 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001634 }
1635 }
1636
1637 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001638 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001639
1640// if (worth_having_dynamic_value)
1641// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1642
Jim Ingham78a685a2011-04-16 00:01:13 +00001643 }
1644}
1645
Jim Ingham58b59f92011-04-22 23:53:53 +00001646ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001647ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001648{
Jim Ingham2837b762011-05-04 03:43:18 +00001649 if (use_dynamic == lldb::eNoDynamicValues)
1650 return ValueObjectSP();
1651
1652 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001653 {
Jim Ingham2837b762011-05-04 03:43:18 +00001654 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001655 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001656 if (m_dynamic_value)
1657 return m_dynamic_value->GetSP();
1658 else
1659 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001660}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001661
Enrico Granatad55546b2011-07-22 00:16:08 +00001662// GetDynamicValue() returns a NULL SharedPointer if the object is not dynamic
1663// or we do not really want a dynamic VO. this method instead returns this object
1664// itself when making it synthetic has no meaning. this makes it much simpler
1665// to replace the SyntheticValue for the ValueObject
1666ValueObjectSP
1667ValueObject::GetSyntheticValue (SyntheticValueType use_synthetic)
1668{
1669 if (use_synthetic == lldb::eNoSyntheticFilter)
1670 return GetSP();
1671
Enrico Granatac3e320a2011-08-02 17:27:39 +00001672 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
Enrico Granatad55546b2011-07-22 00:16:08 +00001673
1674 if (m_last_synthetic_filter.get() == NULL)
1675 return GetSP();
1676
1677 CalculateSyntheticValue(use_synthetic);
1678
1679 if (m_synthetic_value)
1680 return m_synthetic_value->GetSP();
1681 else
1682 return GetSP();
1683}
1684
Greg Claytone221f822011-01-21 01:59:00 +00001685bool
Enrico Granata27b625e2011-08-09 01:04:56 +00001686ValueObject::HasSyntheticValue()
1687{
1688 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
1689
1690 if (m_last_synthetic_filter.get() == NULL)
1691 return false;
1692
1693 CalculateSyntheticValue(lldb::eUseSyntheticFilter);
1694
1695 if (m_synthetic_value)
1696 return true;
1697 else
1698 return false;
1699}
1700
1701bool
Greg Claytone221f822011-01-21 01:59:00 +00001702ValueObject::GetBaseClassPath (Stream &s)
1703{
1704 if (IsBaseClass())
1705 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001706 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001707 clang_type_t clang_type = GetClangType();
1708 std::string cxx_class_name;
1709 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1710 if (this_had_base_class)
1711 {
1712 if (parent_had_base_class)
1713 s.PutCString("::");
1714 s.PutCString(cxx_class_name.c_str());
1715 }
1716 return parent_had_base_class || this_had_base_class;
1717 }
1718 return false;
1719}
1720
1721
1722ValueObject *
1723ValueObject::GetNonBaseClassParent()
1724{
Jim Ingham78a685a2011-04-16 00:01:13 +00001725 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001726 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001727 if (GetParent()->IsBaseClass())
1728 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001729 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001730 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001731 }
1732 return NULL;
1733}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001734
1735void
Enrico Granata4becb372011-06-29 22:27:15 +00001736ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001737{
Greg Claytone221f822011-01-21 01:59:00 +00001738 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00001739
Enrico Granata9dd75c82011-07-15 23:30:15 +00001740 if (is_deref_of_parent && epformat == eDereferencePointers) {
Enrico Granata4becb372011-06-29 22:27:15 +00001741 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
1742 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
1743 // the eHonorPointers mode is meant to produce strings in this latter format
1744 s.PutCString("*(");
1745 }
Greg Claytone221f822011-01-21 01:59:00 +00001746
Enrico Granata4becb372011-06-29 22:27:15 +00001747 ValueObject* parent = GetParent();
1748
1749 if (parent)
1750 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
Enrico Granata0a3958e2011-07-02 00:25:22 +00001751
1752 // if we are a deref_of_parent just because we are synthetic array
1753 // members made up to allow ptr[%d] syntax to work in variable
1754 // printing, then add our name ([%d]) to the expression path
Enrico Granata9dd75c82011-07-15 23:30:15 +00001755 if (m_is_array_item_for_pointer && epformat == eHonorPointers)
Enrico Granata0a3958e2011-07-02 00:25:22 +00001756 s.PutCString(m_name.AsCString());
Enrico Granata4becb372011-06-29 22:27:15 +00001757
Greg Claytone221f822011-01-21 01:59:00 +00001758 if (!IsBaseClass())
1759 {
1760 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001761 {
Greg Claytone221f822011-01-21 01:59:00 +00001762 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1763 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001764 {
Greg Claytone221f822011-01-21 01:59:00 +00001765 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1766 if (non_base_class_parent_clang_type)
1767 {
1768 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1769
Enrico Granata9dd75c82011-07-15 23:30:15 +00001770 if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00001771 {
1772 s.PutCString("->");
1773 }
Enrico Granata4becb372011-06-29 22:27:15 +00001774 else
1775 {
1776 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1777 {
1778 s.PutCString("->");
1779 }
1780 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1781 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1782 {
1783 s.PutChar('.');
1784 }
Greg Claytone221f822011-01-21 01:59:00 +00001785 }
1786 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001787 }
Greg Claytone221f822011-01-21 01:59:00 +00001788
1789 const char *name = GetName().GetCString();
1790 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001791 {
Greg Claytone221f822011-01-21 01:59:00 +00001792 if (qualify_cxx_base_classes)
1793 {
1794 if (GetBaseClassPath (s))
1795 s.PutCString("::");
1796 }
1797 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001798 }
1799 }
1800 }
1801
Enrico Granata4becb372011-06-29 22:27:15 +00001802 if (is_deref_of_parent && epformat == eDereferencePointers) {
Greg Claytone221f822011-01-21 01:59:00 +00001803 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00001804 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001805}
1806
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001807lldb::ValueObjectSP
1808ValueObject::GetValueForExpressionPath(const char* expression,
1809 const char** first_unparsed,
1810 ExpressionPathScanEndReason* reason_to_stop,
1811 ExpressionPathEndResultType* final_value_type,
1812 const GetValueForExpressionPathOptions& options,
1813 ExpressionPathAftermath* final_task_on_target)
1814{
1815
1816 const char* dummy_first_unparsed;
1817 ExpressionPathScanEndReason dummy_reason_to_stop;
1818 ExpressionPathEndResultType dummy_final_value_type;
1819 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1820
1821 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1822 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1823 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1824 final_value_type ? final_value_type : &dummy_final_value_type,
1825 options,
1826 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1827
1828 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1829 {
1830 return ret_val;
1831 }
1832 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1833 {
1834 if (*final_task_on_target == ValueObject::eDereference)
1835 {
1836 Error error;
1837 ValueObjectSP final_value = ret_val->Dereference(error);
1838 if (error.Fail() || !final_value.get())
1839 {
1840 *reason_to_stop = ValueObject::eDereferencingFailed;
1841 *final_value_type = ValueObject::eInvalid;
1842 return ValueObjectSP();
1843 }
1844 else
1845 {
1846 *final_task_on_target = ValueObject::eNothing;
1847 return final_value;
1848 }
1849 }
1850 if (*final_task_on_target == ValueObject::eTakeAddress)
1851 {
1852 Error error;
1853 ValueObjectSP final_value = ret_val->AddressOf(error);
1854 if (error.Fail() || !final_value.get())
1855 {
1856 *reason_to_stop = ValueObject::eTakingAddressFailed;
1857 *final_value_type = ValueObject::eInvalid;
1858 return ValueObjectSP();
1859 }
1860 else
1861 {
1862 *final_task_on_target = ValueObject::eNothing;
1863 return final_value;
1864 }
1865 }
1866 }
1867 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
1868}
1869
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001870int
1871ValueObject::GetValuesForExpressionPath(const char* expression,
1872 lldb::ValueObjectListSP& list,
1873 const char** first_unparsed,
1874 ExpressionPathScanEndReason* reason_to_stop,
1875 ExpressionPathEndResultType* final_value_type,
1876 const GetValueForExpressionPathOptions& options,
1877 ExpressionPathAftermath* final_task_on_target)
1878{
1879 const char* dummy_first_unparsed;
1880 ExpressionPathScanEndReason dummy_reason_to_stop;
1881 ExpressionPathEndResultType dummy_final_value_type;
1882 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1883
1884 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1885 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1886 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1887 final_value_type ? final_value_type : &dummy_final_value_type,
1888 options,
1889 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1890
1891 if (!ret_val.get()) // if there are errors, I add nothing to the list
1892 return 0;
1893
1894 if (*reason_to_stop != eArrayRangeOperatorMet)
1895 {
1896 // I need not expand a range, just post-process the final value and return
1897 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1898 {
1899 list->Append(ret_val);
1900 return 1;
1901 }
1902 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1903 {
1904 if (*final_task_on_target == ValueObject::eDereference)
1905 {
1906 Error error;
1907 ValueObjectSP final_value = ret_val->Dereference(error);
1908 if (error.Fail() || !final_value.get())
1909 {
1910 *reason_to_stop = ValueObject::eDereferencingFailed;
1911 *final_value_type = ValueObject::eInvalid;
1912 return 0;
1913 }
1914 else
1915 {
1916 *final_task_on_target = ValueObject::eNothing;
1917 list->Append(final_value);
1918 return 1;
1919 }
1920 }
1921 if (*final_task_on_target == ValueObject::eTakeAddress)
1922 {
1923 Error error;
1924 ValueObjectSP final_value = ret_val->AddressOf(error);
1925 if (error.Fail() || !final_value.get())
1926 {
1927 *reason_to_stop = ValueObject::eTakingAddressFailed;
1928 *final_value_type = ValueObject::eInvalid;
1929 return 0;
1930 }
1931 else
1932 {
1933 *final_task_on_target = ValueObject::eNothing;
1934 list->Append(final_value);
1935 return 1;
1936 }
1937 }
1938 }
1939 }
1940 else
1941 {
1942 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
1943 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1944 ret_val,
1945 list,
1946 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1947 final_value_type ? final_value_type : &dummy_final_value_type,
1948 options,
1949 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1950 }
1951 // in any non-covered case, just do the obviously right thing
1952 list->Append(ret_val);
1953 return 1;
1954}
1955
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001956lldb::ValueObjectSP
1957ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
1958 const char** first_unparsed,
1959 ExpressionPathScanEndReason* reason_to_stop,
1960 ExpressionPathEndResultType* final_result,
1961 const GetValueForExpressionPathOptions& options,
1962 ExpressionPathAftermath* what_next)
1963{
1964 ValueObjectSP root = GetSP();
1965
1966 if (!root.get())
1967 return ValueObjectSP();
1968
1969 *first_unparsed = expression_cstr;
1970
1971 while (true)
1972 {
1973
1974 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
1975
1976 lldb::clang_type_t root_clang_type = root->GetClangType();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001977 lldb::clang_type_t pointee_clang_type;
1978 Flags root_clang_type_info,pointee_clang_type_info;
1979
1980 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
1981 if (pointee_clang_type)
1982 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001983
1984 if (!expression_cstr || *expression_cstr == '\0')
1985 {
1986 *reason_to_stop = ValueObject::eEndOfString;
1987 return root;
1988 }
1989
1990 switch (*expression_cstr)
1991 {
1992 case '-':
1993 {
1994 if (options.m_check_dot_vs_arrow_syntax &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001995 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 +00001996 {
1997 *first_unparsed = expression_cstr;
1998 *reason_to_stop = ValueObject::eArrowInsteadOfDot;
1999 *final_result = ValueObject::eInvalid;
2000 return ValueObjectSP();
2001 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002002 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
2003 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) &&
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002004 options.m_no_fragile_ivar)
2005 {
2006 *first_unparsed = expression_cstr;
2007 *reason_to_stop = ValueObject::eFragileIVarNotAllowed;
2008 *final_result = ValueObject::eInvalid;
2009 return ValueObjectSP();
2010 }
2011 if (expression_cstr[1] != '>')
2012 {
2013 *first_unparsed = expression_cstr;
2014 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2015 *final_result = ValueObject::eInvalid;
2016 return ValueObjectSP();
2017 }
2018 expression_cstr++; // skip the -
2019 }
2020 case '.': // or fallthrough from ->
2021 {
2022 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002023 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 +00002024 {
2025 *first_unparsed = expression_cstr;
2026 *reason_to_stop = ValueObject::eDotInsteadOfArrow;
2027 *final_result = ValueObject::eInvalid;
2028 return ValueObjectSP();
2029 }
2030 expression_cstr++; // skip .
2031 const char *next_separator = strpbrk(expression_cstr+1,"-.[");
2032 ConstString child_name;
2033 if (!next_separator) // if no other separator just expand this last layer
2034 {
2035 child_name.SetCString (expression_cstr);
Enrico Granata8c9d3562011-08-11 17:08:01 +00002036 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
2037
2038 if (child_valobj_sp.get()) // we know we are done, so just return
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002039 {
2040 *first_unparsed = '\0';
2041 *reason_to_stop = ValueObject::eEndOfString;
2042 *final_result = ValueObject::ePlain;
Enrico Granata8c9d3562011-08-11 17:08:01 +00002043 return child_valobj_sp;
2044 }
2045 else if (options.m_no_synthetic_children == false) // let's try with synthetic children
2046 {
2047 child_valobj_sp = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildMemberWithName(child_name, true);
2048 }
2049
2050 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
2051 // so we hit the "else" branch, and return an error
2052 if(child_valobj_sp.get()) // if it worked, just return
2053 {
2054 *first_unparsed = '\0';
2055 *reason_to_stop = ValueObject::eEndOfString;
2056 *final_result = ValueObject::ePlain;
2057 return child_valobj_sp;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002058 }
2059 else
2060 {
2061 *first_unparsed = expression_cstr;
2062 *reason_to_stop = ValueObject::eNoSuchChild;
2063 *final_result = ValueObject::eInvalid;
2064 return ValueObjectSP();
2065 }
2066 }
2067 else // other layers do expand
2068 {
2069 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
Enrico Granata8c9d3562011-08-11 17:08:01 +00002070 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
2071 if (child_valobj_sp.get()) // store the new root and move on
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002072 {
Enrico Granata8c9d3562011-08-11 17:08:01 +00002073 root = child_valobj_sp;
2074 *first_unparsed = next_separator;
2075 *final_result = ValueObject::ePlain;
2076 continue;
2077 }
2078 else if (options.m_no_synthetic_children == false) // let's try with synthetic children
2079 {
2080 child_valobj_sp = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildMemberWithName(child_name, true);
2081 }
2082
2083 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
2084 // so we hit the "else" branch, and return an error
2085 if(child_valobj_sp.get()) // if it worked, move on
2086 {
2087 root = child_valobj_sp;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002088 *first_unparsed = next_separator;
2089 *final_result = ValueObject::ePlain;
2090 continue;
2091 }
2092 else
2093 {
2094 *first_unparsed = expression_cstr;
2095 *reason_to_stop = ValueObject::eNoSuchChild;
2096 *final_result = ValueObject::eInvalid;
2097 return ValueObjectSP();
2098 }
2099 }
2100 break;
2101 }
2102 case '[':
2103 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002104 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 +00002105 {
Enrico Granata27b625e2011-08-09 01:04:56 +00002106 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar...
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002107 {
Enrico Granata27b625e2011-08-09 01:04:56 +00002108 if (options.m_no_synthetic_children) // ...only chance left is synthetic
2109 {
2110 *first_unparsed = expression_cstr;
2111 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2112 *final_result = ValueObject::eInvalid;
2113 return ValueObjectSP();
2114 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002115 }
2116 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2117 {
2118 *first_unparsed = expression_cstr;
2119 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2120 *final_result = ValueObject::eInvalid;
2121 return ValueObjectSP();
2122 }
2123 }
2124 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2125 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002126 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002127 {
2128 *first_unparsed = expression_cstr;
2129 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2130 *final_result = ValueObject::eInvalid;
2131 return ValueObjectSP();
2132 }
2133 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
2134 {
2135 *first_unparsed = expression_cstr+2;
2136 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2137 *final_result = ValueObject::eUnboundedRange;
2138 return root;
2139 }
2140 }
2141 const char *separator_position = ::strchr(expression_cstr+1,'-');
2142 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2143 if (!close_bracket_position) // if there is no ], this is a syntax error
2144 {
2145 *first_unparsed = expression_cstr;
2146 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2147 *final_result = ValueObject::eInvalid;
2148 return ValueObjectSP();
2149 }
2150 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2151 {
2152 char *end = NULL;
2153 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2154 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2155 {
2156 *first_unparsed = expression_cstr;
2157 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2158 *final_result = ValueObject::eInvalid;
2159 return ValueObjectSP();
2160 }
2161 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2162 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002163 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002164 {
2165 *first_unparsed = expression_cstr+2;
2166 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2167 *final_result = ValueObject::eUnboundedRange;
2168 return root;
2169 }
2170 else
2171 {
2172 *first_unparsed = expression_cstr;
2173 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2174 *final_result = ValueObject::eInvalid;
2175 return ValueObjectSP();
2176 }
2177 }
2178 // from here on we do have a valid index
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002179 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002180 {
Greg Claytondaf515f2011-07-09 20:12:33 +00002181 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2182 if (!child_valobj_sp)
2183 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
Enrico Granata27b625e2011-08-09 01:04:56 +00002184 if (!child_valobj_sp)
2185 if (root->HasSyntheticValue() && root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetNumChildren() > index)
2186 child_valobj_sp = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildAtIndex(index, true);
Greg Claytondaf515f2011-07-09 20:12:33 +00002187 if (child_valobj_sp)
2188 {
2189 root = child_valobj_sp;
2190 *first_unparsed = end+1; // skip ]
2191 *final_result = ValueObject::ePlain;
2192 continue;
2193 }
2194 else
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002195 {
2196 *first_unparsed = expression_cstr;
2197 *reason_to_stop = ValueObject::eNoSuchChild;
2198 *final_result = ValueObject::eInvalid;
2199 return ValueObjectSP();
2200 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002201 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002202 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002203 {
2204 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 +00002205 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002206 {
2207 Error error;
2208 root = root->Dereference(error);
2209 if (error.Fail() || !root.get())
2210 {
2211 *first_unparsed = expression_cstr;
2212 *reason_to_stop = ValueObject::eDereferencingFailed;
2213 *final_result = ValueObject::eInvalid;
2214 return ValueObjectSP();
2215 }
2216 else
2217 {
2218 *what_next = eNothing;
2219 continue;
2220 }
2221 }
2222 else
2223 {
Enrico Granata27b625e2011-08-09 01:04:56 +00002224 if (ClangASTType::GetMinimumLanguage(root->GetClangAST(),
2225 root->GetClangType()) == lldb::eLanguageTypeObjC
2226 &&
2227 ClangASTContext::IsPointerType(ClangASTType::GetPointeeType(root->GetClangType())) == false
2228 &&
2229 root->HasSyntheticValue()
2230 &&
2231 options.m_no_synthetic_children == false)
2232 {
2233 root = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildAtIndex(index, true);
2234 }
2235 else
2236 root = root->GetSyntheticArrayMemberFromPointer(index, true);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002237 if (!root.get())
2238 {
2239 *first_unparsed = expression_cstr;
2240 *reason_to_stop = ValueObject::eNoSuchChild;
2241 *final_result = ValueObject::eInvalid;
2242 return ValueObjectSP();
2243 }
2244 else
2245 {
2246 *first_unparsed = end+1; // skip ]
2247 *final_result = ValueObject::ePlain;
2248 continue;
2249 }
2250 }
2251 }
Enrico Granata27b625e2011-08-09 01:04:56 +00002252 else if (ClangASTContext::IsScalarType(root_clang_type))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002253 {
2254 root = root->GetSyntheticBitFieldChild(index, index, true);
2255 if (!root.get())
2256 {
2257 *first_unparsed = expression_cstr;
2258 *reason_to_stop = ValueObject::eNoSuchChild;
2259 *final_result = ValueObject::eInvalid;
2260 return ValueObjectSP();
2261 }
2262 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2263 {
2264 *first_unparsed = end+1; // skip ]
2265 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2266 *final_result = ValueObject::eBitfield;
2267 return root;
2268 }
2269 }
Enrico Granata8c9d3562011-08-11 17:08:01 +00002270 else if (root->HasSyntheticValue() && options.m_no_synthetic_children == false)
Enrico Granata27b625e2011-08-09 01:04:56 +00002271 {
2272 root = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildAtIndex(index, true);
2273 if (!root.get())
2274 {
2275 *first_unparsed = expression_cstr;
2276 *reason_to_stop = ValueObject::eNoSuchChild;
2277 *final_result = ValueObject::eInvalid;
2278 return ValueObjectSP();
2279 }
Enrico Granata8c9d3562011-08-11 17:08:01 +00002280 else
2281 {
2282 *first_unparsed = end+1; // skip ]
2283 *final_result = ValueObject::ePlain;
2284 continue;
2285 }
Enrico Granata27b625e2011-08-09 01:04:56 +00002286 }
2287 else
2288 {
2289 *first_unparsed = expression_cstr;
2290 *reason_to_stop = ValueObject::eNoSuchChild;
2291 *final_result = ValueObject::eInvalid;
2292 return ValueObjectSP();
2293 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002294 }
2295 else // we have a low and a high index
2296 {
2297 char *end = NULL;
2298 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2299 if (!end || end != separator_position) // if something weird is in our way return an error
2300 {
2301 *first_unparsed = expression_cstr;
2302 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2303 *final_result = ValueObject::eInvalid;
2304 return ValueObjectSP();
2305 }
2306 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2307 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2308 {
2309 *first_unparsed = expression_cstr;
2310 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2311 *final_result = ValueObject::eInvalid;
2312 return ValueObjectSP();
2313 }
2314 if (index_lower > index_higher) // swap indices if required
2315 {
2316 unsigned long temp = index_lower;
2317 index_lower = index_higher;
2318 index_higher = temp;
2319 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002320 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002321 {
2322 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2323 if (!root.get())
2324 {
2325 *first_unparsed = expression_cstr;
2326 *reason_to_stop = ValueObject::eNoSuchChild;
2327 *final_result = ValueObject::eInvalid;
2328 return ValueObjectSP();
2329 }
2330 else
2331 {
2332 *first_unparsed = end+1; // skip ]
2333 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2334 *final_result = ValueObject::eBitfield;
2335 return root;
2336 }
2337 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002338 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 +00002339 *what_next == ValueObject::eDereference &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002340 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002341 {
2342 Error error;
2343 root = root->Dereference(error);
2344 if (error.Fail() || !root.get())
2345 {
2346 *first_unparsed = expression_cstr;
2347 *reason_to_stop = ValueObject::eDereferencingFailed;
2348 *final_result = ValueObject::eInvalid;
2349 return ValueObjectSP();
2350 }
2351 else
2352 {
2353 *what_next = ValueObject::eNothing;
2354 continue;
2355 }
2356 }
2357 else
2358 {
2359 *first_unparsed = expression_cstr;
2360 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2361 *final_result = ValueObject::eBoundedRange;
2362 return root;
2363 }
2364 }
2365 break;
2366 }
2367 default: // some non-separator is in the way
2368 {
2369 *first_unparsed = expression_cstr;
2370 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2371 *final_result = ValueObject::eInvalid;
2372 return ValueObjectSP();
2373 break;
2374 }
2375 }
2376 }
2377}
2378
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002379int
2380ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
2381 const char** first_unparsed,
2382 lldb::ValueObjectSP root,
2383 lldb::ValueObjectListSP& list,
2384 ExpressionPathScanEndReason* reason_to_stop,
2385 ExpressionPathEndResultType* final_result,
2386 const GetValueForExpressionPathOptions& options,
2387 ExpressionPathAftermath* what_next)
2388{
2389 if (!root.get())
2390 return 0;
2391
2392 *first_unparsed = expression_cstr;
2393
2394 while (true)
2395 {
2396
2397 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
2398
2399 lldb::clang_type_t root_clang_type = root->GetClangType();
2400 lldb::clang_type_t pointee_clang_type;
2401 Flags root_clang_type_info,pointee_clang_type_info;
2402
2403 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
2404 if (pointee_clang_type)
2405 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
2406
2407 if (!expression_cstr || *expression_cstr == '\0')
2408 {
2409 *reason_to_stop = ValueObject::eEndOfString;
2410 list->Append(root);
2411 return 1;
2412 }
2413
2414 switch (*expression_cstr)
2415 {
2416 case '[':
2417 {
2418 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
2419 {
2420 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
2421 {
2422 *first_unparsed = expression_cstr;
2423 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2424 *final_result = ValueObject::eInvalid;
2425 return 0;
2426 }
2427 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2428 {
2429 *first_unparsed = expression_cstr;
2430 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2431 *final_result = ValueObject::eInvalid;
2432 return 0;
2433 }
2434 }
2435 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2436 {
2437 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2438 {
2439 *first_unparsed = expression_cstr;
2440 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2441 *final_result = ValueObject::eInvalid;
2442 return 0;
2443 }
2444 else // expand this into list
2445 {
2446 int max_index = root->GetNumChildren() - 1;
2447 for (int index = 0; index < max_index; index++)
2448 {
2449 ValueObjectSP child =
2450 root->GetChildAtIndex(index, true);
2451 list->Append(child);
2452 }
2453 *first_unparsed = expression_cstr+2;
2454 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2455 *final_result = ValueObject::eValueObjectList;
2456 return max_index; // tell me number of items I added to the VOList
2457 }
2458 }
2459 const char *separator_position = ::strchr(expression_cstr+1,'-');
2460 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2461 if (!close_bracket_position) // if there is no ], this is a syntax error
2462 {
2463 *first_unparsed = expression_cstr;
2464 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2465 *final_result = ValueObject::eInvalid;
2466 return 0;
2467 }
2468 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2469 {
2470 char *end = NULL;
2471 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2472 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2473 {
2474 *first_unparsed = expression_cstr;
2475 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2476 *final_result = ValueObject::eInvalid;
2477 return 0;
2478 }
2479 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2480 {
2481 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2482 {
2483 int max_index = root->GetNumChildren() - 1;
2484 for (int index = 0; index < max_index; index++)
2485 {
2486 ValueObjectSP child =
2487 root->GetChildAtIndex(index, true);
2488 list->Append(child);
2489 }
2490 *first_unparsed = expression_cstr+2;
2491 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2492 *final_result = ValueObject::eValueObjectList;
2493 return max_index; // tell me number of items I added to the VOList
2494 }
2495 else
2496 {
2497 *first_unparsed = expression_cstr;
2498 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2499 *final_result = ValueObject::eInvalid;
2500 return 0;
2501 }
2502 }
2503 // from here on we do have a valid index
2504 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2505 {
2506 root = root->GetChildAtIndex(index, true);
2507 if (!root.get())
2508 {
2509 *first_unparsed = expression_cstr;
2510 *reason_to_stop = ValueObject::eNoSuchChild;
2511 *final_result = ValueObject::eInvalid;
2512 return 0;
2513 }
2514 else
2515 {
2516 list->Append(root);
2517 *first_unparsed = end+1; // skip ]
2518 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2519 *final_result = ValueObject::eValueObjectList;
2520 return 1;
2521 }
2522 }
2523 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
2524 {
2525 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
2526 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2527 {
2528 Error error;
2529 root = root->Dereference(error);
2530 if (error.Fail() || !root.get())
2531 {
2532 *first_unparsed = expression_cstr;
2533 *reason_to_stop = ValueObject::eDereferencingFailed;
2534 *final_result = ValueObject::eInvalid;
2535 return 0;
2536 }
2537 else
2538 {
2539 *what_next = eNothing;
2540 continue;
2541 }
2542 }
2543 else
2544 {
2545 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2546 if (!root.get())
2547 {
2548 *first_unparsed = expression_cstr;
2549 *reason_to_stop = ValueObject::eNoSuchChild;
2550 *final_result = ValueObject::eInvalid;
2551 return 0;
2552 }
2553 else
2554 {
2555 list->Append(root);
2556 *first_unparsed = end+1; // skip ]
2557 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2558 *final_result = ValueObject::eValueObjectList;
2559 return 1;
2560 }
2561 }
2562 }
2563 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
2564 {
2565 root = root->GetSyntheticBitFieldChild(index, index, true);
2566 if (!root.get())
2567 {
2568 *first_unparsed = expression_cstr;
2569 *reason_to_stop = ValueObject::eNoSuchChild;
2570 *final_result = ValueObject::eInvalid;
2571 return 0;
2572 }
2573 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2574 {
2575 list->Append(root);
2576 *first_unparsed = end+1; // skip ]
2577 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2578 *final_result = ValueObject::eValueObjectList;
2579 return 1;
2580 }
2581 }
2582 }
2583 else // we have a low and a high index
2584 {
2585 char *end = NULL;
2586 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2587 if (!end || end != separator_position) // if something weird is in our way return an error
2588 {
2589 *first_unparsed = expression_cstr;
2590 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2591 *final_result = ValueObject::eInvalid;
2592 return 0;
2593 }
2594 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2595 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2596 {
2597 *first_unparsed = expression_cstr;
2598 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2599 *final_result = ValueObject::eInvalid;
2600 return 0;
2601 }
2602 if (index_lower > index_higher) // swap indices if required
2603 {
2604 unsigned long temp = index_lower;
2605 index_lower = index_higher;
2606 index_higher = temp;
2607 }
2608 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
2609 {
2610 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2611 if (!root.get())
2612 {
2613 *first_unparsed = expression_cstr;
2614 *reason_to_stop = ValueObject::eNoSuchChild;
2615 *final_result = ValueObject::eInvalid;
2616 return 0;
2617 }
2618 else
2619 {
2620 list->Append(root);
2621 *first_unparsed = end+1; // skip ]
2622 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2623 *final_result = ValueObject::eValueObjectList;
2624 return 1;
2625 }
2626 }
2627 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
2628 *what_next == ValueObject::eDereference &&
2629 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2630 {
2631 Error error;
2632 root = root->Dereference(error);
2633 if (error.Fail() || !root.get())
2634 {
2635 *first_unparsed = expression_cstr;
2636 *reason_to_stop = ValueObject::eDereferencingFailed;
2637 *final_result = ValueObject::eInvalid;
2638 return 0;
2639 }
2640 else
2641 {
2642 *what_next = ValueObject::eNothing;
2643 continue;
2644 }
2645 }
2646 else
2647 {
Johnny Chen44805302011-07-19 19:48:13 +00002648 for (unsigned long index = index_lower;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002649 index <= index_higher; index++)
2650 {
2651 ValueObjectSP child =
2652 root->GetChildAtIndex(index, true);
2653 list->Append(child);
2654 }
2655 *first_unparsed = end+1;
2656 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2657 *final_result = ValueObject::eValueObjectList;
2658 return index_higher-index_lower+1; // tell me number of items I added to the VOList
2659 }
2660 }
2661 break;
2662 }
2663 default: // some non-[ separator, or something entirely wrong, is in the way
2664 {
2665 *first_unparsed = expression_cstr;
2666 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2667 *final_result = ValueObject::eInvalid;
2668 return 0;
2669 break;
2670 }
2671 }
2672 }
2673}
2674
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002675void
Greg Clayton1d3afba2010-10-05 00:00:42 +00002676ValueObject::DumpValueObject
2677(
2678 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00002679 ValueObject *valobj,
2680 const char *root_valobj_name,
2681 uint32_t ptr_depth,
2682 uint32_t curr_depth,
2683 uint32_t max_depth,
2684 bool show_types,
2685 bool show_location,
2686 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00002687 lldb::DynamicValueType use_dynamic,
Enrico Granatad55546b2011-07-22 00:16:08 +00002688 bool use_synth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002689 bool scope_already_checked,
Enrico Granata0c5ef692011-07-16 01:22:04 +00002690 bool flat_output,
Enrico Granata22c55d12011-08-12 02:00:06 +00002691 uint32_t omit_summary_depth,
2692 bool ignore_cap
Greg Clayton1d3afba2010-10-05 00:00:42 +00002693)
2694{
Greg Clayton007d5be2011-05-30 00:49:24 +00002695 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002696 {
Enrico Granatac3e320a2011-08-02 17:27:39 +00002697 bool update_success = valobj->UpdateValueIfNeeded (use_dynamic, true);
Greg Clayton007d5be2011-05-30 00:49:24 +00002698
2699 if (update_success && use_dynamic != lldb::eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00002700 {
Jim Ingham2837b762011-05-04 03:43:18 +00002701 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00002702 if (dynamic_value)
2703 valobj = dynamic_value;
2704 }
2705
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002706 clang_type_t clang_type = valobj->GetClangType();
2707
Greg Clayton73b472d2010-10-27 03:32:59 +00002708 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002709 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00002710 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
2711 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002712
2713 const bool print_valobj = flat_output == false || has_value;
2714
2715 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002716 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002717 if (show_location)
2718 {
Jim Ingham6035b672011-03-31 00:19:25 +00002719 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002720 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002721
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002722 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002723
Greg Clayton7c8a9662010-11-02 01:50:16 +00002724 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00002725 if (show_types || (curr_depth == 0 && !flat_output))
Enrico Granatac3e320a2011-08-02 17:27:39 +00002726 {
Enrico Granata9910bc82011-08-03 02:18:51 +00002727 const char* typeName = valobj->GetTypeName().AsCString("<invalid type>");
2728 s.Printf("(%s", typeName);
2729 // only show dynamic types if the user really wants to see types
2730 if (show_types && use_dynamic != lldb::eNoDynamicValues &&
2731 (/*strstr(typeName, "id") == typeName ||*/
2732 ClangASTType::GetMinimumLanguage(valobj->GetClangAST(), valobj->GetClangType()) == lldb::eLanguageTypeObjC))
Enrico Granatac3e320a2011-08-02 17:27:39 +00002733 {
2734 Process* process = valobj->GetUpdatePoint().GetProcessSP().get();
2735 if (process == NULL)
Enrico Granata9910bc82011-08-03 02:18:51 +00002736 s.Printf(", dynamic type: unknown) ");
Enrico Granatac3e320a2011-08-02 17:27:39 +00002737 else
2738 {
2739 ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
2740 if (runtime == NULL)
Enrico Granata9910bc82011-08-03 02:18:51 +00002741 s.Printf(", dynamic type: unknown) ");
Enrico Granatac3e320a2011-08-02 17:27:39 +00002742 else
2743 {
2744 ObjCLanguageRuntime::ObjCISA isa = runtime->GetISA(*valobj);
2745 if (!runtime->IsValidISA(isa))
Enrico Granata9910bc82011-08-03 02:18:51 +00002746 s.Printf(", dynamic type: unknown) ");
Enrico Granatac3e320a2011-08-02 17:27:39 +00002747 else
2748 s.Printf(", dynamic type: %s) ",
2749 runtime->GetActualTypeName(isa).GetCString());
2750 }
2751 }
2752 }
2753 else
2754 s.Printf(") ");
2755 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002756
Greg Clayton1d3afba2010-10-05 00:00:42 +00002757
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002758 if (flat_output)
2759 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002760 // If we are showing types, also qualify the C++ base classes
2761 const bool qualify_cxx_base_classes = show_types;
2762 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002763 s.PutCString(" =");
2764 }
2765 else
2766 {
2767 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
2768 s.Printf ("%s =", name_cstr);
2769 }
2770
Jim Ingham6035b672011-03-31 00:19:25 +00002771 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002772 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002773 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002774 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002775 }
2776
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002777 const char *val_cstr = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00002778 const char *sum_cstr = NULL;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002779 SummaryFormat* entry = valobj->GetSummaryFormat().get();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002780
Enrico Granata0c5ef692011-07-16 01:22:04 +00002781 if (omit_summary_depth > 0)
2782 entry = NULL;
2783
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002784 if (err_cstr == NULL)
2785 {
Jim Ingham6035b672011-03-31 00:19:25 +00002786 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002787 err_cstr = valobj->GetError().AsCString();
2788 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002789
2790 if (err_cstr)
2791 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002792 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00002793 }
2794 else
2795 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002796 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002797 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002798 {
Enrico Granata4becb372011-06-29 22:27:15 +00002799
Enrico Granata0c5ef692011-07-16 01:22:04 +00002800 sum_cstr = (omit_summary_depth == 0) ? valobj->GetSummaryAsCString() : NULL;
Greg Clayton1d3afba2010-10-05 00:00:42 +00002801
Enrico Granata4becb372011-06-29 22:27:15 +00002802 // We must calculate this value in realtime because entry might alter this variable's value
2803 // (e.g. by saying ${var%fmt}) and render precached values useless
2804 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
2805 s.Printf(" %s", valobj->GetValueAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002806
Enrico Granata9dd75c82011-07-15 23:30:15 +00002807 if (sum_cstr)
Enrico Granata0a3958e2011-07-02 00:25:22 +00002808 {
2809 // for some reason, using %@ (ObjC description) in a summary string, makes
2810 // us believe we need to reset ourselves, thus invalidating the content of
2811 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty
2812 // let us recalculate it!
2813 if (sum_cstr[0] == '\0')
2814 s.Printf(" %s", valobj->GetSummaryAsCString());
2815 else
2816 s.Printf(" %s", sum_cstr);
2817 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002818
2819 if (use_objc)
2820 {
Jim Ingham6035b672011-03-31 00:19:25 +00002821 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002822 if (object_desc)
2823 s.Printf(" %s\n", object_desc);
2824 else
Sean Callanan672ad942010-10-23 00:18:49 +00002825 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002826 return;
Enrico Granata0a3958e2011-07-02 00:25:22 +00002827 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002828 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002829
2830 if (curr_depth < max_depth)
2831 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002832 // We will show children for all concrete types. We won't show
2833 // pointer contents unless a pointer depth has been specified.
2834 // We won't reference contents unless the reference is the
2835 // root object (depth of zero).
2836 bool print_children = true;
2837
2838 // Use a new temporary pointer depth in case we override the
2839 // current pointer depth below...
2840 uint32_t curr_ptr_depth = ptr_depth;
2841
2842 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
2843 if (is_ptr || is_ref)
2844 {
2845 // We have a pointer or reference whose value is an address.
2846 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00002847 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00002848 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
2849 print_children = false;
2850
2851 else if (is_ref && curr_depth == 0)
2852 {
2853 // If this is the root object (depth is zero) that we are showing
2854 // and it is a reference, and no pointer depth has been supplied
2855 // print out what it references. Don't do this at deeper depths
2856 // otherwise we can end up with infinite recursion...
2857 curr_ptr_depth = 1;
2858 }
2859
2860 if (curr_ptr_depth == 0)
2861 print_children = false;
2862 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002863
Enrico Granata0a3958e2011-07-02 00:25:22 +00002864 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00002865 {
Enrico Granatad55546b2011-07-22 00:16:08 +00002866 ValueObjectSP synth_vobj = valobj->GetSyntheticValue(use_synth ?
2867 lldb::eUseSyntheticFilter :
2868 lldb::eNoSyntheticFilter);
Enrico Granata22c55d12011-08-12 02:00:06 +00002869 uint32_t num_children = synth_vobj->GetNumChildren();
2870 bool print_dotdotdot = false;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002871 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002872 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002873 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002874 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002875 if (print_valobj)
2876 s.EOL();
2877 }
2878 else
2879 {
2880 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00002881 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002882 s.IndentMore();
2883 }
Enrico Granata22c55d12011-08-12 02:00:06 +00002884
2885 uint32_t max_num_children = valobj->GetUpdatePoint().GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
2886
2887 if (num_children > max_num_children && !ignore_cap)
2888 {
2889 num_children = max_num_children;
2890 print_dotdotdot = true;
2891 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002892
2893 for (uint32_t idx=0; idx<num_children; ++idx)
2894 {
Enrico Granatad55546b2011-07-22 00:16:08 +00002895 ValueObjectSP child_sp(synth_vobj->GetChildAtIndex(idx, true));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002896 if (child_sp.get())
2897 {
2898 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002899 child_sp.get(),
2900 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00002901 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002902 curr_depth + 1,
2903 max_depth,
2904 show_types,
2905 show_location,
2906 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00002907 use_dynamic,
Enrico Granatad55546b2011-07-22 00:16:08 +00002908 use_synth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002909 true,
Enrico Granata0c5ef692011-07-16 01:22:04 +00002910 flat_output,
Enrico Granata22c55d12011-08-12 02:00:06 +00002911 omit_summary_depth > 1 ? omit_summary_depth - 1 : 0,
2912 ignore_cap);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002913 }
2914 }
2915
2916 if (!flat_output)
2917 {
Enrico Granata22c55d12011-08-12 02:00:06 +00002918 if (print_dotdotdot)
Enrico Granata61a80ba2011-08-12 16:42:31 +00002919 {
2920 valobj->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
Enrico Granata22c55d12011-08-12 02:00:06 +00002921 s.Indent("...\n");
Enrico Granata61a80ba2011-08-12 16:42:31 +00002922 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002923 s.IndentLess();
2924 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002925 }
2926 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002927 else if (has_children)
2928 {
2929 // Aggregate, no children...
2930 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00002931 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002932 }
2933 else
2934 {
2935 if (print_valobj)
2936 s.EOL();
2937 }
2938
Greg Clayton1d3afba2010-10-05 00:00:42 +00002939 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002940 else
2941 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00002942 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002943 }
2944 }
2945 else
2946 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002947 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002948 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002949 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002950 }
2951 }
2952 }
2953 }
2954}
2955
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002956
2957ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00002958ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002959{
2960 ValueObjectSP valobj_sp;
2961
Enrico Granatac3e320a2011-08-02 17:27:39 +00002962 if (UpdateValueIfNeeded(false) && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002963 {
Jim Ingham6035b672011-03-31 00:19:25 +00002964 ExecutionContextScope *exe_scope = GetExecutionContextScope();
2965 if (exe_scope)
2966 {
2967 ExecutionContext exe_ctx;
2968 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002969
Jim Ingham6035b672011-03-31 00:19:25 +00002970 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002971
Jim Ingham6035b672011-03-31 00:19:25 +00002972 DataExtractor data;
2973 data.SetByteOrder (m_data.GetByteOrder());
2974 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002975
Greg Clayton644247c2011-07-07 01:59:51 +00002976 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002977
Jim Ingham58b59f92011-04-22 23:53:53 +00002978 valobj_sp = ValueObjectConstResult::Create (exe_scope,
2979 ast,
2980 GetClangType(),
2981 name,
2982 data);
Jim Ingham6035b672011-03-31 00:19:25 +00002983 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002984 }
Jim Ingham6035b672011-03-31 00:19:25 +00002985
2986 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002987 {
Jim Ingham58b59f92011-04-22 23:53:53 +00002988 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002989 }
2990 return valobj_sp;
2991}
2992
2993lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00002994ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002995{
Jim Ingham58b59f92011-04-22 23:53:53 +00002996 if (m_deref_valobj)
2997 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00002998
Greg Clayton54979cd2010-12-15 05:08:08 +00002999 const bool is_pointer_type = IsPointerType();
3000 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003001 {
3002 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +00003003 bool ignore_array_bounds = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003004
3005 std::string child_name_str;
3006 uint32_t child_byte_size = 0;
3007 int32_t child_byte_offset = 0;
3008 uint32_t child_bitfield_bit_size = 0;
3009 uint32_t child_bitfield_bit_offset = 0;
3010 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00003011 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003012 const bool transparent_pointers = false;
3013 clang::ASTContext *clang_ast = GetClangAST();
3014 clang_type_t clang_type = GetClangType();
3015 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00003016
3017 ExecutionContext exe_ctx;
3018 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
3019
3020 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
3021 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003022 GetName().GetCString(),
3023 clang_type,
3024 0,
3025 transparent_pointers,
3026 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003027 ignore_array_bounds,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003028 child_name_str,
3029 child_byte_size,
3030 child_byte_offset,
3031 child_bitfield_bit_size,
3032 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003033 child_is_base_class,
3034 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00003035 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003036 {
3037 ConstString child_name;
3038 if (!child_name_str.empty())
3039 child_name.SetCString (child_name_str.c_str());
3040
Jim Ingham58b59f92011-04-22 23:53:53 +00003041 m_deref_valobj = new ValueObjectChild (*this,
3042 clang_ast,
3043 child_clang_type,
3044 child_name,
3045 child_byte_size,
3046 child_byte_offset,
3047 child_bitfield_bit_size,
3048 child_bitfield_bit_offset,
3049 child_is_base_class,
3050 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003051 }
3052 }
Greg Clayton54979cd2010-12-15 05:08:08 +00003053
Jim Ingham58b59f92011-04-22 23:53:53 +00003054 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00003055 {
3056 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00003057 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00003058 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003059 else
3060 {
Greg Clayton54979cd2010-12-15 05:08:08 +00003061 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003062 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00003063
3064 if (is_pointer_type)
3065 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
3066 else
3067 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00003068 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003069 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003070}
3071
Jim Ingham78a685a2011-04-16 00:01:13 +00003072lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00003073ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003074{
Jim Ingham78a685a2011-04-16 00:01:13 +00003075 if (m_addr_of_valobj_sp)
3076 return m_addr_of_valobj_sp;
3077
Greg Claytone0d378b2011-03-24 21:19:54 +00003078 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003079 const bool scalar_is_load_address = false;
3080 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00003081 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003082 if (addr != LLDB_INVALID_ADDRESS)
3083 {
3084 switch (address_type)
3085 {
Greg Clayton54979cd2010-12-15 05:08:08 +00003086 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003087 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00003088 {
3089 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003090 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00003091 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
3092 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003093 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00003094
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003095 case eAddressTypeFile:
3096 case eAddressTypeLoad:
3097 case eAddressTypeHost:
3098 {
3099 clang::ASTContext *ast = GetClangAST();
3100 clang_type_t clang_type = GetClangType();
3101 if (ast && clang_type)
3102 {
3103 std::string name (1, '&');
3104 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00003105 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
3106 ast,
3107 ClangASTContext::CreatePointerType (ast, clang_type),
3108 ConstString (name.c_str()),
3109 addr,
3110 eAddressTypeInvalid,
3111 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003112 }
3113 }
3114 break;
3115 }
3116 }
Jim Ingham78a685a2011-04-16 00:01:13 +00003117 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003118}
3119
Greg Claytonb2dcc362011-05-05 23:32:56 +00003120
3121lldb::ValueObjectSP
3122ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
3123{
3124 lldb::ValueObjectSP valobj_sp;
3125 AddressType address_type;
3126 const bool scalar_is_load_address = true;
3127 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
3128
3129 if (ptr_value != LLDB_INVALID_ADDRESS)
3130 {
3131 Address ptr_addr (NULL, ptr_value);
3132
3133 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
3134 name,
3135 ptr_addr,
3136 clang_ast_type);
3137 }
3138 return valobj_sp;
3139}
3140
3141lldb::ValueObjectSP
3142ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
3143{
3144 lldb::ValueObjectSP valobj_sp;
3145 AddressType address_type;
3146 const bool scalar_is_load_address = true;
3147 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
3148
3149 if (ptr_value != LLDB_INVALID_ADDRESS)
3150 {
3151 Address ptr_addr (NULL, ptr_value);
3152
3153 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
3154 name,
3155 ptr_addr,
3156 type_sp);
3157 }
3158 return valobj_sp;
3159}
3160
Jim Ingham6035b672011-03-31 00:19:25 +00003161ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00003162 m_thread_id (LLDB_INVALID_UID),
Jim Ingham4b536182011-08-09 02:12:22 +00003163 m_mod_id ()
Jim Ingham6035b672011-03-31 00:19:25 +00003164{
3165}
3166
3167ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00003168 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00003169 m_first_update (true),
Jim Ingham89b61092011-07-06 17:42:14 +00003170 m_thread_id (LLDB_INVALID_THREAD_ID),
Jim Ingham4b536182011-08-09 02:12:22 +00003171 m_mod_id ()
Stephen Wilson71c21d12011-04-11 19:41:40 +00003172
Jim Ingham6035b672011-03-31 00:19:25 +00003173{
3174 ExecutionContext exe_ctx;
3175 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
3176 // and if so we want to cache that not the original.
3177 if (exe_scope)
3178 exe_scope->CalculateExecutionContext(exe_ctx);
3179 if (exe_ctx.target != NULL)
3180 {
3181 m_target_sp = exe_ctx.target->GetSP();
3182
3183 if (exe_ctx.process == NULL)
3184 m_process_sp = exe_ctx.target->GetProcessSP();
3185 else
3186 m_process_sp = exe_ctx.process->GetSP();
3187
3188 if (m_process_sp != NULL)
3189 {
Jim Ingham4b536182011-08-09 02:12:22 +00003190 m_mod_id = m_process_sp->GetModID();
3191
Jim Ingham6035b672011-03-31 00:19:25 +00003192 Thread *thread = NULL;
3193
3194 if (exe_ctx.thread == NULL)
3195 {
3196 if (use_selected)
3197 {
3198 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
3199 if (thread)
3200 computed_exe_scope = thread;
3201 }
3202 }
3203 else
3204 thread = exe_ctx.thread;
3205
3206 if (thread != NULL)
3207 {
3208 m_thread_id = thread->GetIndexID();
3209 if (exe_ctx.frame == NULL)
3210 {
3211 if (use_selected)
3212 {
3213 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
3214 if (frame)
3215 {
3216 m_stack_id = frame->GetStackID();
3217 computed_exe_scope = frame;
3218 }
3219 }
3220 }
3221 else
3222 m_stack_id = exe_ctx.frame->GetStackID();
3223 }
3224 }
3225 }
3226 m_exe_scope = computed_exe_scope;
3227}
3228
3229ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
3230 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00003231 m_needs_update(true),
3232 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00003233 m_target_sp (rhs.m_target_sp),
3234 m_process_sp (rhs.m_process_sp),
3235 m_thread_id (rhs.m_thread_id),
3236 m_stack_id (rhs.m_stack_id),
Jim Ingham4b536182011-08-09 02:12:22 +00003237 m_mod_id ()
Jim Ingham6035b672011-03-31 00:19:25 +00003238{
3239}
3240
3241ValueObject::EvaluationPoint::~EvaluationPoint ()
3242{
3243}
3244
3245ExecutionContextScope *
3246ValueObject::EvaluationPoint::GetExecutionContextScope ()
3247{
3248 // We have to update before giving out the scope, or we could be handing out stale pointers.
3249 SyncWithProcessState();
3250
3251 return m_exe_scope;
3252}
3253
3254// This function checks the EvaluationPoint against the current process state. If the current
3255// state matches the evaluation point, or the evaluation point is already invalid, then we return
3256// false, meaning "no change". If the current state is different, we update our state, and return
3257// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
3258// future calls to NeedsUpdate will return true.
3259
3260bool
3261ValueObject::EvaluationPoint::SyncWithProcessState()
3262{
Jim Ingham6035b672011-03-31 00:19:25 +00003263 // If we don't have a process nothing can change.
3264 if (!m_process_sp)
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003265 {
3266 m_exe_scope = m_target_sp.get();
Jim Ingham6035b672011-03-31 00:19:25 +00003267 return false;
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003268 }
Jim Ingham6035b672011-03-31 00:19:25 +00003269
3270 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham4b536182011-08-09 02:12:22 +00003271 ProcessModID current_mod_id = m_process_sp->GetModID();
3272
Jim Ingham78a685a2011-04-16 00:01:13 +00003273 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
3274 // In either case, we aren't going to be able to sync with the process state.
Jim Ingham4b536182011-08-09 02:12:22 +00003275 if (current_mod_id.GetStopID() == 0)
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003276 {
3277 m_exe_scope = m_target_sp.get();
Jim Ingham78a685a2011-04-16 00:01:13 +00003278 return false;
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003279 }
Jim Ingham78a685a2011-04-16 00:01:13 +00003280
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003281 if (m_mod_id.IsValid())
3282 {
3283 if (m_mod_id == current_mod_id)
3284 {
3285 // Everything is already up to date in this object, no need do
3286 // update the execution context scope.
3287 return false;
3288 }
3289 m_mod_id = current_mod_id;
3290 m_needs_update = true;
3291 }
Jim Ingham6035b672011-03-31 00:19:25 +00003292 m_exe_scope = m_process_sp.get();
3293
3294 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
3295 // doesn't, mark ourselves as invalid.
3296
3297 if (m_thread_id != LLDB_INVALID_THREAD_ID)
3298 {
3299 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
3300 if (our_thread == NULL)
Greg Clayton262f80d2011-07-06 16:49:27 +00003301 {
Jim Ingham89b61092011-07-06 17:42:14 +00003302 SetInvalid();
Greg Clayton262f80d2011-07-06 16:49:27 +00003303 }
Jim Ingham6035b672011-03-31 00:19:25 +00003304 else
3305 {
3306 m_exe_scope = our_thread;
3307
3308 if (m_stack_id.IsValid())
3309 {
3310 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
3311 if (our_frame == NULL)
3312 SetInvalid();
3313 else
3314 m_exe_scope = our_frame;
3315 }
3316 }
3317 }
3318 return true;
3319}
3320
Jim Ingham61be0902011-05-02 18:13:59 +00003321void
3322ValueObject::EvaluationPoint::SetUpdated ()
3323{
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003324 // this will update the execution context scope and the m_mod_id
3325 SyncWithProcessState();
Jim Ingham61be0902011-05-02 18:13:59 +00003326 m_first_update = false;
3327 m_needs_update = false;
Jim Ingham61be0902011-05-02 18:13:59 +00003328}
3329
3330
Jim Ingham6035b672011-03-31 00:19:25 +00003331bool
3332ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
3333{
3334 if (!IsValid())
3335 return false;
3336
3337 bool needs_update = false;
3338 m_exe_scope = NULL;
3339
3340 // The target has to be non-null, and the
3341 Target *target = exe_scope->CalculateTarget();
3342 if (target != NULL)
3343 {
3344 Target *old_target = m_target_sp.get();
3345 assert (target == old_target);
3346 Process *process = exe_scope->CalculateProcess();
3347 if (process != NULL)
3348 {
3349 // FOR NOW - assume you can't update variable objects across process boundaries.
3350 Process *old_process = m_process_sp.get();
3351 assert (process == old_process);
Jim Ingham4b536182011-08-09 02:12:22 +00003352 ProcessModID current_mod_id = process->GetModID();
3353 if (m_mod_id != current_mod_id)
Jim Ingham6035b672011-03-31 00:19:25 +00003354 {
3355 needs_update = true;
Jim Ingham4b536182011-08-09 02:12:22 +00003356 m_mod_id = current_mod_id;
Jim Ingham6035b672011-03-31 00:19:25 +00003357 }
3358 // See if we're switching the thread or stack context. If no thread is given, this is
3359 // being evaluated in a global context.
3360 Thread *thread = exe_scope->CalculateThread();
3361 if (thread != NULL)
3362 {
3363 lldb::user_id_t new_thread_index = thread->GetIndexID();
3364 if (new_thread_index != m_thread_id)
3365 {
3366 needs_update = true;
3367 m_thread_id = new_thread_index;
3368 m_stack_id.Clear();
3369 }
3370
3371 StackFrame *new_frame = exe_scope->CalculateStackFrame();
3372 if (new_frame != NULL)
3373 {
3374 if (new_frame->GetStackID() != m_stack_id)
3375 {
3376 needs_update = true;
3377 m_stack_id = new_frame->GetStackID();
3378 }
3379 }
3380 else
3381 {
3382 m_stack_id.Clear();
3383 needs_update = true;
3384 }
3385 }
3386 else
3387 {
3388 // If this had been given a thread, and now there is none, we should update.
3389 // Otherwise we don't have to do anything.
3390 if (m_thread_id != LLDB_INVALID_UID)
3391 {
3392 m_thread_id = LLDB_INVALID_UID;
3393 m_stack_id.Clear();
3394 needs_update = true;
3395 }
3396 }
3397 }
3398 else
3399 {
3400 // If there is no process, then we don't need to update anything.
3401 // But if we're switching from having a process to not, we should try to update.
3402 if (m_process_sp.get() != NULL)
3403 {
3404 needs_update = true;
3405 m_process_sp.reset();
3406 m_thread_id = LLDB_INVALID_UID;
3407 m_stack_id.Clear();
3408 }
3409 }
3410 }
3411 else
3412 {
3413 // If there's no target, nothing can change so we don't need to update anything.
3414 // But if we're switching from having a target to not, we should try to update.
3415 if (m_target_sp.get() != NULL)
3416 {
3417 needs_update = true;
3418 m_target_sp.reset();
3419 m_process_sp.reset();
3420 m_thread_id = LLDB_INVALID_UID;
3421 m_stack_id.Clear();
3422 }
3423 }
3424 if (!m_needs_update)
3425 m_needs_update = needs_update;
3426
3427 return needs_update;
3428}
Enrico Granataf2bbf712011-07-15 02:26:42 +00003429
3430void
3431ValueObject::ClearUserVisibleData()
3432{
3433 m_location_str.clear();
3434 m_value_str.clear();
3435 m_summary_str.clear();
3436 m_object_desc_str.clear();
Johnny Chen44805302011-07-19 19:48:13 +00003437}