blob: 5177600b0fedde9256524c63b4e35e2104a1a672 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ValueObject.cpp -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/ValueObject.h"
11
12// C Includes
Greg Claytonf5e56de2010-09-14 23:36:40 +000013#include <stdlib.h>
14
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015// C++ Includes
16// Other libraries and framework includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "llvm/Support/raw_ostream.h"
Jim Ingham5a369122010-09-28 01:25:32 +000018#include "clang/AST/Type.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019
20// Project includes
21#include "lldb/Core/DataBufferHeap.h"
Enrico Granata4becb372011-06-29 22:27:15 +000022#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/StreamString.h"
24#include "lldb/Core/ValueObjectChild.h"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000025#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000026#include "lldb/Core/ValueObjectDynamicValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/ValueObjectList.h"
Greg Claytonb2dcc362011-05-05 23:32:56 +000028#include "lldb/Core/ValueObjectMemory.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029
Greg Clayton7fb56d02011-02-01 01:31:41 +000030#include "lldb/Host/Endian.h"
31
Greg Claytone1a916a2010-07-21 22:12:05 +000032#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Symbol/ClangASTContext.h"
34#include "lldb/Symbol/Type.h"
35
Jim Ingham53c47f12010-09-10 23:12:17 +000036#include "lldb/Target/ExecutionContext.h"
Jim Ingham5a369122010-09-28 01:25:32 +000037#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038#include "lldb/Target/Process.h"
39#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000040#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042
43using namespace lldb;
44using namespace lldb_private;
45
46static lldb::user_id_t g_value_obj_uid = 0;
47
48//----------------------------------------------------------------------
49// ValueObject constructor
50//----------------------------------------------------------------------
Jim Ingham6035b672011-03-31 00:19:25 +000051ValueObject::ValueObject (ValueObject &parent) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052 UserID (++g_value_obj_uid), // Unique identifier for every value object
Jim Ingham6035b672011-03-31 00:19:25 +000053 m_parent (&parent),
Stephen Wilson71c21d12011-04-11 19:41:40 +000054 m_update_point (parent.GetUpdatePoint ()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055 m_name (),
56 m_data (),
57 m_value (),
58 m_error (),
Greg Clayton288bdf92010-09-02 02:59:18 +000059 m_value_str (),
60 m_old_value_str (),
61 m_location_str (),
62 m_summary_str (),
Jim Ingham53c47f12010-09-10 23:12:17 +000063 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000064 m_manager(parent.GetManager()),
Greg Clayton288bdf92010-09-02 02:59:18 +000065 m_children (),
66 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +000067 m_dynamic_value (NULL),
68 m_deref_valobj(NULL),
Greg Clayton32c40852010-10-06 03:09:11 +000069 m_format (eFormatDefault),
Greg Clayton288bdf92010-09-02 02:59:18 +000070 m_value_is_valid (false),
71 m_value_did_change (false),
72 m_children_count_valid (false),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000073 m_old_value_valid (false),
Greg Claytone221f822011-01-21 01:59:00 +000074 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +000075 m_is_deref_of_parent (false),
76 m_last_format_mgr_revision(0),
77 m_last_summary_format(),
78 m_last_value_format()
Jim Ingham6035b672011-03-31 00:19:25 +000079{
Jim Ingham58b59f92011-04-22 23:53:53 +000080 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +000081}
82
83//----------------------------------------------------------------------
84// ValueObject constructor
85//----------------------------------------------------------------------
86ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
87 UserID (++g_value_obj_uid), // Unique identifier for every value object
88 m_parent (NULL),
Stephen Wilson71c21d12011-04-11 19:41:40 +000089 m_update_point (exe_scope),
Jim Ingham6035b672011-03-31 00:19:25 +000090 m_name (),
91 m_data (),
92 m_value (),
93 m_error (),
94 m_value_str (),
95 m_old_value_str (),
96 m_location_str (),
97 m_summary_str (),
98 m_object_desc_str (),
Jim Ingham58b59f92011-04-22 23:53:53 +000099 m_manager(),
Jim Ingham6035b672011-03-31 00:19:25 +0000100 m_children (),
101 m_synthetic_children (),
Jim Ingham58b59f92011-04-22 23:53:53 +0000102 m_dynamic_value (NULL),
103 m_deref_valobj(NULL),
Jim Ingham6035b672011-03-31 00:19:25 +0000104 m_format (eFormatDefault),
105 m_value_is_valid (false),
106 m_value_did_change (false),
107 m_children_count_valid (false),
108 m_old_value_valid (false),
109 m_pointers_point_to_load_addrs (false),
Enrico Granata4becb372011-06-29 22:27:15 +0000110 m_is_deref_of_parent (false),
111 m_last_format_mgr_revision(0),
112 m_last_summary_format(),
113 m_last_value_format()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114{
Jim Ingham58b59f92011-04-22 23:53:53 +0000115 m_manager = new ValueObjectManager();
116 m_manager->ManageObject (this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117}
118
119//----------------------------------------------------------------------
120// Destructor
121//----------------------------------------------------------------------
122ValueObject::~ValueObject ()
123{
124}
125
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126bool
Jim Ingham6035b672011-03-31 00:19:25 +0000127ValueObject::UpdateValueIfNeeded ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128{
Enrico Granata4becb372011-06-29 22:27:15 +0000129
130 UpdateFormatsIfNeeded();
131
Greg Claytonb71f3842010-10-05 03:13:51 +0000132 // If this is a constant value, then our success is predicated on whether
133 // we have an error or not
134 if (GetIsConstant())
135 return m_error.Success();
136
Jim Ingham6035b672011-03-31 00:19:25 +0000137 bool first_update = m_update_point.IsFirstEvaluation();
138
139 if (m_update_point.NeedsUpdating())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140 {
Jim Ingham6035b672011-03-31 00:19:25 +0000141 m_update_point.SetUpdated();
142
143 // Save the old value using swap to avoid a string copy which
144 // also will clear our m_value_str
145 if (m_value_str.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146 {
Jim Ingham6035b672011-03-31 00:19:25 +0000147 m_old_value_valid = false;
148 }
149 else
150 {
151 m_old_value_valid = true;
152 m_old_value_str.swap (m_value_str);
153 m_value_str.clear();
154 }
155 m_location_str.clear();
156 m_summary_str.clear();
157 m_object_desc_str.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158
Jim Ingham6035b672011-03-31 00:19:25 +0000159 const bool value_was_valid = GetValueIsValid();
160 SetValueDidChange (false);
Greg Clayton73b953b2010-08-28 00:08:07 +0000161
Jim Ingham6035b672011-03-31 00:19:25 +0000162 m_error.Clear();
Greg Clayton73b953b2010-08-28 00:08:07 +0000163
Jim Ingham6035b672011-03-31 00:19:25 +0000164 // Call the pure virtual function to update the value
165 bool success = UpdateValue ();
166
167 SetValueIsValid (success);
168
169 if (first_update)
170 SetValueDidChange (false);
171 else if (!m_value_did_change && success == false)
172 {
173 // The value wasn't gotten successfully, so we mark this
174 // as changed if the value used to be valid and now isn't
175 SetValueDidChange (value_was_valid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176 }
177 }
178 return m_error.Success();
179}
180
Enrico Granata4becb372011-06-29 22:27:15 +0000181void
182ValueObject::UpdateFormatsIfNeeded()
183{
184 /*printf("CHECKING FOR UPDATES. I am at revision %d, while the format manager is at revision %d\n",
185 m_last_format_mgr_revision,
186 Debugger::ValueFormats::GetCurrentRevision());*/
187 if (m_last_format_mgr_revision != Debugger::ValueFormats::GetCurrentRevision())
188 {
189 if (m_last_summary_format.get())
190 m_last_summary_format.reset((SummaryFormat*)NULL);
191 if (m_last_value_format.get())
192 m_last_value_format.reset((ValueFormat*)NULL);
193 Debugger::ValueFormats::Get(*this, m_last_value_format);
194 Debugger::SummaryFormats::Get(*this, m_last_summary_format);
195 m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision();
196 m_value_str.clear();
197 m_summary_str.clear();
198 }
199}
200
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201DataExtractor &
202ValueObject::GetDataExtractor ()
203{
Jim Ingham78a685a2011-04-16 00:01:13 +0000204 UpdateValueIfNeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205 return m_data;
206}
207
208const Error &
209ValueObject::GetError() const
210{
211 return m_error;
212}
213
214const ConstString &
215ValueObject::GetName() const
216{
217 return m_name;
218}
219
220const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000221ValueObject::GetLocationAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000222{
Jim Ingham6035b672011-03-31 00:19:25 +0000223 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224 {
225 if (m_location_str.empty())
226 {
227 StreamString sstr;
228
229 switch (m_value.GetValueType())
230 {
231 default:
232 break;
233
234 case Value::eValueTypeScalar:
Greg Clayton526e5af2010-11-13 03:52:47 +0000235 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236 {
237 RegisterInfo *reg_info = m_value.GetRegisterInfo();
238 if (reg_info)
239 {
240 if (reg_info->name)
241 m_location_str = reg_info->name;
242 else if (reg_info->alt_name)
243 m_location_str = reg_info->alt_name;
244 break;
245 }
246 }
247 m_location_str = "scalar";
248 break;
249
250 case Value::eValueTypeLoadAddress:
251 case Value::eValueTypeFileAddress:
252 case Value::eValueTypeHostAddress:
253 {
254 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
255 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
256 m_location_str.swap(sstr.GetString());
257 }
258 break;
259 }
260 }
261 }
262 return m_location_str.c_str();
263}
264
265Value &
266ValueObject::GetValue()
267{
268 return m_value;
269}
270
271const Value &
272ValueObject::GetValue() const
273{
274 return m_value;
275}
276
277bool
Jim Ingham6035b672011-03-31 00:19:25 +0000278ValueObject::ResolveValue (Scalar &scalar)
Greg Clayton8f343b02010-11-04 01:54:29 +0000279{
280 ExecutionContext exe_ctx;
Jim Ingham6035b672011-03-31 00:19:25 +0000281 ExecutionContextScope *exe_scope = GetExecutionContextScope();
282 if (exe_scope)
283 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8f343b02010-11-04 01:54:29 +0000284 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
285 return scalar.IsValid();
286}
287
288bool
Greg Clayton288bdf92010-09-02 02:59:18 +0000289ValueObject::GetValueIsValid () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290{
Greg Clayton288bdf92010-09-02 02:59:18 +0000291 return m_value_is_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000292}
293
294
295void
296ValueObject::SetValueIsValid (bool b)
297{
Greg Clayton288bdf92010-09-02 02:59:18 +0000298 m_value_is_valid = b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000299}
300
301bool
Jim Ingham6035b672011-03-31 00:19:25 +0000302ValueObject::GetValueDidChange ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303{
Jim Ingham6035b672011-03-31 00:19:25 +0000304 GetValueAsCString ();
Greg Clayton288bdf92010-09-02 02:59:18 +0000305 return m_value_did_change;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306}
307
308void
309ValueObject::SetValueDidChange (bool value_changed)
310{
Greg Clayton288bdf92010-09-02 02:59:18 +0000311 m_value_did_change = value_changed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312}
313
314ValueObjectSP
315ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
316{
317 ValueObjectSP child_sp;
Greg Claytondea8cb42011-06-29 22:09:02 +0000318 // We may need to update our value if we are dynamic
319 if (IsPossibleDynamicType ())
320 UpdateValueIfNeeded();
321 if (idx < GetNumChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000323 // Check if we have already made the child value object?
324 if (can_create && m_children[idx] == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000326 // No we haven't created the child at this index, so lets have our
327 // subclass do it and cache the result for quick future access.
328 m_children[idx] = CreateChildAtIndex (idx, false, 0);
Jim Ingham78a685a2011-04-16 00:01:13 +0000329 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000330
331 if (m_children[idx] != NULL)
332 return m_children[idx]->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 }
334 return child_sp;
335}
336
337uint32_t
338ValueObject::GetIndexOfChildWithName (const ConstString &name)
339{
340 bool omit_empty_base_classes = true;
341 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000342 GetClangType(),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000343 name.GetCString(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 omit_empty_base_classes);
345}
346
347ValueObjectSP
348ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
349{
Greg Clayton710dd5a2011-01-08 20:28:42 +0000350 // when getting a child by name, it could be buried inside some base
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351 // classes (which really aren't part of the expression path), so we
352 // need a vector of indexes that can get us down to the correct child
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353 ValueObjectSP child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000354
Greg Claytondea8cb42011-06-29 22:09:02 +0000355 // We may need to update our value if we are dynamic
356 if (IsPossibleDynamicType ())
357 UpdateValueIfNeeded();
358
359 std::vector<uint32_t> child_indexes;
360 clang::ASTContext *clang_ast = GetClangAST();
361 void *clang_type = GetClangType();
362 bool omit_empty_base_classes = true;
363 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
364 clang_type,
365 name.GetCString(),
366 omit_empty_base_classes,
367 child_indexes);
368 if (num_child_indexes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000370 std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
371 std::vector<uint32_t>::const_iterator end = child_indexes.end ();
372
373 child_sp = GetChildAtIndex(*pos, can_create);
374 for (++pos; pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000376 if (child_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +0000377 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000378 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
379 child_sp = new_child_sp;
Jim Ingham78a685a2011-04-16 00:01:13 +0000380 }
Greg Claytondea8cb42011-06-29 22:09:02 +0000381 else
382 {
383 child_sp.reset();
384 }
385
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386 }
387 }
388 return child_sp;
389}
390
391
392uint32_t
393ValueObject::GetNumChildren ()
394{
Greg Clayton288bdf92010-09-02 02:59:18 +0000395 if (!m_children_count_valid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396 {
397 SetNumChildren (CalculateNumChildren());
398 }
399 return m_children.size();
400}
401void
402ValueObject::SetNumChildren (uint32_t num_children)
403{
Greg Clayton288bdf92010-09-02 02:59:18 +0000404 m_children_count_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405 m_children.resize(num_children);
406}
407
408void
409ValueObject::SetName (const char *name)
410{
411 m_name.SetCString(name);
412}
413
414void
415ValueObject::SetName (const ConstString &name)
416{
417 m_name = name;
418}
419
Jim Ingham58b59f92011-04-22 23:53:53 +0000420ValueObject *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
422{
Jim Ingham2eec4872011-05-07 00:10:58 +0000423 ValueObject *valobj = NULL;
Jim Ingham78a685a2011-04-16 00:01:13 +0000424
Greg Claytondea8cb42011-06-29 22:09:02 +0000425 bool omit_empty_base_classes = true;
426
427 std::string child_name_str;
428 uint32_t child_byte_size = 0;
429 int32_t child_byte_offset = 0;
430 uint32_t child_bitfield_bit_size = 0;
431 uint32_t child_bitfield_bit_offset = 0;
432 bool child_is_base_class = false;
433 bool child_is_deref_of_parent = false;
434
435 const bool transparent_pointers = synthetic_array_member == false;
436 clang::ASTContext *clang_ast = GetClangAST();
437 clang_type_t clang_type = GetClangType();
438 clang_type_t child_clang_type;
439
440 ExecutionContext exe_ctx;
441 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
442
443 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
444 clang_ast,
445 GetName().GetCString(),
446 clang_type,
447 idx,
448 transparent_pointers,
449 omit_empty_base_classes,
450 child_name_str,
451 child_byte_size,
452 child_byte_offset,
453 child_bitfield_bit_size,
454 child_bitfield_bit_offset,
455 child_is_base_class,
456 child_is_deref_of_parent);
457 if (child_clang_type && child_byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458 {
Greg Claytondea8cb42011-06-29 22:09:02 +0000459 if (synthetic_index)
460 child_byte_offset += child_byte_size * synthetic_index;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461
Greg Claytondea8cb42011-06-29 22:09:02 +0000462 ConstString child_name;
463 if (!child_name_str.empty())
464 child_name.SetCString (child_name_str.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465
Greg Claytondea8cb42011-06-29 22:09:02 +0000466 valobj = new ValueObjectChild (*this,
467 clang_ast,
468 child_clang_type,
469 child_name,
470 child_byte_size,
471 child_byte_offset,
472 child_bitfield_bit_size,
473 child_bitfield_bit_offset,
474 child_is_base_class,
475 child_is_deref_of_parent);
476 if (m_pointers_point_to_load_addrs)
477 valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000479
Jim Ingham58b59f92011-04-22 23:53:53 +0000480 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481}
482
483const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000484ValueObject::GetSummaryAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000485{
Jim Ingham6035b672011-03-31 00:19:25 +0000486 if (UpdateValueIfNeeded ())
Enrico Granata4becb372011-06-29 22:27:15 +0000487 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488 if (m_summary_str.empty())
489 {
Enrico Granata4becb372011-06-29 22:27:15 +0000490 if (m_last_summary_format.get())
491 {
492 StreamString s;
493 ExecutionContext exe_ctx;
494 this->GetExecutionContextScope()->CalculateExecutionContext(exe_ctx);
495 SymbolContext sc = exe_ctx.frame->GetSymbolContext(eSymbolContextEverything);
496 if (Debugger::FormatPrompt(m_last_summary_format->m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, this))
497 {
498 m_summary_str.swap(s.GetString());
499 return m_summary_str.c_str();
500 }
501 return NULL;
502 }
503
Greg Clayton73b472d2010-10-27 03:32:59 +0000504 clang_type_t clang_type = GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000505
506 // See if this is a pointer to a C string?
Greg Clayton737b9322010-09-13 03:32:57 +0000507 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000508 {
Greg Clayton737b9322010-09-13 03:32:57 +0000509 StreamString sstr;
Greg Clayton73b472d2010-10-27 03:32:59 +0000510 clang_type_t elem_or_pointee_clang_type;
511 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000512 GetClangAST(),
513 &elem_or_pointee_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +0000514
Jim Ingham6035b672011-03-31 00:19:25 +0000515 ExecutionContextScope *exe_scope = GetExecutionContextScope();
516 if (exe_scope)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517 {
Jim Ingham6035b672011-03-31 00:19:25 +0000518 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
519 ClangASTContext::IsCharType (elem_or_pointee_clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520 {
Jim Ingham6035b672011-03-31 00:19:25 +0000521 Process *process = exe_scope->CalculateProcess();
522 if (process != NULL)
523 {
524 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
525 AddressType cstr_address_type = eAddressTypeInvalid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526
Jim Ingham6035b672011-03-31 00:19:25 +0000527 size_t cstr_len = 0;
528 if (type_flags.Test (ClangASTContext::eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 {
Jim Ingham6035b672011-03-31 00:19:25 +0000530 // We have an array
531 cstr_len = ClangASTContext::GetArraySize (clang_type);
532 cstr_address = GetAddressOf (cstr_address_type, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533 }
Greg Clayton737b9322010-09-13 03:32:57 +0000534 else
535 {
Jim Ingham6035b672011-03-31 00:19:25 +0000536 // We have a pointer
537 cstr_address = GetPointerValue (cstr_address_type, true);
Greg Clayton737b9322010-09-13 03:32:57 +0000538 }
Jim Ingham6035b672011-03-31 00:19:25 +0000539 if (cstr_address != LLDB_INVALID_ADDRESS)
Greg Clayton737b9322010-09-13 03:32:57 +0000540 {
Jim Ingham6035b672011-03-31 00:19:25 +0000541 DataExtractor data;
542 size_t bytes_read = 0;
543 std::vector<char> data_buffer;
544 Error error;
545 if (cstr_len > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000546 {
Jim Ingham6035b672011-03-31 00:19:25 +0000547 data_buffer.resize(cstr_len);
548 data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
549 bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error);
550 if (bytes_read > 0)
Greg Clayton737b9322010-09-13 03:32:57 +0000551 {
Jim Ingham6035b672011-03-31 00:19:25 +0000552 sstr << '"';
553 data.Dump (&sstr,
554 0, // Start offset in "data"
Greg Clayton4e4294b2011-06-17 23:50:44 +0000555 eFormatCharArray, // Print as characters
Jim Ingham6035b672011-03-31 00:19:25 +0000556 1, // Size of item (1 byte for a char!)
557 bytes_read, // How many bytes to print?
558 UINT32_MAX, // num per line
559 LLDB_INVALID_ADDRESS,// base address
560 0, // bitfield bit size
561 0); // bitfield bit offset
562 sstr << '"';
Greg Clayton737b9322010-09-13 03:32:57 +0000563 }
564 }
Jim Ingham6035b672011-03-31 00:19:25 +0000565 else
566 {
567 const size_t k_max_buf_size = 256;
568 data_buffer.resize (k_max_buf_size + 1);
569 // NULL terminate in case we don't get the entire C string
570 data_buffer.back() = '\0';
Greg Clayton737b9322010-09-13 03:32:57 +0000571
Jim Ingham6035b672011-03-31 00:19:25 +0000572 sstr << '"';
573
574 data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
575 while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0)
576 {
577 size_t len = strlen(&data_buffer.front());
578 if (len == 0)
579 break;
580 if (len > bytes_read)
581 len = bytes_read;
582
583 data.Dump (&sstr,
584 0, // Start offset in "data"
Greg Clayton4e4294b2011-06-17 23:50:44 +0000585 eFormatCharArray, // Print as characters
Jim Ingham6035b672011-03-31 00:19:25 +0000586 1, // Size of item (1 byte for a char!)
587 len, // How many bytes to print?
588 UINT32_MAX, // num per line
589 LLDB_INVALID_ADDRESS,// base address
590 0, // bitfield bit size
591 0); // bitfield bit offset
592
593 if (len < k_max_buf_size)
594 break;
595 cstr_address += k_max_buf_size;
596 }
597 sstr << '"';
598 }
599 }
Greg Clayton737b9322010-09-13 03:32:57 +0000600 }
Jim Ingham6035b672011-03-31 00:19:25 +0000601
602 if (sstr.GetSize() > 0)
603 m_summary_str.assign (sstr.GetData(), sstr.GetSize());
Greg Clayton737b9322010-09-13 03:32:57 +0000604 }
Jim Ingham6035b672011-03-31 00:19:25 +0000605 else if (ClangASTContext::IsFunctionPointerType (clang_type))
Greg Clayton737b9322010-09-13 03:32:57 +0000606 {
Jim Ingham6035b672011-03-31 00:19:25 +0000607 AddressType func_ptr_address_type = eAddressTypeInvalid;
608 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
609
610 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
611 {
612 switch (func_ptr_address_type)
613 {
614 case eAddressTypeInvalid:
615 case eAddressTypeFile:
616 break;
617
618 case eAddressTypeLoad:
619 {
620 Address so_addr;
621 Target *target = exe_scope->CalculateTarget();
622 if (target && target->GetSectionLoadList().IsEmpty() == false)
623 {
624 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
625 {
626 so_addr.Dump (&sstr,
627 exe_scope,
628 Address::DumpStyleResolvedDescription,
629 Address::DumpStyleSectionNameOffset);
630 }
631 }
632 }
633 break;
634
635 case eAddressTypeHost:
636 break;
637 }
638 }
639 if (sstr.GetSize() > 0)
640 {
641 m_summary_str.assign (1, '(');
642 m_summary_str.append (sstr.GetData(), sstr.GetSize());
643 m_summary_str.append (1, ')');
644 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000645 }
646 }
647 }
648 }
649 }
650 if (m_summary_str.empty())
651 return NULL;
652 return m_summary_str.c_str();
653}
654
Jim Ingham53c47f12010-09-10 23:12:17 +0000655const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000656ValueObject::GetObjectDescription ()
Jim Ingham53c47f12010-09-10 23:12:17 +0000657{
658 if (!m_object_desc_str.empty())
659 return m_object_desc_str.c_str();
660
Jim Ingham6035b672011-03-31 00:19:25 +0000661 if (!UpdateValueIfNeeded ())
Jim Ingham53c47f12010-09-10 23:12:17 +0000662 return NULL;
Jim Ingham6035b672011-03-31 00:19:25 +0000663
664 ExecutionContextScope *exe_scope = GetExecutionContextScope();
665 if (exe_scope == NULL)
666 return NULL;
667
Jim Ingham53c47f12010-09-10 23:12:17 +0000668 Process *process = exe_scope->CalculateProcess();
Jim Ingham5a369122010-09-28 01:25:32 +0000669 if (process == NULL)
Jim Ingham53c47f12010-09-10 23:12:17 +0000670 return NULL;
Jim Ingham5a369122010-09-28 01:25:32 +0000671
Jim Ingham53c47f12010-09-10 23:12:17 +0000672 StreamString s;
Jim Ingham5a369122010-09-28 01:25:32 +0000673
674 lldb::LanguageType language = GetObjectRuntimeLanguage();
675 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
676
Jim Inghama2cf2632010-12-23 02:29:54 +0000677 if (runtime == NULL)
678 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000679 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
Jim Inghama2cf2632010-12-23 02:29:54 +0000680 clang_type_t opaque_qual_type = GetClangType();
681 if (opaque_qual_type != NULL)
682 {
Jim Inghamb7603bb2011-03-18 00:05:18 +0000683 bool is_signed;
684 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed)
685 || ClangASTContext::IsPointerType (opaque_qual_type))
686 {
Jim Inghama2cf2632010-12-23 02:29:54 +0000687 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Jim Inghamb7603bb2011-03-18 00:05:18 +0000688 }
Jim Inghama2cf2632010-12-23 02:29:54 +0000689 }
690 }
691
Jim Ingham8d543de2011-03-31 23:01:21 +0000692 if (runtime && runtime->GetObjectDescription(s, *this))
Jim Ingham53c47f12010-09-10 23:12:17 +0000693 {
694 m_object_desc_str.append (s.GetData());
695 }
Sean Callanan672ad942010-10-23 00:18:49 +0000696
697 if (m_object_desc_str.empty())
698 return NULL;
699 else
700 return m_object_desc_str.c_str();
Jim Ingham53c47f12010-09-10 23:12:17 +0000701}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000702
703const char *
Jim Ingham6035b672011-03-31 00:19:25 +0000704ValueObject::GetValueAsCString ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000705{
706 // If our byte size is zero this is an aggregate type that has children
Greg Clayton1be10fc2010-09-29 01:12:09 +0000707 if (ClangASTContext::IsAggregateType (GetClangType()) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000708 {
Jim Ingham6035b672011-03-31 00:19:25 +0000709 if (UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000710 {
711 if (m_value_str.empty())
712 {
713 const Value::ContextType context_type = m_value.GetContextType();
714
715 switch (context_type)
716 {
Greg Clayton526e5af2010-11-13 03:52:47 +0000717 case Value::eContextTypeClangType:
718 case Value::eContextTypeLLDBType:
719 case Value::eContextTypeVariable:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000720 {
Greg Clayton73b472d2010-10-27 03:32:59 +0000721 clang_type_t clang_type = GetClangType ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000722 if (clang_type)
723 {
724 StreamString sstr;
Greg Clayton68ebae62011-04-28 20:55:26 +0000725 Format format = GetFormat();
Enrico Granata4becb372011-06-29 22:27:15 +0000726 if (format == eFormatDefault)
727 {
728 if (m_last_value_format)
729 format = m_last_value_format->m_format;
730 else
731 format = ClangASTType::GetFormat(clang_type);
732 }
Greg Clayton32c40852010-10-06 03:09:11 +0000733
734 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
735 clang_type, // The clang type to display
736 &sstr,
Enrico Granata4becb372011-06-29 22:27:15 +0000737 format, // Format to display this type with
Greg Clayton32c40852010-10-06 03:09:11 +0000738 m_data, // Data to extract from
739 0, // Byte offset into "m_data"
740 GetByteSize(), // Byte size of item in "m_data"
741 GetBitfieldBitSize(), // Bitfield bit size
742 GetBitfieldBitOffset())) // Bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000743 m_value_str.swap(sstr.GetString());
744 else
Greg Clayton007d5be2011-05-30 00:49:24 +0000745 {
746 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
747 m_data.GetByteSize(),
748 GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000749 m_value_str.clear();
Greg Clayton007d5be2011-05-30 00:49:24 +0000750 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000751 }
752 }
753 break;
754
Greg Clayton526e5af2010-11-13 03:52:47 +0000755 case Value::eContextTypeRegisterInfo:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756 {
757 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
758 if (reg_info)
759 {
760 StreamString reg_sstr;
761 m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
762 m_value_str.swap(reg_sstr.GetString());
763 }
764 }
765 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000766
767 default:
768 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000769 }
770 }
Greg Clayton288bdf92010-09-02 02:59:18 +0000771
772 if (!m_value_did_change && m_old_value_valid)
773 {
774 // The value was gotten successfully, so we consider the
775 // value as changed if the value string differs
776 SetValueDidChange (m_old_value_str != m_value_str);
777 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000778 }
779 }
780 if (m_value_str.empty())
781 return NULL;
782 return m_value_str.c_str();
783}
784
Greg Clayton737b9322010-09-13 03:32:57 +0000785addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000786ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton73b472d2010-10-27 03:32:59 +0000787{
Jim Ingham78a685a2011-04-16 00:01:13 +0000788 if (!UpdateValueIfNeeded())
789 return LLDB_INVALID_ADDRESS;
790
Greg Clayton73b472d2010-10-27 03:32:59 +0000791 switch (m_value.GetValueType())
792 {
793 case Value::eValueTypeScalar:
794 if (scalar_is_load_address)
795 {
796 address_type = eAddressTypeLoad;
797 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
798 }
799 break;
800
801 case Value::eValueTypeLoadAddress:
802 case Value::eValueTypeFileAddress:
803 case Value::eValueTypeHostAddress:
804 {
805 address_type = m_value.GetValueAddressType ();
806 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
807 }
808 break;
809 }
810 address_type = eAddressTypeInvalid;
811 return LLDB_INVALID_ADDRESS;
812}
813
814addr_t
Greg Claytone0d378b2011-03-24 21:19:54 +0000815ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
Greg Clayton737b9322010-09-13 03:32:57 +0000816{
817 lldb::addr_t address = LLDB_INVALID_ADDRESS;
818 address_type = eAddressTypeInvalid;
Jim Ingham78a685a2011-04-16 00:01:13 +0000819
820 if (!UpdateValueIfNeeded())
821 return address;
822
Greg Clayton73b472d2010-10-27 03:32:59 +0000823 switch (m_value.GetValueType())
Greg Clayton737b9322010-09-13 03:32:57 +0000824 {
825 case Value::eValueTypeScalar:
826 if (scalar_is_load_address)
827 {
828 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
829 address_type = eAddressTypeLoad;
830 }
831 break;
832
833 case Value::eValueTypeLoadAddress:
834 case Value::eValueTypeFileAddress:
835 case Value::eValueTypeHostAddress:
836 {
837 uint32_t data_offset = 0;
838 address = m_data.GetPointer(&data_offset);
839 address_type = m_value.GetValueAddressType();
840 if (address_type == eAddressTypeInvalid)
841 address_type = eAddressTypeLoad;
842 }
843 break;
844 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000845
846 if (m_pointers_point_to_load_addrs)
847 address_type = eAddressTypeLoad;
848
Greg Clayton737b9322010-09-13 03:32:57 +0000849 return address;
850}
851
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000852bool
Jim Ingham6035b672011-03-31 00:19:25 +0000853ValueObject::SetValueFromCString (const char *value_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000854{
855 // Make sure our value is up to date first so that our location and location
856 // type is valid.
Jim Ingham6035b672011-03-31 00:19:25 +0000857 if (!UpdateValueIfNeeded())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000858 return false;
859
860 uint32_t count = 0;
Greg Clayton1be10fc2010-09-29 01:12:09 +0000861 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000862
863 char *end = NULL;
Greg Claytonb1320972010-07-14 00:18:15 +0000864 const size_t byte_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865 switch (encoding)
866 {
867 case eEncodingInvalid:
868 return false;
869
870 case eEncodingUint:
871 if (byte_size > sizeof(unsigned long long))
872 {
873 return false;
874 }
875 else
876 {
877 unsigned long long ull_val = strtoull(value_str, &end, 0);
878 if (end && *end != '\0')
879 return false;
880 m_value = ull_val;
881 // Limit the bytes in our m_data appropriately.
882 m_value.GetScalar().GetData (m_data, byte_size);
883 }
884 break;
885
886 case eEncodingSint:
887 if (byte_size > sizeof(long long))
888 {
889 return false;
890 }
891 else
892 {
893 long long sll_val = strtoll(value_str, &end, 0);
894 if (end && *end != '\0')
895 return false;
896 m_value = sll_val;
897 // Limit the bytes in our m_data appropriately.
898 m_value.GetScalar().GetData (m_data, byte_size);
899 }
900 break;
901
902 case eEncodingIEEE754:
903 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000904 const off_t byte_offset = GetByteOffset();
Greg Claytonc982c762010-07-09 20:39:50 +0000905 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000906 if (dst != NULL)
907 {
908 // We are decoding a float into host byte order below, so make
909 // sure m_data knows what it contains.
Greg Clayton7fb56d02011-02-01 01:31:41 +0000910 m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
912 GetClangAST(),
Greg Clayton1be10fc2010-09-29 01:12:09 +0000913 GetClangType(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000914 value_str,
915 dst,
916 byte_size);
917
918 if (converted_byte_size == byte_size)
919 {
920 }
921 }
922 }
923 break;
924
925 case eEncodingVector:
926 return false;
927
928 default:
929 return false;
930 }
931
932 // If we have made it here the value is in m_data and we should write it
933 // out to the target
934 return Write ();
935}
936
937bool
938ValueObject::Write ()
939{
940 // Clear the update ID so the next time we try and read the value
941 // we try and read it again.
Jim Ingham6035b672011-03-31 00:19:25 +0000942 m_update_point.SetNeedsUpdate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000943
944 // TODO: when Value has a method to write a value back, call it from here.
945 return false;
946
947}
948
Jim Ingham5a369122010-09-28 01:25:32 +0000949lldb::LanguageType
950ValueObject::GetObjectRuntimeLanguage ()
951{
Greg Clayton73b472d2010-10-27 03:32:59 +0000952 clang_type_t opaque_qual_type = GetClangType();
Jim Ingham5a369122010-09-28 01:25:32 +0000953 if (opaque_qual_type == NULL)
954 return lldb::eLanguageTypeC;
955
956 // If the type is a reference, then resolve it to what it refers to first:
957 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
958 if (qual_type->isAnyPointerType())
959 {
960 if (qual_type->isObjCObjectPointerType())
961 return lldb::eLanguageTypeObjC;
962
963 clang::QualType pointee_type (qual_type->getPointeeType());
964 if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
965 return lldb::eLanguageTypeC_plus_plus;
966 if (pointee_type->isObjCObjectOrInterfaceType())
967 return lldb::eLanguageTypeObjC;
968 if (pointee_type->isObjCClassType())
969 return lldb::eLanguageTypeObjC;
970 }
971 else
972 {
973 if (ClangASTContext::IsObjCClassType (opaque_qual_type))
974 return lldb::eLanguageTypeObjC;
Johnny Chend440bcc2010-09-28 16:10:54 +0000975 if (ClangASTContext::IsCXXClassType (opaque_qual_type))
Jim Ingham5a369122010-09-28 01:25:32 +0000976 return lldb::eLanguageTypeC_plus_plus;
977 }
978
979 return lldb::eLanguageTypeC;
980}
981
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000982void
Jim Ingham58b59f92011-04-22 23:53:53 +0000983ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000984{
Jim Ingham58b59f92011-04-22 23:53:53 +0000985 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000986}
987
988ValueObjectSP
989ValueObject::GetSyntheticChild (const ConstString &key) const
990{
991 ValueObjectSP synthetic_child_sp;
Jim Ingham58b59f92011-04-22 23:53:53 +0000992 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993 if (pos != m_synthetic_children.end())
Jim Ingham58b59f92011-04-22 23:53:53 +0000994 synthetic_child_sp = pos->second->GetSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000995 return synthetic_child_sp;
996}
997
998bool
999ValueObject::IsPointerType ()
1000{
Greg Clayton1be10fc2010-09-29 01:12:09 +00001001 return ClangASTContext::IsPointerType (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001002}
1003
Jim Inghamb7603bb2011-03-18 00:05:18 +00001004bool
1005ValueObject::IsIntegerType (bool &is_signed)
1006{
1007 return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
1008}
Greg Clayton73b472d2010-10-27 03:32:59 +00001009
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001010bool
1011ValueObject::IsPointerOrReferenceType ()
1012{
Greg Clayton007d5be2011-05-30 00:49:24 +00001013 return ClangASTContext::IsPointerOrReferenceType (GetClangType());
1014}
1015
1016bool
1017ValueObject::IsPossibleCPlusPlusDynamicType ()
1018{
1019 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001020}
1021
Greg Claytondea8cb42011-06-29 22:09:02 +00001022bool
1023ValueObject::IsPossibleDynamicType ()
1024{
1025 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
1026}
1027
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001028ValueObjectSP
1029ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
1030{
1031 ValueObjectSP synthetic_child_sp;
1032 if (IsPointerType ())
1033 {
1034 char index_str[64];
1035 snprintf(index_str, sizeof(index_str), "[%i]", index);
1036 ConstString index_const_str(index_str);
1037 // Check if we have already created a synthetic array member in this
1038 // valid object. If we have we will re-use it.
1039 synthetic_child_sp = GetSyntheticChild (index_const_str);
1040 if (!synthetic_child_sp)
1041 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001042 ValueObject *synthetic_child;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001043 // We haven't made a synthetic array member for INDEX yet, so
1044 // lets make one and cache it for any future reference.
Jim Ingham58b59f92011-04-22 23:53:53 +00001045 synthetic_child = CreateChildAtIndex(0, true, index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046
1047 // Cache the value if we got one back...
Jim Ingham58b59f92011-04-22 23:53:53 +00001048 if (synthetic_child)
1049 {
1050 AddSyntheticChild(index_const_str, synthetic_child);
1051 synthetic_child_sp = synthetic_child->GetSP();
1052 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001053 }
1054 }
1055 return synthetic_child_sp;
1056}
Jim Ingham22777012010-09-23 02:01:19 +00001057
Jim Ingham78a685a2011-04-16 00:01:13 +00001058void
Jim Ingham2837b762011-05-04 03:43:18 +00001059ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
Jim Ingham22777012010-09-23 02:01:19 +00001060{
Jim Ingham2837b762011-05-04 03:43:18 +00001061 if (use_dynamic == lldb::eNoDynamicValues)
1062 return;
1063
Jim Ingham58b59f92011-04-22 23:53:53 +00001064 if (!m_dynamic_value && !IsDynamic())
Jim Ingham78a685a2011-04-16 00:01:13 +00001065 {
1066 Process *process = m_update_point.GetProcess();
1067 bool worth_having_dynamic_value = false;
Jim Ingham22777012010-09-23 02:01:19 +00001068
Jim Ingham78a685a2011-04-16 00:01:13 +00001069
1070 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to
1071 // hard code this everywhere.
1072 lldb::LanguageType known_type = GetObjectRuntimeLanguage();
1073 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
1074 {
1075 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
1076 if (runtime)
1077 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this);
1078 }
1079 else
1080 {
1081 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
1082 if (cpp_runtime)
1083 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this);
1084
1085 if (!worth_having_dynamic_value)
1086 {
1087 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
1088 if (objc_runtime)
Jim Ingham2837b762011-05-04 03:43:18 +00001089 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this);
Jim Ingham78a685a2011-04-16 00:01:13 +00001090 }
1091 }
1092
1093 if (worth_having_dynamic_value)
Jim Ingham2837b762011-05-04 03:43:18 +00001094 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
Jim Ingham58b59f92011-04-22 23:53:53 +00001095
1096// if (worth_having_dynamic_value)
1097// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager);
1098
Jim Ingham78a685a2011-04-16 00:01:13 +00001099 }
1100}
1101
Jim Ingham58b59f92011-04-22 23:53:53 +00001102ValueObjectSP
Jim Ingham2837b762011-05-04 03:43:18 +00001103ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +00001104{
Jim Ingham2837b762011-05-04 03:43:18 +00001105 if (use_dynamic == lldb::eNoDynamicValues)
1106 return ValueObjectSP();
1107
1108 if (!IsDynamic() && m_dynamic_value == NULL)
Jim Ingham78a685a2011-04-16 00:01:13 +00001109 {
Jim Ingham2837b762011-05-04 03:43:18 +00001110 CalculateDynamicValue(use_dynamic);
Jim Ingham78a685a2011-04-16 00:01:13 +00001111 }
Jim Ingham58b59f92011-04-22 23:53:53 +00001112 if (m_dynamic_value)
1113 return m_dynamic_value->GetSP();
1114 else
1115 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001116}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001117
Greg Claytone221f822011-01-21 01:59:00 +00001118bool
1119ValueObject::GetBaseClassPath (Stream &s)
1120{
1121 if (IsBaseClass())
1122 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001123 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
Greg Claytone221f822011-01-21 01:59:00 +00001124 clang_type_t clang_type = GetClangType();
1125 std::string cxx_class_name;
1126 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
1127 if (this_had_base_class)
1128 {
1129 if (parent_had_base_class)
1130 s.PutCString("::");
1131 s.PutCString(cxx_class_name.c_str());
1132 }
1133 return parent_had_base_class || this_had_base_class;
1134 }
1135 return false;
1136}
1137
1138
1139ValueObject *
1140ValueObject::GetNonBaseClassParent()
1141{
Jim Ingham78a685a2011-04-16 00:01:13 +00001142 if (GetParent())
Greg Claytone221f822011-01-21 01:59:00 +00001143 {
Jim Ingham78a685a2011-04-16 00:01:13 +00001144 if (GetParent()->IsBaseClass())
1145 return GetParent()->GetNonBaseClassParent();
Greg Claytone221f822011-01-21 01:59:00 +00001146 else
Jim Ingham78a685a2011-04-16 00:01:13 +00001147 return GetParent();
Greg Claytone221f822011-01-21 01:59:00 +00001148 }
1149 return NULL;
1150}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001151
1152void
Enrico Granata4becb372011-06-29 22:27:15 +00001153ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001154{
Greg Claytone221f822011-01-21 01:59:00 +00001155 const bool is_deref_of_parent = IsDereferenceOfParent ();
Greg Claytone221f822011-01-21 01:59:00 +00001156
Enrico Granata4becb372011-06-29 22:27:15 +00001157 if(is_deref_of_parent && epformat == eDereferencePointers) {
1158 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
1159 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
1160 // the eHonorPointers mode is meant to produce strings in this latter format
1161 s.PutCString("*(");
1162 }
Greg Claytone221f822011-01-21 01:59:00 +00001163
Enrico Granata4becb372011-06-29 22:27:15 +00001164 ValueObject* parent = GetParent();
1165
1166 if (parent)
1167 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
1168
Greg Claytone221f822011-01-21 01:59:00 +00001169 if (!IsBaseClass())
1170 {
1171 if (!is_deref_of_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001172 {
Greg Claytone221f822011-01-21 01:59:00 +00001173 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1174 if (non_base_class_parent)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001175 {
Greg Claytone221f822011-01-21 01:59:00 +00001176 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
1177 if (non_base_class_parent_clang_type)
1178 {
1179 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
1180
Enrico Granata4becb372011-06-29 22:27:15 +00001181 if(parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
Greg Claytone221f822011-01-21 01:59:00 +00001182 {
1183 s.PutCString("->");
1184 }
Enrico Granata4becb372011-06-29 22:27:15 +00001185 else
1186 {
1187 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
1188 {
1189 s.PutCString("->");
1190 }
1191 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
1192 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
1193 {
1194 s.PutChar('.');
1195 }
Greg Claytone221f822011-01-21 01:59:00 +00001196 }
1197 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001198 }
Greg Claytone221f822011-01-21 01:59:00 +00001199
1200 const char *name = GetName().GetCString();
1201 if (name)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001202 {
Greg Claytone221f822011-01-21 01:59:00 +00001203 if (qualify_cxx_base_classes)
1204 {
1205 if (GetBaseClassPath (s))
1206 s.PutCString("::");
1207 }
1208 s.PutCString(name);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001209 }
1210 }
1211 }
1212
Enrico Granata4becb372011-06-29 22:27:15 +00001213 if (is_deref_of_parent && epformat == eDereferencePointers) {
Greg Claytone221f822011-01-21 01:59:00 +00001214 s.PutChar(')');
Enrico Granata4becb372011-06-29 22:27:15 +00001215 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001216}
1217
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001218void
Greg Clayton1d3afba2010-10-05 00:00:42 +00001219ValueObject::DumpValueObject
1220(
1221 Stream &s,
Greg Clayton1d3afba2010-10-05 00:00:42 +00001222 ValueObject *valobj,
1223 const char *root_valobj_name,
1224 uint32_t ptr_depth,
1225 uint32_t curr_depth,
1226 uint32_t max_depth,
1227 bool show_types,
1228 bool show_location,
1229 bool use_objc,
Jim Ingham2837b762011-05-04 03:43:18 +00001230 lldb::DynamicValueType use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001231 bool scope_already_checked,
1232 bool flat_output
Greg Clayton1d3afba2010-10-05 00:00:42 +00001233)
1234{
Greg Clayton007d5be2011-05-30 00:49:24 +00001235 if (valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001236 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001237 bool update_success = valobj->UpdateValueIfNeeded ();
1238
1239 if (update_success && use_dynamic != lldb::eNoDynamicValues)
Jim Ingham78a685a2011-04-16 00:01:13 +00001240 {
Jim Ingham2837b762011-05-04 03:43:18 +00001241 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
Jim Ingham78a685a2011-04-16 00:01:13 +00001242 if (dynamic_value)
1243 valobj = dynamic_value;
1244 }
1245
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001246 clang_type_t clang_type = valobj->GetClangType();
1247
Greg Clayton73b472d2010-10-27 03:32:59 +00001248 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001249 const char *err_cstr = NULL;
Greg Clayton73b472d2010-10-27 03:32:59 +00001250 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
1251 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001252
1253 const bool print_valobj = flat_output == false || has_value;
1254
1255 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001256 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001257 if (show_location)
1258 {
Jim Ingham6035b672011-03-31 00:19:25 +00001259 s.Printf("%s: ", valobj->GetLocationAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001260 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001261
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001262 s.Indent();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001263
Greg Clayton7c8a9662010-11-02 01:50:16 +00001264 // Always show the type for the top level items.
Greg Claytone221f822011-01-21 01:59:00 +00001265 if (show_types || (curr_depth == 0 && !flat_output))
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001266 s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
Greg Clayton1d3afba2010-10-05 00:00:42 +00001267
Greg Clayton1d3afba2010-10-05 00:00:42 +00001268
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001269 if (flat_output)
1270 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001271 // If we are showing types, also qualify the C++ base classes
1272 const bool qualify_cxx_base_classes = show_types;
1273 valobj->GetExpressionPath(s, qualify_cxx_base_classes);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001274 s.PutCString(" =");
1275 }
1276 else
1277 {
1278 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
1279 s.Printf ("%s =", name_cstr);
1280 }
1281
Jim Ingham6035b672011-03-31 00:19:25 +00001282 if (!scope_already_checked && !valobj->IsInScope())
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001283 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001284 err_cstr = "out of scope";
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001285 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001286 }
1287
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001288 const char *val_cstr = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00001289 const char *sum_cstr = NULL;
1290 SummaryFormat* entry = valobj->m_last_summary_format.get();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001291
1292 if (err_cstr == NULL)
1293 {
Jim Ingham6035b672011-03-31 00:19:25 +00001294 val_cstr = valobj->GetValueAsCString();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001295 err_cstr = valobj->GetError().AsCString();
1296 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001297
1298 if (err_cstr)
1299 {
Greg Clayton007d5be2011-05-30 00:49:24 +00001300 s.Printf (" <%s>\n", err_cstr);
Greg Clayton1d3afba2010-10-05 00:00:42 +00001301 }
1302 else
1303 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001304 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001305 if (print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001306 {
Enrico Granata4becb372011-06-29 22:27:15 +00001307
1308 sum_cstr = valobj->GetSummaryAsCString();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001309
Enrico Granata4becb372011-06-29 22:27:15 +00001310 // We must calculate this value in realtime because entry might alter this variable's value
1311 // (e.g. by saying ${var%fmt}) and render precached values useless
1312 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
1313 s.Printf(" %s", valobj->GetValueAsCString());
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001314
1315 if (sum_cstr)
1316 s.Printf(" %s", sum_cstr);
1317
1318 if (use_objc)
1319 {
Jim Ingham6035b672011-03-31 00:19:25 +00001320 const char *object_desc = valobj->GetObjectDescription();
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001321 if (object_desc)
1322 s.Printf(" %s\n", object_desc);
1323 else
Sean Callanan672ad942010-10-23 00:18:49 +00001324 s.Printf (" [no Objective-C description available]\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001325 return;
1326 }
1327 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001328
1329 if (curr_depth < max_depth)
1330 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001331 // We will show children for all concrete types. We won't show
1332 // pointer contents unless a pointer depth has been specified.
1333 // We won't reference contents unless the reference is the
1334 // root object (depth of zero).
1335 bool print_children = true;
1336
1337 // Use a new temporary pointer depth in case we override the
1338 // current pointer depth below...
1339 uint32_t curr_ptr_depth = ptr_depth;
1340
1341 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
1342 if (is_ptr || is_ref)
1343 {
1344 // We have a pointer or reference whose value is an address.
1345 // Make sure that address is not NULL
Greg Claytone0d378b2011-03-24 21:19:54 +00001346 AddressType ptr_address_type;
Greg Clayton73b472d2010-10-27 03:32:59 +00001347 if (valobj->GetPointerValue (ptr_address_type, true) == 0)
1348 print_children = false;
1349
1350 else if (is_ref && curr_depth == 0)
1351 {
1352 // If this is the root object (depth is zero) that we are showing
1353 // and it is a reference, and no pointer depth has been supplied
1354 // print out what it references. Don't do this at deeper depths
1355 // otherwise we can end up with infinite recursion...
1356 curr_ptr_depth = 1;
1357 }
1358
1359 if (curr_ptr_depth == 0)
1360 print_children = false;
1361 }
Greg Clayton1d3afba2010-10-05 00:00:42 +00001362
Enrico Granata4becb372011-06-29 22:27:15 +00001363 if (entry && entry->IsOneliner())
1364 {
1365 const uint32_t num_children = valobj->GetNumChildren();
1366 if (num_children)
1367 {
1368
1369 s.PutChar('(');
1370
1371 for (uint32_t idx=0; idx<num_children; ++idx)
1372 {
1373 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
1374 if (child_sp.get())
1375 {
1376 if (idx)
1377 s.PutCString(", ");
1378 s.PutCString(child_sp.get()->GetName().AsCString());
1379 s.PutChar('=');
1380 s.PutCString(child_sp.get()->GetValueAsCString());
1381 }
1382 }
1383
1384 s.PutChar(')');
1385 s.EOL();
1386 }
1387 }
1388 else if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
Greg Clayton1d3afba2010-10-05 00:00:42 +00001389 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001390 const uint32_t num_children = valobj->GetNumChildren();
1391 if (num_children)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001392 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001393 if (flat_output)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001394 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001395 if (print_valobj)
1396 s.EOL();
1397 }
1398 else
1399 {
1400 if (print_valobj)
Greg Clayton93aa84e2010-10-29 04:59:35 +00001401 s.PutCString(is_ref ? ": {\n" : " {\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001402 s.IndentMore();
1403 }
1404
1405 for (uint32_t idx=0; idx<num_children; ++idx)
1406 {
1407 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
1408 if (child_sp.get())
1409 {
1410 DumpValueObject (s,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001411 child_sp.get(),
1412 NULL,
Greg Clayton73b472d2010-10-27 03:32:59 +00001413 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001414 curr_depth + 1,
1415 max_depth,
1416 show_types,
1417 show_location,
1418 false,
Jim Ingham78a685a2011-04-16 00:01:13 +00001419 use_dynamic,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001420 true,
1421 flat_output);
1422 }
1423 }
1424
1425 if (!flat_output)
1426 {
1427 s.IndentLess();
1428 s.Indent("}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001429 }
1430 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001431 else if (has_children)
1432 {
1433 // Aggregate, no children...
1434 if (print_valobj)
Greg Clayton73b472d2010-10-27 03:32:59 +00001435 s.PutCString(" {}\n");
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001436 }
1437 else
1438 {
1439 if (print_valobj)
1440 s.EOL();
1441 }
1442
Greg Clayton1d3afba2010-10-05 00:00:42 +00001443 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001444 else
1445 {
Greg Clayton1d3afba2010-10-05 00:00:42 +00001446 s.EOL();
Greg Clayton1d3afba2010-10-05 00:00:42 +00001447 }
1448 }
1449 else
1450 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001451 if (has_children && print_valobj)
Greg Clayton1d3afba2010-10-05 00:00:42 +00001452 {
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001453 s.PutCString("{...}\n");
Greg Clayton1d3afba2010-10-05 00:00:42 +00001454 }
1455 }
1456 }
1457 }
1458}
1459
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001460
1461ValueObjectSP
Jim Ingham6035b672011-03-31 00:19:25 +00001462ValueObject::CreateConstantValue (const ConstString &name)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001463{
1464 ValueObjectSP valobj_sp;
1465
Jim Ingham6035b672011-03-31 00:19:25 +00001466 if (UpdateValueIfNeeded() && m_error.Success())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001467 {
Jim Ingham6035b672011-03-31 00:19:25 +00001468 ExecutionContextScope *exe_scope = GetExecutionContextScope();
1469 if (exe_scope)
1470 {
1471 ExecutionContext exe_ctx;
1472 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001473
Jim Ingham6035b672011-03-31 00:19:25 +00001474 clang::ASTContext *ast = GetClangAST ();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001475
Jim Ingham6035b672011-03-31 00:19:25 +00001476 DataExtractor data;
1477 data.SetByteOrder (m_data.GetByteOrder());
1478 data.SetAddressByteSize(m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001479
Jim Ingham6035b672011-03-31 00:19:25 +00001480 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001481
Jim Ingham58b59f92011-04-22 23:53:53 +00001482 valobj_sp = ValueObjectConstResult::Create (exe_scope,
1483 ast,
1484 GetClangType(),
1485 name,
1486 data);
Jim Ingham6035b672011-03-31 00:19:25 +00001487 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001488 }
Jim Ingham6035b672011-03-31 00:19:25 +00001489
1490 if (!valobj_sp)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001491 {
Jim Ingham58b59f92011-04-22 23:53:53 +00001492 valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001493 }
1494 return valobj_sp;
1495}
1496
1497lldb::ValueObjectSP
Greg Claytonaf67cec2010-12-20 20:49:23 +00001498ValueObject::Dereference (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001499{
Jim Ingham58b59f92011-04-22 23:53:53 +00001500 if (m_deref_valobj)
1501 return m_deref_valobj->GetSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00001502
Greg Clayton54979cd2010-12-15 05:08:08 +00001503 const bool is_pointer_type = IsPointerType();
1504 if (is_pointer_type)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001505 {
1506 bool omit_empty_base_classes = true;
1507
1508 std::string child_name_str;
1509 uint32_t child_byte_size = 0;
1510 int32_t child_byte_offset = 0;
1511 uint32_t child_bitfield_bit_size = 0;
1512 uint32_t child_bitfield_bit_offset = 0;
1513 bool child_is_base_class = false;
Greg Claytone221f822011-01-21 01:59:00 +00001514 bool child_is_deref_of_parent = false;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001515 const bool transparent_pointers = false;
1516 clang::ASTContext *clang_ast = GetClangAST();
1517 clang_type_t clang_type = GetClangType();
1518 clang_type_t child_clang_type;
Jim Inghamd555bac2011-06-24 22:03:24 +00001519
1520 ExecutionContext exe_ctx;
1521 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
1522
1523 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
1524 clang_ast,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001525 GetName().GetCString(),
1526 clang_type,
1527 0,
1528 transparent_pointers,
1529 omit_empty_base_classes,
1530 child_name_str,
1531 child_byte_size,
1532 child_byte_offset,
1533 child_bitfield_bit_size,
1534 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00001535 child_is_base_class,
1536 child_is_deref_of_parent);
Greg Clayton3e06bd92011-01-09 21:07:35 +00001537 if (child_clang_type && child_byte_size)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001538 {
1539 ConstString child_name;
1540 if (!child_name_str.empty())
1541 child_name.SetCString (child_name_str.c_str());
1542
Jim Ingham58b59f92011-04-22 23:53:53 +00001543 m_deref_valobj = new ValueObjectChild (*this,
1544 clang_ast,
1545 child_clang_type,
1546 child_name,
1547 child_byte_size,
1548 child_byte_offset,
1549 child_bitfield_bit_size,
1550 child_bitfield_bit_offset,
1551 child_is_base_class,
1552 child_is_deref_of_parent);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001553 }
1554 }
Greg Clayton54979cd2010-12-15 05:08:08 +00001555
Jim Ingham58b59f92011-04-22 23:53:53 +00001556 if (m_deref_valobj)
Greg Clayton54979cd2010-12-15 05:08:08 +00001557 {
1558 error.Clear();
Jim Ingham58b59f92011-04-22 23:53:53 +00001559 return m_deref_valobj->GetSP();
Greg Clayton54979cd2010-12-15 05:08:08 +00001560 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001561 else
1562 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001563 StreamString strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001564 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001565
1566 if (is_pointer_type)
1567 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
1568 else
1569 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
Jim Ingham58b59f92011-04-22 23:53:53 +00001570 return ValueObjectSP();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001571 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001572}
1573
Jim Ingham78a685a2011-04-16 00:01:13 +00001574lldb::ValueObjectSP
Greg Clayton54979cd2010-12-15 05:08:08 +00001575ValueObject::AddressOf (Error &error)
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001576{
Jim Ingham78a685a2011-04-16 00:01:13 +00001577 if (m_addr_of_valobj_sp)
1578 return m_addr_of_valobj_sp;
1579
Greg Claytone0d378b2011-03-24 21:19:54 +00001580 AddressType address_type = eAddressTypeInvalid;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001581 const bool scalar_is_load_address = false;
1582 lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
Greg Clayton54979cd2010-12-15 05:08:08 +00001583 error.Clear();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001584 if (addr != LLDB_INVALID_ADDRESS)
1585 {
1586 switch (address_type)
1587 {
Greg Clayton54979cd2010-12-15 05:08:08 +00001588 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001589 case eAddressTypeInvalid:
Greg Clayton54979cd2010-12-15 05:08:08 +00001590 {
1591 StreamString expr_path_strm;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001592 GetExpressionPath(expr_path_strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00001593 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
1594 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001595 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00001596
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001597 case eAddressTypeFile:
1598 case eAddressTypeLoad:
1599 case eAddressTypeHost:
1600 {
1601 clang::ASTContext *ast = GetClangAST();
1602 clang_type_t clang_type = GetClangType();
1603 if (ast && clang_type)
1604 {
1605 std::string name (1, '&');
1606 name.append (m_name.AsCString(""));
Jim Ingham58b59f92011-04-22 23:53:53 +00001607 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(),
1608 ast,
1609 ClangASTContext::CreatePointerType (ast, clang_type),
1610 ConstString (name.c_str()),
1611 addr,
1612 eAddressTypeInvalid,
1613 m_data.GetAddressByteSize());
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001614 }
1615 }
1616 break;
1617 }
1618 }
Jim Ingham78a685a2011-04-16 00:01:13 +00001619 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001620}
1621
Greg Claytonb2dcc362011-05-05 23:32:56 +00001622
1623lldb::ValueObjectSP
1624ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
1625{
1626 lldb::ValueObjectSP valobj_sp;
1627 AddressType address_type;
1628 const bool scalar_is_load_address = true;
1629 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
1630
1631 if (ptr_value != LLDB_INVALID_ADDRESS)
1632 {
1633 Address ptr_addr (NULL, ptr_value);
1634
1635 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
1636 name,
1637 ptr_addr,
1638 clang_ast_type);
1639 }
1640 return valobj_sp;
1641}
1642
1643lldb::ValueObjectSP
1644ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
1645{
1646 lldb::ValueObjectSP valobj_sp;
1647 AddressType address_type;
1648 const bool scalar_is_load_address = true;
1649 lldb::addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
1650
1651 if (ptr_value != LLDB_INVALID_ADDRESS)
1652 {
1653 Address ptr_addr (NULL, ptr_value);
1654
1655 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(),
1656 name,
1657 ptr_addr,
1658 type_sp);
1659 }
1660 return valobj_sp;
1661}
1662
1663
Jim Ingham6035b672011-03-31 00:19:25 +00001664ValueObject::EvaluationPoint::EvaluationPoint () :
Stephen Wilson71c21d12011-04-11 19:41:40 +00001665 m_thread_id (LLDB_INVALID_UID),
1666 m_stop_id (0)
Jim Ingham6035b672011-03-31 00:19:25 +00001667{
1668}
1669
1670ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
Jim Ingham6035b672011-03-31 00:19:25 +00001671 m_needs_update (true),
Stephen Wilson71c21d12011-04-11 19:41:40 +00001672 m_first_update (true),
1673 m_thread_id (LLDB_INVALID_UID),
1674 m_stop_id (0)
1675
Jim Ingham6035b672011-03-31 00:19:25 +00001676{
1677 ExecutionContext exe_ctx;
1678 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
1679 // and if so we want to cache that not the original.
1680 if (exe_scope)
1681 exe_scope->CalculateExecutionContext(exe_ctx);
1682 if (exe_ctx.target != NULL)
1683 {
1684 m_target_sp = exe_ctx.target->GetSP();
1685
1686 if (exe_ctx.process == NULL)
1687 m_process_sp = exe_ctx.target->GetProcessSP();
1688 else
1689 m_process_sp = exe_ctx.process->GetSP();
1690
1691 if (m_process_sp != NULL)
1692 {
1693 m_stop_id = m_process_sp->GetStopID();
1694 Thread *thread = NULL;
1695
1696 if (exe_ctx.thread == NULL)
1697 {
1698 if (use_selected)
1699 {
1700 thread = m_process_sp->GetThreadList().GetSelectedThread().get();
1701 if (thread)
1702 computed_exe_scope = thread;
1703 }
1704 }
1705 else
1706 thread = exe_ctx.thread;
1707
1708 if (thread != NULL)
1709 {
1710 m_thread_id = thread->GetIndexID();
1711 if (exe_ctx.frame == NULL)
1712 {
1713 if (use_selected)
1714 {
1715 StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
1716 if (frame)
1717 {
1718 m_stack_id = frame->GetStackID();
1719 computed_exe_scope = frame;
1720 }
1721 }
1722 }
1723 else
1724 m_stack_id = exe_ctx.frame->GetStackID();
1725 }
1726 }
1727 }
1728 m_exe_scope = computed_exe_scope;
1729}
1730
1731ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
1732 m_exe_scope (rhs.m_exe_scope),
Stephen Wilson71c21d12011-04-11 19:41:40 +00001733 m_needs_update(true),
1734 m_first_update(true),
Jim Ingham6035b672011-03-31 00:19:25 +00001735 m_target_sp (rhs.m_target_sp),
1736 m_process_sp (rhs.m_process_sp),
1737 m_thread_id (rhs.m_thread_id),
1738 m_stack_id (rhs.m_stack_id),
Jim Ingham6035b672011-03-31 00:19:25 +00001739 m_stop_id (0)
1740{
1741}
1742
1743ValueObject::EvaluationPoint::~EvaluationPoint ()
1744{
1745}
1746
1747ExecutionContextScope *
1748ValueObject::EvaluationPoint::GetExecutionContextScope ()
1749{
1750 // We have to update before giving out the scope, or we could be handing out stale pointers.
1751 SyncWithProcessState();
1752
1753 return m_exe_scope;
1754}
1755
1756// This function checks the EvaluationPoint against the current process state. If the current
1757// state matches the evaluation point, or the evaluation point is already invalid, then we return
1758// false, meaning "no change". If the current state is different, we update our state, and return
1759// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
1760// future calls to NeedsUpdate will return true.
1761
1762bool
1763ValueObject::EvaluationPoint::SyncWithProcessState()
1764{
1765 // If we're already invalid, we don't need to do anything, and nothing has changed:
1766 if (m_stop_id == LLDB_INVALID_UID)
1767 {
1768 // Can't update with an invalid state.
1769 m_needs_update = false;
1770 return false;
1771 }
1772
1773 // If we don't have a process nothing can change.
1774 if (!m_process_sp)
1775 return false;
1776
1777 // If our stop id is the current stop ID, nothing has changed:
Jim Ingham78a685a2011-04-16 00:01:13 +00001778 uint32_t cur_stop_id = m_process_sp->GetStopID();
1779 if (m_stop_id == cur_stop_id)
Jim Ingham6035b672011-03-31 00:19:25 +00001780 return false;
1781
Jim Ingham78a685a2011-04-16 00:01:13 +00001782 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
1783 // In either case, we aren't going to be able to sync with the process state.
1784 if (cur_stop_id == 0)
1785 return false;
1786
1787 m_stop_id = cur_stop_id;
Jim Ingham6035b672011-03-31 00:19:25 +00001788 m_needs_update = true;
1789 m_exe_scope = m_process_sp.get();
1790
1791 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
1792 // doesn't, mark ourselves as invalid.
1793
1794 if (m_thread_id != LLDB_INVALID_THREAD_ID)
1795 {
1796 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
1797 if (our_thread == NULL)
1798 SetInvalid();
1799 else
1800 {
1801 m_exe_scope = our_thread;
1802
1803 if (m_stack_id.IsValid())
1804 {
1805 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
1806 if (our_frame == NULL)
1807 SetInvalid();
1808 else
1809 m_exe_scope = our_frame;
1810 }
1811 }
1812 }
1813 return true;
1814}
1815
Jim Ingham61be0902011-05-02 18:13:59 +00001816void
1817ValueObject::EvaluationPoint::SetUpdated ()
1818{
1819 m_first_update = false;
1820 m_needs_update = false;
1821 if (m_process_sp)
1822 m_stop_id = m_process_sp->GetStopID();
1823}
1824
1825
Jim Ingham6035b672011-03-31 00:19:25 +00001826bool
1827ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
1828{
1829 if (!IsValid())
1830 return false;
1831
1832 bool needs_update = false;
1833 m_exe_scope = NULL;
1834
1835 // The target has to be non-null, and the
1836 Target *target = exe_scope->CalculateTarget();
1837 if (target != NULL)
1838 {
1839 Target *old_target = m_target_sp.get();
1840 assert (target == old_target);
1841 Process *process = exe_scope->CalculateProcess();
1842 if (process != NULL)
1843 {
1844 // FOR NOW - assume you can't update variable objects across process boundaries.
1845 Process *old_process = m_process_sp.get();
1846 assert (process == old_process);
1847
1848 lldb::user_id_t stop_id = process->GetStopID();
1849 if (stop_id != m_stop_id)
1850 {
1851 needs_update = true;
1852 m_stop_id = stop_id;
1853 }
1854 // See if we're switching the thread or stack context. If no thread is given, this is
1855 // being evaluated in a global context.
1856 Thread *thread = exe_scope->CalculateThread();
1857 if (thread != NULL)
1858 {
1859 lldb::user_id_t new_thread_index = thread->GetIndexID();
1860 if (new_thread_index != m_thread_id)
1861 {
1862 needs_update = true;
1863 m_thread_id = new_thread_index;
1864 m_stack_id.Clear();
1865 }
1866
1867 StackFrame *new_frame = exe_scope->CalculateStackFrame();
1868 if (new_frame != NULL)
1869 {
1870 if (new_frame->GetStackID() != m_stack_id)
1871 {
1872 needs_update = true;
1873 m_stack_id = new_frame->GetStackID();
1874 }
1875 }
1876 else
1877 {
1878 m_stack_id.Clear();
1879 needs_update = true;
1880 }
1881 }
1882 else
1883 {
1884 // If this had been given a thread, and now there is none, we should update.
1885 // Otherwise we don't have to do anything.
1886 if (m_thread_id != LLDB_INVALID_UID)
1887 {
1888 m_thread_id = LLDB_INVALID_UID;
1889 m_stack_id.Clear();
1890 needs_update = true;
1891 }
1892 }
1893 }
1894 else
1895 {
1896 // If there is no process, then we don't need to update anything.
1897 // But if we're switching from having a process to not, we should try to update.
1898 if (m_process_sp.get() != NULL)
1899 {
1900 needs_update = true;
1901 m_process_sp.reset();
1902 m_thread_id = LLDB_INVALID_UID;
1903 m_stack_id.Clear();
1904 }
1905 }
1906 }
1907 else
1908 {
1909 // If there's no target, nothing can change so we don't need to update anything.
1910 // But if we're switching from having a target to not, we should try to update.
1911 if (m_target_sp.get() != NULL)
1912 {
1913 needs_update = true;
1914 m_target_sp.reset();
1915 m_process_sp.reset();
1916 m_thread_id = LLDB_INVALID_UID;
1917 m_stack_id.Clear();
1918 }
1919 }
1920 if (!m_needs_update)
1921 m_needs_update = needs_update;
1922
1923 return needs_update;
1924}