blob: 1ab72c8005bfa56f276cb7fe19b7aac234579eaa [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ValueObject.cpp -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/ValueObject.h"
11
12// C Includes
Greg Claytonf5e56de2010-09-14 23:36:40 +000013#include <stdlib.h>
14
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015// C++ Includes
16// Other libraries and framework includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "llvm/Support/raw_ostream.h"
Jim Ingham5a369122010-09-28 01:25:32 +000018#include "clang/AST/Type.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019
20// Project includes
21#include "lldb/Core/DataBufferHeap.h"
Enrico Granata4becb372011-06-29 22:27:15 +000022#include "lldb/Core/Debugger.h"
Enrico Granata6f3533f2011-07-29 19:53:35 +000023#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Core/StreamString.h"
25#include "lldb/Core/ValueObjectChild.h"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000026#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000027#include "lldb/Core/ValueObjectDynamicValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Core/ValueObjectList.h"
Greg Claytonb2dcc362011-05-05 23:32:56 +000029#include "lldb/Core/ValueObjectMemory.h"
Enrico Granatad55546b2011-07-22 00:16:08 +000030#include "lldb/Core/ValueObjectSyntheticFilter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031
Greg Clayton7fb56d02011-02-01 01:31:41 +000032#include "lldb/Host/Endian.h"
33
Enrico Granataf2bbf712011-07-15 02:26:42 +000034#include "lldb/Interpreter/ScriptInterpreterPython.h"
35
Greg Claytone1a916a2010-07-21 22:12:05 +000036#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037#include "lldb/Symbol/ClangASTContext.h"
38#include "lldb/Symbol/Type.h"
39
Jim Ingham53c47f12010-09-10 23:12:17 +000040#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000041#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042#include "lldb/Target/Process.h"
43#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000044#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046
Enrico Granataf4efecd2011-07-12 22:56:10 +000047#include "lldb/Utility/RefCounter.h"
48
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049using namespace lldb;
50using namespace lldb_private;
Enrico Granataf4efecd2011-07-12 22:56:10 +000051using namespace lldb_utility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052
53static lldb::user_id_t g_value_obj_uid = 0;
54
55//----------------------------------------------------------------------
56// ValueObject constructor
57//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000058ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000060 m_parent (&parent),
Stephen Wilson71c21d12011-04-11 19:41:40 +000061 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062 m_name (),
63 m_data (),
64 m_value (),
65 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000066 m_value_str (),
67 m_old_value_str (),
68 m_location_str (),
69 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000070 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000071 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000072 m_children (),
73 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000074 m_dynamic_value (NULL),
Enrico Granatad55546b2011-07-22 00:16:08 +000075 m_synthetic_value(NULL),
Jim Ingham58b59f92011-04-22 23:53:53 +000076 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000077 m_format (eFormatDefault),
Enrico Granata9df29e32011-07-19 20:57:44 +000078 m_last_format_mgr_revision(0),
79 m_last_summary_format(),
80 m_forced_summary_format(),
81 m_last_value_format(),
Enrico Granatad55546b2011-07-22 00:16:08 +000082 m_last_synthetic_filter(),
Enrico Granata9df29e32011-07-19 20:57:44 +000083 m_user_id_of_forced_summary(0),
Greg Clayton288bdf92010-09-02 02:59:18 +000084 m_value_is_valid (false),
85 m_value_did_change (false),
86 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000087 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000088 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +000089 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +000090 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +000091 m_is_bitfield_for_scalar(false),
Enrico Granatad55546b2011-07-22 00:16:08 +000092 m_is_expression_path_child(false),
Enrico Granata6f3533f2011-07-29 19:53:35 +000093 m_is_child_at_offset(false),
Enrico Granataf4efecd2011-07-12 22:56:10 +000094 m_dump_printable_counter(0)
Jim Ingham6035b672011-03-31 00:19:25 +000095{
Jim Ingham58b59f92011-04-22 23:53:53 +000096 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +000097}
98
99//----------------------------------------------------------------------
100// ValueObject constructor
101//----------------------------------------------------------------------
102ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
103 UserID (++g_value_obj_uid), // Unique identifier for every value object
104 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000105 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +0000106 m_name (),
107 m_data (),
108 m_value (),
109 m_error (),
110 m_value_str (),
111 m_old_value_str (),
112 m_location_str (),
113 m_summary_str (),
114 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000115 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +0000116 m_children (),
117 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000118 m_dynamic_value (NULL),
Enrico Granatad55546b2011-07-22 00:16:08 +0000119 m_synthetic_value(NULL),
Jim Ingham58b59f92011-04-22 23:53:53 +0000120 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +0000121 m_format (eFormatDefault),
Enrico Granata9df29e32011-07-19 20:57:44 +0000122 m_last_format_mgr_revision(0),
123 m_last_summary_format(),
124 m_forced_summary_format(),
125 m_last_value_format(),
Enrico Granatad55546b2011-07-22 00:16:08 +0000126 m_last_synthetic_filter(),
Enrico Granata9df29e32011-07-19 20:57:44 +0000127 m_user_id_of_forced_summary(0),
Jim Ingham6035b672011-03-31 00:19:25 +0000128 m_value_is_valid (false),
129 m_value_did_change (false),
130 m_children_count_valid (false),
131 m_old_value_valid (false),
132 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +0000133 m_is_deref_of_parent (false),
Enrico Granata0a3958e2011-07-02 00:25:22 +0000134 m_is_array_item_for_pointer(false),
Enrico Granata9fc19442011-07-06 02:13:41 +0000135 m_is_bitfield_for_scalar(false),
Enrico Granatad55546b2011-07-22 00:16:08 +0000136 m_is_expression_path_child(false),
Enrico Granata6f3533f2011-07-29 19:53:35 +0000137 m_is_child_at_offset(false),
Enrico Granataf4efecd2011-07-12 22:56:10 +0000138 m_dump_printable_counter(0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139{
Jim Ingham58b59f92011-04-22 23:53:53 +0000140 m_manager = new ValueObjectManager();
141 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000142}
143
144//----------------------------------------------------------------------
145// Destructor
146//----------------------------------------------------------------------
147ValueObject::~ValueObject ()
148{
149}
150
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151bool
Enrico Granata0a3958e2011-07-02 00:25:22 +0000152ValueObject::UpdateValueIfNeeded (bool update_format)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153{
Enrico Granata4becb372011-06-29 22:27:15 +0000154
Enrico Granata0a3958e2011-07-02 00:25:22 +0000155 if (update_format)
156 UpdateFormatsIfNeeded();
Enrico Granata4becb372011-06-29 22:27:15 +0000157
Greg Claytonb71f3842010-10-05 03:13:51 +0000158 // If this is a constant value, then our success is predicated on whether
159 // we have an error or not
160 if (GetIsConstant())
161 return m_error.Success();
162
Jim Ingham6035b672011-03-31 00:19:25 +0000163 bool first_update = m_update_point.IsFirstEvaluation();
164
165 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166 {
Jim Ingham6035b672011-03-31 00:19:25 +0000167 m_update_point.SetUpdated();
168
169 // Save the old value using swap to avoid a string copy which
170 // also will clear our m_value_str
171 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172 {
Jim Ingham6035b672011-03-31 00:19:25 +0000173 m_old_value_valid = false;
174 }
175 else
176 {
177 m_old_value_valid = true;
178 m_old_value_str.swap (m_value_str);
179 m_value_str.clear();
180 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181
Enrico Granataf2bbf712011-07-15 02:26:42 +0000182 ClearUserVisibleData();
183
Jim Ingham6035b672011-03-31 00:19:25 +0000184 const bool value_was_valid = GetValueIsValid();
185 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000186
Jim Ingham6035b672011-03-31 00:19:25 +0000187 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000188
Jim Ingham6035b672011-03-31 00:19:25 +0000189 // Call the pure virtual function to update the value
190 bool success = UpdateValue ();
191
192 SetValueIsValid (success);
193
194 if (first_update)
195 SetValueDidChange (false);
196 else if (!m_value_did_change && success == false)
197 {
198 // The value wasn't gotten successfully, so we mark this
199 // as changed if the value used to be valid and now isn't
200 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201 }
202 }
203 return m_error.Success();
204}
205
Enrico Granata4becb372011-06-29 22:27:15 +0000206void
207ValueObject::UpdateFormatsIfNeeded()
208{
Enrico Granata6f3533f2011-07-29 19:53:35 +0000209 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
210 if (log)
211 log->Printf("checking for FormatManager revisions. VO named %s is at revision %d, while the format manager is at revision %d",
212 GetName().GetCString(),
Enrico Granata4becb372011-06-29 22:27:15 +0000213 m_last_format_mgr_revision,
Enrico Granata6f3533f2011-07-29 19:53:35 +0000214 Debugger::Formatting::ValueFormats::GetCurrentRevision());
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000215 if (HasCustomSummaryFormat() && m_update_point.GetUpdateID() != m_user_id_of_forced_summary)
216 {
217 ClearCustomSummaryFormat();
218 m_summary_str.clear();
219 }
Enrico Granata1490c6f2011-07-19 02:34:21 +0000220 if (m_last_format_mgr_revision != Debugger::Formatting::ValueFormats::GetCurrentRevision())
Enrico Granata4becb372011-06-29 22:27:15 +0000221 {
222 if (m_last_summary_format.get())
Enrico Granataf2bbf712011-07-15 02:26:42 +0000223 m_last_summary_format.reset((StringSummaryFormat*)NULL);
Enrico Granata4becb372011-06-29 22:27:15 +0000224 if (m_last_value_format.get())
Enrico Granatad55546b2011-07-22 00:16:08 +0000225 m_last_value_format.reset(/*(ValueFormat*)NULL*/);
226 if (m_last_synthetic_filter.get())
227 m_last_synthetic_filter.reset(/*(SyntheticFilter*)NULL*/);
Enrico Granataa37a0652011-07-24 00:14:56 +0000228
229 m_synthetic_value = NULL;
Enrico Granata1490c6f2011-07-19 02:34:21 +0000230
Enrico Granatad55546b2011-07-22 00:16:08 +0000231 Debugger::Formatting::ValueFormats::Get(*this, m_last_value_format);
Enrico Granata1490c6f2011-07-19 02:34:21 +0000232 Debugger::Formatting::GetSummaryFormat(*this, m_last_summary_format);
Enrico Granatad55546b2011-07-22 00:16:08 +0000233 Debugger::Formatting::GetSyntheticFilter(*this, m_last_synthetic_filter);
Enrico Granata1490c6f2011-07-19 02:34:21 +0000234
235 m_last_format_mgr_revision = Debugger::Formatting::ValueFormats::GetCurrentRevision();
Enrico Granataf2bbf712011-07-15 02:26:42 +0000236
237 ClearUserVisibleData();
Enrico Granata4becb372011-06-29 22:27:15 +0000238 }
239}
240
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000241DataExtractor &
242ValueObject::GetDataExtractor ()
243{
Jim Ingham78a685a2011-04-16 00:01:13 +0000244 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 return m_data;
246}
247
248const Error &
Greg Clayton262f80d2011-07-06 16:49:27 +0000249ValueObject::GetError()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250{
Greg Clayton262f80d2011-07-06 16:49:27 +0000251 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252 return m_error;
253}
254
255const ConstString &
256ValueObject::GetName() const
257{
258 return m_name;
259}
260
261const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000262ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263{
Jim Ingham6035b672011-03-31 00:19:25 +0000264 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265 {
266 if (m_location_str.empty())
267 {
268 StreamString sstr;
269
270 switch (m_value.GetValueType())
271 {
272 default:
273 break;
274
275 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000276 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277 {
278 RegisterInfo *reg_info = m_value.GetRegisterInfo();
279 if (reg_info)
280 {
281 if (reg_info->name)
282 m_location_str = reg_info->name;
283 else if (reg_info->alt_name)
284 m_location_str = reg_info->alt_name;
285 break;
286 }
287 }
288 m_location_str = "scalar";
289 break;
290
291 case Value::eValueTypeLoadAddress:
292 case Value::eValueTypeFileAddress:
293 case Value::eValueTypeHostAddress:
294 {
295 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
296 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
297 m_location_str.swap(sstr.GetString());
298 }
299 break;
300 }
301 }
302 }
303 return m_location_str.c_str();
304}
305
306Value &
307ValueObject::GetValue()
308{
309 return m_value;
310}
311
312const Value &
313ValueObject::GetValue() const
314{
315 return m_value;
316}
317
318bool
Jim Ingham6035b672011-03-31 00:19:25 +0000319ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000320{
321 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000322 ExecutionContextScope *exe_scope = GetExecutionContextScope();
323 if (exe_scope)
324 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000325 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
326 return scalar.IsValid();
327}
328
329bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000330ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331{
Greg Clayton288bdf92010-09-02 02:59:18 +0000332 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333}
334
335
336void
337ValueObject::SetValueIsValid (bool b)
338{
Greg Clayton288bdf92010-09-02 02:59:18 +0000339 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340}
341
342bool
Jim Ingham6035b672011-03-31 00:19:25 +0000343ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344{
Jim Ingham6035b672011-03-31 00:19:25 +0000345 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000346 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347}
348
349void
350ValueObject::SetValueDidChange (bool value_changed)
351{
Greg Clayton288bdf92010-09-02 02:59:18 +0000352 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353}
354
355ValueObjectSP
356ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
357{
358 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000359 // We may need to update our value if we are dynamic
360 if (IsPossibleDynamicType ())
361 UpdateValueIfNeeded();
362 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000364 // Check if we have already made the child value object?
365 if (can_create && m_children[idx] == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000367 // No we haven't created the child at this index, so lets have our
368 // subclass do it and cache the result for quick future access.
369 m_children[idx] = CreateChildAtIndex (idx, false, 0);
Jim Ingham78a685a2011-04-16 00:01:13 +0000370 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000371
372 if (m_children[idx] != NULL)
373 return m_children[idx]->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374 }
375 return child_sp;
376}
377
378uint32_t
379ValueObject::GetIndexOfChildWithName (const ConstString &name)
380{
381 bool omit_empty_base_classes = true;
382 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000383 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000384 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385 omit_empty_base_classes);
386}
387
388ValueObjectSP
389ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
390{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000391 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392 // classes (which really aren't part of the expression path), so we
393 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000395
Greg Claytondea8cb42011-06-29 22:09:02 +0000396 // We may need to update our value if we are dynamic
397 if (IsPossibleDynamicType ())
398 UpdateValueIfNeeded();
399
400 std::vector<uint32_t> child_indexes;
401 clang::ASTContext *clang_ast = GetClangAST();
402 void *clang_type = GetClangType();
403 bool omit_empty_base_classes = true;
404 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
405 clang_type,
406 name.GetCString(),
407 omit_empty_base_classes,
408 child_indexes);
409 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000411 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
412 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
413
414 child_sp = GetChildAtIndex(*pos, can_create);
415 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000417 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000418 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000419 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
420 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000421 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000422 else
423 {
424 child_sp.reset();
425 }
426
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427 }
428 }
429 return child_sp;
430}
431
432
433uint32_t
434ValueObject::GetNumChildren ()
435{
Greg Clayton288bdf92010-09-02 02:59:18 +0000436 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437 {
438 SetNumChildren (CalculateNumChildren());
439 }
440 return m_children.size();
441}
442void
443ValueObject::SetNumChildren (uint32_t num_children)
444{
Greg Clayton288bdf92010-09-02 02:59:18 +0000445 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446 m_children.resize(num_children);
447}
448
449void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450ValueObject::SetName (const ConstString &name)
451{
452 m_name = name;
453}
454
Jim Ingham58b59f92011-04-22 23:53:53 +0000455ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
457{
Jim Ingham2eec4872011-05-07 00:10:58 +0000458 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000459
Greg Claytondea8cb42011-06-29 22:09:02 +0000460 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +0000461 bool ignore_array_bounds = synthetic_array_member;
Greg Claytondea8cb42011-06-29 22:09:02 +0000462 std::string child_name_str;
463 uint32_t child_byte_size = 0;
464 int32_t child_byte_offset = 0;
465 uint32_t child_bitfield_bit_size = 0;
466 uint32_t child_bitfield_bit_offset = 0;
467 bool child_is_base_class = false;
468 bool child_is_deref_of_parent = false;
469
470 const bool transparent_pointers = synthetic_array_member == false;
471 clang::ASTContext *clang_ast = GetClangAST();
472 clang_type_t clang_type = GetClangType();
473 clang_type_t child_clang_type;
474
475 ExecutionContext exe_ctx;
476 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
477
478 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
479 clang_ast,
480 GetName().GetCString(),
481 clang_type,
482 idx,
483 transparent_pointers,
484 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +0000485 ignore_array_bounds,
Greg Claytondea8cb42011-06-29 22:09:02 +0000486 child_name_str,
487 child_byte_size,
488 child_byte_offset,
489 child_bitfield_bit_size,
490 child_bitfield_bit_offset,
491 child_is_base_class,
492 child_is_deref_of_parent);
493 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000495 if (synthetic_index)
496 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000497
Greg Claytondea8cb42011-06-29 22:09:02 +0000498 ConstString child_name;
499 if (!child_name_str.empty())
500 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000501
Greg Claytondea8cb42011-06-29 22:09:02 +0000502 valobj = new ValueObjectChild (*this,
503 clang_ast,
504 child_clang_type,
505 child_name,
506 child_byte_size,
507 child_byte_offset,
508 child_bitfield_bit_size,
509 child_bitfield_bit_offset,
510 child_is_base_class,
511 child_is_deref_of_parent);
512 if (m_pointers_point_to_load_addrs)
513 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000515
Jim Ingham58b59f92011-04-22 23:53:53 +0000516 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517}
518
519const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000520ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521{
Jim Ingham6035b672011-03-31 00:19:25 +0000522 if (UpdateValueIfNeeded ())
Enrico Granata4becb372011-06-29 22:27:15 +0000523 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524 if (m_summary_str.empty())
525 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000526 SummaryFormat *summary_format = GetSummaryFormat().get();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000527
528 if (summary_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000529 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000530 m_summary_str = summary_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000531 }
Enrico Granataf2bbf712011-07-15 02:26:42 +0000532 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000534 clang_type_t clang_type = GetClangType();
Greg Clayton737b9322010-09-13 03:32:57 +0000535
Enrico Granata9dd75c82011-07-15 23:30:15 +0000536 // Do some default printout for function pointers
Enrico Granataf2bbf712011-07-15 02:26:42 +0000537 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000538 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000539 StreamString sstr;
540 clang_type_t elem_or_pointee_clang_type;
541 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
542 GetClangAST(),
543 &elem_or_pointee_clang_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000544
Enrico Granataf2bbf712011-07-15 02:26:42 +0000545 ExecutionContextScope *exe_scope = GetExecutionContextScope();
546 if (exe_scope)
547 {
Enrico Granata9dd75c82011-07-15 23:30:15 +0000548 if (ClangASTContext::IsFunctionPointerType (clang_type))
Jim Ingham6035b672011-03-31 00:19:25 +0000549 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000550 AddressType func_ptr_address_type = eAddressTypeInvalid;
551 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
552
553 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
554 {
555 switch (func_ptr_address_type)
556 {
557 case eAddressTypeInvalid:
558 case eAddressTypeFile:
559 break;
560
561 case eAddressTypeLoad:
562 {
563 Address so_addr;
564 Target *target = exe_scope->CalculateTarget();
565 if (target && target->GetSectionLoadList().IsEmpty() == false)
566 {
567 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
568 {
569 so_addr.Dump (&sstr,
570 exe_scope,
571 Address::DumpStyleResolvedDescription,
572 Address::DumpStyleSectionNameOffset);
573 }
574 }
575 }
576 break;
577
578 case eAddressTypeHost:
579 break;
580 }
581 }
582 if (sstr.GetSize() > 0)
583 {
584 m_summary_str.assign (1, '(');
585 m_summary_str.append (sstr.GetData(), sstr.GetSize());
586 m_summary_str.append (1, ')');
587 }
Jim Ingham6035b672011-03-31 00:19:25 +0000588 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000589 }
590 }
591 }
592 }
593 }
594 if (m_summary_str.empty())
595 return NULL;
596 return m_summary_str.c_str();
597}
598
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000599bool
600ValueObject::IsCStringContainer(bool check_pointer)
601{
602 clang_type_t elem_or_pointee_clang_type;
603 const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(),
604 GetClangAST(),
605 &elem_or_pointee_clang_type));
606 bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
607 ClangASTContext::IsCharType (elem_or_pointee_clang_type));
608 if (!is_char_arr_ptr)
609 return false;
610 if (!check_pointer)
611 return true;
612 if (type_flags.Test(ClangASTContext::eTypeIsArray))
613 return true;
614 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
615 AddressType cstr_address_type = eAddressTypeInvalid;
616 cstr_address = GetAddressOf (cstr_address_type, true);
617 return (cstr_address != LLDB_INVALID_ADDRESS);
618}
619
620void
621ValueObject::ReadPointedString(Stream& s,
622 Error& error,
Enrico Granataf4efecd2011-07-12 22:56:10 +0000623 uint32_t max_length,
624 bool honor_array,
625 lldb::Format item_format)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000626{
627
628 if (max_length == 0)
Enrico Granataf4efecd2011-07-12 22:56:10 +0000629 max_length = 128; // FIXME this should be a setting, or a formatting parameter
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000630
631 clang_type_t clang_type = GetClangType();
632 clang_type_t elem_or_pointee_clang_type;
633 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
634 GetClangAST(),
635 &elem_or_pointee_clang_type));
636 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
637 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
638 {
639 ExecutionContextScope *exe_scope = GetExecutionContextScope();
640 if (exe_scope)
641 {
642 Target *target = exe_scope->CalculateTarget();
Enrico Granata6f3533f2011-07-29 19:53:35 +0000643 if (target == NULL)
644 {
645 s << "<no target to read from>";
646 }
647 else
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000648 {
649 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
650 AddressType cstr_address_type = eAddressTypeInvalid;
651
652 size_t cstr_len = 0;
653 bool capped_data = false;
654 if (type_flags.Test (ClangASTContext::eTypeIsArray))
655 {
656 // We have an array
657 cstr_len = ClangASTContext::GetArraySize (clang_type);
Enrico Granataf4efecd2011-07-12 22:56:10 +0000658 if (cstr_len > max_length)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000659 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000660 capped_data = true;
661 cstr_len = max_length;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000662 }
663 cstr_address = GetAddressOf (cstr_address_type, true);
664 }
665 else
666 {
667 // We have a pointer
668 cstr_address = GetPointerValue (cstr_address_type, true);
669 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000670 if (cstr_address == LLDB_INVALID_ADDRESS)
671 {
672 s << "<invalid address for data>";
673 }
674 else
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000675 {
676 Address cstr_so_addr (NULL, cstr_address);
677 DataExtractor data;
678 size_t bytes_read = 0;
679 std::vector<char> data_buffer;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000680 bool prefer_file_cache = false;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000681 if (cstr_len > 0 && honor_array)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000682 {
683 data_buffer.resize(cstr_len);
684 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
685 bytes_read = target->ReadMemory (cstr_so_addr,
686 prefer_file_cache,
687 &data_buffer.front(),
688 cstr_len,
689 error);
690 if (bytes_read > 0)
691 {
692 s << '"';
693 data.Dump (&s,
694 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000695 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000696 1, // Size of item (1 byte for a char!)
697 bytes_read, // How many bytes to print?
698 UINT32_MAX, // num per line
699 LLDB_INVALID_ADDRESS,// base address
700 0, // bitfield bit size
701 0); // bitfield bit offset
702 if (capped_data)
703 s << "...";
704 s << '"';
705 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000706 else
707 s << "\"<data not available>\"";
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000708 }
709 else
710 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000711 cstr_len = max_length;
712 const size_t k_max_buf_size = 64;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000713 data_buffer.resize (k_max_buf_size + 1);
714 // NULL terminate in case we don't get the entire C string
715 data_buffer.back() = '\0';
716
717 s << '"';
718
Enrico Granata6f3533f2011-07-29 19:53:35 +0000719 bool any_data = false;
720
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000721 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
722 while ((bytes_read = target->ReadMemory (cstr_so_addr,
723 prefer_file_cache,
724 &data_buffer.front(),
725 k_max_buf_size,
726 error)) > 0)
727 {
Enrico Granata6f3533f2011-07-29 19:53:35 +0000728 any_data = true;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000729 size_t len = strlen(&data_buffer.front());
730 if (len == 0)
731 break;
732 if (len > bytes_read)
733 len = bytes_read;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000734 if (len > cstr_len)
735 len = cstr_len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000736
737 data.Dump (&s,
738 0, // Start offset in "data"
Enrico Granataf4efecd2011-07-12 22:56:10 +0000739 item_format,
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000740 1, // Size of item (1 byte for a char!)
741 len, // How many bytes to print?
742 UINT32_MAX, // num per line
743 LLDB_INVALID_ADDRESS,// base address
744 0, // bitfield bit size
745 0); // bitfield bit offset
746
747 if (len < k_max_buf_size)
748 break;
Enrico Granataf4efecd2011-07-12 22:56:10 +0000749 if (len >= cstr_len)
750 {
751 s << "...";
752 break;
753 }
754 cstr_len -= len;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000755 cstr_so_addr.Slide (k_max_buf_size);
756 }
Enrico Granata6f3533f2011-07-29 19:53:35 +0000757
758 if (any_data == false)
759 s << "<data not available>";
760
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000761 s << '"';
762 }
763 }
764 }
765 }
766 }
767 else
768 {
769 error.SetErrorString("impossible to read a string from this object");
Enrico Granata6f3533f2011-07-29 19:53:35 +0000770 s << "<not a string object>";
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000771 }
772}
773
Jim Ingham53c47f12010-09-10 23:12:17 +0000774const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000775ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000776{
Enrico Granata0a3958e2011-07-02 00:25:22 +0000777
Jim Ingham6035b672011-03-31 00:19:25 +0000778 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000779 return NULL;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000780
781 if (!m_object_desc_str.empty())
782 return m_object_desc_str.c_str();
783
Jim Ingham6035b672011-03-31 00:19:25 +0000784 ExecutionContextScope *exe_scope = GetExecutionContextScope();
785 if (exe_scope == NULL)
786 return NULL;
787
Jim Ingham53c47f12010-09-10 23:12:17 +0000788 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000789 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000790 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000791
Jim Ingham53c47f12010-09-10 23:12:17 +0000792 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000793
794 lldb::LanguageType language = GetObjectRuntimeLanguage();
795 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
796
Jim Inghama2cf2632010-12-23 02:29:54 +0000797 if (runtime == NULL)
798 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000799 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000800 clang_type_t opaque_qual_type = GetClangType();
801 if (opaque_qual_type != NULL)
802 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000803 bool is_signed;
804 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
805 || ClangASTContext::IsPointerType (opaque_qual_type))
806 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000807 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000808 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000809 }
810 }
811
Jim Ingham8d543de2011-03-31 23:01:21 +0000812 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000813 {
814 m_object_desc_str.append (s.GetData());
815 }
Sean Callanan672ad942010-10-23 00:18:49 +0000816
817 if (m_object_desc_str.empty())
818 return NULL;
819 else
820 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000821}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000822
823const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000824ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000825{
826 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000827 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000828 {
Jim Ingham6035b672011-03-31 00:19:25 +0000829 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000830 {
831 if (m_value_str.empty())
832 {
833 const Value::ContextType context_type = m_value.GetContextType();
834
835 switch (context_type)
836 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000837 case Value::eContextTypeClangType:
838 case Value::eContextTypeLLDBType:
839 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000840 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000841 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842 if (clang_type)
843 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000844 if (m_last_value_format)
Enrico Granata4becb372011-06-29 22:27:15 +0000845 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000846 m_value_str = m_last_value_format->FormatObject(GetSP());
Enrico Granata4becb372011-06-29 22:27:15 +0000847 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000848 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000849 {
Enrico Granataf2bbf712011-07-15 02:26:42 +0000850 StreamString sstr;
851 Format format = GetFormat();
852 if (format == eFormatDefault)
853 format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
854 ClangASTType::GetFormat(clang_type));
855
856 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
857 clang_type, // The clang type to display
858 &sstr,
859 format, // Format to display this type with
860 m_data, // Data to extract from
861 0, // Byte offset into "m_data"
862 GetByteSize(), // Byte size of item in "m_data"
863 GetBitfieldBitSize(), // Bitfield bit size
864 GetBitfieldBitOffset())) // Bitfield bit offset
865 m_value_str.swap(sstr.GetString());
866 else
867 {
868 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
869 m_data.GetByteSize(),
870 GetByteSize());
871 m_value_str.clear();
872 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000873 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874 }
875 }
876 break;
877
Greg Clayton526e5af2010-11-13 03:52:47 +0000878 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000879 {
880 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
881 if (reg_info)
882 {
883 StreamString reg_sstr;
884 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
885 m_value_str.swap(reg_sstr.GetString());
886 }
887 }
888 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000889
890 default:
891 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892 }
893 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000894
895 if (!m_value_did_change && m_old_value_valid)
896 {
897 // The value was gotten successfully, so we consider the
898 // value as changed if the value string differs
899 SetValueDidChange (m_old_value_str != m_value_str);
900 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000901 }
902 }
903 if (m_value_str.empty())
904 return NULL;
905 return m_value_str.c_str();
906}
907
Enrico Granatae992a082011-07-22 17:03:19 +0000908// this call should only return pointers to data that needs no special memory management
909// (either because they are hardcoded strings, or because they are backed by some other
910// object); returning any new()-ed or malloc()-ed data here, will lead to leaks!
Enrico Granata0a3958e2011-07-02 00:25:22 +0000911const char *
912ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
913 lldb::Format custom_format)
914{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000915
916 RefCounter ref(&m_dump_printable_counter);
917
Enrico Granata9dd75c82011-07-15 23:30:15 +0000918 if (custom_format != lldb::eFormatInvalid)
Enrico Granata0a3958e2011-07-02 00:25:22 +0000919 SetFormat(custom_format);
920
921 const char * return_value;
922
923 switch(val_obj_display)
924 {
925 case eDisplayValue:
926 return_value = GetValueAsCString();
927 break;
928 case eDisplaySummary:
929 return_value = GetSummaryAsCString();
930 break;
931 case eDisplayLanguageSpecific:
932 return_value = GetObjectDescription();
933 break;
Enrico Granataf2bbf712011-07-15 02:26:42 +0000934 case eDisplayLocation:
935 return_value = GetLocationAsCString();
936 break;
Enrico Granata0a3958e2011-07-02 00:25:22 +0000937 }
938
Enrico Granataf4efecd2011-07-12 22:56:10 +0000939 // this code snippet might lead to endless recursion, thus we use a RefCounter here to
940 // check that we are not looping endlessly
941 if (!return_value && (m_dump_printable_counter < 3))
Enrico Granata9fc19442011-07-06 02:13:41 +0000942 {
943 // try to pick the other choice
944 if (val_obj_display == eDisplayValue)
945 return_value = GetSummaryAsCString();
946 else if (val_obj_display == eDisplaySummary)
Enrico Granatae992a082011-07-22 17:03:19 +0000947 {
948 if (ClangASTContext::IsAggregateType (GetClangType()) == true)
949 {
950 // this thing has no value
951 return_value = "<no summary defined for this datatype>";
952 }
953 else
954 return_value = GetValueAsCString();
955 }
Enrico Granata9fc19442011-07-06 02:13:41 +0000956 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000957
Enrico Granatae992a082011-07-22 17:03:19 +0000958 return (return_value ? return_value : "<no printable representation>");
Enrico Granata0a3958e2011-07-02 00:25:22 +0000959
960}
961
Enrico Granata9fc19442011-07-06 02:13:41 +0000962bool
963ValueObject::DumpPrintableRepresentation(Stream& s,
964 ValueObjectRepresentationStyle val_obj_display,
965 lldb::Format custom_format)
966{
Enrico Granataf4efecd2011-07-12 22:56:10 +0000967
968 clang_type_t elem_or_pointee_type;
969 Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000970
Enrico Granataf4efecd2011-07-12 22:56:10 +0000971 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
972 && val_obj_display == ValueObject::eDisplayValue)
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000973 {
Enrico Granataf4efecd2011-07-12 22:56:10 +0000974 // when being asked to get a printable display an array or pointer type directly,
975 // try to "do the right thing"
976
977 if (IsCStringContainer(true) &&
978 (custom_format == lldb::eFormatCString ||
979 custom_format == lldb::eFormatCharArray ||
980 custom_format == lldb::eFormatChar ||
981 custom_format == lldb::eFormatVectorOfChar)) // print char[] & char* directly
982 {
983 Error error;
984 ReadPointedString(s,
985 error,
986 0,
987 (custom_format == lldb::eFormatVectorOfChar) ||
988 (custom_format == lldb::eFormatCharArray));
989 return !error.Fail();
990 }
991
992 if (custom_format == lldb::eFormatEnum)
993 return false;
994
995 // this only works for arrays, because I have no way to know when
996 // the pointed memory ends, and no special \0 end of data marker
997 if (flags.Test(ClangASTContext::eTypeIsArray))
998 {
999 if ((custom_format == lldb::eFormatBytes) ||
1000 (custom_format == lldb::eFormatBytesWithASCII))
1001 {
1002 uint32_t count = GetNumChildren();
1003
1004 s << '[';
1005 for (uint32_t low = 0; low < count; low++)
1006 {
1007
1008 if (low)
1009 s << ',';
1010
1011 ValueObjectSP child = GetChildAtIndex(low,true);
1012 if (!child.get())
1013 {
Enrico Granatae992a082011-07-22 17:03:19 +00001014 s << "<invalid child>";
Enrico Granataf4efecd2011-07-12 22:56:10 +00001015 continue;
1016 }
1017 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format);
1018 }
1019
1020 s << ']';
1021
1022 return true;
1023 }
1024
1025 if ((custom_format == lldb::eFormatVectorOfChar) ||
1026 (custom_format == lldb::eFormatVectorOfFloat32) ||
1027 (custom_format == lldb::eFormatVectorOfFloat64) ||
1028 (custom_format == lldb::eFormatVectorOfSInt16) ||
1029 (custom_format == lldb::eFormatVectorOfSInt32) ||
1030 (custom_format == lldb::eFormatVectorOfSInt64) ||
1031 (custom_format == lldb::eFormatVectorOfSInt8) ||
1032 (custom_format == lldb::eFormatVectorOfUInt128) ||
1033 (custom_format == lldb::eFormatVectorOfUInt16) ||
1034 (custom_format == lldb::eFormatVectorOfUInt32) ||
1035 (custom_format == lldb::eFormatVectorOfUInt64) ||
1036 (custom_format == lldb::eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
1037 {
1038 uint32_t count = GetNumChildren();
1039
1040 lldb::Format format = FormatManager::GetSingleItemFormat(custom_format);
1041
1042 s << '[';
1043 for (uint32_t low = 0; low < count; low++)
1044 {
1045
1046 if (low)
1047 s << ',';
1048
1049 ValueObjectSP child = GetChildAtIndex(low,true);
1050 if (!child.get())
1051 {
Enrico Granatae992a082011-07-22 17:03:19 +00001052 s << "<invalid child>";
Enrico Granataf4efecd2011-07-12 22:56:10 +00001053 continue;
1054 }
1055 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format);
1056 }
1057
1058 s << ']';
1059
1060 return true;
1061 }
1062 }
1063
1064 if ((custom_format == lldb::eFormatBoolean) ||
1065 (custom_format == lldb::eFormatBinary) ||
1066 (custom_format == lldb::eFormatChar) ||
1067 (custom_format == lldb::eFormatCharPrintable) ||
1068 (custom_format == lldb::eFormatComplexFloat) ||
1069 (custom_format == lldb::eFormatDecimal) ||
1070 (custom_format == lldb::eFormatHex) ||
1071 (custom_format == lldb::eFormatFloat) ||
1072 (custom_format == lldb::eFormatOctal) ||
1073 (custom_format == lldb::eFormatOSType) ||
1074 (custom_format == lldb::eFormatUnicode16) ||
1075 (custom_format == lldb::eFormatUnicode32) ||
1076 (custom_format == lldb::eFormatUnsigned) ||
1077 (custom_format == lldb::eFormatPointer) ||
1078 (custom_format == lldb::eFormatComplexInteger) ||
1079 (custom_format == lldb::eFormatComplex) ||
1080 (custom_format == lldb::eFormatDefault)) // use the [] operator
1081 return false;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001082 }
Enrico Granataf4efecd2011-07-12 22:56:10 +00001083 const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
Enrico Granata9dd75c82011-07-15 23:30:15 +00001084 if (targetvalue)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001085 s.PutCString(targetvalue);
1086 bool var_success = (targetvalue != NULL);
Enrico Granata9dd75c82011-07-15 23:30:15 +00001087 if (custom_format != eFormatInvalid)
Enrico Granataf4efecd2011-07-12 22:56:10 +00001088 SetFormat(eFormatDefault);
1089 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001090}
1091
Greg Clayton737b9322010-09-13 03:32:57 +00001092addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001093ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +00001094{
Jim Ingham78a685a2011-04-16 00:01:13 +00001095 if (!UpdateValueIfNeeded())
1096 return LLDB_INVALID_ADDRESS;
1097
Greg Clayton73b472d2010-10-27 03:32:59 +00001098 switch (m_value.GetValueType())
1099 {
1100 case Value::eValueTypeScalar:
1101 if (scalar_is_load_address)
1102 {
1103 address_type = eAddressTypeLoad;
1104 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1105 }
1106 break;
1107
1108 case Value::eValueTypeLoadAddress:
1109 case Value::eValueTypeFileAddress:
1110 case Value::eValueTypeHostAddress:
1111 {
1112 address_type = m_value.GetValueAddressType ();
1113 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1114 }
1115 break;
1116 }
1117 address_type = eAddressTypeInvalid;
1118 return LLDB_INVALID_ADDRESS;
1119}
1120
1121addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +00001122ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +00001123{
1124 lldb::addr_t address = LLDB_INVALID_ADDRESS;
1125 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +00001126
1127 if (!UpdateValueIfNeeded())
1128 return address;
1129
Greg Clayton73b472d2010-10-27 03:32:59 +00001130 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +00001131 {
1132 case Value::eValueTypeScalar:
1133 if (scalar_is_load_address)
1134 {
1135 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1136 address_type = eAddressTypeLoad;
1137 }
1138 break;
1139
1140 case Value::eValueTypeLoadAddress:
1141 case Value::eValueTypeFileAddress:
1142 case Value::eValueTypeHostAddress:
1143 {
1144 uint32_t data_offset = 0;
1145 address = m_data.GetPointer(&data_offset);
1146 address_type = m_value.GetValueAddressType();
1147 if (address_type == eAddressTypeInvalid)
1148 address_type = eAddressTypeLoad;
1149 }
1150 break;
1151 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001152
1153 if (m_pointers_point_to_load_addrs)
1154 address_type = eAddressTypeLoad;
1155
Greg Clayton737b9322010-09-13 03:32:57 +00001156 return address;
1157}
1158
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001159bool
Jim Ingham6035b672011-03-31 00:19:25 +00001160ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001161{
1162 // Make sure our value is up to date first so that our location and location
1163 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +00001164 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001165 return false;
1166
1167 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001168 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001169
1170 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +00001171 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172 switch (encoding)
1173 {
1174 case eEncodingInvalid:
1175 return false;
1176
1177 case eEncodingUint:
1178 if (byte_size > sizeof(unsigned long long))
1179 {
1180 return false;
1181 }
1182 else
1183 {
1184 unsigned long long ull_val = strtoull(value_str, &end, 0);
1185 if (end && *end != '\0')
1186 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001187 m_value.GetScalar() = ull_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001188 // Limit the bytes in our m_data appropriately.
1189 m_value.GetScalar().GetData (m_data, byte_size);
1190 }
1191 break;
1192
1193 case eEncodingSint:
1194 if (byte_size > sizeof(long long))
1195 {
1196 return false;
1197 }
1198 else
1199 {
1200 long long sll_val = strtoll(value_str, &end, 0);
1201 if (end && *end != '\0')
1202 return false;
Greg Clayton644247c2011-07-07 01:59:51 +00001203 m_value.GetScalar() = sll_val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001204 // Limit the bytes in our m_data appropriately.
1205 m_value.GetScalar().GetData (m_data, byte_size);
1206 }
1207 break;
1208
1209 case eEncodingIEEE754:
1210 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001211 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +00001212 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001213 if (dst != NULL)
1214 {
1215 // We are decoding a float into host byte order below, so make
1216 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +00001217 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001218 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
1219 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +00001220 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001221 value_str,
1222 dst,
1223 byte_size);
1224
1225 if (converted_byte_size == byte_size)
1226 {
1227 }
1228 }
1229 }
1230 break;
1231
1232 case eEncodingVector:
1233 return false;
1234
1235 default:
1236 return false;
1237 }
1238
1239 // If we have made it here the value is in m_data and we should write it
1240 // out to the target
1241 return Write ();
1242}
1243
1244bool
1245ValueObject::Write ()
1246{
1247 // Clear the update ID so the next time we try and read the value
1248 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +00001249 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001250
1251 // TODO: when Value has a method to write a value back, call it from here.
1252 return false;
1253
1254}
1255
Jim Ingham5a369122010-09-28 01:25:32 +00001256lldb::LanguageType
1257ValueObject::GetObjectRuntimeLanguage ()
1258{
Greg Clayton73b472d2010-10-27 03:32:59 +00001259 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +00001260 if (opaque_qual_type == NULL)
1261 return lldb::eLanguageTypeC;
1262
1263 // If the type is a reference, then resolve it to what it refers to first:
1264 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
1265 if (qual_type->isAnyPointerType())
1266 {
1267 if (qual_type->isObjCObjectPointerType())
1268 return lldb::eLanguageTypeObjC;
1269
1270 clang::QualType pointee_type (qual_type->getPointeeType());
1271 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
1272 return lldb::eLanguageTypeC_plus_plus;
1273 if (pointee_type->isObjCObjectOrInterfaceType())
1274 return lldb::eLanguageTypeObjC;
1275 if (pointee_type->isObjCClassType())
1276 return lldb::eLanguageTypeObjC;
1277 }
1278 else
1279 {
1280 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
1281 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +00001282 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +00001283 return lldb::eLanguageTypeC_plus_plus;
1284 }
1285
1286 return lldb::eLanguageTypeC;
1287}
1288
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001289void
Jim Ingham58b59f92011-04-22 23:53:53 +00001290ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001291{
Jim Ingham58b59f92011-04-22 23:53:53 +00001292 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001293}
1294
1295ValueObjectSP
1296ValueObject::GetSyntheticChild (const ConstString &key) const
1297{
1298 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +00001299 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001300 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +00001301 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302 return synthetic_child_sp;
1303}
1304
1305bool
1306ValueObject::IsPointerType ()
1307{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001308 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001309}
1310
Jim Inghamb7603bb2011-03-18 00:05:18 +00001311bool
Greg Claytondaf515f2011-07-09 20:12:33 +00001312ValueObject::IsArrayType ()
1313{
1314 return ClangASTContext::IsArrayType (GetClangType());
1315}
1316
1317bool
Enrico Granata9fc19442011-07-06 02:13:41 +00001318ValueObject::IsScalarType ()
1319{
1320 return ClangASTContext::IsScalarType (GetClangType());
1321}
1322
1323bool
Jim Inghamb7603bb2011-03-18 00:05:18 +00001324ValueObject::IsIntegerType (bool &is_signed)
1325{
1326 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
1327}
Greg Clayton73b472d2010-10-27 03:32:59 +00001328
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001329bool
1330ValueObject::IsPointerOrReferenceType ()
1331{
Greg Clayton007d5be2011-05-30 00:49:24 +00001332 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
1333}
1334
1335bool
1336ValueObject::IsPossibleCPlusPlusDynamicType ()
1337{
1338 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001339}
1340
Greg Claytondea8cb42011-06-29 22:09:02 +00001341bool
1342ValueObject::IsPossibleDynamicType ()
1343{
1344 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
1345}
1346
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001347ValueObjectSP
1348ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
1349{
1350 ValueObjectSP synthetic_child_sp;
1351 if (IsPointerType ())
1352 {
1353 char index_str[64];
1354 snprintf(index_str, sizeof(index_str), "[%i]", index);
1355 ConstString index_const_str(index_str);
1356 // Check if we have already created a synthetic array member in this
1357 // valid object. If we have we will re-use it.
1358 synthetic_child_sp = GetSyntheticChild (index_const_str);
1359 if (!synthetic_child_sp)
1360 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001361 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001362 // We haven't made a synthetic array member for INDEX yet, so
1363 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001364 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001365
1366 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001367 if (synthetic_child)
1368 {
1369 AddSyntheticChild(index_const_str, synthetic_child);
1370 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001371 synthetic_child_sp->SetName(ConstString(index_str));
Enrico Granata0a3958e2011-07-02 00:25:22 +00001372 synthetic_child_sp->m_is_array_item_for_pointer = true;
Jim Ingham58b59f92011-04-22 23:53:53 +00001373 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001374 }
1375 }
1376 return synthetic_child_sp;
1377}
Jim Ingham22777012010-09-23 02:01:19 +00001378
Greg Claytondaf515f2011-07-09 20:12:33 +00001379// This allows you to create an array member using and index
1380// that doesn't not fall in the normal bounds of the array.
1381// Many times structure can be defined as:
1382// struct Collection
1383// {
1384// uint32_t item_count;
1385// Item item_array[0];
1386// };
1387// The size of the "item_array" is 1, but many times in practice
1388// there are more items in "item_array".
1389
1390ValueObjectSP
1391ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create)
1392{
1393 ValueObjectSP synthetic_child_sp;
1394 if (IsArrayType ())
1395 {
1396 char index_str[64];
1397 snprintf(index_str, sizeof(index_str), "[%i]", index);
1398 ConstString index_const_str(index_str);
1399 // Check if we have already created a synthetic array member in this
1400 // valid object. If we have we will re-use it.
1401 synthetic_child_sp = GetSyntheticChild (index_const_str);
1402 if (!synthetic_child_sp)
1403 {
1404 ValueObject *synthetic_child;
1405 // We haven't made a synthetic array member for INDEX yet, so
1406 // lets make one and cache it for any future reference.
1407 synthetic_child = CreateChildAtIndex(0, true, index);
1408
1409 // Cache the value if we got one back...
1410 if (synthetic_child)
1411 {
1412 AddSyntheticChild(index_const_str, synthetic_child);
1413 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001414 synthetic_child_sp->SetName(ConstString(index_str));
Greg Claytondaf515f2011-07-09 20:12:33 +00001415 synthetic_child_sp->m_is_array_item_for_pointer = true;
1416 }
1417 }
1418 }
1419 return synthetic_child_sp;
1420}
1421
Enrico Granata9fc19442011-07-06 02:13:41 +00001422ValueObjectSP
1423ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
1424{
1425 ValueObjectSP synthetic_child_sp;
1426 if (IsScalarType ())
1427 {
1428 char index_str[64];
1429 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1430 ConstString index_const_str(index_str);
1431 // Check if we have already created a synthetic array member in this
1432 // valid object. If we have we will re-use it.
1433 synthetic_child_sp = GetSyntheticChild (index_const_str);
1434 if (!synthetic_child_sp)
1435 {
1436 ValueObjectChild *synthetic_child;
1437 // We haven't made a synthetic array member for INDEX yet, so
1438 // lets make one and cache it for any future reference.
1439 synthetic_child = new ValueObjectChild(*this,
1440 GetClangAST(),
1441 GetClangType(),
1442 index_const_str,
1443 GetByteSize(),
1444 0,
1445 to-from+1,
1446 from,
1447 false,
1448 false);
1449
1450 // Cache the value if we got one back...
1451 if (synthetic_child)
1452 {
1453 AddSyntheticChild(index_const_str, synthetic_child);
1454 synthetic_child_sp = synthetic_child->GetSP();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001455 synthetic_child_sp->SetName(ConstString(index_str));
Enrico Granata9fc19442011-07-06 02:13:41 +00001456 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1457 }
1458 }
1459 }
1460 return synthetic_child_sp;
1461}
1462
Enrico Granata6f3533f2011-07-29 19:53:35 +00001463lldb::ValueObjectSP
1464ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
1465{
1466
1467 ValueObjectSP synthetic_child_sp;
1468
1469 char name_str[64];
1470 snprintf(name_str, sizeof(name_str), "@%i", offset);
1471 ConstString name_const_str(name_str);
1472
1473 // Check if we have already created a synthetic array member in this
1474 // valid object. If we have we will re-use it.
1475 synthetic_child_sp = GetSyntheticChild (name_const_str);
1476
1477 if (synthetic_child_sp.get())
1478 return synthetic_child_sp;
1479
1480 if (!can_create)
1481 return lldb::ValueObjectSP();
1482
1483 ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
1484 type.GetASTContext(),
1485 type.GetOpaqueQualType(),
1486 name_const_str,
1487 type.GetTypeByteSize(),
1488 offset,
1489 0,
1490 0,
1491 false,
1492 false);
1493 if (synthetic_child)
1494 {
1495 AddSyntheticChild(name_const_str, synthetic_child);
1496 synthetic_child_sp = synthetic_child->GetSP();
1497 synthetic_child_sp->SetName(name_const_str);
1498 synthetic_child_sp->m_is_child_at_offset = true;
1499 }
1500 return synthetic_child_sp;
1501}
1502
Enrico Granatad55546b2011-07-22 00:16:08 +00001503// your expression path needs to have a leading . or ->
1504// (unless it somehow "looks like" an array, in which case it has
1505// a leading [ symbol). while the [ is meaningful and should be shown
1506// to the user, . and -> are just parser design, but by no means
1507// added information for the user.. strip them off
1508static const char*
1509SkipLeadingExpressionPathSeparators(const char* expression)
1510{
1511 if (!expression || !expression[0])
1512 return expression;
1513 if (expression[0] == '.')
1514 return expression+1;
1515 if (expression[0] == '-' && expression[1] == '>')
1516 return expression+2;
1517 return expression;
1518}
1519
1520lldb::ValueObjectSP
1521ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_create)
1522{
1523 ValueObjectSP synthetic_child_sp;
1524 ConstString name_const_string(expression);
1525 // Check if we have already created a synthetic array member in this
1526 // valid object. If we have we will re-use it.
1527 synthetic_child_sp = GetSyntheticChild (name_const_string);
1528 if (!synthetic_child_sp)
1529 {
1530 // We haven't made a synthetic array member for expression yet, so
1531 // lets make one and cache it for any future reference.
1532 synthetic_child_sp = GetValueForExpressionPath(expression);
1533
1534 // Cache the value if we got one back...
1535 if (synthetic_child_sp.get())
1536 {
1537 AddSyntheticChild(name_const_string, synthetic_child_sp.get());
Enrico Granata6f3533f2011-07-29 19:53:35 +00001538 synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression)));
Enrico Granatad55546b2011-07-22 00:16:08 +00001539 synthetic_child_sp->m_is_expression_path_child = true;
1540 }
1541 }
1542 return synthetic_child_sp;
1543}
1544
1545void
1546ValueObject::CalculateSyntheticValue (lldb::SyntheticValueType use_synthetic)
1547{
1548 if (use_synthetic == lldb::eNoSyntheticFilter)
1549 return;
1550
1551 UpdateFormatsIfNeeded();
1552
1553 if (m_last_synthetic_filter.get() == NULL)
1554 return;
1555
Enrico Granataa37a0652011-07-24 00:14:56 +00001556 if (m_synthetic_value == NULL)
1557 m_synthetic_value = new ValueObjectSynthetic(*this, m_last_synthetic_filter);
Enrico Granatad55546b2011-07-22 00:16:08 +00001558
1559}
1560
Jim Ingham78a685a2011-04-16 00:01:13 +00001561void
Jim Ingham2837b762011-05-04 03:43:18 +00001562ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001563{
Jim Ingham2837b762011-05-04 03:43:18 +00001564 if (use_dynamic == lldb::eNoDynamicValues)
1565 return;
1566
Jim Ingham58b59f92011-04-22 23:53:53 +00001567 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001568 {
Enrico Granata6f3533f2011-07-29 19:53:35 +00001569 Process *process = m_update_point.GetProcessSP().get();
Jim Ingham78a685a2011-04-16 00:01:13 +00001570 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001571
Jim Ingham78a685a2011-04-16 00:01:13 +00001572
1573 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1574 // hard code this everywhere.
1575 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1576 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1577 {
1578 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1579 if (runtime)
1580 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1581 }
1582 else
1583 {
1584 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1585 if (cpp_runtime)
1586 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1587
1588 if (!worth_having_dynamic_value)
1589 {
1590 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1591 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001592 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001593 }
1594 }
1595
1596 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001597 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001598
1599// if (worth_having_dynamic_value)
1600// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1601
Jim Ingham78a685a2011-04-16 00:01:13 +00001602 }
1603}
1604
Jim Ingham58b59f92011-04-22 23:53:53 +00001605ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001606ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001607{
Jim Ingham2837b762011-05-04 03:43:18 +00001608 if (use_dynamic == lldb::eNoDynamicValues)
1609 return ValueObjectSP();
1610
1611 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001612 {
Jim Ingham2837b762011-05-04 03:43:18 +00001613 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001614 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001615 if (m_dynamic_value)
1616 return m_dynamic_value->GetSP();
1617 else
1618 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001619}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001620
Enrico Granatad55546b2011-07-22 00:16:08 +00001621// GetDynamicValue() returns a NULL SharedPointer if the object is not dynamic
1622// or we do not really want a dynamic VO. this method instead returns this object
1623// itself when making it synthetic has no meaning. this makes it much simpler
1624// to replace the SyntheticValue for the ValueObject
1625ValueObjectSP
1626ValueObject::GetSyntheticValue (SyntheticValueType use_synthetic)
1627{
1628 if (use_synthetic == lldb::eNoSyntheticFilter)
1629 return GetSP();
1630
1631 UpdateFormatsIfNeeded();
1632
1633 if (m_last_synthetic_filter.get() == NULL)
1634 return GetSP();
1635
1636 CalculateSyntheticValue(use_synthetic);
1637
1638 if (m_synthetic_value)
1639 return m_synthetic_value->GetSP();
1640 else
1641 return GetSP();
1642}
1643
Greg Claytone221f822011-01-21 01:59:00 +00001644bool
1645ValueObject::GetBaseClassPath (Stream &s)
1646{
1647 if (IsBaseClass())
1648 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001649 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001650 clang_type_t clang_type = GetClangType();
1651 std::string cxx_class_name;
1652 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1653 if (this_had_base_class)
1654 {
1655 if (parent_had_base_class)
1656 s.PutCString("::");
1657 s.PutCString(cxx_class_name.c_str());
1658 }
1659 return parent_had_base_class || this_had_base_class;
1660 }
1661 return false;
1662}
1663
1664
1665ValueObject *
1666ValueObject::GetNonBaseClassParent()
1667{
Jim Ingham78a685a2011-04-16 00:01:13 +00001668 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001669 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001670 if (GetParent()->IsBaseClass())
1671 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001672 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001673 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001674 }
1675 return NULL;
1676}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001677
1678void
Enrico Granata4becb372011-06-29 22:27:15 +00001679ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001680{
Greg Claytone221f822011-01-21 01:59:00 +00001681 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00001682
Enrico Granata9dd75c82011-07-15 23:30:15 +00001683 if (is_deref_of_parent && epformat == eDereferencePointers) {
Enrico Granata4becb372011-06-29 22:27:15 +00001684 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
1685 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
1686 // the eHonorPointers mode is meant to produce strings in this latter format
1687 s.PutCString("*(");
1688 }
Greg Claytone221f822011-01-21 01:59:00 +00001689
Enrico Granata4becb372011-06-29 22:27:15 +00001690 ValueObject* parent = GetParent();
1691
1692 if (parent)
1693 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
Enrico Granata0a3958e2011-07-02 00:25:22 +00001694
1695 // if we are a deref_of_parent just because we are synthetic array
1696 // members made up to allow ptr[%d] syntax to work in variable
1697 // printing, then add our name ([%d]) to the expression path
Enrico Granata9dd75c82011-07-15 23:30:15 +00001698 if (m_is_array_item_for_pointer && epformat == eHonorPointers)
Enrico Granata0a3958e2011-07-02 00:25:22 +00001699 s.PutCString(m_name.AsCString());
Enrico Granata4becb372011-06-29 22:27:15 +00001700
Greg Claytone221f822011-01-21 01:59:00 +00001701 if (!IsBaseClass())
1702 {
1703 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001704 {
Greg Claytone221f822011-01-21 01:59:00 +00001705 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1706 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001707 {
Greg Claytone221f822011-01-21 01:59:00 +00001708 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1709 if (non_base_class_parent_clang_type)
1710 {
1711 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1712
Enrico Granata9dd75c82011-07-15 23:30:15 +00001713 if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00001714 {
1715 s.PutCString("->");
1716 }
Enrico Granata4becb372011-06-29 22:27:15 +00001717 else
1718 {
1719 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1720 {
1721 s.PutCString("->");
1722 }
1723 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1724 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1725 {
1726 s.PutChar('.');
1727 }
Greg Claytone221f822011-01-21 01:59:00 +00001728 }
1729 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001730 }
Greg Claytone221f822011-01-21 01:59:00 +00001731
1732 const char *name = GetName().GetCString();
1733 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001734 {
Greg Claytone221f822011-01-21 01:59:00 +00001735 if (qualify_cxx_base_classes)
1736 {
1737 if (GetBaseClassPath (s))
1738 s.PutCString("::");
1739 }
1740 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001741 }
1742 }
1743 }
1744
Enrico Granata4becb372011-06-29 22:27:15 +00001745 if (is_deref_of_parent && epformat == eDereferencePointers) {
Greg Claytone221f822011-01-21 01:59:00 +00001746 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00001747 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001748}
1749
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001750lldb::ValueObjectSP
1751ValueObject::GetValueForExpressionPath(const char* expression,
1752 const char** first_unparsed,
1753 ExpressionPathScanEndReason* reason_to_stop,
1754 ExpressionPathEndResultType* final_value_type,
1755 const GetValueForExpressionPathOptions& options,
1756 ExpressionPathAftermath* final_task_on_target)
1757{
1758
1759 const char* dummy_first_unparsed;
1760 ExpressionPathScanEndReason dummy_reason_to_stop;
1761 ExpressionPathEndResultType dummy_final_value_type;
1762 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1763
1764 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1765 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1766 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1767 final_value_type ? final_value_type : &dummy_final_value_type,
1768 options,
1769 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1770
1771 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1772 {
1773 return ret_val;
1774 }
1775 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1776 {
1777 if (*final_task_on_target == ValueObject::eDereference)
1778 {
1779 Error error;
1780 ValueObjectSP final_value = ret_val->Dereference(error);
1781 if (error.Fail() || !final_value.get())
1782 {
1783 *reason_to_stop = ValueObject::eDereferencingFailed;
1784 *final_value_type = ValueObject::eInvalid;
1785 return ValueObjectSP();
1786 }
1787 else
1788 {
1789 *final_task_on_target = ValueObject::eNothing;
1790 return final_value;
1791 }
1792 }
1793 if (*final_task_on_target == ValueObject::eTakeAddress)
1794 {
1795 Error error;
1796 ValueObjectSP final_value = ret_val->AddressOf(error);
1797 if (error.Fail() || !final_value.get())
1798 {
1799 *reason_to_stop = ValueObject::eTakingAddressFailed;
1800 *final_value_type = ValueObject::eInvalid;
1801 return ValueObjectSP();
1802 }
1803 else
1804 {
1805 *final_task_on_target = ValueObject::eNothing;
1806 return final_value;
1807 }
1808 }
1809 }
1810 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
1811}
1812
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001813int
1814ValueObject::GetValuesForExpressionPath(const char* expression,
1815 lldb::ValueObjectListSP& list,
1816 const char** first_unparsed,
1817 ExpressionPathScanEndReason* reason_to_stop,
1818 ExpressionPathEndResultType* final_value_type,
1819 const GetValueForExpressionPathOptions& options,
1820 ExpressionPathAftermath* final_task_on_target)
1821{
1822 const char* dummy_first_unparsed;
1823 ExpressionPathScanEndReason dummy_reason_to_stop;
1824 ExpressionPathEndResultType dummy_final_value_type;
1825 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing;
1826
1827 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
1828 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1829 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1830 final_value_type ? final_value_type : &dummy_final_value_type,
1831 options,
1832 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1833
1834 if (!ret_val.get()) // if there are errors, I add nothing to the list
1835 return 0;
1836
1837 if (*reason_to_stop != eArrayRangeOperatorMet)
1838 {
1839 // I need not expand a range, just post-process the final value and return
1840 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing)
1841 {
1842 list->Append(ret_val);
1843 return 1;
1844 }
1845 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects
1846 {
1847 if (*final_task_on_target == ValueObject::eDereference)
1848 {
1849 Error error;
1850 ValueObjectSP final_value = ret_val->Dereference(error);
1851 if (error.Fail() || !final_value.get())
1852 {
1853 *reason_to_stop = ValueObject::eDereferencingFailed;
1854 *final_value_type = ValueObject::eInvalid;
1855 return 0;
1856 }
1857 else
1858 {
1859 *final_task_on_target = ValueObject::eNothing;
1860 list->Append(final_value);
1861 return 1;
1862 }
1863 }
1864 if (*final_task_on_target == ValueObject::eTakeAddress)
1865 {
1866 Error error;
1867 ValueObjectSP final_value = ret_val->AddressOf(error);
1868 if (error.Fail() || !final_value.get())
1869 {
1870 *reason_to_stop = ValueObject::eTakingAddressFailed;
1871 *final_value_type = ValueObject::eInvalid;
1872 return 0;
1873 }
1874 else
1875 {
1876 *final_task_on_target = ValueObject::eNothing;
1877 list->Append(final_value);
1878 return 1;
1879 }
1880 }
1881 }
1882 }
1883 else
1884 {
1885 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
1886 first_unparsed ? first_unparsed : &dummy_first_unparsed,
1887 ret_val,
1888 list,
1889 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
1890 final_value_type ? final_value_type : &dummy_final_value_type,
1891 options,
1892 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
1893 }
1894 // in any non-covered case, just do the obviously right thing
1895 list->Append(ret_val);
1896 return 1;
1897}
1898
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001899lldb::ValueObjectSP
1900ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
1901 const char** first_unparsed,
1902 ExpressionPathScanEndReason* reason_to_stop,
1903 ExpressionPathEndResultType* final_result,
1904 const GetValueForExpressionPathOptions& options,
1905 ExpressionPathAftermath* what_next)
1906{
1907 ValueObjectSP root = GetSP();
1908
1909 if (!root.get())
1910 return ValueObjectSP();
1911
1912 *first_unparsed = expression_cstr;
1913
1914 while (true)
1915 {
1916
1917 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
1918
1919 lldb::clang_type_t root_clang_type = root->GetClangType();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001920 lldb::clang_type_t pointee_clang_type;
1921 Flags root_clang_type_info,pointee_clang_type_info;
1922
1923 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
1924 if (pointee_clang_type)
1925 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001926
1927 if (!expression_cstr || *expression_cstr == '\0')
1928 {
1929 *reason_to_stop = ValueObject::eEndOfString;
1930 return root;
1931 }
1932
1933 switch (*expression_cstr)
1934 {
1935 case '-':
1936 {
1937 if (options.m_check_dot_vs_arrow_syntax &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001938 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 +00001939 {
1940 *first_unparsed = expression_cstr;
1941 *reason_to_stop = ValueObject::eArrowInsteadOfDot;
1942 *final_result = ValueObject::eInvalid;
1943 return ValueObjectSP();
1944 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001945 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
1946 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) &&
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001947 options.m_no_fragile_ivar)
1948 {
1949 *first_unparsed = expression_cstr;
1950 *reason_to_stop = ValueObject::eFragileIVarNotAllowed;
1951 *final_result = ValueObject::eInvalid;
1952 return ValueObjectSP();
1953 }
1954 if (expression_cstr[1] != '>')
1955 {
1956 *first_unparsed = expression_cstr;
1957 *reason_to_stop = ValueObject::eUnexpectedSymbol;
1958 *final_result = ValueObject::eInvalid;
1959 return ValueObjectSP();
1960 }
1961 expression_cstr++; // skip the -
1962 }
1963 case '.': // or fallthrough from ->
1964 {
1965 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001966 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 +00001967 {
1968 *first_unparsed = expression_cstr;
1969 *reason_to_stop = ValueObject::eDotInsteadOfArrow;
1970 *final_result = ValueObject::eInvalid;
1971 return ValueObjectSP();
1972 }
1973 expression_cstr++; // skip .
1974 const char *next_separator = strpbrk(expression_cstr+1,"-.[");
1975 ConstString child_name;
1976 if (!next_separator) // if no other separator just expand this last layer
1977 {
1978 child_name.SetCString (expression_cstr);
1979 root = root->GetChildMemberWithName(child_name, true);
1980 if (root.get()) // we know we are done, so just return
1981 {
1982 *first_unparsed = '\0';
1983 *reason_to_stop = ValueObject::eEndOfString;
1984 *final_result = ValueObject::ePlain;
1985 return root;
1986 }
1987 else
1988 {
1989 *first_unparsed = expression_cstr;
1990 *reason_to_stop = ValueObject::eNoSuchChild;
1991 *final_result = ValueObject::eInvalid;
1992 return ValueObjectSP();
1993 }
1994 }
1995 else // other layers do expand
1996 {
1997 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
1998 root = root->GetChildMemberWithName(child_name, true);
1999 if (root.get()) // store the new root and move on
2000 {
2001 *first_unparsed = next_separator;
2002 *final_result = ValueObject::ePlain;
2003 continue;
2004 }
2005 else
2006 {
2007 *first_unparsed = expression_cstr;
2008 *reason_to_stop = ValueObject::eNoSuchChild;
2009 *final_result = ValueObject::eInvalid;
2010 return ValueObjectSP();
2011 }
2012 }
2013 break;
2014 }
2015 case '[':
2016 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002017 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 +00002018 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002019 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 +00002020 {
2021 *first_unparsed = expression_cstr;
2022 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2023 *final_result = ValueObject::eInvalid;
2024 return ValueObjectSP();
2025 }
2026 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2027 {
2028 *first_unparsed = expression_cstr;
2029 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2030 *final_result = ValueObject::eInvalid;
2031 return ValueObjectSP();
2032 }
2033 }
2034 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2035 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002036 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002037 {
2038 *first_unparsed = expression_cstr;
2039 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2040 *final_result = ValueObject::eInvalid;
2041 return ValueObjectSP();
2042 }
2043 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
2044 {
2045 *first_unparsed = expression_cstr+2;
2046 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2047 *final_result = ValueObject::eUnboundedRange;
2048 return root;
2049 }
2050 }
2051 const char *separator_position = ::strchr(expression_cstr+1,'-');
2052 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2053 if (!close_bracket_position) // if there is no ], this is a syntax error
2054 {
2055 *first_unparsed = expression_cstr;
2056 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2057 *final_result = ValueObject::eInvalid;
2058 return ValueObjectSP();
2059 }
2060 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2061 {
2062 char *end = NULL;
2063 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2064 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2065 {
2066 *first_unparsed = expression_cstr;
2067 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2068 *final_result = ValueObject::eInvalid;
2069 return ValueObjectSP();
2070 }
2071 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2072 {
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002073 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002074 {
2075 *first_unparsed = expression_cstr+2;
2076 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2077 *final_result = ValueObject::eUnboundedRange;
2078 return root;
2079 }
2080 else
2081 {
2082 *first_unparsed = expression_cstr;
2083 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2084 *final_result = ValueObject::eInvalid;
2085 return ValueObjectSP();
2086 }
2087 }
2088 // from here on we do have a valid index
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002089 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002090 {
Greg Claytondaf515f2011-07-09 20:12:33 +00002091 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2092 if (!child_valobj_sp)
2093 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
2094 if (child_valobj_sp)
2095 {
2096 root = child_valobj_sp;
2097 *first_unparsed = end+1; // skip ]
2098 *final_result = ValueObject::ePlain;
2099 continue;
2100 }
2101 else
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002102 {
2103 *first_unparsed = expression_cstr;
2104 *reason_to_stop = ValueObject::eNoSuchChild;
2105 *final_result = ValueObject::eInvalid;
2106 return ValueObjectSP();
2107 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002108 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002109 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002110 {
2111 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 +00002112 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002113 {
2114 Error error;
2115 root = root->Dereference(error);
2116 if (error.Fail() || !root.get())
2117 {
2118 *first_unparsed = expression_cstr;
2119 *reason_to_stop = ValueObject::eDereferencingFailed;
2120 *final_result = ValueObject::eInvalid;
2121 return ValueObjectSP();
2122 }
2123 else
2124 {
2125 *what_next = eNothing;
2126 continue;
2127 }
2128 }
2129 else
2130 {
2131 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2132 if (!root.get())
2133 {
2134 *first_unparsed = expression_cstr;
2135 *reason_to_stop = ValueObject::eNoSuchChild;
2136 *final_result = ValueObject::eInvalid;
2137 return ValueObjectSP();
2138 }
2139 else
2140 {
2141 *first_unparsed = end+1; // skip ]
2142 *final_result = ValueObject::ePlain;
2143 continue;
2144 }
2145 }
2146 }
2147 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
2148 {
2149 root = root->GetSyntheticBitFieldChild(index, index, true);
2150 if (!root.get())
2151 {
2152 *first_unparsed = expression_cstr;
2153 *reason_to_stop = ValueObject::eNoSuchChild;
2154 *final_result = ValueObject::eInvalid;
2155 return ValueObjectSP();
2156 }
2157 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2158 {
2159 *first_unparsed = end+1; // skip ]
2160 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2161 *final_result = ValueObject::eBitfield;
2162 return root;
2163 }
2164 }
2165 }
2166 else // we have a low and a high index
2167 {
2168 char *end = NULL;
2169 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2170 if (!end || end != separator_position) // if something weird is in our way return an error
2171 {
2172 *first_unparsed = expression_cstr;
2173 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2174 *final_result = ValueObject::eInvalid;
2175 return ValueObjectSP();
2176 }
2177 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2178 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2179 {
2180 *first_unparsed = expression_cstr;
2181 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2182 *final_result = ValueObject::eInvalid;
2183 return ValueObjectSP();
2184 }
2185 if (index_lower > index_higher) // swap indices if required
2186 {
2187 unsigned long temp = index_lower;
2188 index_lower = index_higher;
2189 index_higher = temp;
2190 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002191 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002192 {
2193 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2194 if (!root.get())
2195 {
2196 *first_unparsed = expression_cstr;
2197 *reason_to_stop = ValueObject::eNoSuchChild;
2198 *final_result = ValueObject::eInvalid;
2199 return ValueObjectSP();
2200 }
2201 else
2202 {
2203 *first_unparsed = end+1; // skip ]
2204 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet;
2205 *final_result = ValueObject::eBitfield;
2206 return root;
2207 }
2208 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002209 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 +00002210 *what_next == ValueObject::eDereference &&
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002211 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002212 {
2213 Error error;
2214 root = root->Dereference(error);
2215 if (error.Fail() || !root.get())
2216 {
2217 *first_unparsed = expression_cstr;
2218 *reason_to_stop = ValueObject::eDereferencingFailed;
2219 *final_result = ValueObject::eInvalid;
2220 return ValueObjectSP();
2221 }
2222 else
2223 {
2224 *what_next = ValueObject::eNothing;
2225 continue;
2226 }
2227 }
2228 else
2229 {
2230 *first_unparsed = expression_cstr;
2231 *reason_to_stop = ValueObject::eArrayRangeOperatorMet;
2232 *final_result = ValueObject::eBoundedRange;
2233 return root;
2234 }
2235 }
2236 break;
2237 }
2238 default: // some non-separator is in the way
2239 {
2240 *first_unparsed = expression_cstr;
2241 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2242 *final_result = ValueObject::eInvalid;
2243 return ValueObjectSP();
2244 break;
2245 }
2246 }
2247 }
2248}
2249
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002250int
2251ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
2252 const char** first_unparsed,
2253 lldb::ValueObjectSP root,
2254 lldb::ValueObjectListSP& list,
2255 ExpressionPathScanEndReason* reason_to_stop,
2256 ExpressionPathEndResultType* final_result,
2257 const GetValueForExpressionPathOptions& options,
2258 ExpressionPathAftermath* what_next)
2259{
2260 if (!root.get())
2261 return 0;
2262
2263 *first_unparsed = expression_cstr;
2264
2265 while (true)
2266 {
2267
2268 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
2269
2270 lldb::clang_type_t root_clang_type = root->GetClangType();
2271 lldb::clang_type_t pointee_clang_type;
2272 Flags root_clang_type_info,pointee_clang_type_info;
2273
2274 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
2275 if (pointee_clang_type)
2276 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
2277
2278 if (!expression_cstr || *expression_cstr == '\0')
2279 {
2280 *reason_to_stop = ValueObject::eEndOfString;
2281 list->Append(root);
2282 return 1;
2283 }
2284
2285 switch (*expression_cstr)
2286 {
2287 case '[':
2288 {
2289 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
2290 {
2291 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
2292 {
2293 *first_unparsed = expression_cstr;
2294 *reason_to_stop = ValueObject::eRangeOperatorInvalid;
2295 *final_result = ValueObject::eInvalid;
2296 return 0;
2297 }
2298 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2299 {
2300 *first_unparsed = expression_cstr;
2301 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed;
2302 *final_result = ValueObject::eInvalid;
2303 return 0;
2304 }
2305 }
2306 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2307 {
2308 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2309 {
2310 *first_unparsed = expression_cstr;
2311 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2312 *final_result = ValueObject::eInvalid;
2313 return 0;
2314 }
2315 else // expand this into list
2316 {
2317 int max_index = root->GetNumChildren() - 1;
2318 for (int index = 0; index < max_index; index++)
2319 {
2320 ValueObjectSP child =
2321 root->GetChildAtIndex(index, true);
2322 list->Append(child);
2323 }
2324 *first_unparsed = expression_cstr+2;
2325 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2326 *final_result = ValueObject::eValueObjectList;
2327 return max_index; // tell me number of items I added to the VOList
2328 }
2329 }
2330 const char *separator_position = ::strchr(expression_cstr+1,'-');
2331 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2332 if (!close_bracket_position) // if there is no ], this is a syntax error
2333 {
2334 *first_unparsed = expression_cstr;
2335 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2336 *final_result = ValueObject::eInvalid;
2337 return 0;
2338 }
2339 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2340 {
2341 char *end = NULL;
2342 unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2343 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2344 {
2345 *first_unparsed = expression_cstr;
2346 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2347 *final_result = ValueObject::eInvalid;
2348 return 0;
2349 }
2350 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2351 {
2352 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2353 {
2354 int max_index = root->GetNumChildren() - 1;
2355 for (int index = 0; index < max_index; index++)
2356 {
2357 ValueObjectSP child =
2358 root->GetChildAtIndex(index, true);
2359 list->Append(child);
2360 }
2361 *first_unparsed = expression_cstr+2;
2362 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2363 *final_result = ValueObject::eValueObjectList;
2364 return max_index; // tell me number of items I added to the VOList
2365 }
2366 else
2367 {
2368 *first_unparsed = expression_cstr;
2369 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed;
2370 *final_result = ValueObject::eInvalid;
2371 return 0;
2372 }
2373 }
2374 // from here on we do have a valid index
2375 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
2376 {
2377 root = root->GetChildAtIndex(index, true);
2378 if (!root.get())
2379 {
2380 *first_unparsed = expression_cstr;
2381 *reason_to_stop = ValueObject::eNoSuchChild;
2382 *final_result = ValueObject::eInvalid;
2383 return 0;
2384 }
2385 else
2386 {
2387 list->Append(root);
2388 *first_unparsed = end+1; // skip ]
2389 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2390 *final_result = ValueObject::eValueObjectList;
2391 return 1;
2392 }
2393 }
2394 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
2395 {
2396 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
2397 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2398 {
2399 Error error;
2400 root = root->Dereference(error);
2401 if (error.Fail() || !root.get())
2402 {
2403 *first_unparsed = expression_cstr;
2404 *reason_to_stop = ValueObject::eDereferencingFailed;
2405 *final_result = ValueObject::eInvalid;
2406 return 0;
2407 }
2408 else
2409 {
2410 *what_next = eNothing;
2411 continue;
2412 }
2413 }
2414 else
2415 {
2416 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2417 if (!root.get())
2418 {
2419 *first_unparsed = expression_cstr;
2420 *reason_to_stop = ValueObject::eNoSuchChild;
2421 *final_result = ValueObject::eInvalid;
2422 return 0;
2423 }
2424 else
2425 {
2426 list->Append(root);
2427 *first_unparsed = end+1; // skip ]
2428 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2429 *final_result = ValueObject::eValueObjectList;
2430 return 1;
2431 }
2432 }
2433 }
2434 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
2435 {
2436 root = root->GetSyntheticBitFieldChild(index, index, true);
2437 if (!root.get())
2438 {
2439 *first_unparsed = expression_cstr;
2440 *reason_to_stop = ValueObject::eNoSuchChild;
2441 *final_result = ValueObject::eInvalid;
2442 return 0;
2443 }
2444 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2445 {
2446 list->Append(root);
2447 *first_unparsed = end+1; // skip ]
2448 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2449 *final_result = ValueObject::eValueObjectList;
2450 return 1;
2451 }
2452 }
2453 }
2454 else // we have a low and a high index
2455 {
2456 char *end = NULL;
2457 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2458 if (!end || end != separator_position) // if something weird is in our way return an error
2459 {
2460 *first_unparsed = expression_cstr;
2461 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2462 *final_result = ValueObject::eInvalid;
2463 return 0;
2464 }
2465 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2466 if (!end || end != close_bracket_position) // if something weird is in our way return an error
2467 {
2468 *first_unparsed = expression_cstr;
2469 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2470 *final_result = ValueObject::eInvalid;
2471 return 0;
2472 }
2473 if (index_lower > index_higher) // swap indices if required
2474 {
2475 unsigned long temp = index_lower;
2476 index_lower = index_higher;
2477 index_higher = temp;
2478 }
2479 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
2480 {
2481 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2482 if (!root.get())
2483 {
2484 *first_unparsed = expression_cstr;
2485 *reason_to_stop = ValueObject::eNoSuchChild;
2486 *final_result = ValueObject::eInvalid;
2487 return 0;
2488 }
2489 else
2490 {
2491 list->Append(root);
2492 *first_unparsed = end+1; // skip ]
2493 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2494 *final_result = ValueObject::eValueObjectList;
2495 return 1;
2496 }
2497 }
2498 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
2499 *what_next == ValueObject::eDereference &&
2500 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
2501 {
2502 Error error;
2503 root = root->Dereference(error);
2504 if (error.Fail() || !root.get())
2505 {
2506 *first_unparsed = expression_cstr;
2507 *reason_to_stop = ValueObject::eDereferencingFailed;
2508 *final_result = ValueObject::eInvalid;
2509 return 0;
2510 }
2511 else
2512 {
2513 *what_next = ValueObject::eNothing;
2514 continue;
2515 }
2516 }
2517 else
2518 {
Johnny Chen44805302011-07-19 19:48:13 +00002519 for (unsigned long index = index_lower;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002520 index <= index_higher; index++)
2521 {
2522 ValueObjectSP child =
2523 root->GetChildAtIndex(index, true);
2524 list->Append(child);
2525 }
2526 *first_unparsed = end+1;
2527 *reason_to_stop = ValueObject::eRangeOperatorExpanded;
2528 *final_result = ValueObject::eValueObjectList;
2529 return index_higher-index_lower+1; // tell me number of items I added to the VOList
2530 }
2531 }
2532 break;
2533 }
2534 default: // some non-[ separator, or something entirely wrong, is in the way
2535 {
2536 *first_unparsed = expression_cstr;
2537 *reason_to_stop = ValueObject::eUnexpectedSymbol;
2538 *final_result = ValueObject::eInvalid;
2539 return 0;
2540 break;
2541 }
2542 }
2543 }
2544}
2545
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002546void
Greg Clayton1d3afba2010-10-05 00:00:42 +00002547ValueObject::DumpValueObject
2548(
2549 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00002550 ValueObject *valobj,
2551 const char *root_valobj_name,
2552 uint32_t ptr_depth,
2553 uint32_t curr_depth,
2554 uint32_t max_depth,
2555 bool show_types,
2556 bool show_location,
2557 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00002558 lldb::DynamicValueType use_dynamic,
Enrico Granatad55546b2011-07-22 00:16:08 +00002559 bool use_synth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002560 bool scope_already_checked,
Enrico Granata0c5ef692011-07-16 01:22:04 +00002561 bool flat_output,
2562 uint32_t omit_summary_depth
Greg Clayton1d3afba2010-10-05 00:00:42 +00002563)
2564{
Greg Clayton007d5be2011-05-30 00:49:24 +00002565 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002566 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002567 bool update_success = valobj->UpdateValueIfNeeded ();
2568
2569 if (update_success && use_dynamic != lldb::eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00002570 {
Jim Ingham2837b762011-05-04 03:43:18 +00002571 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00002572 if (dynamic_value)
2573 valobj = dynamic_value;
2574 }
2575
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002576 clang_type_t clang_type = valobj->GetClangType();
2577
Greg Clayton73b472d2010-10-27 03:32:59 +00002578 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002579 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00002580 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
2581 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002582
2583 const bool print_valobj = flat_output == false || has_value;
2584
2585 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002586 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002587 if (show_location)
2588 {
Jim Ingham6035b672011-03-31 00:19:25 +00002589 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002590 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002591
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002592 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002593
Greg Clayton7c8a9662010-11-02 01:50:16 +00002594 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00002595 if (show_types || (curr_depth == 0 && !flat_output))
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002596 s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
Greg Clayton1d3afba2010-10-05 00:00:42 +00002597
Greg Clayton1d3afba2010-10-05 00:00:42 +00002598
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002599 if (flat_output)
2600 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002601 // If we are showing types, also qualify the C++ base classes
2602 const bool qualify_cxx_base_classes = show_types;
2603 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002604 s.PutCString(" =");
2605 }
2606 else
2607 {
2608 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
2609 s.Printf ("%s =", name_cstr);
2610 }
2611
Jim Ingham6035b672011-03-31 00:19:25 +00002612 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002613 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002614 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002615 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002616 }
2617
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002618 const char *val_cstr = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00002619 const char *sum_cstr = NULL;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002620 SummaryFormat* entry = valobj->GetSummaryFormat().get();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002621
Enrico Granata0c5ef692011-07-16 01:22:04 +00002622 if (omit_summary_depth > 0)
2623 entry = NULL;
2624
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002625 if (err_cstr == NULL)
2626 {
Jim Ingham6035b672011-03-31 00:19:25 +00002627 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002628 err_cstr = valobj->GetError().AsCString();
2629 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002630
2631 if (err_cstr)
2632 {
Greg Clayton007d5be2011-05-30 00:49:24 +00002633 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00002634 }
2635 else
2636 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002637 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002638 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002639 {
Enrico Granata4becb372011-06-29 22:27:15 +00002640
Enrico Granata0c5ef692011-07-16 01:22:04 +00002641 sum_cstr = (omit_summary_depth == 0) ? valobj->GetSummaryAsCString() : NULL;
Greg Clayton1d3afba2010-10-05 00:00:42 +00002642
Enrico Granata4becb372011-06-29 22:27:15 +00002643 // We must calculate this value in realtime because entry might alter this variable's value
2644 // (e.g. by saying ${var%fmt}) and render precached values useless
2645 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
2646 s.Printf(" %s", valobj->GetValueAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002647
Enrico Granata9dd75c82011-07-15 23:30:15 +00002648 if (sum_cstr)
Enrico Granata0a3958e2011-07-02 00:25:22 +00002649 {
2650 // for some reason, using %@ (ObjC description) in a summary string, makes
2651 // us believe we need to reset ourselves, thus invalidating the content of
2652 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty
2653 // let us recalculate it!
2654 if (sum_cstr[0] == '\0')
2655 s.Printf(" %s", valobj->GetSummaryAsCString());
2656 else
2657 s.Printf(" %s", sum_cstr);
2658 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002659
2660 if (use_objc)
2661 {
Jim Ingham6035b672011-03-31 00:19:25 +00002662 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002663 if (object_desc)
2664 s.Printf(" %s\n", object_desc);
2665 else
Sean Callanan672ad942010-10-23 00:18:49 +00002666 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002667 return;
Enrico Granata0a3958e2011-07-02 00:25:22 +00002668 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002669 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002670
2671 if (curr_depth < max_depth)
2672 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002673 // We will show children for all concrete types. We won't show
2674 // pointer contents unless a pointer depth has been specified.
2675 // We won't reference contents unless the reference is the
2676 // root object (depth of zero).
2677 bool print_children = true;
2678
2679 // Use a new temporary pointer depth in case we override the
2680 // current pointer depth below...
2681 uint32_t curr_ptr_depth = ptr_depth;
2682
2683 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
2684 if (is_ptr || is_ref)
2685 {
2686 // We have a pointer or reference whose value is an address.
2687 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00002688 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00002689 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
2690 print_children = false;
2691
2692 else if (is_ref && curr_depth == 0)
2693 {
2694 // If this is the root object (depth is zero) that we are showing
2695 // and it is a reference, and no pointer depth has been supplied
2696 // print out what it references. Don't do this at deeper depths
2697 // otherwise we can end up with infinite recursion...
2698 curr_ptr_depth = 1;
2699 }
2700
2701 if (curr_ptr_depth == 0)
2702 print_children = false;
2703 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00002704
Enrico Granata0a3958e2011-07-02 00:25:22 +00002705 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00002706 {
Enrico Granatad55546b2011-07-22 00:16:08 +00002707 ValueObjectSP synth_vobj = valobj->GetSyntheticValue(use_synth ?
2708 lldb::eUseSyntheticFilter :
2709 lldb::eNoSyntheticFilter);
2710 const uint32_t num_children = synth_vobj->GetNumChildren();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002711 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002712 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002713 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002714 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002715 if (print_valobj)
2716 s.EOL();
2717 }
2718 else
2719 {
2720 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00002721 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002722 s.IndentMore();
2723 }
2724
2725 for (uint32_t idx=0; idx<num_children; ++idx)
2726 {
Enrico Granatad55546b2011-07-22 00:16:08 +00002727 ValueObjectSP child_sp(synth_vobj->GetChildAtIndex(idx, true));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002728 if (child_sp.get())
2729 {
2730 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002731 child_sp.get(),
2732 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00002733 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002734 curr_depth + 1,
2735 max_depth,
2736 show_types,
2737 show_location,
2738 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00002739 use_dynamic,
Enrico Granatad55546b2011-07-22 00:16:08 +00002740 use_synth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002741 true,
Enrico Granata0c5ef692011-07-16 01:22:04 +00002742 flat_output,
2743 omit_summary_depth > 1 ? omit_summary_depth - 1 : 0);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002744 }
2745 }
2746
2747 if (!flat_output)
2748 {
2749 s.IndentLess();
2750 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002751 }
2752 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002753 else if (has_children)
2754 {
2755 // Aggregate, no children...
2756 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00002757 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002758 }
2759 else
2760 {
2761 if (print_valobj)
2762 s.EOL();
2763 }
2764
Greg Clayton1d3afba2010-10-05 00:00:42 +00002765 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002766 else
2767 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00002768 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00002769 }
2770 }
2771 else
2772 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002773 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00002774 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002775 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00002776 }
2777 }
2778 }
2779 }
2780}
2781
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002782
2783ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00002784ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002785{
2786 ValueObjectSP valobj_sp;
2787
Jim Ingham6035b672011-03-31 00:19:25 +00002788 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002789 {
Jim Ingham6035b672011-03-31 00:19:25 +00002790 ExecutionContextScope *exe_scope = GetExecutionContextScope();
2791 if (exe_scope)
2792 {
2793 ExecutionContext exe_ctx;
2794 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002795
Jim Ingham6035b672011-03-31 00:19:25 +00002796 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002797
Jim Ingham6035b672011-03-31 00:19:25 +00002798 DataExtractor data;
2799 data.SetByteOrder (m_data.GetByteOrder());
2800 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002801
Greg Clayton644247c2011-07-07 01:59:51 +00002802 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002803
Jim Ingham58b59f92011-04-22 23:53:53 +00002804 valobj_sp = ValueObjectConstResult::Create (exe_scope,
2805 ast,
2806 GetClangType(),
2807 name,
2808 data);
Jim Ingham6035b672011-03-31 00:19:25 +00002809 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002810 }
Jim Ingham6035b672011-03-31 00:19:25 +00002811
2812 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002813 {
Jim Ingham58b59f92011-04-22 23:53:53 +00002814 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002815 }
2816 return valobj_sp;
2817}
2818
2819lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00002820ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002821{
Jim Ingham58b59f92011-04-22 23:53:53 +00002822 if (m_deref_valobj)
2823 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00002824
Greg Clayton54979cd2010-12-15 05:08:08 +00002825 const bool is_pointer_type = IsPointerType();
2826 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002827 {
2828 bool omit_empty_base_classes = true;
Greg Claytondaf515f2011-07-09 20:12:33 +00002829 bool ignore_array_bounds = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002830
2831 std::string child_name_str;
2832 uint32_t child_byte_size = 0;
2833 int32_t child_byte_offset = 0;
2834 uint32_t child_bitfield_bit_size = 0;
2835 uint32_t child_bitfield_bit_offset = 0;
2836 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00002837 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002838 const bool transparent_pointers = false;
2839 clang::ASTContext *clang_ast = GetClangAST();
2840 clang_type_t clang_type = GetClangType();
2841 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00002842
2843 ExecutionContext exe_ctx;
2844 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
2845
2846 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
2847 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002848 GetName().GetCString(),
2849 clang_type,
2850 0,
2851 transparent_pointers,
2852 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00002853 ignore_array_bounds,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002854 child_name_str,
2855 child_byte_size,
2856 child_byte_offset,
2857 child_bitfield_bit_size,
2858 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002859 child_is_base_class,
2860 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00002861 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002862 {
2863 ConstString child_name;
2864 if (!child_name_str.empty())
2865 child_name.SetCString (child_name_str.c_str());
2866
Jim Ingham58b59f92011-04-22 23:53:53 +00002867 m_deref_valobj = new ValueObjectChild (*this,
2868 clang_ast,
2869 child_clang_type,
2870 child_name,
2871 child_byte_size,
2872 child_byte_offset,
2873 child_bitfield_bit_size,
2874 child_bitfield_bit_offset,
2875 child_is_base_class,
2876 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002877 }
2878 }
Greg Clayton54979cd2010-12-15 05:08:08 +00002879
Jim Ingham58b59f92011-04-22 23:53:53 +00002880 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00002881 {
2882 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00002883 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00002884 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002885 else
2886 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002887 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002888 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002889
2890 if (is_pointer_type)
2891 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
2892 else
2893 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00002894 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002895 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002896}
2897
Jim Ingham78a685a2011-04-16 00:01:13 +00002898lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00002899ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002900{
Jim Ingham78a685a2011-04-16 00:01:13 +00002901 if (m_addr_of_valobj_sp)
2902 return m_addr_of_valobj_sp;
2903
Greg Claytone0d378b2011-03-24 21:19:54 +00002904 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002905 const bool scalar_is_load_address = false;
2906 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00002907 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002908 if (addr != LLDB_INVALID_ADDRESS)
2909 {
2910 switch (address_type)
2911 {
Greg Clayton54979cd2010-12-15 05:08:08 +00002912 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002913 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00002914 {
2915 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002916 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002917 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
2918 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002919 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002920
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002921 case eAddressTypeFile:
2922 case eAddressTypeLoad:
2923 case eAddressTypeHost:
2924 {
2925 clang::ASTContext *ast = GetClangAST();
2926 clang_type_t clang_type = GetClangType();
2927 if (ast && clang_type)
2928 {
2929 std::string name (1, '&');
2930 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00002931 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
2932 ast,
2933 ClangASTContext::CreatePointerType (ast, clang_type),
2934 ConstString (name.c_str()),
2935 addr,
2936 eAddressTypeInvalid,
2937 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002938 }
2939 }
2940 break;
2941 }
2942 }
Jim Ingham78a685a2011-04-16 00:01:13 +00002943 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002944}
2945
Greg Claytonb2dcc362011-05-05 23:32:56 +00002946
2947lldb::ValueObjectSP
2948ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
2949{
2950 lldb::ValueObjectSP valobj_sp;
2951 AddressType address_type;
2952 const bool scalar_is_load_address = true;
2953 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2954
2955 if (ptr_value != LLDB_INVALID_ADDRESS)
2956 {
2957 Address ptr_addr (NULL, ptr_value);
2958
2959 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2960 name,
2961 ptr_addr,
2962 clang_ast_type);
2963 }
2964 return valobj_sp;
2965}
2966
2967lldb::ValueObjectSP
2968ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
2969{
2970 lldb::ValueObjectSP valobj_sp;
2971 AddressType address_type;
2972 const bool scalar_is_load_address = true;
2973 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
2974
2975 if (ptr_value != LLDB_INVALID_ADDRESS)
2976 {
2977 Address ptr_addr (NULL, ptr_value);
2978
2979 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
2980 name,
2981 ptr_addr,
2982 type_sp);
2983 }
2984 return valobj_sp;
2985}
2986
2987
Jim Ingham6035b672011-03-31 00:19:25 +00002988ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00002989 m_thread_id (LLDB_INVALID_UID),
2990 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00002991{
2992}
2993
2994ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00002995 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002996 m_first_update (true),
Jim Ingham89b61092011-07-06 17:42:14 +00002997 m_thread_id (LLDB_INVALID_THREAD_ID),
Stephen Wilson71c21d12011-04-11 19:41:40 +00002998 m_stop_id (0)
2999
Jim Ingham6035b672011-03-31 00:19:25 +00003000{
3001 ExecutionContext exe_ctx;
3002 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
3003 // and if so we want to cache that not the original.
3004 if (exe_scope)
3005 exe_scope->CalculateExecutionContext(exe_ctx);
3006 if (exe_ctx.target != NULL)
3007 {
3008 m_target_sp = exe_ctx.target->GetSP();
3009
3010 if (exe_ctx.process == NULL)
3011 m_process_sp = exe_ctx.target->GetProcessSP();
3012 else
3013 m_process_sp = exe_ctx.process->GetSP();
3014
3015 if (m_process_sp != NULL)
3016 {
3017 m_stop_id = m_process_sp->GetStopID();
3018 Thread *thread = NULL;
3019
3020 if (exe_ctx.thread == NULL)
3021 {
3022 if (use_selected)
3023 {
3024 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
3025 if (thread)
3026 computed_exe_scope = thread;
3027 }
3028 }
3029 else
3030 thread = exe_ctx.thread;
3031
3032 if (thread != NULL)
3033 {
3034 m_thread_id = thread->GetIndexID();
3035 if (exe_ctx.frame == NULL)
3036 {
3037 if (use_selected)
3038 {
3039 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
3040 if (frame)
3041 {
3042 m_stack_id = frame->GetStackID();
3043 computed_exe_scope = frame;
3044 }
3045 }
3046 }
3047 else
3048 m_stack_id = exe_ctx.frame->GetStackID();
3049 }
3050 }
3051 }
3052 m_exe_scope = computed_exe_scope;
3053}
3054
3055ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
3056 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00003057 m_needs_update(true),
3058 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00003059 m_target_sp (rhs.m_target_sp),
3060 m_process_sp (rhs.m_process_sp),
3061 m_thread_id (rhs.m_thread_id),
3062 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00003063 m_stop_id (0)
3064{
3065}
3066
3067ValueObject::EvaluationPoint::~EvaluationPoint ()
3068{
3069}
3070
3071ExecutionContextScope *
3072ValueObject::EvaluationPoint::GetExecutionContextScope ()
3073{
3074 // We have to update before giving out the scope, or we could be handing out stale pointers.
3075 SyncWithProcessState();
3076
3077 return m_exe_scope;
3078}
3079
3080// This function checks the EvaluationPoint against the current process state. If the current
3081// state matches the evaluation point, or the evaluation point is already invalid, then we return
3082// false, meaning "no change". If the current state is different, we update our state, and return
3083// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
3084// future calls to NeedsUpdate will return true.
3085
3086bool
3087ValueObject::EvaluationPoint::SyncWithProcessState()
3088{
3089 // If we're already invalid, we don't need to do anything, and nothing has changed:
3090 if (m_stop_id == LLDB_INVALID_UID)
3091 {
3092 // Can't update with an invalid state.
3093 m_needs_update = false;
3094 return false;
3095 }
3096
3097 // If we don't have a process nothing can change.
3098 if (!m_process_sp)
3099 return false;
3100
3101 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00003102 uint32_t cur_stop_id = m_process_sp->GetStopID();
3103 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00003104 return false;
3105
Jim Ingham78a685a2011-04-16 00:01:13 +00003106 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
3107 // In either case, we aren't going to be able to sync with the process state.
3108 if (cur_stop_id == 0)
3109 return false;
3110
3111 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00003112 m_needs_update = true;
3113 m_exe_scope = m_process_sp.get();
3114
3115 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
3116 // doesn't, mark ourselves as invalid.
3117
3118 if (m_thread_id != LLDB_INVALID_THREAD_ID)
3119 {
3120 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
3121 if (our_thread == NULL)
Greg Clayton262f80d2011-07-06 16:49:27 +00003122 {
Jim Ingham89b61092011-07-06 17:42:14 +00003123 SetInvalid();
Greg Clayton262f80d2011-07-06 16:49:27 +00003124 }
Jim Ingham6035b672011-03-31 00:19:25 +00003125 else
3126 {
3127 m_exe_scope = our_thread;
3128
3129 if (m_stack_id.IsValid())
3130 {
3131 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
3132 if (our_frame == NULL)
3133 SetInvalid();
3134 else
3135 m_exe_scope = our_frame;
3136 }
3137 }
3138 }
3139 return true;
3140}
3141
Jim Ingham61be0902011-05-02 18:13:59 +00003142void
3143ValueObject::EvaluationPoint::SetUpdated ()
3144{
3145 m_first_update = false;
3146 m_needs_update = false;
3147 if (m_process_sp)
3148 m_stop_id = m_process_sp->GetStopID();
3149}
3150
3151
Jim Ingham6035b672011-03-31 00:19:25 +00003152bool
3153ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
3154{
3155 if (!IsValid())
3156 return false;
3157
3158 bool needs_update = false;
3159 m_exe_scope = NULL;
3160
3161 // The target has to be non-null, and the
3162 Target *target = exe_scope->CalculateTarget();
3163 if (target != NULL)
3164 {
3165 Target *old_target = m_target_sp.get();
3166 assert (target == old_target);
3167 Process *process = exe_scope->CalculateProcess();
3168 if (process != NULL)
3169 {
3170 // FOR NOW - assume you can't update variable objects across process boundaries.
3171 Process *old_process = m_process_sp.get();
3172 assert (process == old_process);
3173
3174 lldb::user_id_t stop_id = process->GetStopID();
3175 if (stop_id != m_stop_id)
3176 {
3177 needs_update = true;
3178 m_stop_id = stop_id;
3179 }
3180 // See if we're switching the thread or stack context. If no thread is given, this is
3181 // being evaluated in a global context.
3182 Thread *thread = exe_scope->CalculateThread();
3183 if (thread != NULL)
3184 {
3185 lldb::user_id_t new_thread_index = thread->GetIndexID();
3186 if (new_thread_index != m_thread_id)
3187 {
3188 needs_update = true;
3189 m_thread_id = new_thread_index;
3190 m_stack_id.Clear();
3191 }
3192
3193 StackFrame *new_frame = exe_scope->CalculateStackFrame();
3194 if (new_frame != NULL)
3195 {
3196 if (new_frame->GetStackID() != m_stack_id)
3197 {
3198 needs_update = true;
3199 m_stack_id = new_frame->GetStackID();
3200 }
3201 }
3202 else
3203 {
3204 m_stack_id.Clear();
3205 needs_update = true;
3206 }
3207 }
3208 else
3209 {
3210 // If this had been given a thread, and now there is none, we should update.
3211 // Otherwise we don't have to do anything.
3212 if (m_thread_id != LLDB_INVALID_UID)
3213 {
3214 m_thread_id = LLDB_INVALID_UID;
3215 m_stack_id.Clear();
3216 needs_update = true;
3217 }
3218 }
3219 }
3220 else
3221 {
3222 // If there is no process, then we don't need to update anything.
3223 // But if we're switching from having a process to not, we should try to update.
3224 if (m_process_sp.get() != NULL)
3225 {
3226 needs_update = true;
3227 m_process_sp.reset();
3228 m_thread_id = LLDB_INVALID_UID;
3229 m_stack_id.Clear();
3230 }
3231 }
3232 }
3233 else
3234 {
3235 // If there's no target, nothing can change so we don't need to update anything.
3236 // But if we're switching from having a target to not, we should try to update.
3237 if (m_target_sp.get() != NULL)
3238 {
3239 needs_update = true;
3240 m_target_sp.reset();
3241 m_process_sp.reset();
3242 m_thread_id = LLDB_INVALID_UID;
3243 m_stack_id.Clear();
3244 }
3245 }
3246 if (!m_needs_update)
3247 m_needs_update = needs_update;
3248
3249 return needs_update;
3250}
Enrico Granataf2bbf712011-07-15 02:26:42 +00003251
3252void
3253ValueObject::ClearUserVisibleData()
3254{
3255 m_location_str.clear();
3256 m_value_str.clear();
3257 m_summary_str.clear();
3258 m_object_desc_str.clear();
Johnny Chen44805302011-07-19 19:48:13 +00003259}