blob: 34ceb3a71cbec8b28c9b9cb027dbf3769c08bc42 [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "lldb/Core/ValueObject.h"
13
14// C Includes
Greg Claytonf5e56de2010-09-14 23:36:40 +000015#include <stdlib.h>
16
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017// C++ Includes
18// Other libraries and framework includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "llvm/Support/raw_ostream.h"
Jim Ingham5a369122010-09-28 01:25:32 +000020#include "clang/AST/Type.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021
22// Project includes
23#include "lldb/Core/DataBufferHeap.h"
Enrico Granata4becb372011-06-29 22:27:15 +000024#include "lldb/Core/Debugger.h"
Enrico Granata6f3533f2011-07-29 19:53:35 +000025#include "lldb/Core/Log.h"
Greg Clayton1f746072012-08-29 21:13:06 +000026#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/StreamString.h"
Enrico Granata21fd13f2012-10-27 02:05:48 +000028#include "lldb/Core/ValueObjectCast.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Core/ValueObjectChild.h"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000030#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000031#include "lldb/Core/ValueObjectDynamicValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Core/ValueObjectList.h"
Greg Claytonb2dcc362011-05-05 23:32:56 +000033#include "lldb/Core/ValueObjectMemory.h"
Enrico Granatad55546b2011-07-22 00:16:08 +000034#include "lldb/Core/ValueObjectSyntheticFilter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
Enrico Granata5548cb52013-01-28 23:47:25 +000036#include "lldb/DataFormatters/DataVisualization.h"
37
Greg Clayton7fb56d02011-02-01 01:31:41 +000038#include "lldb/Host/Endian.h"
39
Enrico Granata61a80ba2011-08-12 16:42:31 +000040#include "lldb/Interpreter/CommandInterpreter.h"
Enrico Granataf2bbf712011-07-15 02:26:42 +000041#include "lldb/Interpreter/ScriptInterpreterPython.h"
42
Greg Claytone1a916a2010-07-21 22:12:05 +000043#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044#include "lldb/Symbol/ClangASTContext.h"
45#include "lldb/Symbol/Type.h"
46
Jim Ingham53c47f12010-09-10 23:12:17 +000047#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000048#include "lldb/Target/LanguageRuntime.h"
Enrico Granatac3e320a2011-08-02 17:27:39 +000049#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050#include "lldb/Target/Process.h"
51#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000052#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054
55using namespace lldb;
56using namespace lldb_private;
Enrico Granataf4efecd2011-07-12 22:56:10 +000057using namespace lldb_utility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058
Greg Claytonafacd142011-09-02 01:15:17 +000059static user_id_t g_value_obj_uid = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060
61//----------------------------------------------------------------------
62// ValueObject constructor
63//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000064ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000066 m_parent (&parent),
Enrico Granata4873e522013-04-11 22:48:58 +000067 m_root (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +000068 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069 m_name (),
70 m_data (),
71 m_value (),
72 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000073 m_value_str (),
74 m_old_value_str (),
75 m_location_str (),
76 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000077 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000078 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000079 m_children (),
80 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000081 m_dynamic_value (NULL),
Enrico Granatad55546b2011-07-22 00:16:08 +000082 m_synthetic_value(NULL),
Jim Ingham58b59f92011-04-22 23:53:53 +000083 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000084 m_format (eFormatDefault),
Enrico Granata9df29e32011-07-19 20:57:44 +000085 m_last_format_mgr_revision(0),
Enrico Granata0c489f52012-03-01 04:24:26 +000086 m_type_summary_sp(),
87 m_type_format_sp(),
88 m_synthetic_children_sp(),
Jim Ingham4b536182011-08-09 02:12:22 +000089 m_user_id_of_forced_summary(),
Daniel Dunbara08823f2011-10-31 22:50:49 +000090 m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid),
Greg Clayton288bdf92010-09-02 02:59:18 +000091 m_value_is_valid (false),
92 m_value_did_change (false),
93 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000094 m_old_value_valid (false),
Enrico Granata4becb372011-06-29 22:27:15 +000095 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +000096 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +000097 m_is_bitfield_for_scalar(false),
Enrico Granata6f3533f2011-07-29 19:53:35 +000098 m_is_child_at_offset(false),
Sean Callanan72772842012-02-22 23:57:45 +000099 m_is_getting_summary(false),
100 m_did_calculate_complete_objc_class_type(false)
Jim Ingham6035b672011-03-31 00:19:25 +0000101{
Jim Ingham58b59f92011-04-22 23:53:53 +0000102 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +0000103}
104
105//----------------------------------------------------------------------
106// ValueObject constructor
107//----------------------------------------------------------------------
Enrico Granata9128ee22011-09-06 19:20:51 +0000108ValueObject::ValueObject (ExecutionContextScope *exe_scope,
109 AddressType child_ptr_or_ref_addr_type) :
Jim Ingham6035b672011-03-31 00:19:25 +0000110 UserID (++g_value_obj_uid), // Unique identifier for every value object
111 m_parent (NULL),
Enrico Granata4873e522013-04-11 22:48:58 +0000112 m_root (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000113 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +0000114 m_name (),
115 m_data (),
116 m_value (),
117 m_error (),
118 m_value_str (),
119 m_old_value_str (),
120 m_location_str (),
121 m_summary_str (),
122 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000123 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +0000124 m_children (),
125 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000126 m_dynamic_value (NULL),
Enrico Granatad55546b2011-07-22 00:16:08 +0000127 m_synthetic_value(NULL),
Jim Ingham58b59f92011-04-22 23:53:53 +0000128 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +0000129 m_format (eFormatDefault),
Enrico Granata9df29e32011-07-19 20:57:44 +0000130 m_last_format_mgr_revision(0),
Enrico Granata0c489f52012-03-01 04:24:26 +0000131 m_type_summary_sp(),
132 m_type_format_sp(),
133 m_synthetic_children_sp(),
Jim Ingham4b536182011-08-09 02:12:22 +0000134 m_user_id_of_forced_summary(),
Daniel Dunbara08823f2011-10-31 22:50:49 +0000135 m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
Jim Ingham6035b672011-03-31 00:19:25 +0000136 m_value_is_valid (false),
137 m_value_did_change (false),
138 m_children_count_valid (false),
139 m_old_value_valid (false),
Enrico Granata4becb372011-06-29 22:27:15 +0000140 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +0000141 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +0000142 m_is_bitfield_for_scalar(false),
Enrico Granata6f3533f2011-07-29 19:53:35 +0000143 m_is_child_at_offset(false),
Sean Callanan72772842012-02-22 23:57:45 +0000144 m_is_getting_summary(false),
145 m_did_calculate_complete_objc_class_type(false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146{
Jim Ingham58b59f92011-04-22 23:53:53 +0000147 m_manager = new ValueObjectManager();
148 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149}
150
151//----------------------------------------------------------------------
152// Destructor
153//----------------------------------------------------------------------
154ValueObject::~ValueObject ()
155{
156}
157
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158bool
Enrico Granata0a3958e2011-07-02 00:25:22 +0000159ValueObject::UpdateValueIfNeeded (bool update_format)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160{
Enrico Granata4becb372011-06-29 22:27:15 +0000161
Enrico Granata9128ee22011-09-06 19:20:51 +0000162 bool did_change_formats = false;
163
Enrico Granata0a3958e2011-07-02 00:25:22 +0000164 if (update_format)
Enrico Granata5548cb52013-01-28 23:47:25 +0000165 did_change_formats = UpdateFormatsIfNeeded();
Enrico Granata4becb372011-06-29 22:27:15 +0000166
Greg Claytonb71f3842010-10-05 03:13:51 +0000167 // If this is a constant value, then our success is predicated on whether
168 // we have an error or not
169 if (GetIsConstant())
Enrico Granata9128ee22011-09-06 19:20:51 +0000170 {
171 // if you were asked to update your formatters, but did not get a chance to do it
172 // clear your own values (this serves the purpose of faking a stop-id for frozen
173 // objects (which are regarded as constant, but could have changes behind their backs
174 // because of the frozen-pointer depth limit)
175 // TODO: decouple summary from value and then remove this code and only force-clear the summary
176 if (update_format && !did_change_formats)
Enrico Granata86cc9822012-03-19 22:58:49 +0000177 ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
Greg Claytonb71f3842010-10-05 03:13:51 +0000178 return m_error.Success();
Enrico Granata9128ee22011-09-06 19:20:51 +0000179 }
Greg Claytonb71f3842010-10-05 03:13:51 +0000180
Jim Ingham6035b672011-03-31 00:19:25 +0000181 bool first_update = m_update_point.IsFirstEvaluation();
182
183 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184 {
Jim Ingham6035b672011-03-31 00:19:25 +0000185 m_update_point.SetUpdated();
186
187 // Save the old value using swap to avoid a string copy which
188 // also will clear our m_value_str
189 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000190 {
Jim Ingham6035b672011-03-31 00:19:25 +0000191 m_old_value_valid = false;
192 }
193 else
194 {
195 m_old_value_valid = true;
196 m_old_value_str.swap (m_value_str);
Enrico Granata86cc9822012-03-19 22:58:49 +0000197 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
Jim Ingham6035b672011-03-31 00:19:25 +0000198 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199
Enrico Granataf2bbf712011-07-15 02:26:42 +0000200 ClearUserVisibleData();
201
Greg Claytonefbc7d22012-03-09 04:23:44 +0000202 if (IsInScope())
Jim Ingham6035b672011-03-31 00:19:25 +0000203 {
Greg Claytonefbc7d22012-03-09 04:23:44 +0000204 const bool value_was_valid = GetValueIsValid();
205 SetValueDidChange (false);
206
207 m_error.Clear();
208
209 // Call the pure virtual function to update the value
210 bool success = UpdateValue ();
211
212 SetValueIsValid (success);
213
214 if (first_update)
215 SetValueDidChange (false);
216 else if (!m_value_did_change && success == false)
217 {
218 // The value wasn't gotten successfully, so we mark this
219 // as changed if the value used to be valid and now isn't
220 SetValueDidChange (value_was_valid);
221 }
222 }
223 else
224 {
225 m_error.SetErrorString("out of scope");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 }
227 }
228 return m_error.Success();
229}
230
Enrico Granata9128ee22011-09-06 19:20:51 +0000231bool
Enrico Granata5548cb52013-01-28 23:47:25 +0000232ValueObject::UpdateFormatsIfNeeded()
Enrico Granata4becb372011-06-29 22:27:15 +0000233{
Greg Clayton5160ce52013-03-27 23:08:40 +0000234 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata6f3533f2011-07-29 19:53:35 +0000235 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +0000236 log->Printf("[%s %p] checking for FormatManager revisions. ValueObject rev: %d - Global rev: %d",
Enrico Granata6f3533f2011-07-29 19:53:35 +0000237 GetName().GetCString(),
Enrico Granatad2284832012-10-17 22:23:56 +0000238 this,
Enrico Granata4becb372011-06-29 22:27:15 +0000239 m_last_format_mgr_revision,
Enrico Granata85933ed2011-08-18 16:38:26 +0000240 DataVisualization::GetCurrentRevision());
Enrico Granata9128ee22011-09-06 19:20:51 +0000241
242 bool any_change = false;
243
Enrico Granata5548cb52013-01-28 23:47:25 +0000244 if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()))
Enrico Granata4becb372011-06-29 22:27:15 +0000245 {
Enrico Granata78d06382011-09-09 23:33:14 +0000246 SetValueFormat(DataVisualization::ValueFormats::GetFormat (*this, eNoDynamicValues));
Enrico Granata5548cb52013-01-28 23:47:25 +0000247 SetSummaryFormat(DataVisualization::GetSummaryFormat (*this, GetDynamicValueType()));
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000248#ifndef LLDB_DISABLE_PYTHON
Enrico Granata5548cb52013-01-28 23:47:25 +0000249 SetSyntheticChildren(DataVisualization::GetSyntheticChildren (*this, GetDynamicValueType()));
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000250#endif
Enrico Granata1490c6f2011-07-19 02:34:21 +0000251
Enrico Granata85933ed2011-08-18 16:38:26 +0000252 m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
Enrico Granata855cd902011-09-06 22:59:55 +0000253
254 any_change = true;
Enrico Granata4becb372011-06-29 22:27:15 +0000255 }
Enrico Granata9128ee22011-09-06 19:20:51 +0000256
257 return any_change;
258
Enrico Granata4becb372011-06-29 22:27:15 +0000259}
260
Jim Ingham16e0c682011-08-12 23:34:31 +0000261void
262ValueObject::SetNeedsUpdate ()
263{
264 m_update_point.SetNeedsUpdate();
265 // We have to clear the value string here so ConstResult children will notice if their values are
266 // changed by hand (i.e. with SetValueAsCString).
Enrico Granata86cc9822012-03-19 22:58:49 +0000267 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
Jim Ingham16e0c682011-08-12 23:34:31 +0000268}
269
Enrico Granata13ac0e22012-10-17 19:03:34 +0000270void
Enrico Granatae3e91512012-10-22 18:18:36 +0000271ValueObject::ClearDynamicTypeInformation ()
Enrico Granata13ac0e22012-10-17 19:03:34 +0000272{
273 m_did_calculate_complete_objc_class_type = false;
Enrico Granatae3e91512012-10-22 18:18:36 +0000274 m_last_format_mgr_revision = 0;
Enrico Granata13ac0e22012-10-17 19:03:34 +0000275 m_override_type = ClangASTType();
Enrico Granatae3e91512012-10-22 18:18:36 +0000276 SetValueFormat(lldb::TypeFormatImplSP());
277 SetSummaryFormat(lldb::TypeSummaryImplSP());
278 SetSyntheticChildren(lldb::SyntheticChildrenSP());
Enrico Granata13ac0e22012-10-17 19:03:34 +0000279}
280
Sean Callanan72772842012-02-22 23:57:45 +0000281ClangASTType
282ValueObject::MaybeCalculateCompleteType ()
283{
284 ClangASTType ret(GetClangASTImpl(), GetClangTypeImpl());
Sean Callanan356e17c2012-03-30 02:04:38 +0000285
Sean Callanan72772842012-02-22 23:57:45 +0000286 if (m_did_calculate_complete_objc_class_type)
287 {
288 if (m_override_type.IsValid())
289 return m_override_type;
290 else
291 return ret;
292 }
293
294 clang_type_t ast_type(GetClangTypeImpl());
295 clang_type_t class_type;
296 bool is_pointer_type;
297
298 if (ClangASTContext::IsObjCObjectPointerType(ast_type, &class_type))
299 {
300 is_pointer_type = true;
301 }
302 else if (ClangASTContext::IsObjCClassType(ast_type))
303 {
304 is_pointer_type = false;
305 class_type = ast_type;
306 }
307 else
308 {
309 return ret;
310 }
311
312 m_did_calculate_complete_objc_class_type = true;
313
314 if (!class_type)
315 return ret;
316
317 std::string class_name;
318
319 if (!ClangASTContext::GetObjCClassName(class_type, class_name))
320 return ret;
321
322 ProcessSP process_sp(GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
323
324 if (!process_sp)
325 return ret;
326
327 ObjCLanguageRuntime *objc_language_runtime(process_sp->GetObjCLanguageRuntime());
328
329 if (!objc_language_runtime)
330 return ret;
331
332 ConstString class_name_cs(class_name.c_str());
333
334 TypeSP complete_objc_class_type_sp = objc_language_runtime->LookupInCompleteClassCache(class_name_cs);
335
336 if (!complete_objc_class_type_sp)
337 return ret;
338
339 ClangASTType complete_class(complete_objc_class_type_sp->GetClangAST(),
340 complete_objc_class_type_sp->GetClangFullType());
341
342 if (!ClangASTContext::GetCompleteType(complete_class.GetASTContext(),
343 complete_class.GetOpaqueQualType()))
344 return ret;
345
346 if (is_pointer_type)
347 {
348 clang_type_t pointer_type = ClangASTContext::CreatePointerType(complete_class.GetASTContext(),
349 complete_class.GetOpaqueQualType());
350
351 m_override_type = ClangASTType(complete_class.GetASTContext(),
352 pointer_type);
353 }
354 else
355 {
356 m_override_type = complete_class;
357 }
358
Sean Callanan356e17c2012-03-30 02:04:38 +0000359 if (m_override_type.IsValid())
360 return m_override_type;
361 else
362 return ret;
Sean Callanan72772842012-02-22 23:57:45 +0000363}
364
365clang::ASTContext *
366ValueObject::GetClangAST ()
367{
368 ClangASTType type = MaybeCalculateCompleteType();
369
370 return type.GetASTContext();
371}
372
373lldb::clang_type_t
374ValueObject::GetClangType ()
375{
376 ClangASTType type = MaybeCalculateCompleteType();
377
378 return type.GetOpaqueQualType();
379}
380
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381DataExtractor &
382ValueObject::GetDataExtractor ()
383{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000384 UpdateValueIfNeeded(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385 return m_data;
386}
387
388const Error &
Greg Clayton262f80d2011-07-06 16:49:27 +0000389ValueObject::GetError()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000391 UpdateValueIfNeeded(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392 return m_error;
393}
394
395const ConstString &
396ValueObject::GetName() const
397{
398 return m_name;
399}
400
401const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000402ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403{
Enrico Granata82fabf82013-04-30 20:45:04 +0000404 return GetLocationAsCStringImpl(m_value,
405 m_data);
406}
407
408const char *
409ValueObject::GetLocationAsCStringImpl (const Value& value,
410 const DataExtractor& data)
411{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000412 if (UpdateValueIfNeeded(false))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000413 {
414 if (m_location_str.empty())
415 {
416 StreamString sstr;
Enrico Granata82fabf82013-04-30 20:45:04 +0000417
418 Value::ValueType value_type = value.GetValueType();
419
420 switch (value_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422 case Value::eValueTypeScalar:
Greg Clayton0665a0f2012-10-30 18:18:43 +0000423 case Value::eValueTypeVector:
Enrico Granata82fabf82013-04-30 20:45:04 +0000424 if (value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425 {
Enrico Granata82fabf82013-04-30 20:45:04 +0000426 RegisterInfo *reg_info = value.GetRegisterInfo();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427 if (reg_info)
428 {
429 if (reg_info->name)
430 m_location_str = reg_info->name;
431 else if (reg_info->alt_name)
432 m_location_str = reg_info->alt_name;
Enrico Granata82fabf82013-04-30 20:45:04 +0000433 if (m_location_str.empty())
434 m_location_str = (reg_info->encoding == lldb::eEncodingVector) ? "vector" : "scalar";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435 }
436 }
Enrico Granata82fabf82013-04-30 20:45:04 +0000437 if (m_location_str.empty())
438 m_location_str = (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439 break;
440
441 case Value::eValueTypeLoadAddress:
442 case Value::eValueTypeFileAddress:
443 case Value::eValueTypeHostAddress:
444 {
Enrico Granata82fabf82013-04-30 20:45:04 +0000445 uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
446 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447 m_location_str.swap(sstr.GetString());
448 }
449 break;
450 }
451 }
452 }
453 return m_location_str.c_str();
454}
455
456Value &
457ValueObject::GetValue()
458{
459 return m_value;
460}
461
462const Value &
463ValueObject::GetValue() const
464{
465 return m_value;
466}
467
468bool
Jim Ingham6035b672011-03-31 00:19:25 +0000469ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000470{
Enrico Granata6fd87d52011-08-04 01:41:02 +0000471 if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
472 {
Greg Claytoncc4d0142012-02-17 07:49:44 +0000473 ExecutionContext exe_ctx (GetExecutionContextRef());
Jim Ingham16e0c682011-08-12 23:34:31 +0000474 Value tmp_value(m_value);
475 scalar = tmp_value.ResolveValue(&exe_ctx, GetClangAST ());
Greg Claytondcad5022011-12-29 01:26:56 +0000476 if (scalar.IsValid())
477 {
478 const uint32_t bitfield_bit_size = GetBitfieldBitSize();
479 if (bitfield_bit_size)
480 return scalar.ExtractBitfield (bitfield_bit_size, GetBitfieldBitOffset());
481 return true;
482 }
Enrico Granata6fd87d52011-08-04 01:41:02 +0000483 }
Greg Claytondcad5022011-12-29 01:26:56 +0000484 return false;
Greg Clayton8f343b02010-11-04 01:54:29 +0000485}
486
487bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000488ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489{
Greg Clayton288bdf92010-09-02 02:59:18 +0000490 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491}
492
493
494void
495ValueObject::SetValueIsValid (bool b)
496{
Greg Clayton288bdf92010-09-02 02:59:18 +0000497 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000498}
499
500bool
Jim Ingham6035b672011-03-31 00:19:25 +0000501ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000502{
Jim Ingham6035b672011-03-31 00:19:25 +0000503 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000504 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000505}
506
507void
508ValueObject::SetValueDidChange (bool value_changed)
509{
Greg Clayton288bdf92010-09-02 02:59:18 +0000510 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511}
512
513ValueObjectSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000514ValueObject::GetChildAtIndex (size_t idx, bool can_create)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515{
516 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000517 // We may need to update our value if we are dynamic
518 if (IsPossibleDynamicType ())
Enrico Granatac3e320a2011-08-02 17:27:39 +0000519 UpdateValueIfNeeded(false);
Greg Claytondea8cb42011-06-29 22:09:02 +0000520 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000522 // Check if we have already made the child value object?
Enrico Granata9d60f602012-03-09 03:09:58 +0000523 if (can_create && !m_children.HasChildAtIndex(idx))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000525 // No we haven't created the child at this index, so lets have our
526 // subclass do it and cache the result for quick future access.
Enrico Granata9d60f602012-03-09 03:09:58 +0000527 m_children.SetChildAtIndex(idx,CreateChildAtIndex (idx, false, 0));
Jim Ingham78a685a2011-04-16 00:01:13 +0000528 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000529
Enrico Granata9d60f602012-03-09 03:09:58 +0000530 ValueObject* child = m_children.GetChildAtIndex(idx);
531 if (child != NULL)
532 return child->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533 }
534 return child_sp;
535}
536
Enrico Granata3309d882013-01-12 01:00:22 +0000537ValueObjectSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000538ValueObject::GetChildAtIndexPath (const std::initializer_list<size_t>& idxs,
539 size_t* index_of_error)
Enrico Granata3309d882013-01-12 01:00:22 +0000540{
541 if (idxs.size() == 0)
542 return GetSP();
543 ValueObjectSP root(GetSP());
Greg Claytonc7bece562013-01-25 18:06:21 +0000544 for (size_t idx : idxs)
Enrico Granata3309d882013-01-12 01:00:22 +0000545 {
546 root = root->GetChildAtIndex(idx, true);
547 if (!root)
548 {
549 if (index_of_error)
550 *index_of_error = idx;
551 return root;
552 }
553 }
554 return root;
555}
556
557ValueObjectSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000558ValueObject::GetChildAtIndexPath (const std::initializer_list< std::pair<size_t, bool> >& idxs,
559 size_t* index_of_error)
Enrico Granata3309d882013-01-12 01:00:22 +0000560{
561 if (idxs.size() == 0)
562 return GetSP();
563 ValueObjectSP root(GetSP());
Greg Claytonc7bece562013-01-25 18:06:21 +0000564 for (std::pair<size_t, bool> idx : idxs)
Enrico Granata3309d882013-01-12 01:00:22 +0000565 {
566 root = root->GetChildAtIndex(idx.first, idx.second);
567 if (!root)
568 {
569 if (index_of_error)
570 *index_of_error = idx.first;
571 return root;
572 }
573 }
574 return root;
575}
576
577lldb::ValueObjectSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000578ValueObject::GetChildAtIndexPath (const std::vector<size_t> &idxs,
579 size_t* index_of_error)
Enrico Granata3309d882013-01-12 01:00:22 +0000580{
581 if (idxs.size() == 0)
582 return GetSP();
583 ValueObjectSP root(GetSP());
Greg Claytonc7bece562013-01-25 18:06:21 +0000584 for (size_t idx : idxs)
Enrico Granata3309d882013-01-12 01:00:22 +0000585 {
586 root = root->GetChildAtIndex(idx, true);
587 if (!root)
588 {
589 if (index_of_error)
590 *index_of_error = idx;
591 return root;
592 }
593 }
594 return root;
595}
596
597lldb::ValueObjectSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000598ValueObject::GetChildAtIndexPath (const std::vector< std::pair<size_t, bool> > &idxs,
599 size_t* index_of_error)
Enrico Granata3309d882013-01-12 01:00:22 +0000600{
601 if (idxs.size() == 0)
602 return GetSP();
603 ValueObjectSP root(GetSP());
Greg Claytonc7bece562013-01-25 18:06:21 +0000604 for (std::pair<size_t, bool> idx : idxs)
Enrico Granata3309d882013-01-12 01:00:22 +0000605 {
606 root = root->GetChildAtIndex(idx.first, idx.second);
607 if (!root)
608 {
609 if (index_of_error)
610 *index_of_error = idx.first;
611 return root;
612 }
613 }
614 return root;
615}
616
Greg Claytonc7bece562013-01-25 18:06:21 +0000617size_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618ValueObject::GetIndexOfChildWithName (const ConstString &name)
619{
620 bool omit_empty_base_classes = true;
621 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000622 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000623 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000624 omit_empty_base_classes);
625}
626
627ValueObjectSP
628ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
629{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000630 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000631 // classes (which really aren't part of the expression path), so we
632 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000633 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000634
Greg Claytondea8cb42011-06-29 22:09:02 +0000635 // We may need to update our value if we are dynamic
636 if (IsPossibleDynamicType ())
Enrico Granatac3e320a2011-08-02 17:27:39 +0000637 UpdateValueIfNeeded(false);
Greg Claytondea8cb42011-06-29 22:09:02 +0000638
639 std::vector<uint32_t> child_indexes;
640 clang::ASTContext *clang_ast = GetClangAST();
641 void *clang_type = GetClangType();
642 bool omit_empty_base_classes = true;
643 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
644 clang_type,
645 name.GetCString(),
646 omit_empty_base_classes,
647 child_indexes);
648 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000650 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
651 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
652
653 child_sp = GetChildAtIndex(*pos, can_create);
654 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000655 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000656 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000657 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000658 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
659 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000660 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000661 else
662 {
663 child_sp.reset();
664 }
665
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666 }
667 }
668 return child_sp;
669}
670
671
Greg Claytonc7bece562013-01-25 18:06:21 +0000672size_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000673ValueObject::GetNumChildren ()
674{
Enrico Granatac5bc4122012-03-27 02:35:13 +0000675 UpdateValueIfNeeded();
Greg Clayton288bdf92010-09-02 02:59:18 +0000676 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000677 {
678 SetNumChildren (CalculateNumChildren());
679 }
Enrico Granata9d60f602012-03-09 03:09:58 +0000680 return m_children.GetChildrenCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681}
Greg Clayton4a792072012-10-23 01:50:10 +0000682
683bool
684ValueObject::MightHaveChildren()
685{
Enrico Granatadb8142b2012-10-23 02:07:54 +0000686 bool has_children = false;
Greg Clayton2452ab72013-02-08 22:02:02 +0000687 const uint32_t type_info = GetTypeInfo();
688 if (type_info)
Greg Clayton4a792072012-10-23 01:50:10 +0000689 {
Greg Clayton4a792072012-10-23 01:50:10 +0000690 if (type_info & (ClangASTContext::eTypeHasChildren |
691 ClangASTContext::eTypeIsPointer |
692 ClangASTContext::eTypeIsReference))
693 has_children = true;
694 }
695 else
696 {
697 has_children = GetNumChildren () > 0;
698 }
699 return has_children;
700}
701
702// Should only be called by ValueObject::GetNumChildren()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703void
Greg Claytonc7bece562013-01-25 18:06:21 +0000704ValueObject::SetNumChildren (size_t num_children)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000705{
Greg Clayton288bdf92010-09-02 02:59:18 +0000706 m_children_count_valid = true;
Enrico Granata9d60f602012-03-09 03:09:58 +0000707 m_children.SetChildrenCount(num_children);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000708}
709
710void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711ValueObject::SetName (const ConstString &name)
712{
713 m_name = name;
714}
715
Jim Ingham58b59f92011-04-22 23:53:53 +0000716ValueObject *
Greg Claytonc7bece562013-01-25 18:06:21 +0000717ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718{
Jim Ingham2eec4872011-05-07 00:10:58 +0000719 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000720
Greg Claytondea8cb42011-06-29 22:09:02 +0000721 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +0000722 bool ignore_array_bounds = synthetic_array_member;
Greg Claytondea8cb42011-06-29 22:09:02 +0000723 std::string child_name_str;
724 uint32_t child_byte_size = 0;
725 int32_t child_byte_offset = 0;
726 uint32_t child_bitfield_bit_size = 0;
727 uint32_t child_bitfield_bit_offset = 0;
728 bool child_is_base_class = false;
729 bool child_is_deref_of_parent = false;
730
731 const bool transparent_pointers = synthetic_array_member == false;
732 clang::ASTContext *clang_ast = GetClangAST();
733 clang_type_t clang_type = GetClangType();
734 clang_type_t child_clang_type;
735
Greg Claytoncc4d0142012-02-17 07:49:44 +0000736 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytondea8cb42011-06-29 22:09:02 +0000737
738 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
739 clang_ast,
740 GetName().GetCString(),
741 clang_type,
742 idx,
743 transparent_pointers,
744 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +0000745 ignore_array_bounds,
Greg Claytondea8cb42011-06-29 22:09:02 +0000746 child_name_str,
747 child_byte_size,
748 child_byte_offset,
749 child_bitfield_bit_size,
750 child_bitfield_bit_offset,
751 child_is_base_class,
752 child_is_deref_of_parent);
Greg Clayton4ef877f2012-12-06 02:33:54 +0000753 if (child_clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000755 if (synthetic_index)
756 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757
Greg Claytondea8cb42011-06-29 22:09:02 +0000758 ConstString child_name;
759 if (!child_name_str.empty())
760 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761
Greg Claytondea8cb42011-06-29 22:09:02 +0000762 valobj = new ValueObjectChild (*this,
763 clang_ast,
764 child_clang_type,
765 child_name,
766 child_byte_size,
767 child_byte_offset,
768 child_bitfield_bit_size,
769 child_bitfield_bit_offset,
770 child_is_base_class,
Enrico Granata9128ee22011-09-06 19:20:51 +0000771 child_is_deref_of_parent,
772 eAddressTypeInvalid);
773 //if (valobj)
774 // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid);
775 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000776
Jim Ingham58b59f92011-04-22 23:53:53 +0000777 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000778}
779
Enrico Granata0c489f52012-03-01 04:24:26 +0000780bool
781ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr,
782 std::string& destination)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000783{
Enrico Granata0c489f52012-03-01 04:24:26 +0000784 destination.clear();
785
786 // ideally we would like to bail out if passing NULL, but if we do so
787 // we end up not providing the summary for function pointers anymore
788 if (/*summary_ptr == NULL ||*/ m_is_getting_summary)
789 return false;
Greg Clayton48ca8b82012-01-07 20:58:07 +0000790
791 m_is_getting_summary = true;
Enrico Granataf18c03e2012-04-04 17:34:10 +0000792
793 // this is a hot path in code and we prefer to avoid setting this string all too often also clearing out other
794 // information that we might care to see in a crash log. might be useful in very specific situations though.
795 /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s. Summary provider's description is %s",
796 GetTypeName().GetCString(),
797 GetName().GetCString(),
798 summary_ptr->GetDescription().c_str());*/
799
Enrico Granata0c489f52012-03-01 04:24:26 +0000800 if (UpdateValueIfNeeded (false))
801 {
802 if (summary_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000803 {
Enrico Granata86cc9822012-03-19 22:58:49 +0000804 if (HasSyntheticValue())
805 m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on the synthetic children being up-to-date (e.g. ${svar%#})
806 summary_ptr->FormatObject(this, destination);
Enrico Granata0c489f52012-03-01 04:24:26 +0000807 }
808 else
809 {
810 clang_type_t clang_type = GetClangType();
811
812 // Do some default printout for function pointers
813 if (clang_type)
Enrico Granata4becb372011-06-29 22:27:15 +0000814 {
Enrico Granata0c489f52012-03-01 04:24:26 +0000815 StreamString sstr;
816 clang_type_t elem_or_pointee_clang_type;
817 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
818 GetClangAST(),
819 &elem_or_pointee_clang_type));
820
821 if (ClangASTContext::IsFunctionPointerType (clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000822 {
Enrico Granata0c489f52012-03-01 04:24:26 +0000823 AddressType func_ptr_address_type = eAddressTypeInvalid;
824 addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type);
825 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
Enrico Granataf2bbf712011-07-15 02:26:42 +0000826 {
Enrico Granata0c489f52012-03-01 04:24:26 +0000827 switch (func_ptr_address_type)
Jim Ingham6035b672011-03-31 00:19:25 +0000828 {
Greg Claytoncc4d0142012-02-17 07:49:44 +0000829 case eAddressTypeInvalid:
830 case eAddressTypeFile:
831 break;
Enrico Granata0c489f52012-03-01 04:24:26 +0000832
Greg Claytoncc4d0142012-02-17 07:49:44 +0000833 case eAddressTypeLoad:
Enrico Granata0c489f52012-03-01 04:24:26 +0000834 {
835 ExecutionContext exe_ctx (GetExecutionContextRef());
836
837 Address so_addr;
838 Target *target = exe_ctx.GetTargetPtr();
839 if (target && target->GetSectionLoadList().IsEmpty() == false)
Greg Claytoncc4d0142012-02-17 07:49:44 +0000840 {
Enrico Granata0c489f52012-03-01 04:24:26 +0000841 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
Enrico Granataf2bbf712011-07-15 02:26:42 +0000842 {
Enrico Granata0c489f52012-03-01 04:24:26 +0000843 so_addr.Dump (&sstr,
844 exe_ctx.GetBestExecutionContextScope(),
845 Address::DumpStyleResolvedDescription,
846 Address::DumpStyleSectionNameOffset);
Enrico Granataf2bbf712011-07-15 02:26:42 +0000847 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000848 }
Enrico Granata0c489f52012-03-01 04:24:26 +0000849 }
Greg Claytoncc4d0142012-02-17 07:49:44 +0000850 break;
Enrico Granata0c489f52012-03-01 04:24:26 +0000851
Greg Claytoncc4d0142012-02-17 07:49:44 +0000852 case eAddressTypeHost:
853 break;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000854 }
Enrico Granata0c489f52012-03-01 04:24:26 +0000855 }
856 if (sstr.GetSize() > 0)
857 {
858 destination.assign (1, '(');
859 destination.append (sstr.GetData(), sstr.GetSize());
860 destination.append (1, ')');
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000861 }
862 }
863 }
864 }
865 }
Greg Clayton48ca8b82012-01-07 20:58:07 +0000866 m_is_getting_summary = false;
Enrico Granata0c489f52012-03-01 04:24:26 +0000867 return !destination.empty();
868}
869
870const char *
871ValueObject::GetSummaryAsCString ()
872{
873 if (UpdateValueIfNeeded(true) && m_summary_str.empty())
874 {
875 GetSummaryAsCString(GetSummaryFormat().get(),
876 m_summary_str);
877 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000878 if (m_summary_str.empty())
879 return NULL;
880 return m_summary_str.c_str();
881}
882
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000883bool
884ValueObject::IsCStringContainer(bool check_pointer)
885{
886 clang_type_t elem_or_pointee_clang_type;
Greg Clayton2452ab72013-02-08 22:02:02 +0000887 const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000888 bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
Greg Clayton2452ab72013-02-08 22:02:02 +0000889 ClangASTContext::IsCharType (elem_or_pointee_clang_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000890 if (!is_char_arr_ptr)
891 return false;
892 if (!check_pointer)
893 return true;
894 if (type_flags.Test(ClangASTContext::eTypeIsArray))
895 return true;
Greg Claytonafacd142011-09-02 01:15:17 +0000896 addr_t cstr_address = LLDB_INVALID_ADDRESS;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000897 AddressType cstr_address_type = eAddressTypeInvalid;
Enrico Granata9128ee22011-09-06 19:20:51 +0000898 cstr_address = GetAddressOf (true, &cstr_address_type);
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000899 return (cstr_address != LLDB_INVALID_ADDRESS);
900}
901
Enrico Granata9128ee22011-09-06 19:20:51 +0000902size_t
903ValueObject::GetPointeeData (DataExtractor& data,
904 uint32_t item_idx,
905 uint32_t item_count)
906{
Greg Clayton2452ab72013-02-08 22:02:02 +0000907 clang_type_t pointee_or_element_clang_type;
908 const uint32_t type_info = GetTypeInfo (&pointee_or_element_clang_type);
909 const bool is_pointer_type = type_info & ClangASTContext::eTypeIsPointer;
910 const bool is_array_type = type_info & ClangASTContext::eTypeIsArray;
911 if (!(is_pointer_type || is_array_type))
Enrico Granata9128ee22011-09-06 19:20:51 +0000912 return 0;
913
914 if (item_count == 0)
915 return 0;
916
Greg Clayton2452ab72013-02-08 22:02:02 +0000917 clang::ASTContext *ast = GetClangAST();
918 ClangASTType pointee_or_element_type(ast, pointee_or_element_clang_type);
Enrico Granata9128ee22011-09-06 19:20:51 +0000919
Greg Clayton2452ab72013-02-08 22:02:02 +0000920 const uint64_t item_type_size = pointee_or_element_type.GetClangTypeByteSize();
Enrico Granata9128ee22011-09-06 19:20:51 +0000921
922 const uint64_t bytes = item_count * item_type_size;
923
924 const uint64_t offset = item_idx * item_type_size;
925
926 if (item_idx == 0 && item_count == 1) // simply a deref
927 {
Greg Clayton2452ab72013-02-08 22:02:02 +0000928 if (is_pointer_type)
Enrico Granata9128ee22011-09-06 19:20:51 +0000929 {
930 Error error;
931 ValueObjectSP pointee_sp = Dereference(error);
932 if (error.Fail() || pointee_sp.get() == NULL)
933 return 0;
934 return pointee_sp->GetDataExtractor().Copy(data);
935 }
936 else
937 {
938 ValueObjectSP child_sp = GetChildAtIndex(0, true);
939 if (child_sp.get() == NULL)
940 return 0;
941 return child_sp->GetDataExtractor().Copy(data);
942 }
943 return true;
944 }
945 else /* (items > 1) */
946 {
947 Error error;
948 lldb_private::DataBufferHeap* heap_buf_ptr = NULL;
949 lldb::DataBufferSP data_sp(heap_buf_ptr = new lldb_private::DataBufferHeap());
950
951 AddressType addr_type;
Greg Clayton2452ab72013-02-08 22:02:02 +0000952 lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type);
Enrico Granata9128ee22011-09-06 19:20:51 +0000953
Enrico Granata9128ee22011-09-06 19:20:51 +0000954 switch (addr_type)
955 {
956 case eAddressTypeFile:
957 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000958 ModuleSP module_sp (GetModule());
959 if (module_sp)
Enrico Granata9128ee22011-09-06 19:20:51 +0000960 {
Enrico Granata9c2efe32012-08-07 01:49:34 +0000961 addr = addr + offset;
Enrico Granata9128ee22011-09-06 19:20:51 +0000962 Address so_addr;
Greg Claytone72dfb32012-02-24 01:59:29 +0000963 module_sp->ResolveFileAddress(addr, so_addr);
Greg Claytoncc4d0142012-02-17 07:49:44 +0000964 ExecutionContext exe_ctx (GetExecutionContextRef());
965 Target* target = exe_ctx.GetTargetPtr();
966 if (target)
Enrico Granata9128ee22011-09-06 19:20:51 +0000967 {
Greg Claytoncc4d0142012-02-17 07:49:44 +0000968 heap_buf_ptr->SetByteSize(bytes);
969 size_t bytes_read = target->ReadMemory(so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
970 if (error.Success())
Enrico Granata9128ee22011-09-06 19:20:51 +0000971 {
Greg Claytoncc4d0142012-02-17 07:49:44 +0000972 data.SetData(data_sp);
973 return bytes_read;
Enrico Granata9128ee22011-09-06 19:20:51 +0000974 }
975 }
976 }
977 }
978 break;
979 case eAddressTypeLoad:
Enrico Granata9128ee22011-09-06 19:20:51 +0000980 {
Greg Claytoncc4d0142012-02-17 07:49:44 +0000981 ExecutionContext exe_ctx (GetExecutionContextRef());
982 Process *process = exe_ctx.GetProcessPtr();
Enrico Granata9128ee22011-09-06 19:20:51 +0000983 if (process)
984 {
985 heap_buf_ptr->SetByteSize(bytes);
986 size_t bytes_read = process->ReadMemory(addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
987 if (error.Success())
988 {
989 data.SetData(data_sp);
990 return bytes_read;
991 }
992 }
993 }
994 break;
995 case eAddressTypeHost:
996 {
Greg Clayton2452ab72013-02-08 22:02:02 +0000997 ClangASTType valobj_type(ast, GetClangType());
998 uint64_t max_bytes = valobj_type.GetClangTypeByteSize();
999 if (max_bytes > offset)
1000 {
1001 size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes);
1002 heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes_read);
1003 data.SetData(data_sp);
1004 return bytes_read;
1005 }
Enrico Granata9128ee22011-09-06 19:20:51 +00001006 }
1007 break;
1008 case eAddressTypeInvalid:
Enrico Granata9128ee22011-09-06 19:20:51 +00001009 break;
1010 }
1011 }
1012 return 0;
1013}
1014
Greg Claytonfaac1112013-03-14 18:31:44 +00001015uint64_t
Enrico Granata9128ee22011-09-06 19:20:51 +00001016ValueObject::GetData (DataExtractor& data)
1017{
1018 UpdateValueIfNeeded(false);
Greg Claytoncc4d0142012-02-17 07:49:44 +00001019 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytone72dfb32012-02-24 01:59:29 +00001020 Error error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), data, 0, GetModule().get());
Enrico Granata9128ee22011-09-06 19:20:51 +00001021 if (error.Fail())
Sean Callananed185ab2013-04-19 19:47:32 +00001022 {
1023 if (m_data.GetByteSize())
1024 {
1025 data = m_data;
1026 return data.GetByteSize();
1027 }
1028 else
1029 {
1030 return 0;
1031 }
1032 }
Enrico Granata9128ee22011-09-06 19:20:51 +00001033 data.SetAddressByteSize(m_data.GetAddressByteSize());
1034 data.SetByteOrder(m_data.GetByteOrder());
1035 return data.GetByteSize();
1036}
1037
Sean Callanan389823e2013-04-13 01:21:23 +00001038bool
1039ValueObject::SetData (DataExtractor &data, Error &error)
1040{
1041 error.Clear();
1042 // Make sure our value is up to date first so that our location and location
1043 // type is valid.
1044 if (!UpdateValueIfNeeded(false))
1045 {
1046 error.SetErrorString("unable to read value");
1047 return false;
1048 }
1049
1050 uint64_t count = 0;
1051 Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
1052
1053 const size_t byte_size = GetByteSize();
1054
1055 Value::ValueType value_type = m_value.GetValueType();
1056
1057 switch (value_type)
1058 {
1059 case Value::eValueTypeScalar:
1060 {
1061 Error set_error = m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
1062
1063 if (!set_error.Success())
1064 {
1065 error.SetErrorStringWithFormat("unable to set scalar value: %s", set_error.AsCString());
1066 return false;
1067 }
1068 }
1069 break;
1070 case Value::eValueTypeLoadAddress:
1071 {
1072 // If it is a load address, then the scalar value is the storage location
1073 // of the data, and we have to shove this value down to that load location.
1074 ExecutionContext exe_ctx (GetExecutionContextRef());
1075 Process *process = exe_ctx.GetProcessPtr();
1076 if (process)
1077 {
1078 addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1079 size_t bytes_written = process->WriteMemory(target_addr,
1080 data.GetDataStart(),
1081 byte_size,
1082 error);
1083 if (!error.Success())
1084 return false;
1085 if (bytes_written != byte_size)
1086 {
1087 error.SetErrorString("unable to write value to memory");
1088 return false;
1089 }
1090 }
1091 }
1092 break;
1093 case Value::eValueTypeHostAddress:
1094 {
1095 // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
1096 DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0));
1097 m_data.SetData(buffer_sp, 0);
1098 data.CopyByteOrderedData (0,
1099 byte_size,
1100 const_cast<uint8_t *>(m_data.GetDataStart()),
1101 byte_size,
1102 m_data.GetByteOrder());
1103 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1104 }
1105 break;
1106 case Value::eValueTypeFileAddress:
1107 case Value::eValueTypeVector:
1108 break;
1109 }
1110
1111 // If we have reached this point, then we have successfully changed the value.
1112 SetNeedsUpdate();
1113 return true;
1114}
1115
Enrico Granata9128ee22011-09-06 19:20:51 +00001116// will compute strlen(str), but without consuming more than
1117// maxlen bytes out of str (this serves the purpose of reading
1118// chunks of a string without having to worry about
1119// missing NULL terminators in the chunk)
1120// of course, if strlen(str) > maxlen, the function will return
1121// maxlen_value (which should be != maxlen, because that allows you
1122// to know whether strlen(str) == maxlen or strlen(str) > maxlen)
1123static uint32_t
1124strlen_or_inf (const char* str,
1125 uint32_t maxlen,
1126 uint32_t maxlen_value)
1127{
1128 uint32_t len = 0;
Greg Clayton8dd5c172011-10-05 22:19:51 +00001129 if (str)
Enrico Granata9128ee22011-09-06 19:20:51 +00001130 {
Greg Clayton8dd5c172011-10-05 22:19:51 +00001131 while(*str)
1132 {
1133 len++;str++;
Greg Clayton2452ab72013-02-08 22:02:02 +00001134 if (len >= maxlen)
Greg Clayton8dd5c172011-10-05 22:19:51 +00001135 return maxlen_value;
1136 }
Enrico Granata9128ee22011-09-06 19:20:51 +00001137 }
1138 return len;
1139}
1140
Enrico Granataea2bc0f2013-02-21 19:57:10 +00001141size_t
Greg Claytoncc4d0142012-02-17 07:49:44 +00001142ValueObject::ReadPointedString (Stream& s,
1143 Error& error,
1144 uint32_t max_length,
1145 bool honor_array,
1146 Format item_format)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001147{
Greg Claytoncc4d0142012-02-17 07:49:44 +00001148 ExecutionContext exe_ctx (GetExecutionContextRef());
1149 Target* target = exe_ctx.GetTargetPtr();
1150
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001151 if (!target)
1152 {
1153 s << "<no target to read from>";
1154 error.SetErrorString("no target to read from");
1155 return 0;
1156 }
1157
1158 if (max_length == 0)
Greg Claytoncc4d0142012-02-17 07:49:44 +00001159 max_length = target->GetMaximumSizeOfStringSummary();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001160
Enrico Granataea2bc0f2013-02-21 19:57:10 +00001161 size_t bytes_read = 0;
1162 size_t total_bytes_read = 0;
1163
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001164 clang_type_t clang_type = GetClangType();
1165 clang_type_t elem_or_pointee_clang_type;
Greg Clayton2452ab72013-02-08 22:02:02 +00001166 const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001167 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
1168 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
1169 {
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001170 addr_t cstr_address = LLDB_INVALID_ADDRESS;
1171 AddressType cstr_address_type = eAddressTypeInvalid;
1172
1173 size_t cstr_len = 0;
1174 bool capped_data = false;
1175 if (type_flags.Test (ClangASTContext::eTypeIsArray))
Greg Claytoncc4d0142012-02-17 07:49:44 +00001176 {
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001177 // We have an array
1178 cstr_len = ClangASTContext::GetArraySize (clang_type);
1179 if (cstr_len > max_length)
1180 {
1181 capped_data = true;
1182 cstr_len = max_length;
1183 }
1184 cstr_address = GetAddressOf (true, &cstr_address_type);
Greg Claytoncc4d0142012-02-17 07:49:44 +00001185 }
1186 else
1187 {
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001188 // We have a pointer
1189 cstr_address = GetPointerValue (&cstr_address_type);
1190 }
1191
1192 if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS)
1193 {
1194 s << "<invalid address>";
1195 error.SetErrorString("invalid address");
1196 return 0;
1197 }
1198
1199 Address cstr_so_addr (cstr_address);
1200 DataExtractor data;
1201 if (cstr_len > 0 && honor_array)
1202 {
1203 // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
1204 // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
1205 GetPointeeData(data, 0, cstr_len);
1206
1207 if ((bytes_read = data.GetByteSize()) > 0)
1208 {
1209 total_bytes_read = bytes_read;
1210 s << '"';
1211 data.Dump (&s,
1212 0, // Start offset in "data"
1213 item_format,
1214 1, // Size of item (1 byte for a char!)
1215 bytes_read, // How many bytes to print?
1216 UINT32_MAX, // num per line
1217 LLDB_INVALID_ADDRESS,// base address
1218 0, // bitfield bit size
1219 0); // bitfield bit offset
1220 if (capped_data)
1221 s << "...";
1222 s << '"';
1223 }
1224 }
1225 else
1226 {
1227 cstr_len = max_length;
1228 const size_t k_max_buf_size = 64;
1229
1230 size_t offset = 0;
Greg Claytoncc4d0142012-02-17 07:49:44 +00001231
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001232 int cstr_len_displayed = -1;
1233 bool capped_cstr = false;
1234 // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
1235 // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
1236 while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001237 {
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001238 total_bytes_read += bytes_read;
1239 const char *cstr = data.PeekCStr(0);
1240 size_t len = strlen_or_inf (cstr, k_max_buf_size, k_max_buf_size+1);
1241 if (len > k_max_buf_size)
1242 len = k_max_buf_size;
1243 if (cstr && cstr_len_displayed < 0)
1244 s << '"';
1245
1246 if (cstr_len_displayed < 0)
1247 cstr_len_displayed = len;
1248
1249 if (len == 0)
1250 break;
1251 cstr_len_displayed += len;
1252 if (len > bytes_read)
1253 len = bytes_read;
1254 if (len > cstr_len)
1255 len = cstr_len;
1256
1257 data.Dump (&s,
1258 0, // Start offset in "data"
1259 item_format,
1260 1, // Size of item (1 byte for a char!)
1261 len, // How many bytes to print?
1262 UINT32_MAX, // num per line
1263 LLDB_INVALID_ADDRESS,// base address
1264 0, // bitfield bit size
1265 0); // bitfield bit offset
1266
1267 if (len < k_max_buf_size)
1268 break;
1269
1270 if (len >= cstr_len)
Enrico Granata6f3533f2011-07-29 19:53:35 +00001271 {
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001272 capped_cstr = true;
1273 break;
Greg Claytoncc4d0142012-02-17 07:49:44 +00001274 }
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001275
1276 cstr_len -= len;
1277 offset += len;
Greg Claytoncc4d0142012-02-17 07:49:44 +00001278 }
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001279
1280 if (cstr_len_displayed >= 0)
Greg Claytoncc4d0142012-02-17 07:49:44 +00001281 {
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001282 s << '"';
1283 if (capped_cstr)
1284 s << "...";
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001285 }
Greg Claytoncc4d0142012-02-17 07:49:44 +00001286 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001287 }
1288 else
1289 {
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001290 error.SetErrorString("not a string object");
Enrico Granata6f3533f2011-07-29 19:53:35 +00001291 s << "<not a string object>";
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001292 }
Enrico Granataea2bc0f2013-02-21 19:57:10 +00001293 return total_bytes_read;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001294}
1295
Jim Ingham53c47f12010-09-10 23:12:17 +00001296const char *
Jim Ingham6035b672011-03-31 00:19:25 +00001297ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +00001298{
Enrico Granata0a3958e2011-07-02 00:25:22 +00001299
Enrico Granatad8b5fce2011-08-02 23:12:24 +00001300 if (!UpdateValueIfNeeded (true))
Jim Ingham53c47f12010-09-10 23:12:17 +00001301 return NULL;
Enrico Granata0a3958e2011-07-02 00:25:22 +00001302
1303 if (!m_object_desc_str.empty())
1304 return m_object_desc_str.c_str();
1305
Greg Claytoncc4d0142012-02-17 07:49:44 +00001306 ExecutionContext exe_ctx (GetExecutionContextRef());
1307 Process *process = exe_ctx.GetProcessPtr();
Jim Ingham5a369122010-09-28 01:25:32 +00001308 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +00001309 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +00001310
Jim Ingham53c47f12010-09-10 23:12:17 +00001311 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +00001312
Greg Claytonafacd142011-09-02 01:15:17 +00001313 LanguageType language = GetObjectRuntimeLanguage();
Jim Ingham5a369122010-09-28 01:25:32 +00001314 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
1315
Jim Inghama2cf2632010-12-23 02:29:54 +00001316 if (runtime == NULL)
1317 {
Jim Inghamb7603bb2011-03-18 00:05:18 +00001318 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +00001319 clang_type_t opaque_qual_type = GetClangType();
1320 if (opaque_qual_type != NULL)
1321 {
Jim Inghamb7603bb2011-03-18 00:05:18 +00001322 bool is_signed;
1323 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
1324 || ClangASTContext::IsPointerType (opaque_qual_type))
1325 {
Greg Claytonafacd142011-09-02 01:15:17 +00001326 runtime = process->GetLanguageRuntime(eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +00001327 }
Jim Inghama2cf2632010-12-23 02:29:54 +00001328 }
1329 }
1330
Jim Ingham8d543de2011-03-31 23:01:21 +00001331 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +00001332 {
1333 m_object_desc_str.append (s.GetData());
1334 }
Sean Callanan672ad942010-10-23 00:18:49 +00001335
1336 if (m_object_desc_str.empty())
1337 return NULL;
1338 else
1339 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +00001340}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001341
Enrico Granata0c489f52012-03-01 04:24:26 +00001342bool
1343ValueObject::GetValueAsCString (lldb::Format format,
1344 std::string& destination)
1345{
1346 if (ClangASTContext::IsAggregateType (GetClangType()) == false &&
1347 UpdateValueIfNeeded(false))
1348 {
1349 const Value::ContextType context_type = m_value.GetContextType();
1350
1351 switch (context_type)
1352 {
1353 case Value::eContextTypeClangType:
1354 case Value::eContextTypeLLDBType:
1355 case Value::eContextTypeVariable:
1356 {
1357 clang_type_t clang_type = GetClangType ();
1358 if (clang_type)
1359 {
Enrico Granata852cce72013-03-23 01:12:38 +00001360 // put custom bytes to display in this DataExtractor to override the default value logic
1361 lldb_private::DataExtractor special_format_data;
1362 clang::ASTContext* ast = GetClangAST();
Enrico Granata123c39c2013-03-23 01:44:23 +00001363 if (format == eFormatCString)
Enrico Granata852cce72013-03-23 01:12:38 +00001364 {
Enrico Granata9d71afe2013-03-23 01:44:59 +00001365 Flags type_flags(ClangASTContext::GetTypeInfo(clang_type, ast, NULL));
Enrico Granata123c39c2013-03-23 01:44:23 +00001366 if (type_flags.Test(ClangASTContext::eTypeIsPointer) && !type_flags.Test(ClangASTContext::eTypeIsObjC))
Enrico Granata852cce72013-03-23 01:12:38 +00001367 {
1368 // if we are dumping a pointer as a c-string, get the pointee data as a string
1369 TargetSP target_sp(GetTargetSP());
1370 if (target_sp)
1371 {
1372 size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
1373 Error error;
1374 DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0));
1375 Address address(GetPointerValue());
1376 if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success())
1377 special_format_data.SetData(buffer_sp);
1378 }
1379 }
1380 }
1381
Enrico Granata0c489f52012-03-01 04:24:26 +00001382 StreamString sstr;
1383 ExecutionContext exe_ctx (GetExecutionContextRef());
Enrico Granata852cce72013-03-23 01:12:38 +00001384 ClangASTType::DumpTypeValue (ast, // The clang AST
1385 clang_type, // The clang type to display
1386 &sstr, // The stream to use for display
1387 format, // Format to display this type with
1388 special_format_data.GetByteSize() ?
1389 special_format_data: m_data, // Data to extract from
1390 0, // Byte offset into "m_data"
1391 GetByteSize(), // Byte size of item in "m_data"
1392 GetBitfieldBitSize(), // Bitfield bit size
1393 GetBitfieldBitOffset(), // Bitfield bit offset
Enrico Granata0c489f52012-03-01 04:24:26 +00001394 exe_ctx.GetBestExecutionContextScope());
1395 // Don't set the m_error to anything here otherwise
1396 // we won't be able to re-format as anything else. The
1397 // code for ClangASTType::DumpTypeValue() should always
1398 // return something, even if that something contains
1399 // an error messsage. "m_error" is used to detect errors
1400 // when reading the valid object, not for formatting errors.
1401 if (sstr.GetString().empty())
1402 destination.clear();
1403 else
1404 destination.swap(sstr.GetString());
1405 }
1406 }
1407 break;
1408
1409 case Value::eContextTypeRegisterInfo:
1410 {
1411 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1412 if (reg_info)
1413 {
1414 ExecutionContext exe_ctx (GetExecutionContextRef());
1415
1416 StreamString reg_sstr;
1417 m_data.Dump (&reg_sstr,
1418 0,
1419 format,
1420 reg_info->byte_size,
1421 1,
1422 UINT32_MAX,
1423 LLDB_INVALID_ADDRESS,
1424 0,
1425 0,
1426 exe_ctx.GetBestExecutionContextScope());
1427 destination.swap(reg_sstr.GetString());
1428 }
1429 }
1430 break;
1431
1432 default:
1433 break;
1434 }
1435 return !destination.empty();
1436 }
1437 else
1438 return false;
1439}
1440
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001441const char *
Jim Ingham6035b672011-03-31 00:19:25 +00001442ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001443{
Enrico Granata0c489f52012-03-01 04:24:26 +00001444 if (UpdateValueIfNeeded(true) && m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001445 {
Enrico Granata0c489f52012-03-01 04:24:26 +00001446 lldb::Format my_format = GetFormat();
Enrico Granatac953a6a2012-12-11 02:17:22 +00001447 if (my_format == lldb::eFormatDefault)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001448 {
Enrico Granata0c489f52012-03-01 04:24:26 +00001449 if (m_type_format_sp)
1450 my_format = m_type_format_sp->GetFormat();
1451 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001452 {
Enrico Granata0c489f52012-03-01 04:24:26 +00001453 if (m_is_bitfield_for_scalar)
1454 my_format = eFormatUnsigned;
1455 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001456 {
Enrico Granata0c489f52012-03-01 04:24:26 +00001457 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001458 {
1459 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1460 if (reg_info)
Enrico Granata0c489f52012-03-01 04:24:26 +00001461 my_format = reg_info->format;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001462 }
Enrico Granata0c489f52012-03-01 04:24:26 +00001463 else
1464 {
1465 clang_type_t clang_type = GetClangType ();
1466 my_format = ClangASTType::GetFormat(clang_type);
1467 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001468 }
1469 }
1470 }
Enrico Granata297e69f2012-03-06 23:21:16 +00001471 if (GetValueAsCString(my_format, m_value_str))
1472 {
1473 if (!m_value_did_change && m_old_value_valid)
1474 {
1475 // The value was gotten successfully, so we consider the
1476 // value as changed if the value string differs
1477 SetValueDidChange (m_old_value_str != m_value_str);
1478 }
1479 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001480 }
1481 if (m_value_str.empty())
1482 return NULL;
1483 return m_value_str.c_str();
1484}
1485
Enrico Granatac3e320a2011-08-02 17:27:39 +00001486// if > 8bytes, 0 is returned. this method should mostly be used
1487// to read address values out of pointers
Greg Clayton56d9a1b2011-08-22 02:49:39 +00001488uint64_t
Johnny Chen3f476c42012-06-05 19:37:43 +00001489ValueObject::GetValueAsUnsigned (uint64_t fail_value, bool *success)
Enrico Granatac3e320a2011-08-02 17:27:39 +00001490{
1491 // If our byte size is zero this is an aggregate type that has children
1492 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
1493 {
Greg Clayton56d9a1b2011-08-22 02:49:39 +00001494 Scalar scalar;
1495 if (ResolveValue (scalar))
Johnny Chen3f476c42012-06-05 19:37:43 +00001496 {
1497 if (success)
1498 *success = true;
Enrico Granata48ea80f2012-10-24 20:24:39 +00001499 return scalar.ULongLong(fail_value);
Johnny Chen3f476c42012-06-05 19:37:43 +00001500 }
1501 // fallthrough, otherwise...
Enrico Granatac3e320a2011-08-02 17:27:39 +00001502 }
Johnny Chen3f476c42012-06-05 19:37:43 +00001503
1504 if (success)
1505 *success = false;
Greg Clayton56d9a1b2011-08-22 02:49:39 +00001506 return fail_value;
Enrico Granatac3e320a2011-08-02 17:27:39 +00001507}
1508
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001509// if any more "special cases" are added to ValueObject::DumpPrintableRepresentation() please keep
1510// this call up to date by returning true for your new special cases. We will eventually move
1511// to checking this call result before trying to display special cases
1512bool
Enrico Granata86cc9822012-03-19 22:58:49 +00001513ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
1514 Format custom_format)
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001515{
1516 clang_type_t elem_or_pointee_type;
Greg Clayton2452ab72013-02-08 22:02:02 +00001517 Flags flags(GetTypeInfo(&elem_or_pointee_type));
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001518
1519 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
Enrico Granata86cc9822012-03-19 22:58:49 +00001520 && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001521 {
1522 if (IsCStringContainer(true) &&
Greg Claytonafacd142011-09-02 01:15:17 +00001523 (custom_format == eFormatCString ||
1524 custom_format == eFormatCharArray ||
1525 custom_format == eFormatChar ||
1526 custom_format == eFormatVectorOfChar))
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001527 return true;
1528
1529 if (flags.Test(ClangASTContext::eTypeIsArray))
1530 {
Greg Claytonafacd142011-09-02 01:15:17 +00001531 if ((custom_format == eFormatBytes) ||
1532 (custom_format == eFormatBytesWithASCII))
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001533 return true;
1534
Greg Claytonafacd142011-09-02 01:15:17 +00001535 if ((custom_format == eFormatVectorOfChar) ||
1536 (custom_format == eFormatVectorOfFloat32) ||
1537 (custom_format == eFormatVectorOfFloat64) ||
1538 (custom_format == eFormatVectorOfSInt16) ||
1539 (custom_format == eFormatVectorOfSInt32) ||
1540 (custom_format == eFormatVectorOfSInt64) ||
1541 (custom_format == eFormatVectorOfSInt8) ||
1542 (custom_format == eFormatVectorOfUInt128) ||
1543 (custom_format == eFormatVectorOfUInt16) ||
1544 (custom_format == eFormatVectorOfUInt32) ||
1545 (custom_format == eFormatVectorOfUInt64) ||
1546 (custom_format == eFormatVectorOfUInt8))
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001547 return true;
1548 }
1549 }
1550 return false;
1551}
1552
Enrico Granata9fc19442011-07-06 02:13:41 +00001553bool
1554ValueObject::DumpPrintableRepresentation(Stream& s,
1555 ValueObjectRepresentationStyle val_obj_display,
Greg Claytonafacd142011-09-02 01:15:17 +00001556 Format custom_format,
Enrico Granata86cc9822012-03-19 22:58:49 +00001557 PrintableRepresentationSpecialCases special)
Enrico Granata9fc19442011-07-06 02:13:41 +00001558{
Enrico Granataf4efecd2011-07-12 22:56:10 +00001559
1560 clang_type_t elem_or_pointee_type;
Greg Clayton2452ab72013-02-08 22:02:02 +00001561 Flags flags(GetTypeInfo(&elem_or_pointee_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001562
Enrico Granata86cc9822012-03-19 22:58:49 +00001563 bool allow_special = ((special & ePrintableRepresentationSpecialCasesAllow) == ePrintableRepresentationSpecialCasesAllow);
1564 bool only_special = ((special & ePrintableRepresentationSpecialCasesOnly) == ePrintableRepresentationSpecialCasesOnly);
1565
1566 if (allow_special)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001567 {
Enrico Granata86cc9822012-03-19 22:58:49 +00001568 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
1569 && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001570 {
Enrico Granata86cc9822012-03-19 22:58:49 +00001571 // when being asked to get a printable display an array or pointer type directly,
1572 // try to "do the right thing"
1573
1574 if (IsCStringContainer(true) &&
1575 (custom_format == eFormatCString ||
1576 custom_format == eFormatCharArray ||
1577 custom_format == eFormatChar ||
1578 custom_format == eFormatVectorOfChar)) // print char[] & char* directly
Enrico Granataf4efecd2011-07-12 22:56:10 +00001579 {
Enrico Granata86cc9822012-03-19 22:58:49 +00001580 Error error;
1581 ReadPointedString(s,
1582 error,
1583 0,
1584 (custom_format == eFormatVectorOfChar) ||
1585 (custom_format == eFormatCharArray));
1586 return !error.Fail();
Enrico Granataf4efecd2011-07-12 22:56:10 +00001587 }
1588
Enrico Granata86cc9822012-03-19 22:58:49 +00001589 if (custom_format == eFormatEnum)
1590 return false;
1591
1592 // this only works for arrays, because I have no way to know when
1593 // the pointed memory ends, and no special \0 end of data marker
1594 if (flags.Test(ClangASTContext::eTypeIsArray))
Enrico Granataf4efecd2011-07-12 22:56:10 +00001595 {
Enrico Granata86cc9822012-03-19 22:58:49 +00001596 if ((custom_format == eFormatBytes) ||
1597 (custom_format == eFormatBytesWithASCII))
Enrico Granataf4efecd2011-07-12 22:56:10 +00001598 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001599 const size_t count = GetNumChildren();
Enrico Granata86cc9822012-03-19 22:58:49 +00001600
1601 s << '[';
Greg Claytonc7bece562013-01-25 18:06:21 +00001602 for (size_t low = 0; low < count; low++)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001603 {
Enrico Granata86cc9822012-03-19 22:58:49 +00001604
1605 if (low)
1606 s << ',';
1607
1608 ValueObjectSP child = GetChildAtIndex(low,true);
1609 if (!child.get())
1610 {
1611 s << "<invalid child>";
1612 continue;
1613 }
1614 child->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleValue, custom_format);
1615 }
1616
1617 s << ']';
1618
1619 return true;
1620 }
Enrico Granataf4efecd2011-07-12 22:56:10 +00001621
Enrico Granata86cc9822012-03-19 22:58:49 +00001622 if ((custom_format == eFormatVectorOfChar) ||
1623 (custom_format == eFormatVectorOfFloat32) ||
1624 (custom_format == eFormatVectorOfFloat64) ||
1625 (custom_format == eFormatVectorOfSInt16) ||
1626 (custom_format == eFormatVectorOfSInt32) ||
1627 (custom_format == eFormatVectorOfSInt64) ||
1628 (custom_format == eFormatVectorOfSInt8) ||
1629 (custom_format == eFormatVectorOfUInt128) ||
1630 (custom_format == eFormatVectorOfUInt16) ||
1631 (custom_format == eFormatVectorOfUInt32) ||
1632 (custom_format == eFormatVectorOfUInt64) ||
1633 (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
1634 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001635 const size_t count = GetNumChildren();
Enrico Granata86cc9822012-03-19 22:58:49 +00001636
1637 Format format = FormatManager::GetSingleItemFormat(custom_format);
1638
1639 s << '[';
Greg Claytonc7bece562013-01-25 18:06:21 +00001640 for (size_t low = 0; low < count; low++)
Enrico Granata86cc9822012-03-19 22:58:49 +00001641 {
1642
1643 if (low)
1644 s << ',';
1645
1646 ValueObjectSP child = GetChildAtIndex(low,true);
1647 if (!child.get())
1648 {
1649 s << "<invalid child>";
1650 continue;
1651 }
1652 child->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleValue, format);
1653 }
1654
1655 s << ']';
1656
1657 return true;
1658 }
Enrico Granataf4efecd2011-07-12 22:56:10 +00001659 }
Enrico Granata86cc9822012-03-19 22:58:49 +00001660
1661 if ((custom_format == eFormatBoolean) ||
1662 (custom_format == eFormatBinary) ||
1663 (custom_format == eFormatChar) ||
1664 (custom_format == eFormatCharPrintable) ||
1665 (custom_format == eFormatComplexFloat) ||
1666 (custom_format == eFormatDecimal) ||
1667 (custom_format == eFormatHex) ||
Enrico Granata7ec18e32012-08-09 19:33:34 +00001668 (custom_format == eFormatHexUppercase) ||
Enrico Granata86cc9822012-03-19 22:58:49 +00001669 (custom_format == eFormatFloat) ||
1670 (custom_format == eFormatOctal) ||
1671 (custom_format == eFormatOSType) ||
1672 (custom_format == eFormatUnicode16) ||
1673 (custom_format == eFormatUnicode32) ||
1674 (custom_format == eFormatUnsigned) ||
1675 (custom_format == eFormatPointer) ||
1676 (custom_format == eFormatComplexInteger) ||
1677 (custom_format == eFormatComplex) ||
1678 (custom_format == eFormatDefault)) // use the [] operator
1679 return false;
Enrico Granataf4efecd2011-07-12 22:56:10 +00001680 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001681 }
Enrico Granata85933ed2011-08-18 16:38:26 +00001682
1683 if (only_special)
1684 return false;
1685
Enrico Granata86cc9822012-03-19 22:58:49 +00001686 bool var_success = false;
1687
1688 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001689 const char *cstr = NULL;
1690 StreamString strm;
Enrico Granata86cc9822012-03-19 22:58:49 +00001691
1692 if (custom_format != eFormatInvalid)
1693 SetFormat(custom_format);
1694
1695 switch(val_obj_display)
1696 {
1697 case eValueObjectRepresentationStyleValue:
Greg Claytonc7bece562013-01-25 18:06:21 +00001698 cstr = GetValueAsCString();
Enrico Granata86cc9822012-03-19 22:58:49 +00001699 break;
1700
1701 case eValueObjectRepresentationStyleSummary:
Greg Claytonc7bece562013-01-25 18:06:21 +00001702 cstr = GetSummaryAsCString();
Enrico Granata86cc9822012-03-19 22:58:49 +00001703 break;
1704
1705 case eValueObjectRepresentationStyleLanguageSpecific:
Greg Claytonc7bece562013-01-25 18:06:21 +00001706 cstr = GetObjectDescription();
Enrico Granata86cc9822012-03-19 22:58:49 +00001707 break;
1708
1709 case eValueObjectRepresentationStyleLocation:
Greg Claytonc7bece562013-01-25 18:06:21 +00001710 cstr = GetLocationAsCString();
Enrico Granata86cc9822012-03-19 22:58:49 +00001711 break;
1712
1713 case eValueObjectRepresentationStyleChildrenCount:
Greg Claytonc7bece562013-01-25 18:06:21 +00001714 strm.Printf("%zu", GetNumChildren());
1715 cstr = strm.GetString().c_str();
Enrico Granata86cc9822012-03-19 22:58:49 +00001716 break;
1717
1718 case eValueObjectRepresentationStyleType:
Greg Claytonc7bece562013-01-25 18:06:21 +00001719 cstr = GetTypeName().AsCString();
Enrico Granata86cc9822012-03-19 22:58:49 +00001720 break;
Enrico Granata86cc9822012-03-19 22:58:49 +00001721 }
1722
Greg Claytonc7bece562013-01-25 18:06:21 +00001723 if (!cstr)
Enrico Granata86cc9822012-03-19 22:58:49 +00001724 {
1725 if (val_obj_display == eValueObjectRepresentationStyleValue)
Greg Claytonc7bece562013-01-25 18:06:21 +00001726 cstr = GetSummaryAsCString();
Enrico Granata86cc9822012-03-19 22:58:49 +00001727 else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1728 {
1729 if (ClangASTContext::IsAggregateType (GetClangType()) == true)
1730 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001731 strm.Printf("%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
1732 cstr = strm.GetString().c_str();
Enrico Granata86cc9822012-03-19 22:58:49 +00001733 }
1734 else
Greg Claytonc7bece562013-01-25 18:06:21 +00001735 cstr = GetValueAsCString();
Enrico Granata86cc9822012-03-19 22:58:49 +00001736 }
1737 }
1738
Greg Claytonc7bece562013-01-25 18:06:21 +00001739 if (cstr)
1740 s.PutCString(cstr);
Enrico Granata86cc9822012-03-19 22:58:49 +00001741 else
1742 {
1743 if (m_error.Fail())
1744 s.Printf("<%s>", m_error.AsCString());
1745 else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1746 s.PutCString("<no summary available>");
1747 else if (val_obj_display == eValueObjectRepresentationStyleValue)
1748 s.PutCString("<no value available>");
1749 else if (val_obj_display == eValueObjectRepresentationStyleLanguageSpecific)
1750 s.PutCString("<not a valid Objective-C object>"); // edit this if we have other runtimes that support a description
1751 else
1752 s.PutCString("<no printable representation>");
1753 }
1754
1755 // we should only return false here if we could not do *anything*
1756 // even if we have an error message as output, that's a success
1757 // from our callers' perspective, so return true
1758 var_success = true;
1759
1760 if (custom_format != eFormatInvalid)
1761 SetFormat(eFormatDefault);
1762 }
1763
Enrico Granataf4efecd2011-07-12 22:56:10 +00001764 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001765}
1766
Greg Clayton737b9322010-09-13 03:32:57 +00001767addr_t
Enrico Granata9128ee22011-09-06 19:20:51 +00001768ValueObject::GetAddressOf (bool scalar_is_load_address, AddressType *address_type)
Greg Clayton73b472d2010-10-27 03:32:59 +00001769{
Enrico Granatac3e320a2011-08-02 17:27:39 +00001770 if (!UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +00001771 return LLDB_INVALID_ADDRESS;
1772
Greg Clayton73b472d2010-10-27 03:32:59 +00001773 switch (m_value.GetValueType())
1774 {
1775 case Value::eValueTypeScalar:
Greg Clayton0665a0f2012-10-30 18:18:43 +00001776 case Value::eValueTypeVector:
Greg Clayton73b472d2010-10-27 03:32:59 +00001777 if (scalar_is_load_address)
1778 {
Enrico Granata9128ee22011-09-06 19:20:51 +00001779 if(address_type)
1780 *address_type = eAddressTypeLoad;
Greg Clayton73b472d2010-10-27 03:32:59 +00001781 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1782 }
1783 break;
1784
1785 case Value::eValueTypeLoadAddress:
1786 case Value::eValueTypeFileAddress:
1787 case Value::eValueTypeHostAddress:
1788 {
Enrico Granata9128ee22011-09-06 19:20:51 +00001789 if(address_type)
1790 *address_type = m_value.GetValueAddressType ();
Greg Clayton73b472d2010-10-27 03:32:59 +00001791 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1792 }
1793 break;
1794 }
Enrico Granata9128ee22011-09-06 19:20:51 +00001795 if (address_type)
1796 *address_type = eAddressTypeInvalid;
Greg Clayton73b472d2010-10-27 03:32:59 +00001797 return LLDB_INVALID_ADDRESS;
1798}
1799
1800addr_t
Enrico Granata9128ee22011-09-06 19:20:51 +00001801ValueObject::GetPointerValue (AddressType *address_type)
Greg Clayton737b9322010-09-13 03:32:57 +00001802{
Greg Claytonafacd142011-09-02 01:15:17 +00001803 addr_t address = LLDB_INVALID_ADDRESS;
Enrico Granata9128ee22011-09-06 19:20:51 +00001804 if(address_type)
1805 *address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +00001806
Enrico Granatac3e320a2011-08-02 17:27:39 +00001807 if (!UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +00001808 return address;
1809
Greg Clayton73b472d2010-10-27 03:32:59 +00001810 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +00001811 {
1812 case Value::eValueTypeScalar:
Greg Clayton0665a0f2012-10-30 18:18:43 +00001813 case Value::eValueTypeVector:
Enrico Granata9128ee22011-09-06 19:20:51 +00001814 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
Greg Clayton737b9322010-09-13 03:32:57 +00001815 break;
1816
Enrico Granata9128ee22011-09-06 19:20:51 +00001817 case Value::eValueTypeHostAddress:
Greg Clayton737b9322010-09-13 03:32:57 +00001818 case Value::eValueTypeLoadAddress:
1819 case Value::eValueTypeFileAddress:
Greg Clayton737b9322010-09-13 03:32:57 +00001820 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001821 lldb::offset_t data_offset = 0;
Greg Clayton737b9322010-09-13 03:32:57 +00001822 address = m_data.GetPointer(&data_offset);
Greg Clayton737b9322010-09-13 03:32:57 +00001823 }
1824 break;
1825 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001826
Enrico Granata9128ee22011-09-06 19:20:51 +00001827 if (address_type)
1828 *address_type = GetAddressTypeOfChildren();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001829
Greg Clayton737b9322010-09-13 03:32:57 +00001830 return address;
1831}
1832
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001833bool
Enrico Granata07a4ac22012-05-08 21:25:06 +00001834ValueObject::SetValueFromCString (const char *value_str, Error& error)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001835{
Enrico Granata07a4ac22012-05-08 21:25:06 +00001836 error.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001837 // Make sure our value is up to date first so that our location and location
1838 // type is valid.
Enrico Granatac3e320a2011-08-02 17:27:39 +00001839 if (!UpdateValueIfNeeded(false))
Enrico Granata07a4ac22012-05-08 21:25:06 +00001840 {
1841 error.SetErrorString("unable to read value");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001842 return false;
Enrico Granata07a4ac22012-05-08 21:25:06 +00001843 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001844
Greg Claytonfaac1112013-03-14 18:31:44 +00001845 uint64_t count = 0;
Greg Claytonafacd142011-09-02 01:15:17 +00001846 Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001847
Greg Claytonb1320972010-07-14 00:18:15 +00001848 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001849
Jim Ingham16e0c682011-08-12 23:34:31 +00001850 Value::ValueType value_type = m_value.GetValueType();
1851
1852 if (value_type == Value::eValueTypeScalar)
1853 {
1854 // If the value is already a scalar, then let the scalar change itself:
1855 m_value.GetScalar().SetValueFromCString (value_str, encoding, byte_size);
1856 }
1857 else if (byte_size <= Scalar::GetMaxByteSize())
1858 {
1859 // If the value fits in a scalar, then make a new scalar and again let the
1860 // scalar code do the conversion, then figure out where to put the new value.
1861 Scalar new_scalar;
Jim Ingham16e0c682011-08-12 23:34:31 +00001862 error = new_scalar.SetValueFromCString (value_str, encoding, byte_size);
1863 if (error.Success())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001864 {
Jim Ingham4b536182011-08-09 02:12:22 +00001865 switch (value_type)
1866 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00001867 case Value::eValueTypeLoadAddress:
Jim Ingham16e0c682011-08-12 23:34:31 +00001868 {
1869 // If it is a load address, then the scalar value is the storage location
1870 // of the data, and we have to shove this value down to that load location.
Greg Claytoncc4d0142012-02-17 07:49:44 +00001871 ExecutionContext exe_ctx (GetExecutionContextRef());
1872 Process *process = exe_ctx.GetProcessPtr();
1873 if (process)
Jim Ingham16e0c682011-08-12 23:34:31 +00001874 {
Enrico Granata48ea80f2012-10-24 20:24:39 +00001875 addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
Greg Claytoncc4d0142012-02-17 07:49:44 +00001876 size_t bytes_written = process->WriteScalarToMemory (target_addr,
1877 new_scalar,
1878 byte_size,
1879 error);
Enrico Granata07a4ac22012-05-08 21:25:06 +00001880 if (!error.Success())
1881 return false;
1882 if (bytes_written != byte_size)
1883 {
1884 error.SetErrorString("unable to write value to memory");
1885 return false;
1886 }
Jim Ingham16e0c682011-08-12 23:34:31 +00001887 }
1888 }
Jim Ingham4b536182011-08-09 02:12:22 +00001889 break;
Greg Claytoncc4d0142012-02-17 07:49:44 +00001890 case Value::eValueTypeHostAddress:
Jim Ingham16e0c682011-08-12 23:34:31 +00001891 {
1892 // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
1893 DataExtractor new_data;
1894 new_data.SetByteOrder (m_data.GetByteOrder());
1895
1896 DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0));
1897 m_data.SetData(buffer_sp, 0);
1898 bool success = new_scalar.GetData(new_data);
1899 if (success)
1900 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00001901 new_data.CopyByteOrderedData (0,
1902 byte_size,
1903 const_cast<uint8_t *>(m_data.GetDataStart()),
1904 byte_size,
1905 m_data.GetByteOrder());
Jim Ingham16e0c682011-08-12 23:34:31 +00001906 }
1907 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1908
1909 }
Jim Ingham4b536182011-08-09 02:12:22 +00001910 break;
Greg Claytoncc4d0142012-02-17 07:49:44 +00001911 case Value::eValueTypeFileAddress:
1912 case Value::eValueTypeScalar:
Greg Clayton0665a0f2012-10-30 18:18:43 +00001913 case Value::eValueTypeVector:
1914 break;
Jim Ingham4b536182011-08-09 02:12:22 +00001915 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001916 }
1917 else
1918 {
Jim Ingham16e0c682011-08-12 23:34:31 +00001919 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001920 }
Jim Ingham16e0c682011-08-12 23:34:31 +00001921 }
1922 else
1923 {
1924 // We don't support setting things bigger than a scalar at present.
Enrico Granata07a4ac22012-05-08 21:25:06 +00001925 error.SetErrorString("unable to write aggregate data type");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001926 return false;
1927 }
Jim Ingham16e0c682011-08-12 23:34:31 +00001928
1929 // If we have reached this point, then we have successfully changed the value.
1930 SetNeedsUpdate();
1931 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001932}
1933
Greg Clayton81e871e2012-02-04 02:27:34 +00001934bool
1935ValueObject::GetDeclaration (Declaration &decl)
1936{
1937 decl.Clear();
1938 return false;
1939}
1940
Greg Clayton84db9102012-03-26 23:03:23 +00001941ConstString
1942ValueObject::GetTypeName()
1943{
1944 return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
1945}
1946
1947ConstString
1948ValueObject::GetQualifiedTypeName()
1949{
1950 return ClangASTType::GetConstQualifiedTypeName (GetClangAST(), GetClangType());
1951}
1952
1953
Greg Claytonafacd142011-09-02 01:15:17 +00001954LanguageType
Jim Ingham5a369122010-09-28 01:25:32 +00001955ValueObject::GetObjectRuntimeLanguage ()
1956{
Enrico Granatac3e320a2011-08-02 17:27:39 +00001957 return ClangASTType::GetMinimumLanguage (GetClangAST(),
1958 GetClangType());
Jim Ingham5a369122010-09-28 01:25:32 +00001959}
1960
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001961void
Jim Ingham58b59f92011-04-22 23:53:53 +00001962ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001963{
Jim Ingham58b59f92011-04-22 23:53:53 +00001964 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001965}
1966
1967ValueObjectSP
1968ValueObject::GetSyntheticChild (const ConstString &key) const
1969{
1970 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +00001971 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001972 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +00001973 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001974 return synthetic_child_sp;
1975}
1976
Greg Clayton2452ab72013-02-08 22:02:02 +00001977uint32_t
1978ValueObject::GetTypeInfo (clang_type_t *pointee_or_element_clang_type)
1979{
1980 return ClangASTContext::GetTypeInfo (GetClangType(), GetClangAST(), pointee_or_element_clang_type);
1981}
1982
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001983bool
1984ValueObject::IsPointerType ()
1985{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001986 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001987}
1988
Jim Inghamb7603bb2011-03-18 00:05:18 +00001989bool
Greg Claytondaf515f2011-07-09 20:12:33 +00001990ValueObject::IsArrayType ()
1991{
Greg Clayton4ef877f2012-12-06 02:33:54 +00001992 return ClangASTContext::IsArrayType (GetClangType(), NULL, NULL, NULL);
Greg Claytondaf515f2011-07-09 20:12:33 +00001993}
1994
1995bool
Enrico Granata9fc19442011-07-06 02:13:41 +00001996ValueObject::IsScalarType ()
1997{
1998 return ClangASTContext::IsScalarType (GetClangType());
1999}
2000
2001bool
Jim Inghamb7603bb2011-03-18 00:05:18 +00002002ValueObject::IsIntegerType (bool &is_signed)
2003{
2004 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
2005}
Greg Clayton73b472d2010-10-27 03:32:59 +00002006
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002007bool
2008ValueObject::IsPointerOrReferenceType ()
2009{
Greg Clayton007d5be2011-05-30 00:49:24 +00002010 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
2011}
2012
2013bool
Greg Claytondea8cb42011-06-29 22:09:02 +00002014ValueObject::IsPossibleDynamicType ()
2015{
Enrico Granatafd4c84e2012-05-21 16:51:35 +00002016 ExecutionContext exe_ctx (GetExecutionContextRef());
2017 Process *process = exe_ctx.GetProcessPtr();
2018 if (process)
2019 return process->IsPossibleDynamicValue(*this);
2020 else
Greg Clayton70364252012-08-31 18:56:24 +00002021 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType(), NULL, true, true);
Greg Claytondea8cb42011-06-29 22:09:02 +00002022}
2023
Enrico Granata9e7b3882012-12-13 23:50:33 +00002024bool
2025ValueObject::IsObjCNil ()
2026{
Enrico Granata7277d202013-03-15 23:33:15 +00002027 const uint32_t mask = ClangASTContext::eTypeIsObjC | ClangASTContext::eTypeIsPointer;
2028 bool isObjCpointer = ( ((ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), NULL)) & mask) == mask);
2029 if (!isObjCpointer)
2030 return false;
Enrico Granata9e7b3882012-12-13 23:50:33 +00002031 bool canReadValue = true;
2032 bool isZero = GetValueAsUnsigned(0,&canReadValue) == 0;
Enrico Granata7277d202013-03-15 23:33:15 +00002033 return canReadValue && isZero;
Enrico Granata9e7b3882012-12-13 23:50:33 +00002034}
2035
Greg Claytonafacd142011-09-02 01:15:17 +00002036ValueObjectSP
Greg Claytonc7bece562013-01-25 18:06:21 +00002037ValueObject::GetSyntheticArrayMember (size_t index, bool can_create)
Enrico Granatad64d0bc2011-08-19 21:13:46 +00002038{
Greg Clayton2452ab72013-02-08 22:02:02 +00002039 const uint32_t type_info = GetTypeInfo ();
2040 if (type_info & ClangASTContext::eTypeIsArray)
Enrico Granatad64d0bc2011-08-19 21:13:46 +00002041 return GetSyntheticArrayMemberFromArray(index, can_create);
2042
Greg Clayton2452ab72013-02-08 22:02:02 +00002043 if (type_info & ClangASTContext::eTypeIsPointer)
Enrico Granatad64d0bc2011-08-19 21:13:46 +00002044 return GetSyntheticArrayMemberFromPointer(index, can_create);
2045
2046 return ValueObjectSP();
2047
2048}
2049
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002050ValueObjectSP
Greg Claytonc7bece562013-01-25 18:06:21 +00002051ValueObject::GetSyntheticArrayMemberFromPointer (size_t index, bool can_create)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002052{
2053 ValueObjectSP synthetic_child_sp;
2054 if (IsPointerType ())
2055 {
2056 char index_str[64];
Greg Claytonc7bece562013-01-25 18:06:21 +00002057 snprintf(index_str, sizeof(index_str), "[%zu]", index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002058 ConstString index_const_str(index_str);
2059 // Check if we have already created a synthetic array member in this
2060 // valid object. If we have we will re-use it.
2061 synthetic_child_sp = GetSyntheticChild (index_const_str);
2062 if (!synthetic_child_sp)
2063 {
Jim Ingham58b59f92011-04-22 23:53:53 +00002064 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002065 // We haven't made a synthetic array member for INDEX yet, so
2066 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00002067 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002068
2069 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00002070 if (synthetic_child)
2071 {
2072 AddSyntheticChild(index_const_str, synthetic_child);
2073 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00002074 synthetic_child_sp->SetName(ConstString(index_str));
Enrico Granata0a3958e2011-07-02 00:25:22 +00002075 synthetic_child_sp->m_is_array_item_for_pointer = true;
Jim Ingham58b59f92011-04-22 23:53:53 +00002076 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002077 }
2078 }
2079 return synthetic_child_sp;
2080}
Jim Ingham22777012010-09-23 02:01:19 +00002081
Greg Claytondaf515f2011-07-09 20:12:33 +00002082// This allows you to create an array member using and index
2083// that doesn't not fall in the normal bounds of the array.
2084// Many times structure can be defined as:
2085// struct Collection
2086// {
2087// uint32_t item_count;
2088// Item item_array[0];
2089// };
2090// The size of the "item_array" is 1, but many times in practice
2091// there are more items in "item_array".
2092
2093ValueObjectSP
Greg Claytonc7bece562013-01-25 18:06:21 +00002094ValueObject::GetSyntheticArrayMemberFromArray (size_t index, bool can_create)
Greg Claytondaf515f2011-07-09 20:12:33 +00002095{
2096 ValueObjectSP synthetic_child_sp;
2097 if (IsArrayType ())
2098 {
2099 char index_str[64];
Greg Claytonc7bece562013-01-25 18:06:21 +00002100 snprintf(index_str, sizeof(index_str), "[%zu]", index);
Greg Claytondaf515f2011-07-09 20:12:33 +00002101 ConstString index_const_str(index_str);
2102 // Check if we have already created a synthetic array member in this
2103 // valid object. If we have we will re-use it.
2104 synthetic_child_sp = GetSyntheticChild (index_const_str);
2105 if (!synthetic_child_sp)
2106 {
2107 ValueObject *synthetic_child;
2108 // We haven't made a synthetic array member for INDEX yet, so
2109 // lets make one and cache it for any future reference.
2110 synthetic_child = CreateChildAtIndex(0, true, index);
2111
2112 // Cache the value if we got one back...
2113 if (synthetic_child)
2114 {
2115 AddSyntheticChild(index_const_str, synthetic_child);
2116 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00002117 synthetic_child_sp->SetName(ConstString(index_str));
Greg Claytondaf515f2011-07-09 20:12:33 +00002118 synthetic_child_sp->m_is_array_item_for_pointer = true;
2119 }
2120 }
2121 }
2122 return synthetic_child_sp;
2123}
2124
Enrico Granata9fc19442011-07-06 02:13:41 +00002125ValueObjectSP
2126ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
2127{
2128 ValueObjectSP synthetic_child_sp;
2129 if (IsScalarType ())
2130 {
2131 char index_str[64];
2132 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
2133 ConstString index_const_str(index_str);
2134 // Check if we have already created a synthetic array member in this
2135 // valid object. If we have we will re-use it.
2136 synthetic_child_sp = GetSyntheticChild (index_const_str);
2137 if (!synthetic_child_sp)
2138 {
2139 ValueObjectChild *synthetic_child;
2140 // We haven't made a synthetic array member for INDEX yet, so
2141 // lets make one and cache it for any future reference.
2142 synthetic_child = new ValueObjectChild(*this,
2143 GetClangAST(),
2144 GetClangType(),
2145 index_const_str,
2146 GetByteSize(),
2147 0,
2148 to-from+1,
2149 from,
2150 false,
Enrico Granata9128ee22011-09-06 19:20:51 +00002151 false,
2152 eAddressTypeInvalid);
Enrico Granata9fc19442011-07-06 02:13:41 +00002153
2154 // Cache the value if we got one back...
2155 if (synthetic_child)
2156 {
2157 AddSyntheticChild(index_const_str, synthetic_child);
2158 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00002159 synthetic_child_sp->SetName(ConstString(index_str));
Enrico Granata9fc19442011-07-06 02:13:41 +00002160 synthetic_child_sp->m_is_bitfield_for_scalar = true;
2161 }
2162 }
2163 }
2164 return synthetic_child_sp;
2165}
2166
Greg Claytonafacd142011-09-02 01:15:17 +00002167ValueObjectSP
Enrico Granata6f3533f2011-07-29 19:53:35 +00002168ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
2169{
2170
2171 ValueObjectSP synthetic_child_sp;
2172
2173 char name_str[64];
2174 snprintf(name_str, sizeof(name_str), "@%i", offset);
2175 ConstString name_const_str(name_str);
2176
2177 // Check if we have already created a synthetic array member in this
2178 // valid object. If we have we will re-use it.
2179 synthetic_child_sp = GetSyntheticChild (name_const_str);
2180
2181 if (synthetic_child_sp.get())
2182 return synthetic_child_sp;
2183
2184 if (!can_create)
Greg Claytonafacd142011-09-02 01:15:17 +00002185 return ValueObjectSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00002186
2187 ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
2188 type.GetASTContext(),
2189 type.GetOpaqueQualType(),
2190 name_const_str,
2191 type.GetTypeByteSize(),
2192 offset,
2193 0,
2194 0,
2195 false,
Enrico Granata9128ee22011-09-06 19:20:51 +00002196 false,
2197 eAddressTypeInvalid);
Enrico Granata6f3533f2011-07-29 19:53:35 +00002198 if (synthetic_child)
2199 {
2200 AddSyntheticChild(name_const_str, synthetic_child);
2201 synthetic_child_sp = synthetic_child->GetSP();
2202 synthetic_child_sp->SetName(name_const_str);
2203 synthetic_child_sp->m_is_child_at_offset = true;
2204 }
2205 return synthetic_child_sp;
2206}
2207
Enrico Granatad55546b2011-07-22 00:16:08 +00002208// your expression path needs to have a leading . or ->
2209// (unless it somehow "looks like" an array, in which case it has
2210// a leading [ symbol). while the [ is meaningful and should be shown
2211// to the user, . and -> are just parser design, but by no means
2212// added information for the user.. strip them off
2213static const char*
2214SkipLeadingExpressionPathSeparators(const char* expression)
2215{
2216 if (!expression || !expression[0])
2217 return expression;
2218 if (expression[0] == '.')
2219 return expression+1;
2220 if (expression[0] == '-' && expression[1] == '>')
2221 return expression+2;
2222 return expression;
2223}
2224
Greg Claytonafacd142011-09-02 01:15:17 +00002225ValueObjectSP
Enrico Granatad55546b2011-07-22 00:16:08 +00002226ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_create)
2227{
2228 ValueObjectSP synthetic_child_sp;
2229 ConstString name_const_string(expression);
2230 // Check if we have already created a synthetic array member in this
2231 // valid object. If we have we will re-use it.
2232 synthetic_child_sp = GetSyntheticChild (name_const_string);
2233 if (!synthetic_child_sp)
2234 {
2235 // We haven't made a synthetic array member for expression yet, so
2236 // lets make one and cache it for any future reference.
Enrico Granatadf31a8a2012-08-02 17:34:05 +00002237 synthetic_child_sp = GetValueForExpressionPath(expression,
2238 NULL, NULL, NULL,
2239 GetValueForExpressionPathOptions().DontAllowSyntheticChildren());
Enrico Granatad55546b2011-07-22 00:16:08 +00002240
2241 // Cache the value if we got one back...
2242 if (synthetic_child_sp.get())
2243 {
Enrico Granataea2bc0f2013-02-21 19:57:10 +00002244 // FIXME: this causes a "real" child to end up with its name changed to the contents of expression
Enrico Granatad55546b2011-07-22 00:16:08 +00002245 AddSyntheticChild(name_const_string, synthetic_child_sp.get());
Enrico Granata6f3533f2011-07-29 19:53:35 +00002246 synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression)));
Enrico Granatad55546b2011-07-22 00:16:08 +00002247 }
2248 }
2249 return synthetic_child_sp;
2250}
2251
2252void
Enrico Granata86cc9822012-03-19 22:58:49 +00002253ValueObject::CalculateSyntheticValue (bool use_synthetic)
Enrico Granatad55546b2011-07-22 00:16:08 +00002254{
Enrico Granata86cc9822012-03-19 22:58:49 +00002255 if (use_synthetic == false)
Enrico Granatad55546b2011-07-22 00:16:08 +00002256 return;
2257
Enrico Granatac5bc4122012-03-27 02:35:13 +00002258 TargetSP target_sp(GetTargetSP());
2259 if (target_sp && (target_sp->GetEnableSyntheticValue() == false || target_sp->GetSuppressSyntheticValue() == true))
2260 {
2261 m_synthetic_value = NULL;
2262 return;
2263 }
2264
Enrico Granatae3e91512012-10-22 18:18:36 +00002265 lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
2266
Enrico Granata5548cb52013-01-28 23:47:25 +00002267 if (!UpdateFormatsIfNeeded() && m_synthetic_value)
Enrico Granata86cc9822012-03-19 22:58:49 +00002268 return;
Enrico Granatad55546b2011-07-22 00:16:08 +00002269
Enrico Granata0c489f52012-03-01 04:24:26 +00002270 if (m_synthetic_children_sp.get() == NULL)
Enrico Granatad55546b2011-07-22 00:16:08 +00002271 return;
2272
Enrico Granatae3e91512012-10-22 18:18:36 +00002273 if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
2274 return;
2275
Enrico Granata86cc9822012-03-19 22:58:49 +00002276 m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
Enrico Granatad55546b2011-07-22 00:16:08 +00002277}
2278
Jim Ingham78a685a2011-04-16 00:01:13 +00002279void
Greg Claytonafacd142011-09-02 01:15:17 +00002280ValueObject::CalculateDynamicValue (DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00002281{
Greg Claytonafacd142011-09-02 01:15:17 +00002282 if (use_dynamic == eNoDynamicValues)
Jim Ingham2837b762011-05-04 03:43:18 +00002283 return;
2284
Jim Ingham58b59f92011-04-22 23:53:53 +00002285 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00002286 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00002287 ExecutionContext exe_ctx (GetExecutionContextRef());
2288 Process *process = exe_ctx.GetProcessPtr();
Enrico Granatafd4c84e2012-05-21 16:51:35 +00002289 if (process && process->IsPossibleDynamicValue(*this))
Enrico Granatae3e91512012-10-22 18:18:36 +00002290 {
2291 ClearDynamicTypeInformation ();
Enrico Granatafd4c84e2012-05-21 16:51:35 +00002292 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Enrico Granatae3e91512012-10-22 18:18:36 +00002293 }
Jim Ingham78a685a2011-04-16 00:01:13 +00002294 }
2295}
2296
Jim Ingham58b59f92011-04-22 23:53:53 +00002297ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00002298ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00002299{
Greg Claytonafacd142011-09-02 01:15:17 +00002300 if (use_dynamic == eNoDynamicValues)
Jim Ingham2837b762011-05-04 03:43:18 +00002301 return ValueObjectSP();
2302
2303 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00002304 {
Jim Ingham2837b762011-05-04 03:43:18 +00002305 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00002306 }
Jim Ingham58b59f92011-04-22 23:53:53 +00002307 if (m_dynamic_value)
2308 return m_dynamic_value->GetSP();
2309 else
2310 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00002311}
Greg Clayton1d3afba2010-10-05 00:00:42 +00002312
Jim Ingham60dbabb2011-12-08 19:44:08 +00002313ValueObjectSP
2314ValueObject::GetStaticValue()
2315{
2316 return GetSP();
2317}
2318
Enrico Granata886147f2012-05-08 18:47:08 +00002319lldb::ValueObjectSP
2320ValueObject::GetNonSyntheticValue ()
2321{
2322 return GetSP();
2323}
2324
Enrico Granatad55546b2011-07-22 00:16:08 +00002325ValueObjectSP
Enrico Granata86cc9822012-03-19 22:58:49 +00002326ValueObject::GetSyntheticValue (bool use_synthetic)
Enrico Granatad55546b2011-07-22 00:16:08 +00002327{
Enrico Granata86cc9822012-03-19 22:58:49 +00002328 if (use_synthetic == false)
2329 return ValueObjectSP();
2330
Enrico Granatad55546b2011-07-22 00:16:08 +00002331 CalculateSyntheticValue(use_synthetic);
2332
2333 if (m_synthetic_value)
2334 return m_synthetic_value->GetSP();
2335 else
Enrico Granata86cc9822012-03-19 22:58:49 +00002336 return ValueObjectSP();
Enrico Granatad55546b2011-07-22 00:16:08 +00002337}
2338
Greg Claytone221f822011-01-21 01:59:00 +00002339bool
Enrico Granata27b625e2011-08-09 01:04:56 +00002340ValueObject::HasSyntheticValue()
2341{
Enrico Granata5548cb52013-01-28 23:47:25 +00002342 UpdateFormatsIfNeeded();
Enrico Granata27b625e2011-08-09 01:04:56 +00002343
Enrico Granata0c489f52012-03-01 04:24:26 +00002344 if (m_synthetic_children_sp.get() == NULL)
Enrico Granata27b625e2011-08-09 01:04:56 +00002345 return false;
2346
Enrico Granata86cc9822012-03-19 22:58:49 +00002347 CalculateSyntheticValue(true);
Enrico Granata27b625e2011-08-09 01:04:56 +00002348
2349 if (m_synthetic_value)
2350 return true;
2351 else
2352 return false;
2353}
2354
2355bool
Greg Claytone221f822011-01-21 01:59:00 +00002356ValueObject::GetBaseClassPath (Stream &s)
2357{
2358 if (IsBaseClass())
2359 {
Jim Ingham78a685a2011-04-16 00:01:13 +00002360 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00002361 clang_type_t clang_type = GetClangType();
2362 std::string cxx_class_name;
2363 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
2364 if (this_had_base_class)
2365 {
2366 if (parent_had_base_class)
2367 s.PutCString("::");
2368 s.PutCString(cxx_class_name.c_str());
2369 }
2370 return parent_had_base_class || this_had_base_class;
2371 }
2372 return false;
2373}
2374
2375
2376ValueObject *
2377ValueObject::GetNonBaseClassParent()
2378{
Jim Ingham78a685a2011-04-16 00:01:13 +00002379 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00002380 {
Jim Ingham78a685a2011-04-16 00:01:13 +00002381 if (GetParent()->IsBaseClass())
2382 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00002383 else
Jim Ingham78a685a2011-04-16 00:01:13 +00002384 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00002385 }
2386 return NULL;
2387}
Greg Clayton1d3afba2010-10-05 00:00:42 +00002388
2389void
Enrico Granata4becb372011-06-29 22:27:15 +00002390ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002391{
Greg Claytone221f822011-01-21 01:59:00 +00002392 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00002393
Enrico Granata86cc9822012-03-19 22:58:49 +00002394 if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
Enrico Granata85933ed2011-08-18 16:38:26 +00002395 {
Enrico Granata4becb372011-06-29 22:27:15 +00002396 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
2397 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
2398 // the eHonorPointers mode is meant to produce strings in this latter format
2399 s.PutCString("*(");
2400 }
Greg Claytone221f822011-01-21 01:59:00 +00002401
Enrico Granata4becb372011-06-29 22:27:15 +00002402 ValueObject* parent = GetParent();
2403
2404 if (parent)
2405 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
Enrico Granata0a3958e2011-07-02 00:25:22 +00002406
2407 // if we are a deref_of_parent just because we are synthetic array
2408 // members made up to allow ptr[%d] syntax to work in variable
2409 // printing, then add our name ([%d]) to the expression path
Enrico Granata86cc9822012-03-19 22:58:49 +00002410 if (m_is_array_item_for_pointer && epformat == eGetExpressionPathFormatHonorPointers)
Enrico Granata0a3958e2011-07-02 00:25:22 +00002411 s.PutCString(m_name.AsCString());
Enrico Granata4becb372011-06-29 22:27:15 +00002412
Greg Claytone221f822011-01-21 01:59:00 +00002413 if (!IsBaseClass())
2414 {
2415 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002416 {
Greg Claytone221f822011-01-21 01:59:00 +00002417 ValueObject *non_base_class_parent = GetNonBaseClassParent();
2418 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002419 {
Greg Claytone221f822011-01-21 01:59:00 +00002420 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
2421 if (non_base_class_parent_clang_type)
2422 {
2423 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
2424
Enrico Granata86cc9822012-03-19 22:58:49 +00002425 if (parent && parent->IsDereferenceOfParent() && epformat == eGetExpressionPathFormatHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00002426 {
2427 s.PutCString("->");
2428 }
Enrico Granata4becb372011-06-29 22:27:15 +00002429 else
2430 {
2431 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
2432 {
2433 s.PutCString("->");
2434 }
2435 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
2436 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
2437 {
2438 s.PutChar('.');
2439 }
Greg Claytone221f822011-01-21 01:59:00 +00002440 }
2441 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002442 }
Greg Claytone221f822011-01-21 01:59:00 +00002443
2444 const char *name = GetName().GetCString();
2445 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002446 {
Greg Claytone221f822011-01-21 01:59:00 +00002447 if (qualify_cxx_base_classes)
2448 {
2449 if (GetBaseClassPath (s))
2450 s.PutCString("::");
2451 }
2452 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002453 }
2454 }
2455 }
2456
Enrico Granata86cc9822012-03-19 22:58:49 +00002457 if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
Enrico Granata85933ed2011-08-18 16:38:26 +00002458 {
Greg Claytone221f822011-01-21 01:59:00 +00002459 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00002460 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002461}
2462
Greg Claytonafacd142011-09-02 01:15:17 +00002463ValueObjectSP
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002464ValueObject::GetValueForExpressionPath(const char* expression,
2465 const char** first_unparsed,
2466 ExpressionPathScanEndReason* reason_to_stop,
2467 ExpressionPathEndResultType* final_value_type,
2468 const GetValueForExpressionPathOptions& options,
2469 ExpressionPathAftermath* final_task_on_target)
2470{
2471
2472 const char* dummy_first_unparsed;
Enrico Granataea2bc0f2013-02-21 19:57:10 +00002473 ExpressionPathScanEndReason dummy_reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnknown;
2474 ExpressionPathEndResultType dummy_final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granata86cc9822012-03-19 22:58:49 +00002475 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002476
2477 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
2478 first_unparsed ? first_unparsed : &dummy_first_unparsed,
2479 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
2480 final_value_type ? final_value_type : &dummy_final_value_type,
2481 options,
2482 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
2483
Enrico Granata86cc9822012-03-19 22:58:49 +00002484 if (!final_task_on_target || *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002485 return ret_val;
Enrico Granata385ad4e2012-03-03 00:45:57 +00002486
Enrico Granata86cc9822012-03-19 22:58:49 +00002487 if (ret_val.get() && ((final_value_type ? *final_value_type : dummy_final_value_type) == eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress of plain objects
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002488 {
Enrico Granata86cc9822012-03-19 22:58:49 +00002489 if ( (final_task_on_target ? *final_task_on_target : dummy_final_task_on_target) == ValueObject::eExpressionPathAftermathDereference)
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002490 {
2491 Error error;
2492 ValueObjectSP final_value = ret_val->Dereference(error);
2493 if (error.Fail() || !final_value.get())
2494 {
Enrico Granata385ad4e2012-03-03 00:45:57 +00002495 if (reason_to_stop)
Enrico Granata86cc9822012-03-19 22:58:49 +00002496 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
Enrico Granata385ad4e2012-03-03 00:45:57 +00002497 if (final_value_type)
Enrico Granata86cc9822012-03-19 22:58:49 +00002498 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002499 return ValueObjectSP();
2500 }
2501 else
2502 {
Enrico Granata385ad4e2012-03-03 00:45:57 +00002503 if (final_task_on_target)
Enrico Granata86cc9822012-03-19 22:58:49 +00002504 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002505 return final_value;
2506 }
2507 }
Enrico Granata86cc9822012-03-19 22:58:49 +00002508 if (*final_task_on_target == ValueObject::eExpressionPathAftermathTakeAddress)
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002509 {
2510 Error error;
2511 ValueObjectSP final_value = ret_val->AddressOf(error);
2512 if (error.Fail() || !final_value.get())
2513 {
Enrico Granata385ad4e2012-03-03 00:45:57 +00002514 if (reason_to_stop)
Enrico Granata86cc9822012-03-19 22:58:49 +00002515 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
Enrico Granata385ad4e2012-03-03 00:45:57 +00002516 if (final_value_type)
Enrico Granata86cc9822012-03-19 22:58:49 +00002517 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002518 return ValueObjectSP();
2519 }
2520 else
2521 {
Enrico Granata385ad4e2012-03-03 00:45:57 +00002522 if (final_task_on_target)
Enrico Granata86cc9822012-03-19 22:58:49 +00002523 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002524 return final_value;
2525 }
2526 }
2527 }
2528 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
2529}
2530
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002531int
2532ValueObject::GetValuesForExpressionPath(const char* expression,
Greg Claytonafacd142011-09-02 01:15:17 +00002533 ValueObjectListSP& list,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002534 const char** first_unparsed,
2535 ExpressionPathScanEndReason* reason_to_stop,
2536 ExpressionPathEndResultType* final_value_type,
2537 const GetValueForExpressionPathOptions& options,
2538 ExpressionPathAftermath* final_task_on_target)
2539{
2540 const char* dummy_first_unparsed;
2541 ExpressionPathScanEndReason dummy_reason_to_stop;
2542 ExpressionPathEndResultType dummy_final_value_type;
Enrico Granata86cc9822012-03-19 22:58:49 +00002543 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002544
2545 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
2546 first_unparsed ? first_unparsed : &dummy_first_unparsed,
2547 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
2548 final_value_type ? final_value_type : &dummy_final_value_type,
2549 options,
2550 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
2551
2552 if (!ret_val.get()) // if there are errors, I add nothing to the list
2553 return 0;
2554
Enrico Granata86ea8d82012-03-29 01:34:34 +00002555 if ( (reason_to_stop ? *reason_to_stop : dummy_reason_to_stop) != eExpressionPathScanEndReasonArrayRangeOperatorMet)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002556 {
2557 // I need not expand a range, just post-process the final value and return
Enrico Granata86cc9822012-03-19 22:58:49 +00002558 if (!final_task_on_target || *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002559 {
2560 list->Append(ret_val);
2561 return 1;
2562 }
Enrico Granata86ea8d82012-03-29 01:34:34 +00002563 if (ret_val.get() && (final_value_type ? *final_value_type : dummy_final_value_type) == eExpressionPathEndResultTypePlain) // I can only deref and takeaddress of plain objects
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002564 {
Enrico Granata86cc9822012-03-19 22:58:49 +00002565 if (*final_task_on_target == ValueObject::eExpressionPathAftermathDereference)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002566 {
2567 Error error;
2568 ValueObjectSP final_value = ret_val->Dereference(error);
2569 if (error.Fail() || !final_value.get())
2570 {
Greg Clayton23f59502012-07-17 03:23:13 +00002571 if (reason_to_stop)
2572 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2573 if (final_value_type)
2574 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002575 return 0;
2576 }
2577 else
2578 {
Enrico Granata86cc9822012-03-19 22:58:49 +00002579 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002580 list->Append(final_value);
2581 return 1;
2582 }
2583 }
Enrico Granata86cc9822012-03-19 22:58:49 +00002584 if (*final_task_on_target == ValueObject::eExpressionPathAftermathTakeAddress)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002585 {
2586 Error error;
2587 ValueObjectSP final_value = ret_val->AddressOf(error);
2588 if (error.Fail() || !final_value.get())
2589 {
Greg Clayton23f59502012-07-17 03:23:13 +00002590 if (reason_to_stop)
2591 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
2592 if (final_value_type)
2593 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002594 return 0;
2595 }
2596 else
2597 {
Enrico Granata86cc9822012-03-19 22:58:49 +00002598 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002599 list->Append(final_value);
2600 return 1;
2601 }
2602 }
2603 }
2604 }
2605 else
2606 {
2607 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
2608 first_unparsed ? first_unparsed : &dummy_first_unparsed,
2609 ret_val,
2610 list,
2611 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
2612 final_value_type ? final_value_type : &dummy_final_value_type,
2613 options,
2614 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
2615 }
2616 // in any non-covered case, just do the obviously right thing
2617 list->Append(ret_val);
2618 return 1;
2619}
2620
Greg Claytonafacd142011-09-02 01:15:17 +00002621ValueObjectSP
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002622ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
2623 const char** first_unparsed,
2624 ExpressionPathScanEndReason* reason_to_stop,
2625 ExpressionPathEndResultType* final_result,
2626 const GetValueForExpressionPathOptions& options,
2627 ExpressionPathAftermath* what_next)
2628{
2629 ValueObjectSP root = GetSP();
2630
2631 if (!root.get())
2632 return ValueObjectSP();
2633
2634 *first_unparsed = expression_cstr;
2635
2636 while (true)
2637 {
2638
2639 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
2640
Greg Claytonafacd142011-09-02 01:15:17 +00002641 clang_type_t root_clang_type = root->GetClangType();
2642 clang_type_t pointee_clang_type;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002643 Flags root_clang_type_info,pointee_clang_type_info;
2644
2645 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
2646 if (pointee_clang_type)
2647 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002648
2649 if (!expression_cstr || *expression_cstr == '\0')
2650 {
Enrico Granata86cc9822012-03-19 22:58:49 +00002651 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002652 return root;
2653 }
2654
2655 switch (*expression_cstr)
2656 {
2657 case '-':
2658 {
2659 if (options.m_check_dot_vs_arrow_syntax &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002660 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 +00002661 {
2662 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002663 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
2664 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002665 return ValueObjectSP();
2666 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002667 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
2668 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) &&
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002669 options.m_no_fragile_ivar)
2670 {
2671 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002672 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
2673 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002674 return ValueObjectSP();
2675 }
2676 if (expression_cstr[1] != '>')
2677 {
2678 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002679 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2680 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002681 return ValueObjectSP();
2682 }
2683 expression_cstr++; // skip the -
2684 }
2685 case '.': // or fallthrough from ->
2686 {
2687 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002688 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 +00002689 {
2690 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002691 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
2692 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002693 return ValueObjectSP();
2694 }
2695 expression_cstr++; // skip .
2696 const char *next_separator = strpbrk(expression_cstr+1,"-.[");
2697 ConstString child_name;
2698 if (!next_separator) // if no other separator just expand this last layer
2699 {
2700 child_name.SetCString (expression_cstr);
Enrico Granata8c9d3562011-08-11 17:08:01 +00002701 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
2702
2703 if (child_valobj_sp.get()) // we know we are done, so just return
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002704 {
Daniel Maleaa85e6b62012-12-07 22:21:08 +00002705 *first_unparsed = "";
Enrico Granata86cc9822012-03-19 22:58:49 +00002706 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2707 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
Enrico Granata8c9d3562011-08-11 17:08:01 +00002708 return child_valobj_sp;
2709 }
2710 else if (options.m_no_synthetic_children == false) // let's try with synthetic children
2711 {
Enrico Granata86cc9822012-03-19 22:58:49 +00002712 if (root->IsSynthetic())
Enrico Granatadf31a8a2012-08-02 17:34:05 +00002713 {
2714 *first_unparsed = expression_cstr;
2715 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2716 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2717 return ValueObjectSP();
2718 }
2719
2720 child_valobj_sp = root->GetSyntheticValue();
Enrico Granata86cc9822012-03-19 22:58:49 +00002721 if (child_valobj_sp.get())
2722 child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
Enrico Granata8c9d3562011-08-11 17:08:01 +00002723 }
2724
2725 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
2726 // so we hit the "else" branch, and return an error
2727 if(child_valobj_sp.get()) // if it worked, just return
2728 {
Daniel Maleaa85e6b62012-12-07 22:21:08 +00002729 *first_unparsed = "";
Enrico Granata86cc9822012-03-19 22:58:49 +00002730 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2731 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
Enrico Granata8c9d3562011-08-11 17:08:01 +00002732 return child_valobj_sp;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002733 }
2734 else
2735 {
2736 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002737 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2738 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002739 return ValueObjectSP();
2740 }
2741 }
2742 else // other layers do expand
2743 {
2744 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
Enrico Granata8c9d3562011-08-11 17:08:01 +00002745 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
2746 if (child_valobj_sp.get()) // store the new root and move on
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002747 {
Enrico Granata8c9d3562011-08-11 17:08:01 +00002748 root = child_valobj_sp;
2749 *first_unparsed = next_separator;
Enrico Granata86cc9822012-03-19 22:58:49 +00002750 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
Enrico Granata8c9d3562011-08-11 17:08:01 +00002751 continue;
2752 }
2753 else if (options.m_no_synthetic_children == false) // let's try with synthetic children
2754 {
Enrico Granatadf31a8a2012-08-02 17:34:05 +00002755 if (root->IsSynthetic())
2756 {
2757 *first_unparsed = expression_cstr;
2758 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2759 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2760 return ValueObjectSP();
2761 }
2762
Enrico Granata86cc9822012-03-19 22:58:49 +00002763 child_valobj_sp = root->GetSyntheticValue(true);
2764 if (child_valobj_sp)
2765 child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
Enrico Granata8c9d3562011-08-11 17:08:01 +00002766 }
2767
2768 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
2769 // so we hit the "else" branch, and return an error
2770 if(child_valobj_sp.get()) // if it worked, move on
2771 {
2772 root = child_valobj_sp;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002773 *first_unparsed = next_separator;
Enrico Granata86cc9822012-03-19 22:58:49 +00002774 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002775 continue;
2776 }
2777 else
2778 {
2779 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002780 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2781 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002782 return ValueObjectSP();
2783 }
2784 }
2785 break;
2786 }
2787 case '[':
2788 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002789 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 +00002790 {
Enrico Granata27b625e2011-08-09 01:04:56 +00002791 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar...
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002792 {
Enrico Granata27b625e2011-08-09 01:04:56 +00002793 if (options.m_no_synthetic_children) // ...only chance left is synthetic
2794 {
2795 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002796 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
2797 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granata27b625e2011-08-09 01:04:56 +00002798 return ValueObjectSP();
2799 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002800 }
2801 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2802 {
2803 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002804 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
2805 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002806 return ValueObjectSP();
2807 }
2808 }
2809 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2810 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002811 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002812 {
2813 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002814 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2815 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002816 return ValueObjectSP();
2817 }
2818 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
2819 {
2820 *first_unparsed = expression_cstr+2;
Enrico Granata86cc9822012-03-19 22:58:49 +00002821 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2822 *final_result = ValueObject::eExpressionPathEndResultTypeUnboundedRange;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002823 return root;
2824 }
2825 }
2826 const char *separator_position = ::strchr(expression_cstr+1,'-');
2827 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2828 if (!close_bracket_position) // if there is no ], this is a syntax error
2829 {
2830 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002831 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2832 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002833 return ValueObjectSP();
2834 }
2835 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2836 {
2837 char *end = NULL;
2838 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2839 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2840 {
2841 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002842 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2843 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002844 return ValueObjectSP();
2845 }
2846 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2847 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002848 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002849 {
2850 *first_unparsed = expression_cstr+2;
Enrico Granata86cc9822012-03-19 22:58:49 +00002851 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2852 *final_result = ValueObject::eExpressionPathEndResultTypeUnboundedRange;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002853 return root;
2854 }
2855 else
2856 {
2857 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002858 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2859 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002860 return ValueObjectSP();
2861 }
2862 }
2863 // from here on we do have a valid index
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002864 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002865 {
Greg Claytondaf515f2011-07-09 20:12:33 +00002866 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2867 if (!child_valobj_sp)
2868 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
Enrico Granata27b625e2011-08-09 01:04:56 +00002869 if (!child_valobj_sp)
Enrico Granata86cc9822012-03-19 22:58:49 +00002870 if (root->HasSyntheticValue() && root->GetSyntheticValue()->GetNumChildren() > index)
2871 child_valobj_sp = root->GetSyntheticValue()->GetChildAtIndex(index, true);
Greg Claytondaf515f2011-07-09 20:12:33 +00002872 if (child_valobj_sp)
2873 {
2874 root = child_valobj_sp;
2875 *first_unparsed = end+1; // skip ]
Enrico Granata86cc9822012-03-19 22:58:49 +00002876 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
Greg Claytondaf515f2011-07-09 20:12:33 +00002877 continue;
2878 }
2879 else
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002880 {
2881 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002882 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2883 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002884 return ValueObjectSP();
2885 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002886 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002887 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002888 {
Enrico Granata86cc9822012-03-19 22:58:49 +00002889 if (*what_next == ValueObject::eExpressionPathAftermathDereference && // 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 +00002890 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002891 {
2892 Error error;
2893 root = root->Dereference(error);
2894 if (error.Fail() || !root.get())
2895 {
2896 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002897 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2898 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002899 return ValueObjectSP();
2900 }
2901 else
2902 {
Enrico Granata86cc9822012-03-19 22:58:49 +00002903 *what_next = eExpressionPathAftermathNothing;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002904 continue;
2905 }
2906 }
2907 else
2908 {
Enrico Granata27b625e2011-08-09 01:04:56 +00002909 if (ClangASTType::GetMinimumLanguage(root->GetClangAST(),
Greg Clayton84db9102012-03-26 23:03:23 +00002910 root->GetClangType()) == eLanguageTypeObjC
2911 && ClangASTContext::IsPointerType(ClangASTType::GetPointeeType(root->GetClangType())) == false
2912 && root->HasSyntheticValue()
2913 && options.m_no_synthetic_children == false)
Enrico Granata27b625e2011-08-09 01:04:56 +00002914 {
Enrico Granata86cc9822012-03-19 22:58:49 +00002915 root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
Enrico Granata27b625e2011-08-09 01:04:56 +00002916 }
2917 else
2918 root = root->GetSyntheticArrayMemberFromPointer(index, true);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002919 if (!root.get())
2920 {
2921 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002922 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2923 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002924 return ValueObjectSP();
2925 }
2926 else
2927 {
2928 *first_unparsed = end+1; // skip ]
Enrico Granata86cc9822012-03-19 22:58:49 +00002929 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002930 continue;
2931 }
2932 }
2933 }
Enrico Granata27b625e2011-08-09 01:04:56 +00002934 else if (ClangASTContext::IsScalarType(root_clang_type))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002935 {
2936 root = root->GetSyntheticBitFieldChild(index, index, true);
2937 if (!root.get())
2938 {
2939 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002940 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2941 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002942 return ValueObjectSP();
2943 }
2944 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2945 {
2946 *first_unparsed = end+1; // skip ]
Enrico Granata86cc9822012-03-19 22:58:49 +00002947 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2948 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002949 return root;
2950 }
2951 }
Enrico Granata86cc9822012-03-19 22:58:49 +00002952 else if (options.m_no_synthetic_children == false)
Enrico Granata27b625e2011-08-09 01:04:56 +00002953 {
Enrico Granata86cc9822012-03-19 22:58:49 +00002954 if (root->HasSyntheticValue())
2955 root = root->GetSyntheticValue();
2956 else if (!root->IsSynthetic())
2957 {
2958 *first_unparsed = expression_cstr;
2959 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2960 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2961 return ValueObjectSP();
2962 }
2963 // if we are here, then root itself is a synthetic VO.. should be good to go
2964
Enrico Granata27b625e2011-08-09 01:04:56 +00002965 if (!root.get())
2966 {
2967 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002968 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2969 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2970 return ValueObjectSP();
2971 }
2972 root = root->GetChildAtIndex(index, true);
2973 if (!root.get())
2974 {
2975 *first_unparsed = expression_cstr;
2976 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2977 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granata27b625e2011-08-09 01:04:56 +00002978 return ValueObjectSP();
2979 }
Enrico Granata8c9d3562011-08-11 17:08:01 +00002980 else
2981 {
2982 *first_unparsed = end+1; // skip ]
Enrico Granata86cc9822012-03-19 22:58:49 +00002983 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
Enrico Granata8c9d3562011-08-11 17:08:01 +00002984 continue;
2985 }
Enrico Granata27b625e2011-08-09 01:04:56 +00002986 }
2987 else
2988 {
2989 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00002990 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2991 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granata27b625e2011-08-09 01:04:56 +00002992 return ValueObjectSP();
2993 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002994 }
2995 else // we have a low and a high index
2996 {
2997 char *end = NULL;
2998 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2999 if (!end || end != separator_position) // if something weird is in our way return an error
3000 {
3001 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003002 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3003 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00003004 return ValueObjectSP();
3005 }
3006 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
3007 if (!end || end != close_bracket_position) // if something weird is in our way return an error
3008 {
3009 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003010 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3011 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00003012 return ValueObjectSP();
3013 }
3014 if (index_lower > index_higher) // swap indices if required
3015 {
3016 unsigned long temp = index_lower;
3017 index_lower = index_higher;
3018 index_higher = temp;
3019 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003020 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
Enrico Granatafc7a7f32011-07-08 02:51:01 +00003021 {
3022 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
3023 if (!root.get())
3024 {
3025 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003026 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
3027 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00003028 return ValueObjectSP();
3029 }
3030 else
3031 {
3032 *first_unparsed = end+1; // skip ]
Enrico Granata86cc9822012-03-19 22:58:49 +00003033 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
3034 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00003035 return root;
3036 }
3037 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003038 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 Granata86cc9822012-03-19 22:58:49 +00003039 *what_next == ValueObject::eExpressionPathAftermathDereference &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003040 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00003041 {
3042 Error error;
3043 root = root->Dereference(error);
3044 if (error.Fail() || !root.get())
3045 {
3046 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003047 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
3048 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00003049 return ValueObjectSP();
3050 }
3051 else
3052 {
Enrico Granata86cc9822012-03-19 22:58:49 +00003053 *what_next = ValueObject::eExpressionPathAftermathNothing;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00003054 continue;
3055 }
3056 }
3057 else
3058 {
3059 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003060 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
3061 *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00003062 return root;
3063 }
3064 }
3065 break;
3066 }
3067 default: // some non-separator is in the way
3068 {
3069 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003070 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3071 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00003072 return ValueObjectSP();
3073 break;
3074 }
3075 }
3076 }
3077}
3078
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003079int
3080ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
3081 const char** first_unparsed,
Greg Claytonafacd142011-09-02 01:15:17 +00003082 ValueObjectSP root,
3083 ValueObjectListSP& list,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003084 ExpressionPathScanEndReason* reason_to_stop,
3085 ExpressionPathEndResultType* final_result,
3086 const GetValueForExpressionPathOptions& options,
3087 ExpressionPathAftermath* what_next)
3088{
3089 if (!root.get())
3090 return 0;
3091
3092 *first_unparsed = expression_cstr;
3093
3094 while (true)
3095 {
3096
3097 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
3098
Greg Claytonafacd142011-09-02 01:15:17 +00003099 clang_type_t root_clang_type = root->GetClangType();
3100 clang_type_t pointee_clang_type;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003101 Flags root_clang_type_info,pointee_clang_type_info;
3102
3103 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
3104 if (pointee_clang_type)
3105 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
3106
3107 if (!expression_cstr || *expression_cstr == '\0')
3108 {
Enrico Granata86cc9822012-03-19 22:58:49 +00003109 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003110 list->Append(root);
3111 return 1;
3112 }
3113
3114 switch (*expression_cstr)
3115 {
3116 case '[':
3117 {
3118 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
3119 {
3120 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
3121 {
3122 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003123 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
3124 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003125 return 0;
3126 }
3127 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
3128 {
3129 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003130 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
3131 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003132 return 0;
3133 }
3134 }
3135 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
3136 {
3137 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
3138 {
3139 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003140 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
3141 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003142 return 0;
3143 }
3144 else // expand this into list
3145 {
Greg Claytonc7bece562013-01-25 18:06:21 +00003146 const size_t max_index = root->GetNumChildren() - 1;
3147 for (size_t index = 0; index < max_index; index++)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003148 {
3149 ValueObjectSP child =
3150 root->GetChildAtIndex(index, true);
3151 list->Append(child);
3152 }
3153 *first_unparsed = expression_cstr+2;
Enrico Granata86cc9822012-03-19 22:58:49 +00003154 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3155 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003156 return max_index; // tell me number of items I added to the VOList
3157 }
3158 }
3159 const char *separator_position = ::strchr(expression_cstr+1,'-');
3160 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
3161 if (!close_bracket_position) // if there is no ], this is a syntax error
3162 {
3163 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003164 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3165 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003166 return 0;
3167 }
3168 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
3169 {
3170 char *end = NULL;
3171 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
3172 if (!end || end != close_bracket_position) // if something weird is in our way return an error
3173 {
3174 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003175 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3176 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003177 return 0;
3178 }
3179 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
3180 {
3181 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
3182 {
Greg Claytonc7bece562013-01-25 18:06:21 +00003183 const size_t max_index = root->GetNumChildren() - 1;
3184 for (size_t index = 0; index < max_index; index++)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003185 {
3186 ValueObjectSP child =
3187 root->GetChildAtIndex(index, true);
3188 list->Append(child);
3189 }
3190 *first_unparsed = expression_cstr+2;
Enrico Granata86cc9822012-03-19 22:58:49 +00003191 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3192 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003193 return max_index; // tell me number of items I added to the VOList
3194 }
3195 else
3196 {
3197 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003198 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
3199 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003200 return 0;
3201 }
3202 }
3203 // from here on we do have a valid index
3204 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
3205 {
3206 root = root->GetChildAtIndex(index, true);
3207 if (!root.get())
3208 {
3209 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003210 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
3211 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003212 return 0;
3213 }
3214 else
3215 {
3216 list->Append(root);
3217 *first_unparsed = end+1; // skip ]
Enrico Granata86cc9822012-03-19 22:58:49 +00003218 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3219 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003220 return 1;
3221 }
3222 }
3223 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
3224 {
Enrico Granata86cc9822012-03-19 22:58:49 +00003225 if (*what_next == ValueObject::eExpressionPathAftermathDereference && // 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 +00003226 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
3227 {
3228 Error error;
3229 root = root->Dereference(error);
3230 if (error.Fail() || !root.get())
3231 {
3232 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003233 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
3234 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003235 return 0;
3236 }
3237 else
3238 {
Enrico Granata86cc9822012-03-19 22:58:49 +00003239 *what_next = eExpressionPathAftermathNothing;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003240 continue;
3241 }
3242 }
3243 else
3244 {
3245 root = root->GetSyntheticArrayMemberFromPointer(index, true);
3246 if (!root.get())
3247 {
3248 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003249 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
3250 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003251 return 0;
3252 }
3253 else
3254 {
3255 list->Append(root);
3256 *first_unparsed = end+1; // skip ]
Enrico Granata86cc9822012-03-19 22:58:49 +00003257 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3258 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003259 return 1;
3260 }
3261 }
3262 }
3263 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
3264 {
3265 root = root->GetSyntheticBitFieldChild(index, index, true);
3266 if (!root.get())
3267 {
3268 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003269 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
3270 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003271 return 0;
3272 }
3273 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
3274 {
3275 list->Append(root);
3276 *first_unparsed = end+1; // skip ]
Enrico Granata86cc9822012-03-19 22:58:49 +00003277 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3278 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003279 return 1;
3280 }
3281 }
3282 }
3283 else // we have a low and a high index
3284 {
3285 char *end = NULL;
3286 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
3287 if (!end || end != separator_position) // if something weird is in our way return an error
3288 {
3289 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003290 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3291 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003292 return 0;
3293 }
3294 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
3295 if (!end || end != close_bracket_position) // if something weird is in our way return an error
3296 {
3297 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003298 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3299 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003300 return 0;
3301 }
3302 if (index_lower > index_higher) // swap indices if required
3303 {
3304 unsigned long temp = index_lower;
3305 index_lower = index_higher;
3306 index_higher = temp;
3307 }
3308 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
3309 {
3310 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
3311 if (!root.get())
3312 {
3313 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003314 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
3315 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003316 return 0;
3317 }
3318 else
3319 {
3320 list->Append(root);
3321 *first_unparsed = end+1; // skip ]
Enrico Granata86cc9822012-03-19 22:58:49 +00003322 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3323 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003324 return 1;
3325 }
3326 }
3327 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 Granata86cc9822012-03-19 22:58:49 +00003328 *what_next == ValueObject::eExpressionPathAftermathDereference &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003329 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
3330 {
3331 Error error;
3332 root = root->Dereference(error);
3333 if (error.Fail() || !root.get())
3334 {
3335 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003336 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
3337 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003338 return 0;
3339 }
3340 else
3341 {
Enrico Granata86cc9822012-03-19 22:58:49 +00003342 *what_next = ValueObject::eExpressionPathAftermathNothing;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003343 continue;
3344 }
3345 }
3346 else
3347 {
Johnny Chen44805302011-07-19 19:48:13 +00003348 for (unsigned long index = index_lower;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003349 index <= index_higher; index++)
3350 {
3351 ValueObjectSP child =
3352 root->GetChildAtIndex(index, true);
3353 list->Append(child);
3354 }
3355 *first_unparsed = end+1;
Enrico Granata86cc9822012-03-19 22:58:49 +00003356 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3357 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003358 return index_higher-index_lower+1; // tell me number of items I added to the VOList
3359 }
3360 }
3361 break;
3362 }
3363 default: // some non-[ separator, or something entirely wrong, is in the way
3364 {
3365 *first_unparsed = expression_cstr;
Enrico Granata86cc9822012-03-19 22:58:49 +00003366 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3367 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00003368 return 0;
3369 break;
3370 }
3371 }
3372 }
3373}
3374
Enrico Granata0c489f52012-03-01 04:24:26 +00003375static void
3376DumpValueObject_Impl (Stream &s,
3377 ValueObject *valobj,
3378 const ValueObject::DumpValueObjectOptions& options,
3379 uint32_t ptr_depth,
3380 uint32_t curr_depth)
Greg Clayton1d3afba2010-10-05 00:00:42 +00003381{
Greg Clayton007d5be2011-05-30 00:49:24 +00003382 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00003383 {
Enrico Granata5548cb52013-01-28 23:47:25 +00003384 bool update_success = valobj->UpdateValueIfNeeded (true);
Greg Clayton007d5be2011-05-30 00:49:24 +00003385
Enrico Granata0c489f52012-03-01 04:24:26 +00003386 const char *root_valobj_name =
3387 options.m_root_valobj_name.empty() ?
3388 valobj->GetName().AsCString() :
3389 options.m_root_valobj_name.c_str();
3390
3391 if (update_success && options.m_use_dynamic != eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00003392 {
Enrico Granata0c489f52012-03-01 04:24:26 +00003393 ValueObject *dynamic_value = valobj->GetDynamicValue(options.m_use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00003394 if (dynamic_value)
3395 valobj = dynamic_value;
3396 }
3397
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003398 clang_type_t clang_type = valobj->GetClangType();
3399
Greg Clayton73b472d2010-10-27 03:32:59 +00003400 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003401 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00003402 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
3403 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003404
Enrico Granata0c489f52012-03-01 04:24:26 +00003405 const bool print_valobj = options.m_flat_output == false || has_value;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003406
3407 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00003408 {
Enrico Granata0c489f52012-03-01 04:24:26 +00003409 if (options.m_show_location)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003410 {
Jim Ingham6035b672011-03-31 00:19:25 +00003411 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003412 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00003413
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003414 s.Indent();
Enrico Granata2b2631c2012-08-09 16:51:25 +00003415
3416 bool show_type = true;
3417 // if we are at the root-level and been asked to hide the root's type, then hide it
3418 if (curr_depth == 0 && options.m_hide_root_type)
3419 show_type = false;
3420 else
3421 // otherwise decide according to the usual rules (asked to show types - always at the root level)
3422 show_type = options.m_show_types || (curr_depth == 0 && !options.m_flat_output);
3423
3424 if (show_type)
Greg Clayton0fa5c972013-04-25 01:05:15 +00003425 {
3426 // Some ValueObjects don't have types (like registers sets). Only print
3427 // the type if there is one to print
3428 ConstString qualified_type_name(valobj->GetQualifiedTypeName());
3429 if (qualified_type_name)
3430 s.Printf("(%s) ", qualified_type_name.GetCString());
3431 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00003432
Enrico Granata0c489f52012-03-01 04:24:26 +00003433 if (options.m_flat_output)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003434 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003435 // If we are showing types, also qualify the C++ base classes
Enrico Granata0c489f52012-03-01 04:24:26 +00003436 const bool qualify_cxx_base_classes = options.m_show_types;
Enrico Granata9a31ccb2013-01-29 01:35:01 +00003437 if (!options.m_hide_name)
3438 {
3439 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
3440 s.PutCString(" =");
3441 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003442 }
Enrico Granata9a31ccb2013-01-29 01:35:01 +00003443 else if (!options.m_hide_name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003444 {
3445 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
3446 s.Printf ("%s =", name_cstr);
3447 }
3448
Enrico Granata0c489f52012-03-01 04:24:26 +00003449 if (!options.m_scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003450 {
Greg Clayton007d5be2011-05-30 00:49:24 +00003451 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003452 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00003453 }
3454
Enrico Granata0c489f52012-03-01 04:24:26 +00003455 std::string summary_str;
Greg Clayton6efba4f2012-01-26 21:08:30 +00003456 std::string value_str;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003457 const char *val_cstr = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00003458 const char *sum_cstr = NULL;
Enrico Granata0c489f52012-03-01 04:24:26 +00003459 TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : valobj->GetSummaryFormat().get();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003460
Enrico Granata0c489f52012-03-01 04:24:26 +00003461 if (options.m_omit_summary_depth > 0)
Enrico Granata0c5ef692011-07-16 01:22:04 +00003462 entry = NULL;
3463
Enrico Granata9e7b3882012-12-13 23:50:33 +00003464 bool is_nil = valobj->IsObjCNil();
3465
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003466 if (err_cstr == NULL)
3467 {
Enrico Granata0c489f52012-03-01 04:24:26 +00003468 if (options.m_format != eFormatDefault && options.m_format != valobj->GetFormat())
Greg Clayton6efba4f2012-01-26 21:08:30 +00003469 {
Enrico Granata0c489f52012-03-01 04:24:26 +00003470 valobj->GetValueAsCString(options.m_format,
3471 value_str);
Greg Clayton6efba4f2012-01-26 21:08:30 +00003472 }
Enrico Granata0c489f52012-03-01 04:24:26 +00003473 else
Greg Clayton6efba4f2012-01-26 21:08:30 +00003474 {
Enrico Granata0c489f52012-03-01 04:24:26 +00003475 val_cstr = valobj->GetValueAsCString();
3476 if (val_cstr)
3477 value_str = val_cstr;
Greg Clayton6efba4f2012-01-26 21:08:30 +00003478 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003479 err_cstr = valobj->GetError().AsCString();
3480 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00003481
3482 if (err_cstr)
3483 {
Greg Clayton007d5be2011-05-30 00:49:24 +00003484 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00003485 }
3486 else
3487 {
Greg Clayton73b472d2010-10-27 03:32:59 +00003488 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003489 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00003490 {
Enrico Granata9e7b3882012-12-13 23:50:33 +00003491 if (is_nil)
3492 sum_cstr = "nil";
3493 else if (options.m_omit_summary_depth == 0)
Enrico Granata0c489f52012-03-01 04:24:26 +00003494 {
3495 if (options.m_summary_sp)
3496 {
3497 valobj->GetSummaryAsCString(entry, summary_str);
3498 sum_cstr = summary_str.c_str();
3499 }
3500 else
3501 sum_cstr = valobj->GetSummaryAsCString();
3502 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00003503
Greg Clayton6efba4f2012-01-26 21:08:30 +00003504 // Make sure we have a value and make sure the summary didn't
Enrico Granata9e7b3882012-12-13 23:50:33 +00003505 // specify that the value should not be printed - and do not print
3506 // the value if this thing is nil
Enrico Granatac2a58d72013-03-25 19:46:48 +00003507 // (but show the value if the user passes a format explicitly)
3508 if (!is_nil && !value_str.empty() && (entry == NULL || (entry->DoesPrintValue() || options.m_format != eFormatDefault) || sum_cstr == NULL) && !options.m_hide_value)
Greg Clayton6efba4f2012-01-26 21:08:30 +00003509 s.Printf(" %s", value_str.c_str());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003510
Enrico Granata9dd75c82011-07-15 23:30:15 +00003511 if (sum_cstr)
Enrico Granata0c489f52012-03-01 04:24:26 +00003512 s.Printf(" %s", sum_cstr);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003513
Enrico Granata9e7b3882012-12-13 23:50:33 +00003514 // let's avoid the overly verbose no description error for a nil thing
3515 if (options.m_use_objc && !is_nil)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003516 {
Enrico Granata9a31ccb2013-01-29 01:35:01 +00003517 if (!options.m_hide_value || !options.m_hide_name)
3518 s.Printf(" ");
Jim Ingham6035b672011-03-31 00:19:25 +00003519 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003520 if (object_desc)
Enrico Granata9a31ccb2013-01-29 01:35:01 +00003521 s.Printf("%s\n", object_desc);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003522 else
Enrico Granata9a31ccb2013-01-29 01:35:01 +00003523 s.Printf ("[no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003524 return;
Enrico Granata0a3958e2011-07-02 00:25:22 +00003525 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003526 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00003527
Enrico Granata0c489f52012-03-01 04:24:26 +00003528 if (curr_depth < options.m_max_depth)
Greg Clayton1d3afba2010-10-05 00:00:42 +00003529 {
Greg Clayton73b472d2010-10-27 03:32:59 +00003530 // We will show children for all concrete types. We won't show
3531 // pointer contents unless a pointer depth has been specified.
3532 // We won't reference contents unless the reference is the
3533 // root object (depth of zero).
3534 bool print_children = true;
3535
3536 // Use a new temporary pointer depth in case we override the
3537 // current pointer depth below...
3538 uint32_t curr_ptr_depth = ptr_depth;
3539
3540 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
3541 if (is_ptr || is_ref)
3542 {
3543 // We have a pointer or reference whose value is an address.
3544 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00003545 AddressType ptr_address_type;
Enrico Granata9128ee22011-09-06 19:20:51 +00003546 if (valobj->GetPointerValue (&ptr_address_type) == 0)
Greg Clayton73b472d2010-10-27 03:32:59 +00003547 print_children = false;
3548
3549 else if (is_ref && curr_depth == 0)
3550 {
3551 // If this is the root object (depth is zero) that we are showing
3552 // and it is a reference, and no pointer depth has been supplied
3553 // print out what it references. Don't do this at deeper depths
3554 // otherwise we can end up with infinite recursion...
3555 curr_ptr_depth = 1;
3556 }
3557
3558 if (curr_ptr_depth == 0)
3559 print_children = false;
3560 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00003561
Enrico Granata0a3958e2011-07-02 00:25:22 +00003562 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00003563 {
Enrico Granata86cc9822012-03-19 22:58:49 +00003564 ValueObjectSP synth_valobj_sp = valobj->GetSyntheticValue (options.m_use_synthetic);
Greg Clayton0fa5c972013-04-25 01:05:15 +00003565 ValueObject* synth_valobj = (synth_valobj_sp ? synth_valobj_sp.get() : valobj);
Enrico Granatac5bc4122012-03-27 02:35:13 +00003566
Greg Claytonc7bece562013-01-25 18:06:21 +00003567 size_t num_children = synth_valobj->GetNumChildren();
Enrico Granata22c55d12011-08-12 02:00:06 +00003568 bool print_dotdotdot = false;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003569 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00003570 {
Enrico Granata0c489f52012-03-01 04:24:26 +00003571 if (options.m_flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00003572 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003573 if (print_valobj)
3574 s.EOL();
3575 }
3576 else
3577 {
3578 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00003579 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003580 s.IndentMore();
3581 }
Enrico Granata22c55d12011-08-12 02:00:06 +00003582
Greg Claytonc7bece562013-01-25 18:06:21 +00003583 const size_t max_num_children = valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
Enrico Granata22c55d12011-08-12 02:00:06 +00003584
Enrico Granata0c489f52012-03-01 04:24:26 +00003585 if (num_children > max_num_children && !options.m_ignore_cap)
Enrico Granata22c55d12011-08-12 02:00:06 +00003586 {
3587 num_children = max_num_children;
3588 print_dotdotdot = true;
3589 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003590
Enrico Granata0c489f52012-03-01 04:24:26 +00003591 ValueObject::DumpValueObjectOptions child_options(options);
Enrico Granatac953a6a2012-12-11 02:17:22 +00003592 child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName();
Enrico Granata9a31ccb2013-01-29 01:35:01 +00003593 child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value)
Enrico Granata0c489f52012-03-01 04:24:26 +00003594 .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
Greg Claytonc7bece562013-01-25 18:06:21 +00003595 for (size_t idx=0; idx<num_children; ++idx)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003596 {
Enrico Granatac482a192011-08-17 22:13:59 +00003597 ValueObjectSP child_sp(synth_valobj->GetChildAtIndex(idx, true));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003598 if (child_sp.get())
3599 {
Enrico Granata0c489f52012-03-01 04:24:26 +00003600 DumpValueObject_Impl (s,
3601 child_sp.get(),
3602 child_options,
3603 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
3604 curr_depth + 1);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003605 }
3606 }
3607
Enrico Granata0c489f52012-03-01 04:24:26 +00003608 if (!options.m_flat_output)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003609 {
Enrico Granata22c55d12011-08-12 02:00:06 +00003610 if (print_dotdotdot)
Enrico Granata61a80ba2011-08-12 16:42:31 +00003611 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00003612 ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
3613 Target *target = exe_ctx.GetTargetPtr();
3614 if (target)
3615 target->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
Enrico Granata22c55d12011-08-12 02:00:06 +00003616 s.Indent("...\n");
Enrico Granata61a80ba2011-08-12 16:42:31 +00003617 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003618 s.IndentLess();
3619 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00003620 }
3621 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003622 else if (has_children)
3623 {
3624 // Aggregate, no children...
3625 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00003626 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003627 }
3628 else
3629 {
3630 if (print_valobj)
3631 s.EOL();
3632 }
3633
Greg Clayton1d3afba2010-10-05 00:00:42 +00003634 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003635 else
3636 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00003637 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00003638 }
3639 }
3640 else
3641 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003642 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00003643 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003644 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00003645 }
3646 }
3647 }
3648 }
3649}
3650
Enrico Granata0c489f52012-03-01 04:24:26 +00003651void
Greg Claytonf830dbb2012-03-22 18:15:37 +00003652ValueObject::LogValueObject (Log *log,
3653 ValueObject *valobj)
3654{
3655 if (log && valobj)
3656 return LogValueObject (log, valobj, DumpValueObjectOptions::DefaultOptions());
3657}
3658
3659void
3660ValueObject::LogValueObject (Log *log,
3661 ValueObject *valobj,
3662 const DumpValueObjectOptions& options)
3663{
3664 if (log && valobj)
3665 {
3666 StreamString s;
3667 ValueObject::DumpValueObject (s, valobj, options);
3668 if (s.GetSize())
3669 log->PutCString(s.GetData());
3670 }
3671}
3672
3673void
Enrico Granata0c489f52012-03-01 04:24:26 +00003674ValueObject::DumpValueObject (Stream &s,
3675 ValueObject *valobj)
3676{
3677
3678 if (!valobj)
3679 return;
3680
3681 DumpValueObject_Impl(s,
3682 valobj,
3683 DumpValueObjectOptions::DefaultOptions(),
3684 0,
3685 0);
3686}
3687
3688void
3689ValueObject::DumpValueObject (Stream &s,
3690 ValueObject *valobj,
3691 const DumpValueObjectOptions& options)
3692{
3693 DumpValueObject_Impl(s,
3694 valobj,
3695 options,
3696 options.m_max_ptr_depth, // max pointer depth allowed, we will go down from here
3697 0 // current object depth is 0 since we are just starting
3698 );
3699}
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003700
3701ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00003702ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003703{
3704 ValueObjectSP valobj_sp;
3705
Enrico Granatac3e320a2011-08-02 17:27:39 +00003706 if (UpdateValueIfNeeded(false) && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003707 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00003708 ExecutionContext exe_ctx (GetExecutionContextRef());
3709 clang::ASTContext *ast = GetClangAST ();
3710
3711 DataExtractor data;
3712 data.SetByteOrder (m_data.GetByteOrder());
3713 data.SetAddressByteSize(m_data.GetAddressByteSize());
3714
Enrico Granata9f1e2042012-04-24 22:15:37 +00003715 if (IsBitfield())
3716 {
3717 Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
3718 m_error = v.GetValueAsData (&exe_ctx, ast, data, 0, GetModule().get());
3719 }
3720 else
3721 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule().get());
Greg Claytoncc4d0142012-02-17 07:49:44 +00003722
3723 valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
3724 ast,
3725 GetClangType(),
3726 name,
3727 data,
3728 GetAddressOf());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003729 }
Jim Ingham6035b672011-03-31 00:19:25 +00003730
3731 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003732 {
Jim Ingham58b59f92011-04-22 23:53:53 +00003733 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003734 }
3735 return valobj_sp;
3736}
3737
Greg Claytonafacd142011-09-02 01:15:17 +00003738ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00003739ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003740{
Jim Ingham58b59f92011-04-22 23:53:53 +00003741 if (m_deref_valobj)
3742 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00003743
Greg Clayton54979cd2010-12-15 05:08:08 +00003744 const bool is_pointer_type = IsPointerType();
3745 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003746 {
3747 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +00003748 bool ignore_array_bounds = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003749
3750 std::string child_name_str;
3751 uint32_t child_byte_size = 0;
3752 int32_t child_byte_offset = 0;
3753 uint32_t child_bitfield_bit_size = 0;
3754 uint32_t child_bitfield_bit_offset = 0;
3755 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00003756 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003757 const bool transparent_pointers = false;
3758 clang::ASTContext *clang_ast = GetClangAST();
3759 clang_type_t clang_type = GetClangType();
3760 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00003761
Greg Claytoncc4d0142012-02-17 07:49:44 +00003762 ExecutionContext exe_ctx (GetExecutionContextRef());
Jim Inghamd555bac2011-06-24 22:03:24 +00003763
3764 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
3765 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003766 GetName().GetCString(),
3767 clang_type,
3768 0,
3769 transparent_pointers,
3770 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003771 ignore_array_bounds,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003772 child_name_str,
3773 child_byte_size,
3774 child_byte_offset,
3775 child_bitfield_bit_size,
3776 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003777 child_is_base_class,
3778 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00003779 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003780 {
3781 ConstString child_name;
3782 if (!child_name_str.empty())
3783 child_name.SetCString (child_name_str.c_str());
3784
Jim Ingham58b59f92011-04-22 23:53:53 +00003785 m_deref_valobj = new ValueObjectChild (*this,
3786 clang_ast,
3787 child_clang_type,
3788 child_name,
3789 child_byte_size,
3790 child_byte_offset,
3791 child_bitfield_bit_size,
3792 child_bitfield_bit_offset,
3793 child_is_base_class,
Enrico Granata9128ee22011-09-06 19:20:51 +00003794 child_is_deref_of_parent,
3795 eAddressTypeInvalid);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003796 }
3797 }
Greg Clayton54979cd2010-12-15 05:08:08 +00003798
Jim Ingham58b59f92011-04-22 23:53:53 +00003799 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00003800 {
3801 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00003802 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00003803 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003804 else
3805 {
Greg Clayton54979cd2010-12-15 05:08:08 +00003806 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003807 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00003808
3809 if (is_pointer_type)
3810 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
3811 else
3812 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00003813 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003814 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003815}
3816
Greg Claytonafacd142011-09-02 01:15:17 +00003817ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00003818ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003819{
Jim Ingham78a685a2011-04-16 00:01:13 +00003820 if (m_addr_of_valobj_sp)
3821 return m_addr_of_valobj_sp;
3822
Greg Claytone0d378b2011-03-24 21:19:54 +00003823 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003824 const bool scalar_is_load_address = false;
Enrico Granata9128ee22011-09-06 19:20:51 +00003825 addr_t addr = GetAddressOf (scalar_is_load_address, &address_type);
Greg Clayton54979cd2010-12-15 05:08:08 +00003826 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003827 if (addr != LLDB_INVALID_ADDRESS)
3828 {
3829 switch (address_type)
3830 {
3831 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00003832 {
3833 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003834 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00003835 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
3836 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003837 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00003838
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003839 case eAddressTypeFile:
3840 case eAddressTypeLoad:
3841 case eAddressTypeHost:
3842 {
3843 clang::ASTContext *ast = GetClangAST();
3844 clang_type_t clang_type = GetClangType();
3845 if (ast && clang_type)
3846 {
3847 std::string name (1, '&');
3848 name.append (m_name.AsCString(""));
Greg Claytoncc4d0142012-02-17 07:49:44 +00003849 ExecutionContext exe_ctx (GetExecutionContextRef());
3850 m_addr_of_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
Jim Ingham58b59f92011-04-22 23:53:53 +00003851 ast,
3852 ClangASTContext::CreatePointerType (ast, clang_type),
3853 ConstString (name.c_str()),
3854 addr,
3855 eAddressTypeInvalid,
3856 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003857 }
3858 }
3859 break;
3860 }
3861 }
Sean Callananed185ab2013-04-19 19:47:32 +00003862 else
3863 {
3864 StreamString expr_path_strm;
3865 GetExpressionPath(expr_path_strm, true);
3866 error.SetErrorStringWithFormat("'%s' doesn't have a valid address", expr_path_strm.GetString().c_str());
3867 }
3868
Jim Ingham78a685a2011-04-16 00:01:13 +00003869 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003870}
3871
Greg Clayton9a142cf2012-02-03 05:34:10 +00003872ValueObjectSP
3873ValueObject::Cast (const ClangASTType &clang_ast_type)
3874{
Greg Clayton81e871e2012-02-04 02:27:34 +00003875 return ValueObjectCast::Create (*this, GetName(), clang_ast_type);
Greg Clayton9a142cf2012-02-03 05:34:10 +00003876}
Greg Claytonb2dcc362011-05-05 23:32:56 +00003877
Greg Claytonafacd142011-09-02 01:15:17 +00003878ValueObjectSP
Greg Claytonb2dcc362011-05-05 23:32:56 +00003879ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
3880{
Greg Claytonafacd142011-09-02 01:15:17 +00003881 ValueObjectSP valobj_sp;
Greg Claytonb2dcc362011-05-05 23:32:56 +00003882 AddressType address_type;
Enrico Granata9128ee22011-09-06 19:20:51 +00003883 addr_t ptr_value = GetPointerValue (&address_type);
Greg Claytonb2dcc362011-05-05 23:32:56 +00003884
3885 if (ptr_value != LLDB_INVALID_ADDRESS)
3886 {
Greg Claytone72dfb32012-02-24 01:59:29 +00003887 Address ptr_addr (ptr_value);
Greg Claytoncc4d0142012-02-17 07:49:44 +00003888 ExecutionContext exe_ctx (GetExecutionContextRef());
3889 valobj_sp = ValueObjectMemory::Create (exe_ctx.GetBestExecutionContextScope(),
Greg Claytonb2dcc362011-05-05 23:32:56 +00003890 name,
3891 ptr_addr,
3892 clang_ast_type);
3893 }
3894 return valobj_sp;
3895}
3896
Greg Claytonafacd142011-09-02 01:15:17 +00003897ValueObjectSP
Greg Claytonb2dcc362011-05-05 23:32:56 +00003898ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
3899{
Greg Claytonafacd142011-09-02 01:15:17 +00003900 ValueObjectSP valobj_sp;
Greg Claytonb2dcc362011-05-05 23:32:56 +00003901 AddressType address_type;
Enrico Granata9128ee22011-09-06 19:20:51 +00003902 addr_t ptr_value = GetPointerValue (&address_type);
Greg Claytonb2dcc362011-05-05 23:32:56 +00003903
3904 if (ptr_value != LLDB_INVALID_ADDRESS)
3905 {
Greg Claytone72dfb32012-02-24 01:59:29 +00003906 Address ptr_addr (ptr_value);
Greg Claytoncc4d0142012-02-17 07:49:44 +00003907 ExecutionContext exe_ctx (GetExecutionContextRef());
3908 valobj_sp = ValueObjectMemory::Create (exe_ctx.GetBestExecutionContextScope(),
Greg Claytonb2dcc362011-05-05 23:32:56 +00003909 name,
3910 ptr_addr,
3911 type_sp);
3912 }
3913 return valobj_sp;
3914}
3915
Jim Ingham6035b672011-03-31 00:19:25 +00003916ValueObject::EvaluationPoint::EvaluationPoint () :
Greg Claytoncc4d0142012-02-17 07:49:44 +00003917 m_mod_id(),
3918 m_exe_ctx_ref(),
3919 m_needs_update (true),
3920 m_first_update (true)
Jim Ingham6035b672011-03-31 00:19:25 +00003921{
3922}
3923
3924ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Greg Claytoncc4d0142012-02-17 07:49:44 +00003925 m_mod_id(),
3926 m_exe_ctx_ref(),
Jim Ingham6035b672011-03-31 00:19:25 +00003927 m_needs_update (true),
Greg Claytoncc4d0142012-02-17 07:49:44 +00003928 m_first_update (true)
Jim Ingham6035b672011-03-31 00:19:25 +00003929{
Greg Claytoncc4d0142012-02-17 07:49:44 +00003930 ExecutionContext exe_ctx(exe_scope);
3931 TargetSP target_sp (exe_ctx.GetTargetSP());
3932 if (target_sp)
Jim Ingham6035b672011-03-31 00:19:25 +00003933 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00003934 m_exe_ctx_ref.SetTargetSP (target_sp);
3935 ProcessSP process_sp (exe_ctx.GetProcessSP());
3936 if (!process_sp)
3937 process_sp = target_sp->GetProcessSP();
Jim Ingham6035b672011-03-31 00:19:25 +00003938
Greg Claytoncc4d0142012-02-17 07:49:44 +00003939 if (process_sp)
Jim Ingham6035b672011-03-31 00:19:25 +00003940 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00003941 m_mod_id = process_sp->GetModID();
3942 m_exe_ctx_ref.SetProcessSP (process_sp);
Jim Ingham4b536182011-08-09 02:12:22 +00003943
Greg Claytoncc4d0142012-02-17 07:49:44 +00003944 ThreadSP thread_sp (exe_ctx.GetThreadSP());
Jim Ingham6035b672011-03-31 00:19:25 +00003945
Greg Claytoncc4d0142012-02-17 07:49:44 +00003946 if (!thread_sp)
Jim Ingham6035b672011-03-31 00:19:25 +00003947 {
3948 if (use_selected)
Greg Claytoncc4d0142012-02-17 07:49:44 +00003949 thread_sp = process_sp->GetThreadList().GetSelectedThread();
Jim Ingham6035b672011-03-31 00:19:25 +00003950 }
Jim Ingham6035b672011-03-31 00:19:25 +00003951
Greg Claytoncc4d0142012-02-17 07:49:44 +00003952 if (thread_sp)
Jim Ingham6035b672011-03-31 00:19:25 +00003953 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00003954 m_exe_ctx_ref.SetThreadSP(thread_sp);
Greg Claytonc14ee322011-09-22 04:58:26 +00003955
Greg Claytoncc4d0142012-02-17 07:49:44 +00003956 StackFrameSP frame_sp (exe_ctx.GetFrameSP());
3957 if (!frame_sp)
Jim Ingham6035b672011-03-31 00:19:25 +00003958 {
3959 if (use_selected)
Greg Claytoncc4d0142012-02-17 07:49:44 +00003960 frame_sp = thread_sp->GetSelectedFrame();
Jim Ingham6035b672011-03-31 00:19:25 +00003961 }
Greg Claytoncc4d0142012-02-17 07:49:44 +00003962 if (frame_sp)
3963 m_exe_ctx_ref.SetFrameSP(frame_sp);
Jim Ingham6035b672011-03-31 00:19:25 +00003964 }
3965 }
3966 }
Jim Ingham6035b672011-03-31 00:19:25 +00003967}
3968
3969ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
Greg Claytoncc4d0142012-02-17 07:49:44 +00003970 m_mod_id(),
3971 m_exe_ctx_ref(rhs.m_exe_ctx_ref),
3972 m_needs_update (true),
3973 m_first_update (true)
Jim Ingham6035b672011-03-31 00:19:25 +00003974{
3975}
3976
3977ValueObject::EvaluationPoint::~EvaluationPoint ()
3978{
3979}
3980
Jim Ingham6035b672011-03-31 00:19:25 +00003981// This function checks the EvaluationPoint against the current process state. If the current
3982// state matches the evaluation point, or the evaluation point is already invalid, then we return
3983// false, meaning "no change". If the current state is different, we update our state, and return
3984// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
3985// future calls to NeedsUpdate will return true.
Jim Ingham9ee01152011-12-10 01:49:43 +00003986// exe_scope will be set to the current execution context scope.
Jim Ingham6035b672011-03-31 00:19:25 +00003987
3988bool
Greg Claytoncc4d0142012-02-17 07:49:44 +00003989ValueObject::EvaluationPoint::SyncWithProcessState()
Jim Ingham6035b672011-03-31 00:19:25 +00003990{
Jim Ingham73ca05a2011-12-17 01:35:57 +00003991
3992 // Start with the target, if it is NULL, then we're obviously not going to get any further:
Greg Claytoncc4d0142012-02-17 07:49:44 +00003993 ExecutionContext exe_ctx(m_exe_ctx_ref.Lock());
Jim Ingham73ca05a2011-12-17 01:35:57 +00003994
Greg Claytoncc4d0142012-02-17 07:49:44 +00003995 if (exe_ctx.GetTargetPtr() == NULL)
Jim Ingham73ca05a2011-12-17 01:35:57 +00003996 return false;
3997
Jim Ingham6035b672011-03-31 00:19:25 +00003998 // If we don't have a process nothing can change.
Greg Claytoncc4d0142012-02-17 07:49:44 +00003999 Process *process = exe_ctx.GetProcessPtr();
4000 if (process == NULL)
Jim Ingham6035b672011-03-31 00:19:25 +00004001 return false;
Jim Ingham73ca05a2011-12-17 01:35:57 +00004002
Jim Ingham6035b672011-03-31 00:19:25 +00004003 // If our stop id is the current stop ID, nothing has changed:
Greg Claytoncc4d0142012-02-17 07:49:44 +00004004 ProcessModID current_mod_id = process->GetModID();
Jim Ingham4b536182011-08-09 02:12:22 +00004005
Jim Ingham78a685a2011-04-16 00:01:13 +00004006 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
4007 // In either case, we aren't going to be able to sync with the process state.
Jim Ingham4b536182011-08-09 02:12:22 +00004008 if (current_mod_id.GetStopID() == 0)
Jim Ingham78a685a2011-04-16 00:01:13 +00004009 return false;
Jim Ingham9ee01152011-12-10 01:49:43 +00004010
Greg Clayton23f59502012-07-17 03:23:13 +00004011 bool changed = false;
4012 const bool was_valid = m_mod_id.IsValid();
4013 if (was_valid)
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00004014 {
4015 if (m_mod_id == current_mod_id)
4016 {
Jim Ingham5cfbe4a2012-01-12 22:42:34 +00004017 // Everything is already up to date in this object, no need to
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00004018 // update the execution context scope.
Jim Ingham9ee01152011-12-10 01:49:43 +00004019 changed = false;
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00004020 }
Jim Ingham9ee01152011-12-10 01:49:43 +00004021 else
4022 {
4023 m_mod_id = current_mod_id;
4024 m_needs_update = true;
4025 changed = true;
4026 }
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00004027 }
Jim Ingham6035b672011-03-31 00:19:25 +00004028
Jim Ingham73ca05a2011-12-17 01:35:57 +00004029 // Now re-look up the thread and frame in case the underlying objects have gone away & been recreated.
4030 // That way we'll be sure to return a valid exe_scope.
4031 // If we used to have a thread or a frame but can't find it anymore, then mark ourselves as invalid.
Jim Ingham6035b672011-03-31 00:19:25 +00004032
Greg Claytoncc4d0142012-02-17 07:49:44 +00004033 if (m_exe_ctx_ref.HasThreadRef())
Jim Ingham6035b672011-03-31 00:19:25 +00004034 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00004035 ThreadSP thread_sp (m_exe_ctx_ref.GetThreadSP());
4036 if (thread_sp)
Greg Clayton262f80d2011-07-06 16:49:27 +00004037 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00004038 if (m_exe_ctx_ref.HasFrameRef())
4039 {
4040 StackFrameSP frame_sp (m_exe_ctx_ref.GetFrameSP());
4041 if (!frame_sp)
4042 {
4043 // We used to have a frame, but now it is gone
4044 SetInvalid();
Greg Clayton23f59502012-07-17 03:23:13 +00004045 changed = was_valid;
Greg Claytoncc4d0142012-02-17 07:49:44 +00004046 }
4047 }
Greg Clayton262f80d2011-07-06 16:49:27 +00004048 }
Jim Ingham6035b672011-03-31 00:19:25 +00004049 else
4050 {
Greg Claytoncc4d0142012-02-17 07:49:44 +00004051 // We used to have a thread, but now it is gone
4052 SetInvalid();
Greg Clayton23f59502012-07-17 03:23:13 +00004053 changed = was_valid;
Jim Ingham6035b672011-03-31 00:19:25 +00004054 }
Greg Claytoncc4d0142012-02-17 07:49:44 +00004055
Jim Ingham6035b672011-03-31 00:19:25 +00004056 }
Jim Ingham9ee01152011-12-10 01:49:43 +00004057 return changed;
Jim Ingham6035b672011-03-31 00:19:25 +00004058}
4059
Jim Ingham61be0902011-05-02 18:13:59 +00004060void
4061ValueObject::EvaluationPoint::SetUpdated ()
4062{
Greg Claytoncc4d0142012-02-17 07:49:44 +00004063 ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
4064 if (process_sp)
4065 m_mod_id = process_sp->GetModID();
Jim Ingham61be0902011-05-02 18:13:59 +00004066 m_first_update = false;
4067 m_needs_update = false;
Jim Ingham61be0902011-05-02 18:13:59 +00004068}
4069
4070
Greg Claytoncc4d0142012-02-17 07:49:44 +00004071//bool
4072//ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
4073//{
4074// if (!IsValid())
4075// return false;
4076//
4077// bool needs_update = false;
4078//
4079// // The target has to be non-null, and the
4080// Target *target = exe_scope->CalculateTarget();
4081// if (target != NULL)
4082// {
4083// Target *old_target = m_target_sp.get();
4084// assert (target == old_target);
4085// Process *process = exe_scope->CalculateProcess();
4086// if (process != NULL)
4087// {
4088// // FOR NOW - assume you can't update variable objects across process boundaries.
4089// Process *old_process = m_process_sp.get();
4090// assert (process == old_process);
4091// ProcessModID current_mod_id = process->GetModID();
4092// if (m_mod_id != current_mod_id)
4093// {
4094// needs_update = true;
4095// m_mod_id = current_mod_id;
4096// }
4097// // See if we're switching the thread or stack context. If no thread is given, this is
4098// // being evaluated in a global context.
4099// Thread *thread = exe_scope->CalculateThread();
4100// if (thread != NULL)
4101// {
4102// user_id_t new_thread_index = thread->GetIndexID();
4103// if (new_thread_index != m_thread_id)
4104// {
4105// needs_update = true;
4106// m_thread_id = new_thread_index;
4107// m_stack_id.Clear();
4108// }
4109//
4110// StackFrame *new_frame = exe_scope->CalculateStackFrame();
4111// if (new_frame != NULL)
4112// {
4113// if (new_frame->GetStackID() != m_stack_id)
4114// {
4115// needs_update = true;
4116// m_stack_id = new_frame->GetStackID();
4117// }
4118// }
4119// else
4120// {
4121// m_stack_id.Clear();
4122// needs_update = true;
4123// }
4124// }
4125// else
4126// {
4127// // If this had been given a thread, and now there is none, we should update.
4128// // Otherwise we don't have to do anything.
4129// if (m_thread_id != LLDB_INVALID_UID)
4130// {
4131// m_thread_id = LLDB_INVALID_UID;
4132// m_stack_id.Clear();
4133// needs_update = true;
4134// }
4135// }
4136// }
4137// else
4138// {
4139// // If there is no process, then we don't need to update anything.
4140// // But if we're switching from having a process to not, we should try to update.
4141// if (m_process_sp.get() != NULL)
4142// {
4143// needs_update = true;
4144// m_process_sp.reset();
4145// m_thread_id = LLDB_INVALID_UID;
4146// m_stack_id.Clear();
4147// }
4148// }
4149// }
4150// else
4151// {
4152// // If there's no target, nothing can change so we don't need to update anything.
4153// // But if we're switching from having a target to not, we should try to update.
4154// if (m_target_sp.get() != NULL)
4155// {
4156// needs_update = true;
4157// m_target_sp.reset();
4158// m_process_sp.reset();
4159// m_thread_id = LLDB_INVALID_UID;
4160// m_stack_id.Clear();
4161// }
4162// }
4163// if (!m_needs_update)
4164// m_needs_update = needs_update;
4165//
4166// return needs_update;
4167//}
Enrico Granataf2bbf712011-07-15 02:26:42 +00004168
4169void
Enrico Granata86cc9822012-03-19 22:58:49 +00004170ValueObject::ClearUserVisibleData(uint32_t clear_mask)
Enrico Granataf2bbf712011-07-15 02:26:42 +00004171{
Enrico Granata86cc9822012-03-19 22:58:49 +00004172 if ((clear_mask & eClearUserVisibleDataItemsValue) == eClearUserVisibleDataItemsValue)
4173 m_value_str.clear();
4174
4175 if ((clear_mask & eClearUserVisibleDataItemsLocation) == eClearUserVisibleDataItemsLocation)
4176 m_location_str.clear();
4177
4178 if ((clear_mask & eClearUserVisibleDataItemsSummary) == eClearUserVisibleDataItemsSummary)
4179 {
Enrico Granata86cc9822012-03-19 22:58:49 +00004180 m_summary_str.clear();
4181 }
4182
4183 if ((clear_mask & eClearUserVisibleDataItemsDescription) == eClearUserVisibleDataItemsDescription)
4184 m_object_desc_str.clear();
4185
4186 if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) == eClearUserVisibleDataItemsSyntheticChildren)
4187 {
4188 if (m_synthetic_value)
4189 m_synthetic_value = NULL;
4190 }
Johnny Chen44805302011-07-19 19:48:13 +00004191}
Enrico Granata9128ee22011-09-06 19:20:51 +00004192
4193SymbolContextScope *
4194ValueObject::GetSymbolContextScope()
4195{
4196 if (m_parent)
4197 {
4198 if (!m_parent->IsPointerOrReferenceType())
4199 return m_parent->GetSymbolContextScope();
4200 }
4201 return NULL;
4202}
Enrico Granatab2698cd2012-09-13 18:27:09 +00004203
4204lldb::ValueObjectSP
4205ValueObject::CreateValueObjectFromExpression (const char* name,
4206 const char* expression,
4207 const ExecutionContext& exe_ctx)
4208{
4209 lldb::ValueObjectSP retval_sp;
4210 lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
4211 if (!target_sp)
4212 return retval_sp;
4213 if (!expression || !*expression)
4214 return retval_sp;
4215 target_sp->EvaluateExpression (expression,
4216 exe_ctx.GetFrameSP().get(),
4217 retval_sp);
4218 if (retval_sp && name && *name)
4219 retval_sp->SetName(ConstString(name));
4220 return retval_sp;
4221}
4222
4223lldb::ValueObjectSP
4224ValueObject::CreateValueObjectFromAddress (const char* name,
4225 uint64_t address,
4226 const ExecutionContext& exe_ctx,
4227 ClangASTType type)
4228{
4229 ClangASTType pointer_type(type.GetASTContext(),type.GetPointerType());
4230 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
4231 lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
4232 pointer_type.GetASTContext(),
4233 pointer_type.GetOpaqueQualType(),
4234 ConstString(name),
4235 buffer,
4236 lldb::endian::InlHostByteOrder(),
4237 exe_ctx.GetAddressByteSize()));
4238 if (ptr_result_valobj_sp)
4239 {
4240 ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
4241 Error err;
4242 ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
4243 if (ptr_result_valobj_sp && name && *name)
4244 ptr_result_valobj_sp->SetName(ConstString(name));
4245 }
4246 return ptr_result_valobj_sp;
4247}
4248
4249lldb::ValueObjectSP
4250ValueObject::CreateValueObjectFromData (const char* name,
4251 DataExtractor& data,
4252 const ExecutionContext& exe_ctx,
4253 ClangASTType type)
4254{
4255 lldb::ValueObjectSP new_value_sp;
4256 new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
4257 type.GetASTContext() ,
4258 type.GetOpaqueQualType(),
4259 ConstString(name),
4260 data,
4261 LLDB_INVALID_ADDRESS);
4262 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
4263 if (new_value_sp && name && *name)
4264 new_value_sp->SetName(ConstString(name));
4265 return new_value_sp;
4266}
Enrico Granata4873e522013-04-11 22:48:58 +00004267
4268ModuleSP
4269ValueObject::GetModule ()
4270{
4271 ValueObject* root(GetRoot());
4272 if (root != this)
4273 return root->GetModule();
4274 return lldb::ModuleSP();
4275}
4276
4277ValueObject*
4278ValueObject::GetRoot ()
4279{
4280 if (m_root)
4281 return m_root;
4282 ValueObject* parent = m_parent;
4283 if (!parent)
4284 return (m_root = this);
4285 while (parent->m_parent)
4286 {
4287 if (parent->m_root)
4288 return (m_root = parent->m_root);
4289 parent = parent->m_parent;
4290 }
4291 return (m_root = parent);
4292}
4293
4294AddressType
4295ValueObject::GetAddressTypeOfChildren()
4296{
4297 if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid)
4298 {
4299 ValueObject* root(GetRoot());
4300 if (root != this)
4301 return root->GetAddressTypeOfChildren();
4302 }
4303 return m_address_type_of_ptr_or_ref_children;
4304}
4305
4306lldb::DynamicValueType
4307ValueObject::GetDynamicValueType ()
4308{
4309 ValueObject* with_dv_info = this;
4310 while (with_dv_info)
4311 {
4312 if (with_dv_info->HasDynamicValueTypeInfo())
4313 return with_dv_info->GetDynamicValueTypeImpl();
4314 with_dv_info = with_dv_info->m_parent;
4315 }
4316 return lldb::eNoDynamicValues;
4317}
Enrico Granata39d51412013-05-31 17:43:40 +00004318
Enrico Granata4873e522013-04-11 22:48:58 +00004319lldb::Format
4320ValueObject::GetFormat () const
4321{
4322 const ValueObject* with_fmt_info = this;
4323 while (with_fmt_info)
4324 {
4325 if (with_fmt_info->m_format != lldb::eFormatDefault)
4326 return with_fmt_info->m_format;
4327 with_fmt_info = with_fmt_info->m_parent;
4328 }
4329 return m_format;
4330}