blob: 275be93e18e0f582073206c306259c84cba97874 [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
Adrian Prantl05097242018-04-30 16:49:04 +0000149 // If this is a constant value, then our success is predicated on whether we
150 // have an error or not
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 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
Adrian Prantl05097242018-04-30 16:49:04 +0000154 // cared to freeze-dry yourself) in this case, your value has not changed,
155 // but "computed" entries might have, so you might now have a different
156 // summary, or a different object description. clear these so we will
157 // recompute them
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158 if (update_format && !did_change_formats)
159 ClearUserVisibleData(eClearUserVisibleDataItemsSummary |
160 eClearUserVisibleDataItemsDescription);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161 return m_error.Success();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162 }
163
164 bool first_update = IsChecksumEmpty();
165
166 if (NeedsUpdating()) {
167 m_update_point.SetUpdated();
168
Adrian Prantl05097242018-04-30 16:49:04 +0000169 // Save the old value using swap to avoid a string copy which also will
170 // clear our m_value_str
Kate Stoneb9c1b512016-09-06 20:57:50 +0000171 if (m_value_str.empty()) {
172 m_old_value_valid = false;
173 } else {
174 m_old_value_valid = true;
175 m_old_value_str.swap(m_value_str);
176 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
177 }
178
179 ClearUserVisibleData();
180
181 if (IsInScope()) {
182 const bool value_was_valid = GetValueIsValid();
183 SetValueDidChange(false);
184
185 m_error.Clear();
186
187 // Call the pure virtual function to update the value
188
189 bool need_compare_checksums = false;
190 llvm::SmallVector<uint8_t, 16> old_checksum;
191
192 if (!first_update && CanProvideValue()) {
193 need_compare_checksums = true;
194 old_checksum.resize(m_value_checksum.size());
195 std::copy(m_value_checksum.begin(), m_value_checksum.end(),
196 old_checksum.begin());
197 }
198
199 bool success = UpdateValue();
200
201 SetValueIsValid(success);
202
203 if (success) {
204 const uint64_t max_checksum_size = 128;
205 m_data.Checksum(m_value_checksum, max_checksum_size);
206 } else {
207 need_compare_checksums = false;
208 m_value_checksum.clear();
209 }
210
211 assert(!need_compare_checksums ||
212 (!old_checksum.empty() && !m_value_checksum.empty()));
213
214 if (first_update)
215 SetValueDidChange(false);
216 else if (!m_value_did_change && success == false) {
Adrian Prantl05097242018-04-30 16:49:04 +0000217 // The value wasn't gotten successfully, so we mark this as changed if
218 // the value used to be valid and now isn't
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219 SetValueDidChange(value_was_valid);
220 } else if (need_compare_checksums) {
221 SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0],
222 m_value_checksum.size()));
223 }
224
225 } else {
226 m_error.SetErrorString("out of scope");
227 }
228 }
229 return m_error.Success();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000230}
231
Kate Stoneb9c1b512016-09-06 20:57:50 +0000232bool ValueObject::UpdateFormatsIfNeeded() {
233 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
234 if (log)
235 log->Printf("[%s %p] checking for FormatManager revisions. ValueObject "
236 "rev: %d - Global rev: %d",
237 GetName().GetCString(), static_cast<void *>(this),
238 m_last_format_mgr_revision,
239 DataVisualization::GetCurrentRevision());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000240
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241 bool any_change = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000242
Kate Stoneb9c1b512016-09-06 20:57:50 +0000243 if ((m_last_format_mgr_revision != DataVisualization::GetCurrentRevision())) {
244 m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
245 any_change = true;
246
247 SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues));
248 SetSummaryFormat(
249 DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000250#ifndef LLDB_DISABLE_PYTHON
Kate Stoneb9c1b512016-09-06 20:57:50 +0000251 SetSyntheticChildren(
252 DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000253#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 SetValidator(DataVisualization::GetValidator(*this, GetDynamicValueType()));
255 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000256
Kate Stoneb9c1b512016-09-06 20:57:50 +0000257 return any_change;
Enrico Granata4becb372011-06-29 22:27:15 +0000258}
259
Kate Stoneb9c1b512016-09-06 20:57:50 +0000260void ValueObject::SetNeedsUpdate() {
261 m_update_point.SetNeedsUpdate();
262 // We have to clear the value string here so ConstResult children will notice
Adrian Prantl05097242018-04-30 16:49:04 +0000263 // if their values are changed by hand (i.e. with SetValueAsCString).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
Jim Ingham16e0c682011-08-12 23:34:31 +0000265}
266
Kate Stoneb9c1b512016-09-06 20:57:50 +0000267void ValueObject::ClearDynamicTypeInformation() {
268 m_children_count_valid = false;
269 m_did_calculate_complete_objc_class_type = false;
270 m_last_format_mgr_revision = 0;
271 m_override_type = CompilerType();
272 SetValueFormat(lldb::TypeFormatImplSP());
273 SetSummaryFormat(lldb::TypeSummaryImplSP());
274 SetSyntheticChildren(lldb::SyntheticChildrenSP());
Enrico Granata13ac0e22012-10-17 19:03:34 +0000275}
276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277CompilerType ValueObject::MaybeCalculateCompleteType() {
278 CompilerType compiler_type(GetCompilerTypeImpl());
279
280 if (m_did_calculate_complete_objc_class_type) {
281 if (m_override_type.IsValid())
282 return m_override_type;
Sean Callanan72772842012-02-22 23:57:45 +0000283 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284 return compiler_type;
285 }
286
287 CompilerType class_type;
288 bool is_pointer_type = false;
289
290 if (ClangASTContext::IsObjCObjectPointerType(compiler_type, &class_type)) {
291 is_pointer_type = true;
292 } else if (ClangASTContext::IsObjCObjectOrInterfaceType(compiler_type)) {
293 class_type = compiler_type;
294 } else {
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000295 return compiler_type;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000296 }
297
298 m_did_calculate_complete_objc_class_type = true;
299
300 if (class_type) {
301 ConstString class_name(class_type.GetConstTypeName());
302
303 if (class_name) {
304 ProcessSP process_sp(
305 GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
306
307 if (process_sp) {
308 ObjCLanguageRuntime *objc_language_runtime(
309 process_sp->GetObjCLanguageRuntime());
310
311 if (objc_language_runtime) {
312 TypeSP complete_objc_class_type_sp =
313 objc_language_runtime->LookupInCompleteClassCache(class_name);
314
315 if (complete_objc_class_type_sp) {
316 CompilerType complete_class(
317 complete_objc_class_type_sp->GetFullCompilerType());
318
319 if (complete_class.GetCompleteType()) {
320 if (is_pointer_type) {
321 m_override_type = complete_class.GetPointerType();
322 } else {
323 m_override_type = complete_class;
324 }
325
326 if (m_override_type.IsValid())
327 return m_override_type;
328 }
329 }
330 }
331 }
332 }
333 }
334 return compiler_type;
Sean Callanan72772842012-02-22 23:57:45 +0000335}
336
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337CompilerType ValueObject::GetCompilerType() {
338 return MaybeCalculateCompleteType();
Sean Callanan72772842012-02-22 23:57:45 +0000339}
340
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341TypeImpl ValueObject::GetTypeImpl() { return TypeImpl(GetCompilerType()); }
342
343DataExtractor &ValueObject::GetDataExtractor() {
344 UpdateValueIfNeeded(false);
345 return m_data;
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000346}
347
Zachary Turner97206d52017-05-12 04:51:55 +0000348const Status &ValueObject::GetError() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000349 UpdateValueIfNeeded(false);
350 return m_error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351}
352
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353const ConstString &ValueObject::GetName() const { return m_name; }
354
355const char *ValueObject::GetLocationAsCString() {
356 return GetLocationAsCStringImpl(m_value, m_data);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357}
358
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
360 const DataExtractor &data) {
361 if (UpdateValueIfNeeded(false)) {
362 if (m_location_str.empty()) {
363 StreamString sstr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364
Kate Stoneb9c1b512016-09-06 20:57:50 +0000365 Value::ValueType value_type = value.GetValueType();
Enrico Granata82fabf82013-04-30 20:45:04 +0000366
Kate Stoneb9c1b512016-09-06 20:57:50 +0000367 switch (value_type) {
368 case Value::eValueTypeScalar:
369 case Value::eValueTypeVector:
370 if (value.GetContextType() == Value::eContextTypeRegisterInfo) {
371 RegisterInfo *reg_info = value.GetRegisterInfo();
372 if (reg_info) {
373 if (reg_info->name)
374 m_location_str = reg_info->name;
375 else if (reg_info->alt_name)
376 m_location_str = reg_info->alt_name;
377 if (m_location_str.empty())
378 m_location_str = (reg_info->encoding == lldb::eEncodingVector)
379 ? "vector"
380 : "scalar";
381 }
382 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383 if (m_location_str.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000384 m_location_str =
385 (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
386 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387
Kate Stoneb9c1b512016-09-06 20:57:50 +0000388 case Value::eValueTypeLoadAddress:
389 case Value::eValueTypeFileAddress:
390 case Value::eValueTypeHostAddress: {
391 uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
392 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size,
393 value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
Zachary Turnerc1564272016-11-16 21:15:24 +0000394 m_location_str = sstr.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395 } break;
396 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000398 }
399 return m_location_str.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400}
401
Kate Stoneb9c1b512016-09-06 20:57:50 +0000402Value &ValueObject::GetValue() { return m_value; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403
Kate Stoneb9c1b512016-09-06 20:57:50 +0000404const Value &ValueObject::GetValue() const { return m_value; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405
Kate Stoneb9c1b512016-09-06 20:57:50 +0000406bool ValueObject::ResolveValue(Scalar &scalar) {
407 if (UpdateValueIfNeeded(
408 false)) // make sure that you are up to date before returning anything
409 {
410 ExecutionContext exe_ctx(GetExecutionContextRef());
411 Value tmp_value(m_value);
412 scalar = tmp_value.ResolveValue(&exe_ctx);
413 if (scalar.IsValid()) {
414 const uint32_t bitfield_bit_size = GetBitfieldBitSize();
415 if (bitfield_bit_size)
416 return scalar.ExtractBitfield(bitfield_bit_size,
417 GetBitfieldBitOffset());
418 return true;
Enrico Granata6fd87d52011-08-04 01:41:02 +0000419 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000420 }
421 return false;
422}
423
Zachary Turner97206d52017-05-12 04:51:55 +0000424bool ValueObject::IsLogicalTrue(Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000425 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
426 LazyBool is_logical_true = language->IsLogicalTrue(*this, error);
427 switch (is_logical_true) {
428 case eLazyBoolYes:
429 case eLazyBoolNo:
430 return (is_logical_true == true);
431 case eLazyBoolCalculate:
432 break;
433 }
434 }
435
436 Scalar scalar_value;
437
438 if (!ResolveValue(scalar_value)) {
439 error.SetErrorString("failed to get a scalar result");
Greg Claytondcad5022011-12-29 01:26:56 +0000440 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000441 }
442
443 bool ret;
444 if (scalar_value.ULongLong(1) == 0)
445 ret = false;
446 else
447 ret = true;
448 error.Clear();
449 return ret;
Greg Clayton8f343b02010-11-04 01:54:29 +0000450}
451
Kate Stoneb9c1b512016-09-06 20:57:50 +0000452bool ValueObject::GetValueIsValid() const { return m_value_is_valid; }
453
454void ValueObject::SetValueIsValid(bool b) { m_value_is_valid = b; }
455
456bool ValueObject::GetValueDidChange() { return m_value_did_change; }
457
458void ValueObject::SetValueDidChange(bool value_changed) {
459 m_value_did_change = value_changed;
460}
461
462ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) {
463 ValueObjectSP child_sp;
464 // We may need to update our value if we are dynamic
465 if (IsPossibleDynamicType())
466 UpdateValueIfNeeded(false);
467 if (idx < GetNumChildren()) {
468 // Check if we have already made the child value object?
469 if (can_create && !m_children.HasChildAtIndex(idx)) {
470 // No we haven't created the child at this index, so lets have our
471 // subclass do it and cache the result for quick future access.
472 m_children.SetChildAtIndex(idx, CreateChildAtIndex(idx, false, 0));
Enrico Granata407b5c62015-11-02 21:52:05 +0000473 }
Jim Ingham98e6daf2015-10-31 00:02:18 +0000474
Kate Stoneb9c1b512016-09-06 20:57:50 +0000475 ValueObject *child = m_children.GetChildAtIndex(idx);
476 if (child != NULL)
477 return child->GetSP();
478 }
479 return child_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480}
481
Enrico Granata3309d882013-01-12 01:00:22 +0000482lldb::ValueObjectSP
Lang Hames088d0012017-04-26 18:15:40 +0000483ValueObject::GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000484 size_t *index_of_error) {
485 if (idxs.size() == 0)
486 return GetSP();
487 ValueObjectSP root(GetSP());
488 for (size_t idx : idxs) {
489 root = root->GetChildAtIndex(idx, true);
490 if (!root) {
491 if (index_of_error)
492 *index_of_error = idx;
493 return root;
Enrico Granata3309d882013-01-12 01:00:22 +0000494 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000495 }
496 return root;
497}
498
499lldb::ValueObjectSP ValueObject::GetChildAtIndexPath(
Lang Hames088d0012017-04-26 18:15:40 +0000500 llvm::ArrayRef<std::pair<size_t, bool>> idxs, size_t *index_of_error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000501 if (idxs.size() == 0)
502 return GetSP();
503 ValueObjectSP root(GetSP());
504 for (std::pair<size_t, bool> idx : idxs) {
505 root = root->GetChildAtIndex(idx.first, idx.second);
506 if (!root) {
507 if (index_of_error)
508 *index_of_error = idx.first;
509 return root;
510 }
511 }
512 return root;
Enrico Granata3309d882013-01-12 01:00:22 +0000513}
514
515lldb::ValueObjectSP
Lang Hames088d0012017-04-26 18:15:40 +0000516ValueObject::GetChildAtNamePath(llvm::ArrayRef<ConstString> names,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000517 ConstString *name_of_error) {
518 if (names.size() == 0)
519 return GetSP();
520 ValueObjectSP root(GetSP());
521 for (ConstString name : names) {
522 root = root->GetChildMemberWithName(name, true);
523 if (!root) {
524 if (name_of_error)
525 *name_of_error = name;
526 return root;
527 }
528 }
529 return root;
Enrico Granataef8dde62015-12-21 23:10:17 +0000530}
531
Kate Stoneb9c1b512016-09-06 20:57:50 +0000532lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
Lang Hames088d0012017-04-26 18:15:40 +0000533 llvm::ArrayRef<std::pair<ConstString, bool>> names,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534 ConstString *name_of_error) {
535 if (names.size() == 0)
536 return GetSP();
537 ValueObjectSP root(GetSP());
538 for (std::pair<ConstString, bool> name : names) {
539 root = root->GetChildMemberWithName(name.first, name.second);
540 if (!root) {
541 if (name_of_error)
542 *name_of_error = name.first;
543 return root;
544 }
545 }
546 return root;
Enrico Granatae2e220a2013-09-12 00:48:47 +0000547}
548
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549size_t ValueObject::GetIndexOfChildWithName(const ConstString &name) {
550 bool omit_empty_base_classes = true;
551 return GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
552 omit_empty_base_classes);
Enrico Granatae2e220a2013-09-12 00:48:47 +0000553}
554
Kate Stoneb9c1b512016-09-06 20:57:50 +0000555ValueObjectSP ValueObject::GetChildMemberWithName(const ConstString &name,
556 bool can_create) {
Adrian Prantl05097242018-04-30 16:49:04 +0000557 // when getting a child by name, it could be buried inside some base classes
558 // (which really aren't part of the expression path), so we need a vector of
559 // indexes that can get us down to the correct child
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560 ValueObjectSP child_sp;
561
562 // We may need to update our value if we are dynamic
563 if (IsPossibleDynamicType())
564 UpdateValueIfNeeded(false);
565
566 std::vector<uint32_t> child_indexes;
567 bool omit_empty_base_classes = true;
568 const size_t num_child_indexes =
569 GetCompilerType().GetIndexOfChildMemberWithName(
570 name.GetCString(), omit_empty_base_classes, child_indexes);
571 if (num_child_indexes > 0) {
572 std::vector<uint32_t>::const_iterator pos = child_indexes.begin();
573 std::vector<uint32_t>::const_iterator end = child_indexes.end();
574
575 child_sp = GetChildAtIndex(*pos, can_create);
576 for (++pos; pos != end; ++pos) {
577 if (child_sp) {
578 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex(*pos, can_create));
579 child_sp = new_child_sp;
580 } else {
581 child_sp.reset();
582 }
Enrico Granatae2e220a2013-09-12 00:48:47 +0000583 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000584 }
585 return child_sp;
Enrico Granatae2e220a2013-09-12 00:48:47 +0000586}
587
Kate Stoneb9c1b512016-09-06 20:57:50 +0000588size_t ValueObject::GetNumChildren(uint32_t max) {
589 UpdateValueIfNeeded();
590
591 if (max < UINT32_MAX) {
592 if (m_children_count_valid) {
593 size_t children_count = m_children.GetChildrenCount();
594 return children_count <= max ? children_count : max;
595 } else
596 return CalculateNumChildren(max);
597 }
598
599 if (!m_children_count_valid) {
600 SetNumChildren(CalculateNumChildren());
601 }
602 return m_children.GetChildrenCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000603}
604
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605bool ValueObject::MightHaveChildren() {
606 bool has_children = false;
607 const uint32_t type_info = GetTypeInfo();
608 if (type_info) {
609 if (type_info & (eTypeHasChildren | eTypeIsPointer | eTypeIsReference))
610 has_children = true;
611 } else {
612 has_children = GetNumChildren() > 0;
613 }
614 return has_children;
Greg Clayton4a792072012-10-23 01:50:10 +0000615}
616
617// Should only be called by ValueObject::GetNumChildren()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000618void ValueObject::SetNumChildren(size_t num_children) {
619 m_children_count_valid = true;
620 m_children.SetChildrenCount(num_children);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000621}
622
Kate Stoneb9c1b512016-09-06 20:57:50 +0000623void ValueObject::SetName(const ConstString &name) { m_name = name; }
624
625ValueObject *ValueObject::CreateChildAtIndex(size_t idx,
626 bool synthetic_array_member,
627 int32_t synthetic_index) {
628 ValueObject *valobj = NULL;
629
630 bool omit_empty_base_classes = true;
631 bool ignore_array_bounds = synthetic_array_member;
632 std::string child_name_str;
633 uint32_t child_byte_size = 0;
634 int32_t child_byte_offset = 0;
635 uint32_t child_bitfield_bit_size = 0;
636 uint32_t child_bitfield_bit_offset = 0;
637 bool child_is_base_class = false;
638 bool child_is_deref_of_parent = false;
639 uint64_t language_flags = 0;
640
641 const bool transparent_pointers = synthetic_array_member == false;
642 CompilerType child_compiler_type;
643
644 ExecutionContext exe_ctx(GetExecutionContextRef());
645
646 child_compiler_type = GetCompilerType().GetChildCompilerTypeAtIndex(
647 &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
648 ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
649 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
650 child_is_deref_of_parent, this, language_flags);
651 if (child_compiler_type) {
652 if (synthetic_index)
653 child_byte_offset += child_byte_size * synthetic_index;
654
655 ConstString child_name;
656 if (!child_name_str.empty())
657 child_name.SetCString(child_name_str.c_str());
658
659 valobj = new ValueObjectChild(
660 *this, child_compiler_type, child_name, child_byte_size,
661 child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
662 child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
663 language_flags);
664 // if (valobj)
665 // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid);
666 }
667
668 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000669}
670
Kate Stoneb9c1b512016-09-06 20:57:50 +0000671bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
672 std::string &destination,
673 lldb::LanguageType lang) {
674 return GetSummaryAsCString(summary_ptr, destination,
675 TypeSummaryOptions().SetLanguage(lang));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000676}
677
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
679 std::string &destination,
680 const TypeSummaryOptions &options) {
681 destination.clear();
682
Adrian Prantl05097242018-04-30 16:49:04 +0000683 // ideally we would like to bail out if passing NULL, but if we do so we end
684 // up not providing the summary for function pointers anymore
Kate Stoneb9c1b512016-09-06 20:57:50 +0000685 if (/*summary_ptr == NULL ||*/ m_is_getting_summary)
686 return false;
687
688 m_is_getting_summary = true;
689
690 TypeSummaryOptions actual_options(options);
691
692 if (actual_options.GetLanguage() == lldb::eLanguageTypeUnknown)
693 actual_options.SetLanguage(GetPreferredDisplayLanguage());
694
695 // this is a hot path in code and we prefer to avoid setting this string all
Adrian Prantl05097242018-04-30 16:49:04 +0000696 // too often also clearing out other information that we might care to see in
697 // a crash log. might be useful in very specific situations though.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000698 /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s.
699 Summary provider's description is %s",
700 GetTypeName().GetCString(),
701 GetName().GetCString(),
702 summary_ptr->GetDescription().c_str());*/
703
704 if (UpdateValueIfNeeded(false) && summary_ptr) {
705 if (HasSyntheticValue())
706 m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on
707 // the synthetic children being
708 // up-to-date (e.g. ${svar%#})
709 summary_ptr->FormatObject(this, destination, actual_options);
710 }
711 m_is_getting_summary = false;
712 return !destination.empty();
Enrico Granatac1247f52014-11-06 21:23:20 +0000713}
714
Kate Stoneb9c1b512016-09-06 20:57:50 +0000715const char *ValueObject::GetSummaryAsCString(lldb::LanguageType lang) {
716 if (UpdateValueIfNeeded(true) && m_summary_str.empty()) {
717 TypeSummaryOptions summary_options;
718 summary_options.SetLanguage(lang);
719 GetSummaryAsCString(GetSummaryFormat().get(), m_summary_str,
720 summary_options);
721 }
722 if (m_summary_str.empty())
723 return NULL;
724 return m_summary_str.c_str();
725}
726
727bool ValueObject::GetSummaryAsCString(std::string &destination,
728 const TypeSummaryOptions &options) {
729 return GetSummaryAsCString(GetSummaryFormat().get(), destination, options);
730}
731
732bool ValueObject::IsCStringContainer(bool check_pointer) {
733 CompilerType pointee_or_element_compiler_type;
734 const Flags type_flags(GetTypeInfo(&pointee_or_element_compiler_type));
735 bool is_char_arr_ptr(type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
736 pointee_or_element_compiler_type.IsCharType());
737 if (!is_char_arr_ptr)
738 return false;
739 if (!check_pointer)
740 return true;
741 if (type_flags.Test(eTypeIsArray))
742 return true;
743 addr_t cstr_address = LLDB_INVALID_ADDRESS;
744 AddressType cstr_address_type = eAddressTypeInvalid;
745 cstr_address = GetAddressOf(true, &cstr_address_type);
746 return (cstr_address != LLDB_INVALID_ADDRESS);
747}
748
749size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
750 uint32_t item_count) {
751 CompilerType pointee_or_element_compiler_type;
752 const uint32_t type_info = GetTypeInfo(&pointee_or_element_compiler_type);
753 const bool is_pointer_type = type_info & eTypeIsPointer;
754 const bool is_array_type = type_info & eTypeIsArray;
755 if (!(is_pointer_type || is_array_type))
756 return 0;
757
758 if (item_count == 0)
759 return 0;
760
761 ExecutionContext exe_ctx(GetExecutionContextRef());
762
763 const uint64_t item_type_size = pointee_or_element_compiler_type.GetByteSize(
764 exe_ctx.GetBestExecutionContextScope());
765 const uint64_t bytes = item_count * item_type_size;
766 const uint64_t offset = item_idx * item_type_size;
767
768 if (item_idx == 0 && item_count == 1) // simply a deref
769 {
770 if (is_pointer_type) {
Zachary Turner97206d52017-05-12 04:51:55 +0000771 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000772 ValueObjectSP pointee_sp = Dereference(error);
773 if (error.Fail() || pointee_sp.get() == NULL)
774 return 0;
775 return pointee_sp->GetData(data, error);
776 } else {
777 ValueObjectSP child_sp = GetChildAtIndex(0, true);
778 if (child_sp.get() == NULL)
779 return 0;
Zachary Turner97206d52017-05-12 04:51:55 +0000780 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000781 return child_sp->GetData(data, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000783 return true;
784 } else /* (items > 1) */
785 {
Zachary Turner97206d52017-05-12 04:51:55 +0000786 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000787 lldb_private::DataBufferHeap *heap_buf_ptr = NULL;
788 lldb::DataBufferSP data_sp(heap_buf_ptr =
789 new lldb_private::DataBufferHeap());
Enrico Granata0c489f52012-03-01 04:24:26 +0000790
Kate Stoneb9c1b512016-09-06 20:57:50 +0000791 AddressType addr_type;
792 lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type)
793 : GetAddressOf(true, &addr_type);
794
795 switch (addr_type) {
796 case eAddressTypeFile: {
797 ModuleSP module_sp(GetModule());
798 if (module_sp) {
799 addr = addr + offset;
800 Address so_addr;
801 module_sp->ResolveFileAddress(addr, so_addr);
802 ExecutionContext exe_ctx(GetExecutionContextRef());
803 Target *target = exe_ctx.GetTargetPtr();
804 if (target) {
805 heap_buf_ptr->SetByteSize(bytes);
806 size_t bytes_read = target->ReadMemory(
807 so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
808 if (error.Success()) {
809 data.SetData(data_sp);
810 return bytes_read;
811 }
812 }
813 }
814 } break;
815 case eAddressTypeLoad: {
816 ExecutionContext exe_ctx(GetExecutionContextRef());
817 Process *process = exe_ctx.GetProcessPtr();
818 if (process) {
819 heap_buf_ptr->SetByteSize(bytes);
820 size_t bytes_read = process->ReadMemory(
821 addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
822 if (error.Success() || bytes_read > 0) {
823 data.SetData(data_sp);
824 return bytes_read;
825 }
826 }
827 } break;
828 case eAddressTypeHost: {
829 const uint64_t max_bytes =
830 GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());
831 if (max_bytes > offset) {
832 size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes);
833 addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
834 if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
835 break;
836 heap_buf_ptr->CopyData((uint8_t *)(addr + offset), bytes_read);
837 data.SetData(data_sp);
838 return bytes_read;
839 }
840 } break;
841 case eAddressTypeInvalid:
842 break;
Enrico Granata0c489f52012-03-01 04:24:26 +0000843 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000844 }
845 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000846}
847
Zachary Turner97206d52017-05-12 04:51:55 +0000848uint64_t ValueObject::GetData(DataExtractor &data, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000849 UpdateValueIfNeeded(false);
850 ExecutionContext exe_ctx(GetExecutionContextRef());
851 error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
852 if (error.Fail()) {
853 if (m_data.GetByteSize()) {
854 data = m_data;
855 error.Clear();
856 return data.GetByteSize();
857 } else {
858 return 0;
859 }
860 }
861 data.SetAddressByteSize(m_data.GetAddressByteSize());
862 data.SetByteOrder(m_data.GetByteOrder());
863 return data.GetByteSize();
Enrico Granata49bfafb2014-11-18 23:36:25 +0000864}
865
Zachary Turner97206d52017-05-12 04:51:55 +0000866bool ValueObject::SetData(DataExtractor &data, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000867 error.Clear();
868 // Make sure our value is up to date first so that our location and location
869 // type is valid.
870 if (!UpdateValueIfNeeded(false)) {
871 error.SetErrorString("unable to read value");
872 return false;
873 }
874
875 uint64_t count = 0;
876 const Encoding encoding = GetCompilerType().GetEncoding(count);
877
878 const size_t byte_size = GetByteSize();
879
880 Value::ValueType value_type = m_value.GetValueType();
881
882 switch (value_type) {
883 case Value::eValueTypeScalar: {
Zachary Turner97206d52017-05-12 04:51:55 +0000884 Status set_error =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000885 m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
886
887 if (!set_error.Success()) {
888 error.SetErrorStringWithFormat("unable to set scalar value: %s",
889 set_error.AsCString());
890 return false;
891 }
892 } break;
893 case Value::eValueTypeLoadAddress: {
894 // If it is a load address, then the scalar value is the storage location
895 // of the data, and we have to shove this value down to that load location.
896 ExecutionContext exe_ctx(GetExecutionContextRef());
897 Process *process = exe_ctx.GetProcessPtr();
898 if (process) {
899 addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
900 size_t bytes_written = process->WriteMemory(
901 target_addr, data.GetDataStart(), byte_size, error);
902 if (!error.Success())
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000903 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000904 if (bytes_written != byte_size) {
905 error.SetErrorString("unable to write value to memory");
906 return false;
907 }
908 }
909 } break;
910 case Value::eValueTypeHostAddress: {
911 // If it is a host address, then we stuff the scalar as a DataBuffer into
912 // the Value's data.
913 DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
914 m_data.SetData(buffer_sp, 0);
915 data.CopyByteOrderedData(0, byte_size,
916 const_cast<uint8_t *>(m_data.GetDataStart()),
917 byte_size, m_data.GetByteOrder());
918 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
919 } break;
920 case Value::eValueTypeFileAddress:
921 case Value::eValueTypeVector:
922 break;
923 }
924
Adrian Prantl05097242018-04-30 16:49:04 +0000925 // If we have reached this point, then we have successfully changed the
926 // value.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000927 SetNeedsUpdate();
928 return true;
929}
930
931static bool CopyStringDataToBufferSP(const StreamString &source,
932 lldb::DataBufferSP &destination) {
933 destination.reset(new DataBufferHeap(source.GetSize() + 1, 0));
Zachary Turnerc1564272016-11-16 21:15:24 +0000934 memcpy(destination->GetBytes(), source.GetString().data(), source.GetSize());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935 return true;
936}
937
938std::pair<size_t, bool>
Zachary Turner97206d52017-05-12 04:51:55 +0000939ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940 uint32_t max_length, bool honor_array,
941 Format item_format) {
942 bool was_capped = false;
943 StreamString s;
944 ExecutionContext exe_ctx(GetExecutionContextRef());
945 Target *target = exe_ctx.GetTargetPtr();
946
947 if (!target) {
948 s << "<no target to read from>";
949 error.SetErrorString("no target to read from");
950 CopyStringDataToBufferSP(s, buffer_sp);
951 return {0, was_capped};
952 }
953
954 if (max_length == 0)
955 max_length = target->GetMaximumSizeOfStringSummary();
956
957 size_t bytes_read = 0;
958 size_t total_bytes_read = 0;
959
960 CompilerType compiler_type = GetCompilerType();
961 CompilerType elem_or_pointee_compiler_type;
962 const Flags type_flags(GetTypeInfo(&elem_or_pointee_compiler_type));
963 if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
964 elem_or_pointee_compiler_type.IsCharType()) {
Greg Claytonafacd142011-09-02 01:15:17 +0000965 addr_t cstr_address = LLDB_INVALID_ADDRESS;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000966 AddressType cstr_address_type = eAddressTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000967
Kate Stoneb9c1b512016-09-06 20:57:50 +0000968 size_t cstr_len = 0;
969 bool capped_data = false;
970 const bool is_array = type_flags.Test(eTypeIsArray);
971 if (is_array) {
972 // We have an array
973 uint64_t array_size = 0;
974 if (compiler_type.IsArrayType(NULL, &array_size, NULL)) {
975 cstr_len = array_size;
976 if (cstr_len > max_length) {
977 capped_data = true;
978 cstr_len = max_length;
Enrico Granata9128ee22011-09-06 19:20:51 +0000979 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000980 }
981 cstr_address = GetAddressOf(true, &cstr_address_type);
982 } else {
983 // We have a pointer
984 cstr_address = GetPointerValue(&cstr_address_type);
Enrico Granata9128ee22011-09-06 19:20:51 +0000985 }
Enrico Granata9128ee22011-09-06 19:20:51 +0000986
Kate Stoneb9c1b512016-09-06 20:57:50 +0000987 if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) {
988 if (cstr_address_type == eAddressTypeHost && is_array) {
989 const char *cstr = GetDataExtractor().PeekCStr(0);
990 if (cstr == nullptr) {
991 s << "<invalid address>";
992 error.SetErrorString("invalid address");
993 CopyStringDataToBufferSP(s, buffer_sp);
994 return {0, was_capped};
Sean Callananed185ab2013-04-19 19:47:32 +0000995 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000996 buffer_sp.reset(new DataBufferHeap(cstr_len, 0));
997 memcpy(buffer_sp->GetBytes(), cstr, cstr_len);
998 return {cstr_len, was_capped};
999 } else {
1000 s << "<invalid address>";
1001 error.SetErrorString("invalid address");
Enrico Granata2206b482014-10-30 18:27:31 +00001002 CopyStringDataToBufferSP(s, buffer_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001003 return {0, was_capped};
1004 }
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001005 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001006
1007 Address cstr_so_addr(cstr_address);
1008 DataExtractor data;
1009 if (cstr_len > 0 && honor_array) {
1010 // I am using GetPointeeData() here to abstract the fact that some
Adrian Prantl05097242018-04-30 16:49:04 +00001011 // ValueObjects are actually frozen pointers in the host but the pointed-
1012 // to data lives in the debuggee, and GetPointeeData() automatically
1013 // takes care of this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001014 GetPointeeData(data, 0, cstr_len);
1015
1016 if ((bytes_read = data.GetByteSize()) > 0) {
1017 total_bytes_read = bytes_read;
1018 for (size_t offset = 0; offset < bytes_read; offset++)
1019 s.Printf("%c", *data.PeekData(offset, 1));
1020 if (capped_data)
1021 was_capped = true;
1022 }
1023 } else {
1024 cstr_len = max_length;
1025 const size_t k_max_buf_size = 64;
1026
1027 size_t offset = 0;
1028
1029 int cstr_len_displayed = -1;
1030 bool capped_cstr = false;
1031 // I am using GetPointeeData() here to abstract the fact that some
Adrian Prantl05097242018-04-30 16:49:04 +00001032 // ValueObjects are actually frozen pointers in the host but the pointed-
1033 // to data lives in the debuggee, and GetPointeeData() automatically
1034 // takes care of this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001035 while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {
1036 total_bytes_read += bytes_read;
1037 const char *cstr = data.PeekCStr(0);
1038 size_t len = strnlen(cstr, k_max_buf_size);
1039 if (cstr_len_displayed < 0)
1040 cstr_len_displayed = len;
1041
1042 if (len == 0)
1043 break;
1044 cstr_len_displayed += len;
1045 if (len > bytes_read)
1046 len = bytes_read;
1047 if (len > cstr_len)
1048 len = cstr_len;
1049
1050 for (size_t offset = 0; offset < bytes_read; offset++)
1051 s.Printf("%c", *data.PeekData(offset, 1));
1052
1053 if (len < k_max_buf_size)
1054 break;
1055
1056 if (len >= cstr_len) {
1057 capped_cstr = true;
1058 break;
1059 }
1060
1061 cstr_len -= len;
1062 offset += len;
1063 }
1064
1065 if (cstr_len_displayed >= 0) {
1066 if (capped_cstr)
1067 was_capped = true;
1068 }
1069 }
1070 } else {
1071 error.SetErrorString("not a string object");
1072 s << "<not a string object>";
1073 }
1074 CopyStringDataToBufferSP(s, buffer_sp);
1075 return {total_bytes_read, was_capped};
1076}
1077
1078std::pair<TypeValidatorResult, std::string> ValueObject::GetValidationStatus() {
1079 if (!UpdateValueIfNeeded(true))
1080 return {TypeValidatorResult::Success,
1081 ""}; // not the validator's job to discuss update problems
1082
1083 if (m_validation_result.hasValue())
1084 return m_validation_result.getValue();
1085
1086 if (!m_type_validator_sp)
1087 return {TypeValidatorResult::Success, ""}; // no validator no failure
1088
1089 auto outcome = m_type_validator_sp->FormatObject(this);
1090
1091 return (m_validation_result = {outcome.m_result, outcome.m_message})
1092 .getValue();
1093}
1094
1095const char *ValueObject::GetObjectDescription() {
1096
1097 if (!UpdateValueIfNeeded(true))
1098 return NULL;
1099
1100 if (!m_object_desc_str.empty())
1101 return m_object_desc_str.c_str();
1102
1103 ExecutionContext exe_ctx(GetExecutionContextRef());
1104 Process *process = exe_ctx.GetProcessPtr();
1105 if (process == NULL)
1106 return NULL;
1107
1108 StreamString s;
1109
1110 LanguageType language = GetObjectRuntimeLanguage();
1111 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
1112
1113 if (runtime == NULL) {
1114 // Aw, hell, if the things a pointer, or even just an integer, let's try
1115 // ObjC anyway...
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001116 CompilerType compiler_type = GetCompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001117 if (compiler_type) {
1118 bool is_signed;
1119 if (compiler_type.IsIntegerType(is_signed) ||
1120 compiler_type.IsPointerType()) {
1121 runtime = process->GetLanguageRuntime(eLanguageTypeObjC);
1122 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001123 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001124 }
1125
1126 if (runtime && runtime->GetObjectDescription(s, *this)) {
Zachary Turnerc1564272016-11-16 21:15:24 +00001127 m_object_desc_str.append(s.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001128 }
1129
1130 if (m_object_desc_str.empty())
1131 return NULL;
1132 else
1133 return m_object_desc_str.c_str();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001134}
1135
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,
1137 std::string &destination) {
1138 if (UpdateValueIfNeeded(false))
1139 return format.FormatObject(this, destination);
1140 else
1141 return false;
Enrico Granata744794a2014-09-05 21:46:22 +00001142}
1143
Kate Stoneb9c1b512016-09-06 20:57:50 +00001144bool ValueObject::GetValueAsCString(lldb::Format format,
1145 std::string &destination) {
1146 return GetValueAsCString(TypeFormatImpl_Format(format), destination);
1147}
Enrico Granata0a3958e2011-07-02 00:25:22 +00001148
Kate Stoneb9c1b512016-09-06 20:57:50 +00001149const char *ValueObject::GetValueAsCString() {
1150 if (UpdateValueIfNeeded(true)) {
1151 lldb::TypeFormatImplSP format_sp;
1152 lldb::Format my_format = GetFormat();
1153 if (my_format == lldb::eFormatDefault) {
1154 if (m_type_format_sp)
1155 format_sp = m_type_format_sp;
1156 else {
1157 if (m_is_bitfield_for_scalar)
1158 my_format = eFormatUnsigned;
1159 else {
1160 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo) {
1161 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1162 if (reg_info)
1163 my_format = reg_info->format;
1164 } else {
1165 my_format = GetValue().GetCompilerType().GetFormat();
1166 }
Jim Inghama2cf2632010-12-23 02:29:54 +00001167 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001168 }
Jim Inghama2cf2632010-12-23 02:29:54 +00001169 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001170 if (my_format != m_last_format || m_value_str.empty()) {
1171 m_last_format = my_format;
1172 if (!format_sp)
1173 format_sp.reset(new TypeFormatImpl_Format(my_format));
1174 if (GetValueAsCString(*format_sp.get(), m_value_str)) {
1175 if (!m_value_did_change && m_old_value_valid) {
Adrian Prantl05097242018-04-30 16:49:04 +00001176 // The value was gotten successfully, so we consider the value as
1177 // changed if the value string differs
Kate Stoneb9c1b512016-09-06 20:57:50 +00001178 SetValueDidChange(m_old_value_str != m_value_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001180 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001181 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001182 }
1183 if (m_value_str.empty())
1184 return NULL;
1185 return m_value_str.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001186}
1187
Adrian Prantl05097242018-04-30 16:49:04 +00001188// if > 8bytes, 0 is returned. this method should mostly be used to read
1189// address values out of pointers
Kate Stoneb9c1b512016-09-06 20:57:50 +00001190uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
1191 // If our byte size is zero this is an aggregate type that has children
1192 if (CanProvideValue()) {
1193 Scalar scalar;
1194 if (ResolveValue(scalar)) {
1195 if (success)
1196 *success = true;
1197 return scalar.ULongLong(fail_value);
Enrico Granatac3e320a2011-08-02 17:27:39 +00001198 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001199 // fallthrough, otherwise...
1200 }
Johnny Chen3f476c42012-06-05 19:37:43 +00001201
Kate Stoneb9c1b512016-09-06 20:57:50 +00001202 if (success)
1203 *success = false;
1204 return fail_value;
Enrico Granatac3e320a2011-08-02 17:27:39 +00001205}
1206
Kate Stoneb9c1b512016-09-06 20:57:50 +00001207int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
1208 // If our byte size is zero this is an aggregate type that has children
1209 if (CanProvideValue()) {
1210 Scalar scalar;
1211 if (ResolveValue(scalar)) {
1212 if (success)
1213 *success = true;
1214 return scalar.SLongLong(fail_value);
Enrico Granatad7373f62013-10-31 18:57:50 +00001215 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001216 // fallthrough, otherwise...
1217 }
1218
1219 if (success)
1220 *success = false;
1221 return fail_value;
Enrico Granatad7373f62013-10-31 18:57:50 +00001222}
1223
Kate Stoneb9c1b512016-09-06 20:57:50 +00001224// if any more "special cases" are added to
Adrian Prantl05097242018-04-30 16:49:04 +00001225// ValueObject::DumpPrintableRepresentation() please keep this call up to date
1226// by returning true for your new special cases. We will eventually move to
1227// checking this call result before trying to display special cases
Kate Stoneb9c1b512016-09-06 20:57:50 +00001228bool ValueObject::HasSpecialPrintableRepresentation(
1229 ValueObjectRepresentationStyle val_obj_display, Format custom_format) {
1230 Flags flags(GetTypeInfo());
1231 if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1232 val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1233 if (IsCStringContainer(true) &&
1234 (custom_format == eFormatCString || custom_format == eFormatCharArray ||
1235 custom_format == eFormatChar || custom_format == eFormatVectorOfChar))
1236 return true;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001237
Kate Stoneb9c1b512016-09-06 20:57:50 +00001238 if (flags.Test(eTypeIsArray)) {
1239 if ((custom_format == eFormatBytes) ||
1240 (custom_format == eFormatBytesWithASCII))
1241 return true;
1242
1243 if ((custom_format == eFormatVectorOfChar) ||
1244 (custom_format == eFormatVectorOfFloat32) ||
1245 (custom_format == eFormatVectorOfFloat64) ||
1246 (custom_format == eFormatVectorOfSInt16) ||
1247 (custom_format == eFormatVectorOfSInt32) ||
1248 (custom_format == eFormatVectorOfSInt64) ||
1249 (custom_format == eFormatVectorOfSInt8) ||
1250 (custom_format == eFormatVectorOfUInt128) ||
1251 (custom_format == eFormatVectorOfUInt16) ||
1252 (custom_format == eFormatVectorOfUInt32) ||
1253 (custom_format == eFormatVectorOfUInt64) ||
1254 (custom_format == eFormatVectorOfUInt8))
1255 return true;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001256 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001257 }
1258 return false;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001259}
1260
Kate Stoneb9c1b512016-09-06 20:57:50 +00001261bool ValueObject::DumpPrintableRepresentation(
1262 Stream &s, ValueObjectRepresentationStyle val_obj_display,
1263 Format custom_format, PrintableRepresentationSpecialCases special,
1264 bool do_dump_error) {
Enrico Granataf4efecd2011-07-12 22:56:10 +00001265
Kate Stoneb9c1b512016-09-06 20:57:50 +00001266 Flags flags(GetTypeInfo());
Enrico Granata86cc9822012-03-19 22:58:49 +00001267
Enrico Granata65d86e42016-11-07 23:32:20 +00001268 bool allow_special =
1269 (special == ValueObject::PrintableRepresentationSpecialCases::eAllow);
1270 const bool only_special = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001271
1272 if (allow_special) {
1273 if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1274 val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1275 // when being asked to get a printable display an array or pointer type
Adrian Prantl05097242018-04-30 16:49:04 +00001276 // directly, try to "do the right thing"
Kate Stoneb9c1b512016-09-06 20:57:50 +00001277
1278 if (IsCStringContainer(true) &&
1279 (custom_format == eFormatCString ||
1280 custom_format == eFormatCharArray || custom_format == eFormatChar ||
1281 custom_format ==
1282 eFormatVectorOfChar)) // print char[] & char* directly
1283 {
Zachary Turner97206d52017-05-12 04:51:55 +00001284 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001285 lldb::DataBufferSP buffer_sp;
1286 std::pair<size_t, bool> read_string = ReadPointedString(
1287 buffer_sp, error, 0, (custom_format == eFormatVectorOfChar) ||
1288 (custom_format == eFormatCharArray));
1289 lldb_private::formatters::StringPrinter::
1290 ReadBufferAndDumpToStreamOptions options(*this);
1291 options.SetData(DataExtractor(
1292 buffer_sp, lldb::eByteOrderInvalid,
1293 8)); // none of this matters for a string - pass some defaults
1294 options.SetStream(&s);
1295 options.SetPrefixToken(0);
1296 options.SetQuote('"');
1297 options.SetSourceSize(buffer_sp->GetByteSize());
1298 options.SetIsTruncated(read_string.second);
1299 formatters::StringPrinter::ReadBufferAndDumpToStream<
1300 lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
1301 options);
1302 return !error.Fail();
1303 }
1304
1305 if (custom_format == eFormatEnum)
Enrico Granata85933ed2011-08-18 16:38:26 +00001306 return false;
Enrico Granata86cc9822012-03-19 22:58:49 +00001307
Adrian Prantl05097242018-04-30 16:49:04 +00001308 // this only works for arrays, because I have no way to know when the
1309 // pointed memory ends, and no special \0 end of data marker
Kate Stoneb9c1b512016-09-06 20:57:50 +00001310 if (flags.Test(eTypeIsArray)) {
1311 if ((custom_format == eFormatBytes) ||
1312 (custom_format == eFormatBytesWithASCII)) {
1313 const size_t count = GetNumChildren();
1314
1315 s << '[';
1316 for (size_t low = 0; low < count; low++) {
1317
1318 if (low)
1319 s << ',';
1320
1321 ValueObjectSP child = GetChildAtIndex(low, true);
1322 if (!child.get()) {
1323 s << "<invalid child>";
1324 continue;
Enrico Granata86cc9822012-03-19 22:58:49 +00001325 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001326 child->DumpPrintableRepresentation(
1327 s, ValueObject::eValueObjectRepresentationStyleValue,
1328 custom_format);
1329 }
1330
1331 s << ']';
1332
1333 return true;
Enrico Granata86cc9822012-03-19 22:58:49 +00001334 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001335
1336 if ((custom_format == eFormatVectorOfChar) ||
1337 (custom_format == eFormatVectorOfFloat32) ||
1338 (custom_format == eFormatVectorOfFloat64) ||
1339 (custom_format == eFormatVectorOfSInt16) ||
1340 (custom_format == eFormatVectorOfSInt32) ||
1341 (custom_format == eFormatVectorOfSInt64) ||
1342 (custom_format == eFormatVectorOfSInt8) ||
1343 (custom_format == eFormatVectorOfUInt128) ||
1344 (custom_format == eFormatVectorOfUInt16) ||
1345 (custom_format == eFormatVectorOfUInt32) ||
1346 (custom_format == eFormatVectorOfUInt64) ||
1347 (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes
1348 // with ASCII or any vector
1349 // format should be printed
1350 // directly
Enrico Granata86cc9822012-03-19 22:58:49 +00001351 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001352 const size_t count = GetNumChildren();
1353
1354 Format format = FormatManager::GetSingleItemFormat(custom_format);
1355
1356 s << '[';
1357 for (size_t low = 0; low < count; low++) {
1358
1359 if (low)
1360 s << ',';
1361
1362 ValueObjectSP child = GetChildAtIndex(low, true);
1363 if (!child.get()) {
1364 s << "<invalid child>";
1365 continue;
Enrico Granata0dba9b32014-01-08 01:36:59 +00001366 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001367 child->DumpPrintableRepresentation(
1368 s, ValueObject::eValueObjectRepresentationStyleValue, format);
1369 }
1370
1371 s << ']';
1372
1373 return true;
Enrico Granata86cc9822012-03-19 22:58:49 +00001374 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001375 }
1376
1377 if ((custom_format == eFormatBoolean) ||
1378 (custom_format == eFormatBinary) || (custom_format == eFormatChar) ||
1379 (custom_format == eFormatCharPrintable) ||
1380 (custom_format == eFormatComplexFloat) ||
1381 (custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||
1382 (custom_format == eFormatHexUppercase) ||
1383 (custom_format == eFormatFloat) || (custom_format == eFormatOctal) ||
1384 (custom_format == eFormatOSType) ||
1385 (custom_format == eFormatUnicode16) ||
1386 (custom_format == eFormatUnicode32) ||
1387 (custom_format == eFormatUnsigned) ||
1388 (custom_format == eFormatPointer) ||
1389 (custom_format == eFormatComplexInteger) ||
1390 (custom_format == eFormatComplex) ||
1391 (custom_format == eFormatDefault)) // use the [] operator
1392 return false;
Enrico Granata86cc9822012-03-19 22:58:49 +00001393 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001394 }
1395
1396 if (only_special)
1397 return false;
1398
1399 bool var_success = false;
1400
1401 {
Zachary Turnerc1564272016-11-16 21:15:24 +00001402 llvm::StringRef str;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001403
1404 // this is a local stream that we are using to ensure that the data pointed
Adrian Prantl05097242018-04-30 16:49:04 +00001405 // to by cstr survives long enough for us to copy it to its destination -
1406 // it is necessary to have this temporary storage area for cases where our
Zachary Turnerc1564272016-11-16 21:15:24 +00001407 // desired output is not backed by some other longer-term storage
Kate Stoneb9c1b512016-09-06 20:57:50 +00001408 StreamString strm;
1409
1410 if (custom_format != eFormatInvalid)
1411 SetFormat(custom_format);
1412
1413 switch (val_obj_display) {
1414 case eValueObjectRepresentationStyleValue:
Zachary Turnerc1564272016-11-16 21:15:24 +00001415 str = GetValueAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001416 break;
1417
1418 case eValueObjectRepresentationStyleSummary:
Zachary Turnerc1564272016-11-16 21:15:24 +00001419 str = GetSummaryAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001420 break;
1421
1422 case eValueObjectRepresentationStyleLanguageSpecific:
Zachary Turnerc1564272016-11-16 21:15:24 +00001423 str = GetObjectDescription();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001424 break;
1425
1426 case eValueObjectRepresentationStyleLocation:
Zachary Turnerc1564272016-11-16 21:15:24 +00001427 str = GetLocationAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001428 break;
1429
1430 case eValueObjectRepresentationStyleChildrenCount:
1431 strm.Printf("%" PRIu64 "", (uint64_t)GetNumChildren());
Zachary Turnerc1564272016-11-16 21:15:24 +00001432 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001433 break;
1434
1435 case eValueObjectRepresentationStyleType:
Zachary Turnerc1564272016-11-16 21:15:24 +00001436 str = GetTypeName().GetStringRef();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001437 break;
1438
1439 case eValueObjectRepresentationStyleName:
Zachary Turnerc1564272016-11-16 21:15:24 +00001440 str = GetName().GetStringRef();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001441 break;
1442
1443 case eValueObjectRepresentationStyleExpressionPath:
1444 GetExpressionPath(strm, false);
Zachary Turnerc1564272016-11-16 21:15:24 +00001445 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001446 break;
1447 }
1448
Zachary Turnerc1564272016-11-16 21:15:24 +00001449 if (str.empty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001450 if (val_obj_display == eValueObjectRepresentationStyleValue)
Zachary Turnerc1564272016-11-16 21:15:24 +00001451 str = GetSummaryAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001452 else if (val_obj_display == eValueObjectRepresentationStyleSummary) {
1453 if (!CanProvideValue()) {
1454 strm.Printf("%s @ %s", GetTypeName().AsCString(),
1455 GetLocationAsCString());
Zachary Turnerc1564272016-11-16 21:15:24 +00001456 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001457 } else
Zachary Turnerc1564272016-11-16 21:15:24 +00001458 str = GetValueAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001459 }
1460 }
1461
Zachary Turnerc1564272016-11-16 21:15:24 +00001462 if (!str.empty())
1463 s << str;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001464 else {
1465 if (m_error.Fail()) {
1466 if (do_dump_error)
1467 s.Printf("<%s>", m_error.AsCString());
1468 else
1469 return false;
1470 } else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1471 s.PutCString("<no summary available>");
1472 else if (val_obj_display == eValueObjectRepresentationStyleValue)
1473 s.PutCString("<no value available>");
1474 else if (val_obj_display ==
1475 eValueObjectRepresentationStyleLanguageSpecific)
1476 s.PutCString("<not a valid Objective-C object>"); // edit this if we
1477 // have other runtimes
1478 // that support a
1479 // description
1480 else
1481 s.PutCString("<no printable representation>");
1482 }
1483
Adrian Prantl05097242018-04-30 16:49:04 +00001484 // we should only return false here if we could not do *anything* even if
1485 // we have an error message as output, that's a success from our callers'
1486 // perspective, so return true
Kate Stoneb9c1b512016-09-06 20:57:50 +00001487 var_success = true;
1488
1489 if (custom_format != eFormatInvalid)
1490 SetFormat(eFormatDefault);
1491 }
1492
1493 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001494}
1495
Kate Stoneb9c1b512016-09-06 20:57:50 +00001496addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
1497 AddressType *address_type) {
1498 // Can't take address of a bitfield
1499 if (IsBitfield())
Greg Clayton73b472d2010-10-27 03:32:59 +00001500 return LLDB_INVALID_ADDRESS;
Greg Clayton73b472d2010-10-27 03:32:59 +00001501
Kate Stoneb9c1b512016-09-06 20:57:50 +00001502 if (!UpdateValueIfNeeded(false))
1503 return LLDB_INVALID_ADDRESS;
Greg Clayton737b9322010-09-13 03:32:57 +00001504
Kate Stoneb9c1b512016-09-06 20:57:50 +00001505 switch (m_value.GetValueType()) {
1506 case Value::eValueTypeScalar:
1507 case Value::eValueTypeVector:
1508 if (scalar_is_load_address) {
1509 if (address_type)
1510 *address_type = eAddressTypeLoad;
1511 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
Greg Clayton737b9322010-09-13 03:32:57 +00001512 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001513 break;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001514
Kate Stoneb9c1b512016-09-06 20:57:50 +00001515 case Value::eValueTypeLoadAddress:
1516 case Value::eValueTypeFileAddress: {
Enrico Granata9128ee22011-09-06 19:20:51 +00001517 if (address_type)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001518 *address_type = m_value.GetValueAddressType();
1519 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1520 } break;
1521 case Value::eValueTypeHostAddress: {
1522 if (address_type)
1523 *address_type = m_value.GetValueAddressType();
1524 return LLDB_INVALID_ADDRESS;
1525 } break;
1526 }
1527 if (address_type)
1528 *address_type = eAddressTypeInvalid;
1529 return LLDB_INVALID_ADDRESS;
1530}
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001531
Kate Stoneb9c1b512016-09-06 20:57:50 +00001532addr_t ValueObject::GetPointerValue(AddressType *address_type) {
1533 addr_t address = LLDB_INVALID_ADDRESS;
1534 if (address_type)
1535 *address_type = eAddressTypeInvalid;
1536
1537 if (!UpdateValueIfNeeded(false))
Greg Clayton737b9322010-09-13 03:32:57 +00001538 return address;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001539
1540 switch (m_value.GetValueType()) {
1541 case Value::eValueTypeScalar:
1542 case Value::eValueTypeVector:
1543 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1544 break;
1545
1546 case Value::eValueTypeHostAddress:
1547 case Value::eValueTypeLoadAddress:
1548 case Value::eValueTypeFileAddress: {
1549 lldb::offset_t data_offset = 0;
1550 address = m_data.GetPointer(&data_offset);
1551 } break;
1552 }
1553
1554 if (address_type)
1555 *address_type = GetAddressTypeOfChildren();
1556
1557 return address;
Greg Clayton737b9322010-09-13 03:32:57 +00001558}
1559
Zachary Turner97206d52017-05-12 04:51:55 +00001560bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001561 error.Clear();
1562 // Make sure our value is up to date first so that our location and location
1563 // type is valid.
1564 if (!UpdateValueIfNeeded(false)) {
1565 error.SetErrorString("unable to read value");
Greg Clayton81e871e2012-02-04 02:27:34 +00001566 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001567 }
1568
1569 uint64_t count = 0;
1570 const Encoding encoding = GetCompilerType().GetEncoding(count);
1571
1572 const size_t byte_size = GetByteSize();
1573
1574 Value::ValueType value_type = m_value.GetValueType();
1575
1576 if (value_type == Value::eValueTypeScalar) {
1577 // If the value is already a scalar, then let the scalar change itself:
1578 m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
1579 } else if (byte_size <= 16) {
1580 // If the value fits in a scalar, then make a new scalar and again let the
1581 // scalar code do the conversion, then figure out where to put the new
1582 // value.
1583 Scalar new_scalar;
1584 error = new_scalar.SetValueFromCString(value_str, encoding, byte_size);
1585 if (error.Success()) {
1586 switch (value_type) {
1587 case Value::eValueTypeLoadAddress: {
1588 // If it is a load address, then the scalar value is the storage
Adrian Prantl05097242018-04-30 16:49:04 +00001589 // location of the data, and we have to shove this value down to that
1590 // load location.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001591 ExecutionContext exe_ctx(GetExecutionContextRef());
1592 Process *process = exe_ctx.GetProcessPtr();
1593 if (process) {
1594 addr_t target_addr =
1595 m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1596 size_t bytes_written = process->WriteScalarToMemory(
1597 target_addr, new_scalar, byte_size, error);
1598 if (!error.Success())
1599 return false;
1600 if (bytes_written != byte_size) {
1601 error.SetErrorString("unable to write value to memory");
1602 return false;
1603 }
1604 }
1605 } break;
1606 case Value::eValueTypeHostAddress: {
1607 // If it is a host address, then we stuff the scalar as a DataBuffer
1608 // into the Value's data.
1609 DataExtractor new_data;
1610 new_data.SetByteOrder(m_data.GetByteOrder());
1611
1612 DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
1613 m_data.SetData(buffer_sp, 0);
1614 bool success = new_scalar.GetData(new_data);
1615 if (success) {
1616 new_data.CopyByteOrderedData(
1617 0, byte_size, const_cast<uint8_t *>(m_data.GetDataStart()),
1618 byte_size, m_data.GetByteOrder());
1619 }
1620 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1621
1622 } break;
1623 case Value::eValueTypeFileAddress:
1624 case Value::eValueTypeScalar:
1625 case Value::eValueTypeVector:
1626 break;
1627 }
1628 } else {
1629 return false;
1630 }
1631 } else {
1632 // We don't support setting things bigger than a scalar at present.
1633 error.SetErrorString("unable to write aggregate data type");
1634 return false;
1635 }
1636
Adrian Prantl05097242018-04-30 16:49:04 +00001637 // If we have reached this point, then we have successfully changed the
1638 // value.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001639 SetNeedsUpdate();
1640 return true;
Greg Clayton81e871e2012-02-04 02:27:34 +00001641}
1642
Kate Stoneb9c1b512016-09-06 20:57:50 +00001643bool ValueObject::GetDeclaration(Declaration &decl) {
1644 decl.Clear();
1645 return false;
Greg Clayton84db9102012-03-26 23:03:23 +00001646}
1647
Kate Stoneb9c1b512016-09-06 20:57:50 +00001648ConstString ValueObject::GetTypeName() {
1649 return GetCompilerType().GetConstTypeName();
Enrico Granatae8daa2f2014-05-17 19:14:17 +00001650}
1651
Kate Stoneb9c1b512016-09-06 20:57:50 +00001652ConstString ValueObject::GetDisplayTypeName() { return GetTypeName(); }
1653
1654ConstString ValueObject::GetQualifiedTypeName() {
1655 return GetCompilerType().GetConstQualifiedTypeName();
Greg Clayton84db9102012-03-26 23:03:23 +00001656}
1657
Kate Stoneb9c1b512016-09-06 20:57:50 +00001658LanguageType ValueObject::GetObjectRuntimeLanguage() {
1659 return GetCompilerType().GetMinimumLanguage();
Jim Ingham5a369122010-09-28 01:25:32 +00001660}
1661
Kate Stoneb9c1b512016-09-06 20:57:50 +00001662void ValueObject::AddSyntheticChild(const ConstString &key,
1663 ValueObject *valobj) {
1664 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001665}
1666
Kate Stoneb9c1b512016-09-06 20:57:50 +00001667ValueObjectSP ValueObject::GetSyntheticChild(const ConstString &key) const {
1668 ValueObjectSP synthetic_child_sp;
1669 std::map<ConstString, ValueObject *>::const_iterator pos =
1670 m_synthetic_children.find(key);
1671 if (pos != m_synthetic_children.end())
1672 synthetic_child_sp = pos->second->GetSP();
1673 return synthetic_child_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001674}
1675
Greg Clayton2452ab72013-02-08 22:02:02 +00001676uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001677ValueObject::GetTypeInfo(CompilerType *pointee_or_element_compiler_type) {
1678 return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type);
Greg Clayton2452ab72013-02-08 22:02:02 +00001679}
1680
Kate Stoneb9c1b512016-09-06 20:57:50 +00001681bool ValueObject::IsPointerType() { return GetCompilerType().IsPointerType(); }
1682
1683bool ValueObject::IsArrayType() {
1684 return GetCompilerType().IsArrayType(NULL, NULL, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001685}
1686
Kate Stoneb9c1b512016-09-06 20:57:50 +00001687bool ValueObject::IsScalarType() { return GetCompilerType().IsScalarType(); }
1688
1689bool ValueObject::IsIntegerType(bool &is_signed) {
1690 return GetCompilerType().IsIntegerType(is_signed);
Greg Claytondaf515f2011-07-09 20:12:33 +00001691}
1692
Kate Stoneb9c1b512016-09-06 20:57:50 +00001693bool ValueObject::IsPointerOrReferenceType() {
1694 return GetCompilerType().IsPointerOrReferenceType();
Enrico Granata9fc19442011-07-06 02:13:41 +00001695}
1696
Kate Stoneb9c1b512016-09-06 20:57:50 +00001697bool ValueObject::IsPossibleDynamicType() {
1698 ExecutionContext exe_ctx(GetExecutionContextRef());
1699 Process *process = exe_ctx.GetProcessPtr();
1700 if (process)
1701 return process->IsPossibleDynamicValue(*this);
1702 else
1703 return GetCompilerType().IsPossibleDynamicType(NULL, true, true);
Jim Inghamb7603bb2011-03-18 00:05:18 +00001704}
Greg Clayton73b472d2010-10-27 03:32:59 +00001705
Kate Stoneb9c1b512016-09-06 20:57:50 +00001706bool ValueObject::IsRuntimeSupportValue() {
1707 Process *process(GetProcessSP().get());
1708 if (process) {
1709 LanguageRuntime *runtime =
1710 process->GetLanguageRuntime(GetObjectRuntimeLanguage());
1711 if (!runtime)
1712 runtime = process->GetObjCLanguageRuntime();
1713 if (runtime)
1714 return runtime->IsRuntimeSupportValue(*this);
1715 }
1716 return false;
Greg Clayton007d5be2011-05-30 00:49:24 +00001717}
1718
Kate Stoneb9c1b512016-09-06 20:57:50 +00001719bool ValueObject::IsNilReference() {
1720 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1721 return language->IsNilReference(*this);
1722 }
1723 return false;
Greg Claytondea8cb42011-06-29 22:09:02 +00001724}
1725
Kate Stoneb9c1b512016-09-06 20:57:50 +00001726bool ValueObject::IsUninitializedReference() {
1727 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1728 return language->IsUninitializedReference(*this);
1729 }
1730 return false;
Enrico Granata9e7b3882012-12-13 23:50:33 +00001731}
1732
Adrian Prantl05097242018-04-30 16:49:04 +00001733// This allows you to create an array member using and index that doesn't not
1734// fall in the normal bounds of the array. Many times structure can be defined
1735// as: struct Collection {
Greg Claytondaf515f2011-07-09 20:12:33 +00001736// uint32_t item_count;
1737// Item item_array[0];
1738// };
Adrian Prantl05097242018-04-30 16:49:04 +00001739// The size of the "item_array" is 1, but many times in practice there are more
1740// items in "item_array".
Greg Claytondaf515f2011-07-09 20:12:33 +00001741
Kate Stoneb9c1b512016-09-06 20:57:50 +00001742ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
1743 bool can_create) {
1744 ValueObjectSP synthetic_child_sp;
1745 if (IsPointerType() || IsArrayType()) {
1746 char index_str[64];
1747 snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index);
1748 ConstString index_const_str(index_str);
Adrian Prantl05097242018-04-30 16:49:04 +00001749 // Check if we have already created a synthetic array member in this valid
1750 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001751 synthetic_child_sp = GetSyntheticChild(index_const_str);
1752 if (!synthetic_child_sp) {
1753 ValueObject *synthetic_child;
Adrian Prantl05097242018-04-30 16:49:04 +00001754 // We haven't made a synthetic array member for INDEX yet, so lets make
1755 // one and cache it for any future reference.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001756 synthetic_child = CreateChildAtIndex(0, true, index);
1757
1758 // Cache the value if we got one back...
1759 if (synthetic_child) {
1760 AddSyntheticChild(index_const_str, synthetic_child);
Enrico Granata6f3533f2011-07-29 19:53:35 +00001761 synthetic_child_sp = synthetic_child->GetSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001762 synthetic_child_sp->SetName(ConstString(index_str));
1763 synthetic_child_sp->m_is_array_item_for_pointer = true;
1764 }
Enrico Granata6f3533f2011-07-29 19:53:35 +00001765 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001766 }
1767 return synthetic_child_sp;
Enrico Granata6f3533f2011-07-29 19:53:35 +00001768}
1769
Kate Stoneb9c1b512016-09-06 20:57:50 +00001770ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
1771 bool can_create) {
1772 ValueObjectSP synthetic_child_sp;
1773 if (IsScalarType()) {
1774 char index_str[64];
1775 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1776 ConstString index_const_str(index_str);
Adrian Prantl05097242018-04-30 16:49:04 +00001777 // Check if we have already created a synthetic array member in this valid
1778 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001779 synthetic_child_sp = GetSyntheticChild(index_const_str);
1780 if (!synthetic_child_sp) {
1781 uint32_t bit_field_size = to - from + 1;
1782 uint32_t bit_field_offset = from;
1783 if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
1784 bit_field_offset =
1785 GetByteSize() * 8 - bit_field_size - bit_field_offset;
Adrian Prantl05097242018-04-30 16:49:04 +00001786 // We haven't made a synthetic array member for INDEX yet, so lets make
1787 // one and cache it for any future reference.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001788 ValueObjectChild *synthetic_child = new ValueObjectChild(
1789 *this, GetCompilerType(), index_const_str, GetByteSize(), 0,
1790 bit_field_size, bit_field_offset, false, false, eAddressTypeInvalid,
1791 0);
1792
1793 // Cache the value if we got one back...
1794 if (synthetic_child) {
1795 AddSyntheticChild(index_const_str, synthetic_child);
Enrico Granata32556cd2014-08-26 20:54:04 +00001796 synthetic_child_sp = synthetic_child->GetSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001797 synthetic_child_sp->SetName(ConstString(index_str));
1798 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1799 }
Enrico Granata32556cd2014-08-26 20:54:04 +00001800 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001801 }
1802 return synthetic_child_sp;
Enrico Granata32556cd2014-08-26 20:54:04 +00001803}
1804
Kate Stoneb9c1b512016-09-06 20:57:50 +00001805ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
1806 uint32_t offset, const CompilerType &type, bool can_create,
1807 ConstString name_const_str) {
1808
1809 ValueObjectSP synthetic_child_sp;
1810
1811 if (name_const_str.IsEmpty()) {
1812 char name_str[64];
1813 snprintf(name_str, sizeof(name_str), "@%i", offset);
1814 name_const_str.SetCString(name_str);
1815 }
1816
Adrian Prantl05097242018-04-30 16:49:04 +00001817 // Check if we have already created a synthetic array member in this valid
1818 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001819 synthetic_child_sp = GetSyntheticChild(name_const_str);
1820
1821 if (synthetic_child_sp.get())
1822 return synthetic_child_sp;
1823
1824 if (!can_create)
1825 return ValueObjectSP();
1826
1827 ExecutionContext exe_ctx(GetExecutionContextRef());
1828
1829 ValueObjectChild *synthetic_child = new ValueObjectChild(
1830 *this, type, name_const_str,
1831 type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0,
1832 false, false, eAddressTypeInvalid, 0);
1833 if (synthetic_child) {
1834 AddSyntheticChild(name_const_str, synthetic_child);
1835 synthetic_child_sp = synthetic_child->GetSP();
1836 synthetic_child_sp->SetName(name_const_str);
1837 synthetic_child_sp->m_is_child_at_offset = true;
1838 }
1839 return synthetic_child_sp;
1840}
1841
1842ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
1843 const CompilerType &type,
1844 bool can_create,
1845 ConstString name_const_str) {
1846 ValueObjectSP synthetic_child_sp;
1847
1848 if (name_const_str.IsEmpty()) {
1849 char name_str[128];
1850 snprintf(name_str, sizeof(name_str), "base%s@%i",
1851 type.GetTypeName().AsCString("<unknown>"), offset);
1852 name_const_str.SetCString(name_str);
1853 }
1854
Adrian Prantl05097242018-04-30 16:49:04 +00001855 // Check if we have already created a synthetic array member in this valid
1856 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001857 synthetic_child_sp = GetSyntheticChild(name_const_str);
1858
1859 if (synthetic_child_sp.get())
1860 return synthetic_child_sp;
1861
1862 if (!can_create)
1863 return ValueObjectSP();
1864
1865 const bool is_base_class = true;
1866
1867 ExecutionContext exe_ctx(GetExecutionContextRef());
1868
1869 ValueObjectChild *synthetic_child = new ValueObjectChild(
1870 *this, type, name_const_str,
1871 type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0,
1872 is_base_class, false, eAddressTypeInvalid, 0);
1873 if (synthetic_child) {
1874 AddSyntheticChild(name_const_str, synthetic_child);
1875 synthetic_child_sp = synthetic_child->GetSP();
1876 synthetic_child_sp->SetName(name_const_str);
1877 }
1878 return synthetic_child_sp;
1879}
Enrico Granata32556cd2014-08-26 20:54:04 +00001880
Adrian Prantl05097242018-04-30 16:49:04 +00001881// your expression path needs to have a leading . or -> (unless it somehow
1882// "looks like" an array, in which case it has a leading [ symbol). while the [
1883// is meaningful and should be shown to the user, . and -> are just parser
1884// design, but by no means added information for the user.. strip them off
Kate Stoneb9c1b512016-09-06 20:57:50 +00001885static const char *SkipLeadingExpressionPathSeparators(const char *expression) {
1886 if (!expression || !expression[0])
Enrico Granatad55546b2011-07-22 00:16:08 +00001887 return expression;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001888 if (expression[0] == '.')
1889 return expression + 1;
1890 if (expression[0] == '-' && expression[1] == '>')
1891 return expression + 2;
1892 return expression;
Enrico Granatad55546b2011-07-22 00:16:08 +00001893}
1894
Greg Claytonafacd142011-09-02 01:15:17 +00001895ValueObjectSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00001896ValueObject::GetSyntheticExpressionPathChild(const char *expression,
1897 bool can_create) {
1898 ValueObjectSP synthetic_child_sp;
1899 ConstString name_const_string(expression);
Adrian Prantl05097242018-04-30 16:49:04 +00001900 // Check if we have already created a synthetic array member in this valid
1901 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001902 synthetic_child_sp = GetSyntheticChild(name_const_string);
1903 if (!synthetic_child_sp) {
Adrian Prantl05097242018-04-30 16:49:04 +00001904 // We haven't made a synthetic array member for expression yet, so lets
1905 // make one and cache it for any future reference.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001906 synthetic_child_sp = GetValueForExpressionPath(
Zachary Turnerd2daca72016-11-18 17:55:04 +00001907 expression, NULL, NULL,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001908 GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(
1909 GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
1910 None));
1911
1912 // Cache the value if we got one back...
1913 if (synthetic_child_sp.get()) {
1914 // FIXME: this causes a "real" child to end up with its name changed to
1915 // the contents of expression
1916 AddSyntheticChild(name_const_string, synthetic_child_sp.get());
1917 synthetic_child_sp->SetName(
1918 ConstString(SkipLeadingExpressionPathSeparators(expression)));
Enrico Granatad55546b2011-07-22 00:16:08 +00001919 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001920 }
1921 return synthetic_child_sp;
Enrico Granatad55546b2011-07-22 00:16:08 +00001922}
1923
Kate Stoneb9c1b512016-09-06 20:57:50 +00001924void ValueObject::CalculateSyntheticValue(bool use_synthetic) {
1925 if (use_synthetic == false)
1926 return;
1927
1928 TargetSP target_sp(GetTargetSP());
1929 if (target_sp && target_sp->GetEnableSyntheticValue() == false) {
1930 m_synthetic_value = NULL;
1931 return;
1932 }
1933
1934 lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
1935
1936 if (!UpdateFormatsIfNeeded() && m_synthetic_value)
1937 return;
1938
1939 if (m_synthetic_children_sp.get() == NULL)
1940 return;
1941
1942 if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
1943 return;
1944
1945 m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
1946}
1947
1948void ValueObject::CalculateDynamicValue(DynamicValueType use_dynamic) {
1949 if (use_dynamic == eNoDynamicValues)
1950 return;
1951
1952 if (!m_dynamic_value && !IsDynamic()) {
1953 ExecutionContext exe_ctx(GetExecutionContextRef());
1954 Process *process = exe_ctx.GetProcessPtr();
1955 if (process && process->IsPossibleDynamicValue(*this)) {
1956 ClearDynamicTypeInformation();
1957 m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
Enrico Granatac5bc4122012-03-27 02:35:13 +00001958 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001959 }
Enrico Granatad55546b2011-07-22 00:16:08 +00001960}
1961
Kate Stoneb9c1b512016-09-06 20:57:50 +00001962ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) {
1963 if (use_dynamic == eNoDynamicValues)
1964 return ValueObjectSP();
1965
1966 if (!IsDynamic() && m_dynamic_value == NULL) {
1967 CalculateDynamicValue(use_dynamic);
1968 }
1969 if (m_dynamic_value)
1970 return m_dynamic_value->GetSP();
1971 else
1972 return ValueObjectSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00001973}
1974
Kate Stoneb9c1b512016-09-06 20:57:50 +00001975ValueObjectSP ValueObject::GetStaticValue() { return GetSP(); }
1976
1977lldb::ValueObjectSP ValueObject::GetNonSyntheticValue() { return GetSP(); }
1978
1979ValueObjectSP ValueObject::GetSyntheticValue(bool use_synthetic) {
1980 if (use_synthetic == false)
1981 return ValueObjectSP();
1982
1983 CalculateSyntheticValue(use_synthetic);
1984
1985 if (m_synthetic_value)
1986 return m_synthetic_value->GetSP();
1987 else
1988 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001989}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001990
Kate Stoneb9c1b512016-09-06 20:57:50 +00001991bool ValueObject::HasSyntheticValue() {
1992 UpdateFormatsIfNeeded();
Jim Ingham60dbabb2011-12-08 19:44:08 +00001993
Kate Stoneb9c1b512016-09-06 20:57:50 +00001994 if (m_synthetic_children_sp.get() == NULL)
1995 return false;
Enrico Granata886147f2012-05-08 18:47:08 +00001996
Kate Stoneb9c1b512016-09-06 20:57:50 +00001997 CalculateSyntheticValue(true);
Enrico Granata86cc9822012-03-19 22:58:49 +00001998
Kate Stoneb9c1b512016-09-06 20:57:50 +00001999 if (m_synthetic_value)
2000 return true;
2001 else
Greg Claytone221f822011-01-21 01:59:00 +00002002 return false;
2003}
2004
Kate Stoneb9c1b512016-09-06 20:57:50 +00002005bool ValueObject::GetBaseClassPath(Stream &s) {
2006 if (IsBaseClass()) {
2007 bool parent_had_base_class =
2008 GetParent() && GetParent()->GetBaseClassPath(s);
2009 CompilerType compiler_type = GetCompilerType();
2010 std::string cxx_class_name;
2011 bool this_had_base_class =
2012 ClangASTContext::GetCXXClassName(compiler_type, cxx_class_name);
2013 if (this_had_base_class) {
2014 if (parent_had_base_class)
2015 s.PutCString("::");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00002016 s.PutCString(cxx_class_name);
Greg Claytone221f822011-01-21 01:59:00 +00002017 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002018 return parent_had_base_class || this_had_base_class;
2019 }
2020 return false;
Greg Claytone221f822011-01-21 01:59:00 +00002021}
Greg Clayton1d3afba2010-10-05 00:00:42 +00002022
Kate Stoneb9c1b512016-09-06 20:57:50 +00002023ValueObject *ValueObject::GetNonBaseClassParent() {
2024 if (GetParent()) {
2025 if (GetParent()->IsBaseClass())
2026 return GetParent()->GetNonBaseClassParent();
2027 else
2028 return GetParent();
2029 }
2030 return NULL;
2031}
Enrico Granataa3c8f042014-08-19 22:29:08 +00002032
Kate Stoneb9c1b512016-09-06 20:57:50 +00002033bool ValueObject::IsBaseClass(uint32_t &depth) {
2034 if (!IsBaseClass()) {
2035 depth = 0;
2036 return false;
2037 }
2038 if (GetParent()) {
2039 GetParent()->IsBaseClass(depth);
2040 depth = depth + 1;
Enrico Granataa3c8f042014-08-19 22:29:08 +00002041 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002042 }
2043 // TODO: a base of no parent? weird..
2044 depth = 1;
2045 return true;
Enrico Granataa3c8f042014-08-19 22:29:08 +00002046}
2047
Kate Stoneb9c1b512016-09-06 20:57:50 +00002048void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes,
2049 GetExpressionPathFormat epformat) {
2050 // synthetic children do not actually "exist" as part of the hierarchy, and
Adrian Prantl05097242018-04-30 16:49:04 +00002051 // sometimes they are consed up in ways that don't make sense from an
2052 // underlying language/API standpoint. So, use a special code path here to
2053 // return something that can hopefully be used in expression
Kate Stoneb9c1b512016-09-06 20:57:50 +00002054 if (m_is_synthetic_children_generated) {
2055 UpdateValueIfNeeded();
2056
2057 if (m_value.GetValueType() == Value::eValueTypeLoadAddress) {
2058 if (IsPointerOrReferenceType()) {
2059 s.Printf("((%s)0x%" PRIx64 ")", GetTypeName().AsCString("void"),
2060 GetValueAsUnsigned(0));
Enrico Granata986fa5f2014-12-09 21:41:16 +00002061 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002062 } else {
2063 uint64_t load_addr =
2064 m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
2065 if (load_addr != LLDB_INVALID_ADDRESS) {
2066 s.Printf("(*( (%s *)0x%" PRIx64 "))", GetTypeName().AsCString("void"),
2067 load_addr);
2068 return;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002069 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002070 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002071 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002072
2073 if (CanProvideValue()) {
2074 s.Printf("((%s)%s)", GetTypeName().AsCString("void"),
2075 GetValueAsCString());
2076 return;
Enrico Granata4becb372011-06-29 22:27:15 +00002077 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002078
2079 return;
2080 }
2081
2082 const bool is_deref_of_parent = IsDereferenceOfParent();
2083
2084 if (is_deref_of_parent &&
2085 epformat == eGetExpressionPathFormatDereferencePointers) {
2086 // this is the original format of GetExpressionPath() producing code like
Adrian Prantl05097242018-04-30 16:49:04 +00002087 // *(a_ptr).memberName, which is entirely fine, until you put this into
Kate Stoneb9c1b512016-09-06 20:57:50 +00002088 // StackFrame::GetValueForVariableExpressionPath() which prefers to see
Adrian Prantl05097242018-04-30 16:49:04 +00002089 // a_ptr->memberName. the eHonorPointers mode is meant to produce strings
2090 // in this latter format
Kate Stoneb9c1b512016-09-06 20:57:50 +00002091 s.PutCString("*(");
2092 }
2093
2094 ValueObject *parent = GetParent();
2095
2096 if (parent)
2097 parent->GetExpressionPath(s, qualify_cxx_base_classes, epformat);
2098
Adrian Prantl05097242018-04-30 16:49:04 +00002099 // if we are a deref_of_parent just because we are synthetic array members
2100 // made up to allow ptr[%d] syntax to work in variable printing, then add our
2101 // name ([%d]) to the expression path
Kate Stoneb9c1b512016-09-06 20:57:50 +00002102 if (m_is_array_item_for_pointer &&
2103 epformat == eGetExpressionPathFormatHonorPointers)
2104 s.PutCString(m_name.AsCString());
2105
2106 if (!IsBaseClass()) {
2107 if (!is_deref_of_parent) {
2108 ValueObject *non_base_class_parent = GetNonBaseClassParent();
2109 if (non_base_class_parent &&
2110 !non_base_class_parent->GetName().IsEmpty()) {
2111 CompilerType non_base_class_parent_compiler_type =
2112 non_base_class_parent->GetCompilerType();
2113 if (non_base_class_parent_compiler_type) {
2114 if (parent && parent->IsDereferenceOfParent() &&
2115 epformat == eGetExpressionPathFormatHonorPointers) {
2116 s.PutCString("->");
2117 } else {
2118 const uint32_t non_base_class_parent_type_info =
2119 non_base_class_parent_compiler_type.GetTypeInfo();
2120
2121 if (non_base_class_parent_type_info & eTypeIsPointer) {
2122 s.PutCString("->");
2123 } else if ((non_base_class_parent_type_info & eTypeHasChildren) &&
2124 !(non_base_class_parent_type_info & eTypeIsArray)) {
2125 s.PutChar('.');
2126 }
2127 }
2128 }
2129 }
2130
2131 const char *name = GetName().GetCString();
2132 if (name) {
2133 if (qualify_cxx_base_classes) {
2134 if (GetBaseClassPath(s))
2135 s.PutCString("::");
2136 }
2137 s.PutCString(name);
2138 }
2139 }
2140 }
2141
2142 if (is_deref_of_parent &&
2143 epformat == eGetExpressionPathFormatDereferencePointers) {
2144 s.PutChar(')');
2145 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002146}
2147
Kate Stoneb9c1b512016-09-06 20:57:50 +00002148ValueObjectSP ValueObject::GetValueForExpressionPath(
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002149 llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002150 ExpressionPathEndResultType *final_value_type,
2151 const GetValueForExpressionPathOptions &options,
2152 ExpressionPathAftermath *final_task_on_target) {
Enrico Granata385ad4e2012-03-03 00:45:57 +00002153
Kate Stoneb9c1b512016-09-06 20:57:50 +00002154 ExpressionPathScanEndReason dummy_reason_to_stop =
2155 ValueObject::eExpressionPathScanEndReasonUnknown;
2156 ExpressionPathEndResultType dummy_final_value_type =
2157 ValueObject::eExpressionPathEndResultTypeInvalid;
2158 ExpressionPathAftermath dummy_final_task_on_target =
2159 ValueObject::eExpressionPathAftermathNothing;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002160
Kate Stoneb9c1b512016-09-06 20:57:50 +00002161 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(
Zachary Turnerd2daca72016-11-18 17:55:04 +00002162 expression, reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002163 final_value_type ? final_value_type : &dummy_final_value_type, options,
2164 final_task_on_target ? final_task_on_target
2165 : &dummy_final_task_on_target);
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002166
Kate Stoneb9c1b512016-09-06 20:57:50 +00002167 if (!final_task_on_target ||
2168 *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
2169 return ret_val;
2170
2171 if (ret_val.get() &&
2172 ((final_value_type ? *final_value_type : dummy_final_value_type) ==
2173 eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress
2174 // of plain objects
2175 {
2176 if ((final_task_on_target ? *final_task_on_target
2177 : dummy_final_task_on_target) ==
2178 ValueObject::eExpressionPathAftermathDereference) {
Zachary Turner97206d52017-05-12 04:51:55 +00002179 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002180 ValueObjectSP final_value = ret_val->Dereference(error);
2181 if (error.Fail() || !final_value.get()) {
2182 if (reason_to_stop)
2183 *reason_to_stop =
2184 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2185 if (final_value_type)
2186 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002187 return ValueObjectSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002188 } else {
2189 if (final_task_on_target)
2190 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2191 return final_value;
2192 }
2193 }
2194 if (*final_task_on_target ==
2195 ValueObject::eExpressionPathAftermathTakeAddress) {
Zachary Turner97206d52017-05-12 04:51:55 +00002196 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002197 ValueObjectSP final_value = ret_val->AddressOf(error);
2198 if (error.Fail() || !final_value.get()) {
2199 if (reason_to_stop)
2200 *reason_to_stop =
2201 ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
2202 if (final_value_type)
2203 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2204 return ValueObjectSP();
2205 } else {
2206 if (final_task_on_target)
2207 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2208 return final_value;
2209 }
2210 }
2211 }
2212 return ret_val; // final_task_on_target will still have its original value, so
2213 // you know I did not do it
2214}
2215
Kate Stoneb9c1b512016-09-06 20:57:50 +00002216ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002217 llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002218 ExpressionPathEndResultType *final_result,
2219 const GetValueForExpressionPathOptions &options,
2220 ExpressionPathAftermath *what_next) {
2221 ValueObjectSP root = GetSP();
2222
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002223 if (!root)
2224 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002225
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002226 llvm::StringRef remainder = expression;
Zachary Turner655c4522016-11-18 06:34:45 +00002227
Kate Stoneb9c1b512016-09-06 20:57:50 +00002228 while (true) {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002229 llvm::StringRef temp_expression = remainder;
Zachary Turner655c4522016-11-18 06:34:45 +00002230
Kate Stoneb9c1b512016-09-06 20:57:50 +00002231 CompilerType root_compiler_type = root->GetCompilerType();
2232 CompilerType pointee_compiler_type;
2233 Flags pointee_compiler_type_info;
2234
2235 Flags root_compiler_type_info(
2236 root_compiler_type.GetTypeInfo(&pointee_compiler_type));
2237 if (pointee_compiler_type)
2238 pointee_compiler_type_info.Reset(pointee_compiler_type.GetTypeInfo());
2239
Zachary Turnerd2daca72016-11-18 17:55:04 +00002240 if (temp_expression.empty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002241 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2242 return root;
2243 }
2244
Zachary Turnerd2daca72016-11-18 17:55:04 +00002245 switch (temp_expression.front()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002246 case '-': {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002247 temp_expression = temp_expression.drop_front();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002248 if (options.m_check_dot_vs_arrow_syntax &&
2249 root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2250 // use -> on a
2251 // non-pointer and I
2252 // must catch the error
2253 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002254 *reason_to_stop =
2255 ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
2256 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2257 return ValueObjectSP();
2258 }
2259 if (root_compiler_type_info.Test(eTypeIsObjC) && // if yo are trying to
2260 // extract an ObjC IVar
2261 // when this is forbidden
2262 root_compiler_type_info.Test(eTypeIsPointer) &&
2263 options.m_no_fragile_ivar) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002264 *reason_to_stop =
2265 ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
2266 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2267 return ValueObjectSP();
2268 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002269 if (!temp_expression.startswith(">")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002270 *reason_to_stop =
2271 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2272 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2273 return ValueObjectSP();
2274 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002275 }
2276 LLVM_FALLTHROUGH;
2277 case '.': // or fallthrough from ->
2278 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002279 if (options.m_check_dot_vs_arrow_syntax &&
2280 temp_expression.front() == '.' &&
Kate Stoneb9c1b512016-09-06 20:57:50 +00002281 root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2282 // use . on a pointer
2283 // and I must catch the
2284 // error
2285 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002286 *reason_to_stop =
2287 ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
2288 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002289 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002290 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002291 temp_expression = temp_expression.drop_front(); // skip . or >
2292
2293 size_t next_sep_pos = temp_expression.find_first_of("-.[", 1);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002294 ConstString child_name;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002295 if (next_sep_pos == llvm::StringRef::npos) // if no other separator just
2296 // expand this last layer
Kate Stoneb9c1b512016-09-06 20:57:50 +00002297 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002298 child_name.SetString(temp_expression);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002299 ValueObjectSP child_valobj_sp =
2300 root->GetChildMemberWithName(child_name, true);
2301
2302 if (child_valobj_sp.get()) // we know we are done, so just return
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002303 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002304 *reason_to_stop =
2305 ValueObject::eExpressionPathScanEndReasonEndOfString;
2306 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2307 return child_valobj_sp;
2308 } else {
2309 switch (options.m_synthetic_children_traversal) {
2310 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2311 None:
2312 break;
2313 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2314 FromSynthetic:
2315 if (root->IsSynthetic()) {
2316 child_valobj_sp = root->GetNonSyntheticValue();
2317 if (child_valobj_sp.get())
2318 child_valobj_sp =
2319 child_valobj_sp->GetChildMemberWithName(child_name, true);
2320 }
2321 break;
2322 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2323 ToSynthetic:
2324 if (!root->IsSynthetic()) {
2325 child_valobj_sp = root->GetSyntheticValue();
2326 if (child_valobj_sp.get())
2327 child_valobj_sp =
2328 child_valobj_sp->GetChildMemberWithName(child_name, true);
2329 }
2330 break;
2331 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2332 Both:
2333 if (root->IsSynthetic()) {
2334 child_valobj_sp = root->GetNonSyntheticValue();
2335 if (child_valobj_sp.get())
2336 child_valobj_sp =
2337 child_valobj_sp->GetChildMemberWithName(child_name, true);
2338 } else {
2339 child_valobj_sp = root->GetSyntheticValue();
2340 if (child_valobj_sp.get())
2341 child_valobj_sp =
2342 child_valobj_sp->GetChildMemberWithName(child_name, true);
2343 }
2344 break;
2345 }
2346 }
2347
2348 // if we are here and options.m_no_synthetic_children is true,
Adrian Prantl05097242018-04-30 16:49:04 +00002349 // child_valobj_sp is going to be a NULL SP, so we hit the "else"
2350 // branch, and return an error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002351 if (child_valobj_sp.get()) // if it worked, just return
2352 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002353 *reason_to_stop =
2354 ValueObject::eExpressionPathScanEndReasonEndOfString;
2355 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2356 return child_valobj_sp;
2357 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002358 *reason_to_stop =
2359 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2360 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002361 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002362 }
2363 } else // other layers do expand
2364 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002365 llvm::StringRef next_separator = temp_expression.substr(next_sep_pos);
2366
2367 child_name.SetString(temp_expression.slice(0, next_sep_pos));
2368
Kate Stoneb9c1b512016-09-06 20:57:50 +00002369 ValueObjectSP child_valobj_sp =
2370 root->GetChildMemberWithName(child_name, true);
2371 if (child_valobj_sp.get()) // store the new root and move on
2372 {
2373 root = child_valobj_sp;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002374 remainder = next_separator;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002375 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2376 continue;
2377 } else {
2378 switch (options.m_synthetic_children_traversal) {
2379 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2380 None:
2381 break;
2382 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2383 FromSynthetic:
2384 if (root->IsSynthetic()) {
2385 child_valobj_sp = root->GetNonSyntheticValue();
2386 if (child_valobj_sp.get())
2387 child_valobj_sp =
2388 child_valobj_sp->GetChildMemberWithName(child_name, true);
2389 }
2390 break;
2391 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2392 ToSynthetic:
2393 if (!root->IsSynthetic()) {
2394 child_valobj_sp = root->GetSyntheticValue();
2395 if (child_valobj_sp.get())
2396 child_valobj_sp =
2397 child_valobj_sp->GetChildMemberWithName(child_name, true);
2398 }
2399 break;
2400 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2401 Both:
2402 if (root->IsSynthetic()) {
2403 child_valobj_sp = root->GetNonSyntheticValue();
2404 if (child_valobj_sp.get())
2405 child_valobj_sp =
2406 child_valobj_sp->GetChildMemberWithName(child_name, true);
2407 } else {
2408 child_valobj_sp = root->GetSyntheticValue();
2409 if (child_valobj_sp.get())
2410 child_valobj_sp =
2411 child_valobj_sp->GetChildMemberWithName(child_name, true);
2412 }
2413 break;
2414 }
2415 }
2416
2417 // if we are here and options.m_no_synthetic_children is true,
Adrian Prantl05097242018-04-30 16:49:04 +00002418 // child_valobj_sp is going to be a NULL SP, so we hit the "else"
2419 // branch, and return an error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002420 if (child_valobj_sp.get()) // if it worked, move on
2421 {
2422 root = child_valobj_sp;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002423 remainder = next_separator;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002424 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2425 continue;
2426 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002427 *reason_to_stop =
2428 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2429 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002430 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002431 }
2432 }
2433 break;
2434 }
2435 case '[': {
2436 if (!root_compiler_type_info.Test(eTypeIsArray) &&
2437 !root_compiler_type_info.Test(eTypeIsPointer) &&
2438 !root_compiler_type_info.Test(
2439 eTypeIsVector)) // if this is not a T[] nor a T*
2440 {
2441 if (!root_compiler_type_info.Test(
2442 eTypeIsScalar)) // if this is not even a scalar...
2443 {
2444 if (options.m_synthetic_children_traversal ==
2445 GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2446 None) // ...only chance left is synthetic
2447 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002448 *reason_to_stop =
2449 ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
2450 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2451 return ValueObjectSP();
2452 }
2453 } else if (!options.m_allow_bitfields_syntax) // if this is a scalar,
2454 // check that we can
2455 // expand bitfields
2456 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002457 *reason_to_stop =
2458 ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
2459 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2460 return ValueObjectSP();
2461 }
2462 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002463 if (temp_expression[1] ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002464 ']') // if this is an unbounded range it only works for arrays
2465 {
2466 if (!root_compiler_type_info.Test(eTypeIsArray)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002467 *reason_to_stop =
2468 ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2469 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002470 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002471 } else // even if something follows, we cannot expand unbounded ranges,
2472 // just let the caller do it
2473 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002474 *reason_to_stop =
2475 ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2476 *final_result =
2477 ValueObject::eExpressionPathEndResultTypeUnboundedRange;
2478 return root;
2479 }
2480 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002481
2482 size_t close_bracket_position = temp_expression.find(']', 1);
2483 if (close_bracket_position ==
2484 llvm::StringRef::npos) // if there is no ], this is a syntax error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002485 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002486 *reason_to_stop =
2487 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2488 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002489 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002490 }
Zachary Turnerc2d55582016-11-18 03:51:19 +00002491
Zachary Turnerd2daca72016-11-18 17:55:04 +00002492 llvm::StringRef bracket_expr =
2493 temp_expression.slice(1, close_bracket_position);
2494
2495 // If this was an empty expression it would have been caught by the if
2496 // above.
2497 assert(!bracket_expr.empty());
2498
2499 if (!bracket_expr.contains('-')) {
Adrian Prantl05097242018-04-30 16:49:04 +00002500 // if no separator, this is of the form [N]. Note that this cannot be
2501 // an unbounded range of the form [], because that case was handled
Zachary Turnerc2d55582016-11-18 03:51:19 +00002502 // above with an unconditional return.
Zachary Turnerd2daca72016-11-18 17:55:04 +00002503 unsigned long index = 0;
2504 if (bracket_expr.getAsInteger(0, index)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002505 *reason_to_stop =
2506 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2507 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002508 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002509 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002510
Kate Stoneb9c1b512016-09-06 20:57:50 +00002511 // from here on we do have a valid index
2512 if (root_compiler_type_info.Test(eTypeIsArray)) {
2513 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2514 if (!child_valobj_sp)
2515 child_valobj_sp = root->GetSyntheticArrayMember(index, true);
2516 if (!child_valobj_sp)
2517 if (root->HasSyntheticValue() &&
2518 root->GetSyntheticValue()->GetNumChildren() > index)
2519 child_valobj_sp =
2520 root->GetSyntheticValue()->GetChildAtIndex(index, true);
2521 if (child_valobj_sp) {
2522 root = child_valobj_sp;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002523 remainder =
2524 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002525 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2526 continue;
2527 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002528 *reason_to_stop =
2529 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2530 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002531 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002532 }
2533 } else if (root_compiler_type_info.Test(eTypeIsPointer)) {
2534 if (*what_next ==
2535 ValueObject::
2536 eExpressionPathAftermathDereference && // if this is a
2537 // ptr-to-scalar, I
2538 // am accessing it
2539 // by index and I
2540 // would have
2541 // deref'ed anyway,
2542 // then do it now
2543 // and use this as
2544 // a bitfield
2545 pointee_compiler_type_info.Test(eTypeIsScalar)) {
Zachary Turner97206d52017-05-12 04:51:55 +00002546 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002547 root = root->Dereference(error);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002548 if (error.Fail() || !root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002549 *reason_to_stop =
2550 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2551 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002552 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002553 } else {
2554 *what_next = eExpressionPathAftermathNothing;
2555 continue;
2556 }
2557 } else {
2558 if (root->GetCompilerType().GetMinimumLanguage() ==
2559 eLanguageTypeObjC &&
2560 pointee_compiler_type_info.AllClear(eTypeIsPointer) &&
2561 root->HasSyntheticValue() &&
2562 (options.m_synthetic_children_traversal ==
2563 GetValueForExpressionPathOptions::
2564 SyntheticChildrenTraversal::ToSynthetic ||
2565 options.m_synthetic_children_traversal ==
2566 GetValueForExpressionPathOptions::
2567 SyntheticChildrenTraversal::Both)) {
2568 root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
2569 } else
2570 root = root->GetSyntheticArrayMember(index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002571 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002572 *reason_to_stop =
2573 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2574 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002575 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002576 } else {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002577 remainder =
2578 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002579 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2580 continue;
2581 }
2582 }
2583 } else if (root_compiler_type_info.Test(eTypeIsScalar)) {
2584 root = root->GetSyntheticBitFieldChild(index, index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002585 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002586 *reason_to_stop =
2587 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2588 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002589 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002590 } else // we do not know how to expand members of bitfields, so we
2591 // just return and let the caller do any further processing
2592 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002593 *reason_to_stop = ValueObject::
2594 eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2595 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2596 return root;
2597 }
2598 } else if (root_compiler_type_info.Test(eTypeIsVector)) {
2599 root = root->GetChildAtIndex(index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002600 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002601 *reason_to_stop =
2602 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2603 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2604 return ValueObjectSP();
2605 } else {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002606 remainder =
2607 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002608 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2609 continue;
2610 }
2611 } else if (options.m_synthetic_children_traversal ==
2612 GetValueForExpressionPathOptions::
2613 SyntheticChildrenTraversal::ToSynthetic ||
2614 options.m_synthetic_children_traversal ==
2615 GetValueForExpressionPathOptions::
2616 SyntheticChildrenTraversal::Both) {
2617 if (root->HasSyntheticValue())
2618 root = root->GetSyntheticValue();
2619 else if (!root->IsSynthetic()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002620 *reason_to_stop =
2621 ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2622 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002623 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002624 }
Adrian Prantl05097242018-04-30 16:49:04 +00002625 // if we are here, then root itself is a synthetic VO.. should be
2626 // good to go
Kate Stoneb9c1b512016-09-06 20:57:50 +00002627
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002628 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002629 *reason_to_stop =
2630 ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2631 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002632 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002633 }
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;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002639 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002640 } 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 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002647 *reason_to_stop =
2648 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2649 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002650 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002651 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002652 } else {
2653 // we have a low and a high index
2654 llvm::StringRef sleft, sright;
2655 unsigned long low_index, high_index;
2656 std::tie(sleft, sright) = bracket_expr.split('-');
2657 if (sleft.getAsInteger(0, low_index) ||
2658 sright.getAsInteger(0, high_index)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002659 *reason_to_stop =
2660 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2661 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002662 return nullptr;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002663 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002664
2665 if (low_index > high_index) // swap indices if required
2666 std::swap(low_index, high_index);
Zachary Turnerc2d55582016-11-18 03:51:19 +00002667
Kate Stoneb9c1b512016-09-06 20:57:50 +00002668 if (root_compiler_type_info.Test(
2669 eTypeIsScalar)) // expansion only works for scalars
2670 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002671 root = root->GetSyntheticBitFieldChild(low_index, high_index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002672 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002673 *reason_to_stop =
2674 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2675 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002676 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002677 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002678 *reason_to_stop = ValueObject::
2679 eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2680 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2681 return root;
2682 }
2683 } else if (root_compiler_type_info.Test(
2684 eTypeIsPointer) && // if this is a ptr-to-scalar, I am
2685 // accessing it by index and I would
2686 // have deref'ed anyway, then do it
2687 // now and use this as a bitfield
2688 *what_next ==
2689 ValueObject::eExpressionPathAftermathDereference &&
2690 pointee_compiler_type_info.Test(eTypeIsScalar)) {
Zachary Turner97206d52017-05-12 04:51:55 +00002691 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002692 root = root->Dereference(error);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002693 if (error.Fail() || !root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002694 *reason_to_stop =
2695 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2696 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002697 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002698 } else {
2699 *what_next = ValueObject::eExpressionPathAftermathNothing;
2700 continue;
2701 }
2702 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002703 *reason_to_stop =
2704 ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2705 *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
2706 return root;
2707 }
2708 }
2709 break;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002710 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002711 default: // some non-separator is in the way
2712 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002713 *reason_to_stop =
2714 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2715 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002716 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002717 }
2718 }
2719 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002720}
2721
Kate Stoneb9c1b512016-09-06 20:57:50 +00002722void ValueObject::LogValueObject(Log *log) {
2723 if (log)
2724 return LogValueObject(log, DumpValueObjectOptions(*this));
Enrico Granata538a88a2014-10-09 18:24:30 +00002725}
2726
Kate Stoneb9c1b512016-09-06 20:57:50 +00002727void ValueObject::LogValueObject(Log *log,
2728 const DumpValueObjectOptions &options) {
2729 if (log) {
2730 StreamString s;
2731 Dump(s, options);
2732 if (s.GetSize())
2733 log->PutCString(s.GetData());
2734 }
Greg Clayton759e7442014-07-19 00:12:57 +00002735}
2736
Kate Stoneb9c1b512016-09-06 20:57:50 +00002737void ValueObject::Dump(Stream &s) { Dump(s, DumpValueObjectOptions(*this)); }
Chaoren Lind7bdc272015-07-31 00:35:40 +00002738
Kate Stoneb9c1b512016-09-06 20:57:50 +00002739void ValueObject::Dump(Stream &s, const DumpValueObjectOptions &options) {
2740 ValueObjectPrinter printer(this, &s, options);
2741 printer.PrintValueObject();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002742}
2743
Kate Stoneb9c1b512016-09-06 20:57:50 +00002744ValueObjectSP ValueObject::CreateConstantValue(const ConstString &name) {
2745 ValueObjectSP valobj_sp;
2746
2747 if (UpdateValueIfNeeded(false) && m_error.Success()) {
2748 ExecutionContext exe_ctx(GetExecutionContextRef());
2749
2750 DataExtractor data;
2751 data.SetByteOrder(m_data.GetByteOrder());
2752 data.SetAddressByteSize(m_data.GetAddressByteSize());
2753
2754 if (IsBitfield()) {
2755 Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
2756 m_error = v.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
2757 } else
2758 m_error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
2759
2760 valobj_sp = ValueObjectConstResult::Create(
2761 exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,
2762 GetAddressOf());
2763 }
2764
2765 if (!valobj_sp) {
2766 ExecutionContext exe_ctx(GetExecutionContextRef());
2767 valobj_sp = ValueObjectConstResult::Create(
2768 exe_ctx.GetBestExecutionContextScope(), m_error);
2769 }
2770 return valobj_sp;
2771}
2772
2773ValueObjectSP ValueObject::GetQualifiedRepresentationIfAvailable(
2774 lldb::DynamicValueType dynValue, bool synthValue) {
2775 ValueObjectSP result_sp(GetSP());
2776
2777 switch (dynValue) {
2778 case lldb::eDynamicCanRunTarget:
2779 case lldb::eDynamicDontRunTarget: {
2780 if (!result_sp->IsDynamic()) {
2781 if (result_sp->GetDynamicValue(dynValue))
2782 result_sp = result_sp->GetDynamicValue(dynValue);
2783 }
2784 } break;
2785 case lldb::eNoDynamicValues: {
2786 if (result_sp->IsDynamic()) {
2787 if (result_sp->GetStaticValue())
2788 result_sp = result_sp->GetStaticValue();
2789 }
2790 } break;
2791 }
2792
2793 if (synthValue) {
2794 if (!result_sp->IsSynthetic()) {
2795 if (result_sp->GetSyntheticValue())
2796 result_sp = result_sp->GetSyntheticValue();
2797 }
2798 } else {
2799 if (result_sp->IsSynthetic()) {
2800 if (result_sp->GetNonSyntheticValue())
2801 result_sp = result_sp->GetNonSyntheticValue();
2802 }
2803 }
2804
2805 return result_sp;
2806}
2807
2808lldb::addr_t ValueObject::GetCPPVTableAddress(AddressType &address_type) {
2809 CompilerType pointee_type;
2810 CompilerType this_type(GetCompilerType());
2811 uint32_t type_info = this_type.GetTypeInfo(&pointee_type);
2812 if (type_info) {
2813 bool ptr_or_ref = false;
2814 if (type_info & (eTypeIsPointer | eTypeIsReference)) {
2815 ptr_or_ref = true;
2816 type_info = pointee_type.GetTypeInfo();
2817 }
2818
2819 const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus;
2820 if ((type_info & cpp_class) == cpp_class) {
2821 if (ptr_or_ref) {
2822 address_type = GetAddressTypeOfChildren();
2823 return GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
2824 } else
2825 return GetAddressOf(false, &address_type);
2826 }
2827 }
2828
2829 address_type = eAddressTypeInvalid;
2830 return LLDB_INVALID_ADDRESS;
2831}
2832
Zachary Turner97206d52017-05-12 04:51:55 +00002833ValueObjectSP ValueObject::Dereference(Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002834 if (m_deref_valobj)
2835 return m_deref_valobj->GetSP();
2836
2837 const bool is_pointer_or_reference_type = IsPointerOrReferenceType();
2838 if (is_pointer_or_reference_type) {
2839 bool omit_empty_base_classes = true;
2840 bool ignore_array_bounds = false;
2841
2842 std::string child_name_str;
2843 uint32_t child_byte_size = 0;
2844 int32_t child_byte_offset = 0;
2845 uint32_t child_bitfield_bit_size = 0;
2846 uint32_t child_bitfield_bit_offset = 0;
2847 bool child_is_base_class = false;
2848 bool child_is_deref_of_parent = false;
2849 const bool transparent_pointers = false;
2850 CompilerType compiler_type = GetCompilerType();
2851 CompilerType child_compiler_type;
2852 uint64_t language_flags;
2853
2854 ExecutionContext exe_ctx(GetExecutionContextRef());
2855
2856 child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex(
2857 &exe_ctx, 0, transparent_pointers, omit_empty_base_classes,
2858 ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
2859 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
2860 child_is_deref_of_parent, this, language_flags);
2861 if (child_compiler_type && child_byte_size) {
2862 ConstString child_name;
2863 if (!child_name_str.empty())
2864 child_name.SetCString(child_name_str.c_str());
2865
2866 m_deref_valobj = new ValueObjectChild(
2867 *this, child_compiler_type, child_name, child_byte_size,
2868 child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
2869 child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
2870 language_flags);
2871 }
Tamas Berghammer4c08fe22017-03-31 20:23:22 +00002872 } else if (HasSyntheticValue()) {
2873 m_deref_valobj =
2874 GetSyntheticValue()
2875 ->GetChildMemberWithName(ConstString("$$dereference$$"), true)
2876 .get();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002877 }
2878
2879 if (m_deref_valobj) {
Greg Clayton54979cd2010-12-15 05:08:08 +00002880 error.Clear();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002881 return m_deref_valobj->GetSP();
2882 } else {
2883 StreamString strm;
2884 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002885
Kate Stoneb9c1b512016-09-06 20:57:50 +00002886 if (is_pointer_or_reference_type)
2887 error.SetErrorStringWithFormat("dereference failed: (%s) %s",
2888 GetTypeName().AsCString("<invalid type>"),
Zachary Turnerc1564272016-11-16 21:15:24 +00002889 strm.GetData());
Sean Callananed185ab2013-04-19 19:47:32 +00002890 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00002891 error.SetErrorStringWithFormat("not a pointer or reference type: (%s) %s",
2892 GetTypeName().AsCString("<invalid type>"),
Zachary Turnerc1564272016-11-16 21:15:24 +00002893 strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002894 return ValueObjectSP();
2895 }
2896}
2897
Zachary Turner97206d52017-05-12 04:51:55 +00002898ValueObjectSP ValueObject::AddressOf(Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002899 if (m_addr_of_valobj_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +00002900 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002901
Kate Stoneb9c1b512016-09-06 20:57:50 +00002902 AddressType address_type = eAddressTypeInvalid;
2903 const bool scalar_is_load_address = false;
2904 addr_t addr = GetAddressOf(scalar_is_load_address, &address_type);
2905 error.Clear();
2906 if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {
2907 switch (address_type) {
2908 case eAddressTypeInvalid: {
2909 StreamString expr_path_strm;
2910 GetExpressionPath(expr_path_strm, true);
2911 error.SetErrorStringWithFormat("'%s' is not in memory",
Zachary Turnerc1564272016-11-16 21:15:24 +00002912 expr_path_strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002913 } break;
Greg Claytonb2dcc362011-05-05 23:32:56 +00002914
Kate Stoneb9c1b512016-09-06 20:57:50 +00002915 case eAddressTypeFile:
2916 case eAddressTypeLoad: {
2917 CompilerType compiler_type = GetCompilerType();
2918 if (compiler_type) {
2919 std::string name(1, '&');
2920 name.append(m_name.AsCString(""));
2921 ExecutionContext exe_ctx(GetExecutionContextRef());
2922 m_addr_of_valobj_sp = ValueObjectConstResult::Create(
2923 exe_ctx.GetBestExecutionContextScope(),
2924 compiler_type.GetPointerType(), ConstString(name.c_str()), addr,
2925 eAddressTypeInvalid, m_data.GetAddressByteSize());
2926 }
2927 } break;
2928 default:
2929 break;
Greg Claytonb2dcc362011-05-05 23:32:56 +00002930 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002931 } else {
2932 StreamString expr_path_strm;
2933 GetExpressionPath(expr_path_strm, true);
2934 error.SetErrorStringWithFormat("'%s' doesn't have a valid address",
Zachary Turnerc1564272016-11-16 21:15:24 +00002935 expr_path_strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002936 }
2937
2938 return m_addr_of_valobj_sp;
Greg Claytonb2dcc362011-05-05 23:32:56 +00002939}
2940
Kate Stoneb9c1b512016-09-06 20:57:50 +00002941ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {
2942 return ValueObjectCast::Create(*this, GetName(), compiler_type);
Greg Claytonb2dcc362011-05-05 23:32:56 +00002943}
2944
Tamas Berghammer4fbb55b2017-03-31 20:48:00 +00002945lldb::ValueObjectSP ValueObject::Clone(const ConstString &new_name) {
2946 return ValueObjectCast::Create(*this, new_name, GetCompilerType());
2947}
2948
Kate Stoneb9c1b512016-09-06 20:57:50 +00002949ValueObjectSP ValueObject::CastPointerType(const char *name,
2950 CompilerType &compiler_type) {
2951 ValueObjectSP valobj_sp;
2952 AddressType address_type;
2953 addr_t ptr_value = GetPointerValue(&address_type);
2954
2955 if (ptr_value != LLDB_INVALID_ADDRESS) {
2956 Address ptr_addr(ptr_value);
2957 ExecutionContext exe_ctx(GetExecutionContextRef());
2958 valobj_sp = ValueObjectMemory::Create(
2959 exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, compiler_type);
2960 }
2961 return valobj_sp;
Jim Ingham6035b672011-03-31 00:19:25 +00002962}
2963
Kate Stoneb9c1b512016-09-06 20:57:50 +00002964ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {
2965 ValueObjectSP valobj_sp;
2966 AddressType address_type;
2967 addr_t ptr_value = GetPointerValue(&address_type);
2968
2969 if (ptr_value != LLDB_INVALID_ADDRESS) {
2970 Address ptr_addr(ptr_value);
2971 ExecutionContext exe_ctx(GetExecutionContextRef());
2972 valobj_sp = ValueObjectMemory::Create(
2973 exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, type_sp);
2974 }
2975 return valobj_sp;
2976}
2977
2978ValueObject::EvaluationPoint::EvaluationPoint()
2979 : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {}
2980
2981ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope,
2982 bool use_selected)
2983 : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {
2984 ExecutionContext exe_ctx(exe_scope);
2985 TargetSP target_sp(exe_ctx.GetTargetSP());
2986 if (target_sp) {
2987 m_exe_ctx_ref.SetTargetSP(target_sp);
2988 ProcessSP process_sp(exe_ctx.GetProcessSP());
2989 if (!process_sp)
2990 process_sp = target_sp->GetProcessSP();
2991
2992 if (process_sp) {
2993 m_mod_id = process_sp->GetModID();
2994 m_exe_ctx_ref.SetProcessSP(process_sp);
2995
2996 ThreadSP thread_sp(exe_ctx.GetThreadSP());
2997
2998 if (!thread_sp) {
2999 if (use_selected)
3000 thread_sp = process_sp->GetThreadList().GetSelectedThread();
3001 }
3002
3003 if (thread_sp) {
3004 m_exe_ctx_ref.SetThreadSP(thread_sp);
3005
3006 StackFrameSP frame_sp(exe_ctx.GetFrameSP());
3007 if (!frame_sp) {
3008 if (use_selected)
3009 frame_sp = thread_sp->GetSelectedFrame();
Jim Ingham6035b672011-03-31 00:19:25 +00003010 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003011 if (frame_sp)
3012 m_exe_ctx_ref.SetFrameSP(frame_sp);
3013 }
Jim Ingham6035b672011-03-31 00:19:25 +00003014 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003015 }
Jim Ingham6035b672011-03-31 00:19:25 +00003016}
3017
Kate Stoneb9c1b512016-09-06 20:57:50 +00003018ValueObject::EvaluationPoint::EvaluationPoint(
3019 const ValueObject::EvaluationPoint &rhs)
3020 : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref), m_needs_update(true) {}
Jim Ingham6035b672011-03-31 00:19:25 +00003021
Kate Stoneb9c1b512016-09-06 20:57:50 +00003022ValueObject::EvaluationPoint::~EvaluationPoint() {}
Jim Ingham6035b672011-03-31 00:19:25 +00003023
Kate Stoneb9c1b512016-09-06 20:57:50 +00003024// This function checks the EvaluationPoint against the current process state.
Adrian Prantl05097242018-04-30 16:49:04 +00003025// If the current state matches the evaluation point, or the evaluation point
3026// is already invalid, then we return false, meaning "no change". If the
3027// current state is different, we update our state, and return true meaning
3028// "yes, change". If we did see a change, we also set m_needs_update to true,
3029// so future calls to NeedsUpdate will return true. exe_scope will be set to
3030// the current execution context scope.
Jim Ingham6035b672011-03-31 00:19:25 +00003031
Kate Stoneb9c1b512016-09-06 20:57:50 +00003032bool ValueObject::EvaluationPoint::SyncWithProcessState(
3033 bool accept_invalid_exe_ctx) {
Adrian Prantl05097242018-04-30 16:49:04 +00003034 // Start with the target, if it is NULL, then we're obviously not going to
3035 // get any further:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003036 const bool thread_and_frame_only_if_stopped = true;
3037 ExecutionContext exe_ctx(
3038 m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
3039
3040 if (exe_ctx.GetTargetPtr() == NULL)
3041 return false;
3042
3043 // If we don't have a process nothing can change.
3044 Process *process = exe_ctx.GetProcessPtr();
3045 if (process == NULL)
3046 return false;
3047
3048 // If our stop id is the current stop ID, nothing has changed:
3049 ProcessModID current_mod_id = process->GetModID();
3050
3051 // If the current stop id is 0, either we haven't run yet, or the process
Adrian Prantl05097242018-04-30 16:49:04 +00003052 // state has been cleared. In either case, we aren't going to be able to sync
3053 // with the process state.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003054 if (current_mod_id.GetStopID() == 0)
3055 return false;
3056
3057 bool changed = false;
3058 const bool was_valid = m_mod_id.IsValid();
3059 if (was_valid) {
3060 if (m_mod_id == current_mod_id) {
Adrian Prantl05097242018-04-30 16:49:04 +00003061 // Everything is already up to date in this object, no need to update the
3062 // execution context scope.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003063 changed = false;
3064 } else {
3065 m_mod_id = current_mod_id;
3066 m_needs_update = true;
3067 changed = true;
3068 }
3069 }
3070
3071 // Now re-look up the thread and frame in case the underlying objects have
Adrian Prantl05097242018-04-30 16:49:04 +00003072 // gone away & been recreated. That way we'll be sure to return a valid
3073 // exe_scope. If we used to have a thread or a frame but can't find it
3074 // anymore, then mark ourselves as invalid.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003075
3076 if (!accept_invalid_exe_ctx) {
3077 if (m_exe_ctx_ref.HasThreadRef()) {
3078 ThreadSP thread_sp(m_exe_ctx_ref.GetThreadSP());
3079 if (thread_sp) {
3080 if (m_exe_ctx_ref.HasFrameRef()) {
3081 StackFrameSP frame_sp(m_exe_ctx_ref.GetFrameSP());
3082 if (!frame_sp) {
3083 // We used to have a frame, but now it is gone
3084 SetInvalid();
3085 changed = was_valid;
3086 }
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003087 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003088 } else {
3089 // We used to have a thread, but now it is gone
3090 SetInvalid();
3091 changed = was_valid;
3092 }
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003093 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003094 }
Enrico Granatabb642e52015-05-16 01:27:00 +00003095
Kate Stoneb9c1b512016-09-06 20:57:50 +00003096 return changed;
Jim Ingham6035b672011-03-31 00:19:25 +00003097}
3098
Kate Stoneb9c1b512016-09-06 20:57:50 +00003099void ValueObject::EvaluationPoint::SetUpdated() {
3100 ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
3101 if (process_sp)
3102 m_mod_id = process_sp->GetModID();
3103 m_needs_update = false;
Johnny Chen44805302011-07-19 19:48:13 +00003104}
Enrico Granata9128ee22011-09-06 19:20:51 +00003105
Kate Stoneb9c1b512016-09-06 20:57:50 +00003106void ValueObject::ClearUserVisibleData(uint32_t clear_mask) {
3107 if ((clear_mask & eClearUserVisibleDataItemsValue) ==
3108 eClearUserVisibleDataItemsValue)
3109 m_value_str.clear();
3110
3111 if ((clear_mask & eClearUserVisibleDataItemsLocation) ==
3112 eClearUserVisibleDataItemsLocation)
3113 m_location_str.clear();
3114
3115 if ((clear_mask & eClearUserVisibleDataItemsSummary) ==
3116 eClearUserVisibleDataItemsSummary)
3117 m_summary_str.clear();
3118
3119 if ((clear_mask & eClearUserVisibleDataItemsDescription) ==
3120 eClearUserVisibleDataItemsDescription)
3121 m_object_desc_str.clear();
3122
3123 if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) ==
3124 eClearUserVisibleDataItemsSyntheticChildren) {
3125 if (m_synthetic_value)
3126 m_synthetic_value = NULL;
3127 }
3128
3129 if ((clear_mask & eClearUserVisibleDataItemsValidator) ==
3130 eClearUserVisibleDataItemsValidator)
3131 m_validation_result.reset();
Enrico Granata9128ee22011-09-06 19:20:51 +00003132}
Enrico Granatab2698cd2012-09-13 18:27:09 +00003133
Kate Stoneb9c1b512016-09-06 20:57:50 +00003134SymbolContextScope *ValueObject::GetSymbolContextScope() {
3135 if (m_parent) {
3136 if (!m_parent->IsPointerOrReferenceType())
3137 return m_parent->GetSymbolContextScope();
3138 }
3139 return NULL;
Enrico Granata972be532014-12-17 21:18:43 +00003140}
3141
Zachary Turneraa5611f2016-11-13 03:29:46 +00003142lldb::ValueObjectSP
3143ValueObject::CreateValueObjectFromExpression(llvm::StringRef name,
3144 llvm::StringRef expression,
3145 const ExecutionContext &exe_ctx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003146 return CreateValueObjectFromExpression(name, expression, exe_ctx,
3147 EvaluateExpressionOptions());
3148}
Enrico Granata972be532014-12-17 21:18:43 +00003149
Kate Stoneb9c1b512016-09-06 20:57:50 +00003150lldb::ValueObjectSP ValueObject::CreateValueObjectFromExpression(
Zachary Turneraa5611f2016-11-13 03:29:46 +00003151 llvm::StringRef name, llvm::StringRef expression,
3152 const ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003153 lldb::ValueObjectSP retval_sp;
3154 lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
3155 if (!target_sp)
Enrico Granatab2698cd2012-09-13 18:27:09 +00003156 return retval_sp;
Zachary Turneraa5611f2016-11-13 03:29:46 +00003157 if (expression.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003158 return retval_sp;
3159 target_sp->EvaluateExpression(expression, exe_ctx.GetFrameSP().get(),
3160 retval_sp, options);
Zachary Turneraa5611f2016-11-13 03:29:46 +00003161 if (retval_sp && !name.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003162 retval_sp->SetName(ConstString(name));
3163 return retval_sp;
Enrico Granatab2698cd2012-09-13 18:27:09 +00003164}
3165
Zachary Turneraa5611f2016-11-13 03:29:46 +00003166lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress(
3167 llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
3168 CompilerType type) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003169 if (type) {
3170 CompilerType pointer_type(type.GetPointerType());
3171 if (pointer_type) {
3172 lldb::DataBufferSP buffer(
3173 new lldb_private::DataBufferHeap(&address, sizeof(lldb::addr_t)));
3174 lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(
3175 exe_ctx.GetBestExecutionContextScope(), pointer_type,
3176 ConstString(name), buffer, exe_ctx.GetByteOrder(),
3177 exe_ctx.GetAddressByteSize()));
3178 if (ptr_result_valobj_sp) {
3179 ptr_result_valobj_sp->GetValue().SetValueType(
3180 Value::eValueTypeLoadAddress);
Zachary Turner97206d52017-05-12 04:51:55 +00003181 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003182 ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
Zachary Turneraa5611f2016-11-13 03:29:46 +00003183 if (ptr_result_valobj_sp && !name.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003184 ptr_result_valobj_sp->SetName(ConstString(name));
3185 }
3186 return ptr_result_valobj_sp;
Enrico Granatab2698cd2012-09-13 18:27:09 +00003187 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003188 }
3189 return lldb::ValueObjectSP();
Enrico Granatab2698cd2012-09-13 18:27:09 +00003190}
3191
Kate Stoneb9c1b512016-09-06 20:57:50 +00003192lldb::ValueObjectSP ValueObject::CreateValueObjectFromData(
Zachary Turneraa5611f2016-11-13 03:29:46 +00003193 llvm::StringRef name, const DataExtractor &data,
Kate Stoneb9c1b512016-09-06 20:57:50 +00003194 const ExecutionContext &exe_ctx, CompilerType type) {
3195 lldb::ValueObjectSP new_value_sp;
3196 new_value_sp = ValueObjectConstResult::Create(
3197 exe_ctx.GetBestExecutionContextScope(), type, ConstString(name), data,
3198 LLDB_INVALID_ADDRESS);
3199 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
Zachary Turneraa5611f2016-11-13 03:29:46 +00003200 if (new_value_sp && !name.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003201 new_value_sp->SetName(ConstString(name));
3202 return new_value_sp;
Enrico Granatab2698cd2012-09-13 18:27:09 +00003203}
Enrico Granata4873e522013-04-11 22:48:58 +00003204
Kate Stoneb9c1b512016-09-06 20:57:50 +00003205ModuleSP ValueObject::GetModule() {
3206 ValueObject *root(GetRoot());
3207 if (root != this)
3208 return root->GetModule();
3209 return lldb::ModuleSP();
3210}
3211
3212ValueObject *ValueObject::GetRoot() {
3213 if (m_root)
3214 return m_root;
3215 return (m_root = FollowParentChain([](ValueObject *vo) -> bool {
3216 return (vo->m_parent != nullptr);
3217 }));
3218}
3219
3220ValueObject *
3221ValueObject::FollowParentChain(std::function<bool(ValueObject *)> f) {
3222 ValueObject *vo = this;
3223 while (vo) {
3224 if (f(vo) == false)
3225 break;
3226 vo = vo->m_parent;
3227 }
3228 return vo;
3229}
3230
3231AddressType ValueObject::GetAddressTypeOfChildren() {
3232 if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) {
3233 ValueObject *root(GetRoot());
Enrico Granata4873e522013-04-11 22:48:58 +00003234 if (root != this)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003235 return root->GetAddressTypeOfChildren();
3236 }
3237 return m_address_type_of_ptr_or_ref_children;
Enrico Granata4873e522013-04-11 22:48:58 +00003238}
3239
Kate Stoneb9c1b512016-09-06 20:57:50 +00003240lldb::DynamicValueType ValueObject::GetDynamicValueType() {
3241 ValueObject *with_dv_info = this;
3242 while (with_dv_info) {
3243 if (with_dv_info->HasDynamicValueTypeInfo())
3244 return with_dv_info->GetDynamicValueTypeImpl();
3245 with_dv_info = with_dv_info->m_parent;
3246 }
3247 return lldb::eNoDynamicValues;
Enrico Granatade61eba2015-01-22 03:07:34 +00003248}
3249
Kate Stoneb9c1b512016-09-06 20:57:50 +00003250lldb::Format ValueObject::GetFormat() const {
3251 const ValueObject *with_fmt_info = this;
3252 while (with_fmt_info) {
3253 if (with_fmt_info->m_format != lldb::eFormatDefault)
3254 return with_fmt_info->m_format;
3255 with_fmt_info = with_fmt_info->m_parent;
3256 }
3257 return m_format;
Enrico Granata4873e522013-04-11 22:48:58 +00003258}
3259
Kate Stoneb9c1b512016-09-06 20:57:50 +00003260lldb::LanguageType ValueObject::GetPreferredDisplayLanguage() {
3261 lldb::LanguageType type = m_preferred_display_language;
3262 if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
3263 if (GetRoot()) {
3264 if (GetRoot() == this) {
3265 if (StackFrameSP frame_sp = GetFrameSP()) {
3266 const SymbolContext &sc(
3267 frame_sp->GetSymbolContext(eSymbolContextCompUnit));
3268 if (CompileUnit *cu = sc.comp_unit)
3269 type = cu->GetLanguage();
Enrico Granatac1247f52014-11-06 21:23:20 +00003270 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003271 } else {
3272 type = GetRoot()->GetPreferredDisplayLanguage();
3273 }
Enrico Granatac1247f52014-11-06 21:23:20 +00003274 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003275 }
3276 return (m_preferred_display_language = type); // only compute it once
Enrico Granataed3228a2015-01-21 01:47:13 +00003277}
3278
Kate Stoneb9c1b512016-09-06 20:57:50 +00003279void ValueObject::SetPreferredDisplayLanguage(lldb::LanguageType lt) {
3280 m_preferred_display_language = lt;
Enrico Granatac1247f52014-11-06 21:23:20 +00003281}
3282
Kate Stoneb9c1b512016-09-06 20:57:50 +00003283void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {
3284 if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
3285 SetPreferredDisplayLanguage(lt);
Enrico Granata73e8c4d2015-10-07 02:36:35 +00003286}
3287
Kate Stoneb9c1b512016-09-06 20:57:50 +00003288bool ValueObject::CanProvideValue() {
Adrian Prantl05097242018-04-30 16:49:04 +00003289 // we need to support invalid types as providers of values because some bare-
3290 // board debugging scenarios have no notion of types, but still manage to
3291 // have raw numeric values for things like registers. sigh.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003292 const CompilerType &type(GetCompilerType());
3293 return (false == type.IsValid()) ||
3294 (0 != (type.GetTypeInfo() & eTypeHasValue));
Sean Callanan7375f3e2014-12-09 21:18:59 +00003295}
3296
Kate Stoneb9c1b512016-09-06 20:57:50 +00003297bool ValueObject::IsChecksumEmpty() { return m_value_checksum.empty(); }
3298
3299ValueObjectSP ValueObject::Persist() {
3300 if (!UpdateValueIfNeeded())
3301 return nullptr;
3302
3303 TargetSP target_sp(GetTargetSP());
3304 if (!target_sp)
3305 return nullptr;
3306
3307 PersistentExpressionState *persistent_state =
3308 target_sp->GetPersistentExpressionStateForLanguage(
3309 GetPreferredDisplayLanguage());
3310
3311 if (!persistent_state)
3312 return nullptr;
3313
Adrian Prantl03219f72018-04-30 23:59:17 +00003314 auto prefix = persistent_state->GetPersistentVariablePrefix();
3315 ConstString name =
3316 persistent_state->GetNextPersistentVariableName(*target_sp, prefix);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003317
3318 ValueObjectSP const_result_sp =
3319 ValueObjectConstResult::Create(target_sp.get(), GetValue(), name);
3320
3321 ExpressionVariableSP clang_var_sp =
3322 persistent_state->CreatePersistentVariable(const_result_sp);
3323 clang_var_sp->m_live_sp = clang_var_sp->m_frozen_sp;
3324 clang_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference;
3325
3326 return clang_var_sp->GetValueObject();
Enrico Granatad07cfd32014-10-08 18:27:36 +00003327}
Enrico Granata0c10a852014-12-08 23:13:56 +00003328
Kate Stoneb9c1b512016-09-06 20:57:50 +00003329bool ValueObject::IsSyntheticChildrenGenerated() {
3330 return m_is_synthetic_children_generated;
Enrico Granata0c10a852014-12-08 23:13:56 +00003331}
Enrico Granatae29df232014-12-09 19:51:20 +00003332
Kate Stoneb9c1b512016-09-06 20:57:50 +00003333void ValueObject::SetSyntheticChildrenGenerated(bool b) {
3334 m_is_synthetic_children_generated = b;
Enrico Granatae29df232014-12-09 19:51:20 +00003335}
3336
Kate Stoneb9c1b512016-09-06 20:57:50 +00003337uint64_t ValueObject::GetLanguageFlags() { return m_language_flags; }
Enrico Granatadc62ffd2015-11-09 19:27:34 +00003338
Kate Stoneb9c1b512016-09-06 20:57:50 +00003339void ValueObject::SetLanguageFlags(uint64_t flags) { m_language_flags = flags; }
Greg Clayton8369b282016-12-28 21:22:37 +00003340
3341ValueObjectManager::ValueObjectManager(lldb::ValueObjectSP in_valobj_sp,
3342 lldb::DynamicValueType use_dynamic,
3343 bool use_synthetic) : m_root_valobj_sp(),
3344 m_user_valobj_sp(), m_use_dynamic(use_dynamic), m_stop_id(UINT32_MAX),
3345 m_use_synthetic(use_synthetic) {
3346 if (!in_valobj_sp)
3347 return;
3348 // If the user passes in a value object that is dynamic or synthetic, then
3349 // water it down to the static type.
3350 m_root_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(lldb::eNoDynamicValues, false);
3351}
3352
3353bool ValueObjectManager::IsValid() const {
3354 if (!m_root_valobj_sp)
3355 return false;
3356 lldb::TargetSP target_sp = GetTargetSP();
3357 if (target_sp)
3358 return target_sp->IsValid();
3359 return false;
3360}
3361
3362lldb::ValueObjectSP ValueObjectManager::GetSP() {
3363 lldb::ProcessSP process_sp = GetProcessSP();
3364 if (!process_sp)
3365 return lldb::ValueObjectSP();
3366
3367 const uint32_t current_stop_id = process_sp->GetLastNaturalStopID();
3368 if (current_stop_id == m_stop_id)
3369 return m_user_valobj_sp;
3370
3371 m_stop_id = current_stop_id;
3372
3373 if (!m_root_valobj_sp) {
3374 m_user_valobj_sp.reset();
3375 return m_root_valobj_sp;
3376 }
3377
3378 m_user_valobj_sp = m_root_valobj_sp;
3379
3380 if (m_use_dynamic != lldb::eNoDynamicValues) {
3381 lldb::ValueObjectSP dynamic_sp = m_user_valobj_sp->GetDynamicValue(m_use_dynamic);
3382 if (dynamic_sp)
3383 m_user_valobj_sp = dynamic_sp;
3384 }
3385
3386 if (m_use_synthetic) {
3387 lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(m_use_synthetic);
3388 if (synthetic_sp)
3389 m_user_valobj_sp = synthetic_sp;
3390 }
3391
3392 return m_user_valobj_sp;
3393}
3394
3395void ValueObjectManager::SetUseDynamic(lldb::DynamicValueType use_dynamic) {
3396 if (use_dynamic != m_use_dynamic) {
3397 m_use_dynamic = use_dynamic;
3398 m_user_valobj_sp.reset();
3399 m_stop_id = UINT32_MAX;
3400 }
3401}
3402
3403void ValueObjectManager::SetUseSynthetic(bool use_synthetic) {
3404 if (m_use_synthetic != use_synthetic) {
3405 m_use_synthetic = use_synthetic;
3406 m_user_valobj_sp.reset();
3407 m_stop_id = UINT32_MAX;
3408 }
3409}
3410
3411lldb::TargetSP ValueObjectManager::GetTargetSP() const {
3412 if (!m_root_valobj_sp)
3413 return m_root_valobj_sp->GetTargetSP();
3414 return lldb::TargetSP();
3415}
3416
3417lldb::ProcessSP ValueObjectManager::GetProcessSP() const {
3418 if (m_root_valobj_sp)
3419 return m_root_valobj_sp->GetProcessSP();
3420 return lldb::ProcessSP();
3421}
3422
3423lldb::ThreadSP ValueObjectManager::GetThreadSP() const {
3424 if (m_root_valobj_sp)
3425 return m_root_valobj_sp->GetThreadSP();
3426 return lldb::ThreadSP();
3427}
3428
3429lldb::StackFrameSP ValueObjectManager::GetFrameSP() const {
3430 if (m_root_valobj_sp)
3431 return m_root_valobj_sp->GetFrameSP();
3432 return lldb::StackFrameSP();
3433}
3434