blob: 77ee5c14e52919317e2d64fd7078c26dfda5363f [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 Granataf2bbf712011-07-15 02:26:42 +000034#include "lldb/Interpreter/ScriptInterpreterPython.h"
35
Greg Claytone1a916a2010-07-21 22:12:05 +000036#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037#include "lldb/Symbol/ClangASTContext.h"
38#include "lldb/Symbol/Type.h"
39
Jim Ingham53c47f12010-09-10 23:12:17 +000040#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000041#include "lldb/Target/LanguageRuntime.h"
Enrico Granatac3e320a2011-08-02 17:27:39 +000042#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043#include "lldb/Target/Process.h"
44#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000045#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047
Enrico Granataf4efecd2011-07-12 22:56:10 +000048#include "lldb/Utility/RefCounter.h"
49
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050using namespace lldb;
51using namespace lldb_private;
Enrico Granataf4efecd2011-07-12 22:56:10 +000052using namespace lldb_utility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053
54static lldb::user_id_t g_value_obj_uid = 0;
55
56//----------------------------------------------------------------------
57// ValueObject constructor
58//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000059ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000061 m_parent (&parent),
Stephen Wilson71c21d12011-04-11 19:41:40 +000062 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063 m_name (),
64 m_data (),
65 m_value (),
66 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000067 m_value_str (),
68 m_old_value_str (),
69 m_location_str (),
70 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000071 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000072 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000073 m_children (),
74 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000075 m_dynamic_value (NULL),
Enrico Granatad55546b2011-07-22 00:16:08 +000076 m_synthetic_value(NULL),
Jim Ingham58b59f92011-04-22 23:53:53 +000077 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000078 m_format (eFormatDefault),
Enrico Granata9df29e32011-07-19 20:57:44 +000079 m_last_format_mgr_revision(0),
Enrico Granatac3e320a2011-08-02 17:27:39 +000080 m_last_format_mgr_dynamic(lldb::eNoDynamicValues),
Enrico Granata9df29e32011-07-19 20:57:44 +000081 m_last_summary_format(),
82 m_forced_summary_format(),
83 m_last_value_format(),
Enrico Granatad55546b2011-07-22 00:16:08 +000084 m_last_synthetic_filter(),
Enrico Granata9df29e32011-07-19 20:57:44 +000085 m_user_id_of_forced_summary(0),
Greg Clayton288bdf92010-09-02 02:59:18 +000086 m_value_is_valid (false),
87 m_value_did_change (false),
88 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000089 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000090 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +000091 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +000092 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +000093 m_is_bitfield_for_scalar(false),
Enrico Granatad55546b2011-07-22 00:16:08 +000094 m_is_expression_path_child(false),
Enrico Granata6f3533f2011-07-29 19:53:35 +000095 m_is_child_at_offset(false),
Enrico Granatac3e320a2011-08-02 17:27:39 +000096 m_is_expression_result(false),
Enrico Granataf4efecd2011-07-12 22:56:10 +000097 m_dump_printable_counter(0)
Jim Ingham6035b672011-03-31 00:19:25 +000098{
Jim Ingham58b59f92011-04-22 23:53:53 +000099 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +0000100}
101
102//----------------------------------------------------------------------
103// ValueObject constructor
104//----------------------------------------------------------------------
105ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
106 UserID (++g_value_obj_uid), // Unique identifier for every value object
107 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000108 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +0000109 m_name (),
110 m_data (),
111 m_value (),
112 m_error (),
113 m_value_str (),
114 m_old_value_str (),
115 m_location_str (),
116 m_summary_str (),
117 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000118 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +0000119 m_children (),
120 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000121 m_dynamic_value (NULL),
Enrico Granatad55546b2011-07-22 00:16:08 +0000122 m_synthetic_value(NULL),
Jim Ingham58b59f92011-04-22 23:53:53 +0000123 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +0000124 m_format (eFormatDefault),
Enrico Granata9df29e32011-07-19 20:57:44 +0000125 m_last_format_mgr_revision(0),
Enrico Granatac3e320a2011-08-02 17:27:39 +0000126 m_last_format_mgr_dynamic(lldb::eNoDynamicValues),
Enrico Granata9df29e32011-07-19 20:57:44 +0000127 m_last_summary_format(),
128 m_forced_summary_format(),
129 m_last_value_format(),
Enrico Granatad55546b2011-07-22 00:16:08 +0000130 m_last_synthetic_filter(),
Enrico Granata9df29e32011-07-19 20:57:44 +0000131 m_user_id_of_forced_summary(0),
Jim Ingham6035b672011-03-31 00:19:25 +0000132 m_value_is_valid (false),
133 m_value_did_change (false),
134 m_children_count_valid (false),
135 m_old_value_valid (false),
136 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +0000137 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +0000138 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +0000139 m_is_bitfield_for_scalar(false),
Enrico Granatad55546b2011-07-22 00:16:08 +0000140 m_is_expression_path_child(false),
Enrico Granata6f3533f2011-07-29 19:53:35 +0000141 m_is_child_at_offset(false),
Enrico Granatac3e320a2011-08-02 17:27:39 +0000142 m_is_expression_result(false),
Enrico Granataf4efecd2011-07-12 22:56:10 +0000143 m_dump_printable_counter(0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144{
Jim Ingham58b59f92011-04-22 23:53:53 +0000145 m_manager = new ValueObjectManager();
146 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147}
148
149//----------------------------------------------------------------------
150// Destructor
151//----------------------------------------------------------------------
152ValueObject::~ValueObject ()
153{
154}
155
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156bool
Enrico Granata0a3958e2011-07-02 00:25:22 +0000157ValueObject::UpdateValueIfNeeded (bool update_format)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000159 return UpdateValueIfNeeded(m_last_format_mgr_dynamic, update_format);
160}
161
162bool
163ValueObject::UpdateValueIfNeeded (lldb::DynamicValueType use_dynamic, bool update_format)
164{
Enrico Granata4becb372011-06-29 22:27:15 +0000165
Enrico Granata0a3958e2011-07-02 00:25:22 +0000166 if (update_format)
Enrico Granatac3e320a2011-08-02 17:27:39 +0000167 UpdateFormatsIfNeeded(use_dynamic);
Enrico Granata4becb372011-06-29 22:27:15 +0000168
Greg Claytonb71f3842010-10-05 03:13:51 +0000169 // If this is a constant value, then our success is predicated on whether
170 // we have an error or not
171 if (GetIsConstant())
172 return m_error.Success();
173
Jim Ingham6035b672011-03-31 00:19:25 +0000174 bool first_update = m_update_point.IsFirstEvaluation();
175
176 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000177 {
Jim Ingham6035b672011-03-31 00:19:25 +0000178 m_update_point.SetUpdated();
179
180 // Save the old value using swap to avoid a string copy which
181 // also will clear our m_value_str
182 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183 {
Jim Ingham6035b672011-03-31 00:19:25 +0000184 m_old_value_valid = false;
185 }
186 else
187 {
188 m_old_value_valid = true;
189 m_old_value_str.swap (m_value_str);
190 m_value_str.clear();
191 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000192
Enrico Granataf2bbf712011-07-15 02:26:42 +0000193 ClearUserVisibleData();
194
Jim Ingham6035b672011-03-31 00:19:25 +0000195 const bool value_was_valid = GetValueIsValid();
196 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000197
Jim Ingham6035b672011-03-31 00:19:25 +0000198 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000199
Jim Ingham6035b672011-03-31 00:19:25 +0000200 // Call the pure virtual function to update the value
201 bool success = UpdateValue ();
202
203 SetValueIsValid (success);
204
205 if (first_update)
206 SetValueDidChange (false);
207 else if (!m_value_did_change && success == false)
208 {
209 // The value wasn't gotten successfully, so we mark this
210 // as changed if the value used to be valid and now isn't
211 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000212 }
213 }
214 return m_error.Success();
215}
216
Enrico Granata4becb372011-06-29 22:27:15 +0000217void
Enrico Granatac3e320a2011-08-02 17:27:39 +0000218ValueObject::UpdateFormatsIfNeeded(lldb::DynamicValueType use_dynamic)
Enrico Granata4becb372011-06-29 22:27:15 +0000219{
Enrico Granata6f3533f2011-07-29 19:53:35 +0000220 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
221 if (log)
222 log->Printf("checking for FormatManager revisions. VO named %s is at revision %d, while the format manager is at revision %d",
223 GetName().GetCString(),
Enrico Granata4becb372011-06-29 22:27:15 +0000224 m_last_format_mgr_revision,
Enrico Granata6f3533f2011-07-29 19:53:35 +0000225 Debugger::Formatting::ValueFormats::GetCurrentRevision());
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000226 if (HasCustomSummaryFormat() && m_update_point.GetUpdateID() != m_user_id_of_forced_summary)
227 {
228 ClearCustomSummaryFormat();
229 m_summary_str.clear();
230 }
Enrico Granatac3e320a2011-08-02 17:27:39 +0000231 if ( (m_last_format_mgr_revision != Debugger::Formatting::ValueFormats::GetCurrentRevision()) ||
232 m_last_format_mgr_dynamic != use_dynamic)
Enrico Granata4becb372011-06-29 22:27:15 +0000233 {
234 if (m_last_summary_format.get())
Enrico Granataf2bbf712011-07-15 02:26:42 +0000235 m_last_summary_format.reset((StringSummaryFormat*)NULL);
Enrico Granata4becb372011-06-29 22:27:15 +0000236 if (m_last_value_format.get())
Enrico Granatad55546b2011-07-22 00:16:08 +0000237 m_last_value_format.reset(/*(ValueFormat*)NULL*/);
238 if (m_last_synthetic_filter.get())
239 m_last_synthetic_filter.reset(/*(SyntheticFilter*)NULL*/);
Enrico Granataa37a0652011-07-24 00:14:56 +0000240
241 m_synthetic_value = NULL;
Enrico Granata1490c6f2011-07-19 02:34:21 +0000242
Enrico Granatac3e320a2011-08-02 17:27:39 +0000243 Debugger::Formatting::ValueFormats::Get(*this, use_dynamic, m_last_value_format);
244 Debugger::Formatting::GetSummaryFormat(*this, use_dynamic, m_last_summary_format);
245 Debugger::Formatting::GetSyntheticFilter(*this, use_dynamic, m_last_synthetic_filter);
Enrico Granata1490c6f2011-07-19 02:34:21 +0000246
247 m_last_format_mgr_revision = Debugger::Formatting::ValueFormats::GetCurrentRevision();
Enrico Granatac3e320a2011-08-02 17:27:39 +0000248 m_last_format_mgr_dynamic = use_dynamic;
Enrico Granataf2bbf712011-07-15 02:26:42 +0000249
250 ClearUserVisibleData();
Enrico Granata4becb372011-06-29 22:27:15 +0000251 }
252}
253
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000254DataExtractor &
255ValueObject::GetDataExtractor ()
256{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000257 UpdateValueIfNeeded(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258 return m_data;
259}
260
261const Error &
Greg Clayton262f80d2011-07-06 16:49:27 +0000262ValueObject::GetError()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000264 UpdateValueIfNeeded(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265 return m_error;
266}
267
268const ConstString &
269ValueObject::GetName() const
270{
271 return m_name;
272}
273
274const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000275ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000277 if (UpdateValueIfNeeded(false))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000278 {
279 if (m_location_str.empty())
280 {
281 StreamString sstr;
282
283 switch (m_value.GetValueType())
284 {
285 default:
286 break;
287
288 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000289 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290 {
291 RegisterInfo *reg_info = m_value.GetRegisterInfo();
292 if (reg_info)
293 {
294 if (reg_info->name)
295 m_location_str = reg_info->name;
296 else if (reg_info->alt_name)
297 m_location_str = reg_info->alt_name;
298 break;
299 }
300 }
301 m_location_str = "scalar";
302 break;
303
304 case Value::eValueTypeLoadAddress:
305 case Value::eValueTypeFileAddress:
306 case Value::eValueTypeHostAddress:
307 {
308 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
309 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
310 m_location_str.swap(sstr.GetString());
311 }
312 break;
313 }
314 }
315 }
316 return m_location_str.c_str();
317}
318
319Value &
320ValueObject::GetValue()
321{
322 return m_value;
323}
324
325const Value &
326ValueObject::GetValue() const
327{
328 return m_value;
329}
330
331bool
Jim Ingham6035b672011-03-31 00:19:25 +0000332ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000333{
334 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000335 ExecutionContextScope *exe_scope = GetExecutionContextScope();
336 if (exe_scope)
337 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000338 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
339 return scalar.IsValid();
340}
341
342bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000343ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344{
Greg Clayton288bdf92010-09-02 02:59:18 +0000345 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346}
347
348
349void
350ValueObject::SetValueIsValid (bool b)
351{
Greg Clayton288bdf92010-09-02 02:59:18 +0000352 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353}
354
355bool
Jim Ingham6035b672011-03-31 00:19:25 +0000356ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357{
Jim Ingham6035b672011-03-31 00:19:25 +0000358 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000359 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360}
361
362void
363ValueObject::SetValueDidChange (bool value_changed)
364{
Greg Clayton288bdf92010-09-02 02:59:18 +0000365 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366}
367
368ValueObjectSP
369ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
370{
371 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000372 // We may need to update our value if we are dynamic
373 if (IsPossibleDynamicType ())
Enrico Granatac3e320a2011-08-02 17:27:39 +0000374 UpdateValueIfNeeded(false);
Greg Claytondea8cb42011-06-29 22:09:02 +0000375 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000377 // Check if we have already made the child value object?
378 if (can_create && m_children[idx] == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000379 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000380 // No we haven't created the child at this index, so lets have our
381 // subclass do it and cache the result for quick future access.
382 m_children[idx] = CreateChildAtIndex (idx, false, 0);
Jim Ingham78a685a2011-04-16 00:01:13 +0000383 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000384
385 if (m_children[idx] != NULL)
386 return m_children[idx]->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387 }
388 return child_sp;
389}
390
391uint32_t
392ValueObject::GetIndexOfChildWithName (const ConstString &name)
393{
394 bool omit_empty_base_classes = true;
395 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000396 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000397 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398 omit_empty_base_classes);
399}
400
401ValueObjectSP
402ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
403{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000404 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405 // classes (which really aren't part of the expression path), so we
406 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000408
Greg Claytondea8cb42011-06-29 22:09:02 +0000409 // We may need to update our value if we are dynamic
410 if (IsPossibleDynamicType ())
Enrico Granatac3e320a2011-08-02 17:27:39 +0000411 UpdateValueIfNeeded(false);
Greg Claytondea8cb42011-06-29 22:09:02 +0000412
413 std::vector<uint32_t> child_indexes;
414 clang::ASTContext *clang_ast = GetClangAST();
415 void *clang_type = GetClangType();
416 bool omit_empty_base_classes = true;
417 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
418 clang_type,
419 name.GetCString(),
420 omit_empty_base_classes,
421 child_indexes);
422 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000424 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
425 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
426
427 child_sp = GetChildAtIndex(*pos, can_create);
428 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000430 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000431 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000432 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
433 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000434 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000435 else
436 {
437 child_sp.reset();
438 }
439
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440 }
441 }
442 return child_sp;
443}
444
445
446uint32_t
447ValueObject::GetNumChildren ()
448{
Greg Clayton288bdf92010-09-02 02:59:18 +0000449 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450 {
451 SetNumChildren (CalculateNumChildren());
452 }
453 return m_children.size();
454}
455void
456ValueObject::SetNumChildren (uint32_t num_children)
457{
Greg Clayton288bdf92010-09-02 02:59:18 +0000458 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459 m_children.resize(num_children);
460}
461
462void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463ValueObject::SetName (const ConstString &name)
464{
465 m_name = name;
466}
467
Jim Ingham58b59f92011-04-22 23:53:53 +0000468ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
470{
Jim Ingham2eec4872011-05-07 00:10:58 +0000471 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000472
Greg Claytondea8cb42011-06-29 22:09:02 +0000473 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +0000474 bool ignore_array_bounds = synthetic_array_member;
Greg Claytondea8cb42011-06-29 22:09:02 +0000475 std::string child_name_str;
476 uint32_t child_byte_size = 0;
477 int32_t child_byte_offset = 0;
478 uint32_t child_bitfield_bit_size = 0;
479 uint32_t child_bitfield_bit_offset = 0;
480 bool child_is_base_class = false;
481 bool child_is_deref_of_parent = false;
482
483 const bool transparent_pointers = synthetic_array_member == false;
484 clang::ASTContext *clang_ast = GetClangAST();
485 clang_type_t clang_type = GetClangType();
486 clang_type_t child_clang_type;
487
488 ExecutionContext exe_ctx;
489 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
490
491 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
492 clang_ast,
493 GetName().GetCString(),
494 clang_type,
495 idx,
496 transparent_pointers,
497 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +0000498 ignore_array_bounds,
Greg Claytondea8cb42011-06-29 22:09:02 +0000499 child_name_str,
500 child_byte_size,
501 child_byte_offset,
502 child_bitfield_bit_size,
503 child_bitfield_bit_offset,
504 child_is_base_class,
505 child_is_deref_of_parent);
506 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000507 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000508 if (synthetic_index)
509 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510
Greg Claytondea8cb42011-06-29 22:09:02 +0000511 ConstString child_name;
512 if (!child_name_str.empty())
513 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514
Greg Claytondea8cb42011-06-29 22:09:02 +0000515 valobj = new ValueObjectChild (*this,
516 clang_ast,
517 child_clang_type,
518 child_name,
519 child_byte_size,
520 child_byte_offset,
521 child_bitfield_bit_size,
522 child_bitfield_bit_offset,
523 child_is_base_class,
524 child_is_deref_of_parent);
525 if (m_pointers_point_to_load_addrs)
526 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000527 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000528
Jim Ingham58b59f92011-04-22 23:53:53 +0000529 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000530}
531
532const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000533ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000535 if (UpdateValueIfNeeded (m_last_format_mgr_dynamic, true))
Enrico Granata4becb372011-06-29 22:27:15 +0000536 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000537 if (m_summary_str.empty())
538 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000539 SummaryFormat *summary_format = GetSummaryFormat().get();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000540
541 if (summary_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000542 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000543 m_summary_str = summary_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000544 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000545 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000546 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000547 clang_type_t clang_type = GetClangType();
Greg Clayton737b9322010-09-13 03:32:57 +0000548
Enrico Granata9dd75c82011-07-15 23:30:15 +0000549 // Do some default printout for function pointers
Enrico Granataf2bbf712011-07-15 02:26:42 +0000550 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000551 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000552 StreamString sstr;
553 clang_type_t elem_or_pointee_clang_type;
554 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
555 GetClangAST(),
556 &elem_or_pointee_clang_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557
Enrico Granataf2bbf712011-07-15 02:26:42 +0000558 ExecutionContextScope *exe_scope = GetExecutionContextScope();
559 if (exe_scope)
560 {
Enrico Granata9dd75c82011-07-15 23:30:15 +0000561 if (ClangASTContext::IsFunctionPointerType (clang_type))
Jim Ingham6035b672011-03-31 00:19:25 +0000562 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000563 AddressType func_ptr_address_type = eAddressTypeInvalid;
564 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
565
566 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
567 {
568 switch (func_ptr_address_type)
569 {
570 case eAddressTypeInvalid:
571 case eAddressTypeFile:
572 break;
573
574 case eAddressTypeLoad:
575 {
576 Address so_addr;
577 Target *target = exe_scope->CalculateTarget();
578 if (target && target->GetSectionLoadList().IsEmpty() == false)
579 {
580 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
581 {
582 so_addr.Dump (&sstr,
583 exe_scope,
584 Address::DumpStyleResolvedDescription,
585 Address::DumpStyleSectionNameOffset);
586 }
587 }
588 }
589 break;
590
591 case eAddressTypeHost:
592 break;
593 }
594 }
595 if (sstr.GetSize() > 0)
596 {
597 m_summary_str.assign (1, '(');
598 m_summary_str.append (sstr.GetData(), sstr.GetSize());
599 m_summary_str.append (1, ')');
600 }
Jim Ingham6035b672011-03-31 00:19:25 +0000601 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602 }
603 }
604 }
605 }
606 }
607 if (m_summary_str.empty())
608 return NULL;
609 return m_summary_str.c_str();
610}
611
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000612bool
613ValueObject::IsCStringContainer(bool check_pointer)
614{
615 clang_type_t elem_or_pointee_clang_type;
616 const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(),
617 GetClangAST(),
618 &elem_or_pointee_clang_type));
619 bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
620 ClangASTContext::IsCharType (elem_or_pointee_clang_type));
621 if (!is_char_arr_ptr)
622 return false;
623 if (!check_pointer)
624 return true;
625 if (type_flags.Test(ClangASTContext::eTypeIsArray))
626 return true;
627 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
628 AddressType cstr_address_type = eAddressTypeInvalid;
629 cstr_address = GetAddressOf (cstr_address_type, true);
630 return (cstr_address != LLDB_INVALID_ADDRESS);
631}
632
633void
634ValueObject::ReadPointedString(Stream& s,
635 Error& error,
Enrico Granataf4efecd2011-07-12 22:56:10 +0000636 uint32_t max_length,
637 bool honor_array,
638 lldb::Format item_format)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000639{
640
641 if (max_length == 0)
Enrico Granataf4efecd2011-07-12 22:56:10 +0000642 max_length = 128; // FIXME this should be a setting, or a formatting parameter
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000643
644 clang_type_t clang_type = GetClangType();
645 clang_type_t elem_or_pointee_clang_type;
646 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
647 GetClangAST(),
648 &elem_or_pointee_clang_type));
649 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
650 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
651 {
652 ExecutionContextScope *exe_scope = GetExecutionContextScope();
653 if (exe_scope)
654 {
655 Target *target = exe_scope->CalculateTarget();
Enrico Granata6f3533f2011-07-29 19:53:35 +0000656 if (target == NULL)
657 {
658 s << "<no target to read from>";
659 }
660 else
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000661 {
662 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
663 AddressType cstr_address_type = eAddressTypeInvalid;
664
665 size_t cstr_len = 0;
666 bool capped_data = false;
667 if (type_flags.Test (ClangASTContext::eTypeIsArray))
668 {
669 // We have an array
670 cstr_len = ClangASTContext::GetArraySize (clang_type);
Enrico Granataf4efecd2011-07-12 22:56:10 +0000671 if (cstr_len > max_length)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000672 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000673 capped_data = true;
674 cstr_len = max_length;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000675 }
676 cstr_address = GetAddressOf (cstr_address_type, true);
677 }
678 else
679 {
680 // We have a pointer
681 cstr_address = GetPointerValue (cstr_address_type, true);
682 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000683 if (cstr_address == LLDB_INVALID_ADDRESS)
684 {
685 s << "<invalid address for data>";
686 }
687 else
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000688 {
689 Address cstr_so_addr (NULL, cstr_address);
690 DataExtractor data;
691 size_t bytes_read = 0;
692 std::vector<char> data_buffer;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000693 bool prefer_file_cache = false;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000694 if (cstr_len > 0 && honor_array)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000695 {
696 data_buffer.resize(cstr_len);
697 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
698 bytes_read = target->ReadMemory (cstr_so_addr,
699 prefer_file_cache,
700 &data_buffer.front(),
701 cstr_len,
702 error);
703 if (bytes_read > 0)
704 {
705 s << '"';
706 data.Dump (&s,
707 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000708 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000709 1, // Size of item (1 byte for a char!)
710 bytes_read, // How many bytes to print?
711 UINT32_MAX, // num per line
712 LLDB_INVALID_ADDRESS,// base address
713 0, // bitfield bit size
714 0); // bitfield bit offset
715 if (capped_data)
716 s << "...";
717 s << '"';
718 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000719 else
720 s << "\"<data not available>\"";
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000721 }
722 else
723 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000724 cstr_len = max_length;
725 const size_t k_max_buf_size = 64;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000726 data_buffer.resize (k_max_buf_size + 1);
727 // NULL terminate in case we don't get the entire C string
728 data_buffer.back() = '\0';
729
730 s << '"';
731
Enrico Granata6f3533f2011-07-29 19:53:35 +0000732 bool any_data = false;
733
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000734 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
735 while ((bytes_read = target->ReadMemory (cstr_so_addr,
736 prefer_file_cache,
737 &data_buffer.front(),
738 k_max_buf_size,
739 error)) > 0)
740 {
Enrico Granata6f3533f2011-07-29 19:53:35 +0000741 any_data = true;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000742 size_t len = strlen(&data_buffer.front());
743 if (len == 0)
744 break;
745 if (len > bytes_read)
746 len = bytes_read;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000747 if (len > cstr_len)
748 len = cstr_len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000749
750 data.Dump (&s,
751 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000752 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000753 1, // Size of item (1 byte for a char!)
754 len, // How many bytes to print?
755 UINT32_MAX, // num per line
756 LLDB_INVALID_ADDRESS,// base address
757 0, // bitfield bit size
758 0); // bitfield bit offset
759
760 if (len < k_max_buf_size)
761 break;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000762 if (len >= cstr_len)
763 {
764 s << "...";
765 break;
766 }
767 cstr_len -= len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000768 cstr_so_addr.Slide (k_max_buf_size);
769 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000770
771 if (any_data == false)
772 s << "<data not available>";
773
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000774 s << '"';
775 }
776 }
777 }
778 }
779 }
780 else
781 {
782 error.SetErrorString("impossible to read a string from this object");
Enrico Granata6f3533f2011-07-29 19:53:35 +0000783 s << "<not a string object>";
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000784 }
785}
786
Jim Ingham53c47f12010-09-10 23:12:17 +0000787const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000788ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000789{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000790
Enrico Granatac3e320a2011-08-02 17:27:39 +0000791 if (!UpdateValueIfNeeded (m_last_format_mgr_dynamic, true))
Jim Ingham53c47f12010-09-10 23:12:17 +0000792 return NULL;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000793
794 if (!m_object_desc_str.empty())
795 return m_object_desc_str.c_str();
796
Jim Ingham6035b672011-03-31 00:19:25 +0000797 ExecutionContextScope *exe_scope = GetExecutionContextScope();
798 if (exe_scope == NULL)
799 return NULL;
800
Jim Ingham53c47f12010-09-10 23:12:17 +0000801 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000802 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000803 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000804
Jim Ingham53c47f12010-09-10 23:12:17 +0000805 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000806
807 lldb::LanguageType language = GetObjectRuntimeLanguage();
808 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
809
Jim Inghama2cf2632010-12-23 02:29:54 +0000810 if (runtime == NULL)
811 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000812 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000813 clang_type_t opaque_qual_type = GetClangType();
814 if (opaque_qual_type != NULL)
815 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000816 bool is_signed;
817 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
818 || ClangASTContext::IsPointerType (opaque_qual_type))
819 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000820 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000821 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000822 }
823 }
824
Jim Ingham8d543de2011-03-31 23:01:21 +0000825 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000826 {
827 m_object_desc_str.append (s.GetData());
828 }
Sean Callanan672ad942010-10-23 00:18:49 +0000829
830 if (m_object_desc_str.empty())
831 return NULL;
832 else
833 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000834}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000835
836const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000837ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000838{
839 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000840 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000841 {
Enrico Granatac3e320a2011-08-02 17:27:39 +0000842 if (UpdateValueIfNeeded(true))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000843 {
844 if (m_value_str.empty())
845 {
846 const Value::ContextType context_type = m_value.GetContextType();
847
848 switch (context_type)
849 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000850 case Value::eContextTypeClangType:
851 case Value::eContextTypeLLDBType:
852 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000854 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000855 if (clang_type)
856 {
Enrico Granatac3e320a2011-08-02 17:27:39 +0000857 if (m_format == lldb::eFormatDefault && m_last_value_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000858 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000859 m_value_str = m_last_value_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000860 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000861 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000862 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000863 StreamString sstr;
864 Format format = GetFormat();
865 if (format == eFormatDefault)
866 format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
867 ClangASTType::GetFormat(clang_type));
868
869 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
870 clang_type, // The clang type to display
871 &sstr,
872 format, // Format to display this type with
873 m_data, // Data to extract from
874 0, // Byte offset into "m_data"
875 GetByteSize(), // Byte size of item in "m_data"
876 GetBitfieldBitSize(), // Bitfield bit size
877 GetBitfieldBitOffset())) // Bitfield bit offset
878 m_value_str.swap(sstr.GetString());
879 else
880 {
881 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
882 m_data.GetByteSize(),
883 GetByteSize());
884 m_value_str.clear();
885 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000886 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000887 }
888 }
889 break;
890
Greg Clayton526e5af2010-11-13 03:52:47 +0000891 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892 {
893 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
894 if (reg_info)
895 {
896 StreamString reg_sstr;
897 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
898 m_value_str.swap(reg_sstr.GetString());
899 }
900 }
901 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000902
903 default:
904 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000905 }
906 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000907
908 if (!m_value_did_change && m_old_value_valid)
909 {
910 // The value was gotten successfully, so we consider the
911 // value as changed if the value string differs
912 SetValueDidChange (m_old_value_str != m_value_str);
913 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000914 }
915 }
916 if (m_value_str.empty())
917 return NULL;
918 return m_value_str.c_str();
919}
920
Enrico Granatac3e320a2011-08-02 17:27:39 +0000921// if > 8bytes, 0 is returned. this method should mostly be used
922// to read address values out of pointers
923unsigned long long
924ValueObject::GetValueAsUnsigned()
925{
926 // If our byte size is zero this is an aggregate type that has children
927 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
928 {
929 if (UpdateValueIfNeeded(true))
930 {
931 uint32_t offset = 0;
932 return m_data.GetMaxU64(&offset,
933 m_data.GetByteSize());
934 }
935 }
936 return 0;
937}
938
Enrico Granatae992a082011-07-22 17:03:19 +0000939// this call should only return pointers to data that needs no special memory management
940// (either because they are hardcoded strings, or because they are backed by some other
941// object); returning any new()-ed or malloc()-ed data here, will lead to leaks!
Enrico Granata0a3958e2011-07-02 00:25:22 +0000942const char *
943ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
944 lldb::Format custom_format)
945{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000946
947 RefCounter ref(&m_dump_printable_counter);
948
Enrico Granata9dd75c82011-07-15 23:30:15 +0000949 if (custom_format != lldb::eFormatInvalid)
Enrico Granata0a3958e2011-07-02 00:25:22 +0000950 SetFormat(custom_format);
951
952 const char * return_value;
953
954 switch(val_obj_display)
955 {
956 case eDisplayValue:
957 return_value = GetValueAsCString();
958 break;
959 case eDisplaySummary:
960 return_value = GetSummaryAsCString();
961 break;
962 case eDisplayLanguageSpecific:
963 return_value = GetObjectDescription();
964 break;
Enrico Granataf2bbf712011-07-15 02:26:42 +0000965 case eDisplayLocation:
966 return_value = GetLocationAsCString();
967 break;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000968 }
969
Enrico Granataf4efecd2011-07-12 22:56:10 +0000970 // this code snippet might lead to endless recursion, thus we use a RefCounter here to
971 // check that we are not looping endlessly
972 if (!return_value && (m_dump_printable_counter < 3))
Enrico Granata9fc19442011-07-06 02:13:41 +0000973 {
974 // try to pick the other choice
975 if (val_obj_display == eDisplayValue)
976 return_value = GetSummaryAsCString();
977 else if (val_obj_display == eDisplaySummary)
Enrico Granatae992a082011-07-22 17:03:19 +0000978 {
979 if (ClangASTContext::IsAggregateType (GetClangType()) == true)
980 {
981 // this thing has no value
982 return_value = "<no summary defined for this datatype>";
983 }
984 else
985 return_value = GetValueAsCString();
986 }
Enrico Granata9fc19442011-07-06 02:13:41 +0000987 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000988
Enrico Granatae992a082011-07-22 17:03:19 +0000989 return (return_value ? return_value : "<no printable representation>");
Enrico Granata0a3958e2011-07-02 00:25:22 +0000990
991}
992
Enrico Granata9fc19442011-07-06 02:13:41 +0000993bool
994ValueObject::DumpPrintableRepresentation(Stream& s,
995 ValueObjectRepresentationStyle val_obj_display,
996 lldb::Format custom_format)
997{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000998
999 clang_type_t elem_or_pointee_type;
1000 Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001001
Enrico Granataf4efecd2011-07-12 22:56:10 +00001002 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
1003 && val_obj_display == ValueObject::eDisplayValue)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001004 {
Enrico Granataf4efecd2011-07-12 22:56:10 +00001005 // when being asked to get a printable display an array or pointer type directly,
1006 // try to "do the right thing"
1007
1008 if (IsCStringContainer(true) &&
1009 (custom_format == lldb::eFormatCString ||
1010 custom_format == lldb::eFormatCharArray ||
1011 custom_format == lldb::eFormatChar ||
1012 custom_format == lldb::eFormatVectorOfChar)) // print char[] & char* directly
1013 {
1014 Error error;
1015 ReadPointedString(s,
1016 error,
1017 0,
1018 (custom_format == lldb::eFormatVectorOfChar) ||
1019 (custom_format == lldb::eFormatCharArray));
1020 return !error.Fail();
1021 }
1022
1023 if (custom_format == lldb::eFormatEnum)
1024 return false;
1025
1026 // this only works for arrays, because I have no way to know when
1027 // the pointed memory ends, and no special \0 end of data marker
1028 if (flags.Test(ClangASTContext::eTypeIsArray))
1029 {
1030 if ((custom_format == lldb::eFormatBytes) ||
1031 (custom_format == lldb::eFormatBytesWithASCII))
1032 {
1033 uint32_t count = GetNumChildren();
1034
1035 s << '[';
1036 for (uint32_t low = 0; low < count; low++)
1037 {
1038
1039 if (low)
1040 s << ',';
1041
1042 ValueObjectSP child = GetChildAtIndex(low,true);
1043 if (!child.get())
1044 {
Enrico Granatae992a082011-07-22 17:03:19 +00001045 s << "<invalid child>";
Enrico Granataf4efecd2011-07-12 22:56:10 +00001046 continue;
1047 }
1048 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format);
1049 }
1050
1051 s << ']';
1052
1053 return true;
1054 }
1055
1056 if ((custom_format == lldb::eFormatVectorOfChar) ||
1057 (custom_format == lldb::eFormatVectorOfFloat32) ||
1058 (custom_format == lldb::eFormatVectorOfFloat64) ||
1059 (custom_format == lldb::eFormatVectorOfSInt16) ||
1060 (custom_format == lldb::eFormatVectorOfSInt32) ||
1061 (custom_format == lldb::eFormatVectorOfSInt64) ||
1062 (custom_format == lldb::eFormatVectorOfSInt8) ||
1063 (custom_format == lldb::eFormatVectorOfUInt128) ||
1064 (custom_format == lldb::eFormatVectorOfUInt16) ||
1065 (custom_format == lldb::eFormatVectorOfUInt32) ||
1066 (custom_format == lldb::eFormatVectorOfUInt64) ||
1067 (custom_format == lldb::eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
1068 {
1069 uint32_t count = GetNumChildren();
1070
1071 lldb::Format format = FormatManager::GetSingleItemFormat(custom_format);
1072
1073 s << '[';
1074 for (uint32_t low = 0; low < count; low++)
1075 {
1076
1077 if (low)
1078 s << ',';
1079
1080 ValueObjectSP child = GetChildAtIndex(low,true);
1081 if (!child.get())
1082 {
Enrico Granatae992a082011-07-22 17:03:19 +00001083 s << "<invalid child>";
Enrico Granataf4efecd2011-07-12 22:56:10 +00001084 continue;
1085 }
1086 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format);
1087 }
1088
1089 s << ']';
1090
1091 return true;
1092 }
1093 }
1094
1095 if ((custom_format == lldb::eFormatBoolean) ||
1096 (custom_format == lldb::eFormatBinary) ||
1097 (custom_format == lldb::eFormatChar) ||
1098 (custom_format == lldb::eFormatCharPrintable) ||
1099 (custom_format == lldb::eFormatComplexFloat) ||
1100 (custom_format == lldb::eFormatDecimal) ||
1101 (custom_format == lldb::eFormatHex) ||
1102 (custom_format == lldb::eFormatFloat) ||
1103 (custom_format == lldb::eFormatOctal) ||
1104 (custom_format == lldb::eFormatOSType) ||
1105 (custom_format == lldb::eFormatUnicode16) ||
1106 (custom_format == lldb::eFormatUnicode32) ||
1107 (custom_format == lldb::eFormatUnsigned) ||
1108 (custom_format == lldb::eFormatPointer) ||
1109 (custom_format == lldb::eFormatComplexInteger) ||
1110 (custom_format == lldb::eFormatComplex) ||
1111 (custom_format == lldb::eFormatDefault)) // use the [] operator
1112 return false;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001113 }
Enrico Granataf4efecd2011-07-12 22:56:10 +00001114 const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
Enrico Granata9dd75c82011-07-15 23:30:15 +00001115 if (targetvalue)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001116 s.PutCString(targetvalue);
1117 bool var_success = (targetvalue != NULL);
Enrico Granata9dd75c82011-07-15 23:30:15 +00001118 if (custom_format != eFormatInvalid)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001119 SetFormat(eFormatDefault);
1120 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001121}
1122
Greg Clayton737b9322010-09-13 03:32:57 +00001123addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001124ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +00001125{
Enrico Granatac3e320a2011-08-02 17:27:39 +00001126 if (!UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +00001127 return LLDB_INVALID_ADDRESS;
1128
Greg Clayton73b472d2010-10-27 03:32:59 +00001129 switch (m_value.GetValueType())
1130 {
1131 case Value::eValueTypeScalar:
1132 if (scalar_is_load_address)
1133 {
1134 address_type = eAddressTypeLoad;
1135 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1136 }
1137 break;
1138
1139 case Value::eValueTypeLoadAddress:
1140 case Value::eValueTypeFileAddress:
1141 case Value::eValueTypeHostAddress:
1142 {
1143 address_type = m_value.GetValueAddressType ();
1144 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1145 }
1146 break;
1147 }
1148 address_type = eAddressTypeInvalid;
1149 return LLDB_INVALID_ADDRESS;
1150}
1151
1152addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001153ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +00001154{
1155 lldb::addr_t address = LLDB_INVALID_ADDRESS;
1156 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +00001157
Enrico Granatac3e320a2011-08-02 17:27:39 +00001158 if (!UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +00001159 return address;
1160
Greg Clayton73b472d2010-10-27 03:32:59 +00001161 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +00001162 {
1163 case Value::eValueTypeScalar:
1164 if (scalar_is_load_address)
1165 {
1166 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1167 address_type = eAddressTypeLoad;
1168 }
1169 break;
1170
1171 case Value::eValueTypeLoadAddress:
1172 case Value::eValueTypeFileAddress:
1173 case Value::eValueTypeHostAddress:
1174 {
1175 uint32_t data_offset = 0;
1176 address = m_data.GetPointer(&data_offset);
1177 address_type = m_value.GetValueAddressType();
1178 if (address_type == eAddressTypeInvalid)
1179 address_type = eAddressTypeLoad;
1180 }
1181 break;
1182 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001183
1184 if (m_pointers_point_to_load_addrs)
1185 address_type = eAddressTypeLoad;
1186
Greg Clayton737b9322010-09-13 03:32:57 +00001187 return address;
1188}
1189
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001190bool
Jim Ingham6035b672011-03-31 00:19:25 +00001191ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192{
1193 // Make sure our value is up to date first so that our location and location
1194 // type is valid.
Enrico Granatac3e320a2011-08-02 17:27:39 +00001195 if (!UpdateValueIfNeeded(false))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001196 return false;
1197
1198 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001199 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001200
1201 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +00001202 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001203 switch (encoding)
1204 {
1205 case eEncodingInvalid:
1206 return false;
1207
1208 case eEncodingUint:
1209 if (byte_size > sizeof(unsigned long long))
1210 {
1211 return false;
1212 }
1213 else
1214 {
1215 unsigned long long ull_val = strtoull(value_str, &end, 0);
1216 if (end && *end != '\0')
1217 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001218 m_value.GetScalar() = ull_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001219 // Limit the bytes in our m_data appropriately.
1220 m_value.GetScalar().GetData (m_data, byte_size);
1221 }
1222 break;
1223
1224 case eEncodingSint:
1225 if (byte_size > sizeof(long long))
1226 {
1227 return false;
1228 }
1229 else
1230 {
1231 long long sll_val = strtoll(value_str, &end, 0);
1232 if (end && *end != '\0')
1233 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001234 m_value.GetScalar() = sll_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001235 // Limit the bytes in our m_data appropriately.
1236 m_value.GetScalar().GetData (m_data, byte_size);
1237 }
1238 break;
1239
1240 case eEncodingIEEE754:
1241 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001242 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +00001243 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001244 if (dst != NULL)
1245 {
1246 // We are decoding a float into host byte order below, so make
1247 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +00001248 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001249 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
1250 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +00001251 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001252 value_str,
1253 dst,
1254 byte_size);
1255
1256 if (converted_byte_size == byte_size)
1257 {
1258 }
1259 }
1260 }
1261 break;
1262
1263 case eEncodingVector:
1264 return false;
1265
1266 default:
1267 return false;
1268 }
1269
1270 // If we have made it here the value is in m_data and we should write it
1271 // out to the target
1272 return Write ();
1273}
1274
1275bool
1276ValueObject::Write ()
1277{
1278 // Clear the update ID so the next time we try and read the value
1279 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +00001280 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001281
1282 // TODO: when Value has a method to write a value back, call it from here.
1283 return false;
1284
1285}
1286
Jim Ingham5a369122010-09-28 01:25:32 +00001287lldb::LanguageType
1288ValueObject::GetObjectRuntimeLanguage ()
1289{
Enrico Granatac3e320a2011-08-02 17:27:39 +00001290 return ClangASTType::GetMinimumLanguage (GetClangAST(),
1291 GetClangType());
Jim Ingham5a369122010-09-28 01:25:32 +00001292}
1293
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001294void
Jim Ingham58b59f92011-04-22 23:53:53 +00001295ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296{
Jim Ingham58b59f92011-04-22 23:53:53 +00001297 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001298}
1299
1300ValueObjectSP
1301ValueObject::GetSyntheticChild (const ConstString &key) const
1302{
1303 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +00001304 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001305 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +00001306 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001307 return synthetic_child_sp;
1308}
1309
1310bool
1311ValueObject::IsPointerType ()
1312{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001313 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001314}
1315
Jim Inghamb7603bb2011-03-18 00:05:18 +00001316bool
Greg Claytondaf515f2011-07-09 20:12:33 +00001317ValueObject::IsArrayType ()
1318{
1319 return ClangASTContext::IsArrayType (GetClangType());
1320}
1321
1322bool
Enrico Granata9fc19442011-07-06 02:13:41 +00001323ValueObject::IsScalarType ()
1324{
1325 return ClangASTContext::IsScalarType (GetClangType());
1326}
1327
1328bool
Jim Inghamb7603bb2011-03-18 00:05:18 +00001329ValueObject::IsIntegerType (bool &is_signed)
1330{
1331 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
1332}
Greg Clayton73b472d2010-10-27 03:32:59 +00001333
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001334bool
1335ValueObject::IsPointerOrReferenceType ()
1336{
Greg Clayton007d5be2011-05-30 00:49:24 +00001337 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
1338}
1339
1340bool
1341ValueObject::IsPossibleCPlusPlusDynamicType ()
1342{
1343 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001344}
1345
Greg Claytondea8cb42011-06-29 22:09:02 +00001346bool
1347ValueObject::IsPossibleDynamicType ()
1348{
1349 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
1350}
1351
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001352ValueObjectSP
1353ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
1354{
1355 ValueObjectSP synthetic_child_sp;
1356 if (IsPointerType ())
1357 {
1358 char index_str[64];
1359 snprintf(index_str, sizeof(index_str), "[%i]", index);
1360 ConstString index_const_str(index_str);
1361 // Check if we have already created a synthetic array member in this
1362 // valid object. If we have we will re-use it.
1363 synthetic_child_sp = GetSyntheticChild (index_const_str);
1364 if (!synthetic_child_sp)
1365 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001366 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001367 // We haven't made a synthetic array member for INDEX yet, so
1368 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001369 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001370
1371 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001372 if (synthetic_child)
1373 {
1374 AddSyntheticChild(index_const_str, synthetic_child);
1375 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001376 synthetic_child_sp->SetName(ConstString(index_str));
Enrico Granata0a3958e2011-07-02 00:25:22 +00001377 synthetic_child_sp->m_is_array_item_for_pointer = true;
Jim Ingham58b59f92011-04-22 23:53:53 +00001378 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001379 }
1380 }
1381 return synthetic_child_sp;
1382}
Jim Ingham22777012010-09-23 02:01:19 +00001383
Greg Claytondaf515f2011-07-09 20:12:33 +00001384// This allows you to create an array member using and index
1385// that doesn't not fall in the normal bounds of the array.
1386// Many times structure can be defined as:
1387// struct Collection
1388// {
1389// uint32_t item_count;
1390// Item item_array[0];
1391// };
1392// The size of the "item_array" is 1, but many times in practice
1393// there are more items in "item_array".
1394
1395ValueObjectSP
1396ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create)
1397{
1398 ValueObjectSP synthetic_child_sp;
1399 if (IsArrayType ())
1400 {
1401 char index_str[64];
1402 snprintf(index_str, sizeof(index_str), "[%i]", index);
1403 ConstString index_const_str(index_str);
1404 // Check if we have already created a synthetic array member in this
1405 // valid object. If we have we will re-use it.
1406 synthetic_child_sp = GetSyntheticChild (index_const_str);
1407 if (!synthetic_child_sp)
1408 {
1409 ValueObject *synthetic_child;
1410 // We haven't made a synthetic array member for INDEX yet, so
1411 // lets make one and cache it for any future reference.
1412 synthetic_child = CreateChildAtIndex(0, true, index);
1413
1414 // Cache the value if we got one back...
1415 if (synthetic_child)
1416 {
1417 AddSyntheticChild(index_const_str, synthetic_child);
1418 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001419 synthetic_child_sp->SetName(ConstString(index_str));
Greg Claytondaf515f2011-07-09 20:12:33 +00001420 synthetic_child_sp->m_is_array_item_for_pointer = true;
1421 }
1422 }
1423 }
1424 return synthetic_child_sp;
1425}
1426
Enrico Granata9fc19442011-07-06 02:13:41 +00001427ValueObjectSP
1428ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
1429{
1430 ValueObjectSP synthetic_child_sp;
1431 if (IsScalarType ())
1432 {
1433 char index_str[64];
1434 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1435 ConstString index_const_str(index_str);
1436 // Check if we have already created a synthetic array member in this
1437 // valid object. If we have we will re-use it.
1438 synthetic_child_sp = GetSyntheticChild (index_const_str);
1439 if (!synthetic_child_sp)
1440 {
1441 ValueObjectChild *synthetic_child;
1442 // We haven't made a synthetic array member for INDEX yet, so
1443 // lets make one and cache it for any future reference.
1444 synthetic_child = new ValueObjectChild(*this,
1445 GetClangAST(),
1446 GetClangType(),
1447 index_const_str,
1448 GetByteSize(),
1449 0,
1450 to-from+1,
1451 from,
1452 false,
1453 false);
1454
1455 // Cache the value if we got one back...
1456 if (synthetic_child)
1457 {
1458 AddSyntheticChild(index_const_str, synthetic_child);
1459 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001460 synthetic_child_sp->SetName(ConstString(index_str));
Enrico Granata9fc19442011-07-06 02:13:41 +00001461 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1462 }
1463 }
1464 }
1465 return synthetic_child_sp;
1466}
1467
Enrico Granata6f3533f2011-07-29 19:53:35 +00001468lldb::ValueObjectSP
1469ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
1470{
1471
1472 ValueObjectSP synthetic_child_sp;
1473
1474 char name_str[64];
1475 snprintf(name_str, sizeof(name_str), "@%i", offset);
1476 ConstString name_const_str(name_str);
1477
1478 // Check if we have already created a synthetic array member in this
1479 // valid object. If we have we will re-use it.
1480 synthetic_child_sp = GetSyntheticChild (name_const_str);
1481
1482 if (synthetic_child_sp.get())
1483 return synthetic_child_sp;
1484
1485 if (!can_create)
1486 return lldb::ValueObjectSP();
1487
1488 ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
1489 type.GetASTContext(),
1490 type.GetOpaqueQualType(),
1491 name_const_str,
1492 type.GetTypeByteSize(),
1493 offset,
1494 0,
1495 0,
1496 false,
1497 false);
1498 if (synthetic_child)
1499 {
1500 AddSyntheticChild(name_const_str, synthetic_child);
1501 synthetic_child_sp = synthetic_child->GetSP();
1502 synthetic_child_sp->SetName(name_const_str);
1503 synthetic_child_sp->m_is_child_at_offset = true;
1504 }
1505 return synthetic_child_sp;
1506}
1507
Enrico Granatad55546b2011-07-22 00:16:08 +00001508// your expression path needs to have a leading . or ->
1509// (unless it somehow "looks like" an array, in which case it has
1510// a leading [ symbol). while the [ is meaningful and should be shown
1511// to the user, . and -> are just parser design, but by no means
1512// added information for the user.. strip them off
1513static const char*
1514SkipLeadingExpressionPathSeparators(const char* expression)
1515{
1516 if (!expression || !expression[0])
1517 return expression;
1518 if (expression[0] == '.')
1519 return expression+1;
1520 if (expression[0] == '-' && expression[1] == '>')
1521 return expression+2;
1522 return expression;
1523}
1524
1525lldb::ValueObjectSP
1526ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_create)
1527{
1528 ValueObjectSP synthetic_child_sp;
1529 ConstString name_const_string(expression);
1530 // Check if we have already created a synthetic array member in this
1531 // valid object. If we have we will re-use it.
1532 synthetic_child_sp = GetSyntheticChild (name_const_string);
1533 if (!synthetic_child_sp)
1534 {
1535 // We haven't made a synthetic array member for expression yet, so
1536 // lets make one and cache it for any future reference.
1537 synthetic_child_sp = GetValueForExpressionPath(expression);
1538
1539 // Cache the value if we got one back...
1540 if (synthetic_child_sp.get())
1541 {
1542 AddSyntheticChild(name_const_string, synthetic_child_sp.get());
Enrico Granata6f3533f2011-07-29 19:53:35 +00001543 synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression)));
Enrico Granatad55546b2011-07-22 00:16:08 +00001544 synthetic_child_sp->m_is_expression_path_child = true;
1545 }
1546 }
1547 return synthetic_child_sp;
1548}
1549
1550void
1551ValueObject::CalculateSyntheticValue (lldb::SyntheticValueType use_synthetic)
1552{
1553 if (use_synthetic == lldb::eNoSyntheticFilter)
1554 return;
1555
Enrico Granatac3e320a2011-08-02 17:27:39 +00001556 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
Enrico Granatad55546b2011-07-22 00:16:08 +00001557
1558 if (m_last_synthetic_filter.get() == NULL)
1559 return;
1560
Enrico Granataa37a0652011-07-24 00:14:56 +00001561 if (m_synthetic_value == NULL)
1562 m_synthetic_value = new ValueObjectSynthetic(*this, m_last_synthetic_filter);
Enrico Granatad55546b2011-07-22 00:16:08 +00001563
1564}
1565
Jim Ingham78a685a2011-04-16 00:01:13 +00001566void
Jim Ingham2837b762011-05-04 03:43:18 +00001567ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001568{
Jim Ingham2837b762011-05-04 03:43:18 +00001569 if (use_dynamic == lldb::eNoDynamicValues)
1570 return;
1571
Jim Ingham58b59f92011-04-22 23:53:53 +00001572 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001573 {
Enrico Granata6f3533f2011-07-29 19:53:35 +00001574 Process *process = m_update_point.GetProcessSP().get();
Jim Ingham78a685a2011-04-16 00:01:13 +00001575 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001576
Jim Ingham78a685a2011-04-16 00:01:13 +00001577
1578 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1579 // hard code this everywhere.
1580 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1581 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1582 {
1583 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1584 if (runtime)
1585 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1586 }
1587 else
1588 {
1589 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1590 if (cpp_runtime)
1591 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1592
1593 if (!worth_having_dynamic_value)
1594 {
1595 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1596 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001597 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001598 }
1599 }
1600
1601 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001602 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001603
1604// if (worth_having_dynamic_value)
1605// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1606
Jim Ingham78a685a2011-04-16 00:01:13 +00001607 }
1608}
1609
Jim Ingham58b59f92011-04-22 23:53:53 +00001610ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001611ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001612{
Jim Ingham2837b762011-05-04 03:43:18 +00001613 if (use_dynamic == lldb::eNoDynamicValues)
1614 return ValueObjectSP();
1615
1616 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001617 {
Jim Ingham2837b762011-05-04 03:43:18 +00001618 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001619 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001620 if (m_dynamic_value)
1621 return m_dynamic_value->GetSP();
1622 else
1623 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001624}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001625
Enrico Granatad55546b2011-07-22 00:16:08 +00001626// GetDynamicValue() returns a NULL SharedPointer if the object is not dynamic
1627// or we do not really want a dynamic VO. this method instead returns this object
1628// itself when making it synthetic has no meaning. this makes it much simpler
1629// to replace the SyntheticValue for the ValueObject
1630ValueObjectSP
1631ValueObject::GetSyntheticValue (SyntheticValueType use_synthetic)
1632{
1633 if (use_synthetic == lldb::eNoSyntheticFilter)
1634 return GetSP();
1635
Enrico Granatac3e320a2011-08-02 17:27:39 +00001636 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
Enrico Granatad55546b2011-07-22 00:16:08 +00001637
1638 if (m_last_synthetic_filter.get() == NULL)
1639 return GetSP();
1640
1641 CalculateSyntheticValue(use_synthetic);
1642
1643 if (m_synthetic_value)
1644 return m_synthetic_value->GetSP();
1645 else
1646 return GetSP();
1647}
1648
Greg Claytone221f822011-01-21 01:59:00 +00001649bool
1650ValueObject::GetBaseClassPath (Stream &s)
1651{
1652 if (IsBaseClass())
1653 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001654 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001655 clang_type_t clang_type = GetClangType();
1656 std::string cxx_class_name;
1657 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1658 if (this_had_base_class)
1659 {
1660 if (parent_had_base_class)
1661 s.PutCString("::");
1662 s.PutCString(cxx_class_name.c_str());
1663 }
1664 return parent_had_base_class || this_had_base_class;
1665 }
1666 return false;
1667}
1668
1669
1670ValueObject *
1671ValueObject::GetNonBaseClassParent()
1672{
Jim Ingham78a685a2011-04-16 00:01:13 +00001673 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001674 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001675 if (GetParent()->IsBaseClass())
1676 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001677 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001678 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001679 }
1680 return NULL;
1681}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001682
1683void
Enrico Granata4becb372011-06-29 22:27:15 +00001684ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001685{
Greg Claytone221f822011-01-21 01:59:00 +00001686 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00001687
Enrico Granata9dd75c82011-07-15 23:30:15 +00001688 if (is_deref_of_parent && epformat == eDereferencePointers) {
Enrico Granata4becb372011-06-29 22:27:15 +00001689 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
1690 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
1691 // the eHonorPointers mode is meant to produce strings in this latter format
1692 s.PutCString("*(");
1693 }
Greg Claytone221f822011-01-21 01:59:00 +00001694
Enrico Granata4becb372011-06-29 22:27:15 +00001695 ValueObject* parent = GetParent();
1696
1697 if (parent)
1698 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
Enrico Granata0a3958e2011-07-02 00:25:22 +00001699
1700 // if we are a deref_of_parent just because we are synthetic array
1701 // members made up to allow ptr[%d] syntax to work in variable
1702 // printing, then add our name ([%d]) to the expression path
Enrico Granata9dd75c82011-07-15 23:30:15 +00001703 if (m_is_array_item_for_pointer && epformat == eHonorPointers)
Enrico Granata0a3958e2011-07-02 00:25:22 +00001704 s.PutCString(m_name.AsCString());
Enrico Granata4becb372011-06-29 22:27:15 +00001705
Greg Claytone221f822011-01-21 01:59:00 +00001706 if (!IsBaseClass())
1707 {
1708 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001709 {
Greg Claytone221f822011-01-21 01:59:00 +00001710 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1711 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001712 {
Greg Claytone221f822011-01-21 01:59:00 +00001713 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1714 if (non_base_class_parent_clang_type)
1715 {
1716 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1717
Enrico Granata9dd75c82011-07-15 23:30:15 +00001718 if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00001719 {
1720 s.PutCString("->");
1721 }
Enrico Granata4becb372011-06-29 22:27:15 +00001722 else
1723 {
1724 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1725 {
1726 s.PutCString("->");
1727 }
1728 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1729 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1730 {
1731 s.PutChar('.');
1732 }
Greg Claytone221f822011-01-21 01:59:00 +00001733 }
1734 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001735 }
Greg Claytone221f822011-01-21 01:59:00 +00001736
1737 const char *name = GetName().GetCString();
1738 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001739 {
Greg Claytone221f822011-01-21 01:59:00 +00001740 if (qualify_cxx_base_classes)
1741 {
1742 if (GetBaseClassPath (s))
1743 s.PutCString("::");
1744 }
1745 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001746 }
1747 }
1748 }
1749
Enrico Granata4becb372011-06-29 22:27:15 +00001750 if (is_deref_of_parent && epformat == eDereferencePointers) {
Greg Claytone221f822011-01-21 01:59:00 +00001751 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00001752 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001753}
1754
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001755lldb::ValueObjectSP
1756ValueObject::GetValueForExpressionPath(const char* expression,
1757 const char** first_unparsed,
1758 ExpressionPathScanEndReason* reason_to_stop,
1759 ExpressionPathEndResultType* final_value_type,
1760 const GetValueForExpressionPathOptions& options,
1761 ExpressionPathAftermath* final_task_on_target)
1762{
1763
1764 const char* dummy_first_unparsed;
1765 ExpressionPathScanEndReason dummy_reason_to_stop;
1766 ExpressionPathEndResultType dummy_final_value_type;
1767 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1768
1769 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1770 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1771 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1772 final_value_type ? final_value_type : &dummy_final_value_type,
1773 options,
1774 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1775
1776 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1777 {
1778 return ret_val;
1779 }
1780 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1781 {
1782 if (*final_task_on_target == ValueObject::eDereference)
1783 {
1784 Error error;
1785 ValueObjectSP final_value = ret_val->Dereference(error);
1786 if (error.Fail() || !final_value.get())
1787 {
1788 *reason_to_stop = ValueObject::eDereferencingFailed;
1789 *final_value_type = ValueObject::eInvalid;
1790 return ValueObjectSP();
1791 }
1792 else
1793 {
1794 *final_task_on_target = ValueObject::eNothing;
1795 return final_value;
1796 }
1797 }
1798 if (*final_task_on_target == ValueObject::eTakeAddress)
1799 {
1800 Error error;
1801 ValueObjectSP final_value = ret_val->AddressOf(error);
1802 if (error.Fail() || !final_value.get())
1803 {
1804 *reason_to_stop = ValueObject::eTakingAddressFailed;
1805 *final_value_type = ValueObject::eInvalid;
1806 return ValueObjectSP();
1807 }
1808 else
1809 {
1810 *final_task_on_target = ValueObject::eNothing;
1811 return final_value;
1812 }
1813 }
1814 }
1815 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
1816}
1817
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001818int
1819ValueObject::GetValuesForExpressionPath(const char* expression,
1820 lldb::ValueObjectListSP& list,
1821 const char** first_unparsed,
1822 ExpressionPathScanEndReason* reason_to_stop,
1823 ExpressionPathEndResultType* final_value_type,
1824 const GetValueForExpressionPathOptions& options,
1825 ExpressionPathAftermath* final_task_on_target)
1826{
1827 const char* dummy_first_unparsed;
1828 ExpressionPathScanEndReason dummy_reason_to_stop;
1829 ExpressionPathEndResultType dummy_final_value_type;
1830 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1831
1832 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1833 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1834 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1835 final_value_type ? final_value_type : &dummy_final_value_type,
1836 options,
1837 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1838
1839 if (!ret_val.get()) // if there are errors, I add nothing to the list
1840 return 0;
1841
1842 if (*reason_to_stop != eArrayRangeOperatorMet)
1843 {
1844 // I need not expand a range, just post-process the final value and return
1845 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1846 {
1847 list->Append(ret_val);
1848 return 1;
1849 }
1850 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1851 {
1852 if (*final_task_on_target == ValueObject::eDereference)
1853 {
1854 Error error;
1855 ValueObjectSP final_value = ret_val->Dereference(error);
1856 if (error.Fail() || !final_value.get())
1857 {
1858 *reason_to_stop = ValueObject::eDereferencingFailed;
1859 *final_value_type = ValueObject::eInvalid;
1860 return 0;
1861 }
1862 else
1863 {
1864 *final_task_on_target = ValueObject::eNothing;
1865 list->Append(final_value);
1866 return 1;
1867 }
1868 }
1869 if (*final_task_on_target == ValueObject::eTakeAddress)
1870 {
1871 Error error;
1872 ValueObjectSP final_value = ret_val->AddressOf(error);
1873 if (error.Fail() || !final_value.get())
1874 {
1875 *reason_to_stop = ValueObject::eTakingAddressFailed;
1876 *final_value_type = ValueObject::eInvalid;
1877 return 0;
1878 }
1879 else
1880 {
1881 *final_task_on_target = ValueObject::eNothing;
1882 list->Append(final_value);
1883 return 1;
1884 }
1885 }
1886 }
1887 }
1888 else
1889 {
1890 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
1891 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1892 ret_val,
1893 list,
1894 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1895 final_value_type ? final_value_type : &dummy_final_value_type,
1896 options,
1897 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1898 }
1899 // in any non-covered case, just do the obviously right thing
1900 list->Append(ret_val);
1901 return 1;
1902}
1903
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001904lldb::ValueObjectSP
1905ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
1906 const char** first_unparsed,
1907 ExpressionPathScanEndReason* reason_to_stop,
1908 ExpressionPathEndResultType* final_result,
1909 const GetValueForExpressionPathOptions& options,
1910 ExpressionPathAftermath* what_next)
1911{
1912 ValueObjectSP root = GetSP();
1913
1914 if (!root.get())
1915 return ValueObjectSP();
1916
1917 *first_unparsed = expression_cstr;
1918
1919 while (true)
1920 {
1921
1922 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
1923
1924 lldb::clang_type_t root_clang_type = root->GetClangType();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001925 lldb::clang_type_t pointee_clang_type;
1926 Flags root_clang_type_info,pointee_clang_type_info;
1927
1928 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
1929 if (pointee_clang_type)
1930 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001931
1932 if (!expression_cstr || *expression_cstr == '\0')
1933 {
1934 *reason_to_stop = ValueObject::eEndOfString;
1935 return root;
1936 }
1937
1938 switch (*expression_cstr)
1939 {
1940 case '-':
1941 {
1942 if (options.m_check_dot_vs_arrow_syntax &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001943 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 +00001944 {
1945 *first_unparsed = expression_cstr;
1946 *reason_to_stop = ValueObject::eArrowInsteadOfDot;
1947 *final_result = ValueObject::eInvalid;
1948 return ValueObjectSP();
1949 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001950 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
1951 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) &&
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001952 options.m_no_fragile_ivar)
1953 {
1954 *first_unparsed = expression_cstr;
1955 *reason_to_stop = ValueObject::eFragileIVarNotAllowed;
1956 *final_result = ValueObject::eInvalid;
1957 return ValueObjectSP();
1958 }
1959 if (expression_cstr[1] != '>')
1960 {
1961 *first_unparsed = expression_cstr;
1962 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1963 *final_result = ValueObject::eInvalid;
1964 return ValueObjectSP();
1965 }
1966 expression_cstr++; // skip the -
1967 }
1968 case '.': // or fallthrough from ->
1969 {
1970 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001971 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 +00001972 {
1973 *first_unparsed = expression_cstr;
1974 *reason_to_stop = ValueObject::eDotInsteadOfArrow;
1975 *final_result = ValueObject::eInvalid;
1976 return ValueObjectSP();
1977 }
1978 expression_cstr++; // skip .
1979 const char *next_separator = strpbrk(expression_cstr+1,"-.[");
1980 ConstString child_name;
1981 if (!next_separator) // if no other separator just expand this last layer
1982 {
1983 child_name.SetCString (expression_cstr);
1984 root = root->GetChildMemberWithName(child_name, true);
1985 if (root.get()) // we know we are done, so just return
1986 {
1987 *first_unparsed = '\0';
1988 *reason_to_stop = ValueObject::eEndOfString;
1989 *final_result = ValueObject::ePlain;
1990 return root;
1991 }
1992 else
1993 {
1994 *first_unparsed = expression_cstr;
1995 *reason_to_stop = ValueObject::eNoSuchChild;
1996 *final_result = ValueObject::eInvalid;
1997 return ValueObjectSP();
1998 }
1999 }
2000 else // other layers do expand
2001 {
2002 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
2003 root = root->GetChildMemberWithName(child_name, true);
2004 if (root.get()) // store the new root and move on
2005 {
2006 *first_unparsed = next_separator;
2007 *final_result = ValueObject::ePlain;
2008 continue;
2009 }
2010 else
2011 {
2012 *first_unparsed = expression_cstr;
2013 *reason_to_stop = ValueObject::eNoSuchChild;
2014 *final_result = ValueObject::eInvalid;
2015 return ValueObjectSP();
2016 }
2017 }
2018 break;
2019 }
2020 case '[':
2021 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002022 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 +00002023 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002024 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002025 {
2026 *first_unparsed = expression_cstr;
2027 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2028 *final_result = ValueObject::eInvalid;
2029 return ValueObjectSP();
2030 }
2031 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2032 {
2033 *first_unparsed = expression_cstr;
2034 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2035 *final_result = ValueObject::eInvalid;
2036 return ValueObjectSP();
2037 }
2038 }
2039 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2040 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002041 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002042 {
2043 *first_unparsed = expression_cstr;
2044 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2045 *final_result = ValueObject::eInvalid;
2046 return ValueObjectSP();
2047 }
2048 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
2049 {
2050 *first_unparsed = expression_cstr+2;
2051 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2052 *final_result = ValueObject::eUnboundedRange;
2053 return root;
2054 }
2055 }
2056 const char *separator_position = ::strchr(expression_cstr+1,'-');
2057 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2058 if (!close_bracket_position) // if there is no ], this is a syntax error
2059 {
2060 *first_unparsed = expression_cstr;
2061 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2062 *final_result = ValueObject::eInvalid;
2063 return ValueObjectSP();
2064 }
2065 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2066 {
2067 char *end = NULL;
2068 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2069 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2070 {
2071 *first_unparsed = expression_cstr;
2072 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2073 *final_result = ValueObject::eInvalid;
2074 return ValueObjectSP();
2075 }
2076 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2077 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002078 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002079 {
2080 *first_unparsed = expression_cstr+2;
2081 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2082 *final_result = ValueObject::eUnboundedRange;
2083 return root;
2084 }
2085 else
2086 {
2087 *first_unparsed = expression_cstr;
2088 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2089 *final_result = ValueObject::eInvalid;
2090 return ValueObjectSP();
2091 }
2092 }
2093 // from here on we do have a valid index
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002094 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002095 {
Greg Claytondaf515f2011-07-09 20:12:33 +00002096 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2097 if (!child_valobj_sp)
2098 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
2099 if (child_valobj_sp)
2100 {
2101 root = child_valobj_sp;
2102 *first_unparsed = end+1; // skip ]
2103 *final_result = ValueObject::ePlain;
2104 continue;
2105 }
2106 else
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002107 {
2108 *first_unparsed = expression_cstr;
2109 *reason_to_stop = ValueObject::eNoSuchChild;
2110 *final_result = ValueObject::eInvalid;
2111 return ValueObjectSP();
2112 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002113 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002114 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002115 {
2116 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 +00002117 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002118 {
2119 Error error;
2120 root = root->Dereference(error);
2121 if (error.Fail() || !root.get())
2122 {
2123 *first_unparsed = expression_cstr;
2124 *reason_to_stop = ValueObject::eDereferencingFailed;
2125 *final_result = ValueObject::eInvalid;
2126 return ValueObjectSP();
2127 }
2128 else
2129 {
2130 *what_next = eNothing;
2131 continue;
2132 }
2133 }
2134 else
2135 {
2136 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2137 if (!root.get())
2138 {
2139 *first_unparsed = expression_cstr;
2140 *reason_to_stop = ValueObject::eNoSuchChild;
2141 *final_result = ValueObject::eInvalid;
2142 return ValueObjectSP();
2143 }
2144 else
2145 {
2146 *first_unparsed = end+1; // skip ]
2147 *final_result = ValueObject::ePlain;
2148 continue;
2149 }
2150 }
2151 }
2152 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
2153 {
2154 root = root->GetSyntheticBitFieldChild(index, index, true);
2155 if (!root.get())
2156 {
2157 *first_unparsed = expression_cstr;
2158 *reason_to_stop = ValueObject::eNoSuchChild;
2159 *final_result = ValueObject::eInvalid;
2160 return ValueObjectSP();
2161 }
2162 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2163 {
2164 *first_unparsed = end+1; // skip ]
2165 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2166 *final_result = ValueObject::eBitfield;
2167 return root;
2168 }
2169 }
2170 }
2171 else // we have a low and a high index
2172 {
2173 char *end = NULL;
2174 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2175 if (!end || end != separator_position) // if something weird is in our way return an error
2176 {
2177 *first_unparsed = expression_cstr;
2178 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2179 *final_result = ValueObject::eInvalid;
2180 return ValueObjectSP();
2181 }
2182 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2183 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2184 {
2185 *first_unparsed = expression_cstr;
2186 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2187 *final_result = ValueObject::eInvalid;
2188 return ValueObjectSP();
2189 }
2190 if (index_lower > index_higher) // swap indices if required
2191 {
2192 unsigned long temp = index_lower;
2193 index_lower = index_higher;
2194 index_higher = temp;
2195 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002196 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002197 {
2198 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2199 if (!root.get())
2200 {
2201 *first_unparsed = expression_cstr;
2202 *reason_to_stop = ValueObject::eNoSuchChild;
2203 *final_result = ValueObject::eInvalid;
2204 return ValueObjectSP();
2205 }
2206 else
2207 {
2208 *first_unparsed = end+1; // skip ]
2209 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2210 *final_result = ValueObject::eBitfield;
2211 return root;
2212 }
2213 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002214 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 +00002215 *what_next == ValueObject::eDereference &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002216 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002217 {
2218 Error error;
2219 root = root->Dereference(error);
2220 if (error.Fail() || !root.get())
2221 {
2222 *first_unparsed = expression_cstr;
2223 *reason_to_stop = ValueObject::eDereferencingFailed;
2224 *final_result = ValueObject::eInvalid;
2225 return ValueObjectSP();
2226 }
2227 else
2228 {
2229 *what_next = ValueObject::eNothing;
2230 continue;
2231 }
2232 }
2233 else
2234 {
2235 *first_unparsed = expression_cstr;
2236 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2237 *final_result = ValueObject::eBoundedRange;
2238 return root;
2239 }
2240 }
2241 break;
2242 }
2243 default: // some non-separator is in the way
2244 {
2245 *first_unparsed = expression_cstr;
2246 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2247 *final_result = ValueObject::eInvalid;
2248 return ValueObjectSP();
2249 break;
2250 }
2251 }
2252 }
2253}
2254
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002255int
2256ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
2257 const char** first_unparsed,
2258 lldb::ValueObjectSP root,
2259 lldb::ValueObjectListSP& list,
2260 ExpressionPathScanEndReason* reason_to_stop,
2261 ExpressionPathEndResultType* final_result,
2262 const GetValueForExpressionPathOptions& options,
2263 ExpressionPathAftermath* what_next)
2264{
2265 if (!root.get())
2266 return 0;
2267
2268 *first_unparsed = expression_cstr;
2269
2270 while (true)
2271 {
2272
2273 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
2274
2275 lldb::clang_type_t root_clang_type = root->GetClangType();
2276 lldb::clang_type_t pointee_clang_type;
2277 Flags root_clang_type_info,pointee_clang_type_info;
2278
2279 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
2280 if (pointee_clang_type)
2281 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
2282
2283 if (!expression_cstr || *expression_cstr == '\0')
2284 {
2285 *reason_to_stop = ValueObject::eEndOfString;
2286 list->Append(root);
2287 return 1;
2288 }
2289
2290 switch (*expression_cstr)
2291 {
2292 case '[':
2293 {
2294 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
2295 {
2296 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
2297 {
2298 *first_unparsed = expression_cstr;
2299 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2300 *final_result = ValueObject::eInvalid;
2301 return 0;
2302 }
2303 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2304 {
2305 *first_unparsed = expression_cstr;
2306 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2307 *final_result = ValueObject::eInvalid;
2308 return 0;
2309 }
2310 }
2311 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2312 {
2313 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2314 {
2315 *first_unparsed = expression_cstr;
2316 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2317 *final_result = ValueObject::eInvalid;
2318 return 0;
2319 }
2320 else // expand this into list
2321 {
2322 int max_index = root->GetNumChildren() - 1;
2323 for (int index = 0; index < max_index; index++)
2324 {
2325 ValueObjectSP child =
2326 root->GetChildAtIndex(index, true);
2327 list->Append(child);
2328 }
2329 *first_unparsed = expression_cstr+2;
2330 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2331 *final_result = ValueObject::eValueObjectList;
2332 return max_index; // tell me number of items I added to the VOList
2333 }
2334 }
2335 const char *separator_position = ::strchr(expression_cstr+1,'-');
2336 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2337 if (!close_bracket_position) // if there is no ], this is a syntax error
2338 {
2339 *first_unparsed = expression_cstr;
2340 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2341 *final_result = ValueObject::eInvalid;
2342 return 0;
2343 }
2344 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2345 {
2346 char *end = NULL;
2347 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2348 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2349 {
2350 *first_unparsed = expression_cstr;
2351 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2352 *final_result = ValueObject::eInvalid;
2353 return 0;
2354 }
2355 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2356 {
2357 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2358 {
2359 int max_index = root->GetNumChildren() - 1;
2360 for (int index = 0; index < max_index; index++)
2361 {
2362 ValueObjectSP child =
2363 root->GetChildAtIndex(index, true);
2364 list->Append(child);
2365 }
2366 *first_unparsed = expression_cstr+2;
2367 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2368 *final_result = ValueObject::eValueObjectList;
2369 return max_index; // tell me number of items I added to the VOList
2370 }
2371 else
2372 {
2373 *first_unparsed = expression_cstr;
2374 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2375 *final_result = ValueObject::eInvalid;
2376 return 0;
2377 }
2378 }
2379 // from here on we do have a valid index
2380 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2381 {
2382 root = root->GetChildAtIndex(index, true);
2383 if (!root.get())
2384 {
2385 *first_unparsed = expression_cstr;
2386 *reason_to_stop = ValueObject::eNoSuchChild;
2387 *final_result = ValueObject::eInvalid;
2388 return 0;
2389 }
2390 else
2391 {
2392 list->Append(root);
2393 *first_unparsed = end+1; // skip ]
2394 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2395 *final_result = ValueObject::eValueObjectList;
2396 return 1;
2397 }
2398 }
2399 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
2400 {
2401 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
2402 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2403 {
2404 Error error;
2405 root = root->Dereference(error);
2406 if (error.Fail() || !root.get())
2407 {
2408 *first_unparsed = expression_cstr;
2409 *reason_to_stop = ValueObject::eDereferencingFailed;
2410 *final_result = ValueObject::eInvalid;
2411 return 0;
2412 }
2413 else
2414 {
2415 *what_next = eNothing;
2416 continue;
2417 }
2418 }
2419 else
2420 {
2421 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2422 if (!root.get())
2423 {
2424 *first_unparsed = expression_cstr;
2425 *reason_to_stop = ValueObject::eNoSuchChild;
2426 *final_result = ValueObject::eInvalid;
2427 return 0;
2428 }
2429 else
2430 {
2431 list->Append(root);
2432 *first_unparsed = end+1; // skip ]
2433 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2434 *final_result = ValueObject::eValueObjectList;
2435 return 1;
2436 }
2437 }
2438 }
2439 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
2440 {
2441 root = root->GetSyntheticBitFieldChild(index, index, true);
2442 if (!root.get())
2443 {
2444 *first_unparsed = expression_cstr;
2445 *reason_to_stop = ValueObject::eNoSuchChild;
2446 *final_result = ValueObject::eInvalid;
2447 return 0;
2448 }
2449 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2450 {
2451 list->Append(root);
2452 *first_unparsed = end+1; // skip ]
2453 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2454 *final_result = ValueObject::eValueObjectList;
2455 return 1;
2456 }
2457 }
2458 }
2459 else // we have a low and a high index
2460 {
2461 char *end = NULL;
2462 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2463 if (!end || end != separator_position) // if something weird is in our way return an error
2464 {
2465 *first_unparsed = expression_cstr;
2466 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2467 *final_result = ValueObject::eInvalid;
2468 return 0;
2469 }
2470 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2471 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2472 {
2473 *first_unparsed = expression_cstr;
2474 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2475 *final_result = ValueObject::eInvalid;
2476 return 0;
2477 }
2478 if (index_lower > index_higher) // swap indices if required
2479 {
2480 unsigned long temp = index_lower;
2481 index_lower = index_higher;
2482 index_higher = temp;
2483 }
2484 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
2485 {
2486 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2487 if (!root.get())
2488 {
2489 *first_unparsed = expression_cstr;
2490 *reason_to_stop = ValueObject::eNoSuchChild;
2491 *final_result = ValueObject::eInvalid;
2492 return 0;
2493 }
2494 else
2495 {
2496 list->Append(root);
2497 *first_unparsed = end+1; // skip ]
2498 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2499 *final_result = ValueObject::eValueObjectList;
2500 return 1;
2501 }
2502 }
2503 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
2504 *what_next == ValueObject::eDereference &&
2505 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2506 {
2507 Error error;
2508 root = root->Dereference(error);
2509 if (error.Fail() || !root.get())
2510 {
2511 *first_unparsed = expression_cstr;
2512 *reason_to_stop = ValueObject::eDereferencingFailed;
2513 *final_result = ValueObject::eInvalid;
2514 return 0;
2515 }
2516 else
2517 {
2518 *what_next = ValueObject::eNothing;
2519 continue;
2520 }
2521 }
2522 else
2523 {
Johnny Chen44805302011-07-19 19:48:13 +00002524 for (unsigned long index = index_lower;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002525 index <= index_higher; index++)
2526 {
2527 ValueObjectSP child =
2528 root->GetChildAtIndex(index, true);
2529 list->Append(child);
2530 }
2531 *first_unparsed = end+1;
2532 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2533 *final_result = ValueObject::eValueObjectList;
2534 return index_higher-index_lower+1; // tell me number of items I added to the VOList
2535 }
2536 }
2537 break;
2538 }
2539 default: // some non-[ separator, or something entirely wrong, is in the way
2540 {
2541 *first_unparsed = expression_cstr;
2542 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2543 *final_result = ValueObject::eInvalid;
2544 return 0;
2545 break;
2546 }
2547 }
2548 }
2549}
2550
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002551void
Greg Clayton1d3afba2010-10-05 00:00:42 +00002552ValueObject::DumpValueObject
2553(
2554 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00002555 ValueObject *valobj,
2556 const char *root_valobj_name,
2557 uint32_t ptr_depth,
2558 uint32_t curr_depth,
2559 uint32_t max_depth,
2560 bool show_types,
2561 bool show_location,
2562 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00002563 lldb::DynamicValueType use_dynamic,
Enrico Granatad55546b2011-07-22 00:16:08 +00002564 bool use_synth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002565 bool scope_already_checked,
Enrico Granata0c5ef692011-07-16 01:22:04 +00002566 bool flat_output,
2567 uint32_t omit_summary_depth
Greg Clayton1d3afba2010-10-05 00:00:42 +00002568)
2569{
Greg Clayton007d5be2011-05-30 00:49:24 +00002570 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002571 {
Enrico Granatac3e320a2011-08-02 17:27:39 +00002572 bool update_success = valobj->UpdateValueIfNeeded (use_dynamic, true);
Greg Clayton007d5be2011-05-30 00:49:24 +00002573
2574 if (update_success && use_dynamic != lldb::eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00002575 {
Jim Ingham2837b762011-05-04 03:43:18 +00002576 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00002577 if (dynamic_value)
2578 valobj = dynamic_value;
2579 }
2580
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002581 clang_type_t clang_type = valobj->GetClangType();
2582
Greg Clayton73b472d2010-10-27 03:32:59 +00002583 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002584 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00002585 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
2586 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002587
2588 const bool print_valobj = flat_output == false || has_value;
2589
2590 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002591 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002592 if (show_location)
2593 {
Jim Ingham6035b672011-03-31 00:19:25 +00002594 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002595 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002596
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002597 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002598
Greg Clayton7c8a9662010-11-02 01:50:16 +00002599 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00002600 if (show_types || (curr_depth == 0 && !flat_output))
Enrico Granatac3e320a2011-08-02 17:27:39 +00002601 {
2602 s.Printf("(%s", valobj->GetTypeName().AsCString("<invalid type>"));
2603 if (use_dynamic != lldb::eNoDynamicValues &&
2604 strcmp(valobj->GetTypeName().AsCString("NULL"), "id") == 0)
2605 {
2606 Process* process = valobj->GetUpdatePoint().GetProcessSP().get();
2607 if (process == NULL)
2608 s.Printf(") ");
2609 else
2610 {
2611 ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
2612 if (runtime == NULL)
2613 s.Printf(") ");
2614 else
2615 {
2616 ObjCLanguageRuntime::ObjCISA isa = runtime->GetISA(*valobj);
2617 if (!runtime->IsValidISA(isa))
2618 s.Printf(") ");
2619 else
2620 s.Printf(", dynamic type: %s) ",
2621 runtime->GetActualTypeName(isa).GetCString());
2622 }
2623 }
2624 }
2625 else
2626 s.Printf(") ");
2627 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002628
Greg Clayton1d3afba2010-10-05 00:00:42 +00002629
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002630 if (flat_output)
2631 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002632 // If we are showing types, also qualify the C++ base classes
2633 const bool qualify_cxx_base_classes = show_types;
2634 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002635 s.PutCString(" =");
2636 }
2637 else
2638 {
2639 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
2640 s.Printf ("%s =", name_cstr);
2641 }
2642
Jim Ingham6035b672011-03-31 00:19:25 +00002643 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002644 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002645 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002646 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002647 }
2648
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002649 const char *val_cstr = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00002650 const char *sum_cstr = NULL;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002651 SummaryFormat* entry = valobj->GetSummaryFormat().get();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002652
Enrico Granata0c5ef692011-07-16 01:22:04 +00002653 if (omit_summary_depth > 0)
2654 entry = NULL;
2655
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002656 if (err_cstr == NULL)
2657 {
Jim Ingham6035b672011-03-31 00:19:25 +00002658 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002659 err_cstr = valobj->GetError().AsCString();
2660 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002661
2662 if (err_cstr)
2663 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002664 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00002665 }
2666 else
2667 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002668 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002669 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002670 {
Enrico Granata4becb372011-06-29 22:27:15 +00002671
Enrico Granata0c5ef692011-07-16 01:22:04 +00002672 sum_cstr = (omit_summary_depth == 0) ? valobj->GetSummaryAsCString() : NULL;
Greg Clayton1d3afba2010-10-05 00:00:42 +00002673
Enrico Granata4becb372011-06-29 22:27:15 +00002674 // We must calculate this value in realtime because entry might alter this variable's value
2675 // (e.g. by saying ${var%fmt}) and render precached values useless
2676 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
2677 s.Printf(" %s", valobj->GetValueAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002678
Enrico Granata9dd75c82011-07-15 23:30:15 +00002679 if (sum_cstr)
Enrico Granata0a3958e2011-07-02 00:25:22 +00002680 {
2681 // for some reason, using %@ (ObjC description) in a summary string, makes
2682 // us believe we need to reset ourselves, thus invalidating the content of
2683 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty
2684 // let us recalculate it!
2685 if (sum_cstr[0] == '\0')
2686 s.Printf(" %s", valobj->GetSummaryAsCString());
2687 else
2688 s.Printf(" %s", sum_cstr);
2689 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002690
2691 if (use_objc)
2692 {
Jim Ingham6035b672011-03-31 00:19:25 +00002693 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002694 if (object_desc)
2695 s.Printf(" %s\n", object_desc);
2696 else
Sean Callanan672ad942010-10-23 00:18:49 +00002697 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002698 return;
Enrico Granata0a3958e2011-07-02 00:25:22 +00002699 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002700 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002701
2702 if (curr_depth < max_depth)
2703 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002704 // We will show children for all concrete types. We won't show
2705 // pointer contents unless a pointer depth has been specified.
2706 // We won't reference contents unless the reference is the
2707 // root object (depth of zero).
2708 bool print_children = true;
2709
2710 // Use a new temporary pointer depth in case we override the
2711 // current pointer depth below...
2712 uint32_t curr_ptr_depth = ptr_depth;
2713
2714 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
2715 if (is_ptr || is_ref)
2716 {
2717 // We have a pointer or reference whose value is an address.
2718 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00002719 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00002720 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
2721 print_children = false;
2722
2723 else if (is_ref && curr_depth == 0)
2724 {
2725 // If this is the root object (depth is zero) that we are showing
2726 // and it is a reference, and no pointer depth has been supplied
2727 // print out what it references. Don't do this at deeper depths
2728 // otherwise we can end up with infinite recursion...
2729 curr_ptr_depth = 1;
2730 }
2731
2732 if (curr_ptr_depth == 0)
2733 print_children = false;
2734 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002735
Enrico Granata0a3958e2011-07-02 00:25:22 +00002736 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00002737 {
Enrico Granatad55546b2011-07-22 00:16:08 +00002738 ValueObjectSP synth_vobj = valobj->GetSyntheticValue(use_synth ?
2739 lldb::eUseSyntheticFilter :
2740 lldb::eNoSyntheticFilter);
2741 const uint32_t num_children = synth_vobj->GetNumChildren();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002742 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002743 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002744 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002745 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002746 if (print_valobj)
2747 s.EOL();
2748 }
2749 else
2750 {
2751 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00002752 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002753 s.IndentMore();
2754 }
2755
2756 for (uint32_t idx=0; idx<num_children; ++idx)
2757 {
Enrico Granatad55546b2011-07-22 00:16:08 +00002758 ValueObjectSP child_sp(synth_vobj->GetChildAtIndex(idx, true));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002759 if (child_sp.get())
2760 {
2761 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002762 child_sp.get(),
2763 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00002764 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002765 curr_depth + 1,
2766 max_depth,
2767 show_types,
2768 show_location,
2769 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00002770 use_dynamic,
Enrico Granatad55546b2011-07-22 00:16:08 +00002771 use_synth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002772 true,
Enrico Granata0c5ef692011-07-16 01:22:04 +00002773 flat_output,
2774 omit_summary_depth > 1 ? omit_summary_depth - 1 : 0);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002775 }
2776 }
2777
2778 if (!flat_output)
2779 {
2780 s.IndentLess();
2781 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002782 }
2783 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002784 else if (has_children)
2785 {
2786 // Aggregate, no children...
2787 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00002788 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002789 }
2790 else
2791 {
2792 if (print_valobj)
2793 s.EOL();
2794 }
2795
Greg Clayton1d3afba2010-10-05 00:00:42 +00002796 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002797 else
2798 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00002799 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002800 }
2801 }
2802 else
2803 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002804 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002805 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002806 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002807 }
2808 }
2809 }
2810 }
2811}
2812
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002813
2814ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00002815ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002816{
2817 ValueObjectSP valobj_sp;
2818
Enrico Granatac3e320a2011-08-02 17:27:39 +00002819 if (UpdateValueIfNeeded(false) && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002820 {
Jim Ingham6035b672011-03-31 00:19:25 +00002821 ExecutionContextScope *exe_scope = GetExecutionContextScope();
2822 if (exe_scope)
2823 {
2824 ExecutionContext exe_ctx;
2825 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002826
Jim Ingham6035b672011-03-31 00:19:25 +00002827 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002828
Jim Ingham6035b672011-03-31 00:19:25 +00002829 DataExtractor data;
2830 data.SetByteOrder (m_data.GetByteOrder());
2831 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002832
Greg Clayton644247c2011-07-07 01:59:51 +00002833 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002834
Jim Ingham58b59f92011-04-22 23:53:53 +00002835 valobj_sp = ValueObjectConstResult::Create (exe_scope,
2836 ast,
2837 GetClangType(),
2838 name,
2839 data);
Jim Ingham6035b672011-03-31 00:19:25 +00002840 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002841 }
Jim Ingham6035b672011-03-31 00:19:25 +00002842
2843 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002844 {
Jim Ingham58b59f92011-04-22 23:53:53 +00002845 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002846 }
2847 return valobj_sp;
2848}
2849
2850lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00002851ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002852{
Jim Ingham58b59f92011-04-22 23:53:53 +00002853 if (m_deref_valobj)
2854 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00002855
Greg Clayton54979cd2010-12-15 05:08:08 +00002856 const bool is_pointer_type = IsPointerType();
2857 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002858 {
2859 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +00002860 bool ignore_array_bounds = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002861
2862 std::string child_name_str;
2863 uint32_t child_byte_size = 0;
2864 int32_t child_byte_offset = 0;
2865 uint32_t child_bitfield_bit_size = 0;
2866 uint32_t child_bitfield_bit_offset = 0;
2867 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00002868 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002869 const bool transparent_pointers = false;
2870 clang::ASTContext *clang_ast = GetClangAST();
2871 clang_type_t clang_type = GetClangType();
2872 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00002873
2874 ExecutionContext exe_ctx;
2875 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
2876
2877 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
2878 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002879 GetName().GetCString(),
2880 clang_type,
2881 0,
2882 transparent_pointers,
2883 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00002884 ignore_array_bounds,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002885 child_name_str,
2886 child_byte_size,
2887 child_byte_offset,
2888 child_bitfield_bit_size,
2889 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002890 child_is_base_class,
2891 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00002892 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002893 {
2894 ConstString child_name;
2895 if (!child_name_str.empty())
2896 child_name.SetCString (child_name_str.c_str());
2897
Jim Ingham58b59f92011-04-22 23:53:53 +00002898 m_deref_valobj = new ValueObjectChild (*this,
2899 clang_ast,
2900 child_clang_type,
2901 child_name,
2902 child_byte_size,
2903 child_byte_offset,
2904 child_bitfield_bit_size,
2905 child_bitfield_bit_offset,
2906 child_is_base_class,
2907 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002908 }
2909 }
Greg Clayton54979cd2010-12-15 05:08:08 +00002910
Jim Ingham58b59f92011-04-22 23:53:53 +00002911 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00002912 {
2913 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00002914 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00002915 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002916 else
2917 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002918 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002919 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002920
2921 if (is_pointer_type)
2922 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
2923 else
2924 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00002925 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002926 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002927}
2928
Jim Ingham78a685a2011-04-16 00:01:13 +00002929lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00002930ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002931{
Jim Ingham78a685a2011-04-16 00:01:13 +00002932 if (m_addr_of_valobj_sp)
2933 return m_addr_of_valobj_sp;
2934
Greg Claytone0d378b2011-03-24 21:19:54 +00002935 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002936 const bool scalar_is_load_address = false;
2937 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00002938 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002939 if (addr != LLDB_INVALID_ADDRESS)
2940 {
2941 switch (address_type)
2942 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002943 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002944 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00002945 {
2946 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002947 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002948 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
2949 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002950 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002951
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002952 case eAddressTypeFile:
2953 case eAddressTypeLoad:
2954 case eAddressTypeHost:
2955 {
2956 clang::ASTContext *ast = GetClangAST();
2957 clang_type_t clang_type = GetClangType();
2958 if (ast && clang_type)
2959 {
2960 std::string name (1, '&');
2961 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00002962 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
2963 ast,
2964 ClangASTContext::CreatePointerType (ast, clang_type),
2965 ConstString (name.c_str()),
2966 addr,
2967 eAddressTypeInvalid,
2968 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002969 }
2970 }
2971 break;
2972 }
2973 }
Jim Ingham78a685a2011-04-16 00:01:13 +00002974 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002975}
2976
Greg Claytonb2dcc362011-05-05 23:32:56 +00002977
2978lldb::ValueObjectSP
2979ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
2980{
2981 lldb::ValueObjectSP valobj_sp;
2982 AddressType address_type;
2983 const bool scalar_is_load_address = true;
2984 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2985
2986 if (ptr_value != LLDB_INVALID_ADDRESS)
2987 {
2988 Address ptr_addr (NULL, ptr_value);
2989
2990 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2991 name,
2992 ptr_addr,
2993 clang_ast_type);
2994 }
2995 return valobj_sp;
2996}
2997
2998lldb::ValueObjectSP
2999ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
3000{
3001 lldb::ValueObjectSP valobj_sp;
3002 AddressType address_type;
3003 const bool scalar_is_load_address = true;
3004 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
3005
3006 if (ptr_value != LLDB_INVALID_ADDRESS)
3007 {
3008 Address ptr_addr (NULL, ptr_value);
3009
3010 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
3011 name,
3012 ptr_addr,
3013 type_sp);
3014 }
3015 return valobj_sp;
3016}
3017
Jim Ingham6035b672011-03-31 00:19:25 +00003018ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00003019 m_thread_id (LLDB_INVALID_UID),
3020 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00003021{
3022}
3023
3024ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00003025 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00003026 m_first_update (true),
Jim Ingham89b61092011-07-06 17:42:14 +00003027 m_thread_id (LLDB_INVALID_THREAD_ID),
Stephen Wilson71c21d12011-04-11 19:41:40 +00003028 m_stop_id (0)
3029
Jim Ingham6035b672011-03-31 00:19:25 +00003030{
3031 ExecutionContext exe_ctx;
3032 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
3033 // and if so we want to cache that not the original.
3034 if (exe_scope)
3035 exe_scope->CalculateExecutionContext(exe_ctx);
3036 if (exe_ctx.target != NULL)
3037 {
3038 m_target_sp = exe_ctx.target->GetSP();
3039
3040 if (exe_ctx.process == NULL)
3041 m_process_sp = exe_ctx.target->GetProcessSP();
3042 else
3043 m_process_sp = exe_ctx.process->GetSP();
3044
3045 if (m_process_sp != NULL)
3046 {
3047 m_stop_id = m_process_sp->GetStopID();
3048 Thread *thread = NULL;
3049
3050 if (exe_ctx.thread == NULL)
3051 {
3052 if (use_selected)
3053 {
3054 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
3055 if (thread)
3056 computed_exe_scope = thread;
3057 }
3058 }
3059 else
3060 thread = exe_ctx.thread;
3061
3062 if (thread != NULL)
3063 {
3064 m_thread_id = thread->GetIndexID();
3065 if (exe_ctx.frame == NULL)
3066 {
3067 if (use_selected)
3068 {
3069 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
3070 if (frame)
3071 {
3072 m_stack_id = frame->GetStackID();
3073 computed_exe_scope = frame;
3074 }
3075 }
3076 }
3077 else
3078 m_stack_id = exe_ctx.frame->GetStackID();
3079 }
3080 }
3081 }
3082 m_exe_scope = computed_exe_scope;
3083}
3084
3085ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
3086 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00003087 m_needs_update(true),
3088 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00003089 m_target_sp (rhs.m_target_sp),
3090 m_process_sp (rhs.m_process_sp),
3091 m_thread_id (rhs.m_thread_id),
3092 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00003093 m_stop_id (0)
3094{
3095}
3096
3097ValueObject::EvaluationPoint::~EvaluationPoint ()
3098{
3099}
3100
3101ExecutionContextScope *
3102ValueObject::EvaluationPoint::GetExecutionContextScope ()
3103{
3104 // We have to update before giving out the scope, or we could be handing out stale pointers.
3105 SyncWithProcessState();
3106
3107 return m_exe_scope;
3108}
3109
3110// This function checks the EvaluationPoint against the current process state. If the current
3111// state matches the evaluation point, or the evaluation point is already invalid, then we return
3112// false, meaning "no change". If the current state is different, we update our state, and return
3113// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
3114// future calls to NeedsUpdate will return true.
3115
3116bool
3117ValueObject::EvaluationPoint::SyncWithProcessState()
3118{
3119 // If we're already invalid, we don't need to do anything, and nothing has changed:
3120 if (m_stop_id == LLDB_INVALID_UID)
3121 {
3122 // Can't update with an invalid state.
3123 m_needs_update = false;
3124 return false;
3125 }
3126
3127 // If we don't have a process nothing can change.
3128 if (!m_process_sp)
3129 return false;
3130
3131 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00003132 uint32_t cur_stop_id = m_process_sp->GetStopID();
3133 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00003134 return false;
3135
Jim Ingham78a685a2011-04-16 00:01:13 +00003136 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
3137 // In either case, we aren't going to be able to sync with the process state.
3138 if (cur_stop_id == 0)
3139 return false;
3140
3141 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00003142 m_needs_update = true;
3143 m_exe_scope = m_process_sp.get();
3144
3145 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
3146 // doesn't, mark ourselves as invalid.
3147
3148 if (m_thread_id != LLDB_INVALID_THREAD_ID)
3149 {
3150 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
3151 if (our_thread == NULL)
Greg Clayton262f80d2011-07-06 16:49:27 +00003152 {
Jim Ingham89b61092011-07-06 17:42:14 +00003153 SetInvalid();
Greg Clayton262f80d2011-07-06 16:49:27 +00003154 }
Jim Ingham6035b672011-03-31 00:19:25 +00003155 else
3156 {
3157 m_exe_scope = our_thread;
3158
3159 if (m_stack_id.IsValid())
3160 {
3161 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
3162 if (our_frame == NULL)
3163 SetInvalid();
3164 else
3165 m_exe_scope = our_frame;
3166 }
3167 }
3168 }
3169 return true;
3170}
3171
Jim Ingham61be0902011-05-02 18:13:59 +00003172void
3173ValueObject::EvaluationPoint::SetUpdated ()
3174{
3175 m_first_update = false;
3176 m_needs_update = false;
3177 if (m_process_sp)
3178 m_stop_id = m_process_sp->GetStopID();
3179}
3180
3181
Jim Ingham6035b672011-03-31 00:19:25 +00003182bool
3183ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
3184{
3185 if (!IsValid())
3186 return false;
3187
3188 bool needs_update = false;
3189 m_exe_scope = NULL;
3190
3191 // The target has to be non-null, and the
3192 Target *target = exe_scope->CalculateTarget();
3193 if (target != NULL)
3194 {
3195 Target *old_target = m_target_sp.get();
3196 assert (target == old_target);
3197 Process *process = exe_scope->CalculateProcess();
3198 if (process != NULL)
3199 {
3200 // FOR NOW - assume you can't update variable objects across process boundaries.
3201 Process *old_process = m_process_sp.get();
3202 assert (process == old_process);
3203
3204 lldb::user_id_t stop_id = process->GetStopID();
3205 if (stop_id != m_stop_id)
3206 {
3207 needs_update = true;
3208 m_stop_id = stop_id;
3209 }
3210 // See if we're switching the thread or stack context. If no thread is given, this is
3211 // being evaluated in a global context.
3212 Thread *thread = exe_scope->CalculateThread();
3213 if (thread != NULL)
3214 {
3215 lldb::user_id_t new_thread_index = thread->GetIndexID();
3216 if (new_thread_index != m_thread_id)
3217 {
3218 needs_update = true;
3219 m_thread_id = new_thread_index;
3220 m_stack_id.Clear();
3221 }
3222
3223 StackFrame *new_frame = exe_scope->CalculateStackFrame();
3224 if (new_frame != NULL)
3225 {
3226 if (new_frame->GetStackID() != m_stack_id)
3227 {
3228 needs_update = true;
3229 m_stack_id = new_frame->GetStackID();
3230 }
3231 }
3232 else
3233 {
3234 m_stack_id.Clear();
3235 needs_update = true;
3236 }
3237 }
3238 else
3239 {
3240 // If this had been given a thread, and now there is none, we should update.
3241 // Otherwise we don't have to do anything.
3242 if (m_thread_id != LLDB_INVALID_UID)
3243 {
3244 m_thread_id = LLDB_INVALID_UID;
3245 m_stack_id.Clear();
3246 needs_update = true;
3247 }
3248 }
3249 }
3250 else
3251 {
3252 // If there is no process, then we don't need to update anything.
3253 // But if we're switching from having a process to not, we should try to update.
3254 if (m_process_sp.get() != NULL)
3255 {
3256 needs_update = true;
3257 m_process_sp.reset();
3258 m_thread_id = LLDB_INVALID_UID;
3259 m_stack_id.Clear();
3260 }
3261 }
3262 }
3263 else
3264 {
3265 // If there's no target, nothing can change so we don't need to update anything.
3266 // But if we're switching from having a target to not, we should try to update.
3267 if (m_target_sp.get() != NULL)
3268 {
3269 needs_update = true;
3270 m_target_sp.reset();
3271 m_process_sp.reset();
3272 m_thread_id = LLDB_INVALID_UID;
3273 m_stack_id.Clear();
3274 }
3275 }
3276 if (!m_needs_update)
3277 m_needs_update = needs_update;
3278
3279 return needs_update;
3280}
Enrico Granataf2bbf712011-07-15 02:26:42 +00003281
3282void
3283ValueObject::ClearUserVisibleData()
3284{
3285 m_location_str.clear();
3286 m_value_str.clear();
3287 m_summary_str.clear();
3288 m_object_desc_str.clear();
Johnny Chen44805302011-07-19 19:48:13 +00003289}