blob: 381763dab8e1dd74f7fd705e0a8eb8b05ad71486 [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
Zachary Turner2f3df612017-04-06 21:28:29 +000012#include "lldb/Core/Address.h" // for Address
Greg Clayton1f746072012-08-29 21:13:06 +000013#include "lldb/Core/Module.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000014#include "lldb/Core/Scalar.h" // for Scalar
Enrico Granata21fd13f2012-10-27 02:05:48 +000015#include "lldb/Core/ValueObjectCast.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/ValueObjectChild.h"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000017#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000018#include "lldb/Core/ValueObjectDynamicValue.h"
Greg Claytonb2dcc362011-05-05 23:32:56 +000019#include "lldb/Core/ValueObjectMemory.h"
Enrico Granatad55546b2011-07-22 00:16:08 +000020#include "lldb/Core/ValueObjectSyntheticFilter.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000021#include "lldb/DataFormatters/DataVisualization.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000022#include "lldb/DataFormatters/FormatManager.h" // for FormatManager
Enrico Granata2206b482014-10-30 18:27:31 +000023#include "lldb/DataFormatters/StringPrinter.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000024#include "lldb/DataFormatters/TypeFormat.h" // for TypeFormatImpl_F...
25#include "lldb/DataFormatters/TypeSummary.h" // for TypeSummaryOptions
26#include "lldb/DataFormatters/TypeValidator.h" // for TypeValidatorImp...
Enrico Granata4d93b8c2013-09-30 19:11:51 +000027#include "lldb/DataFormatters/ValueObjectPrinter.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000028#include "lldb/Expression/ExpressionVariable.h" // for ExpressionVariable
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Symbol/ClangASTContext.h"
Enrico Granatac1247f52014-11-06 21:23:20 +000030#include "lldb/Symbol/CompileUnit.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000031#include "lldb/Symbol/CompilerType.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000032#include "lldb/Symbol/Declaration.h" // for Declaration
33#include "lldb/Symbol/SymbolContext.h" // for SymbolContext
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Symbol/Type.h"
Jim Ingham53c47f12010-09-10 23:12:17 +000035#include "lldb/Target/ExecutionContext.h"
Enrico Granata407b5c62015-11-02 21:52:05 +000036#include "lldb/Target/Language.h"
Jim Ingham5a369122010-09-28 01:25:32 +000037#include "lldb/Target/LanguageRuntime.h"
Enrico Granatac3e320a2011-08-02 17:27:39 +000038#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Target/Process.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000040#include "lldb/Target/StackFrame.h" // for StackFrame
Greg Claytonf5e56de2010-09-14 23:36:40 +000041#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042#include "lldb/Target/Thread.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000043#include "lldb/Target/ThreadList.h" // for ThreadList
44#include "lldb/Utility/DataBuffer.h" // for DataBuffer
45#include "lldb/Utility/DataBufferHeap.h"
46#include "lldb/Utility/Flags.h" // for Flags
47#include "lldb/Utility/Log.h"
48#include "lldb/Utility/Logging.h" // for GetLogIfAllCateg...
49#include "lldb/Utility/SharingPtr.h" // for SharingPtr
50#include "lldb/Utility/Stream.h" // for Stream
51#include "lldb/Utility/StreamString.h"
52#include "lldb/lldb-private-types.h" // for RegisterInfo
53
54#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH
55
56#include <algorithm> // for min
57#include <cstdint> // for uint32_t, uint64_t
58#include <cstdlib> // for size_t, NULL
59#include <memory> // for shared_ptr, oper...
60#include <tuple> // for tie, tuple
61
62#include <assert.h> // for assert
63#include <inttypes.h> // for PRIu64, PRIx64
64#include <stdio.h> // for snprintf
65#include <string.h> // for memcpy, memcmp
66
67namespace lldb_private {
68class ExecutionContextScope;
69}
70namespace lldb_private {
71class SymbolContextScope;
72}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073
74using namespace lldb;
75using namespace lldb_private;
Enrico Granataf4efecd2011-07-12 22:56:10 +000076using namespace lldb_utility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077
Greg Claytonafacd142011-09-02 01:15:17 +000078static user_id_t g_value_obj_uid = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079
80//----------------------------------------------------------------------
81// ValueObject constructor
82//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000083ValueObject::ValueObject(ValueObject &parent)
84 : UserID(++g_value_obj_uid), // Unique identifier for every value object
85 m_parent(&parent), m_root(NULL), m_update_point(parent.GetUpdatePoint()),
86 m_name(), m_data(), m_value(), m_error(), m_value_str(),
87 m_old_value_str(), m_location_str(), m_summary_str(), m_object_desc_str(),
88 m_validation_result(), m_manager(parent.GetManager()), m_children(),
89 m_synthetic_children(), m_dynamic_value(NULL), m_synthetic_value(NULL),
90 m_deref_valobj(NULL), m_format(eFormatDefault),
91 m_last_format(eFormatDefault), m_last_format_mgr_revision(0),
92 m_type_summary_sp(), m_type_format_sp(), m_synthetic_children_sp(),
93 m_type_validator_sp(), m_user_id_of_forced_summary(),
94 m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid),
95 m_value_checksum(),
96 m_preferred_display_language(lldb::eLanguageTypeUnknown),
97 m_language_flags(0), m_value_is_valid(false), m_value_did_change(false),
98 m_children_count_valid(false), m_old_value_valid(false),
99 m_is_deref_of_parent(false), m_is_array_item_for_pointer(false),
100 m_is_bitfield_for_scalar(false), m_is_child_at_offset(false),
101 m_is_getting_summary(false),
102 m_did_calculate_complete_objc_class_type(false),
103 m_is_synthetic_children_generated(
104 parent.m_is_synthetic_children_generated) {
105 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +0000106}
107
108//----------------------------------------------------------------------
109// ValueObject constructor
110//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111ValueObject::ValueObject(ExecutionContextScope *exe_scope,
112 AddressType child_ptr_or_ref_addr_type)
113 : UserID(++g_value_obj_uid), // Unique identifier for every value object
114 m_parent(NULL), m_root(NULL), m_update_point(exe_scope), m_name(),
115 m_data(), m_value(), m_error(), m_value_str(), m_old_value_str(),
116 m_location_str(), m_summary_str(), m_object_desc_str(),
117 m_validation_result(), m_manager(), m_children(), m_synthetic_children(),
118 m_dynamic_value(NULL), m_synthetic_value(NULL), m_deref_valobj(NULL),
119 m_format(eFormatDefault), m_last_format(eFormatDefault),
120 m_last_format_mgr_revision(0), m_type_summary_sp(), m_type_format_sp(),
121 m_synthetic_children_sp(), m_type_validator_sp(),
122 m_user_id_of_forced_summary(),
123 m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
124 m_value_checksum(),
125 m_preferred_display_language(lldb::eLanguageTypeUnknown),
126 m_language_flags(0), m_value_is_valid(false), m_value_did_change(false),
127 m_children_count_valid(false), m_old_value_valid(false),
128 m_is_deref_of_parent(false), m_is_array_item_for_pointer(false),
129 m_is_bitfield_for_scalar(false), m_is_child_at_offset(false),
130 m_is_getting_summary(false),
131 m_did_calculate_complete_objc_class_type(false),
132 m_is_synthetic_children_generated(false) {
133 m_manager = new ValueObjectManager();
134 m_manager->ManageObject(this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135}
136
137//----------------------------------------------------------------------
138// Destructor
139//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140ValueObject::~ValueObject() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142bool ValueObject::UpdateValueIfNeeded(bool update_format) {
Greg Claytonb71f3842010-10-05 03:13:51 +0000143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 bool did_change_formats = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146 if (update_format)
147 did_change_formats = UpdateFormatsIfNeeded();
Greg Claytonefbc7d22012-03-09 04:23:44 +0000148
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149 // If this is a constant value, then our success is predicated on whether
150 // we have an error or not
151 if (GetIsConstant()) {
152 // if you are constant, things might still have changed behind your back
153 // (e.g. you are a frozen object and things have changed deeper than you
154 // cared to freeze-dry yourself)
155 // in this case, your value has not changed, but "computed" entries might
156 // have, so you might now have
157 // a different summary, or a different object description. clear these so we
158 // will recompute them
159 if (update_format && !did_change_formats)
160 ClearUserVisibleData(eClearUserVisibleDataItemsSummary |
161 eClearUserVisibleDataItemsDescription);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162 return m_error.Success();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 }
164
165 bool first_update = IsChecksumEmpty();
166
167 if (NeedsUpdating()) {
168 m_update_point.SetUpdated();
169
170 // Save the old value using swap to avoid a string copy which
171 // also will clear our m_value_str
172 if (m_value_str.empty()) {
173 m_old_value_valid = false;
174 } else {
175 m_old_value_valid = true;
176 m_old_value_str.swap(m_value_str);
177 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
178 }
179
180 ClearUserVisibleData();
181
182 if (IsInScope()) {
183 const bool value_was_valid = GetValueIsValid();
184 SetValueDidChange(false);
185
186 m_error.Clear();
187
188 // Call the pure virtual function to update the value
189
190 bool need_compare_checksums = false;
191 llvm::SmallVector<uint8_t, 16> old_checksum;
192
193 if (!first_update && CanProvideValue()) {
194 need_compare_checksums = true;
195 old_checksum.resize(m_value_checksum.size());
196 std::copy(m_value_checksum.begin(), m_value_checksum.end(),
197 old_checksum.begin());
198 }
199
200 bool success = UpdateValue();
201
202 SetValueIsValid(success);
203
204 if (success) {
205 const uint64_t max_checksum_size = 128;
206 m_data.Checksum(m_value_checksum, max_checksum_size);
207 } else {
208 need_compare_checksums = false;
209 m_value_checksum.clear();
210 }
211
212 assert(!need_compare_checksums ||
213 (!old_checksum.empty() && !m_value_checksum.empty()));
214
215 if (first_update)
216 SetValueDidChange(false);
217 else if (!m_value_did_change && success == false) {
218 // The value wasn't gotten successfully, so we mark this
219 // as changed if the value used to be valid and now isn't
220 SetValueDidChange(value_was_valid);
221 } else if (need_compare_checksums) {
222 SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0],
223 m_value_checksum.size()));
224 }
225
226 } else {
227 m_error.SetErrorString("out of scope");
228 }
229 }
230 return m_error.Success();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000231}
232
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233bool ValueObject::UpdateFormatsIfNeeded() {
234 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
235 if (log)
236 log->Printf("[%s %p] checking for FormatManager revisions. ValueObject "
237 "rev: %d - Global rev: %d",
238 GetName().GetCString(), static_cast<void *>(this),
239 m_last_format_mgr_revision,
240 DataVisualization::GetCurrentRevision());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000241
Kate Stoneb9c1b512016-09-06 20:57:50 +0000242 bool any_change = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000243
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244 if ((m_last_format_mgr_revision != DataVisualization::GetCurrentRevision())) {
245 m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
246 any_change = true;
247
248 SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues));
249 SetSummaryFormat(
250 DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000251#ifndef LLDB_DISABLE_PYTHON
Kate Stoneb9c1b512016-09-06 20:57:50 +0000252 SetSyntheticChildren(
253 DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000254#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000255 SetValidator(DataVisualization::GetValidator(*this, GetDynamicValueType()));
256 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000257
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 return any_change;
Enrico Granata4becb372011-06-29 22:27:15 +0000259}
260
Kate Stoneb9c1b512016-09-06 20:57:50 +0000261void ValueObject::SetNeedsUpdate() {
262 m_update_point.SetNeedsUpdate();
263 // We have to clear the value string here so ConstResult children will notice
264 // if their values are
265 // changed by hand (i.e. with SetValueAsCString).
266 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
Jim Ingham16e0c682011-08-12 23:34:31 +0000267}
268
Kate Stoneb9c1b512016-09-06 20:57:50 +0000269void ValueObject::ClearDynamicTypeInformation() {
270 m_children_count_valid = false;
271 m_did_calculate_complete_objc_class_type = false;
272 m_last_format_mgr_revision = 0;
273 m_override_type = CompilerType();
274 SetValueFormat(lldb::TypeFormatImplSP());
275 SetSummaryFormat(lldb::TypeSummaryImplSP());
276 SetSyntheticChildren(lldb::SyntheticChildrenSP());
Enrico Granata13ac0e22012-10-17 19:03:34 +0000277}
278
Kate Stoneb9c1b512016-09-06 20:57:50 +0000279CompilerType ValueObject::MaybeCalculateCompleteType() {
280 CompilerType compiler_type(GetCompilerTypeImpl());
281
282 if (m_did_calculate_complete_objc_class_type) {
283 if (m_override_type.IsValid())
284 return m_override_type;
Sean Callanan72772842012-02-22 23:57:45 +0000285 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000286 return compiler_type;
287 }
288
289 CompilerType class_type;
290 bool is_pointer_type = false;
291
292 if (ClangASTContext::IsObjCObjectPointerType(compiler_type, &class_type)) {
293 is_pointer_type = true;
294 } else if (ClangASTContext::IsObjCObjectOrInterfaceType(compiler_type)) {
295 class_type = compiler_type;
296 } else {
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000297 return compiler_type;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298 }
299
300 m_did_calculate_complete_objc_class_type = true;
301
302 if (class_type) {
303 ConstString class_name(class_type.GetConstTypeName());
304
305 if (class_name) {
306 ProcessSP process_sp(
307 GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
308
309 if (process_sp) {
310 ObjCLanguageRuntime *objc_language_runtime(
311 process_sp->GetObjCLanguageRuntime());
312
313 if (objc_language_runtime) {
314 TypeSP complete_objc_class_type_sp =
315 objc_language_runtime->LookupInCompleteClassCache(class_name);
316
317 if (complete_objc_class_type_sp) {
318 CompilerType complete_class(
319 complete_objc_class_type_sp->GetFullCompilerType());
320
321 if (complete_class.GetCompleteType()) {
322 if (is_pointer_type) {
323 m_override_type = complete_class.GetPointerType();
324 } else {
325 m_override_type = complete_class;
326 }
327
328 if (m_override_type.IsValid())
329 return m_override_type;
330 }
331 }
332 }
333 }
334 }
335 }
336 return compiler_type;
Sean Callanan72772842012-02-22 23:57:45 +0000337}
338
Kate Stoneb9c1b512016-09-06 20:57:50 +0000339CompilerType ValueObject::GetCompilerType() {
340 return MaybeCalculateCompleteType();
Sean Callanan72772842012-02-22 23:57:45 +0000341}
342
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343TypeImpl ValueObject::GetTypeImpl() { return TypeImpl(GetCompilerType()); }
344
345DataExtractor &ValueObject::GetDataExtractor() {
346 UpdateValueIfNeeded(false);
347 return m_data;
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000348}
349
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350const Error &ValueObject::GetError() {
351 UpdateValueIfNeeded(false);
352 return m_error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353}
354
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355const ConstString &ValueObject::GetName() const { return m_name; }
356
357const char *ValueObject::GetLocationAsCString() {
358 return GetLocationAsCStringImpl(m_value, m_data);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359}
360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
362 const DataExtractor &data) {
363 if (UpdateValueIfNeeded(false)) {
364 if (m_location_str.empty()) {
365 StreamString sstr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366
Kate Stoneb9c1b512016-09-06 20:57:50 +0000367 Value::ValueType value_type = value.GetValueType();
Enrico Granata82fabf82013-04-30 20:45:04 +0000368
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369 switch (value_type) {
370 case Value::eValueTypeScalar:
371 case Value::eValueTypeVector:
372 if (value.GetContextType() == Value::eContextTypeRegisterInfo) {
373 RegisterInfo *reg_info = value.GetRegisterInfo();
374 if (reg_info) {
375 if (reg_info->name)
376 m_location_str = reg_info->name;
377 else if (reg_info->alt_name)
378 m_location_str = reg_info->alt_name;
379 if (m_location_str.empty())
380 m_location_str = (reg_info->encoding == lldb::eEncodingVector)
381 ? "vector"
382 : "scalar";
383 }
384 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385 if (m_location_str.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000386 m_location_str =
387 (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
388 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390 case Value::eValueTypeLoadAddress:
391 case Value::eValueTypeFileAddress:
392 case Value::eValueTypeHostAddress: {
393 uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
394 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size,
395 value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
Zachary Turnerc1564272016-11-16 21:15:24 +0000396 m_location_str = sstr.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397 } break;
398 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400 }
401 return m_location_str.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402}
403
Kate Stoneb9c1b512016-09-06 20:57:50 +0000404Value &ValueObject::GetValue() { return m_value; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405
Kate Stoneb9c1b512016-09-06 20:57:50 +0000406const Value &ValueObject::GetValue() const { return m_value; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408bool ValueObject::ResolveValue(Scalar &scalar) {
409 if (UpdateValueIfNeeded(
410 false)) // make sure that you are up to date before returning anything
411 {
412 ExecutionContext exe_ctx(GetExecutionContextRef());
413 Value tmp_value(m_value);
414 scalar = tmp_value.ResolveValue(&exe_ctx);
415 if (scalar.IsValid()) {
416 const uint32_t bitfield_bit_size = GetBitfieldBitSize();
417 if (bitfield_bit_size)
418 return scalar.ExtractBitfield(bitfield_bit_size,
419 GetBitfieldBitOffset());
420 return true;
Enrico Granata6fd87d52011-08-04 01:41:02 +0000421 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422 }
423 return false;
424}
425
426bool ValueObject::IsLogicalTrue(Error &error) {
427 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
428 LazyBool is_logical_true = language->IsLogicalTrue(*this, error);
429 switch (is_logical_true) {
430 case eLazyBoolYes:
431 case eLazyBoolNo:
432 return (is_logical_true == true);
433 case eLazyBoolCalculate:
434 break;
435 }
436 }
437
438 Scalar scalar_value;
439
440 if (!ResolveValue(scalar_value)) {
441 error.SetErrorString("failed to get a scalar result");
Greg Claytondcad5022011-12-29 01:26:56 +0000442 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443 }
444
445 bool ret;
446 if (scalar_value.ULongLong(1) == 0)
447 ret = false;
448 else
449 ret = true;
450 error.Clear();
451 return ret;
Greg Clayton8f343b02010-11-04 01:54:29 +0000452}
453
Kate Stoneb9c1b512016-09-06 20:57:50 +0000454bool ValueObject::GetValueIsValid() const { return m_value_is_valid; }
455
456void ValueObject::SetValueIsValid(bool b) { m_value_is_valid = b; }
457
458bool ValueObject::GetValueDidChange() { return m_value_did_change; }
459
460void ValueObject::SetValueDidChange(bool value_changed) {
461 m_value_did_change = value_changed;
462}
463
464ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) {
465 ValueObjectSP child_sp;
466 // We may need to update our value if we are dynamic
467 if (IsPossibleDynamicType())
468 UpdateValueIfNeeded(false);
469 if (idx < GetNumChildren()) {
470 // Check if we have already made the child value object?
471 if (can_create && !m_children.HasChildAtIndex(idx)) {
472 // No we haven't created the child at this index, so lets have our
473 // subclass do it and cache the result for quick future access.
474 m_children.SetChildAtIndex(idx, CreateChildAtIndex(idx, false, 0));
Enrico Granata407b5c62015-11-02 21:52:05 +0000475 }
Jim Ingham98e6daf2015-10-31 00:02:18 +0000476
Kate Stoneb9c1b512016-09-06 20:57:50 +0000477 ValueObject *child = m_children.GetChildAtIndex(idx);
478 if (child != NULL)
479 return child->GetSP();
480 }
481 return child_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482}
483
484ValueObjectSP
Kate Stoneb9c1b512016-09-06 20:57:50 +0000485ValueObject::GetChildAtIndexPath(const std::initializer_list<size_t> &idxs,
486 size_t *index_of_error) {
487 return GetChildAtIndexPath(std::vector<size_t>(idxs), index_of_error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488}
489
Kate Stoneb9c1b512016-09-06 20:57:50 +0000490ValueObjectSP ValueObject::GetChildAtIndexPath(
491 const std::initializer_list<std::pair<size_t, bool>> &idxs,
492 size_t *index_of_error) {
493 return GetChildAtIndexPath(std::vector<std::pair<size_t, bool>>(idxs),
494 index_of_error);
Enrico Granata3309d882013-01-12 01:00:22 +0000495}
496
497lldb::ValueObjectSP
Kate Stoneb9c1b512016-09-06 20:57:50 +0000498ValueObject::GetChildAtIndexPath(const std::vector<size_t> &idxs,
499 size_t *index_of_error) {
500 if (idxs.size() == 0)
501 return GetSP();
502 ValueObjectSP root(GetSP());
503 for (size_t idx : idxs) {
504 root = root->GetChildAtIndex(idx, true);
505 if (!root) {
506 if (index_of_error)
507 *index_of_error = idx;
508 return root;
Enrico Granata3309d882013-01-12 01:00:22 +0000509 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000510 }
511 return root;
512}
513
514lldb::ValueObjectSP ValueObject::GetChildAtIndexPath(
515 const std::vector<std::pair<size_t, bool>> &idxs, size_t *index_of_error) {
516 if (idxs.size() == 0)
517 return GetSP();
518 ValueObjectSP root(GetSP());
519 for (std::pair<size_t, bool> idx : idxs) {
520 root = root->GetChildAtIndex(idx.first, idx.second);
521 if (!root) {
522 if (index_of_error)
523 *index_of_error = idx.first;
524 return root;
525 }
526 }
527 return root;
Enrico Granata3309d882013-01-12 01:00:22 +0000528}
529
530lldb::ValueObjectSP
Kate Stoneb9c1b512016-09-06 20:57:50 +0000531ValueObject::GetChildAtNamePath(const std::initializer_list<ConstString> &names,
532 ConstString *name_of_error) {
533 return GetChildAtNamePath(std::vector<ConstString>(names), name_of_error);
534}
535
536lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
537 const std::initializer_list<std::pair<ConstString, bool>> &names,
538 ConstString *name_of_error) {
539 return GetChildAtNamePath(std::vector<std::pair<ConstString, bool>>(names),
540 name_of_error);
Enrico Granata3309d882013-01-12 01:00:22 +0000541}
542
Enrico Granatae2e220a2013-09-12 00:48:47 +0000543lldb::ValueObjectSP
Kate Stoneb9c1b512016-09-06 20:57:50 +0000544ValueObject::GetChildAtNamePath(const std::vector<ConstString> &names,
545 ConstString *name_of_error) {
546 if (names.size() == 0)
547 return GetSP();
548 ValueObjectSP root(GetSP());
549 for (ConstString name : names) {
550 root = root->GetChildMemberWithName(name, true);
551 if (!root) {
552 if (name_of_error)
553 *name_of_error = name;
554 return root;
555 }
556 }
557 return root;
Enrico Granataef8dde62015-12-21 23:10:17 +0000558}
559
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
561 const std::vector<std::pair<ConstString, bool>> &names,
562 ConstString *name_of_error) {
563 if (names.size() == 0)
564 return GetSP();
565 ValueObjectSP root(GetSP());
566 for (std::pair<ConstString, bool> name : names) {
567 root = root->GetChildMemberWithName(name.first, name.second);
568 if (!root) {
569 if (name_of_error)
570 *name_of_error = name.first;
571 return root;
572 }
573 }
574 return root;
Enrico Granatae2e220a2013-09-12 00:48:47 +0000575}
576
Kate Stoneb9c1b512016-09-06 20:57:50 +0000577size_t ValueObject::GetIndexOfChildWithName(const ConstString &name) {
578 bool omit_empty_base_classes = true;
579 return GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
580 omit_empty_base_classes);
Enrico Granatae2e220a2013-09-12 00:48:47 +0000581}
582
Kate Stoneb9c1b512016-09-06 20:57:50 +0000583ValueObjectSP ValueObject::GetChildMemberWithName(const ConstString &name,
584 bool can_create) {
585 // when getting a child by name, it could be buried inside some base
586 // classes (which really aren't part of the expression path), so we
587 // need a vector of indexes that can get us down to the correct child
588 ValueObjectSP child_sp;
589
590 // We may need to update our value if we are dynamic
591 if (IsPossibleDynamicType())
592 UpdateValueIfNeeded(false);
593
594 std::vector<uint32_t> child_indexes;
595 bool omit_empty_base_classes = true;
596 const size_t num_child_indexes =
597 GetCompilerType().GetIndexOfChildMemberWithName(
598 name.GetCString(), omit_empty_base_classes, child_indexes);
599 if (num_child_indexes > 0) {
600 std::vector<uint32_t>::const_iterator pos = child_indexes.begin();
601 std::vector<uint32_t>::const_iterator end = child_indexes.end();
602
603 child_sp = GetChildAtIndex(*pos, can_create);
604 for (++pos; pos != end; ++pos) {
605 if (child_sp) {
606 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex(*pos, can_create));
607 child_sp = new_child_sp;
608 } else {
609 child_sp.reset();
610 }
Enrico Granatae2e220a2013-09-12 00:48:47 +0000611 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000612 }
613 return child_sp;
Enrico Granatae2e220a2013-09-12 00:48:47 +0000614}
615
Kate Stoneb9c1b512016-09-06 20:57:50 +0000616size_t ValueObject::GetNumChildren(uint32_t max) {
617 UpdateValueIfNeeded();
618
619 if (max < UINT32_MAX) {
620 if (m_children_count_valid) {
621 size_t children_count = m_children.GetChildrenCount();
622 return children_count <= max ? children_count : max;
623 } else
624 return CalculateNumChildren(max);
625 }
626
627 if (!m_children_count_valid) {
628 SetNumChildren(CalculateNumChildren());
629 }
630 return m_children.GetChildrenCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000631}
632
Kate Stoneb9c1b512016-09-06 20:57:50 +0000633bool ValueObject::MightHaveChildren() {
634 bool has_children = false;
635 const uint32_t type_info = GetTypeInfo();
636 if (type_info) {
637 if (type_info & (eTypeHasChildren | eTypeIsPointer | eTypeIsReference))
638 has_children = true;
639 } else {
640 has_children = GetNumChildren() > 0;
641 }
642 return has_children;
Greg Clayton4a792072012-10-23 01:50:10 +0000643}
644
645// Should only be called by ValueObject::GetNumChildren()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000646void ValueObject::SetNumChildren(size_t num_children) {
647 m_children_count_valid = true;
648 m_children.SetChildrenCount(num_children);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649}
650
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651void ValueObject::SetName(const ConstString &name) { m_name = name; }
652
653ValueObject *ValueObject::CreateChildAtIndex(size_t idx,
654 bool synthetic_array_member,
655 int32_t synthetic_index) {
656 ValueObject *valobj = NULL;
657
658 bool omit_empty_base_classes = true;
659 bool ignore_array_bounds = synthetic_array_member;
660 std::string child_name_str;
661 uint32_t child_byte_size = 0;
662 int32_t child_byte_offset = 0;
663 uint32_t child_bitfield_bit_size = 0;
664 uint32_t child_bitfield_bit_offset = 0;
665 bool child_is_base_class = false;
666 bool child_is_deref_of_parent = false;
667 uint64_t language_flags = 0;
668
669 const bool transparent_pointers = synthetic_array_member == false;
670 CompilerType child_compiler_type;
671
672 ExecutionContext exe_ctx(GetExecutionContextRef());
673
674 child_compiler_type = GetCompilerType().GetChildCompilerTypeAtIndex(
675 &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
676 ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
677 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
678 child_is_deref_of_parent, this, language_flags);
679 if (child_compiler_type) {
680 if (synthetic_index)
681 child_byte_offset += child_byte_size * synthetic_index;
682
683 ConstString child_name;
684 if (!child_name_str.empty())
685 child_name.SetCString(child_name_str.c_str());
686
687 valobj = new ValueObjectChild(
688 *this, child_compiler_type, child_name, child_byte_size,
689 child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
690 child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
691 language_flags);
692 // if (valobj)
693 // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid);
694 }
695
696 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697}
698
Kate Stoneb9c1b512016-09-06 20:57:50 +0000699bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
700 std::string &destination,
701 lldb::LanguageType lang) {
702 return GetSummaryAsCString(summary_ptr, destination,
703 TypeSummaryOptions().SetLanguage(lang));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704}
705
Kate Stoneb9c1b512016-09-06 20:57:50 +0000706bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
707 std::string &destination,
708 const TypeSummaryOptions &options) {
709 destination.clear();
710
711 // ideally we would like to bail out if passing NULL, but if we do so
712 // we end up not providing the summary for function pointers anymore
713 if (/*summary_ptr == NULL ||*/ m_is_getting_summary)
714 return false;
715
716 m_is_getting_summary = true;
717
718 TypeSummaryOptions actual_options(options);
719
720 if (actual_options.GetLanguage() == lldb::eLanguageTypeUnknown)
721 actual_options.SetLanguage(GetPreferredDisplayLanguage());
722
723 // this is a hot path in code and we prefer to avoid setting this string all
724 // too often also clearing out other
725 // information that we might care to see in a crash log. might be useful in
726 // very specific situations though.
727 /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s.
728 Summary provider's description is %s",
729 GetTypeName().GetCString(),
730 GetName().GetCString(),
731 summary_ptr->GetDescription().c_str());*/
732
733 if (UpdateValueIfNeeded(false) && summary_ptr) {
734 if (HasSyntheticValue())
735 m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on
736 // the synthetic children being
737 // up-to-date (e.g. ${svar%#})
738 summary_ptr->FormatObject(this, destination, actual_options);
739 }
740 m_is_getting_summary = false;
741 return !destination.empty();
Enrico Granatac1247f52014-11-06 21:23:20 +0000742}
743
Kate Stoneb9c1b512016-09-06 20:57:50 +0000744const char *ValueObject::GetSummaryAsCString(lldb::LanguageType lang) {
745 if (UpdateValueIfNeeded(true) && m_summary_str.empty()) {
746 TypeSummaryOptions summary_options;
747 summary_options.SetLanguage(lang);
748 GetSummaryAsCString(GetSummaryFormat().get(), m_summary_str,
749 summary_options);
750 }
751 if (m_summary_str.empty())
752 return NULL;
753 return m_summary_str.c_str();
754}
755
756bool ValueObject::GetSummaryAsCString(std::string &destination,
757 const TypeSummaryOptions &options) {
758 return GetSummaryAsCString(GetSummaryFormat().get(), destination, options);
759}
760
761bool ValueObject::IsCStringContainer(bool check_pointer) {
762 CompilerType pointee_or_element_compiler_type;
763 const Flags type_flags(GetTypeInfo(&pointee_or_element_compiler_type));
764 bool is_char_arr_ptr(type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
765 pointee_or_element_compiler_type.IsCharType());
766 if (!is_char_arr_ptr)
767 return false;
768 if (!check_pointer)
769 return true;
770 if (type_flags.Test(eTypeIsArray))
771 return true;
772 addr_t cstr_address = LLDB_INVALID_ADDRESS;
773 AddressType cstr_address_type = eAddressTypeInvalid;
774 cstr_address = GetAddressOf(true, &cstr_address_type);
775 return (cstr_address != LLDB_INVALID_ADDRESS);
776}
777
778size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
779 uint32_t item_count) {
780 CompilerType pointee_or_element_compiler_type;
781 const uint32_t type_info = GetTypeInfo(&pointee_or_element_compiler_type);
782 const bool is_pointer_type = type_info & eTypeIsPointer;
783 const bool is_array_type = type_info & eTypeIsArray;
784 if (!(is_pointer_type || is_array_type))
785 return 0;
786
787 if (item_count == 0)
788 return 0;
789
790 ExecutionContext exe_ctx(GetExecutionContextRef());
791
792 const uint64_t item_type_size = pointee_or_element_compiler_type.GetByteSize(
793 exe_ctx.GetBestExecutionContextScope());
794 const uint64_t bytes = item_count * item_type_size;
795 const uint64_t offset = item_idx * item_type_size;
796
797 if (item_idx == 0 && item_count == 1) // simply a deref
798 {
799 if (is_pointer_type) {
800 Error error;
801 ValueObjectSP pointee_sp = Dereference(error);
802 if (error.Fail() || pointee_sp.get() == NULL)
803 return 0;
804 return pointee_sp->GetData(data, error);
805 } else {
806 ValueObjectSP child_sp = GetChildAtIndex(0, true);
807 if (child_sp.get() == NULL)
808 return 0;
809 Error error;
810 return child_sp->GetData(data, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000811 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000812 return true;
813 } else /* (items > 1) */
814 {
815 Error error;
816 lldb_private::DataBufferHeap *heap_buf_ptr = NULL;
817 lldb::DataBufferSP data_sp(heap_buf_ptr =
818 new lldb_private::DataBufferHeap());
Enrico Granata0c489f52012-03-01 04:24:26 +0000819
Kate Stoneb9c1b512016-09-06 20:57:50 +0000820 AddressType addr_type;
821 lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type)
822 : GetAddressOf(true, &addr_type);
823
824 switch (addr_type) {
825 case eAddressTypeFile: {
826 ModuleSP module_sp(GetModule());
827 if (module_sp) {
828 addr = addr + offset;
829 Address so_addr;
830 module_sp->ResolveFileAddress(addr, so_addr);
831 ExecutionContext exe_ctx(GetExecutionContextRef());
832 Target *target = exe_ctx.GetTargetPtr();
833 if (target) {
834 heap_buf_ptr->SetByteSize(bytes);
835 size_t bytes_read = target->ReadMemory(
836 so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
837 if (error.Success()) {
838 data.SetData(data_sp);
839 return bytes_read;
840 }
841 }
842 }
843 } break;
844 case eAddressTypeLoad: {
845 ExecutionContext exe_ctx(GetExecutionContextRef());
846 Process *process = exe_ctx.GetProcessPtr();
847 if (process) {
848 heap_buf_ptr->SetByteSize(bytes);
849 size_t bytes_read = process->ReadMemory(
850 addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
851 if (error.Success() || bytes_read > 0) {
852 data.SetData(data_sp);
853 return bytes_read;
854 }
855 }
856 } break;
857 case eAddressTypeHost: {
858 const uint64_t max_bytes =
859 GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());
860 if (max_bytes > offset) {
861 size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes);
862 addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
863 if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
864 break;
865 heap_buf_ptr->CopyData((uint8_t *)(addr + offset), bytes_read);
866 data.SetData(data_sp);
867 return bytes_read;
868 }
869 } break;
870 case eAddressTypeInvalid:
871 break;
Enrico Granata0c489f52012-03-01 04:24:26 +0000872 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000873 }
874 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000875}
876
Kate Stoneb9c1b512016-09-06 20:57:50 +0000877uint64_t ValueObject::GetData(DataExtractor &data, Error &error) {
878 UpdateValueIfNeeded(false);
879 ExecutionContext exe_ctx(GetExecutionContextRef());
880 error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
881 if (error.Fail()) {
882 if (m_data.GetByteSize()) {
883 data = m_data;
884 error.Clear();
885 return data.GetByteSize();
886 } else {
887 return 0;
888 }
889 }
890 data.SetAddressByteSize(m_data.GetAddressByteSize());
891 data.SetByteOrder(m_data.GetByteOrder());
892 return data.GetByteSize();
Enrico Granata49bfafb2014-11-18 23:36:25 +0000893}
894
Kate Stoneb9c1b512016-09-06 20:57:50 +0000895bool ValueObject::SetData(DataExtractor &data, Error &error) {
896 error.Clear();
897 // Make sure our value is up to date first so that our location and location
898 // type is valid.
899 if (!UpdateValueIfNeeded(false)) {
900 error.SetErrorString("unable to read value");
901 return false;
902 }
903
904 uint64_t count = 0;
905 const Encoding encoding = GetCompilerType().GetEncoding(count);
906
907 const size_t byte_size = GetByteSize();
908
909 Value::ValueType value_type = m_value.GetValueType();
910
911 switch (value_type) {
912 case Value::eValueTypeScalar: {
913 Error set_error =
914 m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
915
916 if (!set_error.Success()) {
917 error.SetErrorStringWithFormat("unable to set scalar value: %s",
918 set_error.AsCString());
919 return false;
920 }
921 } break;
922 case Value::eValueTypeLoadAddress: {
923 // If it is a load address, then the scalar value is the storage location
924 // of the data, and we have to shove this value down to that load location.
925 ExecutionContext exe_ctx(GetExecutionContextRef());
926 Process *process = exe_ctx.GetProcessPtr();
927 if (process) {
928 addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
929 size_t bytes_written = process->WriteMemory(
930 target_addr, data.GetDataStart(), byte_size, error);
931 if (!error.Success())
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000932 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000933 if (bytes_written != byte_size) {
934 error.SetErrorString("unable to write value to memory");
935 return false;
936 }
937 }
938 } break;
939 case Value::eValueTypeHostAddress: {
940 // If it is a host address, then we stuff the scalar as a DataBuffer into
941 // the Value's data.
942 DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
943 m_data.SetData(buffer_sp, 0);
944 data.CopyByteOrderedData(0, byte_size,
945 const_cast<uint8_t *>(m_data.GetDataStart()),
946 byte_size, m_data.GetByteOrder());
947 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
948 } break;
949 case Value::eValueTypeFileAddress:
950 case Value::eValueTypeVector:
951 break;
952 }
953
954 // If we have reached this point, then we have successfully changed the value.
955 SetNeedsUpdate();
956 return true;
957}
958
959static bool CopyStringDataToBufferSP(const StreamString &source,
960 lldb::DataBufferSP &destination) {
961 destination.reset(new DataBufferHeap(source.GetSize() + 1, 0));
Zachary Turnerc1564272016-11-16 21:15:24 +0000962 memcpy(destination->GetBytes(), source.GetString().data(), source.GetSize());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000963 return true;
964}
965
966std::pair<size_t, bool>
967ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Error &error,
968 uint32_t max_length, bool honor_array,
969 Format item_format) {
970 bool was_capped = false;
971 StreamString s;
972 ExecutionContext exe_ctx(GetExecutionContextRef());
973 Target *target = exe_ctx.GetTargetPtr();
974
975 if (!target) {
976 s << "<no target to read from>";
977 error.SetErrorString("no target to read from");
978 CopyStringDataToBufferSP(s, buffer_sp);
979 return {0, was_capped};
980 }
981
982 if (max_length == 0)
983 max_length = target->GetMaximumSizeOfStringSummary();
984
985 size_t bytes_read = 0;
986 size_t total_bytes_read = 0;
987
988 CompilerType compiler_type = GetCompilerType();
989 CompilerType elem_or_pointee_compiler_type;
990 const Flags type_flags(GetTypeInfo(&elem_or_pointee_compiler_type));
991 if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
992 elem_or_pointee_compiler_type.IsCharType()) {
Greg Claytonafacd142011-09-02 01:15:17 +0000993 addr_t cstr_address = LLDB_INVALID_ADDRESS;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000994 AddressType cstr_address_type = eAddressTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000995
Kate Stoneb9c1b512016-09-06 20:57:50 +0000996 size_t cstr_len = 0;
997 bool capped_data = false;
998 const bool is_array = type_flags.Test(eTypeIsArray);
999 if (is_array) {
1000 // We have an array
1001 uint64_t array_size = 0;
1002 if (compiler_type.IsArrayType(NULL, &array_size, NULL)) {
1003 cstr_len = array_size;
1004 if (cstr_len > max_length) {
1005 capped_data = true;
1006 cstr_len = max_length;
Enrico Granata9128ee22011-09-06 19:20:51 +00001007 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001008 }
1009 cstr_address = GetAddressOf(true, &cstr_address_type);
1010 } else {
1011 // We have a pointer
1012 cstr_address = GetPointerValue(&cstr_address_type);
Enrico Granata9128ee22011-09-06 19:20:51 +00001013 }
Enrico Granata9128ee22011-09-06 19:20:51 +00001014
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) {
1016 if (cstr_address_type == eAddressTypeHost && is_array) {
1017 const char *cstr = GetDataExtractor().PeekCStr(0);
1018 if (cstr == nullptr) {
1019 s << "<invalid address>";
1020 error.SetErrorString("invalid address");
1021 CopyStringDataToBufferSP(s, buffer_sp);
1022 return {0, was_capped};
Sean Callananed185ab2013-04-19 19:47:32 +00001023 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001024 buffer_sp.reset(new DataBufferHeap(cstr_len, 0));
1025 memcpy(buffer_sp->GetBytes(), cstr, cstr_len);
1026 return {cstr_len, was_capped};
1027 } else {
1028 s << "<invalid address>";
1029 error.SetErrorString("invalid address");
Enrico Granata2206b482014-10-30 18:27:31 +00001030 CopyStringDataToBufferSP(s, buffer_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031 return {0, was_capped};
1032 }
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001033 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001034
1035 Address cstr_so_addr(cstr_address);
1036 DataExtractor data;
1037 if (cstr_len > 0 && honor_array) {
1038 // I am using GetPointeeData() here to abstract the fact that some
1039 // ValueObjects are actually frozen pointers in the host
1040 // but the pointed-to data lives in the debuggee, and GetPointeeData()
1041 // automatically takes care of this
1042 GetPointeeData(data, 0, cstr_len);
1043
1044 if ((bytes_read = data.GetByteSize()) > 0) {
1045 total_bytes_read = bytes_read;
1046 for (size_t offset = 0; offset < bytes_read; offset++)
1047 s.Printf("%c", *data.PeekData(offset, 1));
1048 if (capped_data)
1049 was_capped = true;
1050 }
1051 } else {
1052 cstr_len = max_length;
1053 const size_t k_max_buf_size = 64;
1054
1055 size_t offset = 0;
1056
1057 int cstr_len_displayed = -1;
1058 bool capped_cstr = false;
1059 // I am using GetPointeeData() here to abstract the fact that some
1060 // ValueObjects are actually frozen pointers in the host
1061 // but the pointed-to data lives in the debuggee, and GetPointeeData()
1062 // automatically takes care of this
1063 while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {
1064 total_bytes_read += bytes_read;
1065 const char *cstr = data.PeekCStr(0);
1066 size_t len = strnlen(cstr, k_max_buf_size);
1067 if (cstr_len_displayed < 0)
1068 cstr_len_displayed = len;
1069
1070 if (len == 0)
1071 break;
1072 cstr_len_displayed += len;
1073 if (len > bytes_read)
1074 len = bytes_read;
1075 if (len > cstr_len)
1076 len = cstr_len;
1077
1078 for (size_t offset = 0; offset < bytes_read; offset++)
1079 s.Printf("%c", *data.PeekData(offset, 1));
1080
1081 if (len < k_max_buf_size)
1082 break;
1083
1084 if (len >= cstr_len) {
1085 capped_cstr = true;
1086 break;
1087 }
1088
1089 cstr_len -= len;
1090 offset += len;
1091 }
1092
1093 if (cstr_len_displayed >= 0) {
1094 if (capped_cstr)
1095 was_capped = true;
1096 }
1097 }
1098 } else {
1099 error.SetErrorString("not a string object");
1100 s << "<not a string object>";
1101 }
1102 CopyStringDataToBufferSP(s, buffer_sp);
1103 return {total_bytes_read, was_capped};
1104}
1105
1106std::pair<TypeValidatorResult, std::string> ValueObject::GetValidationStatus() {
1107 if (!UpdateValueIfNeeded(true))
1108 return {TypeValidatorResult::Success,
1109 ""}; // not the validator's job to discuss update problems
1110
1111 if (m_validation_result.hasValue())
1112 return m_validation_result.getValue();
1113
1114 if (!m_type_validator_sp)
1115 return {TypeValidatorResult::Success, ""}; // no validator no failure
1116
1117 auto outcome = m_type_validator_sp->FormatObject(this);
1118
1119 return (m_validation_result = {outcome.m_result, outcome.m_message})
1120 .getValue();
1121}
1122
1123const char *ValueObject::GetObjectDescription() {
1124
1125 if (!UpdateValueIfNeeded(true))
1126 return NULL;
1127
1128 if (!m_object_desc_str.empty())
1129 return m_object_desc_str.c_str();
1130
1131 ExecutionContext exe_ctx(GetExecutionContextRef());
1132 Process *process = exe_ctx.GetProcessPtr();
1133 if (process == NULL)
1134 return NULL;
1135
1136 StreamString s;
1137
1138 LanguageType language = GetObjectRuntimeLanguage();
1139 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
1140
1141 if (runtime == NULL) {
1142 // Aw, hell, if the things a pointer, or even just an integer, let's try
1143 // ObjC anyway...
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001144 CompilerType compiler_type = GetCompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145 if (compiler_type) {
1146 bool is_signed;
1147 if (compiler_type.IsIntegerType(is_signed) ||
1148 compiler_type.IsPointerType()) {
1149 runtime = process->GetLanguageRuntime(eLanguageTypeObjC);
1150 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001151 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001152 }
1153
1154 if (runtime && runtime->GetObjectDescription(s, *this)) {
Zachary Turnerc1564272016-11-16 21:15:24 +00001155 m_object_desc_str.append(s.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001156 }
1157
1158 if (m_object_desc_str.empty())
1159 return NULL;
1160 else
1161 return m_object_desc_str.c_str();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001162}
1163
Kate Stoneb9c1b512016-09-06 20:57:50 +00001164bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,
1165 std::string &destination) {
1166 if (UpdateValueIfNeeded(false))
1167 return format.FormatObject(this, destination);
1168 else
1169 return false;
Enrico Granata744794a2014-09-05 21:46:22 +00001170}
1171
Kate Stoneb9c1b512016-09-06 20:57:50 +00001172bool ValueObject::GetValueAsCString(lldb::Format format,
1173 std::string &destination) {
1174 return GetValueAsCString(TypeFormatImpl_Format(format), destination);
1175}
Enrico Granata0a3958e2011-07-02 00:25:22 +00001176
Kate Stoneb9c1b512016-09-06 20:57:50 +00001177const char *ValueObject::GetValueAsCString() {
1178 if (UpdateValueIfNeeded(true)) {
1179 lldb::TypeFormatImplSP format_sp;
1180 lldb::Format my_format = GetFormat();
1181 if (my_format == lldb::eFormatDefault) {
1182 if (m_type_format_sp)
1183 format_sp = m_type_format_sp;
1184 else {
1185 if (m_is_bitfield_for_scalar)
1186 my_format = eFormatUnsigned;
1187 else {
1188 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo) {
1189 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1190 if (reg_info)
1191 my_format = reg_info->format;
1192 } else {
1193 my_format = GetValue().GetCompilerType().GetFormat();
1194 }
Jim Inghama2cf2632010-12-23 02:29:54 +00001195 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001196 }
Jim Inghama2cf2632010-12-23 02:29:54 +00001197 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001198 if (my_format != m_last_format || m_value_str.empty()) {
1199 m_last_format = my_format;
1200 if (!format_sp)
1201 format_sp.reset(new TypeFormatImpl_Format(my_format));
1202 if (GetValueAsCString(*format_sp.get(), m_value_str)) {
1203 if (!m_value_did_change && m_old_value_valid) {
1204 // The value was gotten successfully, so we consider the
1205 // value as changed if the value string differs
1206 SetValueDidChange(m_old_value_str != m_value_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001207 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001208 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001210 }
1211 if (m_value_str.empty())
1212 return NULL;
1213 return m_value_str.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001214}
1215
Enrico Granatac3e320a2011-08-02 17:27:39 +00001216// if > 8bytes, 0 is returned. this method should mostly be used
1217// to read address values out of pointers
Kate Stoneb9c1b512016-09-06 20:57:50 +00001218uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
1219 // If our byte size is zero this is an aggregate type that has children
1220 if (CanProvideValue()) {
1221 Scalar scalar;
1222 if (ResolveValue(scalar)) {
1223 if (success)
1224 *success = true;
1225 return scalar.ULongLong(fail_value);
Enrico Granatac3e320a2011-08-02 17:27:39 +00001226 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001227 // fallthrough, otherwise...
1228 }
Johnny Chen3f476c42012-06-05 19:37:43 +00001229
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230 if (success)
1231 *success = false;
1232 return fail_value;
Enrico Granatac3e320a2011-08-02 17:27:39 +00001233}
1234
Kate Stoneb9c1b512016-09-06 20:57:50 +00001235int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
1236 // If our byte size is zero this is an aggregate type that has children
1237 if (CanProvideValue()) {
1238 Scalar scalar;
1239 if (ResolveValue(scalar)) {
1240 if (success)
1241 *success = true;
1242 return scalar.SLongLong(fail_value);
Enrico Granatad7373f62013-10-31 18:57:50 +00001243 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001244 // fallthrough, otherwise...
1245 }
1246
1247 if (success)
1248 *success = false;
1249 return fail_value;
Enrico Granatad7373f62013-10-31 18:57:50 +00001250}
1251
Kate Stoneb9c1b512016-09-06 20:57:50 +00001252// if any more "special cases" are added to
1253// ValueObject::DumpPrintableRepresentation() please keep
1254// this call up to date by returning true for your new special cases. We will
1255// eventually move
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001256// to checking this call result before trying to display special cases
Kate Stoneb9c1b512016-09-06 20:57:50 +00001257bool ValueObject::HasSpecialPrintableRepresentation(
1258 ValueObjectRepresentationStyle val_obj_display, Format custom_format) {
1259 Flags flags(GetTypeInfo());
1260 if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1261 val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1262 if (IsCStringContainer(true) &&
1263 (custom_format == eFormatCString || custom_format == eFormatCharArray ||
1264 custom_format == eFormatChar || custom_format == eFormatVectorOfChar))
1265 return true;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001266
Kate Stoneb9c1b512016-09-06 20:57:50 +00001267 if (flags.Test(eTypeIsArray)) {
1268 if ((custom_format == eFormatBytes) ||
1269 (custom_format == eFormatBytesWithASCII))
1270 return true;
1271
1272 if ((custom_format == eFormatVectorOfChar) ||
1273 (custom_format == eFormatVectorOfFloat32) ||
1274 (custom_format == eFormatVectorOfFloat64) ||
1275 (custom_format == eFormatVectorOfSInt16) ||
1276 (custom_format == eFormatVectorOfSInt32) ||
1277 (custom_format == eFormatVectorOfSInt64) ||
1278 (custom_format == eFormatVectorOfSInt8) ||
1279 (custom_format == eFormatVectorOfUInt128) ||
1280 (custom_format == eFormatVectorOfUInt16) ||
1281 (custom_format == eFormatVectorOfUInt32) ||
1282 (custom_format == eFormatVectorOfUInt64) ||
1283 (custom_format == eFormatVectorOfUInt8))
1284 return true;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001285 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001286 }
1287 return false;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001288}
1289
Kate Stoneb9c1b512016-09-06 20:57:50 +00001290bool ValueObject::DumpPrintableRepresentation(
1291 Stream &s, ValueObjectRepresentationStyle val_obj_display,
1292 Format custom_format, PrintableRepresentationSpecialCases special,
1293 bool do_dump_error) {
Enrico Granataf4efecd2011-07-12 22:56:10 +00001294
Kate Stoneb9c1b512016-09-06 20:57:50 +00001295 Flags flags(GetTypeInfo());
Enrico Granata86cc9822012-03-19 22:58:49 +00001296
Enrico Granata65d86e42016-11-07 23:32:20 +00001297 bool allow_special =
1298 (special == ValueObject::PrintableRepresentationSpecialCases::eAllow);
1299 const bool only_special = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001300
1301 if (allow_special) {
1302 if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1303 val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1304 // when being asked to get a printable display an array or pointer type
1305 // directly,
1306 // try to "do the right thing"
1307
1308 if (IsCStringContainer(true) &&
1309 (custom_format == eFormatCString ||
1310 custom_format == eFormatCharArray || custom_format == eFormatChar ||
1311 custom_format ==
1312 eFormatVectorOfChar)) // print char[] & char* directly
1313 {
1314 Error error;
1315 lldb::DataBufferSP buffer_sp;
1316 std::pair<size_t, bool> read_string = ReadPointedString(
1317 buffer_sp, error, 0, (custom_format == eFormatVectorOfChar) ||
1318 (custom_format == eFormatCharArray));
1319 lldb_private::formatters::StringPrinter::
1320 ReadBufferAndDumpToStreamOptions options(*this);
1321 options.SetData(DataExtractor(
1322 buffer_sp, lldb::eByteOrderInvalid,
1323 8)); // none of this matters for a string - pass some defaults
1324 options.SetStream(&s);
1325 options.SetPrefixToken(0);
1326 options.SetQuote('"');
1327 options.SetSourceSize(buffer_sp->GetByteSize());
1328 options.SetIsTruncated(read_string.second);
1329 formatters::StringPrinter::ReadBufferAndDumpToStream<
1330 lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
1331 options);
1332 return !error.Fail();
1333 }
1334
1335 if (custom_format == eFormatEnum)
Enrico Granata85933ed2011-08-18 16:38:26 +00001336 return false;
Enrico Granata86cc9822012-03-19 22:58:49 +00001337
Kate Stoneb9c1b512016-09-06 20:57:50 +00001338 // this only works for arrays, because I have no way to know when
1339 // the pointed memory ends, and no special \0 end of data marker
1340 if (flags.Test(eTypeIsArray)) {
1341 if ((custom_format == eFormatBytes) ||
1342 (custom_format == eFormatBytesWithASCII)) {
1343 const size_t count = GetNumChildren();
1344
1345 s << '[';
1346 for (size_t low = 0; low < count; low++) {
1347
1348 if (low)
1349 s << ',';
1350
1351 ValueObjectSP child = GetChildAtIndex(low, true);
1352 if (!child.get()) {
1353 s << "<invalid child>";
1354 continue;
Enrico Granata86cc9822012-03-19 22:58:49 +00001355 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001356 child->DumpPrintableRepresentation(
1357 s, ValueObject::eValueObjectRepresentationStyleValue,
1358 custom_format);
1359 }
1360
1361 s << ']';
1362
1363 return true;
Enrico Granata86cc9822012-03-19 22:58:49 +00001364 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001365
1366 if ((custom_format == eFormatVectorOfChar) ||
1367 (custom_format == eFormatVectorOfFloat32) ||
1368 (custom_format == eFormatVectorOfFloat64) ||
1369 (custom_format == eFormatVectorOfSInt16) ||
1370 (custom_format == eFormatVectorOfSInt32) ||
1371 (custom_format == eFormatVectorOfSInt64) ||
1372 (custom_format == eFormatVectorOfSInt8) ||
1373 (custom_format == eFormatVectorOfUInt128) ||
1374 (custom_format == eFormatVectorOfUInt16) ||
1375 (custom_format == eFormatVectorOfUInt32) ||
1376 (custom_format == eFormatVectorOfUInt64) ||
1377 (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes
1378 // with ASCII or any vector
1379 // format should be printed
1380 // directly
Enrico Granata86cc9822012-03-19 22:58:49 +00001381 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001382 const size_t count = GetNumChildren();
1383
1384 Format format = FormatManager::GetSingleItemFormat(custom_format);
1385
1386 s << '[';
1387 for (size_t low = 0; low < count; low++) {
1388
1389 if (low)
1390 s << ',';
1391
1392 ValueObjectSP child = GetChildAtIndex(low, true);
1393 if (!child.get()) {
1394 s << "<invalid child>";
1395 continue;
Enrico Granata0dba9b32014-01-08 01:36:59 +00001396 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001397 child->DumpPrintableRepresentation(
1398 s, ValueObject::eValueObjectRepresentationStyleValue, format);
1399 }
1400
1401 s << ']';
1402
1403 return true;
Enrico Granata86cc9822012-03-19 22:58:49 +00001404 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001405 }
1406
1407 if ((custom_format == eFormatBoolean) ||
1408 (custom_format == eFormatBinary) || (custom_format == eFormatChar) ||
1409 (custom_format == eFormatCharPrintable) ||
1410 (custom_format == eFormatComplexFloat) ||
1411 (custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||
1412 (custom_format == eFormatHexUppercase) ||
1413 (custom_format == eFormatFloat) || (custom_format == eFormatOctal) ||
1414 (custom_format == eFormatOSType) ||
1415 (custom_format == eFormatUnicode16) ||
1416 (custom_format == eFormatUnicode32) ||
1417 (custom_format == eFormatUnsigned) ||
1418 (custom_format == eFormatPointer) ||
1419 (custom_format == eFormatComplexInteger) ||
1420 (custom_format == eFormatComplex) ||
1421 (custom_format == eFormatDefault)) // use the [] operator
1422 return false;
Enrico Granata86cc9822012-03-19 22:58:49 +00001423 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001424 }
1425
1426 if (only_special)
1427 return false;
1428
1429 bool var_success = false;
1430
1431 {
Zachary Turnerc1564272016-11-16 21:15:24 +00001432 llvm::StringRef str;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001433
1434 // this is a local stream that we are using to ensure that the data pointed
Zachary Turnerc1564272016-11-16 21:15:24 +00001435 // to by cstr survives long enough for us to copy it to its destination - it
1436 // is necessary to have this temporary storage area for cases where our
1437 // desired output is not backed by some other longer-term storage
Kate Stoneb9c1b512016-09-06 20:57:50 +00001438 StreamString strm;
1439
1440 if (custom_format != eFormatInvalid)
1441 SetFormat(custom_format);
1442
1443 switch (val_obj_display) {
1444 case eValueObjectRepresentationStyleValue:
Zachary Turnerc1564272016-11-16 21:15:24 +00001445 str = GetValueAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001446 break;
1447
1448 case eValueObjectRepresentationStyleSummary:
Zachary Turnerc1564272016-11-16 21:15:24 +00001449 str = GetSummaryAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001450 break;
1451
1452 case eValueObjectRepresentationStyleLanguageSpecific:
Zachary Turnerc1564272016-11-16 21:15:24 +00001453 str = GetObjectDescription();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001454 break;
1455
1456 case eValueObjectRepresentationStyleLocation:
Zachary Turnerc1564272016-11-16 21:15:24 +00001457 str = GetLocationAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001458 break;
1459
1460 case eValueObjectRepresentationStyleChildrenCount:
1461 strm.Printf("%" PRIu64 "", (uint64_t)GetNumChildren());
Zachary Turnerc1564272016-11-16 21:15:24 +00001462 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001463 break;
1464
1465 case eValueObjectRepresentationStyleType:
Zachary Turnerc1564272016-11-16 21:15:24 +00001466 str = GetTypeName().GetStringRef();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001467 break;
1468
1469 case eValueObjectRepresentationStyleName:
Zachary Turnerc1564272016-11-16 21:15:24 +00001470 str = GetName().GetStringRef();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001471 break;
1472
1473 case eValueObjectRepresentationStyleExpressionPath:
1474 GetExpressionPath(strm, false);
Zachary Turnerc1564272016-11-16 21:15:24 +00001475 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001476 break;
1477 }
1478
Zachary Turnerc1564272016-11-16 21:15:24 +00001479 if (str.empty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001480 if (val_obj_display == eValueObjectRepresentationStyleValue)
Zachary Turnerc1564272016-11-16 21:15:24 +00001481 str = GetSummaryAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001482 else if (val_obj_display == eValueObjectRepresentationStyleSummary) {
1483 if (!CanProvideValue()) {
1484 strm.Printf("%s @ %s", GetTypeName().AsCString(),
1485 GetLocationAsCString());
Zachary Turnerc1564272016-11-16 21:15:24 +00001486 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001487 } else
Zachary Turnerc1564272016-11-16 21:15:24 +00001488 str = GetValueAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001489 }
1490 }
1491
Zachary Turnerc1564272016-11-16 21:15:24 +00001492 if (!str.empty())
1493 s << str;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001494 else {
1495 if (m_error.Fail()) {
1496 if (do_dump_error)
1497 s.Printf("<%s>", m_error.AsCString());
1498 else
1499 return false;
1500 } else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1501 s.PutCString("<no summary available>");
1502 else if (val_obj_display == eValueObjectRepresentationStyleValue)
1503 s.PutCString("<no value available>");
1504 else if (val_obj_display ==
1505 eValueObjectRepresentationStyleLanguageSpecific)
1506 s.PutCString("<not a valid Objective-C object>"); // edit this if we
1507 // have other runtimes
1508 // that support a
1509 // description
1510 else
1511 s.PutCString("<no printable representation>");
1512 }
1513
1514 // we should only return false here if we could not do *anything*
1515 // even if we have an error message as output, that's a success
1516 // from our callers' perspective, so return true
1517 var_success = true;
1518
1519 if (custom_format != eFormatInvalid)
1520 SetFormat(eFormatDefault);
1521 }
1522
1523 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001524}
1525
Kate Stoneb9c1b512016-09-06 20:57:50 +00001526addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
1527 AddressType *address_type) {
1528 // Can't take address of a bitfield
1529 if (IsBitfield())
Greg Clayton73b472d2010-10-27 03:32:59 +00001530 return LLDB_INVALID_ADDRESS;
Greg Clayton73b472d2010-10-27 03:32:59 +00001531
Kate Stoneb9c1b512016-09-06 20:57:50 +00001532 if (!UpdateValueIfNeeded(false))
1533 return LLDB_INVALID_ADDRESS;
Greg Clayton737b9322010-09-13 03:32:57 +00001534
Kate Stoneb9c1b512016-09-06 20:57:50 +00001535 switch (m_value.GetValueType()) {
1536 case Value::eValueTypeScalar:
1537 case Value::eValueTypeVector:
1538 if (scalar_is_load_address) {
1539 if (address_type)
1540 *address_type = eAddressTypeLoad;
1541 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
Greg Clayton737b9322010-09-13 03:32:57 +00001542 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001543 break;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001544
Kate Stoneb9c1b512016-09-06 20:57:50 +00001545 case Value::eValueTypeLoadAddress:
1546 case Value::eValueTypeFileAddress: {
Enrico Granata9128ee22011-09-06 19:20:51 +00001547 if (address_type)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001548 *address_type = m_value.GetValueAddressType();
1549 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1550 } break;
1551 case Value::eValueTypeHostAddress: {
1552 if (address_type)
1553 *address_type = m_value.GetValueAddressType();
1554 return LLDB_INVALID_ADDRESS;
1555 } break;
1556 }
1557 if (address_type)
1558 *address_type = eAddressTypeInvalid;
1559 return LLDB_INVALID_ADDRESS;
1560}
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001561
Kate Stoneb9c1b512016-09-06 20:57:50 +00001562addr_t ValueObject::GetPointerValue(AddressType *address_type) {
1563 addr_t address = LLDB_INVALID_ADDRESS;
1564 if (address_type)
1565 *address_type = eAddressTypeInvalid;
1566
1567 if (!UpdateValueIfNeeded(false))
Greg Clayton737b9322010-09-13 03:32:57 +00001568 return address;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001569
1570 switch (m_value.GetValueType()) {
1571 case Value::eValueTypeScalar:
1572 case Value::eValueTypeVector:
1573 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1574 break;
1575
1576 case Value::eValueTypeHostAddress:
1577 case Value::eValueTypeLoadAddress:
1578 case Value::eValueTypeFileAddress: {
1579 lldb::offset_t data_offset = 0;
1580 address = m_data.GetPointer(&data_offset);
1581 } break;
1582 }
1583
1584 if (address_type)
1585 *address_type = GetAddressTypeOfChildren();
1586
1587 return address;
Greg Clayton737b9322010-09-13 03:32:57 +00001588}
1589
Kate Stoneb9c1b512016-09-06 20:57:50 +00001590bool ValueObject::SetValueFromCString(const char *value_str, Error &error) {
1591 error.Clear();
1592 // Make sure our value is up to date first so that our location and location
1593 // type is valid.
1594 if (!UpdateValueIfNeeded(false)) {
1595 error.SetErrorString("unable to read value");
Greg Clayton81e871e2012-02-04 02:27:34 +00001596 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001597 }
1598
1599 uint64_t count = 0;
1600 const Encoding encoding = GetCompilerType().GetEncoding(count);
1601
1602 const size_t byte_size = GetByteSize();
1603
1604 Value::ValueType value_type = m_value.GetValueType();
1605
1606 if (value_type == Value::eValueTypeScalar) {
1607 // If the value is already a scalar, then let the scalar change itself:
1608 m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
1609 } else if (byte_size <= 16) {
1610 // If the value fits in a scalar, then make a new scalar and again let the
1611 // scalar code do the conversion, then figure out where to put the new
1612 // value.
1613 Scalar new_scalar;
1614 error = new_scalar.SetValueFromCString(value_str, encoding, byte_size);
1615 if (error.Success()) {
1616 switch (value_type) {
1617 case Value::eValueTypeLoadAddress: {
1618 // If it is a load address, then the scalar value is the storage
1619 // location
1620 // of the data, and we have to shove this value down to that load
1621 // location.
1622 ExecutionContext exe_ctx(GetExecutionContextRef());
1623 Process *process = exe_ctx.GetProcessPtr();
1624 if (process) {
1625 addr_t target_addr =
1626 m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1627 size_t bytes_written = process->WriteScalarToMemory(
1628 target_addr, new_scalar, byte_size, error);
1629 if (!error.Success())
1630 return false;
1631 if (bytes_written != byte_size) {
1632 error.SetErrorString("unable to write value to memory");
1633 return false;
1634 }
1635 }
1636 } break;
1637 case Value::eValueTypeHostAddress: {
1638 // If it is a host address, then we stuff the scalar as a DataBuffer
1639 // into the Value's data.
1640 DataExtractor new_data;
1641 new_data.SetByteOrder(m_data.GetByteOrder());
1642
1643 DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
1644 m_data.SetData(buffer_sp, 0);
1645 bool success = new_scalar.GetData(new_data);
1646 if (success) {
1647 new_data.CopyByteOrderedData(
1648 0, byte_size, const_cast<uint8_t *>(m_data.GetDataStart()),
1649 byte_size, m_data.GetByteOrder());
1650 }
1651 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1652
1653 } break;
1654 case Value::eValueTypeFileAddress:
1655 case Value::eValueTypeScalar:
1656 case Value::eValueTypeVector:
1657 break;
1658 }
1659 } else {
1660 return false;
1661 }
1662 } else {
1663 // We don't support setting things bigger than a scalar at present.
1664 error.SetErrorString("unable to write aggregate data type");
1665 return false;
1666 }
1667
1668 // If we have reached this point, then we have successfully changed the value.
1669 SetNeedsUpdate();
1670 return true;
Greg Clayton81e871e2012-02-04 02:27:34 +00001671}
1672
Kate Stoneb9c1b512016-09-06 20:57:50 +00001673bool ValueObject::GetDeclaration(Declaration &decl) {
1674 decl.Clear();
1675 return false;
Greg Clayton84db9102012-03-26 23:03:23 +00001676}
1677
Kate Stoneb9c1b512016-09-06 20:57:50 +00001678ConstString ValueObject::GetTypeName() {
1679 return GetCompilerType().GetConstTypeName();
Enrico Granatae8daa2f2014-05-17 19:14:17 +00001680}
1681
Kate Stoneb9c1b512016-09-06 20:57:50 +00001682ConstString ValueObject::GetDisplayTypeName() { return GetTypeName(); }
1683
1684ConstString ValueObject::GetQualifiedTypeName() {
1685 return GetCompilerType().GetConstQualifiedTypeName();
Greg Clayton84db9102012-03-26 23:03:23 +00001686}
1687
Kate Stoneb9c1b512016-09-06 20:57:50 +00001688LanguageType ValueObject::GetObjectRuntimeLanguage() {
1689 return GetCompilerType().GetMinimumLanguage();
Jim Ingham5a369122010-09-28 01:25:32 +00001690}
1691
Kate Stoneb9c1b512016-09-06 20:57:50 +00001692void ValueObject::AddSyntheticChild(const ConstString &key,
1693 ValueObject *valobj) {
1694 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001695}
1696
Kate Stoneb9c1b512016-09-06 20:57:50 +00001697ValueObjectSP ValueObject::GetSyntheticChild(const ConstString &key) const {
1698 ValueObjectSP synthetic_child_sp;
1699 std::map<ConstString, ValueObject *>::const_iterator pos =
1700 m_synthetic_children.find(key);
1701 if (pos != m_synthetic_children.end())
1702 synthetic_child_sp = pos->second->GetSP();
1703 return synthetic_child_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001704}
1705
Greg Clayton2452ab72013-02-08 22:02:02 +00001706uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001707ValueObject::GetTypeInfo(CompilerType *pointee_or_element_compiler_type) {
1708 return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type);
Greg Clayton2452ab72013-02-08 22:02:02 +00001709}
1710
Kate Stoneb9c1b512016-09-06 20:57:50 +00001711bool ValueObject::IsPointerType() { return GetCompilerType().IsPointerType(); }
1712
1713bool ValueObject::IsArrayType() {
1714 return GetCompilerType().IsArrayType(NULL, NULL, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001715}
1716
Kate Stoneb9c1b512016-09-06 20:57:50 +00001717bool ValueObject::IsScalarType() { return GetCompilerType().IsScalarType(); }
1718
1719bool ValueObject::IsIntegerType(bool &is_signed) {
1720 return GetCompilerType().IsIntegerType(is_signed);
Greg Claytondaf515f2011-07-09 20:12:33 +00001721}
1722
Kate Stoneb9c1b512016-09-06 20:57:50 +00001723bool ValueObject::IsPointerOrReferenceType() {
1724 return GetCompilerType().IsPointerOrReferenceType();
Enrico Granata9fc19442011-07-06 02:13:41 +00001725}
1726
Kate Stoneb9c1b512016-09-06 20:57:50 +00001727bool ValueObject::IsPossibleDynamicType() {
1728 ExecutionContext exe_ctx(GetExecutionContextRef());
1729 Process *process = exe_ctx.GetProcessPtr();
1730 if (process)
1731 return process->IsPossibleDynamicValue(*this);
1732 else
1733 return GetCompilerType().IsPossibleDynamicType(NULL, true, true);
Jim Inghamb7603bb2011-03-18 00:05:18 +00001734}
Greg Clayton73b472d2010-10-27 03:32:59 +00001735
Kate Stoneb9c1b512016-09-06 20:57:50 +00001736bool ValueObject::IsRuntimeSupportValue() {
1737 Process *process(GetProcessSP().get());
1738 if (process) {
1739 LanguageRuntime *runtime =
1740 process->GetLanguageRuntime(GetObjectRuntimeLanguage());
1741 if (!runtime)
1742 runtime = process->GetObjCLanguageRuntime();
1743 if (runtime)
1744 return runtime->IsRuntimeSupportValue(*this);
1745 }
1746 return false;
Greg Clayton007d5be2011-05-30 00:49:24 +00001747}
1748
Kate Stoneb9c1b512016-09-06 20:57:50 +00001749bool ValueObject::IsNilReference() {
1750 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1751 return language->IsNilReference(*this);
1752 }
1753 return false;
Greg Claytondea8cb42011-06-29 22:09:02 +00001754}
1755
Kate Stoneb9c1b512016-09-06 20:57:50 +00001756bool ValueObject::IsUninitializedReference() {
1757 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1758 return language->IsUninitializedReference(*this);
1759 }
1760 return false;
Enrico Granata9e7b3882012-12-13 23:50:33 +00001761}
1762
Greg Claytondaf515f2011-07-09 20:12:33 +00001763// This allows you to create an array member using and index
1764// that doesn't not fall in the normal bounds of the array.
1765// Many times structure can be defined as:
1766// struct Collection
1767// {
1768// uint32_t item_count;
1769// Item item_array[0];
1770// };
1771// The size of the "item_array" is 1, but many times in practice
1772// there are more items in "item_array".
1773
Kate Stoneb9c1b512016-09-06 20:57:50 +00001774ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
1775 bool can_create) {
1776 ValueObjectSP synthetic_child_sp;
1777 if (IsPointerType() || IsArrayType()) {
1778 char index_str[64];
1779 snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index);
1780 ConstString index_const_str(index_str);
Enrico Granata6f3533f2011-07-29 19:53:35 +00001781 // Check if we have already created a synthetic array member in this
1782 // valid object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001783 synthetic_child_sp = GetSyntheticChild(index_const_str);
1784 if (!synthetic_child_sp) {
1785 ValueObject *synthetic_child;
1786 // We haven't made a synthetic array member for INDEX yet, so
1787 // lets make one and cache it for any future reference.
1788 synthetic_child = CreateChildAtIndex(0, true, index);
1789
1790 // Cache the value if we got one back...
1791 if (synthetic_child) {
1792 AddSyntheticChild(index_const_str, synthetic_child);
Enrico Granata6f3533f2011-07-29 19:53:35 +00001793 synthetic_child_sp = synthetic_child->GetSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001794 synthetic_child_sp->SetName(ConstString(index_str));
1795 synthetic_child_sp->m_is_array_item_for_pointer = true;
1796 }
Enrico Granata6f3533f2011-07-29 19:53:35 +00001797 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001798 }
1799 return synthetic_child_sp;
Enrico Granata6f3533f2011-07-29 19:53:35 +00001800}
1801
Kate Stoneb9c1b512016-09-06 20:57:50 +00001802ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
1803 bool can_create) {
1804 ValueObjectSP synthetic_child_sp;
1805 if (IsScalarType()) {
1806 char index_str[64];
1807 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1808 ConstString index_const_str(index_str);
Enrico Granata32556cd2014-08-26 20:54:04 +00001809 // Check if we have already created a synthetic array member in this
1810 // valid object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001811 synthetic_child_sp = GetSyntheticChild(index_const_str);
1812 if (!synthetic_child_sp) {
1813 uint32_t bit_field_size = to - from + 1;
1814 uint32_t bit_field_offset = from;
1815 if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
1816 bit_field_offset =
1817 GetByteSize() * 8 - bit_field_size - bit_field_offset;
1818 // We haven't made a synthetic array member for INDEX yet, so
1819 // lets make one and cache it for any future reference.
1820 ValueObjectChild *synthetic_child = new ValueObjectChild(
1821 *this, GetCompilerType(), index_const_str, GetByteSize(), 0,
1822 bit_field_size, bit_field_offset, false, false, eAddressTypeInvalid,
1823 0);
1824
1825 // Cache the value if we got one back...
1826 if (synthetic_child) {
1827 AddSyntheticChild(index_const_str, synthetic_child);
Enrico Granata32556cd2014-08-26 20:54:04 +00001828 synthetic_child_sp = synthetic_child->GetSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001829 synthetic_child_sp->SetName(ConstString(index_str));
1830 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1831 }
Enrico Granata32556cd2014-08-26 20:54:04 +00001832 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001833 }
1834 return synthetic_child_sp;
Enrico Granata32556cd2014-08-26 20:54:04 +00001835}
1836
Kate Stoneb9c1b512016-09-06 20:57:50 +00001837ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
1838 uint32_t offset, const CompilerType &type, bool can_create,
1839 ConstString name_const_str) {
1840
1841 ValueObjectSP synthetic_child_sp;
1842
1843 if (name_const_str.IsEmpty()) {
1844 char name_str[64];
1845 snprintf(name_str, sizeof(name_str), "@%i", offset);
1846 name_const_str.SetCString(name_str);
1847 }
1848
1849 // Check if we have already created a synthetic array member in this
1850 // valid object. If we have we will re-use it.
1851 synthetic_child_sp = GetSyntheticChild(name_const_str);
1852
1853 if (synthetic_child_sp.get())
1854 return synthetic_child_sp;
1855
1856 if (!can_create)
1857 return ValueObjectSP();
1858
1859 ExecutionContext exe_ctx(GetExecutionContextRef());
1860
1861 ValueObjectChild *synthetic_child = new ValueObjectChild(
1862 *this, type, name_const_str,
1863 type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0,
1864 false, false, eAddressTypeInvalid, 0);
1865 if (synthetic_child) {
1866 AddSyntheticChild(name_const_str, synthetic_child);
1867 synthetic_child_sp = synthetic_child->GetSP();
1868 synthetic_child_sp->SetName(name_const_str);
1869 synthetic_child_sp->m_is_child_at_offset = true;
1870 }
1871 return synthetic_child_sp;
1872}
1873
1874ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
1875 const CompilerType &type,
1876 bool can_create,
1877 ConstString name_const_str) {
1878 ValueObjectSP synthetic_child_sp;
1879
1880 if (name_const_str.IsEmpty()) {
1881 char name_str[128];
1882 snprintf(name_str, sizeof(name_str), "base%s@%i",
1883 type.GetTypeName().AsCString("<unknown>"), offset);
1884 name_const_str.SetCString(name_str);
1885 }
1886
1887 // Check if we have already created a synthetic array member in this
1888 // valid object. If we have we will re-use it.
1889 synthetic_child_sp = GetSyntheticChild(name_const_str);
1890
1891 if (synthetic_child_sp.get())
1892 return synthetic_child_sp;
1893
1894 if (!can_create)
1895 return ValueObjectSP();
1896
1897 const bool is_base_class = true;
1898
1899 ExecutionContext exe_ctx(GetExecutionContextRef());
1900
1901 ValueObjectChild *synthetic_child = new ValueObjectChild(
1902 *this, type, name_const_str,
1903 type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0,
1904 is_base_class, false, eAddressTypeInvalid, 0);
1905 if (synthetic_child) {
1906 AddSyntheticChild(name_const_str, synthetic_child);
1907 synthetic_child_sp = synthetic_child->GetSP();
1908 synthetic_child_sp->SetName(name_const_str);
1909 }
1910 return synthetic_child_sp;
1911}
Enrico Granata32556cd2014-08-26 20:54:04 +00001912
Enrico Granatad55546b2011-07-22 00:16:08 +00001913// your expression path needs to have a leading . or ->
1914// (unless it somehow "looks like" an array, in which case it has
1915// a leading [ symbol). while the [ is meaningful and should be shown
1916// to the user, . and -> are just parser design, but by no means
1917// added information for the user.. strip them off
Kate Stoneb9c1b512016-09-06 20:57:50 +00001918static const char *SkipLeadingExpressionPathSeparators(const char *expression) {
1919 if (!expression || !expression[0])
Enrico Granatad55546b2011-07-22 00:16:08 +00001920 return expression;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001921 if (expression[0] == '.')
1922 return expression + 1;
1923 if (expression[0] == '-' && expression[1] == '>')
1924 return expression + 2;
1925 return expression;
Enrico Granatad55546b2011-07-22 00:16:08 +00001926}
1927
Greg Claytonafacd142011-09-02 01:15:17 +00001928ValueObjectSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00001929ValueObject::GetSyntheticExpressionPathChild(const char *expression,
1930 bool can_create) {
1931 ValueObjectSP synthetic_child_sp;
1932 ConstString name_const_string(expression);
1933 // Check if we have already created a synthetic array member in this
1934 // valid object. If we have we will re-use it.
1935 synthetic_child_sp = GetSyntheticChild(name_const_string);
1936 if (!synthetic_child_sp) {
1937 // We haven't made a synthetic array member for expression yet, so
1938 // lets make one and cache it for any future reference.
1939 synthetic_child_sp = GetValueForExpressionPath(
Zachary Turnerd2daca72016-11-18 17:55:04 +00001940 expression, NULL, NULL,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001941 GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(
1942 GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
1943 None));
1944
1945 // Cache the value if we got one back...
1946 if (synthetic_child_sp.get()) {
1947 // FIXME: this causes a "real" child to end up with its name changed to
1948 // the contents of expression
1949 AddSyntheticChild(name_const_string, synthetic_child_sp.get());
1950 synthetic_child_sp->SetName(
1951 ConstString(SkipLeadingExpressionPathSeparators(expression)));
Enrico Granatad55546b2011-07-22 00:16:08 +00001952 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001953 }
1954 return synthetic_child_sp;
Enrico Granatad55546b2011-07-22 00:16:08 +00001955}
1956
Kate Stoneb9c1b512016-09-06 20:57:50 +00001957void ValueObject::CalculateSyntheticValue(bool use_synthetic) {
1958 if (use_synthetic == false)
1959 return;
1960
1961 TargetSP target_sp(GetTargetSP());
1962 if (target_sp && target_sp->GetEnableSyntheticValue() == false) {
1963 m_synthetic_value = NULL;
1964 return;
1965 }
1966
1967 lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
1968
1969 if (!UpdateFormatsIfNeeded() && m_synthetic_value)
1970 return;
1971
1972 if (m_synthetic_children_sp.get() == NULL)
1973 return;
1974
1975 if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
1976 return;
1977
1978 m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
1979}
1980
1981void ValueObject::CalculateDynamicValue(DynamicValueType use_dynamic) {
1982 if (use_dynamic == eNoDynamicValues)
1983 return;
1984
1985 if (!m_dynamic_value && !IsDynamic()) {
1986 ExecutionContext exe_ctx(GetExecutionContextRef());
1987 Process *process = exe_ctx.GetProcessPtr();
1988 if (process && process->IsPossibleDynamicValue(*this)) {
1989 ClearDynamicTypeInformation();
1990 m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
Enrico Granatac5bc4122012-03-27 02:35:13 +00001991 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001992 }
Enrico Granatad55546b2011-07-22 00:16:08 +00001993}
1994
Kate Stoneb9c1b512016-09-06 20:57:50 +00001995ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) {
1996 if (use_dynamic == eNoDynamicValues)
1997 return ValueObjectSP();
1998
1999 if (!IsDynamic() && m_dynamic_value == NULL) {
2000 CalculateDynamicValue(use_dynamic);
2001 }
2002 if (m_dynamic_value)
2003 return m_dynamic_value->GetSP();
2004 else
2005 return ValueObjectSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00002006}
2007
Kate Stoneb9c1b512016-09-06 20:57:50 +00002008ValueObjectSP ValueObject::GetStaticValue() { return GetSP(); }
2009
2010lldb::ValueObjectSP ValueObject::GetNonSyntheticValue() { return GetSP(); }
2011
2012ValueObjectSP ValueObject::GetSyntheticValue(bool use_synthetic) {
2013 if (use_synthetic == false)
2014 return ValueObjectSP();
2015
2016 CalculateSyntheticValue(use_synthetic);
2017
2018 if (m_synthetic_value)
2019 return m_synthetic_value->GetSP();
2020 else
2021 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00002022}
Greg Clayton1d3afba2010-10-05 00:00:42 +00002023
Kate Stoneb9c1b512016-09-06 20:57:50 +00002024bool ValueObject::HasSyntheticValue() {
2025 UpdateFormatsIfNeeded();
Jim Ingham60dbabb2011-12-08 19:44:08 +00002026
Kate Stoneb9c1b512016-09-06 20:57:50 +00002027 if (m_synthetic_children_sp.get() == NULL)
2028 return false;
Enrico Granata886147f2012-05-08 18:47:08 +00002029
Kate Stoneb9c1b512016-09-06 20:57:50 +00002030 CalculateSyntheticValue(true);
Enrico Granata86cc9822012-03-19 22:58:49 +00002031
Kate Stoneb9c1b512016-09-06 20:57:50 +00002032 if (m_synthetic_value)
2033 return true;
2034 else
Greg Claytone221f822011-01-21 01:59:00 +00002035 return false;
2036}
2037
Kate Stoneb9c1b512016-09-06 20:57:50 +00002038bool ValueObject::GetBaseClassPath(Stream &s) {
2039 if (IsBaseClass()) {
2040 bool parent_had_base_class =
2041 GetParent() && GetParent()->GetBaseClassPath(s);
2042 CompilerType compiler_type = GetCompilerType();
2043 std::string cxx_class_name;
2044 bool this_had_base_class =
2045 ClangASTContext::GetCXXClassName(compiler_type, cxx_class_name);
2046 if (this_had_base_class) {
2047 if (parent_had_base_class)
2048 s.PutCString("::");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00002049 s.PutCString(cxx_class_name);
Greg Claytone221f822011-01-21 01:59:00 +00002050 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002051 return parent_had_base_class || this_had_base_class;
2052 }
2053 return false;
Greg Claytone221f822011-01-21 01:59:00 +00002054}
Greg Clayton1d3afba2010-10-05 00:00:42 +00002055
Kate Stoneb9c1b512016-09-06 20:57:50 +00002056ValueObject *ValueObject::GetNonBaseClassParent() {
2057 if (GetParent()) {
2058 if (GetParent()->IsBaseClass())
2059 return GetParent()->GetNonBaseClassParent();
2060 else
2061 return GetParent();
2062 }
2063 return NULL;
2064}
Enrico Granataa3c8f042014-08-19 22:29:08 +00002065
Kate Stoneb9c1b512016-09-06 20:57:50 +00002066bool ValueObject::IsBaseClass(uint32_t &depth) {
2067 if (!IsBaseClass()) {
2068 depth = 0;
2069 return false;
2070 }
2071 if (GetParent()) {
2072 GetParent()->IsBaseClass(depth);
2073 depth = depth + 1;
Enrico Granataa3c8f042014-08-19 22:29:08 +00002074 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002075 }
2076 // TODO: a base of no parent? weird..
2077 depth = 1;
2078 return true;
Enrico Granataa3c8f042014-08-19 22:29:08 +00002079}
2080
Kate Stoneb9c1b512016-09-06 20:57:50 +00002081void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes,
2082 GetExpressionPathFormat epformat) {
2083 // synthetic children do not actually "exist" as part of the hierarchy, and
2084 // sometimes they are consed up in ways
2085 // that don't make sense from an underlying language/API standpoint. So, use a
2086 // special code path here to return
2087 // something that can hopefully be used in expression
2088 if (m_is_synthetic_children_generated) {
2089 UpdateValueIfNeeded();
2090
2091 if (m_value.GetValueType() == Value::eValueTypeLoadAddress) {
2092 if (IsPointerOrReferenceType()) {
2093 s.Printf("((%s)0x%" PRIx64 ")", GetTypeName().AsCString("void"),
2094 GetValueAsUnsigned(0));
Enrico Granata986fa5f2014-12-09 21:41:16 +00002095 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002096 } else {
2097 uint64_t load_addr =
2098 m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
2099 if (load_addr != LLDB_INVALID_ADDRESS) {
2100 s.Printf("(*( (%s *)0x%" PRIx64 "))", GetTypeName().AsCString("void"),
2101 load_addr);
2102 return;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002103 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002104 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002105 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002106
2107 if (CanProvideValue()) {
2108 s.Printf("((%s)%s)", GetTypeName().AsCString("void"),
2109 GetValueAsCString());
2110 return;
Enrico Granata4becb372011-06-29 22:27:15 +00002111 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002112
2113 return;
2114 }
2115
2116 const bool is_deref_of_parent = IsDereferenceOfParent();
2117
2118 if (is_deref_of_parent &&
2119 epformat == eGetExpressionPathFormatDereferencePointers) {
2120 // this is the original format of GetExpressionPath() producing code like
2121 // *(a_ptr).memberName, which is entirely
2122 // fine, until you put this into
2123 // StackFrame::GetValueForVariableExpressionPath() which prefers to see
2124 // a_ptr->memberName.
2125 // the eHonorPointers mode is meant to produce strings in this latter format
2126 s.PutCString("*(");
2127 }
2128
2129 ValueObject *parent = GetParent();
2130
2131 if (parent)
2132 parent->GetExpressionPath(s, qualify_cxx_base_classes, epformat);
2133
2134 // if we are a deref_of_parent just because we are synthetic array
2135 // members made up to allow ptr[%d] syntax to work in variable
2136 // printing, then add our name ([%d]) to the expression path
2137 if (m_is_array_item_for_pointer &&
2138 epformat == eGetExpressionPathFormatHonorPointers)
2139 s.PutCString(m_name.AsCString());
2140
2141 if (!IsBaseClass()) {
2142 if (!is_deref_of_parent) {
2143 ValueObject *non_base_class_parent = GetNonBaseClassParent();
2144 if (non_base_class_parent &&
2145 !non_base_class_parent->GetName().IsEmpty()) {
2146 CompilerType non_base_class_parent_compiler_type =
2147 non_base_class_parent->GetCompilerType();
2148 if (non_base_class_parent_compiler_type) {
2149 if (parent && parent->IsDereferenceOfParent() &&
2150 epformat == eGetExpressionPathFormatHonorPointers) {
2151 s.PutCString("->");
2152 } else {
2153 const uint32_t non_base_class_parent_type_info =
2154 non_base_class_parent_compiler_type.GetTypeInfo();
2155
2156 if (non_base_class_parent_type_info & eTypeIsPointer) {
2157 s.PutCString("->");
2158 } else if ((non_base_class_parent_type_info & eTypeHasChildren) &&
2159 !(non_base_class_parent_type_info & eTypeIsArray)) {
2160 s.PutChar('.');
2161 }
2162 }
2163 }
2164 }
2165
2166 const char *name = GetName().GetCString();
2167 if (name) {
2168 if (qualify_cxx_base_classes) {
2169 if (GetBaseClassPath(s))
2170 s.PutCString("::");
2171 }
2172 s.PutCString(name);
2173 }
2174 }
2175 }
2176
2177 if (is_deref_of_parent &&
2178 epformat == eGetExpressionPathFormatDereferencePointers) {
2179 s.PutChar(')');
2180 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002181}
2182
Kate Stoneb9c1b512016-09-06 20:57:50 +00002183ValueObjectSP ValueObject::GetValueForExpressionPath(
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002184 llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002185 ExpressionPathEndResultType *final_value_type,
2186 const GetValueForExpressionPathOptions &options,
2187 ExpressionPathAftermath *final_task_on_target) {
Enrico Granata385ad4e2012-03-03 00:45:57 +00002188
Kate Stoneb9c1b512016-09-06 20:57:50 +00002189 ExpressionPathScanEndReason dummy_reason_to_stop =
2190 ValueObject::eExpressionPathScanEndReasonUnknown;
2191 ExpressionPathEndResultType dummy_final_value_type =
2192 ValueObject::eExpressionPathEndResultTypeInvalid;
2193 ExpressionPathAftermath dummy_final_task_on_target =
2194 ValueObject::eExpressionPathAftermathNothing;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002195
Kate Stoneb9c1b512016-09-06 20:57:50 +00002196 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(
Zachary Turnerd2daca72016-11-18 17:55:04 +00002197 expression, reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002198 final_value_type ? final_value_type : &dummy_final_value_type, options,
2199 final_task_on_target ? final_task_on_target
2200 : &dummy_final_task_on_target);
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002201
Kate Stoneb9c1b512016-09-06 20:57:50 +00002202 if (!final_task_on_target ||
2203 *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
2204 return ret_val;
2205
2206 if (ret_val.get() &&
2207 ((final_value_type ? *final_value_type : dummy_final_value_type) ==
2208 eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress
2209 // of plain objects
2210 {
2211 if ((final_task_on_target ? *final_task_on_target
2212 : dummy_final_task_on_target) ==
2213 ValueObject::eExpressionPathAftermathDereference) {
2214 Error error;
2215 ValueObjectSP final_value = ret_val->Dereference(error);
2216 if (error.Fail() || !final_value.get()) {
2217 if (reason_to_stop)
2218 *reason_to_stop =
2219 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2220 if (final_value_type)
2221 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002222 return ValueObjectSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002223 } else {
2224 if (final_task_on_target)
2225 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2226 return final_value;
2227 }
2228 }
2229 if (*final_task_on_target ==
2230 ValueObject::eExpressionPathAftermathTakeAddress) {
2231 Error error;
2232 ValueObjectSP final_value = ret_val->AddressOf(error);
2233 if (error.Fail() || !final_value.get()) {
2234 if (reason_to_stop)
2235 *reason_to_stop =
2236 ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
2237 if (final_value_type)
2238 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2239 return ValueObjectSP();
2240 } else {
2241 if (final_task_on_target)
2242 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2243 return final_value;
2244 }
2245 }
2246 }
2247 return ret_val; // final_task_on_target will still have its original value, so
2248 // you know I did not do it
2249}
2250
Kate Stoneb9c1b512016-09-06 20:57:50 +00002251ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002252 llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002253 ExpressionPathEndResultType *final_result,
2254 const GetValueForExpressionPathOptions &options,
2255 ExpressionPathAftermath *what_next) {
2256 ValueObjectSP root = GetSP();
2257
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002258 if (!root)
2259 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002260
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002261 llvm::StringRef remainder = expression;
Zachary Turner655c4522016-11-18 06:34:45 +00002262
Kate Stoneb9c1b512016-09-06 20:57:50 +00002263 while (true) {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002264 llvm::StringRef temp_expression = remainder;
Zachary Turner655c4522016-11-18 06:34:45 +00002265
Kate Stoneb9c1b512016-09-06 20:57:50 +00002266 CompilerType root_compiler_type = root->GetCompilerType();
2267 CompilerType pointee_compiler_type;
2268 Flags pointee_compiler_type_info;
2269
2270 Flags root_compiler_type_info(
2271 root_compiler_type.GetTypeInfo(&pointee_compiler_type));
2272 if (pointee_compiler_type)
2273 pointee_compiler_type_info.Reset(pointee_compiler_type.GetTypeInfo());
2274
Zachary Turnerd2daca72016-11-18 17:55:04 +00002275 if (temp_expression.empty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002276 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2277 return root;
2278 }
2279
Zachary Turnerd2daca72016-11-18 17:55:04 +00002280 switch (temp_expression.front()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002281 case '-': {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002282 temp_expression = temp_expression.drop_front();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002283 if (options.m_check_dot_vs_arrow_syntax &&
2284 root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2285 // use -> on a
2286 // non-pointer and I
2287 // must catch the error
2288 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002289 *reason_to_stop =
2290 ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
2291 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2292 return ValueObjectSP();
2293 }
2294 if (root_compiler_type_info.Test(eTypeIsObjC) && // if yo are trying to
2295 // extract an ObjC IVar
2296 // when this is forbidden
2297 root_compiler_type_info.Test(eTypeIsPointer) &&
2298 options.m_no_fragile_ivar) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002299 *reason_to_stop =
2300 ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
2301 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2302 return ValueObjectSP();
2303 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002304 if (!temp_expression.startswith(">")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002305 *reason_to_stop =
2306 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2307 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2308 return ValueObjectSP();
2309 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002310 }
2311 LLVM_FALLTHROUGH;
2312 case '.': // or fallthrough from ->
2313 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002314 if (options.m_check_dot_vs_arrow_syntax &&
2315 temp_expression.front() == '.' &&
Kate Stoneb9c1b512016-09-06 20:57:50 +00002316 root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2317 // use . on a pointer
2318 // and I must catch the
2319 // error
2320 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002321 *reason_to_stop =
2322 ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
2323 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002324 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002325 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002326 temp_expression = temp_expression.drop_front(); // skip . or >
2327
2328 size_t next_sep_pos = temp_expression.find_first_of("-.[", 1);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002329 ConstString child_name;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002330 if (next_sep_pos == llvm::StringRef::npos) // if no other separator just
2331 // expand this last layer
Kate Stoneb9c1b512016-09-06 20:57:50 +00002332 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002333 child_name.SetString(temp_expression);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002334 ValueObjectSP child_valobj_sp =
2335 root->GetChildMemberWithName(child_name, true);
2336
2337 if (child_valobj_sp.get()) // we know we are done, so just return
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002338 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002339 *reason_to_stop =
2340 ValueObject::eExpressionPathScanEndReasonEndOfString;
2341 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2342 return child_valobj_sp;
2343 } else {
2344 switch (options.m_synthetic_children_traversal) {
2345 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2346 None:
2347 break;
2348 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2349 FromSynthetic:
2350 if (root->IsSynthetic()) {
2351 child_valobj_sp = root->GetNonSyntheticValue();
2352 if (child_valobj_sp.get())
2353 child_valobj_sp =
2354 child_valobj_sp->GetChildMemberWithName(child_name, true);
2355 }
2356 break;
2357 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2358 ToSynthetic:
2359 if (!root->IsSynthetic()) {
2360 child_valobj_sp = root->GetSyntheticValue();
2361 if (child_valobj_sp.get())
2362 child_valobj_sp =
2363 child_valobj_sp->GetChildMemberWithName(child_name, true);
2364 }
2365 break;
2366 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2367 Both:
2368 if (root->IsSynthetic()) {
2369 child_valobj_sp = root->GetNonSyntheticValue();
2370 if (child_valobj_sp.get())
2371 child_valobj_sp =
2372 child_valobj_sp->GetChildMemberWithName(child_name, true);
2373 } else {
2374 child_valobj_sp = root->GetSyntheticValue();
2375 if (child_valobj_sp.get())
2376 child_valobj_sp =
2377 child_valobj_sp->GetChildMemberWithName(child_name, true);
2378 }
2379 break;
2380 }
2381 }
2382
2383 // if we are here and options.m_no_synthetic_children is true,
2384 // child_valobj_sp is going to be a NULL SP,
2385 // so we hit the "else" branch, and return an error
2386 if (child_valobj_sp.get()) // if it worked, just return
2387 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002388 *reason_to_stop =
2389 ValueObject::eExpressionPathScanEndReasonEndOfString;
2390 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2391 return child_valobj_sp;
2392 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002393 *reason_to_stop =
2394 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2395 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002396 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002397 }
2398 } else // other layers do expand
2399 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002400 llvm::StringRef next_separator = temp_expression.substr(next_sep_pos);
2401
2402 child_name.SetString(temp_expression.slice(0, next_sep_pos));
2403
Kate Stoneb9c1b512016-09-06 20:57:50 +00002404 ValueObjectSP child_valobj_sp =
2405 root->GetChildMemberWithName(child_name, true);
2406 if (child_valobj_sp.get()) // store the new root and move on
2407 {
2408 root = child_valobj_sp;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002409 remainder = next_separator;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002410 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2411 continue;
2412 } else {
2413 switch (options.m_synthetic_children_traversal) {
2414 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2415 None:
2416 break;
2417 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2418 FromSynthetic:
2419 if (root->IsSynthetic()) {
2420 child_valobj_sp = root->GetNonSyntheticValue();
2421 if (child_valobj_sp.get())
2422 child_valobj_sp =
2423 child_valobj_sp->GetChildMemberWithName(child_name, true);
2424 }
2425 break;
2426 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2427 ToSynthetic:
2428 if (!root->IsSynthetic()) {
2429 child_valobj_sp = root->GetSyntheticValue();
2430 if (child_valobj_sp.get())
2431 child_valobj_sp =
2432 child_valobj_sp->GetChildMemberWithName(child_name, true);
2433 }
2434 break;
2435 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2436 Both:
2437 if (root->IsSynthetic()) {
2438 child_valobj_sp = root->GetNonSyntheticValue();
2439 if (child_valobj_sp.get())
2440 child_valobj_sp =
2441 child_valobj_sp->GetChildMemberWithName(child_name, true);
2442 } else {
2443 child_valobj_sp = root->GetSyntheticValue();
2444 if (child_valobj_sp.get())
2445 child_valobj_sp =
2446 child_valobj_sp->GetChildMemberWithName(child_name, true);
2447 }
2448 break;
2449 }
2450 }
2451
2452 // if we are here and options.m_no_synthetic_children is true,
2453 // child_valobj_sp is going to be a NULL SP,
2454 // so we hit the "else" branch, and return an error
2455 if (child_valobj_sp.get()) // if it worked, move on
2456 {
2457 root = child_valobj_sp;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002458 remainder = next_separator;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002459 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2460 continue;
2461 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002462 *reason_to_stop =
2463 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2464 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002465 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002466 }
2467 }
2468 break;
2469 }
2470 case '[': {
2471 if (!root_compiler_type_info.Test(eTypeIsArray) &&
2472 !root_compiler_type_info.Test(eTypeIsPointer) &&
2473 !root_compiler_type_info.Test(
2474 eTypeIsVector)) // if this is not a T[] nor a T*
2475 {
2476 if (!root_compiler_type_info.Test(
2477 eTypeIsScalar)) // if this is not even a scalar...
2478 {
2479 if (options.m_synthetic_children_traversal ==
2480 GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2481 None) // ...only chance left is synthetic
2482 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002483 *reason_to_stop =
2484 ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
2485 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2486 return ValueObjectSP();
2487 }
2488 } else if (!options.m_allow_bitfields_syntax) // if this is a scalar,
2489 // check that we can
2490 // expand bitfields
2491 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002492 *reason_to_stop =
2493 ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
2494 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2495 return ValueObjectSP();
2496 }
2497 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002498 if (temp_expression[1] ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002499 ']') // if this is an unbounded range it only works for arrays
2500 {
2501 if (!root_compiler_type_info.Test(eTypeIsArray)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002502 *reason_to_stop =
2503 ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2504 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002505 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002506 } else // even if something follows, we cannot expand unbounded ranges,
2507 // just let the caller do it
2508 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002509 *reason_to_stop =
2510 ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2511 *final_result =
2512 ValueObject::eExpressionPathEndResultTypeUnboundedRange;
2513 return root;
2514 }
2515 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002516
2517 size_t close_bracket_position = temp_expression.find(']', 1);
2518 if (close_bracket_position ==
2519 llvm::StringRef::npos) // if there is no ], this is a syntax error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002520 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002521 *reason_to_stop =
2522 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2523 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002524 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002525 }
Zachary Turnerc2d55582016-11-18 03:51:19 +00002526
Zachary Turnerd2daca72016-11-18 17:55:04 +00002527 llvm::StringRef bracket_expr =
2528 temp_expression.slice(1, close_bracket_position);
2529
2530 // If this was an empty expression it would have been caught by the if
2531 // above.
2532 assert(!bracket_expr.empty());
2533
2534 if (!bracket_expr.contains('-')) {
Zachary Turnerc2d55582016-11-18 03:51:19 +00002535 // if no separator, this is of the form [N]. Note that this cannot
2536 // be an unbounded range of the form [], because that case was handled
2537 // above with an unconditional return.
Zachary Turnerd2daca72016-11-18 17:55:04 +00002538 unsigned long index = 0;
2539 if (bracket_expr.getAsInteger(0, index)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002540 *reason_to_stop =
2541 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2542 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002543 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002544 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002545
Kate Stoneb9c1b512016-09-06 20:57:50 +00002546 // from here on we do have a valid index
2547 if (root_compiler_type_info.Test(eTypeIsArray)) {
2548 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2549 if (!child_valobj_sp)
2550 child_valobj_sp = root->GetSyntheticArrayMember(index, true);
2551 if (!child_valobj_sp)
2552 if (root->HasSyntheticValue() &&
2553 root->GetSyntheticValue()->GetNumChildren() > index)
2554 child_valobj_sp =
2555 root->GetSyntheticValue()->GetChildAtIndex(index, true);
2556 if (child_valobj_sp) {
2557 root = child_valobj_sp;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002558 remainder =
2559 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002560 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2561 continue;
2562 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002563 *reason_to_stop =
2564 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2565 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002566 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002567 }
2568 } else if (root_compiler_type_info.Test(eTypeIsPointer)) {
2569 if (*what_next ==
2570 ValueObject::
2571 eExpressionPathAftermathDereference && // if this is a
2572 // ptr-to-scalar, I
2573 // am accessing it
2574 // by index and I
2575 // would have
2576 // deref'ed anyway,
2577 // then do it now
2578 // and use this as
2579 // a bitfield
2580 pointee_compiler_type_info.Test(eTypeIsScalar)) {
2581 Error error;
2582 root = root->Dereference(error);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002583 if (error.Fail() || !root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002584 *reason_to_stop =
2585 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2586 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002587 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002588 } else {
2589 *what_next = eExpressionPathAftermathNothing;
2590 continue;
2591 }
2592 } else {
2593 if (root->GetCompilerType().GetMinimumLanguage() ==
2594 eLanguageTypeObjC &&
2595 pointee_compiler_type_info.AllClear(eTypeIsPointer) &&
2596 root->HasSyntheticValue() &&
2597 (options.m_synthetic_children_traversal ==
2598 GetValueForExpressionPathOptions::
2599 SyntheticChildrenTraversal::ToSynthetic ||
2600 options.m_synthetic_children_traversal ==
2601 GetValueForExpressionPathOptions::
2602 SyntheticChildrenTraversal::Both)) {
2603 root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
2604 } else
2605 root = root->GetSyntheticArrayMember(index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002606 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002607 *reason_to_stop =
2608 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2609 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002610 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002611 } else {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002612 remainder =
2613 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002614 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2615 continue;
2616 }
2617 }
2618 } else if (root_compiler_type_info.Test(eTypeIsScalar)) {
2619 root = root->GetSyntheticBitFieldChild(index, index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002620 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002621 *reason_to_stop =
2622 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2623 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002624 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002625 } else // we do not know how to expand members of bitfields, so we
2626 // just return and let the caller do any further processing
2627 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002628 *reason_to_stop = ValueObject::
2629 eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2630 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2631 return root;
2632 }
2633 } else if (root_compiler_type_info.Test(eTypeIsVector)) {
2634 root = root->GetChildAtIndex(index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002635 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002636 *reason_to_stop =
2637 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2638 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2639 return ValueObjectSP();
2640 } else {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002641 remainder =
2642 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002643 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2644 continue;
2645 }
2646 } else if (options.m_synthetic_children_traversal ==
2647 GetValueForExpressionPathOptions::
2648 SyntheticChildrenTraversal::ToSynthetic ||
2649 options.m_synthetic_children_traversal ==
2650 GetValueForExpressionPathOptions::
2651 SyntheticChildrenTraversal::Both) {
2652 if (root->HasSyntheticValue())
2653 root = root->GetSyntheticValue();
2654 else if (!root->IsSynthetic()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002655 *reason_to_stop =
2656 ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2657 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002658 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002659 }
2660 // if we are here, then root itself is a synthetic VO.. should be good
2661 // to go
2662
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002663 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002664 *reason_to_stop =
2665 ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2666 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002667 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002668 }
2669 root = root->GetChildAtIndex(index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002670 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002671 *reason_to_stop =
2672 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2673 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002674 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002675 } else {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002676 remainder =
2677 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002678 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2679 continue;
2680 }
2681 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002682 *reason_to_stop =
2683 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2684 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002685 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002686 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002687 } else {
2688 // we have a low and a high index
2689 llvm::StringRef sleft, sright;
2690 unsigned long low_index, high_index;
2691 std::tie(sleft, sright) = bracket_expr.split('-');
2692 if (sleft.getAsInteger(0, low_index) ||
2693 sright.getAsInteger(0, high_index)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002694 *reason_to_stop =
2695 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2696 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002697 return nullptr;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002698 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002699
2700 if (low_index > high_index) // swap indices if required
2701 std::swap(low_index, high_index);
Zachary Turnerc2d55582016-11-18 03:51:19 +00002702
Kate Stoneb9c1b512016-09-06 20:57:50 +00002703 if (root_compiler_type_info.Test(
2704 eTypeIsScalar)) // expansion only works for scalars
2705 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002706 root = root->GetSyntheticBitFieldChild(low_index, high_index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002707 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002708 *reason_to_stop =
2709 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2710 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002711 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002712 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002713 *reason_to_stop = ValueObject::
2714 eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2715 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2716 return root;
2717 }
2718 } else if (root_compiler_type_info.Test(
2719 eTypeIsPointer) && // if this is a ptr-to-scalar, I am
2720 // accessing it by index and I would
2721 // have deref'ed anyway, then do it
2722 // now and use this as a bitfield
2723 *what_next ==
2724 ValueObject::eExpressionPathAftermathDereference &&
2725 pointee_compiler_type_info.Test(eTypeIsScalar)) {
2726 Error error;
2727 root = root->Dereference(error);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002728 if (error.Fail() || !root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002729 *reason_to_stop =
2730 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2731 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002732 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002733 } else {
2734 *what_next = ValueObject::eExpressionPathAftermathNothing;
2735 continue;
2736 }
2737 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002738 *reason_to_stop =
2739 ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2740 *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
2741 return root;
2742 }
2743 }
2744 break;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002745 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002746 default: // some non-separator is in the way
2747 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002748 *reason_to_stop =
2749 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2750 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002751 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002752 }
2753 }
2754 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002755}
2756
Kate Stoneb9c1b512016-09-06 20:57:50 +00002757void ValueObject::LogValueObject(Log *log) {
2758 if (log)
2759 return LogValueObject(log, DumpValueObjectOptions(*this));
Enrico Granata538a88a2014-10-09 18:24:30 +00002760}
2761
Kate Stoneb9c1b512016-09-06 20:57:50 +00002762void ValueObject::LogValueObject(Log *log,
2763 const DumpValueObjectOptions &options) {
2764 if (log) {
2765 StreamString s;
2766 Dump(s, options);
2767 if (s.GetSize())
2768 log->PutCString(s.GetData());
2769 }
Greg Clayton759e7442014-07-19 00:12:57 +00002770}
2771
Kate Stoneb9c1b512016-09-06 20:57:50 +00002772void ValueObject::Dump(Stream &s) { Dump(s, DumpValueObjectOptions(*this)); }
Chaoren Lind7bdc272015-07-31 00:35:40 +00002773
Kate Stoneb9c1b512016-09-06 20:57:50 +00002774void ValueObject::Dump(Stream &s, const DumpValueObjectOptions &options) {
2775 ValueObjectPrinter printer(this, &s, options);
2776 printer.PrintValueObject();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002777}
2778
Kate Stoneb9c1b512016-09-06 20:57:50 +00002779ValueObjectSP ValueObject::CreateConstantValue(const ConstString &name) {
2780 ValueObjectSP valobj_sp;
2781
2782 if (UpdateValueIfNeeded(false) && m_error.Success()) {
2783 ExecutionContext exe_ctx(GetExecutionContextRef());
2784
2785 DataExtractor data;
2786 data.SetByteOrder(m_data.GetByteOrder());
2787 data.SetAddressByteSize(m_data.GetAddressByteSize());
2788
2789 if (IsBitfield()) {
2790 Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
2791 m_error = v.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
2792 } else
2793 m_error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
2794
2795 valobj_sp = ValueObjectConstResult::Create(
2796 exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,
2797 GetAddressOf());
2798 }
2799
2800 if (!valobj_sp) {
2801 ExecutionContext exe_ctx(GetExecutionContextRef());
2802 valobj_sp = ValueObjectConstResult::Create(
2803 exe_ctx.GetBestExecutionContextScope(), m_error);
2804 }
2805 return valobj_sp;
2806}
2807
2808ValueObjectSP ValueObject::GetQualifiedRepresentationIfAvailable(
2809 lldb::DynamicValueType dynValue, bool synthValue) {
2810 ValueObjectSP result_sp(GetSP());
2811
2812 switch (dynValue) {
2813 case lldb::eDynamicCanRunTarget:
2814 case lldb::eDynamicDontRunTarget: {
2815 if (!result_sp->IsDynamic()) {
2816 if (result_sp->GetDynamicValue(dynValue))
2817 result_sp = result_sp->GetDynamicValue(dynValue);
2818 }
2819 } break;
2820 case lldb::eNoDynamicValues: {
2821 if (result_sp->IsDynamic()) {
2822 if (result_sp->GetStaticValue())
2823 result_sp = result_sp->GetStaticValue();
2824 }
2825 } break;
2826 }
2827
2828 if (synthValue) {
2829 if (!result_sp->IsSynthetic()) {
2830 if (result_sp->GetSyntheticValue())
2831 result_sp = result_sp->GetSyntheticValue();
2832 }
2833 } else {
2834 if (result_sp->IsSynthetic()) {
2835 if (result_sp->GetNonSyntheticValue())
2836 result_sp = result_sp->GetNonSyntheticValue();
2837 }
2838 }
2839
2840 return result_sp;
2841}
2842
2843lldb::addr_t ValueObject::GetCPPVTableAddress(AddressType &address_type) {
2844 CompilerType pointee_type;
2845 CompilerType this_type(GetCompilerType());
2846 uint32_t type_info = this_type.GetTypeInfo(&pointee_type);
2847 if (type_info) {
2848 bool ptr_or_ref = false;
2849 if (type_info & (eTypeIsPointer | eTypeIsReference)) {
2850 ptr_or_ref = true;
2851 type_info = pointee_type.GetTypeInfo();
2852 }
2853
2854 const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus;
2855 if ((type_info & cpp_class) == cpp_class) {
2856 if (ptr_or_ref) {
2857 address_type = GetAddressTypeOfChildren();
2858 return GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
2859 } else
2860 return GetAddressOf(false, &address_type);
2861 }
2862 }
2863
2864 address_type = eAddressTypeInvalid;
2865 return LLDB_INVALID_ADDRESS;
2866}
2867
2868ValueObjectSP ValueObject::Dereference(Error &error) {
2869 if (m_deref_valobj)
2870 return m_deref_valobj->GetSP();
2871
2872 const bool is_pointer_or_reference_type = IsPointerOrReferenceType();
2873 if (is_pointer_or_reference_type) {
2874 bool omit_empty_base_classes = true;
2875 bool ignore_array_bounds = false;
2876
2877 std::string child_name_str;
2878 uint32_t child_byte_size = 0;
2879 int32_t child_byte_offset = 0;
2880 uint32_t child_bitfield_bit_size = 0;
2881 uint32_t child_bitfield_bit_offset = 0;
2882 bool child_is_base_class = false;
2883 bool child_is_deref_of_parent = false;
2884 const bool transparent_pointers = false;
2885 CompilerType compiler_type = GetCompilerType();
2886 CompilerType child_compiler_type;
2887 uint64_t language_flags;
2888
2889 ExecutionContext exe_ctx(GetExecutionContextRef());
2890
2891 child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex(
2892 &exe_ctx, 0, transparent_pointers, omit_empty_base_classes,
2893 ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
2894 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
2895 child_is_deref_of_parent, this, language_flags);
2896 if (child_compiler_type && child_byte_size) {
2897 ConstString child_name;
2898 if (!child_name_str.empty())
2899 child_name.SetCString(child_name_str.c_str());
2900
2901 m_deref_valobj = new ValueObjectChild(
2902 *this, child_compiler_type, child_name, child_byte_size,
2903 child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
2904 child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
2905 language_flags);
2906 }
Tamas Berghammer4c08fe22017-03-31 20:23:22 +00002907 } else if (HasSyntheticValue()) {
2908 m_deref_valobj =
2909 GetSyntheticValue()
2910 ->GetChildMemberWithName(ConstString("$$dereference$$"), true)
2911 .get();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002912 }
2913
2914 if (m_deref_valobj) {
Greg Clayton54979cd2010-12-15 05:08:08 +00002915 error.Clear();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002916 return m_deref_valobj->GetSP();
2917 } else {
2918 StreamString strm;
2919 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002920
Kate Stoneb9c1b512016-09-06 20:57:50 +00002921 if (is_pointer_or_reference_type)
2922 error.SetErrorStringWithFormat("dereference failed: (%s) %s",
2923 GetTypeName().AsCString("<invalid type>"),
Zachary Turnerc1564272016-11-16 21:15:24 +00002924 strm.GetData());
Sean Callananed185ab2013-04-19 19:47:32 +00002925 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00002926 error.SetErrorStringWithFormat("not a pointer or reference type: (%s) %s",
2927 GetTypeName().AsCString("<invalid type>"),
Zachary Turnerc1564272016-11-16 21:15:24 +00002928 strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002929 return ValueObjectSP();
2930 }
2931}
2932
2933ValueObjectSP ValueObject::AddressOf(Error &error) {
2934 if (m_addr_of_valobj_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +00002935 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002936
Kate Stoneb9c1b512016-09-06 20:57:50 +00002937 AddressType address_type = eAddressTypeInvalid;
2938 const bool scalar_is_load_address = false;
2939 addr_t addr = GetAddressOf(scalar_is_load_address, &address_type);
2940 error.Clear();
2941 if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {
2942 switch (address_type) {
2943 case eAddressTypeInvalid: {
2944 StreamString expr_path_strm;
2945 GetExpressionPath(expr_path_strm, true);
2946 error.SetErrorStringWithFormat("'%s' is not in memory",
Zachary Turnerc1564272016-11-16 21:15:24 +00002947 expr_path_strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002948 } break;
Greg Claytonb2dcc362011-05-05 23:32:56 +00002949
Kate Stoneb9c1b512016-09-06 20:57:50 +00002950 case eAddressTypeFile:
2951 case eAddressTypeLoad: {
2952 CompilerType compiler_type = GetCompilerType();
2953 if (compiler_type) {
2954 std::string name(1, '&');
2955 name.append(m_name.AsCString(""));
2956 ExecutionContext exe_ctx(GetExecutionContextRef());
2957 m_addr_of_valobj_sp = ValueObjectConstResult::Create(
2958 exe_ctx.GetBestExecutionContextScope(),
2959 compiler_type.GetPointerType(), ConstString(name.c_str()), addr,
2960 eAddressTypeInvalid, m_data.GetAddressByteSize());
2961 }
2962 } break;
2963 default:
2964 break;
Greg Claytonb2dcc362011-05-05 23:32:56 +00002965 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002966 } else {
2967 StreamString expr_path_strm;
2968 GetExpressionPath(expr_path_strm, true);
2969 error.SetErrorStringWithFormat("'%s' doesn't have a valid address",
Zachary Turnerc1564272016-11-16 21:15:24 +00002970 expr_path_strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002971 }
2972
2973 return m_addr_of_valobj_sp;
Greg Claytonb2dcc362011-05-05 23:32:56 +00002974}
2975
Kate Stoneb9c1b512016-09-06 20:57:50 +00002976ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {
2977 return ValueObjectCast::Create(*this, GetName(), compiler_type);
Greg Claytonb2dcc362011-05-05 23:32:56 +00002978}
2979
Tamas Berghammer4fbb55b2017-03-31 20:48:00 +00002980lldb::ValueObjectSP ValueObject::Clone(const ConstString &new_name) {
2981 return ValueObjectCast::Create(*this, new_name, GetCompilerType());
2982}
2983
Kate Stoneb9c1b512016-09-06 20:57:50 +00002984ValueObjectSP ValueObject::CastPointerType(const char *name,
2985 CompilerType &compiler_type) {
2986 ValueObjectSP valobj_sp;
2987 AddressType address_type;
2988 addr_t ptr_value = GetPointerValue(&address_type);
2989
2990 if (ptr_value != LLDB_INVALID_ADDRESS) {
2991 Address ptr_addr(ptr_value);
2992 ExecutionContext exe_ctx(GetExecutionContextRef());
2993 valobj_sp = ValueObjectMemory::Create(
2994 exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, compiler_type);
2995 }
2996 return valobj_sp;
Jim Ingham6035b672011-03-31 00:19:25 +00002997}
2998
Kate Stoneb9c1b512016-09-06 20:57:50 +00002999ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {
3000 ValueObjectSP valobj_sp;
3001 AddressType address_type;
3002 addr_t ptr_value = GetPointerValue(&address_type);
3003
3004 if (ptr_value != LLDB_INVALID_ADDRESS) {
3005 Address ptr_addr(ptr_value);
3006 ExecutionContext exe_ctx(GetExecutionContextRef());
3007 valobj_sp = ValueObjectMemory::Create(
3008 exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, type_sp);
3009 }
3010 return valobj_sp;
3011}
3012
3013ValueObject::EvaluationPoint::EvaluationPoint()
3014 : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {}
3015
3016ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope,
3017 bool use_selected)
3018 : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {
3019 ExecutionContext exe_ctx(exe_scope);
3020 TargetSP target_sp(exe_ctx.GetTargetSP());
3021 if (target_sp) {
3022 m_exe_ctx_ref.SetTargetSP(target_sp);
3023 ProcessSP process_sp(exe_ctx.GetProcessSP());
3024 if (!process_sp)
3025 process_sp = target_sp->GetProcessSP();
3026
3027 if (process_sp) {
3028 m_mod_id = process_sp->GetModID();
3029 m_exe_ctx_ref.SetProcessSP(process_sp);
3030
3031 ThreadSP thread_sp(exe_ctx.GetThreadSP());
3032
3033 if (!thread_sp) {
3034 if (use_selected)
3035 thread_sp = process_sp->GetThreadList().GetSelectedThread();
3036 }
3037
3038 if (thread_sp) {
3039 m_exe_ctx_ref.SetThreadSP(thread_sp);
3040
3041 StackFrameSP frame_sp(exe_ctx.GetFrameSP());
3042 if (!frame_sp) {
3043 if (use_selected)
3044 frame_sp = thread_sp->GetSelectedFrame();
Jim Ingham6035b672011-03-31 00:19:25 +00003045 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003046 if (frame_sp)
3047 m_exe_ctx_ref.SetFrameSP(frame_sp);
3048 }
Jim Ingham6035b672011-03-31 00:19:25 +00003049 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003050 }
Jim Ingham6035b672011-03-31 00:19:25 +00003051}
3052
Kate Stoneb9c1b512016-09-06 20:57:50 +00003053ValueObject::EvaluationPoint::EvaluationPoint(
3054 const ValueObject::EvaluationPoint &rhs)
3055 : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref), m_needs_update(true) {}
Jim Ingham6035b672011-03-31 00:19:25 +00003056
Kate Stoneb9c1b512016-09-06 20:57:50 +00003057ValueObject::EvaluationPoint::~EvaluationPoint() {}
Jim Ingham6035b672011-03-31 00:19:25 +00003058
Kate Stoneb9c1b512016-09-06 20:57:50 +00003059// This function checks the EvaluationPoint against the current process state.
3060// If the current
3061// state matches the evaluation point, or the evaluation point is already
3062// invalid, then we return
3063// false, meaning "no change". If the current state is different, we update our
3064// state, and return
3065// true meaning "yes, change". If we did see a change, we also set
3066// m_needs_update to true, so
Jim Ingham6035b672011-03-31 00:19:25 +00003067// future calls to NeedsUpdate will return true.
Jim Ingham9ee01152011-12-10 01:49:43 +00003068// exe_scope will be set to the current execution context scope.
Jim Ingham6035b672011-03-31 00:19:25 +00003069
Kate Stoneb9c1b512016-09-06 20:57:50 +00003070bool ValueObject::EvaluationPoint::SyncWithProcessState(
3071 bool accept_invalid_exe_ctx) {
3072 // Start with the target, if it is NULL, then we're obviously not going to get
3073 // any further:
3074 const bool thread_and_frame_only_if_stopped = true;
3075 ExecutionContext exe_ctx(
3076 m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
3077
3078 if (exe_ctx.GetTargetPtr() == NULL)
3079 return false;
3080
3081 // If we don't have a process nothing can change.
3082 Process *process = exe_ctx.GetProcessPtr();
3083 if (process == NULL)
3084 return false;
3085
3086 // If our stop id is the current stop ID, nothing has changed:
3087 ProcessModID current_mod_id = process->GetModID();
3088
3089 // If the current stop id is 0, either we haven't run yet, or the process
3090 // state has been cleared.
3091 // In either case, we aren't going to be able to sync with the process state.
3092 if (current_mod_id.GetStopID() == 0)
3093 return false;
3094
3095 bool changed = false;
3096 const bool was_valid = m_mod_id.IsValid();
3097 if (was_valid) {
3098 if (m_mod_id == current_mod_id) {
3099 // Everything is already up to date in this object, no need to
3100 // update the execution context scope.
3101 changed = false;
3102 } else {
3103 m_mod_id = current_mod_id;
3104 m_needs_update = true;
3105 changed = true;
3106 }
3107 }
3108
3109 // Now re-look up the thread and frame in case the underlying objects have
3110 // gone away & been recreated.
3111 // That way we'll be sure to return a valid exe_scope.
3112 // If we used to have a thread or a frame but can't find it anymore, then mark
3113 // ourselves as invalid.
3114
3115 if (!accept_invalid_exe_ctx) {
3116 if (m_exe_ctx_ref.HasThreadRef()) {
3117 ThreadSP thread_sp(m_exe_ctx_ref.GetThreadSP());
3118 if (thread_sp) {
3119 if (m_exe_ctx_ref.HasFrameRef()) {
3120 StackFrameSP frame_sp(m_exe_ctx_ref.GetFrameSP());
3121 if (!frame_sp) {
3122 // We used to have a frame, but now it is gone
3123 SetInvalid();
3124 changed = was_valid;
3125 }
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003126 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003127 } else {
3128 // We used to have a thread, but now it is gone
3129 SetInvalid();
3130 changed = was_valid;
3131 }
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003132 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003133 }
Enrico Granatabb642e52015-05-16 01:27:00 +00003134
Kate Stoneb9c1b512016-09-06 20:57:50 +00003135 return changed;
Jim Ingham6035b672011-03-31 00:19:25 +00003136}
3137
Kate Stoneb9c1b512016-09-06 20:57:50 +00003138void ValueObject::EvaluationPoint::SetUpdated() {
3139 ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
3140 if (process_sp)
3141 m_mod_id = process_sp->GetModID();
3142 m_needs_update = false;
Johnny Chen44805302011-07-19 19:48:13 +00003143}
Enrico Granata9128ee22011-09-06 19:20:51 +00003144
Kate Stoneb9c1b512016-09-06 20:57:50 +00003145void ValueObject::ClearUserVisibleData(uint32_t clear_mask) {
3146 if ((clear_mask & eClearUserVisibleDataItemsValue) ==
3147 eClearUserVisibleDataItemsValue)
3148 m_value_str.clear();
3149
3150 if ((clear_mask & eClearUserVisibleDataItemsLocation) ==
3151 eClearUserVisibleDataItemsLocation)
3152 m_location_str.clear();
3153
3154 if ((clear_mask & eClearUserVisibleDataItemsSummary) ==
3155 eClearUserVisibleDataItemsSummary)
3156 m_summary_str.clear();
3157
3158 if ((clear_mask & eClearUserVisibleDataItemsDescription) ==
3159 eClearUserVisibleDataItemsDescription)
3160 m_object_desc_str.clear();
3161
3162 if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) ==
3163 eClearUserVisibleDataItemsSyntheticChildren) {
3164 if (m_synthetic_value)
3165 m_synthetic_value = NULL;
3166 }
3167
3168 if ((clear_mask & eClearUserVisibleDataItemsValidator) ==
3169 eClearUserVisibleDataItemsValidator)
3170 m_validation_result.reset();
Enrico Granata9128ee22011-09-06 19:20:51 +00003171}
Enrico Granatab2698cd2012-09-13 18:27:09 +00003172
Kate Stoneb9c1b512016-09-06 20:57:50 +00003173SymbolContextScope *ValueObject::GetSymbolContextScope() {
3174 if (m_parent) {
3175 if (!m_parent->IsPointerOrReferenceType())
3176 return m_parent->GetSymbolContextScope();
3177 }
3178 return NULL;
Enrico Granata972be532014-12-17 21:18:43 +00003179}
3180
Zachary Turneraa5611f2016-11-13 03:29:46 +00003181lldb::ValueObjectSP
3182ValueObject::CreateValueObjectFromExpression(llvm::StringRef name,
3183 llvm::StringRef expression,
3184 const ExecutionContext &exe_ctx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003185 return CreateValueObjectFromExpression(name, expression, exe_ctx,
3186 EvaluateExpressionOptions());
3187}
Enrico Granata972be532014-12-17 21:18:43 +00003188
Kate Stoneb9c1b512016-09-06 20:57:50 +00003189lldb::ValueObjectSP ValueObject::CreateValueObjectFromExpression(
Zachary Turneraa5611f2016-11-13 03:29:46 +00003190 llvm::StringRef name, llvm::StringRef expression,
3191 const ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003192 lldb::ValueObjectSP retval_sp;
3193 lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
3194 if (!target_sp)
Enrico Granatab2698cd2012-09-13 18:27:09 +00003195 return retval_sp;
Zachary Turneraa5611f2016-11-13 03:29:46 +00003196 if (expression.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003197 return retval_sp;
3198 target_sp->EvaluateExpression(expression, exe_ctx.GetFrameSP().get(),
3199 retval_sp, options);
Zachary Turneraa5611f2016-11-13 03:29:46 +00003200 if (retval_sp && !name.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003201 retval_sp->SetName(ConstString(name));
3202 return retval_sp;
Enrico Granatab2698cd2012-09-13 18:27:09 +00003203}
3204
Zachary Turneraa5611f2016-11-13 03:29:46 +00003205lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress(
3206 llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
3207 CompilerType type) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003208 if (type) {
3209 CompilerType pointer_type(type.GetPointerType());
3210 if (pointer_type) {
3211 lldb::DataBufferSP buffer(
3212 new lldb_private::DataBufferHeap(&address, sizeof(lldb::addr_t)));
3213 lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(
3214 exe_ctx.GetBestExecutionContextScope(), pointer_type,
3215 ConstString(name), buffer, exe_ctx.GetByteOrder(),
3216 exe_ctx.GetAddressByteSize()));
3217 if (ptr_result_valobj_sp) {
3218 ptr_result_valobj_sp->GetValue().SetValueType(
3219 Value::eValueTypeLoadAddress);
3220 Error err;
3221 ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
Zachary Turneraa5611f2016-11-13 03:29:46 +00003222 if (ptr_result_valobj_sp && !name.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003223 ptr_result_valobj_sp->SetName(ConstString(name));
3224 }
3225 return ptr_result_valobj_sp;
Enrico Granatab2698cd2012-09-13 18:27:09 +00003226 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003227 }
3228 return lldb::ValueObjectSP();
Enrico Granatab2698cd2012-09-13 18:27:09 +00003229}
3230
Kate Stoneb9c1b512016-09-06 20:57:50 +00003231lldb::ValueObjectSP ValueObject::CreateValueObjectFromData(
Zachary Turneraa5611f2016-11-13 03:29:46 +00003232 llvm::StringRef name, const DataExtractor &data,
Kate Stoneb9c1b512016-09-06 20:57:50 +00003233 const ExecutionContext &exe_ctx, CompilerType type) {
3234 lldb::ValueObjectSP new_value_sp;
3235 new_value_sp = ValueObjectConstResult::Create(
3236 exe_ctx.GetBestExecutionContextScope(), type, ConstString(name), data,
3237 LLDB_INVALID_ADDRESS);
3238 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
Zachary Turneraa5611f2016-11-13 03:29:46 +00003239 if (new_value_sp && !name.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003240 new_value_sp->SetName(ConstString(name));
3241 return new_value_sp;
Enrico Granatab2698cd2012-09-13 18:27:09 +00003242}
Enrico Granata4873e522013-04-11 22:48:58 +00003243
Kate Stoneb9c1b512016-09-06 20:57:50 +00003244ModuleSP ValueObject::GetModule() {
3245 ValueObject *root(GetRoot());
3246 if (root != this)
3247 return root->GetModule();
3248 return lldb::ModuleSP();
3249}
3250
3251ValueObject *ValueObject::GetRoot() {
3252 if (m_root)
3253 return m_root;
3254 return (m_root = FollowParentChain([](ValueObject *vo) -> bool {
3255 return (vo->m_parent != nullptr);
3256 }));
3257}
3258
3259ValueObject *
3260ValueObject::FollowParentChain(std::function<bool(ValueObject *)> f) {
3261 ValueObject *vo = this;
3262 while (vo) {
3263 if (f(vo) == false)
3264 break;
3265 vo = vo->m_parent;
3266 }
3267 return vo;
3268}
3269
3270AddressType ValueObject::GetAddressTypeOfChildren() {
3271 if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) {
3272 ValueObject *root(GetRoot());
Enrico Granata4873e522013-04-11 22:48:58 +00003273 if (root != this)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003274 return root->GetAddressTypeOfChildren();
3275 }
3276 return m_address_type_of_ptr_or_ref_children;
Enrico Granata4873e522013-04-11 22:48:58 +00003277}
3278
Kate Stoneb9c1b512016-09-06 20:57:50 +00003279lldb::DynamicValueType ValueObject::GetDynamicValueType() {
3280 ValueObject *with_dv_info = this;
3281 while (with_dv_info) {
3282 if (with_dv_info->HasDynamicValueTypeInfo())
3283 return with_dv_info->GetDynamicValueTypeImpl();
3284 with_dv_info = with_dv_info->m_parent;
3285 }
3286 return lldb::eNoDynamicValues;
Enrico Granatade61eba2015-01-22 03:07:34 +00003287}
3288
Kate Stoneb9c1b512016-09-06 20:57:50 +00003289lldb::Format ValueObject::GetFormat() const {
3290 const ValueObject *with_fmt_info = this;
3291 while (with_fmt_info) {
3292 if (with_fmt_info->m_format != lldb::eFormatDefault)
3293 return with_fmt_info->m_format;
3294 with_fmt_info = with_fmt_info->m_parent;
3295 }
3296 return m_format;
Enrico Granata4873e522013-04-11 22:48:58 +00003297}
3298
Kate Stoneb9c1b512016-09-06 20:57:50 +00003299lldb::LanguageType ValueObject::GetPreferredDisplayLanguage() {
3300 lldb::LanguageType type = m_preferred_display_language;
3301 if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
3302 if (GetRoot()) {
3303 if (GetRoot() == this) {
3304 if (StackFrameSP frame_sp = GetFrameSP()) {
3305 const SymbolContext &sc(
3306 frame_sp->GetSymbolContext(eSymbolContextCompUnit));
3307 if (CompileUnit *cu = sc.comp_unit)
3308 type = cu->GetLanguage();
Enrico Granatac1247f52014-11-06 21:23:20 +00003309 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003310 } else {
3311 type = GetRoot()->GetPreferredDisplayLanguage();
3312 }
Enrico Granatac1247f52014-11-06 21:23:20 +00003313 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003314 }
3315 return (m_preferred_display_language = type); // only compute it once
Enrico Granataed3228a2015-01-21 01:47:13 +00003316}
3317
Kate Stoneb9c1b512016-09-06 20:57:50 +00003318void ValueObject::SetPreferredDisplayLanguage(lldb::LanguageType lt) {
3319 m_preferred_display_language = lt;
Enrico Granatac1247f52014-11-06 21:23:20 +00003320}
3321
Kate Stoneb9c1b512016-09-06 20:57:50 +00003322void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {
3323 if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
3324 SetPreferredDisplayLanguage(lt);
Enrico Granata73e8c4d2015-10-07 02:36:35 +00003325}
3326
Kate Stoneb9c1b512016-09-06 20:57:50 +00003327bool ValueObject::CanProvideValue() {
3328 // we need to support invalid types as providers of values because some
3329 // bare-board
3330 // debugging scenarios have no notion of types, but still manage to have raw
3331 // numeric
3332 // values for things like registers. sigh.
3333 const CompilerType &type(GetCompilerType());
3334 return (false == type.IsValid()) ||
3335 (0 != (type.GetTypeInfo() & eTypeHasValue));
Sean Callanan7375f3e2014-12-09 21:18:59 +00003336}
3337
Kate Stoneb9c1b512016-09-06 20:57:50 +00003338bool ValueObject::IsChecksumEmpty() { return m_value_checksum.empty(); }
3339
3340ValueObjectSP ValueObject::Persist() {
3341 if (!UpdateValueIfNeeded())
3342 return nullptr;
3343
3344 TargetSP target_sp(GetTargetSP());
3345 if (!target_sp)
3346 return nullptr;
3347
3348 PersistentExpressionState *persistent_state =
3349 target_sp->GetPersistentExpressionStateForLanguage(
3350 GetPreferredDisplayLanguage());
3351
3352 if (!persistent_state)
3353 return nullptr;
3354
3355 ConstString name(persistent_state->GetNextPersistentVariableName());
3356
3357 ValueObjectSP const_result_sp =
3358 ValueObjectConstResult::Create(target_sp.get(), GetValue(), name);
3359
3360 ExpressionVariableSP clang_var_sp =
3361 persistent_state->CreatePersistentVariable(const_result_sp);
3362 clang_var_sp->m_live_sp = clang_var_sp->m_frozen_sp;
3363 clang_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference;
3364
3365 return clang_var_sp->GetValueObject();
Enrico Granatad07cfd32014-10-08 18:27:36 +00003366}
Enrico Granata0c10a852014-12-08 23:13:56 +00003367
Kate Stoneb9c1b512016-09-06 20:57:50 +00003368bool ValueObject::IsSyntheticChildrenGenerated() {
3369 return m_is_synthetic_children_generated;
Enrico Granata0c10a852014-12-08 23:13:56 +00003370}
Enrico Granatae29df232014-12-09 19:51:20 +00003371
Kate Stoneb9c1b512016-09-06 20:57:50 +00003372void ValueObject::SetSyntheticChildrenGenerated(bool b) {
3373 m_is_synthetic_children_generated = b;
Enrico Granatae29df232014-12-09 19:51:20 +00003374}
3375
Kate Stoneb9c1b512016-09-06 20:57:50 +00003376uint64_t ValueObject::GetLanguageFlags() { return m_language_flags; }
Enrico Granatadc62ffd2015-11-09 19:27:34 +00003377
Kate Stoneb9c1b512016-09-06 20:57:50 +00003378void ValueObject::SetLanguageFlags(uint64_t flags) { m_language_flags = flags; }
Greg Clayton8369b282016-12-28 21:22:37 +00003379
3380ValueObjectManager::ValueObjectManager(lldb::ValueObjectSP in_valobj_sp,
3381 lldb::DynamicValueType use_dynamic,
3382 bool use_synthetic) : m_root_valobj_sp(),
3383 m_user_valobj_sp(), m_use_dynamic(use_dynamic), m_stop_id(UINT32_MAX),
3384 m_use_synthetic(use_synthetic) {
3385 if (!in_valobj_sp)
3386 return;
3387 // If the user passes in a value object that is dynamic or synthetic, then
3388 // water it down to the static type.
3389 m_root_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(lldb::eNoDynamicValues, false);
3390}
3391
3392bool ValueObjectManager::IsValid() const {
3393 if (!m_root_valobj_sp)
3394 return false;
3395 lldb::TargetSP target_sp = GetTargetSP();
3396 if (target_sp)
3397 return target_sp->IsValid();
3398 return false;
3399}
3400
3401lldb::ValueObjectSP ValueObjectManager::GetSP() {
3402 lldb::ProcessSP process_sp = GetProcessSP();
3403 if (!process_sp)
3404 return lldb::ValueObjectSP();
3405
3406 const uint32_t current_stop_id = process_sp->GetLastNaturalStopID();
3407 if (current_stop_id == m_stop_id)
3408 return m_user_valobj_sp;
3409
3410 m_stop_id = current_stop_id;
3411
3412 if (!m_root_valobj_sp) {
3413 m_user_valobj_sp.reset();
3414 return m_root_valobj_sp;
3415 }
3416
3417 m_user_valobj_sp = m_root_valobj_sp;
3418
3419 if (m_use_dynamic != lldb::eNoDynamicValues) {
3420 lldb::ValueObjectSP dynamic_sp = m_user_valobj_sp->GetDynamicValue(m_use_dynamic);
3421 if (dynamic_sp)
3422 m_user_valobj_sp = dynamic_sp;
3423 }
3424
3425 if (m_use_synthetic) {
3426 lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(m_use_synthetic);
3427 if (synthetic_sp)
3428 m_user_valobj_sp = synthetic_sp;
3429 }
3430
3431 return m_user_valobj_sp;
3432}
3433
3434void ValueObjectManager::SetUseDynamic(lldb::DynamicValueType use_dynamic) {
3435 if (use_dynamic != m_use_dynamic) {
3436 m_use_dynamic = use_dynamic;
3437 m_user_valobj_sp.reset();
3438 m_stop_id = UINT32_MAX;
3439 }
3440}
3441
3442void ValueObjectManager::SetUseSynthetic(bool use_synthetic) {
3443 if (m_use_synthetic != use_synthetic) {
3444 m_use_synthetic = use_synthetic;
3445 m_user_valobj_sp.reset();
3446 m_stop_id = UINT32_MAX;
3447 }
3448}
3449
3450lldb::TargetSP ValueObjectManager::GetTargetSP() const {
3451 if (!m_root_valobj_sp)
3452 return m_root_valobj_sp->GetTargetSP();
3453 return lldb::TargetSP();
3454}
3455
3456lldb::ProcessSP ValueObjectManager::GetProcessSP() const {
3457 if (m_root_valobj_sp)
3458 return m_root_valobj_sp->GetProcessSP();
3459 return lldb::ProcessSP();
3460}
3461
3462lldb::ThreadSP ValueObjectManager::GetThreadSP() const {
3463 if (m_root_valobj_sp)
3464 return m_root_valobj_sp->GetThreadSP();
3465 return lldb::ThreadSP();
3466}
3467
3468lldb::StackFrameSP ValueObjectManager::GetFrameSP() const {
3469 if (m_root_valobj_sp)
3470 return m_root_valobj_sp->GetFrameSP();
3471 return lldb::StackFrameSP();
3472}
3473