blob: 09cbd8c60f946d4e8ba2727d196e2654e607d84e [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ValueObject.cpp -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/ValueObject.h"
11
12// C Includes
Greg Claytonf5e56de2010-09-14 23:36:40 +000013#include <stdlib.h>
14
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015// C++ Includes
16// Other libraries and framework includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "llvm/Support/raw_ostream.h"
Jim Ingham5a369122010-09-28 01:25:32 +000018#include "clang/AST/Type.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019
20// Project includes
21#include "lldb/Core/DataBufferHeap.h"
Enrico Granata4becb372011-06-29 22:27:15 +000022#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/StreamString.h"
24#include "lldb/Core/ValueObjectChild.h"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000025#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000026#include "lldb/Core/ValueObjectDynamicValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/ValueObjectList.h"
Greg Claytonb2dcc362011-05-05 23:32:56 +000028#include "lldb/Core/ValueObjectMemory.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029
Greg Clayton7fb56d02011-02-01 01:31:41 +000030#include "lldb/Host/Endian.h"
31
Greg Claytone1a916a2010-07-21 22:12:05 +000032#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Symbol/ClangASTContext.h"
34#include "lldb/Symbol/Type.h"
35
Jim Ingham53c47f12010-09-10 23:12:17 +000036#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000037#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038#include "lldb/Target/Process.h"
39#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000040#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042
43using namespace lldb;
44using namespace lldb_private;
45
46static lldb::user_id_t g_value_obj_uid = 0;
47
48//----------------------------------------------------------------------
49// ValueObject constructor
50//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000051ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000053 m_parent (&parent),
Stephen Wilson71c21d12011-04-11 19:41:40 +000054 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055 m_name (),
56 m_data (),
57 m_value (),
58 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000059 m_value_str (),
60 m_old_value_str (),
61 m_location_str (),
62 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000063 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000064 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000065 m_children (),
66 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000067 m_dynamic_value (NULL),
68 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000069 m_format (eFormatDefault),
Greg Clayton288bdf92010-09-02 02:59:18 +000070 m_value_is_valid (false),
71 m_value_did_change (false),
72 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000073 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000074 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +000075 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +000076 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +000077 m_is_bitfield_for_scalar(false),
Enrico Granata4becb372011-06-29 22:27:15 +000078 m_last_format_mgr_revision(0),
79 m_last_summary_format(),
80 m_last_value_format()
Jim Ingham6035b672011-03-31 00:19:25 +000081{
Jim Ingham58b59f92011-04-22 23:53:53 +000082 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +000083}
84
85//----------------------------------------------------------------------
86// ValueObject constructor
87//----------------------------------------------------------------------
88ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
89 UserID (++g_value_obj_uid), // Unique identifier for every value object
90 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +000091 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +000092 m_name (),
93 m_data (),
94 m_value (),
95 m_error (),
96 m_value_str (),
97 m_old_value_str (),
98 m_location_str (),
99 m_summary_str (),
100 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000101 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +0000102 m_children (),
103 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000104 m_dynamic_value (NULL),
105 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +0000106 m_format (eFormatDefault),
107 m_value_is_valid (false),
108 m_value_did_change (false),
109 m_children_count_valid (false),
110 m_old_value_valid (false),
111 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +0000112 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +0000113 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +0000114 m_is_bitfield_for_scalar(false),
Enrico Granata4becb372011-06-29 22:27:15 +0000115 m_last_format_mgr_revision(0),
116 m_last_summary_format(),
117 m_last_value_format()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118{
Jim Ingham58b59f92011-04-22 23:53:53 +0000119 m_manager = new ValueObjectManager();
120 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121}
122
123//----------------------------------------------------------------------
124// Destructor
125//----------------------------------------------------------------------
126ValueObject::~ValueObject ()
127{
128}
129
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130bool
Enrico Granata0a3958e2011-07-02 00:25:22 +0000131ValueObject::UpdateValueIfNeeded (bool update_format)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132{
Enrico Granata4becb372011-06-29 22:27:15 +0000133
Enrico Granata0a3958e2011-07-02 00:25:22 +0000134 if (update_format)
135 UpdateFormatsIfNeeded();
Enrico Granata4becb372011-06-29 22:27:15 +0000136
Greg Claytonb71f3842010-10-05 03:13:51 +0000137 // If this is a constant value, then our success is predicated on whether
138 // we have an error or not
139 if (GetIsConstant())
140 return m_error.Success();
141
Jim Ingham6035b672011-03-31 00:19:25 +0000142 bool first_update = m_update_point.IsFirstEvaluation();
143
144 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145 {
Jim Ingham6035b672011-03-31 00:19:25 +0000146 m_update_point.SetUpdated();
147
148 // Save the old value using swap to avoid a string copy which
149 // also will clear our m_value_str
150 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151 {
Jim Ingham6035b672011-03-31 00:19:25 +0000152 m_old_value_valid = false;
153 }
154 else
155 {
156 m_old_value_valid = true;
157 m_old_value_str.swap (m_value_str);
158 m_value_str.clear();
159 }
160 m_location_str.clear();
161 m_summary_str.clear();
162 m_object_desc_str.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163
Jim Ingham6035b672011-03-31 00:19:25 +0000164 const bool value_was_valid = GetValueIsValid();
165 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000166
Jim Ingham6035b672011-03-31 00:19:25 +0000167 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000168
Jim Ingham6035b672011-03-31 00:19:25 +0000169 // Call the pure virtual function to update the value
170 bool success = UpdateValue ();
171
172 SetValueIsValid (success);
173
174 if (first_update)
175 SetValueDidChange (false);
176 else if (!m_value_did_change && success == false)
177 {
178 // The value wasn't gotten successfully, so we mark this
179 // as changed if the value used to be valid and now isn't
180 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181 }
182 }
183 return m_error.Success();
184}
185
Enrico Granata4becb372011-06-29 22:27:15 +0000186void
187ValueObject::UpdateFormatsIfNeeded()
188{
189 /*printf("CHECKING FOR UPDATES. I am at revision %d, while the format manager is at revision %d\n",
190 m_last_format_mgr_revision,
191 Debugger::ValueFormats::GetCurrentRevision());*/
192 if (m_last_format_mgr_revision != Debugger::ValueFormats::GetCurrentRevision())
193 {
194 if (m_last_summary_format.get())
195 m_last_summary_format.reset((SummaryFormat*)NULL);
196 if (m_last_value_format.get())
197 m_last_value_format.reset((ValueFormat*)NULL);
198 Debugger::ValueFormats::Get(*this, m_last_value_format);
Enrico Granata0a3958e2011-07-02 00:25:22 +0000199 if (!Debugger::SummaryFormats::Get(*this, m_last_summary_format))
200 Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format);
Enrico Granata4becb372011-06-29 22:27:15 +0000201 m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision();
202 m_value_str.clear();
203 m_summary_str.clear();
204 }
205}
206
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207DataExtractor &
208ValueObject::GetDataExtractor ()
209{
Jim Ingham78a685a2011-04-16 00:01:13 +0000210 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211 return m_data;
212}
213
214const Error &
Greg Clayton262f80d2011-07-06 16:49:27 +0000215ValueObject::GetError()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000216{
Greg Clayton262f80d2011-07-06 16:49:27 +0000217 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000218 return m_error;
219}
220
221const ConstString &
222ValueObject::GetName() const
223{
224 return m_name;
225}
226
227const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000228ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229{
Jim Ingham6035b672011-03-31 00:19:25 +0000230 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000231 {
232 if (m_location_str.empty())
233 {
234 StreamString sstr;
235
236 switch (m_value.GetValueType())
237 {
238 default:
239 break;
240
241 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000242 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243 {
244 RegisterInfo *reg_info = m_value.GetRegisterInfo();
245 if (reg_info)
246 {
247 if (reg_info->name)
248 m_location_str = reg_info->name;
249 else if (reg_info->alt_name)
250 m_location_str = reg_info->alt_name;
251 break;
252 }
253 }
254 m_location_str = "scalar";
255 break;
256
257 case Value::eValueTypeLoadAddress:
258 case Value::eValueTypeFileAddress:
259 case Value::eValueTypeHostAddress:
260 {
261 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
262 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
263 m_location_str.swap(sstr.GetString());
264 }
265 break;
266 }
267 }
268 }
269 return m_location_str.c_str();
270}
271
272Value &
273ValueObject::GetValue()
274{
275 return m_value;
276}
277
278const Value &
279ValueObject::GetValue() const
280{
281 return m_value;
282}
283
284bool
Jim Ingham6035b672011-03-31 00:19:25 +0000285ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000286{
287 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000288 ExecutionContextScope *exe_scope = GetExecutionContextScope();
289 if (exe_scope)
290 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000291 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
292 return scalar.IsValid();
293}
294
295bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000296ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297{
Greg Clayton288bdf92010-09-02 02:59:18 +0000298 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000299}
300
301
302void
303ValueObject::SetValueIsValid (bool b)
304{
Greg Clayton288bdf92010-09-02 02:59:18 +0000305 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306}
307
308bool
Jim Ingham6035b672011-03-31 00:19:25 +0000309ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310{
Jim Ingham6035b672011-03-31 00:19:25 +0000311 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000312 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313}
314
315void
316ValueObject::SetValueDidChange (bool value_changed)
317{
Greg Clayton288bdf92010-09-02 02:59:18 +0000318 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319}
320
321ValueObjectSP
322ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
323{
324 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000325 // We may need to update our value if we are dynamic
326 if (IsPossibleDynamicType ())
327 UpdateValueIfNeeded();
328 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000329 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000330 // Check if we have already made the child value object?
331 if (can_create && m_children[idx] == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000333 // No we haven't created the child at this index, so lets have our
334 // subclass do it and cache the result for quick future access.
335 m_children[idx] = CreateChildAtIndex (idx, false, 0);
Jim Ingham78a685a2011-04-16 00:01:13 +0000336 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000337
338 if (m_children[idx] != NULL)
339 return m_children[idx]->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 }
341 return child_sp;
342}
343
344uint32_t
345ValueObject::GetIndexOfChildWithName (const ConstString &name)
346{
347 bool omit_empty_base_classes = true;
348 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000349 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000350 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351 omit_empty_base_classes);
352}
353
354ValueObjectSP
355ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
356{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000357 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358 // classes (which really aren't part of the expression path), so we
359 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000361
Greg Claytondea8cb42011-06-29 22:09:02 +0000362 // We may need to update our value if we are dynamic
363 if (IsPossibleDynamicType ())
364 UpdateValueIfNeeded();
365
366 std::vector<uint32_t> child_indexes;
367 clang::ASTContext *clang_ast = GetClangAST();
368 void *clang_type = GetClangType();
369 bool omit_empty_base_classes = true;
370 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
371 clang_type,
372 name.GetCString(),
373 omit_empty_base_classes,
374 child_indexes);
375 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000377 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
378 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
379
380 child_sp = GetChildAtIndex(*pos, can_create);
381 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000383 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000384 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000385 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
386 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000387 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000388 else
389 {
390 child_sp.reset();
391 }
392
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000393 }
394 }
395 return child_sp;
396}
397
398
399uint32_t
400ValueObject::GetNumChildren ()
401{
Greg Clayton288bdf92010-09-02 02:59:18 +0000402 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403 {
404 SetNumChildren (CalculateNumChildren());
405 }
406 return m_children.size();
407}
408void
409ValueObject::SetNumChildren (uint32_t num_children)
410{
Greg Clayton288bdf92010-09-02 02:59:18 +0000411 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412 m_children.resize(num_children);
413}
414
415void
416ValueObject::SetName (const char *name)
417{
418 m_name.SetCString(name);
419}
420
421void
422ValueObject::SetName (const ConstString &name)
423{
424 m_name = name;
425}
426
Jim Ingham58b59f92011-04-22 23:53:53 +0000427ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000428ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
429{
Jim Ingham2eec4872011-05-07 00:10:58 +0000430 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000431
Greg Claytondea8cb42011-06-29 22:09:02 +0000432 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +0000433 bool ignore_array_bounds = synthetic_array_member;
Greg Claytondea8cb42011-06-29 22:09:02 +0000434 std::string child_name_str;
435 uint32_t child_byte_size = 0;
436 int32_t child_byte_offset = 0;
437 uint32_t child_bitfield_bit_size = 0;
438 uint32_t child_bitfield_bit_offset = 0;
439 bool child_is_base_class = false;
440 bool child_is_deref_of_parent = false;
441
442 const bool transparent_pointers = synthetic_array_member == false;
443 clang::ASTContext *clang_ast = GetClangAST();
444 clang_type_t clang_type = GetClangType();
445 clang_type_t child_clang_type;
446
447 ExecutionContext exe_ctx;
448 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
449
450 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
451 clang_ast,
452 GetName().GetCString(),
453 clang_type,
454 idx,
455 transparent_pointers,
456 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +0000457 ignore_array_bounds,
Greg Claytondea8cb42011-06-29 22:09:02 +0000458 child_name_str,
459 child_byte_size,
460 child_byte_offset,
461 child_bitfield_bit_size,
462 child_bitfield_bit_offset,
463 child_is_base_class,
464 child_is_deref_of_parent);
465 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000467 if (synthetic_index)
468 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469
Greg Claytondea8cb42011-06-29 22:09:02 +0000470 ConstString child_name;
471 if (!child_name_str.empty())
472 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000473
Greg Claytondea8cb42011-06-29 22:09:02 +0000474 valobj = new ValueObjectChild (*this,
475 clang_ast,
476 child_clang_type,
477 child_name,
478 child_byte_size,
479 child_byte_offset,
480 child_bitfield_bit_size,
481 child_bitfield_bit_offset,
482 child_is_base_class,
483 child_is_deref_of_parent);
484 if (m_pointers_point_to_load_addrs)
485 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000487
Jim Ingham58b59f92011-04-22 23:53:53 +0000488 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489}
490
491const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000492ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000493{
Jim Ingham6035b672011-03-31 00:19:25 +0000494 if (UpdateValueIfNeeded ())
Enrico Granata4becb372011-06-29 22:27:15 +0000495 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 if (m_summary_str.empty())
497 {
Enrico Granata4becb372011-06-29 22:27:15 +0000498 if (m_last_summary_format.get())
499 {
500 StreamString s;
501 ExecutionContext exe_ctx;
502 this->GetExecutionContextScope()->CalculateExecutionContext(exe_ctx);
Greg Claytondaf515f2011-07-09 20:12:33 +0000503 SymbolContext sc;
504 if (exe_ctx.frame)
505 sc = exe_ctx.frame->GetSymbolContext(eSymbolContextEverything);
Enrico Granata0a3958e2011-07-02 00:25:22 +0000506
507 if (m_last_summary_format->m_show_members_oneliner)
Enrico Granata4becb372011-06-29 22:27:15 +0000508 {
Enrico Granata0a3958e2011-07-02 00:25:22 +0000509 const uint32_t num_children = GetNumChildren();
510 if (num_children)
511 {
512
513 s.PutChar('(');
514
515 for (uint32_t idx=0; idx<num_children; ++idx)
516 {
517 ValueObjectSP child_sp(GetChildAtIndex(idx, true));
518 if (child_sp.get())
519 {
520 if (idx)
521 s.PutCString(", ");
522 s.PutCString(child_sp.get()->GetName().AsCString());
523 s.PutChar('=');
Enrico Granata9fc19442011-07-06 02:13:41 +0000524 s.PutCString(child_sp.get()->GetPrintableRepresentation());
Enrico Granata0a3958e2011-07-02 00:25:22 +0000525 }
526 }
527
528 s.PutChar(')');
529
530 m_summary_str.swap(s.GetString());
531 return m_summary_str.c_str();
532 }
533 else
534 return "()";
535
Enrico Granata4becb372011-06-29 22:27:15 +0000536 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000537 else
538 {
539 if (Debugger::FormatPrompt(m_last_summary_format->m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, this))
540 {
541 m_summary_str.swap(s.GetString());
542 return m_summary_str.c_str();
543 }
544 else
545 return NULL;
546 }
Enrico Granata4becb372011-06-29 22:27:15 +0000547 }
548
Greg Clayton73b472d2010-10-27 03:32:59 +0000549 clang_type_t clang_type = GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550
551 // See if this is a pointer to a C string?
Greg Clayton737b9322010-09-13 03:32:57 +0000552 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000553 {
Greg Clayton737b9322010-09-13 03:32:57 +0000554 StreamString sstr;
Greg Clayton73b472d2010-10-27 03:32:59 +0000555 clang_type_t elem_or_pointee_clang_type;
556 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000557 GetClangAST(),
558 &elem_or_pointee_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +0000559
Jim Ingham6035b672011-03-31 00:19:25 +0000560 ExecutionContextScope *exe_scope = GetExecutionContextScope();
561 if (exe_scope)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562 {
Jim Ingham6035b672011-03-31 00:19:25 +0000563 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
564 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000565 {
Jim Ingham6035b672011-03-31 00:19:25 +0000566 Process *process = exe_scope->CalculateProcess();
567 if (process != NULL)
568 {
569 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
570 AddressType cstr_address_type = eAddressTypeInvalid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000571
Jim Ingham6035b672011-03-31 00:19:25 +0000572 size_t cstr_len = 0;
Greg Clayton5707d222011-07-09 17:17:07 +0000573 bool capped_data = false;
Jim Ingham6035b672011-03-31 00:19:25 +0000574 if (type_flags.Test (ClangASTContext::eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575 {
Jim Ingham6035b672011-03-31 00:19:25 +0000576 // We have an array
577 cstr_len = ClangASTContext::GetArraySize (clang_type);
Greg Clayton5707d222011-07-09 17:17:07 +0000578 if (cstr_len > 512) // TODO: make cap a setting
579 {
580 cstr_len = ClangASTContext::GetArraySize (clang_type);
581 if (cstr_len > 512) // TODO: make cap a setting
582 {
583 capped_data = true;
584 cstr_len = 512;
585 }
586 }
Jim Ingham6035b672011-03-31 00:19:25 +0000587 cstr_address = GetAddressOf (cstr_address_type, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000588 }
Greg Clayton737b9322010-09-13 03:32:57 +0000589 else
590 {
Jim Ingham6035b672011-03-31 00:19:25 +0000591 // We have a pointer
592 cstr_address = GetPointerValue (cstr_address_type, true);
Greg Clayton737b9322010-09-13 03:32:57 +0000593 }
Jim Ingham6035b672011-03-31 00:19:25 +0000594 if (cstr_address != LLDB_INVALID_ADDRESS)
Greg Clayton737b9322010-09-13 03:32:57 +0000595 {
Jim Ingham6035b672011-03-31 00:19:25 +0000596 DataExtractor data;
597 size_t bytes_read = 0;
598 std::vector<char> data_buffer;
599 Error error;
600 if (cstr_len > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000601 {
Jim Ingham6035b672011-03-31 00:19:25 +0000602 data_buffer.resize(cstr_len);
603 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
604 bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error);
605 if (bytes_read > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000606 {
Jim Ingham6035b672011-03-31 00:19:25 +0000607 sstr << '"';
608 data.Dump (&sstr,
609 0, // Start offset in "data"
Greg Clayton4e4294b2011-06-17 23:50:44 +0000610 eFormatCharArray, // Print as characters
Jim Ingham6035b672011-03-31 00:19:25 +0000611 1, // Size of item (1 byte for a char!)
612 bytes_read, // How many bytes to print?
613 UINT32_MAX, // num per line
614 LLDB_INVALID_ADDRESS,// base address
615 0, // bitfield bit size
616 0); // bitfield bit offset
Greg Clayton5707d222011-07-09 17:17:07 +0000617 if (capped_data)
618 sstr << "...";
Jim Ingham6035b672011-03-31 00:19:25 +0000619 sstr << '"';
Greg Clayton737b9322010-09-13 03:32:57 +0000620 }
621 }
Jim Ingham6035b672011-03-31 00:19:25 +0000622 else
623 {
624 const size_t k_max_buf_size = 256;
625 data_buffer.resize (k_max_buf_size + 1);
626 // NULL terminate in case we don't get the entire C string
627 data_buffer.back() = '\0';
Greg Clayton737b9322010-09-13 03:32:57 +0000628
Jim Ingham6035b672011-03-31 00:19:25 +0000629 sstr << '"';
630
631 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
632 while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0)
633 {
634 size_t len = strlen(&data_buffer.front());
635 if (len == 0)
636 break;
637 if (len > bytes_read)
638 len = bytes_read;
639
640 data.Dump (&sstr,
641 0, // Start offset in "data"
Greg Clayton4e4294b2011-06-17 23:50:44 +0000642 eFormatCharArray, // Print as characters
Jim Ingham6035b672011-03-31 00:19:25 +0000643 1, // Size of item (1 byte for a char!)
644 len, // How many bytes to print?
645 UINT32_MAX, // num per line
646 LLDB_INVALID_ADDRESS,// base address
647 0, // bitfield bit size
648 0); // bitfield bit offset
649
650 if (len < k_max_buf_size)
651 break;
652 cstr_address += k_max_buf_size;
653 }
654 sstr << '"';
655 }
656 }
Greg Clayton737b9322010-09-13 03:32:57 +0000657 }
Jim Ingham6035b672011-03-31 00:19:25 +0000658
659 if (sstr.GetSize() > 0)
660 m_summary_str.assign (sstr.GetData(), sstr.GetSize());
Greg Clayton737b9322010-09-13 03:32:57 +0000661 }
Jim Ingham6035b672011-03-31 00:19:25 +0000662 else if (ClangASTContext::IsFunctionPointerType (clang_type))
Greg Clayton737b9322010-09-13 03:32:57 +0000663 {
Jim Ingham6035b672011-03-31 00:19:25 +0000664 AddressType func_ptr_address_type = eAddressTypeInvalid;
665 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
666
667 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
668 {
669 switch (func_ptr_address_type)
670 {
671 case eAddressTypeInvalid:
672 case eAddressTypeFile:
673 break;
674
675 case eAddressTypeLoad:
676 {
677 Address so_addr;
678 Target *target = exe_scope->CalculateTarget();
679 if (target && target->GetSectionLoadList().IsEmpty() == false)
680 {
681 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
682 {
683 so_addr.Dump (&sstr,
684 exe_scope,
685 Address::DumpStyleResolvedDescription,
686 Address::DumpStyleSectionNameOffset);
687 }
688 }
689 }
690 break;
691
692 case eAddressTypeHost:
693 break;
694 }
695 }
696 if (sstr.GetSize() > 0)
697 {
698 m_summary_str.assign (1, '(');
699 m_summary_str.append (sstr.GetData(), sstr.GetSize());
700 m_summary_str.append (1, ')');
701 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000702 }
703 }
704 }
705 }
706 }
707 if (m_summary_str.empty())
708 return NULL;
709 return m_summary_str.c_str();
710}
711
Jim Ingham53c47f12010-09-10 23:12:17 +0000712const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000713ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000714{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000715
Jim Ingham6035b672011-03-31 00:19:25 +0000716 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000717 return NULL;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000718
719 if (!m_object_desc_str.empty())
720 return m_object_desc_str.c_str();
721
Jim Ingham6035b672011-03-31 00:19:25 +0000722 ExecutionContextScope *exe_scope = GetExecutionContextScope();
723 if (exe_scope == NULL)
724 return NULL;
725
Jim Ingham53c47f12010-09-10 23:12:17 +0000726 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000727 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000728 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000729
Jim Ingham53c47f12010-09-10 23:12:17 +0000730 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000731
732 lldb::LanguageType language = GetObjectRuntimeLanguage();
733 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
734
Jim Inghama2cf2632010-12-23 02:29:54 +0000735 if (runtime == NULL)
736 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000737 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000738 clang_type_t opaque_qual_type = GetClangType();
739 if (opaque_qual_type != NULL)
740 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000741 bool is_signed;
742 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
743 || ClangASTContext::IsPointerType (opaque_qual_type))
744 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000745 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000746 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000747 }
748 }
749
Jim Ingham8d543de2011-03-31 23:01:21 +0000750 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000751 {
752 m_object_desc_str.append (s.GetData());
753 }
Sean Callanan672ad942010-10-23 00:18:49 +0000754
755 if (m_object_desc_str.empty())
756 return NULL;
757 else
758 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000759}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000760
761const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000762ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000763{
764 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000765 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000766 {
Jim Ingham6035b672011-03-31 00:19:25 +0000767 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000768 {
769 if (m_value_str.empty())
770 {
771 const Value::ContextType context_type = m_value.GetContextType();
772
773 switch (context_type)
774 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000775 case Value::eContextTypeClangType:
776 case Value::eContextTypeLLDBType:
777 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000778 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000779 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000780 if (clang_type)
781 {
782 StreamString sstr;
Greg Clayton68ebae62011-04-28 20:55:26 +0000783 Format format = GetFormat();
Enrico Granata4becb372011-06-29 22:27:15 +0000784 if (format == eFormatDefault)
785 {
786 if (m_last_value_format)
787 format = m_last_value_format->m_format;
788 else
Enrico Granata9fc19442011-07-06 02:13:41 +0000789 // force the system into using unsigned integers for bitfields
790 format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
791 ClangASTType::GetFormat(clang_type));
Enrico Granata4becb372011-06-29 22:27:15 +0000792 }
Greg Clayton32c40852010-10-06 03:09:11 +0000793
794 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
795 clang_type, // The clang type to display
796 &sstr,
Enrico Granata4becb372011-06-29 22:27:15 +0000797 format, // Format to display this type with
Greg Clayton32c40852010-10-06 03:09:11 +0000798 m_data, // Data to extract from
799 0, // Byte offset into "m_data"
800 GetByteSize(), // Byte size of item in "m_data"
801 GetBitfieldBitSize(), // Bitfield bit size
802 GetBitfieldBitOffset())) // Bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000803 m_value_str.swap(sstr.GetString());
804 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000805 {
806 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
807 m_data.GetByteSize(),
808 GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000809 m_value_str.clear();
Greg Clayton007d5be2011-05-30 00:49:24 +0000810 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000811 }
812 }
813 break;
814
Greg Clayton526e5af2010-11-13 03:52:47 +0000815 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000816 {
817 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
818 if (reg_info)
819 {
820 StreamString reg_sstr;
821 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
822 m_value_str.swap(reg_sstr.GetString());
823 }
824 }
825 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000826
827 default:
828 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829 }
830 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000831
832 if (!m_value_did_change && m_old_value_valid)
833 {
834 // The value was gotten successfully, so we consider the
835 // value as changed if the value string differs
836 SetValueDidChange (m_old_value_str != m_value_str);
837 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000838 }
839 }
840 if (m_value_str.empty())
841 return NULL;
842 return m_value_str.c_str();
843}
844
Enrico Granata0a3958e2011-07-02 00:25:22 +0000845const char *
846ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
847 lldb::Format custom_format)
848{
849 if(custom_format != lldb::eFormatInvalid)
850 SetFormat(custom_format);
851
852 const char * return_value;
853
854 switch(val_obj_display)
855 {
856 case eDisplayValue:
857 return_value = GetValueAsCString();
858 break;
859 case eDisplaySummary:
860 return_value = GetSummaryAsCString();
861 break;
862 case eDisplayLanguageSpecific:
863 return_value = GetObjectDescription();
864 break;
865 }
866
Enrico Granata9fc19442011-07-06 02:13:41 +0000867 if (!return_value)
868 {
869 // try to pick the other choice
870 if (val_obj_display == eDisplayValue)
871 return_value = GetSummaryAsCString();
872 else if (val_obj_display == eDisplaySummary)
873 return_value = GetValueAsCString();
874 else
875 return_value = "";
876 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000877
Enrico Granata9fc19442011-07-06 02:13:41 +0000878 return (return_value ? return_value : "");
Enrico Granata0a3958e2011-07-02 00:25:22 +0000879
880}
881
Enrico Granata9fc19442011-07-06 02:13:41 +0000882bool
883ValueObject::DumpPrintableRepresentation(Stream& s,
884 ValueObjectRepresentationStyle val_obj_display,
885 lldb::Format custom_format)
886{
887 const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
888 if(targetvalue)
889 s.PutCString(targetvalue);
890 bool var_success = (targetvalue != NULL);
891 if(custom_format != eFormatInvalid)
892 SetFormat(eFormatDefault);
893 return var_success;
894}
895
Greg Clayton737b9322010-09-13 03:32:57 +0000896addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000897ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +0000898{
Jim Ingham78a685a2011-04-16 00:01:13 +0000899 if (!UpdateValueIfNeeded())
900 return LLDB_INVALID_ADDRESS;
901
Greg Clayton73b472d2010-10-27 03:32:59 +0000902 switch (m_value.GetValueType())
903 {
904 case Value::eValueTypeScalar:
905 if (scalar_is_load_address)
906 {
907 address_type = eAddressTypeLoad;
908 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
909 }
910 break;
911
912 case Value::eValueTypeLoadAddress:
913 case Value::eValueTypeFileAddress:
914 case Value::eValueTypeHostAddress:
915 {
916 address_type = m_value.GetValueAddressType ();
917 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
918 }
919 break;
920 }
921 address_type = eAddressTypeInvalid;
922 return LLDB_INVALID_ADDRESS;
923}
924
925addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000926ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +0000927{
928 lldb::addr_t address = LLDB_INVALID_ADDRESS;
929 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +0000930
931 if (!UpdateValueIfNeeded())
932 return address;
933
Greg Clayton73b472d2010-10-27 03:32:59 +0000934 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +0000935 {
936 case Value::eValueTypeScalar:
937 if (scalar_is_load_address)
938 {
939 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
940 address_type = eAddressTypeLoad;
941 }
942 break;
943
944 case Value::eValueTypeLoadAddress:
945 case Value::eValueTypeFileAddress:
946 case Value::eValueTypeHostAddress:
947 {
948 uint32_t data_offset = 0;
949 address = m_data.GetPointer(&data_offset);
950 address_type = m_value.GetValueAddressType();
951 if (address_type == eAddressTypeInvalid)
952 address_type = eAddressTypeLoad;
953 }
954 break;
955 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000956
957 if (m_pointers_point_to_load_addrs)
958 address_type = eAddressTypeLoad;
959
Greg Clayton737b9322010-09-13 03:32:57 +0000960 return address;
961}
962
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000963bool
Jim Ingham6035b672011-03-31 00:19:25 +0000964ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000965{
966 // Make sure our value is up to date first so that our location and location
967 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +0000968 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000969 return false;
970
971 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +0000972 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000973
974 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +0000975 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000976 switch (encoding)
977 {
978 case eEncodingInvalid:
979 return false;
980
981 case eEncodingUint:
982 if (byte_size > sizeof(unsigned long long))
983 {
984 return false;
985 }
986 else
987 {
988 unsigned long long ull_val = strtoull(value_str, &end, 0);
989 if (end && *end != '\0')
990 return false;
Greg Clayton644247c2011-07-07 01:59:51 +0000991 m_value.GetScalar() = ull_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000992 // Limit the bytes in our m_data appropriately.
993 m_value.GetScalar().GetData (m_data, byte_size);
994 }
995 break;
996
997 case eEncodingSint:
998 if (byte_size > sizeof(long long))
999 {
1000 return false;
1001 }
1002 else
1003 {
1004 long long sll_val = strtoll(value_str, &end, 0);
1005 if (end && *end != '\0')
1006 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001007 m_value.GetScalar() = sll_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001008 // Limit the bytes in our m_data appropriately.
1009 m_value.GetScalar().GetData (m_data, byte_size);
1010 }
1011 break;
1012
1013 case eEncodingIEEE754:
1014 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +00001016 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017 if (dst != NULL)
1018 {
1019 // We are decoding a float into host byte order below, so make
1020 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +00001021 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001022 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
1023 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +00001024 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001025 value_str,
1026 dst,
1027 byte_size);
1028
1029 if (converted_byte_size == byte_size)
1030 {
1031 }
1032 }
1033 }
1034 break;
1035
1036 case eEncodingVector:
1037 return false;
1038
1039 default:
1040 return false;
1041 }
1042
1043 // If we have made it here the value is in m_data and we should write it
1044 // out to the target
1045 return Write ();
1046}
1047
1048bool
1049ValueObject::Write ()
1050{
1051 // Clear the update ID so the next time we try and read the value
1052 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +00001053 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054
1055 // TODO: when Value has a method to write a value back, call it from here.
1056 return false;
1057
1058}
1059
Jim Ingham5a369122010-09-28 01:25:32 +00001060lldb::LanguageType
1061ValueObject::GetObjectRuntimeLanguage ()
1062{
Greg Clayton73b472d2010-10-27 03:32:59 +00001063 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +00001064 if (opaque_qual_type == NULL)
1065 return lldb::eLanguageTypeC;
1066
1067 // If the type is a reference, then resolve it to what it refers to first:
1068 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
1069 if (qual_type->isAnyPointerType())
1070 {
1071 if (qual_type->isObjCObjectPointerType())
1072 return lldb::eLanguageTypeObjC;
1073
1074 clang::QualType pointee_type (qual_type->getPointeeType());
1075 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
1076 return lldb::eLanguageTypeC_plus_plus;
1077 if (pointee_type->isObjCObjectOrInterfaceType())
1078 return lldb::eLanguageTypeObjC;
1079 if (pointee_type->isObjCClassType())
1080 return lldb::eLanguageTypeObjC;
1081 }
1082 else
1083 {
1084 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
1085 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +00001086 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +00001087 return lldb::eLanguageTypeC_plus_plus;
1088 }
1089
1090 return lldb::eLanguageTypeC;
1091}
1092
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093void
Jim Ingham58b59f92011-04-22 23:53:53 +00001094ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001095{
Jim Ingham58b59f92011-04-22 23:53:53 +00001096 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097}
1098
1099ValueObjectSP
1100ValueObject::GetSyntheticChild (const ConstString &key) const
1101{
1102 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +00001103 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001104 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +00001105 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106 return synthetic_child_sp;
1107}
1108
1109bool
1110ValueObject::IsPointerType ()
1111{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001112 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001113}
1114
Jim Inghamb7603bb2011-03-18 00:05:18 +00001115bool
Greg Claytondaf515f2011-07-09 20:12:33 +00001116ValueObject::IsArrayType ()
1117{
1118 return ClangASTContext::IsArrayType (GetClangType());
1119}
1120
1121bool
Enrico Granata9fc19442011-07-06 02:13:41 +00001122ValueObject::IsScalarType ()
1123{
1124 return ClangASTContext::IsScalarType (GetClangType());
1125}
1126
1127bool
Jim Inghamb7603bb2011-03-18 00:05:18 +00001128ValueObject::IsIntegerType (bool &is_signed)
1129{
1130 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
1131}
Greg Clayton73b472d2010-10-27 03:32:59 +00001132
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133bool
1134ValueObject::IsPointerOrReferenceType ()
1135{
Greg Clayton007d5be2011-05-30 00:49:24 +00001136 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
1137}
1138
1139bool
1140ValueObject::IsPossibleCPlusPlusDynamicType ()
1141{
1142 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001143}
1144
Greg Claytondea8cb42011-06-29 22:09:02 +00001145bool
1146ValueObject::IsPossibleDynamicType ()
1147{
1148 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
1149}
1150
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001151ValueObjectSP
1152ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
1153{
1154 ValueObjectSP synthetic_child_sp;
1155 if (IsPointerType ())
1156 {
1157 char index_str[64];
1158 snprintf(index_str, sizeof(index_str), "[%i]", index);
1159 ConstString index_const_str(index_str);
1160 // Check if we have already created a synthetic array member in this
1161 // valid object. If we have we will re-use it.
1162 synthetic_child_sp = GetSyntheticChild (index_const_str);
1163 if (!synthetic_child_sp)
1164 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001165 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001166 // We haven't made a synthetic array member for INDEX yet, so
1167 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001168 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001169
1170 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001171 if (synthetic_child)
1172 {
1173 AddSyntheticChild(index_const_str, synthetic_child);
1174 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata0a3958e2011-07-02 00:25:22 +00001175 synthetic_child_sp->SetName(index_str);
1176 synthetic_child_sp->m_is_array_item_for_pointer = true;
Jim Ingham58b59f92011-04-22 23:53:53 +00001177 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001178 }
1179 }
1180 return synthetic_child_sp;
1181}
Jim Ingham22777012010-09-23 02:01:19 +00001182
Greg Claytondaf515f2011-07-09 20:12:33 +00001183// This allows you to create an array member using and index
1184// that doesn't not fall in the normal bounds of the array.
1185// Many times structure can be defined as:
1186// struct Collection
1187// {
1188// uint32_t item_count;
1189// Item item_array[0];
1190// };
1191// The size of the "item_array" is 1, but many times in practice
1192// there are more items in "item_array".
1193
1194ValueObjectSP
1195ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create)
1196{
1197 ValueObjectSP synthetic_child_sp;
1198 if (IsArrayType ())
1199 {
1200 char index_str[64];
1201 snprintf(index_str, sizeof(index_str), "[%i]", index);
1202 ConstString index_const_str(index_str);
1203 // Check if we have already created a synthetic array member in this
1204 // valid object. If we have we will re-use it.
1205 synthetic_child_sp = GetSyntheticChild (index_const_str);
1206 if (!synthetic_child_sp)
1207 {
1208 ValueObject *synthetic_child;
1209 // We haven't made a synthetic array member for INDEX yet, so
1210 // lets make one and cache it for any future reference.
1211 synthetic_child = CreateChildAtIndex(0, true, index);
1212
1213 // Cache the value if we got one back...
1214 if (synthetic_child)
1215 {
1216 AddSyntheticChild(index_const_str, synthetic_child);
1217 synthetic_child_sp = synthetic_child->GetSP();
1218 synthetic_child_sp->SetName(index_str);
1219 synthetic_child_sp->m_is_array_item_for_pointer = true;
1220 }
1221 }
1222 }
1223 return synthetic_child_sp;
1224}
1225
Enrico Granata9fc19442011-07-06 02:13:41 +00001226ValueObjectSP
1227ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
1228{
1229 ValueObjectSP synthetic_child_sp;
1230 if (IsScalarType ())
1231 {
1232 char index_str[64];
1233 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1234 ConstString index_const_str(index_str);
1235 // Check if we have already created a synthetic array member in this
1236 // valid object. If we have we will re-use it.
1237 synthetic_child_sp = GetSyntheticChild (index_const_str);
1238 if (!synthetic_child_sp)
1239 {
1240 ValueObjectChild *synthetic_child;
1241 // We haven't made a synthetic array member for INDEX yet, so
1242 // lets make one and cache it for any future reference.
1243 synthetic_child = new ValueObjectChild(*this,
1244 GetClangAST(),
1245 GetClangType(),
1246 index_const_str,
1247 GetByteSize(),
1248 0,
1249 to-from+1,
1250 from,
1251 false,
1252 false);
1253
1254 // Cache the value if we got one back...
1255 if (synthetic_child)
1256 {
1257 AddSyntheticChild(index_const_str, synthetic_child);
1258 synthetic_child_sp = synthetic_child->GetSP();
1259 synthetic_child_sp->SetName(index_str);
1260 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1261 }
1262 }
1263 }
1264 return synthetic_child_sp;
1265}
1266
Jim Ingham78a685a2011-04-16 00:01:13 +00001267void
Jim Ingham2837b762011-05-04 03:43:18 +00001268ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001269{
Jim Ingham2837b762011-05-04 03:43:18 +00001270 if (use_dynamic == lldb::eNoDynamicValues)
1271 return;
1272
Jim Ingham58b59f92011-04-22 23:53:53 +00001273 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001274 {
1275 Process *process = m_update_point.GetProcess();
1276 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001277
Jim Ingham78a685a2011-04-16 00:01:13 +00001278
1279 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1280 // hard code this everywhere.
1281 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1282 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1283 {
1284 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1285 if (runtime)
1286 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1287 }
1288 else
1289 {
1290 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1291 if (cpp_runtime)
1292 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1293
1294 if (!worth_having_dynamic_value)
1295 {
1296 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1297 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001298 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001299 }
1300 }
1301
1302 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001303 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001304
1305// if (worth_having_dynamic_value)
1306// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1307
Jim Ingham78a685a2011-04-16 00:01:13 +00001308 }
1309}
1310
Jim Ingham58b59f92011-04-22 23:53:53 +00001311ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001312ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001313{
Jim Ingham2837b762011-05-04 03:43:18 +00001314 if (use_dynamic == lldb::eNoDynamicValues)
1315 return ValueObjectSP();
1316
1317 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001318 {
Jim Ingham2837b762011-05-04 03:43:18 +00001319 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001320 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001321 if (m_dynamic_value)
1322 return m_dynamic_value->GetSP();
1323 else
1324 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001325}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001326
Greg Claytone221f822011-01-21 01:59:00 +00001327bool
1328ValueObject::GetBaseClassPath (Stream &s)
1329{
1330 if (IsBaseClass())
1331 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001332 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001333 clang_type_t clang_type = GetClangType();
1334 std::string cxx_class_name;
1335 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1336 if (this_had_base_class)
1337 {
1338 if (parent_had_base_class)
1339 s.PutCString("::");
1340 s.PutCString(cxx_class_name.c_str());
1341 }
1342 return parent_had_base_class || this_had_base_class;
1343 }
1344 return false;
1345}
1346
1347
1348ValueObject *
1349ValueObject::GetNonBaseClassParent()
1350{
Jim Ingham78a685a2011-04-16 00:01:13 +00001351 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001352 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001353 if (GetParent()->IsBaseClass())
1354 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001355 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001356 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001357 }
1358 return NULL;
1359}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001360
1361void
Enrico Granata4becb372011-06-29 22:27:15 +00001362ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001363{
Greg Claytone221f822011-01-21 01:59:00 +00001364 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00001365
Enrico Granata4becb372011-06-29 22:27:15 +00001366 if(is_deref_of_parent && epformat == eDereferencePointers) {
1367 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
1368 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
1369 // the eHonorPointers mode is meant to produce strings in this latter format
1370 s.PutCString("*(");
1371 }
Greg Claytone221f822011-01-21 01:59:00 +00001372
Enrico Granata4becb372011-06-29 22:27:15 +00001373 ValueObject* parent = GetParent();
1374
1375 if (parent)
1376 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
Enrico Granata0a3958e2011-07-02 00:25:22 +00001377
1378 // if we are a deref_of_parent just because we are synthetic array
1379 // members made up to allow ptr[%d] syntax to work in variable
1380 // printing, then add our name ([%d]) to the expression path
1381 if(m_is_array_item_for_pointer && epformat == eHonorPointers)
1382 s.PutCString(m_name.AsCString());
Enrico Granata4becb372011-06-29 22:27:15 +00001383
Greg Claytone221f822011-01-21 01:59:00 +00001384 if (!IsBaseClass())
1385 {
1386 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001387 {
Greg Claytone221f822011-01-21 01:59:00 +00001388 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1389 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001390 {
Greg Claytone221f822011-01-21 01:59:00 +00001391 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1392 if (non_base_class_parent_clang_type)
1393 {
1394 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1395
Enrico Granata4becb372011-06-29 22:27:15 +00001396 if(parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00001397 {
1398 s.PutCString("->");
1399 }
Enrico Granata4becb372011-06-29 22:27:15 +00001400 else
1401 {
1402 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1403 {
1404 s.PutCString("->");
1405 }
1406 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1407 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1408 {
1409 s.PutChar('.');
1410 }
Greg Claytone221f822011-01-21 01:59:00 +00001411 }
1412 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001413 }
Greg Claytone221f822011-01-21 01:59:00 +00001414
1415 const char *name = GetName().GetCString();
1416 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001417 {
Greg Claytone221f822011-01-21 01:59:00 +00001418 if (qualify_cxx_base_classes)
1419 {
1420 if (GetBaseClassPath (s))
1421 s.PutCString("::");
1422 }
1423 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001424 }
1425 }
1426 }
1427
Enrico Granata4becb372011-06-29 22:27:15 +00001428 if (is_deref_of_parent && epformat == eDereferencePointers) {
Greg Claytone221f822011-01-21 01:59:00 +00001429 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00001430 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001431}
1432
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001433lldb::ValueObjectSP
1434ValueObject::GetValueForExpressionPath(const char* expression,
1435 const char** first_unparsed,
1436 ExpressionPathScanEndReason* reason_to_stop,
1437 ExpressionPathEndResultType* final_value_type,
1438 const GetValueForExpressionPathOptions& options,
1439 ExpressionPathAftermath* final_task_on_target)
1440{
1441
1442 const char* dummy_first_unparsed;
1443 ExpressionPathScanEndReason dummy_reason_to_stop;
1444 ExpressionPathEndResultType dummy_final_value_type;
1445 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1446
1447 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1448 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1449 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1450 final_value_type ? final_value_type : &dummy_final_value_type,
1451 options,
1452 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1453
1454 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1455 {
1456 return ret_val;
1457 }
1458 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1459 {
1460 if (*final_task_on_target == ValueObject::eDereference)
1461 {
1462 Error error;
1463 ValueObjectSP final_value = ret_val->Dereference(error);
1464 if (error.Fail() || !final_value.get())
1465 {
1466 *reason_to_stop = ValueObject::eDereferencingFailed;
1467 *final_value_type = ValueObject::eInvalid;
1468 return ValueObjectSP();
1469 }
1470 else
1471 {
1472 *final_task_on_target = ValueObject::eNothing;
1473 return final_value;
1474 }
1475 }
1476 if (*final_task_on_target == ValueObject::eTakeAddress)
1477 {
1478 Error error;
1479 ValueObjectSP final_value = ret_val->AddressOf(error);
1480 if (error.Fail() || !final_value.get())
1481 {
1482 *reason_to_stop = ValueObject::eTakingAddressFailed;
1483 *final_value_type = ValueObject::eInvalid;
1484 return ValueObjectSP();
1485 }
1486 else
1487 {
1488 *final_task_on_target = ValueObject::eNothing;
1489 return final_value;
1490 }
1491 }
1492 }
1493 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
1494}
1495
1496lldb::ValueObjectSP
1497ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
1498 const char** first_unparsed,
1499 ExpressionPathScanEndReason* reason_to_stop,
1500 ExpressionPathEndResultType* final_result,
1501 const GetValueForExpressionPathOptions& options,
1502 ExpressionPathAftermath* what_next)
1503{
1504 ValueObjectSP root = GetSP();
1505
1506 if (!root.get())
1507 return ValueObjectSP();
1508
1509 *first_unparsed = expression_cstr;
1510
1511 while (true)
1512 {
1513
1514 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
1515
1516 lldb::clang_type_t root_clang_type = root->GetClangType();
1517
1518 if (!expression_cstr || *expression_cstr == '\0')
1519 {
1520 *reason_to_stop = ValueObject::eEndOfString;
1521 return root;
1522 }
1523
1524 switch (*expression_cstr)
1525 {
1526 case '-':
1527 {
1528 if (options.m_check_dot_vs_arrow_syntax &&
1529 !ClangASTContext::IsPointerType(root_clang_type)) // if you are trying to use -> on a non-pointer and I must catch the error
1530 {
1531 *first_unparsed = expression_cstr;
1532 *reason_to_stop = ValueObject::eArrowInsteadOfDot;
1533 *final_result = ValueObject::eInvalid;
1534 return ValueObjectSP();
1535 }
1536 const uint32_t pointer_type_flags = ClangASTContext::GetTypeInfo (root_clang_type, NULL, NULL);
1537 if ((pointer_type_flags & ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
1538 (pointer_type_flags & ClangASTContext::eTypeIsPointer) &&
1539 options.m_no_fragile_ivar)
1540 {
1541 *first_unparsed = expression_cstr;
1542 *reason_to_stop = ValueObject::eFragileIVarNotAllowed;
1543 *final_result = ValueObject::eInvalid;
1544 return ValueObjectSP();
1545 }
1546 if (expression_cstr[1] != '>')
1547 {
1548 *first_unparsed = expression_cstr;
1549 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1550 *final_result = ValueObject::eInvalid;
1551 return ValueObjectSP();
1552 }
1553 expression_cstr++; // skip the -
1554 }
1555 case '.': // or fallthrough from ->
1556 {
1557 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
1558 ClangASTContext::IsPointerType(root_clang_type)) // if you are trying to use . on a pointer and I must catch the error
1559 {
1560 *first_unparsed = expression_cstr;
1561 *reason_to_stop = ValueObject::eDotInsteadOfArrow;
1562 *final_result = ValueObject::eInvalid;
1563 return ValueObjectSP();
1564 }
1565 expression_cstr++; // skip .
1566 const char *next_separator = strpbrk(expression_cstr+1,"-.[");
1567 ConstString child_name;
1568 if (!next_separator) // if no other separator just expand this last layer
1569 {
1570 child_name.SetCString (expression_cstr);
1571 root = root->GetChildMemberWithName(child_name, true);
1572 if (root.get()) // we know we are done, so just return
1573 {
1574 *first_unparsed = '\0';
1575 *reason_to_stop = ValueObject::eEndOfString;
1576 *final_result = ValueObject::ePlain;
1577 return root;
1578 }
1579 else
1580 {
1581 *first_unparsed = expression_cstr;
1582 *reason_to_stop = ValueObject::eNoSuchChild;
1583 *final_result = ValueObject::eInvalid;
1584 return ValueObjectSP();
1585 }
1586 }
1587 else // other layers do expand
1588 {
1589 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
1590 root = root->GetChildMemberWithName(child_name, true);
1591 if (root.get()) // store the new root and move on
1592 {
1593 *first_unparsed = next_separator;
1594 *final_result = ValueObject::ePlain;
1595 continue;
1596 }
1597 else
1598 {
1599 *first_unparsed = expression_cstr;
1600 *reason_to_stop = ValueObject::eNoSuchChild;
1601 *final_result = ValueObject::eInvalid;
1602 return ValueObjectSP();
1603 }
1604 }
1605 break;
1606 }
1607 case '[':
1608 {
1609 if (!ClangASTContext::IsArrayType(root_clang_type) && !ClangASTContext::IsPointerType(root_clang_type)) // if this is not a T[] nor a T*
1610 {
1611 if (!ClangASTContext::IsScalarType(root_clang_type)) // if this is not even a scalar, this syntax is just plain wrong!
1612 {
1613 *first_unparsed = expression_cstr;
1614 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
1615 *final_result = ValueObject::eInvalid;
1616 return ValueObjectSP();
1617 }
1618 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
1619 {
1620 *first_unparsed = expression_cstr;
1621 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
1622 *final_result = ValueObject::eInvalid;
1623 return ValueObjectSP();
1624 }
1625 }
1626 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
1627 {
1628 if (!ClangASTContext::IsArrayType(root_clang_type))
1629 {
1630 *first_unparsed = expression_cstr;
1631 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
1632 *final_result = ValueObject::eInvalid;
1633 return ValueObjectSP();
1634 }
1635 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
1636 {
1637 *first_unparsed = expression_cstr+2;
1638 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
1639 *final_result = ValueObject::eUnboundedRange;
1640 return root;
1641 }
1642 }
1643 const char *separator_position = ::strchr(expression_cstr+1,'-');
1644 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
1645 if (!close_bracket_position) // if there is no ], this is a syntax error
1646 {
1647 *first_unparsed = expression_cstr;
1648 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1649 *final_result = ValueObject::eInvalid;
1650 return ValueObjectSP();
1651 }
1652 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
1653 {
1654 char *end = NULL;
1655 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
1656 if (!end || end != close_bracket_position) // if something weird is in our way return an error
1657 {
1658 *first_unparsed = expression_cstr;
1659 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1660 *final_result = ValueObject::eInvalid;
1661 return ValueObjectSP();
1662 }
1663 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
1664 {
1665 if (ClangASTContext::IsArrayType(root_clang_type))
1666 {
1667 *first_unparsed = expression_cstr+2;
1668 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
1669 *final_result = ValueObject::eUnboundedRange;
1670 return root;
1671 }
1672 else
1673 {
1674 *first_unparsed = expression_cstr;
1675 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
1676 *final_result = ValueObject::eInvalid;
1677 return ValueObjectSP();
1678 }
1679 }
1680 // from here on we do have a valid index
1681 if (ClangASTContext::IsArrayType(root_clang_type))
1682 {
Greg Claytondaf515f2011-07-09 20:12:33 +00001683 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
1684 if (!child_valobj_sp)
1685 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
1686 if (child_valobj_sp)
1687 {
1688 root = child_valobj_sp;
1689 *first_unparsed = end+1; // skip ]
1690 *final_result = ValueObject::ePlain;
1691 continue;
1692 }
1693 else
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001694 {
1695 *first_unparsed = expression_cstr;
1696 *reason_to_stop = ValueObject::eNoSuchChild;
1697 *final_result = ValueObject::eInvalid;
1698 return ValueObjectSP();
1699 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001700 }
1701 else if (ClangASTContext::IsPointerType(root_clang_type))
1702 {
1703 if (*what_next == ValueObject::eDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
1704 ClangASTContext::IsScalarType(clang::QualType::getFromOpaquePtr(root_clang_type).getTypePtr()->getPointeeType().getAsOpaquePtr()))
1705 {
1706 Error error;
1707 root = root->Dereference(error);
1708 if (error.Fail() || !root.get())
1709 {
1710 *first_unparsed = expression_cstr;
1711 *reason_to_stop = ValueObject::eDereferencingFailed;
1712 *final_result = ValueObject::eInvalid;
1713 return ValueObjectSP();
1714 }
1715 else
1716 {
1717 *what_next = eNothing;
1718 continue;
1719 }
1720 }
1721 else
1722 {
1723 root = root->GetSyntheticArrayMemberFromPointer(index, true);
1724 if (!root.get())
1725 {
1726 *first_unparsed = expression_cstr;
1727 *reason_to_stop = ValueObject::eNoSuchChild;
1728 *final_result = ValueObject::eInvalid;
1729 return ValueObjectSP();
1730 }
1731 else
1732 {
1733 *first_unparsed = end+1; // skip ]
1734 *final_result = ValueObject::ePlain;
1735 continue;
1736 }
1737 }
1738 }
1739 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
1740 {
1741 root = root->GetSyntheticBitFieldChild(index, index, true);
1742 if (!root.get())
1743 {
1744 *first_unparsed = expression_cstr;
1745 *reason_to_stop = ValueObject::eNoSuchChild;
1746 *final_result = ValueObject::eInvalid;
1747 return ValueObjectSP();
1748 }
1749 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
1750 {
1751 *first_unparsed = end+1; // skip ]
1752 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
1753 *final_result = ValueObject::eBitfield;
1754 return root;
1755 }
1756 }
1757 }
1758 else // we have a low and a high index
1759 {
1760 char *end = NULL;
1761 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
1762 if (!end || end != separator_position) // if something weird is in our way return an error
1763 {
1764 *first_unparsed = expression_cstr;
1765 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1766 *final_result = ValueObject::eInvalid;
1767 return ValueObjectSP();
1768 }
1769 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
1770 if (!end || end != close_bracket_position) // if something weird is in our way return an error
1771 {
1772 *first_unparsed = expression_cstr;
1773 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1774 *final_result = ValueObject::eInvalid;
1775 return ValueObjectSP();
1776 }
1777 if (index_lower > index_higher) // swap indices if required
1778 {
1779 unsigned long temp = index_lower;
1780 index_lower = index_higher;
1781 index_higher = temp;
1782 }
1783 if (ClangASTContext::IsScalarType(root_clang_type)) // expansion only works for scalars
1784 {
1785 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
1786 if (!root.get())
1787 {
1788 *first_unparsed = expression_cstr;
1789 *reason_to_stop = ValueObject::eNoSuchChild;
1790 *final_result = ValueObject::eInvalid;
1791 return ValueObjectSP();
1792 }
1793 else
1794 {
1795 *first_unparsed = end+1; // skip ]
1796 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
1797 *final_result = ValueObject::eBitfield;
1798 return root;
1799 }
1800 }
1801 else if (ClangASTContext::IsPointerType(root_clang_type) && // 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
1802 *what_next == ValueObject::eDereference &&
1803 ClangASTContext::IsScalarType(clang::QualType::getFromOpaquePtr(root_clang_type).getTypePtr()->getPointeeType().getAsOpaquePtr()))
1804 {
1805 Error error;
1806 root = root->Dereference(error);
1807 if (error.Fail() || !root.get())
1808 {
1809 *first_unparsed = expression_cstr;
1810 *reason_to_stop = ValueObject::eDereferencingFailed;
1811 *final_result = ValueObject::eInvalid;
1812 return ValueObjectSP();
1813 }
1814 else
1815 {
1816 *what_next = ValueObject::eNothing;
1817 continue;
1818 }
1819 }
1820 else
1821 {
1822 *first_unparsed = expression_cstr;
1823 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
1824 *final_result = ValueObject::eBoundedRange;
1825 return root;
1826 }
1827 }
1828 break;
1829 }
1830 default: // some non-separator is in the way
1831 {
1832 *first_unparsed = expression_cstr;
1833 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1834 *final_result = ValueObject::eInvalid;
1835 return ValueObjectSP();
1836 break;
1837 }
1838 }
1839 }
1840}
1841
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001842void
Greg Clayton1d3afba2010-10-05 00:00:42 +00001843ValueObject::DumpValueObject
1844(
1845 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00001846 ValueObject *valobj,
1847 const char *root_valobj_name,
1848 uint32_t ptr_depth,
1849 uint32_t curr_depth,
1850 uint32_t max_depth,
1851 bool show_types,
1852 bool show_location,
1853 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00001854 lldb::DynamicValueType use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001855 bool scope_already_checked,
1856 bool flat_output
Greg Clayton1d3afba2010-10-05 00:00:42 +00001857)
1858{
Greg Clayton007d5be2011-05-30 00:49:24 +00001859 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001860 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001861 bool update_success = valobj->UpdateValueIfNeeded ();
1862
1863 if (update_success && use_dynamic != lldb::eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00001864 {
Jim Ingham2837b762011-05-04 03:43:18 +00001865 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00001866 if (dynamic_value)
1867 valobj = dynamic_value;
1868 }
1869
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001870 clang_type_t clang_type = valobj->GetClangType();
1871
Greg Clayton73b472d2010-10-27 03:32:59 +00001872 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001873 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00001874 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
1875 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001876
1877 const bool print_valobj = flat_output == false || has_value;
1878
1879 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001880 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001881 if (show_location)
1882 {
Jim Ingham6035b672011-03-31 00:19:25 +00001883 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001884 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001885
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001886 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001887
Greg Clayton7c8a9662010-11-02 01:50:16 +00001888 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00001889 if (show_types || (curr_depth == 0 && !flat_output))
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001890 s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
Greg Clayton1d3afba2010-10-05 00:00:42 +00001891
Greg Clayton1d3afba2010-10-05 00:00:42 +00001892
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001893 if (flat_output)
1894 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001895 // If we are showing types, also qualify the C++ base classes
1896 const bool qualify_cxx_base_classes = show_types;
1897 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001898 s.PutCString(" =");
1899 }
1900 else
1901 {
1902 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
1903 s.Printf ("%s =", name_cstr);
1904 }
1905
Jim Ingham6035b672011-03-31 00:19:25 +00001906 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001907 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001908 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001909 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001910 }
1911
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001912 const char *val_cstr = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00001913 const char *sum_cstr = NULL;
1914 SummaryFormat* entry = valobj->m_last_summary_format.get();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001915
1916 if (err_cstr == NULL)
1917 {
Jim Ingham6035b672011-03-31 00:19:25 +00001918 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001919 err_cstr = valobj->GetError().AsCString();
1920 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001921
1922 if (err_cstr)
1923 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001924 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00001925 }
1926 else
1927 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001928 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001929 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001930 {
Enrico Granata4becb372011-06-29 22:27:15 +00001931
1932 sum_cstr = valobj->GetSummaryAsCString();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001933
Enrico Granata4becb372011-06-29 22:27:15 +00001934 // We must calculate this value in realtime because entry might alter this variable's value
1935 // (e.g. by saying ${var%fmt}) and render precached values useless
1936 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
1937 s.Printf(" %s", valobj->GetValueAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001938
Enrico Granata0a3958e2011-07-02 00:25:22 +00001939 if(sum_cstr)
1940 {
1941 // for some reason, using %@ (ObjC description) in a summary string, makes
1942 // us believe we need to reset ourselves, thus invalidating the content of
1943 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty
1944 // let us recalculate it!
1945 if (sum_cstr[0] == '\0')
1946 s.Printf(" %s", valobj->GetSummaryAsCString());
1947 else
1948 s.Printf(" %s", sum_cstr);
1949 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001950
1951 if (use_objc)
1952 {
Jim Ingham6035b672011-03-31 00:19:25 +00001953 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001954 if (object_desc)
1955 s.Printf(" %s\n", object_desc);
1956 else
Sean Callanan672ad942010-10-23 00:18:49 +00001957 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001958 return;
Enrico Granata0a3958e2011-07-02 00:25:22 +00001959 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001960 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001961
1962 if (curr_depth < max_depth)
1963 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001964 // We will show children for all concrete types. We won't show
1965 // pointer contents unless a pointer depth has been specified.
1966 // We won't reference contents unless the reference is the
1967 // root object (depth of zero).
1968 bool print_children = true;
1969
1970 // Use a new temporary pointer depth in case we override the
1971 // current pointer depth below...
1972 uint32_t curr_ptr_depth = ptr_depth;
1973
1974 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
1975 if (is_ptr || is_ref)
1976 {
1977 // We have a pointer or reference whose value is an address.
1978 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00001979 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00001980 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
1981 print_children = false;
1982
1983 else if (is_ref && curr_depth == 0)
1984 {
1985 // If this is the root object (depth is zero) that we are showing
1986 // and it is a reference, and no pointer depth has been supplied
1987 // print out what it references. Don't do this at deeper depths
1988 // otherwise we can end up with infinite recursion...
1989 curr_ptr_depth = 1;
1990 }
1991
1992 if (curr_ptr_depth == 0)
1993 print_children = false;
1994 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001995
Enrico Granata0a3958e2011-07-02 00:25:22 +00001996 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00001997 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001998 const uint32_t num_children = valobj->GetNumChildren();
1999 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002000 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002001 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002002 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002003 if (print_valobj)
2004 s.EOL();
2005 }
2006 else
2007 {
2008 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00002009 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002010 s.IndentMore();
2011 }
2012
2013 for (uint32_t idx=0; idx<num_children; ++idx)
2014 {
2015 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
2016 if (child_sp.get())
2017 {
2018 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002019 child_sp.get(),
2020 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00002021 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002022 curr_depth + 1,
2023 max_depth,
2024 show_types,
2025 show_location,
2026 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00002027 use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002028 true,
2029 flat_output);
2030 }
2031 }
2032
2033 if (!flat_output)
2034 {
2035 s.IndentLess();
2036 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002037 }
2038 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002039 else if (has_children)
2040 {
2041 // Aggregate, no children...
2042 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00002043 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002044 }
2045 else
2046 {
2047 if (print_valobj)
2048 s.EOL();
2049 }
2050
Greg Clayton1d3afba2010-10-05 00:00:42 +00002051 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002052 else
2053 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00002054 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002055 }
2056 }
2057 else
2058 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002059 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002060 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002061 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002062 }
2063 }
2064 }
2065 }
2066}
2067
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002068
2069ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00002070ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002071{
2072 ValueObjectSP valobj_sp;
2073
Jim Ingham6035b672011-03-31 00:19:25 +00002074 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002075 {
Jim Ingham6035b672011-03-31 00:19:25 +00002076 ExecutionContextScope *exe_scope = GetExecutionContextScope();
2077 if (exe_scope)
2078 {
2079 ExecutionContext exe_ctx;
2080 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002081
Jim Ingham6035b672011-03-31 00:19:25 +00002082 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002083
Jim Ingham6035b672011-03-31 00:19:25 +00002084 DataExtractor data;
2085 data.SetByteOrder (m_data.GetByteOrder());
2086 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002087
Greg Clayton644247c2011-07-07 01:59:51 +00002088 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002089
Jim Ingham58b59f92011-04-22 23:53:53 +00002090 valobj_sp = ValueObjectConstResult::Create (exe_scope,
2091 ast,
2092 GetClangType(),
2093 name,
2094 data);
Jim Ingham6035b672011-03-31 00:19:25 +00002095 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002096 }
Jim Ingham6035b672011-03-31 00:19:25 +00002097
2098 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002099 {
Jim Ingham58b59f92011-04-22 23:53:53 +00002100 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002101 }
2102 return valobj_sp;
2103}
2104
2105lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00002106ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002107{
Jim Ingham58b59f92011-04-22 23:53:53 +00002108 if (m_deref_valobj)
2109 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00002110
Greg Clayton54979cd2010-12-15 05:08:08 +00002111 const bool is_pointer_type = IsPointerType();
2112 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002113 {
2114 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +00002115 bool ignore_array_bounds = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002116
2117 std::string child_name_str;
2118 uint32_t child_byte_size = 0;
2119 int32_t child_byte_offset = 0;
2120 uint32_t child_bitfield_bit_size = 0;
2121 uint32_t child_bitfield_bit_offset = 0;
2122 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00002123 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002124 const bool transparent_pointers = false;
2125 clang::ASTContext *clang_ast = GetClangAST();
2126 clang_type_t clang_type = GetClangType();
2127 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00002128
2129 ExecutionContext exe_ctx;
2130 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
2131
2132 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
2133 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002134 GetName().GetCString(),
2135 clang_type,
2136 0,
2137 transparent_pointers,
2138 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00002139 ignore_array_bounds,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002140 child_name_str,
2141 child_byte_size,
2142 child_byte_offset,
2143 child_bitfield_bit_size,
2144 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002145 child_is_base_class,
2146 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00002147 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002148 {
2149 ConstString child_name;
2150 if (!child_name_str.empty())
2151 child_name.SetCString (child_name_str.c_str());
2152
Jim Ingham58b59f92011-04-22 23:53:53 +00002153 m_deref_valobj = new ValueObjectChild (*this,
2154 clang_ast,
2155 child_clang_type,
2156 child_name,
2157 child_byte_size,
2158 child_byte_offset,
2159 child_bitfield_bit_size,
2160 child_bitfield_bit_offset,
2161 child_is_base_class,
2162 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002163 }
2164 }
Greg Clayton54979cd2010-12-15 05:08:08 +00002165
Jim Ingham58b59f92011-04-22 23:53:53 +00002166 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00002167 {
2168 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00002169 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00002170 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002171 else
2172 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002173 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002174 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002175
2176 if (is_pointer_type)
2177 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
2178 else
2179 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00002180 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002181 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002182}
2183
Jim Ingham78a685a2011-04-16 00:01:13 +00002184lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00002185ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002186{
Jim Ingham78a685a2011-04-16 00:01:13 +00002187 if (m_addr_of_valobj_sp)
2188 return m_addr_of_valobj_sp;
2189
Greg Claytone0d378b2011-03-24 21:19:54 +00002190 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002191 const bool scalar_is_load_address = false;
2192 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00002193 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002194 if (addr != LLDB_INVALID_ADDRESS)
2195 {
2196 switch (address_type)
2197 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002198 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002199 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00002200 {
2201 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002202 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002203 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
2204 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002205 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002206
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002207 case eAddressTypeFile:
2208 case eAddressTypeLoad:
2209 case eAddressTypeHost:
2210 {
2211 clang::ASTContext *ast = GetClangAST();
2212 clang_type_t clang_type = GetClangType();
2213 if (ast && clang_type)
2214 {
2215 std::string name (1, '&');
2216 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00002217 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
2218 ast,
2219 ClangASTContext::CreatePointerType (ast, clang_type),
2220 ConstString (name.c_str()),
2221 addr,
2222 eAddressTypeInvalid,
2223 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002224 }
2225 }
2226 break;
2227 }
2228 }
Jim Ingham78a685a2011-04-16 00:01:13 +00002229 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002230}
2231
Greg Claytonb2dcc362011-05-05 23:32:56 +00002232
2233lldb::ValueObjectSP
2234ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
2235{
2236 lldb::ValueObjectSP valobj_sp;
2237 AddressType address_type;
2238 const bool scalar_is_load_address = true;
2239 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2240
2241 if (ptr_value != LLDB_INVALID_ADDRESS)
2242 {
2243 Address ptr_addr (NULL, ptr_value);
2244
2245 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2246 name,
2247 ptr_addr,
2248 clang_ast_type);
2249 }
2250 return valobj_sp;
2251}
2252
2253lldb::ValueObjectSP
2254ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
2255{
2256 lldb::ValueObjectSP valobj_sp;
2257 AddressType address_type;
2258 const bool scalar_is_load_address = true;
2259 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2260
2261 if (ptr_value != LLDB_INVALID_ADDRESS)
2262 {
2263 Address ptr_addr (NULL, ptr_value);
2264
2265 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2266 name,
2267 ptr_addr,
2268 type_sp);
2269 }
2270 return valobj_sp;
2271}
2272
2273
Jim Ingham6035b672011-03-31 00:19:25 +00002274ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00002275 m_thread_id (LLDB_INVALID_UID),
2276 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00002277{
2278}
2279
2280ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00002281 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002282 m_first_update (true),
Jim Ingham89b61092011-07-06 17:42:14 +00002283 m_thread_id (LLDB_INVALID_THREAD_ID),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002284 m_stop_id (0)
2285
Jim Ingham6035b672011-03-31 00:19:25 +00002286{
2287 ExecutionContext exe_ctx;
2288 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
2289 // and if so we want to cache that not the original.
2290 if (exe_scope)
2291 exe_scope->CalculateExecutionContext(exe_ctx);
2292 if (exe_ctx.target != NULL)
2293 {
2294 m_target_sp = exe_ctx.target->GetSP();
2295
2296 if (exe_ctx.process == NULL)
2297 m_process_sp = exe_ctx.target->GetProcessSP();
2298 else
2299 m_process_sp = exe_ctx.process->GetSP();
2300
2301 if (m_process_sp != NULL)
2302 {
2303 m_stop_id = m_process_sp->GetStopID();
2304 Thread *thread = NULL;
2305
2306 if (exe_ctx.thread == NULL)
2307 {
2308 if (use_selected)
2309 {
2310 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
2311 if (thread)
2312 computed_exe_scope = thread;
2313 }
2314 }
2315 else
2316 thread = exe_ctx.thread;
2317
2318 if (thread != NULL)
2319 {
2320 m_thread_id = thread->GetIndexID();
2321 if (exe_ctx.frame == NULL)
2322 {
2323 if (use_selected)
2324 {
2325 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
2326 if (frame)
2327 {
2328 m_stack_id = frame->GetStackID();
2329 computed_exe_scope = frame;
2330 }
2331 }
2332 }
2333 else
2334 m_stack_id = exe_ctx.frame->GetStackID();
2335 }
2336 }
2337 }
2338 m_exe_scope = computed_exe_scope;
2339}
2340
2341ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
2342 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002343 m_needs_update(true),
2344 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00002345 m_target_sp (rhs.m_target_sp),
2346 m_process_sp (rhs.m_process_sp),
2347 m_thread_id (rhs.m_thread_id),
2348 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00002349 m_stop_id (0)
2350{
2351}
2352
2353ValueObject::EvaluationPoint::~EvaluationPoint ()
2354{
2355}
2356
2357ExecutionContextScope *
2358ValueObject::EvaluationPoint::GetExecutionContextScope ()
2359{
2360 // We have to update before giving out the scope, or we could be handing out stale pointers.
2361 SyncWithProcessState();
2362
2363 return m_exe_scope;
2364}
2365
2366// This function checks the EvaluationPoint against the current process state. If the current
2367// state matches the evaluation point, or the evaluation point is already invalid, then we return
2368// false, meaning "no change". If the current state is different, we update our state, and return
2369// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
2370// future calls to NeedsUpdate will return true.
2371
2372bool
2373ValueObject::EvaluationPoint::SyncWithProcessState()
2374{
2375 // If we're already invalid, we don't need to do anything, and nothing has changed:
2376 if (m_stop_id == LLDB_INVALID_UID)
2377 {
2378 // Can't update with an invalid state.
2379 m_needs_update = false;
2380 return false;
2381 }
2382
2383 // If we don't have a process nothing can change.
2384 if (!m_process_sp)
2385 return false;
2386
2387 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00002388 uint32_t cur_stop_id = m_process_sp->GetStopID();
2389 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00002390 return false;
2391
Jim Ingham78a685a2011-04-16 00:01:13 +00002392 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
2393 // In either case, we aren't going to be able to sync with the process state.
2394 if (cur_stop_id == 0)
2395 return false;
2396
2397 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00002398 m_needs_update = true;
2399 m_exe_scope = m_process_sp.get();
2400
2401 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
2402 // doesn't, mark ourselves as invalid.
2403
2404 if (m_thread_id != LLDB_INVALID_THREAD_ID)
2405 {
2406 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
2407 if (our_thread == NULL)
Greg Clayton262f80d2011-07-06 16:49:27 +00002408 {
Jim Ingham89b61092011-07-06 17:42:14 +00002409 SetInvalid();
Greg Clayton262f80d2011-07-06 16:49:27 +00002410 }
Jim Ingham6035b672011-03-31 00:19:25 +00002411 else
2412 {
2413 m_exe_scope = our_thread;
2414
2415 if (m_stack_id.IsValid())
2416 {
2417 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
2418 if (our_frame == NULL)
2419 SetInvalid();
2420 else
2421 m_exe_scope = our_frame;
2422 }
2423 }
2424 }
2425 return true;
2426}
2427
Jim Ingham61be0902011-05-02 18:13:59 +00002428void
2429ValueObject::EvaluationPoint::SetUpdated ()
2430{
2431 m_first_update = false;
2432 m_needs_update = false;
2433 if (m_process_sp)
2434 m_stop_id = m_process_sp->GetStopID();
2435}
2436
2437
Jim Ingham6035b672011-03-31 00:19:25 +00002438bool
2439ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
2440{
2441 if (!IsValid())
2442 return false;
2443
2444 bool needs_update = false;
2445 m_exe_scope = NULL;
2446
2447 // The target has to be non-null, and the
2448 Target *target = exe_scope->CalculateTarget();
2449 if (target != NULL)
2450 {
2451 Target *old_target = m_target_sp.get();
2452 assert (target == old_target);
2453 Process *process = exe_scope->CalculateProcess();
2454 if (process != NULL)
2455 {
2456 // FOR NOW - assume you can't update variable objects across process boundaries.
2457 Process *old_process = m_process_sp.get();
2458 assert (process == old_process);
2459
2460 lldb::user_id_t stop_id = process->GetStopID();
2461 if (stop_id != m_stop_id)
2462 {
2463 needs_update = true;
2464 m_stop_id = stop_id;
2465 }
2466 // See if we're switching the thread or stack context. If no thread is given, this is
2467 // being evaluated in a global context.
2468 Thread *thread = exe_scope->CalculateThread();
2469 if (thread != NULL)
2470 {
2471 lldb::user_id_t new_thread_index = thread->GetIndexID();
2472 if (new_thread_index != m_thread_id)
2473 {
2474 needs_update = true;
2475 m_thread_id = new_thread_index;
2476 m_stack_id.Clear();
2477 }
2478
2479 StackFrame *new_frame = exe_scope->CalculateStackFrame();
2480 if (new_frame != NULL)
2481 {
2482 if (new_frame->GetStackID() != m_stack_id)
2483 {
2484 needs_update = true;
2485 m_stack_id = new_frame->GetStackID();
2486 }
2487 }
2488 else
2489 {
2490 m_stack_id.Clear();
2491 needs_update = true;
2492 }
2493 }
2494 else
2495 {
2496 // If this had been given a thread, and now there is none, we should update.
2497 // Otherwise we don't have to do anything.
2498 if (m_thread_id != LLDB_INVALID_UID)
2499 {
2500 m_thread_id = LLDB_INVALID_UID;
2501 m_stack_id.Clear();
2502 needs_update = true;
2503 }
2504 }
2505 }
2506 else
2507 {
2508 // If there is no process, then we don't need to update anything.
2509 // But if we're switching from having a process to not, we should try to update.
2510 if (m_process_sp.get() != NULL)
2511 {
2512 needs_update = true;
2513 m_process_sp.reset();
2514 m_thread_id = LLDB_INVALID_UID;
2515 m_stack_id.Clear();
2516 }
2517 }
2518 }
2519 else
2520 {
2521 // If there's no target, nothing can change so we don't need to update anything.
2522 // But if we're switching from having a target to not, we should try to update.
2523 if (m_target_sp.get() != NULL)
2524 {
2525 needs_update = true;
2526 m_target_sp.reset();
2527 m_process_sp.reset();
2528 m_thread_id = LLDB_INVALID_UID;
2529 m_stack_id.Clear();
2530 }
2531 }
2532 if (!m_needs_update)
2533 m_needs_update = needs_update;
2534
2535 return needs_update;
2536}