blob: ca0b0aca0c6a357301ec89ba167fc7abcd6e1f1d [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
Enrico Granataf2bbf712011-07-15 02:26:42 +000032#include "lldb/Interpreter/ScriptInterpreterPython.h"
33
Greg Claytone1a916a2010-07-21 22:12:05 +000034#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Symbol/ClangASTContext.h"
36#include "lldb/Symbol/Type.h"
37
Jim Ingham53c47f12010-09-10 23:12:17 +000038#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000039#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040#include "lldb/Target/Process.h"
41#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000042#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044
Enrico Granataf4efecd2011-07-12 22:56:10 +000045#include "lldb/Utility/RefCounter.h"
46
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047using namespace lldb;
48using namespace lldb_private;
Enrico Granataf4efecd2011-07-12 22:56:10 +000049using namespace lldb_utility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050
51static lldb::user_id_t g_value_obj_uid = 0;
52
53//----------------------------------------------------------------------
54// ValueObject constructor
55//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000056ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000058 m_parent (&parent),
Stephen Wilson71c21d12011-04-11 19:41:40 +000059 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060 m_name (),
61 m_data (),
62 m_value (),
63 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000064 m_value_str (),
65 m_old_value_str (),
66 m_location_str (),
67 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000068 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000069 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000070 m_children (),
71 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000072 m_dynamic_value (NULL),
73 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000074 m_format (eFormatDefault),
Greg Clayton288bdf92010-09-02 02:59:18 +000075 m_value_is_valid (false),
76 m_value_did_change (false),
77 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000078 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000079 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +000080 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +000081 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +000082 m_is_bitfield_for_scalar(false),
Enrico Granata4becb372011-06-29 22:27:15 +000083 m_last_format_mgr_revision(0),
Enrico Granataf9fa6ee2011-07-12 00:18:11 +000084 m_last_value_format(),
Enrico Granataf2bbf712011-07-15 02:26:42 +000085 m_last_summary_format(),
Enrico Granataf4efecd2011-07-12 22:56:10 +000086 m_forced_summary_format(),
87 m_dump_printable_counter(0)
Jim Ingham6035b672011-03-31 00:19:25 +000088{
Jim Ingham58b59f92011-04-22 23:53:53 +000089 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +000090}
91
92//----------------------------------------------------------------------
93// ValueObject constructor
94//----------------------------------------------------------------------
95ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
96 UserID (++g_value_obj_uid), // Unique identifier for every value object
97 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +000098 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +000099 m_name (),
100 m_data (),
101 m_value (),
102 m_error (),
103 m_value_str (),
104 m_old_value_str (),
105 m_location_str (),
106 m_summary_str (),
107 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000108 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +0000109 m_children (),
110 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000111 m_dynamic_value (NULL),
112 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +0000113 m_format (eFormatDefault),
114 m_value_is_valid (false),
115 m_value_did_change (false),
116 m_children_count_valid (false),
117 m_old_value_valid (false),
118 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +0000119 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +0000120 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +0000121 m_is_bitfield_for_scalar(false),
Enrico Granata4becb372011-06-29 22:27:15 +0000122 m_last_format_mgr_revision(0),
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000123 m_last_value_format(),
Enrico Granataf2bbf712011-07-15 02:26:42 +0000124 m_last_summary_format(),
Enrico Granataf4efecd2011-07-12 22:56:10 +0000125 m_forced_summary_format(),
126 m_dump_printable_counter(0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127{
Jim Ingham58b59f92011-04-22 23:53:53 +0000128 m_manager = new ValueObjectManager();
129 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130}
131
132//----------------------------------------------------------------------
133// Destructor
134//----------------------------------------------------------------------
135ValueObject::~ValueObject ()
136{
137}
138
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139bool
Enrico Granata0a3958e2011-07-02 00:25:22 +0000140ValueObject::UpdateValueIfNeeded (bool update_format)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141{
Enrico Granata4becb372011-06-29 22:27:15 +0000142
Enrico Granata0a3958e2011-07-02 00:25:22 +0000143 if (update_format)
144 UpdateFormatsIfNeeded();
Enrico Granata4becb372011-06-29 22:27:15 +0000145
Greg Claytonb71f3842010-10-05 03:13:51 +0000146 // If this is a constant value, then our success is predicated on whether
147 // we have an error or not
148 if (GetIsConstant())
149 return m_error.Success();
150
Jim Ingham6035b672011-03-31 00:19:25 +0000151 bool first_update = m_update_point.IsFirstEvaluation();
152
153 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000154 {
Jim Ingham6035b672011-03-31 00:19:25 +0000155 m_update_point.SetUpdated();
156
157 // Save the old value using swap to avoid a string copy which
158 // also will clear our m_value_str
159 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 {
Jim Ingham6035b672011-03-31 00:19:25 +0000161 m_old_value_valid = false;
162 }
163 else
164 {
165 m_old_value_valid = true;
166 m_old_value_str.swap (m_value_str);
167 m_value_str.clear();
168 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169
Enrico Granataf2bbf712011-07-15 02:26:42 +0000170 ClearUserVisibleData();
171
Jim Ingham6035b672011-03-31 00:19:25 +0000172 const bool value_was_valid = GetValueIsValid();
173 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000174
Jim Ingham6035b672011-03-31 00:19:25 +0000175 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000176
Jim Ingham6035b672011-03-31 00:19:25 +0000177 // Call the pure virtual function to update the value
178 bool success = UpdateValue ();
179
180 SetValueIsValid (success);
181
182 if (first_update)
183 SetValueDidChange (false);
184 else if (!m_value_did_change && success == false)
185 {
186 // The value wasn't gotten successfully, so we mark this
187 // as changed if the value used to be valid and now isn't
188 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189 }
190 }
191 return m_error.Success();
192}
193
Enrico Granata4becb372011-06-29 22:27:15 +0000194void
195ValueObject::UpdateFormatsIfNeeded()
196{
197 /*printf("CHECKING FOR UPDATES. I am at revision %d, while the format manager is at revision %d\n",
198 m_last_format_mgr_revision,
199 Debugger::ValueFormats::GetCurrentRevision());*/
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000200 if (HasCustomSummaryFormat() && m_update_point.GetUpdateID() != m_user_id_of_forced_summary)
201 {
202 ClearCustomSummaryFormat();
203 m_summary_str.clear();
204 }
Enrico Granata4becb372011-06-29 22:27:15 +0000205 if (m_last_format_mgr_revision != Debugger::ValueFormats::GetCurrentRevision())
206 {
207 if (m_last_summary_format.get())
Enrico Granataf2bbf712011-07-15 02:26:42 +0000208 m_last_summary_format.reset((StringSummaryFormat*)NULL);
Enrico Granata4becb372011-06-29 22:27:15 +0000209 if (m_last_value_format.get())
210 m_last_value_format.reset((ValueFormat*)NULL);
211 Debugger::ValueFormats::Get(*this, m_last_value_format);
Enrico Granata0a3958e2011-07-02 00:25:22 +0000212 if (!Debugger::SummaryFormats::Get(*this, m_last_summary_format))
213 Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format);
Enrico Granata4becb372011-06-29 22:27:15 +0000214 m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision();
Enrico Granataf2bbf712011-07-15 02:26:42 +0000215
216 ClearUserVisibleData();
Enrico Granata4becb372011-06-29 22:27:15 +0000217 }
218}
219
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220DataExtractor &
221ValueObject::GetDataExtractor ()
222{
Jim Ingham78a685a2011-04-16 00:01:13 +0000223 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224 return m_data;
225}
226
227const Error &
Greg Clayton262f80d2011-07-06 16:49:27 +0000228ValueObject::GetError()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229{
Greg Clayton262f80d2011-07-06 16:49:27 +0000230 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000231 return m_error;
232}
233
234const ConstString &
235ValueObject::GetName() const
236{
237 return m_name;
238}
239
240const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000241ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242{
Jim Ingham6035b672011-03-31 00:19:25 +0000243 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244 {
245 if (m_location_str.empty())
246 {
247 StreamString sstr;
248
249 switch (m_value.GetValueType())
250 {
251 default:
252 break;
253
254 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000255 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000256 {
257 RegisterInfo *reg_info = m_value.GetRegisterInfo();
258 if (reg_info)
259 {
260 if (reg_info->name)
261 m_location_str = reg_info->name;
262 else if (reg_info->alt_name)
263 m_location_str = reg_info->alt_name;
264 break;
265 }
266 }
267 m_location_str = "scalar";
268 break;
269
270 case Value::eValueTypeLoadAddress:
271 case Value::eValueTypeFileAddress:
272 case Value::eValueTypeHostAddress:
273 {
274 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
275 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
276 m_location_str.swap(sstr.GetString());
277 }
278 break;
279 }
280 }
281 }
282 return m_location_str.c_str();
283}
284
285Value &
286ValueObject::GetValue()
287{
288 return m_value;
289}
290
291const Value &
292ValueObject::GetValue() const
293{
294 return m_value;
295}
296
297bool
Jim Ingham6035b672011-03-31 00:19:25 +0000298ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000299{
300 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000301 ExecutionContextScope *exe_scope = GetExecutionContextScope();
302 if (exe_scope)
303 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000304 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
305 return scalar.IsValid();
306}
307
308bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000309ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310{
Greg Clayton288bdf92010-09-02 02:59:18 +0000311 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312}
313
314
315void
316ValueObject::SetValueIsValid (bool b)
317{
Greg Clayton288bdf92010-09-02 02:59:18 +0000318 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319}
320
321bool
Jim Ingham6035b672011-03-31 00:19:25 +0000322ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000323{
Jim Ingham6035b672011-03-31 00:19:25 +0000324 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000325 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326}
327
328void
329ValueObject::SetValueDidChange (bool value_changed)
330{
Greg Clayton288bdf92010-09-02 02:59:18 +0000331 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332}
333
334ValueObjectSP
335ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
336{
337 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000338 // We may need to update our value if we are dynamic
339 if (IsPossibleDynamicType ())
340 UpdateValueIfNeeded();
341 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000343 // Check if we have already made the child value object?
344 if (can_create && m_children[idx] == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000346 // No we haven't created the child at this index, so lets have our
347 // subclass do it and cache the result for quick future access.
348 m_children[idx] = CreateChildAtIndex (idx, false, 0);
Jim Ingham78a685a2011-04-16 00:01:13 +0000349 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000350
351 if (m_children[idx] != NULL)
352 return m_children[idx]->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353 }
354 return child_sp;
355}
356
357uint32_t
358ValueObject::GetIndexOfChildWithName (const ConstString &name)
359{
360 bool omit_empty_base_classes = true;
361 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000362 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000363 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364 omit_empty_base_classes);
365}
366
367ValueObjectSP
368ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
369{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000370 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000371 // classes (which really aren't part of the expression path), so we
372 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000374
Greg Claytondea8cb42011-06-29 22:09:02 +0000375 // We may need to update our value if we are dynamic
376 if (IsPossibleDynamicType ())
377 UpdateValueIfNeeded();
378
379 std::vector<uint32_t> child_indexes;
380 clang::ASTContext *clang_ast = GetClangAST();
381 void *clang_type = GetClangType();
382 bool omit_empty_base_classes = true;
383 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
384 clang_type,
385 name.GetCString(),
386 omit_empty_base_classes,
387 child_indexes);
388 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000390 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
391 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
392
393 child_sp = GetChildAtIndex(*pos, can_create);
394 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000396 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000397 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000398 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
399 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000400 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000401 else
402 {
403 child_sp.reset();
404 }
405
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406 }
407 }
408 return child_sp;
409}
410
411
412uint32_t
413ValueObject::GetNumChildren ()
414{
Greg Clayton288bdf92010-09-02 02:59:18 +0000415 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 {
417 SetNumChildren (CalculateNumChildren());
418 }
419 return m_children.size();
420}
421void
422ValueObject::SetNumChildren (uint32_t num_children)
423{
Greg Clayton288bdf92010-09-02 02:59:18 +0000424 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425 m_children.resize(num_children);
426}
427
428void
429ValueObject::SetName (const char *name)
430{
431 m_name.SetCString(name);
432}
433
434void
435ValueObject::SetName (const ConstString &name)
436{
437 m_name = name;
438}
439
Jim Ingham58b59f92011-04-22 23:53:53 +0000440ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
442{
Jim Ingham2eec4872011-05-07 00:10:58 +0000443 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000444
Greg Claytondea8cb42011-06-29 22:09:02 +0000445 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +0000446 bool ignore_array_bounds = synthetic_array_member;
Greg Claytondea8cb42011-06-29 22:09:02 +0000447 std::string child_name_str;
448 uint32_t child_byte_size = 0;
449 int32_t child_byte_offset = 0;
450 uint32_t child_bitfield_bit_size = 0;
451 uint32_t child_bitfield_bit_offset = 0;
452 bool child_is_base_class = false;
453 bool child_is_deref_of_parent = false;
454
455 const bool transparent_pointers = synthetic_array_member == false;
456 clang::ASTContext *clang_ast = GetClangAST();
457 clang_type_t clang_type = GetClangType();
458 clang_type_t child_clang_type;
459
460 ExecutionContext exe_ctx;
461 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
462
463 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
464 clang_ast,
465 GetName().GetCString(),
466 clang_type,
467 idx,
468 transparent_pointers,
469 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +0000470 ignore_array_bounds,
Greg Claytondea8cb42011-06-29 22:09:02 +0000471 child_name_str,
472 child_byte_size,
473 child_byte_offset,
474 child_bitfield_bit_size,
475 child_bitfield_bit_offset,
476 child_is_base_class,
477 child_is_deref_of_parent);
478 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000479 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000480 if (synthetic_index)
481 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482
Greg Claytondea8cb42011-06-29 22:09:02 +0000483 ConstString child_name;
484 if (!child_name_str.empty())
485 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486
Greg Claytondea8cb42011-06-29 22:09:02 +0000487 valobj = new ValueObjectChild (*this,
488 clang_ast,
489 child_clang_type,
490 child_name,
491 child_byte_size,
492 child_byte_offset,
493 child_bitfield_bit_size,
494 child_bitfield_bit_offset,
495 child_is_base_class,
496 child_is_deref_of_parent);
497 if (m_pointers_point_to_load_addrs)
498 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000500
Jim Ingham58b59f92011-04-22 23:53:53 +0000501 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000502}
503
504const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000505ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000506{
Jim Ingham6035b672011-03-31 00:19:25 +0000507 if (UpdateValueIfNeeded ())
Enrico Granata4becb372011-06-29 22:27:15 +0000508 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000509 if (m_summary_str.empty())
510 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000511 SummaryFormat *summary_format = GetSummaryFormat().get();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000512
513 if (summary_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000514 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000515 m_summary_str = summary_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000516 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000517 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000519 clang_type_t clang_type = GetClangType();
Greg Clayton737b9322010-09-13 03:32:57 +0000520
Enrico Granataf2bbf712011-07-15 02:26:42 +0000521 // See if this is a pointer to a C string?
522 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000524 StreamString sstr;
525 clang_type_t elem_or_pointee_clang_type;
526 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
527 GetClangAST(),
528 &elem_or_pointee_clang_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529
Enrico Granataf2bbf712011-07-15 02:26:42 +0000530 ExecutionContextScope *exe_scope = GetExecutionContextScope();
531 if (exe_scope)
532 {
533 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
534 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
535 {
536 Target *target = exe_scope->CalculateTarget();
537 if (target != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000538 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000539 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
540 AddressType cstr_address_type = eAddressTypeInvalid;
541
542 size_t cstr_len = 0;
543 bool capped_data = false;
544 if (type_flags.Test (ClangASTContext::eTypeIsArray))
Greg Clayton5707d222011-07-09 17:17:07 +0000545 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000546 // We have an array
Greg Clayton5707d222011-07-09 17:17:07 +0000547 cstr_len = ClangASTContext::GetArraySize (clang_type);
548 if (cstr_len > 512) // TODO: make cap a setting
549 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000550 cstr_len = ClangASTContext::GetArraySize (clang_type);
551 if (cstr_len > 512) // TODO: make cap a setting
552 {
553 capped_data = true;
554 cstr_len = 512;
555 }
Greg Clayton5707d222011-07-09 17:17:07 +0000556 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000557 cstr_address = GetAddressOf (cstr_address_type, true);
Greg Clayton737b9322010-09-13 03:32:57 +0000558 }
Jim Ingham6035b672011-03-31 00:19:25 +0000559 else
560 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000561 // We have a pointer
562 cstr_address = GetPointerValue (cstr_address_type, true);
Jim Ingham6035b672011-03-31 00:19:25 +0000563 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000564 if (cstr_address != LLDB_INVALID_ADDRESS)
Jim Ingham6035b672011-03-31 00:19:25 +0000565 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000566 Address cstr_so_addr (NULL, cstr_address);
567 DataExtractor data;
568 size_t bytes_read = 0;
569 std::vector<char> data_buffer;
570 Error error;
571 bool prefer_file_cache = false;
572 if (cstr_len > 0)
Jim Ingham6035b672011-03-31 00:19:25 +0000573 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000574 data_buffer.resize(cstr_len);
575 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
576 bytes_read = target->ReadMemory (cstr_so_addr,
577 prefer_file_cache,
578 &data_buffer.front(),
579 cstr_len,
580 error);
581 if (bytes_read > 0)
Jim Ingham6035b672011-03-31 00:19:25 +0000582 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000583 sstr << '"';
584 data.Dump (&sstr,
585 0, // Start offset in "data"
586 eFormatCharArray, // Print as characters
587 1, // Size of item (1 byte for a char!)
588 bytes_read, // How many bytes to print?
589 UINT32_MAX, // num per line
590 LLDB_INVALID_ADDRESS,// base address
591 0, // bitfield bit size
592 0); // bitfield bit offset
593 if (capped_data)
594 sstr << "...";
595 sstr << '"';
Jim Ingham6035b672011-03-31 00:19:25 +0000596 }
597 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000598 else
599 {
600 const size_t k_max_buf_size = 256;
601 data_buffer.resize (k_max_buf_size + 1);
602 // NULL terminate in case we don't get the entire C string
603 data_buffer.back() = '\0';
Jim Ingham6035b672011-03-31 00:19:25 +0000604
Enrico Granataf2bbf712011-07-15 02:26:42 +0000605 sstr << '"';
606
607 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
608 while ((bytes_read = target->ReadMemory (cstr_so_addr,
609 prefer_file_cache,
610 &data_buffer.front(),
611 k_max_buf_size,
612 error)) > 0)
613 {
614 size_t len = strlen(&data_buffer.front());
615 if (len == 0)
616 break;
617 if (len > bytes_read)
618 len = bytes_read;
619
620 data.Dump (&sstr,
621 0, // Start offset in "data"
622 eFormatCharArray, // Print as characters
623 1, // Size of item (1 byte for a char!)
624 len, // How many bytes to print?
625 UINT32_MAX, // num per line
626 LLDB_INVALID_ADDRESS,// base address
627 0, // bitfield bit size
628 0); // bitfield bit offset
629
630 if (len < k_max_buf_size)
631 break;
632 cstr_so_addr.Slide (k_max_buf_size);
633 }
634 sstr << '"';
635 }
636 }
Jim Ingham6035b672011-03-31 00:19:25 +0000637 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000638
639 if (sstr.GetSize() > 0)
640 m_summary_str.assign (sstr.GetData(), sstr.GetSize());
Jim Ingham6035b672011-03-31 00:19:25 +0000641 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000642 else if (ClangASTContext::IsFunctionPointerType (clang_type))
Jim Ingham6035b672011-03-31 00:19:25 +0000643 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000644 AddressType func_ptr_address_type = eAddressTypeInvalid;
645 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
646
647 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
648 {
649 switch (func_ptr_address_type)
650 {
651 case eAddressTypeInvalid:
652 case eAddressTypeFile:
653 break;
654
655 case eAddressTypeLoad:
656 {
657 Address so_addr;
658 Target *target = exe_scope->CalculateTarget();
659 if (target && target->GetSectionLoadList().IsEmpty() == false)
660 {
661 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
662 {
663 so_addr.Dump (&sstr,
664 exe_scope,
665 Address::DumpStyleResolvedDescription,
666 Address::DumpStyleSectionNameOffset);
667 }
668 }
669 }
670 break;
671
672 case eAddressTypeHost:
673 break;
674 }
675 }
676 if (sstr.GetSize() > 0)
677 {
678 m_summary_str.assign (1, '(');
679 m_summary_str.append (sstr.GetData(), sstr.GetSize());
680 m_summary_str.append (1, ')');
681 }
Jim Ingham6035b672011-03-31 00:19:25 +0000682 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000683 }
684 }
685 }
686 }
687 }
688 if (m_summary_str.empty())
689 return NULL;
690 return m_summary_str.c_str();
691}
692
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000693bool
694ValueObject::IsCStringContainer(bool check_pointer)
695{
696 clang_type_t elem_or_pointee_clang_type;
697 const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(),
698 GetClangAST(),
699 &elem_or_pointee_clang_type));
700 bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
701 ClangASTContext::IsCharType (elem_or_pointee_clang_type));
702 if (!is_char_arr_ptr)
703 return false;
704 if (!check_pointer)
705 return true;
706 if (type_flags.Test(ClangASTContext::eTypeIsArray))
707 return true;
708 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
709 AddressType cstr_address_type = eAddressTypeInvalid;
710 cstr_address = GetAddressOf (cstr_address_type, true);
711 return (cstr_address != LLDB_INVALID_ADDRESS);
712}
713
714void
715ValueObject::ReadPointedString(Stream& s,
716 Error& error,
Enrico Granataf4efecd2011-07-12 22:56:10 +0000717 uint32_t max_length,
718 bool honor_array,
719 lldb::Format item_format)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000720{
721
722 if (max_length == 0)
Enrico Granataf4efecd2011-07-12 22:56:10 +0000723 max_length = 128; // FIXME this should be a setting, or a formatting parameter
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000724
725 clang_type_t clang_type = GetClangType();
726 clang_type_t elem_or_pointee_clang_type;
727 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
728 GetClangAST(),
729 &elem_or_pointee_clang_type));
730 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
731 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
732 {
733 ExecutionContextScope *exe_scope = GetExecutionContextScope();
734 if (exe_scope)
735 {
736 Target *target = exe_scope->CalculateTarget();
737 if (target != NULL)
738 {
739 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
740 AddressType cstr_address_type = eAddressTypeInvalid;
741
742 size_t cstr_len = 0;
743 bool capped_data = false;
744 if (type_flags.Test (ClangASTContext::eTypeIsArray))
745 {
746 // We have an array
747 cstr_len = ClangASTContext::GetArraySize (clang_type);
Enrico Granataf4efecd2011-07-12 22:56:10 +0000748 if (cstr_len > max_length)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000749 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000750 capped_data = true;
751 cstr_len = max_length;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000752 }
753 cstr_address = GetAddressOf (cstr_address_type, true);
754 }
755 else
756 {
757 // We have a pointer
758 cstr_address = GetPointerValue (cstr_address_type, true);
759 }
760 if (cstr_address != LLDB_INVALID_ADDRESS)
761 {
762 Address cstr_so_addr (NULL, cstr_address);
763 DataExtractor data;
764 size_t bytes_read = 0;
765 std::vector<char> data_buffer;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000766 bool prefer_file_cache = false;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000767 if (cstr_len > 0 && honor_array)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000768 {
769 data_buffer.resize(cstr_len);
770 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
771 bytes_read = target->ReadMemory (cstr_so_addr,
772 prefer_file_cache,
773 &data_buffer.front(),
774 cstr_len,
775 error);
776 if (bytes_read > 0)
777 {
778 s << '"';
779 data.Dump (&s,
780 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000781 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000782 1, // Size of item (1 byte for a char!)
783 bytes_read, // How many bytes to print?
784 UINT32_MAX, // num per line
785 LLDB_INVALID_ADDRESS,// base address
786 0, // bitfield bit size
787 0); // bitfield bit offset
788 if (capped_data)
789 s << "...";
790 s << '"';
791 }
792 }
793 else
794 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000795 cstr_len = max_length;
796 const size_t k_max_buf_size = 64;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000797 data_buffer.resize (k_max_buf_size + 1);
798 // NULL terminate in case we don't get the entire C string
799 data_buffer.back() = '\0';
800
801 s << '"';
802
803 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
804 while ((bytes_read = target->ReadMemory (cstr_so_addr,
805 prefer_file_cache,
806 &data_buffer.front(),
807 k_max_buf_size,
808 error)) > 0)
809 {
810 size_t len = strlen(&data_buffer.front());
811 if (len == 0)
812 break;
813 if (len > bytes_read)
814 len = bytes_read;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000815 if (len > cstr_len)
816 len = cstr_len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000817
818 data.Dump (&s,
819 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000820 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000821 1, // Size of item (1 byte for a char!)
822 len, // How many bytes to print?
823 UINT32_MAX, // num per line
824 LLDB_INVALID_ADDRESS,// base address
825 0, // bitfield bit size
826 0); // bitfield bit offset
827
828 if (len < k_max_buf_size)
829 break;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000830 if (len >= cstr_len)
831 {
832 s << "...";
833 break;
834 }
835 cstr_len -= len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000836 cstr_so_addr.Slide (k_max_buf_size);
837 }
838 s << '"';
839 }
840 }
841 }
842 }
843 }
844 else
845 {
846 error.SetErrorString("impossible to read a string from this object");
847 }
848}
849
Jim Ingham53c47f12010-09-10 23:12:17 +0000850const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000851ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000852{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000853
Jim Ingham6035b672011-03-31 00:19:25 +0000854 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000855 return NULL;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000856
857 if (!m_object_desc_str.empty())
858 return m_object_desc_str.c_str();
859
Jim Ingham6035b672011-03-31 00:19:25 +0000860 ExecutionContextScope *exe_scope = GetExecutionContextScope();
861 if (exe_scope == NULL)
862 return NULL;
863
Jim Ingham53c47f12010-09-10 23:12:17 +0000864 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000865 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000866 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000867
Jim Ingham53c47f12010-09-10 23:12:17 +0000868 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000869
870 lldb::LanguageType language = GetObjectRuntimeLanguage();
871 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
872
Jim Inghama2cf2632010-12-23 02:29:54 +0000873 if (runtime == NULL)
874 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000875 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000876 clang_type_t opaque_qual_type = GetClangType();
877 if (opaque_qual_type != NULL)
878 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000879 bool is_signed;
880 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
881 || ClangASTContext::IsPointerType (opaque_qual_type))
882 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000883 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000884 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000885 }
886 }
887
Jim Ingham8d543de2011-03-31 23:01:21 +0000888 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000889 {
890 m_object_desc_str.append (s.GetData());
891 }
Sean Callanan672ad942010-10-23 00:18:49 +0000892
893 if (m_object_desc_str.empty())
894 return NULL;
895 else
896 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000897}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000898
899const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000900ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000901{
902 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000903 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000904 {
Jim Ingham6035b672011-03-31 00:19:25 +0000905 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000906 {
907 if (m_value_str.empty())
908 {
909 const Value::ContextType context_type = m_value.GetContextType();
910
911 switch (context_type)
912 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000913 case Value::eContextTypeClangType:
914 case Value::eContextTypeLLDBType:
915 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000917 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000918 if (clang_type)
919 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000920 if (m_last_value_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000921 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000922 m_value_str = m_last_value_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000923 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000925 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000926 StreamString sstr;
927 Format format = GetFormat();
928 if (format == eFormatDefault)
929 format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
930 ClangASTType::GetFormat(clang_type));
931
932 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
933 clang_type, // The clang type to display
934 &sstr,
935 format, // Format to display this type with
936 m_data, // Data to extract from
937 0, // Byte offset into "m_data"
938 GetByteSize(), // Byte size of item in "m_data"
939 GetBitfieldBitSize(), // Bitfield bit size
940 GetBitfieldBitOffset())) // Bitfield bit offset
941 m_value_str.swap(sstr.GetString());
942 else
943 {
944 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
945 m_data.GetByteSize(),
946 GetByteSize());
947 m_value_str.clear();
948 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000949 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950 }
951 }
952 break;
953
Greg Clayton526e5af2010-11-13 03:52:47 +0000954 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000955 {
956 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
957 if (reg_info)
958 {
959 StreamString reg_sstr;
960 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
961 m_value_str.swap(reg_sstr.GetString());
962 }
963 }
964 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000965
966 default:
967 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000968 }
969 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000970
971 if (!m_value_did_change && m_old_value_valid)
972 {
973 // The value was gotten successfully, so we consider the
974 // value as changed if the value string differs
975 SetValueDidChange (m_old_value_str != m_value_str);
976 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977 }
978 }
979 if (m_value_str.empty())
980 return NULL;
981 return m_value_str.c_str();
982}
983
Enrico Granata0a3958e2011-07-02 00:25:22 +0000984const char *
985ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
986 lldb::Format custom_format)
987{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000988
989 RefCounter ref(&m_dump_printable_counter);
990
Enrico Granata0a3958e2011-07-02 00:25:22 +0000991 if(custom_format != lldb::eFormatInvalid)
992 SetFormat(custom_format);
993
994 const char * return_value;
995
996 switch(val_obj_display)
997 {
998 case eDisplayValue:
999 return_value = GetValueAsCString();
1000 break;
1001 case eDisplaySummary:
1002 return_value = GetSummaryAsCString();
1003 break;
1004 case eDisplayLanguageSpecific:
1005 return_value = GetObjectDescription();
1006 break;
Enrico Granataf2bbf712011-07-15 02:26:42 +00001007 case eDisplayLocation:
1008 return_value = GetLocationAsCString();
1009 break;
Enrico Granata0a3958e2011-07-02 00:25:22 +00001010 }
1011
Enrico Granataf4efecd2011-07-12 22:56:10 +00001012 // this code snippet might lead to endless recursion, thus we use a RefCounter here to
1013 // check that we are not looping endlessly
1014 if (!return_value && (m_dump_printable_counter < 3))
Enrico Granata9fc19442011-07-06 02:13:41 +00001015 {
1016 // try to pick the other choice
1017 if (val_obj_display == eDisplayValue)
1018 return_value = GetSummaryAsCString();
1019 else if (val_obj_display == eDisplaySummary)
1020 return_value = GetValueAsCString();
Enrico Granata9fc19442011-07-06 02:13:41 +00001021 }
Enrico Granata0a3958e2011-07-02 00:25:22 +00001022
Enrico Granataf4efecd2011-07-12 22:56:10 +00001023 return (return_value ? return_value : "<error>");
Enrico Granata0a3958e2011-07-02 00:25:22 +00001024
1025}
1026
Enrico Granata9fc19442011-07-06 02:13:41 +00001027bool
1028ValueObject::DumpPrintableRepresentation(Stream& s,
1029 ValueObjectRepresentationStyle val_obj_display,
1030 lldb::Format custom_format)
1031{
Enrico Granataf4efecd2011-07-12 22:56:10 +00001032
1033 clang_type_t elem_or_pointee_type;
1034 Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001035
Enrico Granataf4efecd2011-07-12 22:56:10 +00001036 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
1037 && val_obj_display == ValueObject::eDisplayValue)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001038 {
Enrico Granataf4efecd2011-07-12 22:56:10 +00001039 // when being asked to get a printable display an array or pointer type directly,
1040 // try to "do the right thing"
1041
1042 if (IsCStringContainer(true) &&
1043 (custom_format == lldb::eFormatCString ||
1044 custom_format == lldb::eFormatCharArray ||
1045 custom_format == lldb::eFormatChar ||
1046 custom_format == lldb::eFormatVectorOfChar)) // print char[] & char* directly
1047 {
1048 Error error;
1049 ReadPointedString(s,
1050 error,
1051 0,
1052 (custom_format == lldb::eFormatVectorOfChar) ||
1053 (custom_format == lldb::eFormatCharArray));
1054 return !error.Fail();
1055 }
1056
1057 if (custom_format == lldb::eFormatEnum)
1058 return false;
1059
1060 // this only works for arrays, because I have no way to know when
1061 // the pointed memory ends, and no special \0 end of data marker
1062 if (flags.Test(ClangASTContext::eTypeIsArray))
1063 {
1064 if ((custom_format == lldb::eFormatBytes) ||
1065 (custom_format == lldb::eFormatBytesWithASCII))
1066 {
1067 uint32_t count = GetNumChildren();
1068
1069 s << '[';
1070 for (uint32_t low = 0; low < count; low++)
1071 {
1072
1073 if (low)
1074 s << ',';
1075
1076 ValueObjectSP child = GetChildAtIndex(low,true);
1077 if (!child.get())
1078 {
1079 s << "<error>";
1080 continue;
1081 }
1082 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format);
1083 }
1084
1085 s << ']';
1086
1087 return true;
1088 }
1089
1090 if ((custom_format == lldb::eFormatVectorOfChar) ||
1091 (custom_format == lldb::eFormatVectorOfFloat32) ||
1092 (custom_format == lldb::eFormatVectorOfFloat64) ||
1093 (custom_format == lldb::eFormatVectorOfSInt16) ||
1094 (custom_format == lldb::eFormatVectorOfSInt32) ||
1095 (custom_format == lldb::eFormatVectorOfSInt64) ||
1096 (custom_format == lldb::eFormatVectorOfSInt8) ||
1097 (custom_format == lldb::eFormatVectorOfUInt128) ||
1098 (custom_format == lldb::eFormatVectorOfUInt16) ||
1099 (custom_format == lldb::eFormatVectorOfUInt32) ||
1100 (custom_format == lldb::eFormatVectorOfUInt64) ||
1101 (custom_format == lldb::eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
1102 {
1103 uint32_t count = GetNumChildren();
1104
1105 lldb::Format format = FormatManager::GetSingleItemFormat(custom_format);
1106
1107 s << '[';
1108 for (uint32_t low = 0; low < count; low++)
1109 {
1110
1111 if (low)
1112 s << ',';
1113
1114 ValueObjectSP child = GetChildAtIndex(low,true);
1115 if (!child.get())
1116 {
1117 s << "<error>";
1118 continue;
1119 }
1120 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format);
1121 }
1122
1123 s << ']';
1124
1125 return true;
1126 }
1127 }
1128
1129 if ((custom_format == lldb::eFormatBoolean) ||
1130 (custom_format == lldb::eFormatBinary) ||
1131 (custom_format == lldb::eFormatChar) ||
1132 (custom_format == lldb::eFormatCharPrintable) ||
1133 (custom_format == lldb::eFormatComplexFloat) ||
1134 (custom_format == lldb::eFormatDecimal) ||
1135 (custom_format == lldb::eFormatHex) ||
1136 (custom_format == lldb::eFormatFloat) ||
1137 (custom_format == lldb::eFormatOctal) ||
1138 (custom_format == lldb::eFormatOSType) ||
1139 (custom_format == lldb::eFormatUnicode16) ||
1140 (custom_format == lldb::eFormatUnicode32) ||
1141 (custom_format == lldb::eFormatUnsigned) ||
1142 (custom_format == lldb::eFormatPointer) ||
1143 (custom_format == lldb::eFormatComplexInteger) ||
1144 (custom_format == lldb::eFormatComplex) ||
1145 (custom_format == lldb::eFormatDefault)) // use the [] operator
1146 return false;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001147 }
Enrico Granataf4efecd2011-07-12 22:56:10 +00001148 const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
1149 if(targetvalue)
1150 s.PutCString(targetvalue);
1151 bool var_success = (targetvalue != NULL);
1152 if(custom_format != eFormatInvalid)
1153 SetFormat(eFormatDefault);
1154 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001155}
1156
Greg Clayton737b9322010-09-13 03:32:57 +00001157addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001158ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +00001159{
Jim Ingham78a685a2011-04-16 00:01:13 +00001160 if (!UpdateValueIfNeeded())
1161 return LLDB_INVALID_ADDRESS;
1162
Greg Clayton73b472d2010-10-27 03:32:59 +00001163 switch (m_value.GetValueType())
1164 {
1165 case Value::eValueTypeScalar:
1166 if (scalar_is_load_address)
1167 {
1168 address_type = eAddressTypeLoad;
1169 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1170 }
1171 break;
1172
1173 case Value::eValueTypeLoadAddress:
1174 case Value::eValueTypeFileAddress:
1175 case Value::eValueTypeHostAddress:
1176 {
1177 address_type = m_value.GetValueAddressType ();
1178 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1179 }
1180 break;
1181 }
1182 address_type = eAddressTypeInvalid;
1183 return LLDB_INVALID_ADDRESS;
1184}
1185
1186addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001187ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +00001188{
1189 lldb::addr_t address = LLDB_INVALID_ADDRESS;
1190 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +00001191
1192 if (!UpdateValueIfNeeded())
1193 return address;
1194
Greg Clayton73b472d2010-10-27 03:32:59 +00001195 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +00001196 {
1197 case Value::eValueTypeScalar:
1198 if (scalar_is_load_address)
1199 {
1200 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1201 address_type = eAddressTypeLoad;
1202 }
1203 break;
1204
1205 case Value::eValueTypeLoadAddress:
1206 case Value::eValueTypeFileAddress:
1207 case Value::eValueTypeHostAddress:
1208 {
1209 uint32_t data_offset = 0;
1210 address = m_data.GetPointer(&data_offset);
1211 address_type = m_value.GetValueAddressType();
1212 if (address_type == eAddressTypeInvalid)
1213 address_type = eAddressTypeLoad;
1214 }
1215 break;
1216 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001217
1218 if (m_pointers_point_to_load_addrs)
1219 address_type = eAddressTypeLoad;
1220
Greg Clayton737b9322010-09-13 03:32:57 +00001221 return address;
1222}
1223
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001224bool
Jim Ingham6035b672011-03-31 00:19:25 +00001225ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001226{
1227 // Make sure our value is up to date first so that our location and location
1228 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +00001229 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001230 return false;
1231
1232 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001233 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001234
1235 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +00001236 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001237 switch (encoding)
1238 {
1239 case eEncodingInvalid:
1240 return false;
1241
1242 case eEncodingUint:
1243 if (byte_size > sizeof(unsigned long long))
1244 {
1245 return false;
1246 }
1247 else
1248 {
1249 unsigned long long ull_val = strtoull(value_str, &end, 0);
1250 if (end && *end != '\0')
1251 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001252 m_value.GetScalar() = ull_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001253 // Limit the bytes in our m_data appropriately.
1254 m_value.GetScalar().GetData (m_data, byte_size);
1255 }
1256 break;
1257
1258 case eEncodingSint:
1259 if (byte_size > sizeof(long long))
1260 {
1261 return false;
1262 }
1263 else
1264 {
1265 long long sll_val = strtoll(value_str, &end, 0);
1266 if (end && *end != '\0')
1267 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001268 m_value.GetScalar() = sll_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001269 // Limit the bytes in our m_data appropriately.
1270 m_value.GetScalar().GetData (m_data, byte_size);
1271 }
1272 break;
1273
1274 case eEncodingIEEE754:
1275 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001276 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +00001277 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001278 if (dst != NULL)
1279 {
1280 // We are decoding a float into host byte order below, so make
1281 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +00001282 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001283 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
1284 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +00001285 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001286 value_str,
1287 dst,
1288 byte_size);
1289
1290 if (converted_byte_size == byte_size)
1291 {
1292 }
1293 }
1294 }
1295 break;
1296
1297 case eEncodingVector:
1298 return false;
1299
1300 default:
1301 return false;
1302 }
1303
1304 // If we have made it here the value is in m_data and we should write it
1305 // out to the target
1306 return Write ();
1307}
1308
1309bool
1310ValueObject::Write ()
1311{
1312 // Clear the update ID so the next time we try and read the value
1313 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +00001314 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001315
1316 // TODO: when Value has a method to write a value back, call it from here.
1317 return false;
1318
1319}
1320
Jim Ingham5a369122010-09-28 01:25:32 +00001321lldb::LanguageType
1322ValueObject::GetObjectRuntimeLanguage ()
1323{
Greg Clayton73b472d2010-10-27 03:32:59 +00001324 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +00001325 if (opaque_qual_type == NULL)
1326 return lldb::eLanguageTypeC;
1327
1328 // If the type is a reference, then resolve it to what it refers to first:
1329 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
1330 if (qual_type->isAnyPointerType())
1331 {
1332 if (qual_type->isObjCObjectPointerType())
1333 return lldb::eLanguageTypeObjC;
1334
1335 clang::QualType pointee_type (qual_type->getPointeeType());
1336 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
1337 return lldb::eLanguageTypeC_plus_plus;
1338 if (pointee_type->isObjCObjectOrInterfaceType())
1339 return lldb::eLanguageTypeObjC;
1340 if (pointee_type->isObjCClassType())
1341 return lldb::eLanguageTypeObjC;
1342 }
1343 else
1344 {
1345 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
1346 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +00001347 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +00001348 return lldb::eLanguageTypeC_plus_plus;
1349 }
1350
1351 return lldb::eLanguageTypeC;
1352}
1353
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001354void
Jim Ingham58b59f92011-04-22 23:53:53 +00001355ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001356{
Jim Ingham58b59f92011-04-22 23:53:53 +00001357 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001358}
1359
1360ValueObjectSP
1361ValueObject::GetSyntheticChild (const ConstString &key) const
1362{
1363 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +00001364 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001365 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +00001366 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001367 return synthetic_child_sp;
1368}
1369
1370bool
1371ValueObject::IsPointerType ()
1372{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001373 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001374}
1375
Jim Inghamb7603bb2011-03-18 00:05:18 +00001376bool
Greg Claytondaf515f2011-07-09 20:12:33 +00001377ValueObject::IsArrayType ()
1378{
1379 return ClangASTContext::IsArrayType (GetClangType());
1380}
1381
1382bool
Enrico Granata9fc19442011-07-06 02:13:41 +00001383ValueObject::IsScalarType ()
1384{
1385 return ClangASTContext::IsScalarType (GetClangType());
1386}
1387
1388bool
Jim Inghamb7603bb2011-03-18 00:05:18 +00001389ValueObject::IsIntegerType (bool &is_signed)
1390{
1391 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
1392}
Greg Clayton73b472d2010-10-27 03:32:59 +00001393
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001394bool
1395ValueObject::IsPointerOrReferenceType ()
1396{
Greg Clayton007d5be2011-05-30 00:49:24 +00001397 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
1398}
1399
1400bool
1401ValueObject::IsPossibleCPlusPlusDynamicType ()
1402{
1403 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001404}
1405
Greg Claytondea8cb42011-06-29 22:09:02 +00001406bool
1407ValueObject::IsPossibleDynamicType ()
1408{
1409 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
1410}
1411
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001412ValueObjectSP
1413ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
1414{
1415 ValueObjectSP synthetic_child_sp;
1416 if (IsPointerType ())
1417 {
1418 char index_str[64];
1419 snprintf(index_str, sizeof(index_str), "[%i]", index);
1420 ConstString index_const_str(index_str);
1421 // Check if we have already created a synthetic array member in this
1422 // valid object. If we have we will re-use it.
1423 synthetic_child_sp = GetSyntheticChild (index_const_str);
1424 if (!synthetic_child_sp)
1425 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001426 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001427 // We haven't made a synthetic array member for INDEX yet, so
1428 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001429 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001430
1431 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001432 if (synthetic_child)
1433 {
1434 AddSyntheticChild(index_const_str, synthetic_child);
1435 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata0a3958e2011-07-02 00:25:22 +00001436 synthetic_child_sp->SetName(index_str);
1437 synthetic_child_sp->m_is_array_item_for_pointer = true;
Jim Ingham58b59f92011-04-22 23:53:53 +00001438 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001439 }
1440 }
1441 return synthetic_child_sp;
1442}
Jim Ingham22777012010-09-23 02:01:19 +00001443
Greg Claytondaf515f2011-07-09 20:12:33 +00001444// This allows you to create an array member using and index
1445// that doesn't not fall in the normal bounds of the array.
1446// Many times structure can be defined as:
1447// struct Collection
1448// {
1449// uint32_t item_count;
1450// Item item_array[0];
1451// };
1452// The size of the "item_array" is 1, but many times in practice
1453// there are more items in "item_array".
1454
1455ValueObjectSP
1456ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create)
1457{
1458 ValueObjectSP synthetic_child_sp;
1459 if (IsArrayType ())
1460 {
1461 char index_str[64];
1462 snprintf(index_str, sizeof(index_str), "[%i]", index);
1463 ConstString index_const_str(index_str);
1464 // Check if we have already created a synthetic array member in this
1465 // valid object. If we have we will re-use it.
1466 synthetic_child_sp = GetSyntheticChild (index_const_str);
1467 if (!synthetic_child_sp)
1468 {
1469 ValueObject *synthetic_child;
1470 // We haven't made a synthetic array member for INDEX yet, so
1471 // lets make one and cache it for any future reference.
1472 synthetic_child = CreateChildAtIndex(0, true, index);
1473
1474 // Cache the value if we got one back...
1475 if (synthetic_child)
1476 {
1477 AddSyntheticChild(index_const_str, synthetic_child);
1478 synthetic_child_sp = synthetic_child->GetSP();
1479 synthetic_child_sp->SetName(index_str);
1480 synthetic_child_sp->m_is_array_item_for_pointer = true;
1481 }
1482 }
1483 }
1484 return synthetic_child_sp;
1485}
1486
Enrico Granata9fc19442011-07-06 02:13:41 +00001487ValueObjectSP
1488ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
1489{
1490 ValueObjectSP synthetic_child_sp;
1491 if (IsScalarType ())
1492 {
1493 char index_str[64];
1494 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1495 ConstString index_const_str(index_str);
1496 // Check if we have already created a synthetic array member in this
1497 // valid object. If we have we will re-use it.
1498 synthetic_child_sp = GetSyntheticChild (index_const_str);
1499 if (!synthetic_child_sp)
1500 {
1501 ValueObjectChild *synthetic_child;
1502 // We haven't made a synthetic array member for INDEX yet, so
1503 // lets make one and cache it for any future reference.
1504 synthetic_child = new ValueObjectChild(*this,
1505 GetClangAST(),
1506 GetClangType(),
1507 index_const_str,
1508 GetByteSize(),
1509 0,
1510 to-from+1,
1511 from,
1512 false,
1513 false);
1514
1515 // Cache the value if we got one back...
1516 if (synthetic_child)
1517 {
1518 AddSyntheticChild(index_const_str, synthetic_child);
1519 synthetic_child_sp = synthetic_child->GetSP();
1520 synthetic_child_sp->SetName(index_str);
1521 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1522 }
1523 }
1524 }
1525 return synthetic_child_sp;
1526}
1527
Jim Ingham78a685a2011-04-16 00:01:13 +00001528void
Jim Ingham2837b762011-05-04 03:43:18 +00001529ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001530{
Jim Ingham2837b762011-05-04 03:43:18 +00001531 if (use_dynamic == lldb::eNoDynamicValues)
1532 return;
1533
Jim Ingham58b59f92011-04-22 23:53:53 +00001534 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001535 {
1536 Process *process = m_update_point.GetProcess();
1537 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001538
Jim Ingham78a685a2011-04-16 00:01:13 +00001539
1540 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1541 // hard code this everywhere.
1542 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1543 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1544 {
1545 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1546 if (runtime)
1547 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1548 }
1549 else
1550 {
1551 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1552 if (cpp_runtime)
1553 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1554
1555 if (!worth_having_dynamic_value)
1556 {
1557 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1558 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001559 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001560 }
1561 }
1562
1563 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001564 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001565
1566// if (worth_having_dynamic_value)
1567// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1568
Jim Ingham78a685a2011-04-16 00:01:13 +00001569 }
1570}
1571
Jim Ingham58b59f92011-04-22 23:53:53 +00001572ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001573ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001574{
Jim Ingham2837b762011-05-04 03:43:18 +00001575 if (use_dynamic == lldb::eNoDynamicValues)
1576 return ValueObjectSP();
1577
1578 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001579 {
Jim Ingham2837b762011-05-04 03:43:18 +00001580 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001581 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001582 if (m_dynamic_value)
1583 return m_dynamic_value->GetSP();
1584 else
1585 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001586}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001587
Greg Claytone221f822011-01-21 01:59:00 +00001588bool
1589ValueObject::GetBaseClassPath (Stream &s)
1590{
1591 if (IsBaseClass())
1592 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001593 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001594 clang_type_t clang_type = GetClangType();
1595 std::string cxx_class_name;
1596 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1597 if (this_had_base_class)
1598 {
1599 if (parent_had_base_class)
1600 s.PutCString("::");
1601 s.PutCString(cxx_class_name.c_str());
1602 }
1603 return parent_had_base_class || this_had_base_class;
1604 }
1605 return false;
1606}
1607
1608
1609ValueObject *
1610ValueObject::GetNonBaseClassParent()
1611{
Jim Ingham78a685a2011-04-16 00:01:13 +00001612 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001613 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001614 if (GetParent()->IsBaseClass())
1615 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001616 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001617 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001618 }
1619 return NULL;
1620}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001621
1622void
Enrico Granata4becb372011-06-29 22:27:15 +00001623ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001624{
Greg Claytone221f822011-01-21 01:59:00 +00001625 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00001626
Enrico Granata4becb372011-06-29 22:27:15 +00001627 if(is_deref_of_parent && epformat == eDereferencePointers) {
1628 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
1629 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
1630 // the eHonorPointers mode is meant to produce strings in this latter format
1631 s.PutCString("*(");
1632 }
Greg Claytone221f822011-01-21 01:59:00 +00001633
Enrico Granata4becb372011-06-29 22:27:15 +00001634 ValueObject* parent = GetParent();
1635
1636 if (parent)
1637 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
Enrico Granata0a3958e2011-07-02 00:25:22 +00001638
1639 // if we are a deref_of_parent just because we are synthetic array
1640 // members made up to allow ptr[%d] syntax to work in variable
1641 // printing, then add our name ([%d]) to the expression path
1642 if(m_is_array_item_for_pointer && epformat == eHonorPointers)
1643 s.PutCString(m_name.AsCString());
Enrico Granata4becb372011-06-29 22:27:15 +00001644
Greg Claytone221f822011-01-21 01:59:00 +00001645 if (!IsBaseClass())
1646 {
1647 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001648 {
Greg Claytone221f822011-01-21 01:59:00 +00001649 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1650 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001651 {
Greg Claytone221f822011-01-21 01:59:00 +00001652 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1653 if (non_base_class_parent_clang_type)
1654 {
1655 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1656
Enrico Granata4becb372011-06-29 22:27:15 +00001657 if(parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00001658 {
1659 s.PutCString("->");
1660 }
Enrico Granata4becb372011-06-29 22:27:15 +00001661 else
1662 {
1663 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1664 {
1665 s.PutCString("->");
1666 }
1667 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1668 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1669 {
1670 s.PutChar('.');
1671 }
Greg Claytone221f822011-01-21 01:59:00 +00001672 }
1673 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001674 }
Greg Claytone221f822011-01-21 01:59:00 +00001675
1676 const char *name = GetName().GetCString();
1677 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001678 {
Greg Claytone221f822011-01-21 01:59:00 +00001679 if (qualify_cxx_base_classes)
1680 {
1681 if (GetBaseClassPath (s))
1682 s.PutCString("::");
1683 }
1684 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001685 }
1686 }
1687 }
1688
Enrico Granata4becb372011-06-29 22:27:15 +00001689 if (is_deref_of_parent && epformat == eDereferencePointers) {
Greg Claytone221f822011-01-21 01:59:00 +00001690 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00001691 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001692}
1693
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001694lldb::ValueObjectSP
1695ValueObject::GetValueForExpressionPath(const char* expression,
1696 const char** first_unparsed,
1697 ExpressionPathScanEndReason* reason_to_stop,
1698 ExpressionPathEndResultType* final_value_type,
1699 const GetValueForExpressionPathOptions& options,
1700 ExpressionPathAftermath* final_task_on_target)
1701{
1702
1703 const char* dummy_first_unparsed;
1704 ExpressionPathScanEndReason dummy_reason_to_stop;
1705 ExpressionPathEndResultType dummy_final_value_type;
1706 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1707
1708 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1709 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1710 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1711 final_value_type ? final_value_type : &dummy_final_value_type,
1712 options,
1713 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1714
1715 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1716 {
1717 return ret_val;
1718 }
1719 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1720 {
1721 if (*final_task_on_target == ValueObject::eDereference)
1722 {
1723 Error error;
1724 ValueObjectSP final_value = ret_val->Dereference(error);
1725 if (error.Fail() || !final_value.get())
1726 {
1727 *reason_to_stop = ValueObject::eDereferencingFailed;
1728 *final_value_type = ValueObject::eInvalid;
1729 return ValueObjectSP();
1730 }
1731 else
1732 {
1733 *final_task_on_target = ValueObject::eNothing;
1734 return final_value;
1735 }
1736 }
1737 if (*final_task_on_target == ValueObject::eTakeAddress)
1738 {
1739 Error error;
1740 ValueObjectSP final_value = ret_val->AddressOf(error);
1741 if (error.Fail() || !final_value.get())
1742 {
1743 *reason_to_stop = ValueObject::eTakingAddressFailed;
1744 *final_value_type = ValueObject::eInvalid;
1745 return ValueObjectSP();
1746 }
1747 else
1748 {
1749 *final_task_on_target = ValueObject::eNothing;
1750 return final_value;
1751 }
1752 }
1753 }
1754 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
1755}
1756
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001757int
1758ValueObject::GetValuesForExpressionPath(const char* expression,
1759 lldb::ValueObjectListSP& list,
1760 const char** first_unparsed,
1761 ExpressionPathScanEndReason* reason_to_stop,
1762 ExpressionPathEndResultType* final_value_type,
1763 const GetValueForExpressionPathOptions& options,
1764 ExpressionPathAftermath* final_task_on_target)
1765{
1766 const char* dummy_first_unparsed;
1767 ExpressionPathScanEndReason dummy_reason_to_stop;
1768 ExpressionPathEndResultType dummy_final_value_type;
1769 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1770
1771 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1772 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1773 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1774 final_value_type ? final_value_type : &dummy_final_value_type,
1775 options,
1776 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1777
1778 if (!ret_val.get()) // if there are errors, I add nothing to the list
1779 return 0;
1780
1781 if (*reason_to_stop != eArrayRangeOperatorMet)
1782 {
1783 // I need not expand a range, just post-process the final value and return
1784 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1785 {
1786 list->Append(ret_val);
1787 return 1;
1788 }
1789 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1790 {
1791 if (*final_task_on_target == ValueObject::eDereference)
1792 {
1793 Error error;
1794 ValueObjectSP final_value = ret_val->Dereference(error);
1795 if (error.Fail() || !final_value.get())
1796 {
1797 *reason_to_stop = ValueObject::eDereferencingFailed;
1798 *final_value_type = ValueObject::eInvalid;
1799 return 0;
1800 }
1801 else
1802 {
1803 *final_task_on_target = ValueObject::eNothing;
1804 list->Append(final_value);
1805 return 1;
1806 }
1807 }
1808 if (*final_task_on_target == ValueObject::eTakeAddress)
1809 {
1810 Error error;
1811 ValueObjectSP final_value = ret_val->AddressOf(error);
1812 if (error.Fail() || !final_value.get())
1813 {
1814 *reason_to_stop = ValueObject::eTakingAddressFailed;
1815 *final_value_type = ValueObject::eInvalid;
1816 return 0;
1817 }
1818 else
1819 {
1820 *final_task_on_target = ValueObject::eNothing;
1821 list->Append(final_value);
1822 return 1;
1823 }
1824 }
1825 }
1826 }
1827 else
1828 {
1829 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
1830 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1831 ret_val,
1832 list,
1833 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1834 final_value_type ? final_value_type : &dummy_final_value_type,
1835 options,
1836 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1837 }
1838 // in any non-covered case, just do the obviously right thing
1839 list->Append(ret_val);
1840 return 1;
1841}
1842
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001843lldb::ValueObjectSP
1844ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
1845 const char** first_unparsed,
1846 ExpressionPathScanEndReason* reason_to_stop,
1847 ExpressionPathEndResultType* final_result,
1848 const GetValueForExpressionPathOptions& options,
1849 ExpressionPathAftermath* what_next)
1850{
1851 ValueObjectSP root = GetSP();
1852
1853 if (!root.get())
1854 return ValueObjectSP();
1855
1856 *first_unparsed = expression_cstr;
1857
1858 while (true)
1859 {
1860
1861 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
1862
1863 lldb::clang_type_t root_clang_type = root->GetClangType();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001864 lldb::clang_type_t pointee_clang_type;
1865 Flags root_clang_type_info,pointee_clang_type_info;
1866
1867 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
1868 if (pointee_clang_type)
1869 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001870
1871 if (!expression_cstr || *expression_cstr == '\0')
1872 {
1873 *reason_to_stop = ValueObject::eEndOfString;
1874 return root;
1875 }
1876
1877 switch (*expression_cstr)
1878 {
1879 case '-':
1880 {
1881 if (options.m_check_dot_vs_arrow_syntax &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001882 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001883 {
1884 *first_unparsed = expression_cstr;
1885 *reason_to_stop = ValueObject::eArrowInsteadOfDot;
1886 *final_result = ValueObject::eInvalid;
1887 return ValueObjectSP();
1888 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001889 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
1890 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) &&
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001891 options.m_no_fragile_ivar)
1892 {
1893 *first_unparsed = expression_cstr;
1894 *reason_to_stop = ValueObject::eFragileIVarNotAllowed;
1895 *final_result = ValueObject::eInvalid;
1896 return ValueObjectSP();
1897 }
1898 if (expression_cstr[1] != '>')
1899 {
1900 *first_unparsed = expression_cstr;
1901 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1902 *final_result = ValueObject::eInvalid;
1903 return ValueObjectSP();
1904 }
1905 expression_cstr++; // skip the -
1906 }
1907 case '.': // or fallthrough from ->
1908 {
1909 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001910 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001911 {
1912 *first_unparsed = expression_cstr;
1913 *reason_to_stop = ValueObject::eDotInsteadOfArrow;
1914 *final_result = ValueObject::eInvalid;
1915 return ValueObjectSP();
1916 }
1917 expression_cstr++; // skip .
1918 const char *next_separator = strpbrk(expression_cstr+1,"-.[");
1919 ConstString child_name;
1920 if (!next_separator) // if no other separator just expand this last layer
1921 {
1922 child_name.SetCString (expression_cstr);
1923 root = root->GetChildMemberWithName(child_name, true);
1924 if (root.get()) // we know we are done, so just return
1925 {
1926 *first_unparsed = '\0';
1927 *reason_to_stop = ValueObject::eEndOfString;
1928 *final_result = ValueObject::ePlain;
1929 return root;
1930 }
1931 else
1932 {
1933 *first_unparsed = expression_cstr;
1934 *reason_to_stop = ValueObject::eNoSuchChild;
1935 *final_result = ValueObject::eInvalid;
1936 return ValueObjectSP();
1937 }
1938 }
1939 else // other layers do expand
1940 {
1941 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
1942 root = root->GetChildMemberWithName(child_name, true);
1943 if (root.get()) // store the new root and move on
1944 {
1945 *first_unparsed = next_separator;
1946 *final_result = ValueObject::ePlain;
1947 continue;
1948 }
1949 else
1950 {
1951 *first_unparsed = expression_cstr;
1952 *reason_to_stop = ValueObject::eNoSuchChild;
1953 *final_result = ValueObject::eInvalid;
1954 return ValueObjectSP();
1955 }
1956 }
1957 break;
1958 }
1959 case '[':
1960 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001961 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001962 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001963 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001964 {
1965 *first_unparsed = expression_cstr;
1966 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
1967 *final_result = ValueObject::eInvalid;
1968 return ValueObjectSP();
1969 }
1970 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
1971 {
1972 *first_unparsed = expression_cstr;
1973 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
1974 *final_result = ValueObject::eInvalid;
1975 return ValueObjectSP();
1976 }
1977 }
1978 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
1979 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001980 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001981 {
1982 *first_unparsed = expression_cstr;
1983 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
1984 *final_result = ValueObject::eInvalid;
1985 return ValueObjectSP();
1986 }
1987 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
1988 {
1989 *first_unparsed = expression_cstr+2;
1990 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
1991 *final_result = ValueObject::eUnboundedRange;
1992 return root;
1993 }
1994 }
1995 const char *separator_position = ::strchr(expression_cstr+1,'-');
1996 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
1997 if (!close_bracket_position) // if there is no ], this is a syntax error
1998 {
1999 *first_unparsed = expression_cstr;
2000 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2001 *final_result = ValueObject::eInvalid;
2002 return ValueObjectSP();
2003 }
2004 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2005 {
2006 char *end = NULL;
2007 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2008 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2009 {
2010 *first_unparsed = expression_cstr;
2011 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2012 *final_result = ValueObject::eInvalid;
2013 return ValueObjectSP();
2014 }
2015 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2016 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002017 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002018 {
2019 *first_unparsed = expression_cstr+2;
2020 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2021 *final_result = ValueObject::eUnboundedRange;
2022 return root;
2023 }
2024 else
2025 {
2026 *first_unparsed = expression_cstr;
2027 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2028 *final_result = ValueObject::eInvalid;
2029 return ValueObjectSP();
2030 }
2031 }
2032 // from here on we do have a valid index
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002033 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002034 {
Greg Claytondaf515f2011-07-09 20:12:33 +00002035 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2036 if (!child_valobj_sp)
2037 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
2038 if (child_valobj_sp)
2039 {
2040 root = child_valobj_sp;
2041 *first_unparsed = end+1; // skip ]
2042 *final_result = ValueObject::ePlain;
2043 continue;
2044 }
2045 else
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002046 {
2047 *first_unparsed = expression_cstr;
2048 *reason_to_stop = ValueObject::eNoSuchChild;
2049 *final_result = ValueObject::eInvalid;
2050 return ValueObjectSP();
2051 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002052 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002053 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002054 {
2055 if (*what_next == ValueObject::eDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002056 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002057 {
2058 Error error;
2059 root = root->Dereference(error);
2060 if (error.Fail() || !root.get())
2061 {
2062 *first_unparsed = expression_cstr;
2063 *reason_to_stop = ValueObject::eDereferencingFailed;
2064 *final_result = ValueObject::eInvalid;
2065 return ValueObjectSP();
2066 }
2067 else
2068 {
2069 *what_next = eNothing;
2070 continue;
2071 }
2072 }
2073 else
2074 {
2075 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2076 if (!root.get())
2077 {
2078 *first_unparsed = expression_cstr;
2079 *reason_to_stop = ValueObject::eNoSuchChild;
2080 *final_result = ValueObject::eInvalid;
2081 return ValueObjectSP();
2082 }
2083 else
2084 {
2085 *first_unparsed = end+1; // skip ]
2086 *final_result = ValueObject::ePlain;
2087 continue;
2088 }
2089 }
2090 }
2091 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
2092 {
2093 root = root->GetSyntheticBitFieldChild(index, index, true);
2094 if (!root.get())
2095 {
2096 *first_unparsed = expression_cstr;
2097 *reason_to_stop = ValueObject::eNoSuchChild;
2098 *final_result = ValueObject::eInvalid;
2099 return ValueObjectSP();
2100 }
2101 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2102 {
2103 *first_unparsed = end+1; // skip ]
2104 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2105 *final_result = ValueObject::eBitfield;
2106 return root;
2107 }
2108 }
2109 }
2110 else // we have a low and a high index
2111 {
2112 char *end = NULL;
2113 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2114 if (!end || end != separator_position) // if something weird is in our way return an error
2115 {
2116 *first_unparsed = expression_cstr;
2117 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2118 *final_result = ValueObject::eInvalid;
2119 return ValueObjectSP();
2120 }
2121 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2122 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2123 {
2124 *first_unparsed = expression_cstr;
2125 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2126 *final_result = ValueObject::eInvalid;
2127 return ValueObjectSP();
2128 }
2129 if (index_lower > index_higher) // swap indices if required
2130 {
2131 unsigned long temp = index_lower;
2132 index_lower = index_higher;
2133 index_higher = temp;
2134 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002135 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002136 {
2137 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2138 if (!root.get())
2139 {
2140 *first_unparsed = expression_cstr;
2141 *reason_to_stop = ValueObject::eNoSuchChild;
2142 *final_result = ValueObject::eInvalid;
2143 return ValueObjectSP();
2144 }
2145 else
2146 {
2147 *first_unparsed = end+1; // skip ]
2148 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2149 *final_result = ValueObject::eBitfield;
2150 return root;
2151 }
2152 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002153 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002154 *what_next == ValueObject::eDereference &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002155 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002156 {
2157 Error error;
2158 root = root->Dereference(error);
2159 if (error.Fail() || !root.get())
2160 {
2161 *first_unparsed = expression_cstr;
2162 *reason_to_stop = ValueObject::eDereferencingFailed;
2163 *final_result = ValueObject::eInvalid;
2164 return ValueObjectSP();
2165 }
2166 else
2167 {
2168 *what_next = ValueObject::eNothing;
2169 continue;
2170 }
2171 }
2172 else
2173 {
2174 *first_unparsed = expression_cstr;
2175 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2176 *final_result = ValueObject::eBoundedRange;
2177 return root;
2178 }
2179 }
2180 break;
2181 }
2182 default: // some non-separator is in the way
2183 {
2184 *first_unparsed = expression_cstr;
2185 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2186 *final_result = ValueObject::eInvalid;
2187 return ValueObjectSP();
2188 break;
2189 }
2190 }
2191 }
2192}
2193
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002194int
2195ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
2196 const char** first_unparsed,
2197 lldb::ValueObjectSP root,
2198 lldb::ValueObjectListSP& list,
2199 ExpressionPathScanEndReason* reason_to_stop,
2200 ExpressionPathEndResultType* final_result,
2201 const GetValueForExpressionPathOptions& options,
2202 ExpressionPathAftermath* what_next)
2203{
2204 if (!root.get())
2205 return 0;
2206
2207 *first_unparsed = expression_cstr;
2208
2209 while (true)
2210 {
2211
2212 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
2213
2214 lldb::clang_type_t root_clang_type = root->GetClangType();
2215 lldb::clang_type_t pointee_clang_type;
2216 Flags root_clang_type_info,pointee_clang_type_info;
2217
2218 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
2219 if (pointee_clang_type)
2220 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
2221
2222 if (!expression_cstr || *expression_cstr == '\0')
2223 {
2224 *reason_to_stop = ValueObject::eEndOfString;
2225 list->Append(root);
2226 return 1;
2227 }
2228
2229 switch (*expression_cstr)
2230 {
2231 case '[':
2232 {
2233 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
2234 {
2235 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
2236 {
2237 *first_unparsed = expression_cstr;
2238 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2239 *final_result = ValueObject::eInvalid;
2240 return 0;
2241 }
2242 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2243 {
2244 *first_unparsed = expression_cstr;
2245 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2246 *final_result = ValueObject::eInvalid;
2247 return 0;
2248 }
2249 }
2250 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2251 {
2252 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2253 {
2254 *first_unparsed = expression_cstr;
2255 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2256 *final_result = ValueObject::eInvalid;
2257 return 0;
2258 }
2259 else // expand this into list
2260 {
2261 int max_index = root->GetNumChildren() - 1;
2262 for (int index = 0; index < max_index; index++)
2263 {
2264 ValueObjectSP child =
2265 root->GetChildAtIndex(index, true);
2266 list->Append(child);
2267 }
2268 *first_unparsed = expression_cstr+2;
2269 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2270 *final_result = ValueObject::eValueObjectList;
2271 return max_index; // tell me number of items I added to the VOList
2272 }
2273 }
2274 const char *separator_position = ::strchr(expression_cstr+1,'-');
2275 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2276 if (!close_bracket_position) // if there is no ], this is a syntax error
2277 {
2278 *first_unparsed = expression_cstr;
2279 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2280 *final_result = ValueObject::eInvalid;
2281 return 0;
2282 }
2283 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2284 {
2285 char *end = NULL;
2286 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2287 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2288 {
2289 *first_unparsed = expression_cstr;
2290 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2291 *final_result = ValueObject::eInvalid;
2292 return 0;
2293 }
2294 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2295 {
2296 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2297 {
2298 int max_index = root->GetNumChildren() - 1;
2299 for (int index = 0; index < max_index; index++)
2300 {
2301 ValueObjectSP child =
2302 root->GetChildAtIndex(index, true);
2303 list->Append(child);
2304 }
2305 *first_unparsed = expression_cstr+2;
2306 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2307 *final_result = ValueObject::eValueObjectList;
2308 return max_index; // tell me number of items I added to the VOList
2309 }
2310 else
2311 {
2312 *first_unparsed = expression_cstr;
2313 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2314 *final_result = ValueObject::eInvalid;
2315 return 0;
2316 }
2317 }
2318 // from here on we do have a valid index
2319 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2320 {
2321 root = root->GetChildAtIndex(index, true);
2322 if (!root.get())
2323 {
2324 *first_unparsed = expression_cstr;
2325 *reason_to_stop = ValueObject::eNoSuchChild;
2326 *final_result = ValueObject::eInvalid;
2327 return 0;
2328 }
2329 else
2330 {
2331 list->Append(root);
2332 *first_unparsed = end+1; // skip ]
2333 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2334 *final_result = ValueObject::eValueObjectList;
2335 return 1;
2336 }
2337 }
2338 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
2339 {
2340 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
2341 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2342 {
2343 Error error;
2344 root = root->Dereference(error);
2345 if (error.Fail() || !root.get())
2346 {
2347 *first_unparsed = expression_cstr;
2348 *reason_to_stop = ValueObject::eDereferencingFailed;
2349 *final_result = ValueObject::eInvalid;
2350 return 0;
2351 }
2352 else
2353 {
2354 *what_next = eNothing;
2355 continue;
2356 }
2357 }
2358 else
2359 {
2360 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2361 if (!root.get())
2362 {
2363 *first_unparsed = expression_cstr;
2364 *reason_to_stop = ValueObject::eNoSuchChild;
2365 *final_result = ValueObject::eInvalid;
2366 return 0;
2367 }
2368 else
2369 {
2370 list->Append(root);
2371 *first_unparsed = end+1; // skip ]
2372 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2373 *final_result = ValueObject::eValueObjectList;
2374 return 1;
2375 }
2376 }
2377 }
2378 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
2379 {
2380 root = root->GetSyntheticBitFieldChild(index, index, true);
2381 if (!root.get())
2382 {
2383 *first_unparsed = expression_cstr;
2384 *reason_to_stop = ValueObject::eNoSuchChild;
2385 *final_result = ValueObject::eInvalid;
2386 return 0;
2387 }
2388 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2389 {
2390 list->Append(root);
2391 *first_unparsed = end+1; // skip ]
2392 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2393 *final_result = ValueObject::eValueObjectList;
2394 return 1;
2395 }
2396 }
2397 }
2398 else // we have a low and a high index
2399 {
2400 char *end = NULL;
2401 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2402 if (!end || end != separator_position) // if something weird is in our way return an error
2403 {
2404 *first_unparsed = expression_cstr;
2405 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2406 *final_result = ValueObject::eInvalid;
2407 return 0;
2408 }
2409 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2410 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2411 {
2412 *first_unparsed = expression_cstr;
2413 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2414 *final_result = ValueObject::eInvalid;
2415 return 0;
2416 }
2417 if (index_lower > index_higher) // swap indices if required
2418 {
2419 unsigned long temp = index_lower;
2420 index_lower = index_higher;
2421 index_higher = temp;
2422 }
2423 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
2424 {
2425 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2426 if (!root.get())
2427 {
2428 *first_unparsed = expression_cstr;
2429 *reason_to_stop = ValueObject::eNoSuchChild;
2430 *final_result = ValueObject::eInvalid;
2431 return 0;
2432 }
2433 else
2434 {
2435 list->Append(root);
2436 *first_unparsed = end+1; // skip ]
2437 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2438 *final_result = ValueObject::eValueObjectList;
2439 return 1;
2440 }
2441 }
2442 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
2443 *what_next == ValueObject::eDereference &&
2444 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2445 {
2446 Error error;
2447 root = root->Dereference(error);
2448 if (error.Fail() || !root.get())
2449 {
2450 *first_unparsed = expression_cstr;
2451 *reason_to_stop = ValueObject::eDereferencingFailed;
2452 *final_result = ValueObject::eInvalid;
2453 return 0;
2454 }
2455 else
2456 {
2457 *what_next = ValueObject::eNothing;
2458 continue;
2459 }
2460 }
2461 else
2462 {
2463 for (int index = index_lower;
2464 index <= index_higher; index++)
2465 {
2466 ValueObjectSP child =
2467 root->GetChildAtIndex(index, true);
2468 list->Append(child);
2469 }
2470 *first_unparsed = end+1;
2471 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2472 *final_result = ValueObject::eValueObjectList;
2473 return index_higher-index_lower+1; // tell me number of items I added to the VOList
2474 }
2475 }
2476 break;
2477 }
2478 default: // some non-[ separator, or something entirely wrong, is in the way
2479 {
2480 *first_unparsed = expression_cstr;
2481 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2482 *final_result = ValueObject::eInvalid;
2483 return 0;
2484 break;
2485 }
2486 }
2487 }
2488}
2489
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002490void
Greg Clayton1d3afba2010-10-05 00:00:42 +00002491ValueObject::DumpValueObject
2492(
2493 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00002494 ValueObject *valobj,
2495 const char *root_valobj_name,
2496 uint32_t ptr_depth,
2497 uint32_t curr_depth,
2498 uint32_t max_depth,
2499 bool show_types,
2500 bool show_location,
2501 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00002502 lldb::DynamicValueType use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002503 bool scope_already_checked,
2504 bool flat_output
Greg Clayton1d3afba2010-10-05 00:00:42 +00002505)
2506{
Greg Clayton007d5be2011-05-30 00:49:24 +00002507 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002508 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002509 bool update_success = valobj->UpdateValueIfNeeded ();
2510
2511 if (update_success && use_dynamic != lldb::eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00002512 {
Jim Ingham2837b762011-05-04 03:43:18 +00002513 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00002514 if (dynamic_value)
2515 valobj = dynamic_value;
2516 }
2517
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002518 clang_type_t clang_type = valobj->GetClangType();
2519
Greg Clayton73b472d2010-10-27 03:32:59 +00002520 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002521 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00002522 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
2523 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002524
2525 const bool print_valobj = flat_output == false || has_value;
2526
2527 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002528 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002529 if (show_location)
2530 {
Jim Ingham6035b672011-03-31 00:19:25 +00002531 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002532 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002533
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002534 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002535
Greg Clayton7c8a9662010-11-02 01:50:16 +00002536 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00002537 if (show_types || (curr_depth == 0 && !flat_output))
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002538 s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
Greg Clayton1d3afba2010-10-05 00:00:42 +00002539
Greg Clayton1d3afba2010-10-05 00:00:42 +00002540
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002541 if (flat_output)
2542 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002543 // If we are showing types, also qualify the C++ base classes
2544 const bool qualify_cxx_base_classes = show_types;
2545 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002546 s.PutCString(" =");
2547 }
2548 else
2549 {
2550 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
2551 s.Printf ("%s =", name_cstr);
2552 }
2553
Jim Ingham6035b672011-03-31 00:19:25 +00002554 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002555 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002556 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002557 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002558 }
2559
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002560 const char *val_cstr = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00002561 const char *sum_cstr = NULL;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002562 SummaryFormat* entry = valobj->GetSummaryFormat().get();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002563
2564 if (err_cstr == NULL)
2565 {
Jim Ingham6035b672011-03-31 00:19:25 +00002566 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002567 err_cstr = valobj->GetError().AsCString();
2568 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002569
2570 if (err_cstr)
2571 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002572 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00002573 }
2574 else
2575 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002576 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002577 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002578 {
Enrico Granata4becb372011-06-29 22:27:15 +00002579
2580 sum_cstr = valobj->GetSummaryAsCString();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002581
Enrico Granata4becb372011-06-29 22:27:15 +00002582 // We must calculate this value in realtime because entry might alter this variable's value
2583 // (e.g. by saying ${var%fmt}) and render precached values useless
2584 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
2585 s.Printf(" %s", valobj->GetValueAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002586
Enrico Granata0a3958e2011-07-02 00:25:22 +00002587 if(sum_cstr)
2588 {
2589 // for some reason, using %@ (ObjC description) in a summary string, makes
2590 // us believe we need to reset ourselves, thus invalidating the content of
2591 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty
2592 // let us recalculate it!
2593 if (sum_cstr[0] == '\0')
2594 s.Printf(" %s", valobj->GetSummaryAsCString());
2595 else
2596 s.Printf(" %s", sum_cstr);
2597 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002598
2599 if (use_objc)
2600 {
Jim Ingham6035b672011-03-31 00:19:25 +00002601 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002602 if (object_desc)
2603 s.Printf(" %s\n", object_desc);
2604 else
Sean Callanan672ad942010-10-23 00:18:49 +00002605 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002606 return;
Enrico Granata0a3958e2011-07-02 00:25:22 +00002607 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002608 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002609
2610 if (curr_depth < max_depth)
2611 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002612 // We will show children for all concrete types. We won't show
2613 // pointer contents unless a pointer depth has been specified.
2614 // We won't reference contents unless the reference is the
2615 // root object (depth of zero).
2616 bool print_children = true;
2617
2618 // Use a new temporary pointer depth in case we override the
2619 // current pointer depth below...
2620 uint32_t curr_ptr_depth = ptr_depth;
2621
2622 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
2623 if (is_ptr || is_ref)
2624 {
2625 // We have a pointer or reference whose value is an address.
2626 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00002627 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00002628 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
2629 print_children = false;
2630
2631 else if (is_ref && curr_depth == 0)
2632 {
2633 // If this is the root object (depth is zero) that we are showing
2634 // and it is a reference, and no pointer depth has been supplied
2635 // print out what it references. Don't do this at deeper depths
2636 // otherwise we can end up with infinite recursion...
2637 curr_ptr_depth = 1;
2638 }
2639
2640 if (curr_ptr_depth == 0)
2641 print_children = false;
2642 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002643
Enrico Granata0a3958e2011-07-02 00:25:22 +00002644 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00002645 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002646 const uint32_t num_children = valobj->GetNumChildren();
2647 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002648 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002649 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002650 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002651 if (print_valobj)
2652 s.EOL();
2653 }
2654 else
2655 {
2656 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00002657 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002658 s.IndentMore();
2659 }
2660
2661 for (uint32_t idx=0; idx<num_children; ++idx)
2662 {
2663 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
2664 if (child_sp.get())
2665 {
2666 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002667 child_sp.get(),
2668 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00002669 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002670 curr_depth + 1,
2671 max_depth,
2672 show_types,
2673 show_location,
2674 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00002675 use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002676 true,
2677 flat_output);
2678 }
2679 }
2680
2681 if (!flat_output)
2682 {
2683 s.IndentLess();
2684 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002685 }
2686 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002687 else if (has_children)
2688 {
2689 // Aggregate, no children...
2690 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00002691 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002692 }
2693 else
2694 {
2695 if (print_valobj)
2696 s.EOL();
2697 }
2698
Greg Clayton1d3afba2010-10-05 00:00:42 +00002699 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002700 else
2701 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00002702 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002703 }
2704 }
2705 else
2706 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002707 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002708 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002709 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002710 }
2711 }
2712 }
2713 }
2714}
2715
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002716
2717ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00002718ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002719{
2720 ValueObjectSP valobj_sp;
2721
Jim Ingham6035b672011-03-31 00:19:25 +00002722 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002723 {
Jim Ingham6035b672011-03-31 00:19:25 +00002724 ExecutionContextScope *exe_scope = GetExecutionContextScope();
2725 if (exe_scope)
2726 {
2727 ExecutionContext exe_ctx;
2728 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002729
Jim Ingham6035b672011-03-31 00:19:25 +00002730 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002731
Jim Ingham6035b672011-03-31 00:19:25 +00002732 DataExtractor data;
2733 data.SetByteOrder (m_data.GetByteOrder());
2734 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002735
Greg Clayton644247c2011-07-07 01:59:51 +00002736 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002737
Jim Ingham58b59f92011-04-22 23:53:53 +00002738 valobj_sp = ValueObjectConstResult::Create (exe_scope,
2739 ast,
2740 GetClangType(),
2741 name,
2742 data);
Jim Ingham6035b672011-03-31 00:19:25 +00002743 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002744 }
Jim Ingham6035b672011-03-31 00:19:25 +00002745
2746 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002747 {
Jim Ingham58b59f92011-04-22 23:53:53 +00002748 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002749 }
2750 return valobj_sp;
2751}
2752
2753lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00002754ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002755{
Jim Ingham58b59f92011-04-22 23:53:53 +00002756 if (m_deref_valobj)
2757 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00002758
Greg Clayton54979cd2010-12-15 05:08:08 +00002759 const bool is_pointer_type = IsPointerType();
2760 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002761 {
2762 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +00002763 bool ignore_array_bounds = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002764
2765 std::string child_name_str;
2766 uint32_t child_byte_size = 0;
2767 int32_t child_byte_offset = 0;
2768 uint32_t child_bitfield_bit_size = 0;
2769 uint32_t child_bitfield_bit_offset = 0;
2770 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00002771 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002772 const bool transparent_pointers = false;
2773 clang::ASTContext *clang_ast = GetClangAST();
2774 clang_type_t clang_type = GetClangType();
2775 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00002776
2777 ExecutionContext exe_ctx;
2778 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
2779
2780 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
2781 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002782 GetName().GetCString(),
2783 clang_type,
2784 0,
2785 transparent_pointers,
2786 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00002787 ignore_array_bounds,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002788 child_name_str,
2789 child_byte_size,
2790 child_byte_offset,
2791 child_bitfield_bit_size,
2792 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002793 child_is_base_class,
2794 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00002795 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002796 {
2797 ConstString child_name;
2798 if (!child_name_str.empty())
2799 child_name.SetCString (child_name_str.c_str());
2800
Jim Ingham58b59f92011-04-22 23:53:53 +00002801 m_deref_valobj = new ValueObjectChild (*this,
2802 clang_ast,
2803 child_clang_type,
2804 child_name,
2805 child_byte_size,
2806 child_byte_offset,
2807 child_bitfield_bit_size,
2808 child_bitfield_bit_offset,
2809 child_is_base_class,
2810 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002811 }
2812 }
Greg Clayton54979cd2010-12-15 05:08:08 +00002813
Jim Ingham58b59f92011-04-22 23:53:53 +00002814 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00002815 {
2816 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00002817 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00002818 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002819 else
2820 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002821 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002822 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002823
2824 if (is_pointer_type)
2825 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
2826 else
2827 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00002828 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002829 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002830}
2831
Jim Ingham78a685a2011-04-16 00:01:13 +00002832lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00002833ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002834{
Jim Ingham78a685a2011-04-16 00:01:13 +00002835 if (m_addr_of_valobj_sp)
2836 return m_addr_of_valobj_sp;
2837
Greg Claytone0d378b2011-03-24 21:19:54 +00002838 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002839 const bool scalar_is_load_address = false;
2840 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00002841 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002842 if (addr != LLDB_INVALID_ADDRESS)
2843 {
2844 switch (address_type)
2845 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002846 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002847 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00002848 {
2849 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002850 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002851 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
2852 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002853 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002854
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002855 case eAddressTypeFile:
2856 case eAddressTypeLoad:
2857 case eAddressTypeHost:
2858 {
2859 clang::ASTContext *ast = GetClangAST();
2860 clang_type_t clang_type = GetClangType();
2861 if (ast && clang_type)
2862 {
2863 std::string name (1, '&');
2864 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00002865 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
2866 ast,
2867 ClangASTContext::CreatePointerType (ast, clang_type),
2868 ConstString (name.c_str()),
2869 addr,
2870 eAddressTypeInvalid,
2871 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002872 }
2873 }
2874 break;
2875 }
2876 }
Jim Ingham78a685a2011-04-16 00:01:13 +00002877 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002878}
2879
Greg Claytonb2dcc362011-05-05 23:32:56 +00002880
2881lldb::ValueObjectSP
2882ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
2883{
2884 lldb::ValueObjectSP valobj_sp;
2885 AddressType address_type;
2886 const bool scalar_is_load_address = true;
2887 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2888
2889 if (ptr_value != LLDB_INVALID_ADDRESS)
2890 {
2891 Address ptr_addr (NULL, ptr_value);
2892
2893 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2894 name,
2895 ptr_addr,
2896 clang_ast_type);
2897 }
2898 return valobj_sp;
2899}
2900
2901lldb::ValueObjectSP
2902ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
2903{
2904 lldb::ValueObjectSP valobj_sp;
2905 AddressType address_type;
2906 const bool scalar_is_load_address = true;
2907 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2908
2909 if (ptr_value != LLDB_INVALID_ADDRESS)
2910 {
2911 Address ptr_addr (NULL, ptr_value);
2912
2913 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2914 name,
2915 ptr_addr,
2916 type_sp);
2917 }
2918 return valobj_sp;
2919}
2920
2921
Jim Ingham6035b672011-03-31 00:19:25 +00002922ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00002923 m_thread_id (LLDB_INVALID_UID),
2924 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00002925{
2926}
2927
2928ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00002929 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002930 m_first_update (true),
Jim Ingham89b61092011-07-06 17:42:14 +00002931 m_thread_id (LLDB_INVALID_THREAD_ID),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002932 m_stop_id (0)
2933
Jim Ingham6035b672011-03-31 00:19:25 +00002934{
2935 ExecutionContext exe_ctx;
2936 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
2937 // and if so we want to cache that not the original.
2938 if (exe_scope)
2939 exe_scope->CalculateExecutionContext(exe_ctx);
2940 if (exe_ctx.target != NULL)
2941 {
2942 m_target_sp = exe_ctx.target->GetSP();
2943
2944 if (exe_ctx.process == NULL)
2945 m_process_sp = exe_ctx.target->GetProcessSP();
2946 else
2947 m_process_sp = exe_ctx.process->GetSP();
2948
2949 if (m_process_sp != NULL)
2950 {
2951 m_stop_id = m_process_sp->GetStopID();
2952 Thread *thread = NULL;
2953
2954 if (exe_ctx.thread == NULL)
2955 {
2956 if (use_selected)
2957 {
2958 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
2959 if (thread)
2960 computed_exe_scope = thread;
2961 }
2962 }
2963 else
2964 thread = exe_ctx.thread;
2965
2966 if (thread != NULL)
2967 {
2968 m_thread_id = thread->GetIndexID();
2969 if (exe_ctx.frame == NULL)
2970 {
2971 if (use_selected)
2972 {
2973 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
2974 if (frame)
2975 {
2976 m_stack_id = frame->GetStackID();
2977 computed_exe_scope = frame;
2978 }
2979 }
2980 }
2981 else
2982 m_stack_id = exe_ctx.frame->GetStackID();
2983 }
2984 }
2985 }
2986 m_exe_scope = computed_exe_scope;
2987}
2988
2989ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
2990 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002991 m_needs_update(true),
2992 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00002993 m_target_sp (rhs.m_target_sp),
2994 m_process_sp (rhs.m_process_sp),
2995 m_thread_id (rhs.m_thread_id),
2996 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00002997 m_stop_id (0)
2998{
2999}
3000
3001ValueObject::EvaluationPoint::~EvaluationPoint ()
3002{
3003}
3004
3005ExecutionContextScope *
3006ValueObject::EvaluationPoint::GetExecutionContextScope ()
3007{
3008 // We have to update before giving out the scope, or we could be handing out stale pointers.
3009 SyncWithProcessState();
3010
3011 return m_exe_scope;
3012}
3013
3014// This function checks the EvaluationPoint against the current process state. If the current
3015// state matches the evaluation point, or the evaluation point is already invalid, then we return
3016// false, meaning "no change". If the current state is different, we update our state, and return
3017// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
3018// future calls to NeedsUpdate will return true.
3019
3020bool
3021ValueObject::EvaluationPoint::SyncWithProcessState()
3022{
3023 // If we're already invalid, we don't need to do anything, and nothing has changed:
3024 if (m_stop_id == LLDB_INVALID_UID)
3025 {
3026 // Can't update with an invalid state.
3027 m_needs_update = false;
3028 return false;
3029 }
3030
3031 // If we don't have a process nothing can change.
3032 if (!m_process_sp)
3033 return false;
3034
3035 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00003036 uint32_t cur_stop_id = m_process_sp->GetStopID();
3037 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00003038 return false;
3039
Jim Ingham78a685a2011-04-16 00:01:13 +00003040 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
3041 // In either case, we aren't going to be able to sync with the process state.
3042 if (cur_stop_id == 0)
3043 return false;
3044
3045 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00003046 m_needs_update = true;
3047 m_exe_scope = m_process_sp.get();
3048
3049 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
3050 // doesn't, mark ourselves as invalid.
3051
3052 if (m_thread_id != LLDB_INVALID_THREAD_ID)
3053 {
3054 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
3055 if (our_thread == NULL)
Greg Clayton262f80d2011-07-06 16:49:27 +00003056 {
Jim Ingham89b61092011-07-06 17:42:14 +00003057 SetInvalid();
Greg Clayton262f80d2011-07-06 16:49:27 +00003058 }
Jim Ingham6035b672011-03-31 00:19:25 +00003059 else
3060 {
3061 m_exe_scope = our_thread;
3062
3063 if (m_stack_id.IsValid())
3064 {
3065 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
3066 if (our_frame == NULL)
3067 SetInvalid();
3068 else
3069 m_exe_scope = our_frame;
3070 }
3071 }
3072 }
3073 return true;
3074}
3075
Jim Ingham61be0902011-05-02 18:13:59 +00003076void
3077ValueObject::EvaluationPoint::SetUpdated ()
3078{
3079 m_first_update = false;
3080 m_needs_update = false;
3081 if (m_process_sp)
3082 m_stop_id = m_process_sp->GetStopID();
3083}
3084
3085
Jim Ingham6035b672011-03-31 00:19:25 +00003086bool
3087ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
3088{
3089 if (!IsValid())
3090 return false;
3091
3092 bool needs_update = false;
3093 m_exe_scope = NULL;
3094
3095 // The target has to be non-null, and the
3096 Target *target = exe_scope->CalculateTarget();
3097 if (target != NULL)
3098 {
3099 Target *old_target = m_target_sp.get();
3100 assert (target == old_target);
3101 Process *process = exe_scope->CalculateProcess();
3102 if (process != NULL)
3103 {
3104 // FOR NOW - assume you can't update variable objects across process boundaries.
3105 Process *old_process = m_process_sp.get();
3106 assert (process == old_process);
3107
3108 lldb::user_id_t stop_id = process->GetStopID();
3109 if (stop_id != m_stop_id)
3110 {
3111 needs_update = true;
3112 m_stop_id = stop_id;
3113 }
3114 // See if we're switching the thread or stack context. If no thread is given, this is
3115 // being evaluated in a global context.
3116 Thread *thread = exe_scope->CalculateThread();
3117 if (thread != NULL)
3118 {
3119 lldb::user_id_t new_thread_index = thread->GetIndexID();
3120 if (new_thread_index != m_thread_id)
3121 {
3122 needs_update = true;
3123 m_thread_id = new_thread_index;
3124 m_stack_id.Clear();
3125 }
3126
3127 StackFrame *new_frame = exe_scope->CalculateStackFrame();
3128 if (new_frame != NULL)
3129 {
3130 if (new_frame->GetStackID() != m_stack_id)
3131 {
3132 needs_update = true;
3133 m_stack_id = new_frame->GetStackID();
3134 }
3135 }
3136 else
3137 {
3138 m_stack_id.Clear();
3139 needs_update = true;
3140 }
3141 }
3142 else
3143 {
3144 // If this had been given a thread, and now there is none, we should update.
3145 // Otherwise we don't have to do anything.
3146 if (m_thread_id != LLDB_INVALID_UID)
3147 {
3148 m_thread_id = LLDB_INVALID_UID;
3149 m_stack_id.Clear();
3150 needs_update = true;
3151 }
3152 }
3153 }
3154 else
3155 {
3156 // If there is no process, then we don't need to update anything.
3157 // But if we're switching from having a process to not, we should try to update.
3158 if (m_process_sp.get() != NULL)
3159 {
3160 needs_update = true;
3161 m_process_sp.reset();
3162 m_thread_id = LLDB_INVALID_UID;
3163 m_stack_id.Clear();
3164 }
3165 }
3166 }
3167 else
3168 {
3169 // If there's no target, nothing can change so we don't need to update anything.
3170 // But if we're switching from having a target to not, we should try to update.
3171 if (m_target_sp.get() != NULL)
3172 {
3173 needs_update = true;
3174 m_target_sp.reset();
3175 m_process_sp.reset();
3176 m_thread_id = LLDB_INVALID_UID;
3177 m_stack_id.Clear();
3178 }
3179 }
3180 if (!m_needs_update)
3181 m_needs_update = needs_update;
3182
3183 return needs_update;
3184}
Enrico Granataf2bbf712011-07-15 02:26:42 +00003185
3186void
3187ValueObject::ClearUserVisibleData()
3188{
3189 m_location_str.clear();
3190 m_value_str.clear();
3191 m_summary_str.clear();
3192 m_object_desc_str.clear();
3193}