blob: 1d9d7d495432a38576cfb762f543a1841c6a9394 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ValueObject.cpp -----------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Core/ValueObject.h"
10
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000011#include "lldb/Core/Address.h"
Greg Clayton1f746072012-08-29 21:13:06 +000012#include "lldb/Core/Module.h"
Enrico Granata21fd13f2012-10-27 02:05:48 +000013#include "lldb/Core/ValueObjectCast.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014#include "lldb/Core/ValueObjectChild.h"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000015#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000016#include "lldb/Core/ValueObjectDynamicValue.h"
Greg Claytonb2dcc362011-05-05 23:32:56 +000017#include "lldb/Core/ValueObjectMemory.h"
Enrico Granatad55546b2011-07-22 00:16:08 +000018#include "lldb/Core/ValueObjectSyntheticFilter.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000019#include "lldb/DataFormatters/DataVisualization.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000020#include "lldb/DataFormatters/DumpValueObjectOptions.h"
21#include "lldb/DataFormatters/FormatManager.h"
Enrico Granata2206b482014-10-30 18:27:31 +000022#include "lldb/DataFormatters/StringPrinter.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000023#include "lldb/DataFormatters/TypeFormat.h"
24#include "lldb/DataFormatters/TypeSummary.h"
25#include "lldb/DataFormatters/TypeValidator.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000026#include "lldb/DataFormatters/ValueObjectPrinter.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000027#include "lldb/Expression/ExpressionVariable.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Symbol/ClangASTContext.h"
Enrico Granatac1247f52014-11-06 21:23:20 +000029#include "lldb/Symbol/CompileUnit.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000030#include "lldb/Symbol/CompilerType.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000031#include "lldb/Symbol/Declaration.h"
32#include "lldb/Symbol/SymbolContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Symbol/Type.h"
Jim Ingham53c47f12010-09-10 23:12:17 +000034#include "lldb/Target/ExecutionContext.h"
Enrico Granata407b5c62015-11-02 21:52:05 +000035#include "lldb/Target/Language.h"
Jim Ingham5a369122010-09-28 01:25:32 +000036#include "lldb/Target/LanguageRuntime.h"
Enrico Granatac3e320a2011-08-02 17:27:39 +000037#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038#include "lldb/Target/Process.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000039#include "lldb/Target/StackFrame.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000040#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041#include "lldb/Target/Thread.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000042#include "lldb/Target/ThreadList.h"
43#include "lldb/Utility/DataBuffer.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000044#include "lldb/Utility/DataBufferHeap.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000045#include "lldb/Utility/Flags.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000046#include "lldb/Utility/Log.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000047#include "lldb/Utility/Logging.h"
48#include "lldb/Utility/Scalar.h"
49#include "lldb/Utility/SharingPtr.h"
50#include "lldb/Utility/Stream.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000051#include "lldb/Utility/StreamString.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000052#include "lldb/lldb-private-types.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000053
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000054#include "llvm/Support/Compiler.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000055
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000056#include <algorithm>
57#include <cstdint>
58#include <cstdlib>
59#include <memory>
60#include <tuple>
Zachary Turner2f3df612017-04-06 21:28:29 +000061
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000062#include <assert.h>
63#include <inttypes.h>
64#include <stdio.h>
65#include <string.h>
Zachary Turner2f3df612017-04-06 21:28:29 +000066
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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080// ValueObject constructor
Kate Stoneb9c1b512016-09-06 20:57:50 +000081ValueObject::ValueObject(ValueObject &parent)
82 : UserID(++g_value_obj_uid), // Unique identifier for every value object
83 m_parent(&parent), m_root(NULL), m_update_point(parent.GetUpdatePoint()),
84 m_name(), m_data(), m_value(), m_error(), m_value_str(),
85 m_old_value_str(), m_location_str(), m_summary_str(), m_object_desc_str(),
86 m_validation_result(), m_manager(parent.GetManager()), m_children(),
87 m_synthetic_children(), m_dynamic_value(NULL), m_synthetic_value(NULL),
88 m_deref_valobj(NULL), m_format(eFormatDefault),
89 m_last_format(eFormatDefault), m_last_format_mgr_revision(0),
90 m_type_summary_sp(), m_type_format_sp(), m_synthetic_children_sp(),
91 m_type_validator_sp(), m_user_id_of_forced_summary(),
92 m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid),
93 m_value_checksum(),
94 m_preferred_display_language(lldb::eLanguageTypeUnknown),
95 m_language_flags(0), m_value_is_valid(false), m_value_did_change(false),
96 m_children_count_valid(false), m_old_value_valid(false),
97 m_is_deref_of_parent(false), m_is_array_item_for_pointer(false),
98 m_is_bitfield_for_scalar(false), m_is_child_at_offset(false),
99 m_is_getting_summary(false),
100 m_did_calculate_complete_objc_class_type(false),
101 m_is_synthetic_children_generated(
102 parent.m_is_synthetic_children_generated) {
103 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +0000104}
105
Jim Ingham6035b672011-03-31 00:19:25 +0000106// ValueObject constructor
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107ValueObject::ValueObject(ExecutionContextScope *exe_scope,
108 AddressType child_ptr_or_ref_addr_type)
109 : UserID(++g_value_obj_uid), // Unique identifier for every value object
110 m_parent(NULL), m_root(NULL), m_update_point(exe_scope), m_name(),
111 m_data(), m_value(), m_error(), m_value_str(), m_old_value_str(),
112 m_location_str(), m_summary_str(), m_object_desc_str(),
113 m_validation_result(), m_manager(), m_children(), m_synthetic_children(),
114 m_dynamic_value(NULL), m_synthetic_value(NULL), m_deref_valobj(NULL),
115 m_format(eFormatDefault), m_last_format(eFormatDefault),
116 m_last_format_mgr_revision(0), m_type_summary_sp(), m_type_format_sp(),
117 m_synthetic_children_sp(), m_type_validator_sp(),
118 m_user_id_of_forced_summary(),
119 m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
120 m_value_checksum(),
121 m_preferred_display_language(lldb::eLanguageTypeUnknown),
122 m_language_flags(0), m_value_is_valid(false), m_value_did_change(false),
123 m_children_count_valid(false), m_old_value_valid(false),
124 m_is_deref_of_parent(false), m_is_array_item_for_pointer(false),
125 m_is_bitfield_for_scalar(false), m_is_child_at_offset(false),
126 m_is_getting_summary(false),
127 m_did_calculate_complete_objc_class_type(false),
128 m_is_synthetic_children_generated(false) {
129 m_manager = new ValueObjectManager();
130 m_manager->ManageObject(this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131}
132
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133// Destructor
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134ValueObject::~ValueObject() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136bool ValueObject::UpdateValueIfNeeded(bool update_format) {
Greg Claytonb71f3842010-10-05 03:13:51 +0000137
Kate Stoneb9c1b512016-09-06 20:57:50 +0000138 bool did_change_formats = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 if (update_format)
141 did_change_formats = UpdateFormatsIfNeeded();
Greg Claytonefbc7d22012-03-09 04:23:44 +0000142
Adrian Prantl05097242018-04-30 16:49:04 +0000143 // If this is a constant value, then our success is predicated on whether we
144 // have an error or not
Kate Stoneb9c1b512016-09-06 20:57:50 +0000145 if (GetIsConstant()) {
146 // if you are constant, things might still have changed behind your back
147 // (e.g. you are a frozen object and things have changed deeper than you
Adrian Prantl05097242018-04-30 16:49:04 +0000148 // cared to freeze-dry yourself) in this case, your value has not changed,
149 // but "computed" entries might have, so you might now have a different
150 // summary, or a different object description. clear these so we will
151 // recompute them
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152 if (update_format && !did_change_formats)
153 ClearUserVisibleData(eClearUserVisibleDataItemsSummary |
154 eClearUserVisibleDataItemsDescription);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155 return m_error.Success();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000156 }
157
158 bool first_update = IsChecksumEmpty();
159
160 if (NeedsUpdating()) {
161 m_update_point.SetUpdated();
162
Adrian Prantl05097242018-04-30 16:49:04 +0000163 // Save the old value using swap to avoid a string copy which also will
164 // clear our m_value_str
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165 if (m_value_str.empty()) {
166 m_old_value_valid = false;
167 } else {
168 m_old_value_valid = true;
169 m_old_value_str.swap(m_value_str);
170 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
171 }
172
173 ClearUserVisibleData();
174
175 if (IsInScope()) {
176 const bool value_was_valid = GetValueIsValid();
177 SetValueDidChange(false);
178
179 m_error.Clear();
180
181 // Call the pure virtual function to update the value
182
183 bool need_compare_checksums = false;
184 llvm::SmallVector<uint8_t, 16> old_checksum;
185
186 if (!first_update && CanProvideValue()) {
187 need_compare_checksums = true;
188 old_checksum.resize(m_value_checksum.size());
189 std::copy(m_value_checksum.begin(), m_value_checksum.end(),
190 old_checksum.begin());
191 }
192
193 bool success = UpdateValue();
194
195 SetValueIsValid(success);
196
197 if (success) {
198 const uint64_t max_checksum_size = 128;
199 m_data.Checksum(m_value_checksum, max_checksum_size);
200 } else {
201 need_compare_checksums = false;
202 m_value_checksum.clear();
203 }
204
205 assert(!need_compare_checksums ||
206 (!old_checksum.empty() && !m_value_checksum.empty()));
207
208 if (first_update)
209 SetValueDidChange(false);
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000210 else if (!m_value_did_change && !success) {
Adrian Prantl05097242018-04-30 16:49:04 +0000211 // The value wasn't gotten successfully, so we mark this as changed if
212 // the value used to be valid and now isn't
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213 SetValueDidChange(value_was_valid);
214 } else if (need_compare_checksums) {
215 SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0],
216 m_value_checksum.size()));
217 }
218
219 } else {
220 m_error.SetErrorString("out of scope");
221 }
222 }
223 return m_error.Success();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224}
225
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226bool ValueObject::UpdateFormatsIfNeeded() {
227 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
228 if (log)
229 log->Printf("[%s %p] checking for FormatManager revisions. ValueObject "
230 "rev: %d - Global rev: %d",
231 GetName().GetCString(), static_cast<void *>(this),
232 m_last_format_mgr_revision,
233 DataVisualization::GetCurrentRevision());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000234
Kate Stoneb9c1b512016-09-06 20:57:50 +0000235 bool any_change = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000236
Kate Stoneb9c1b512016-09-06 20:57:50 +0000237 if ((m_last_format_mgr_revision != DataVisualization::GetCurrentRevision())) {
238 m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
239 any_change = true;
240
241 SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues));
242 SetSummaryFormat(
243 DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000244#ifndef LLDB_DISABLE_PYTHON
Kate Stoneb9c1b512016-09-06 20:57:50 +0000245 SetSyntheticChildren(
246 DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000247#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000248 SetValidator(DataVisualization::GetValidator(*this, GetDynamicValueType()));
249 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000250
Kate Stoneb9c1b512016-09-06 20:57:50 +0000251 return any_change;
Enrico Granata4becb372011-06-29 22:27:15 +0000252}
253
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254void ValueObject::SetNeedsUpdate() {
255 m_update_point.SetNeedsUpdate();
256 // We have to clear the value string here so ConstResult children will notice
Adrian Prantl05097242018-04-30 16:49:04 +0000257 // if their values are changed by hand (i.e. with SetValueAsCString).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
Jim Ingham16e0c682011-08-12 23:34:31 +0000259}
260
Kate Stoneb9c1b512016-09-06 20:57:50 +0000261void ValueObject::ClearDynamicTypeInformation() {
262 m_children_count_valid = false;
263 m_did_calculate_complete_objc_class_type = false;
264 m_last_format_mgr_revision = 0;
265 m_override_type = CompilerType();
266 SetValueFormat(lldb::TypeFormatImplSP());
267 SetSummaryFormat(lldb::TypeSummaryImplSP());
268 SetSyntheticChildren(lldb::SyntheticChildrenSP());
Enrico Granata13ac0e22012-10-17 19:03:34 +0000269}
270
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271CompilerType ValueObject::MaybeCalculateCompleteType() {
272 CompilerType compiler_type(GetCompilerTypeImpl());
273
274 if (m_did_calculate_complete_objc_class_type) {
275 if (m_override_type.IsValid())
276 return m_override_type;
Sean Callanan72772842012-02-22 23:57:45 +0000277 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 return compiler_type;
279 }
280
281 CompilerType class_type;
282 bool is_pointer_type = false;
283
284 if (ClangASTContext::IsObjCObjectPointerType(compiler_type, &class_type)) {
285 is_pointer_type = true;
286 } else if (ClangASTContext::IsObjCObjectOrInterfaceType(compiler_type)) {
287 class_type = compiler_type;
288 } else {
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000289 return compiler_type;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000290 }
291
292 m_did_calculate_complete_objc_class_type = true;
293
294 if (class_type) {
295 ConstString class_name(class_type.GetConstTypeName());
296
297 if (class_name) {
298 ProcessSP process_sp(
299 GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
300
301 if (process_sp) {
302 ObjCLanguageRuntime *objc_language_runtime(
303 process_sp->GetObjCLanguageRuntime());
304
305 if (objc_language_runtime) {
306 TypeSP complete_objc_class_type_sp =
307 objc_language_runtime->LookupInCompleteClassCache(class_name);
308
309 if (complete_objc_class_type_sp) {
310 CompilerType complete_class(
311 complete_objc_class_type_sp->GetFullCompilerType());
312
313 if (complete_class.GetCompleteType()) {
314 if (is_pointer_type) {
315 m_override_type = complete_class.GetPointerType();
316 } else {
317 m_override_type = complete_class;
318 }
319
320 if (m_override_type.IsValid())
321 return m_override_type;
322 }
323 }
324 }
325 }
326 }
327 }
328 return compiler_type;
Sean Callanan72772842012-02-22 23:57:45 +0000329}
330
Kate Stoneb9c1b512016-09-06 20:57:50 +0000331CompilerType ValueObject::GetCompilerType() {
332 return MaybeCalculateCompleteType();
Sean Callanan72772842012-02-22 23:57:45 +0000333}
334
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335TypeImpl ValueObject::GetTypeImpl() { return TypeImpl(GetCompilerType()); }
336
337DataExtractor &ValueObject::GetDataExtractor() {
338 UpdateValueIfNeeded(false);
339 return m_data;
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000340}
341
Zachary Turner97206d52017-05-12 04:51:55 +0000342const Status &ValueObject::GetError() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343 UpdateValueIfNeeded(false);
344 return m_error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345}
346
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000347ConstString ValueObject::GetName() const { return m_name; }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000348
349const char *ValueObject::GetLocationAsCString() {
350 return GetLocationAsCStringImpl(m_value, m_data);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351}
352
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
354 const DataExtractor &data) {
355 if (UpdateValueIfNeeded(false)) {
356 if (m_location_str.empty()) {
357 StreamString sstr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359 Value::ValueType value_type = value.GetValueType();
Enrico Granata82fabf82013-04-30 20:45:04 +0000360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361 switch (value_type) {
362 case Value::eValueTypeScalar:
363 case Value::eValueTypeVector:
364 if (value.GetContextType() == Value::eContextTypeRegisterInfo) {
365 RegisterInfo *reg_info = value.GetRegisterInfo();
366 if (reg_info) {
367 if (reg_info->name)
368 m_location_str = reg_info->name;
369 else if (reg_info->alt_name)
370 m_location_str = reg_info->alt_name;
371 if (m_location_str.empty())
372 m_location_str = (reg_info->encoding == lldb::eEncodingVector)
373 ? "vector"
374 : "scalar";
375 }
376 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000377 if (m_location_str.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000378 m_location_str =
379 (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
380 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382 case Value::eValueTypeLoadAddress:
383 case Value::eValueTypeFileAddress:
384 case Value::eValueTypeHostAddress: {
385 uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
386 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size,
387 value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
Zachary Turnerc1564272016-11-16 21:15:24 +0000388 m_location_str = sstr.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000389 } break;
390 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000392 }
393 return m_location_str.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394}
395
Kate Stoneb9c1b512016-09-06 20:57:50 +0000396Value &ValueObject::GetValue() { return m_value; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397
Kate Stoneb9c1b512016-09-06 20:57:50 +0000398const Value &ValueObject::GetValue() const { return m_value; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400bool ValueObject::ResolveValue(Scalar &scalar) {
401 if (UpdateValueIfNeeded(
402 false)) // make sure that you are up to date before returning anything
403 {
404 ExecutionContext exe_ctx(GetExecutionContextRef());
405 Value tmp_value(m_value);
406 scalar = tmp_value.ResolveValue(&exe_ctx);
407 if (scalar.IsValid()) {
408 const uint32_t bitfield_bit_size = GetBitfieldBitSize();
409 if (bitfield_bit_size)
410 return scalar.ExtractBitfield(bitfield_bit_size,
411 GetBitfieldBitOffset());
412 return true;
Enrico Granata6fd87d52011-08-04 01:41:02 +0000413 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414 }
415 return false;
416}
417
Zachary Turner97206d52017-05-12 04:51:55 +0000418bool ValueObject::IsLogicalTrue(Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000419 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
420 LazyBool is_logical_true = language->IsLogicalTrue(*this, error);
421 switch (is_logical_true) {
422 case eLazyBoolYes:
423 case eLazyBoolNo:
424 return (is_logical_true == true);
425 case eLazyBoolCalculate:
426 break;
427 }
428 }
429
430 Scalar scalar_value;
431
432 if (!ResolveValue(scalar_value)) {
433 error.SetErrorString("failed to get a scalar result");
Greg Claytondcad5022011-12-29 01:26:56 +0000434 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435 }
436
437 bool ret;
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000438 ret = scalar_value.ULongLong(1) != 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000439 error.Clear();
440 return ret;
Greg Clayton8f343b02010-11-04 01:54:29 +0000441}
442
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443bool ValueObject::GetValueIsValid() const { return m_value_is_valid; }
444
445void ValueObject::SetValueIsValid(bool b) { m_value_is_valid = b; }
446
447bool ValueObject::GetValueDidChange() { return m_value_did_change; }
448
449void ValueObject::SetValueDidChange(bool value_changed) {
450 m_value_did_change = value_changed;
451}
452
453ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) {
454 ValueObjectSP child_sp;
455 // We may need to update our value if we are dynamic
456 if (IsPossibleDynamicType())
457 UpdateValueIfNeeded(false);
458 if (idx < GetNumChildren()) {
459 // Check if we have already made the child value object?
460 if (can_create && !m_children.HasChildAtIndex(idx)) {
461 // No we haven't created the child at this index, so lets have our
462 // subclass do it and cache the result for quick future access.
463 m_children.SetChildAtIndex(idx, CreateChildAtIndex(idx, false, 0));
Enrico Granata407b5c62015-11-02 21:52:05 +0000464 }
Jim Ingham98e6daf2015-10-31 00:02:18 +0000465
Kate Stoneb9c1b512016-09-06 20:57:50 +0000466 ValueObject *child = m_children.GetChildAtIndex(idx);
467 if (child != NULL)
468 return child->GetSP();
469 }
470 return child_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000471}
472
Enrico Granata3309d882013-01-12 01:00:22 +0000473lldb::ValueObjectSP
Lang Hames088d0012017-04-26 18:15:40 +0000474ValueObject::GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000475 size_t *index_of_error) {
476 if (idxs.size() == 0)
477 return GetSP();
478 ValueObjectSP root(GetSP());
479 for (size_t idx : idxs) {
480 root = root->GetChildAtIndex(idx, true);
481 if (!root) {
482 if (index_of_error)
483 *index_of_error = idx;
484 return root;
Enrico Granata3309d882013-01-12 01:00:22 +0000485 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000486 }
487 return root;
488}
489
490lldb::ValueObjectSP ValueObject::GetChildAtIndexPath(
Lang Hames088d0012017-04-26 18:15:40 +0000491 llvm::ArrayRef<std::pair<size_t, bool>> idxs, size_t *index_of_error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000492 if (idxs.size() == 0)
493 return GetSP();
494 ValueObjectSP root(GetSP());
495 for (std::pair<size_t, bool> idx : idxs) {
496 root = root->GetChildAtIndex(idx.first, idx.second);
497 if (!root) {
498 if (index_of_error)
499 *index_of_error = idx.first;
500 return root;
501 }
502 }
503 return root;
Enrico Granata3309d882013-01-12 01:00:22 +0000504}
505
506lldb::ValueObjectSP
Lang Hames088d0012017-04-26 18:15:40 +0000507ValueObject::GetChildAtNamePath(llvm::ArrayRef<ConstString> names,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000508 ConstString *name_of_error) {
509 if (names.size() == 0)
510 return GetSP();
511 ValueObjectSP root(GetSP());
512 for (ConstString name : names) {
513 root = root->GetChildMemberWithName(name, true);
514 if (!root) {
515 if (name_of_error)
516 *name_of_error = name;
517 return root;
518 }
519 }
520 return root;
Enrico Granataef8dde62015-12-21 23:10:17 +0000521}
522
Kate Stoneb9c1b512016-09-06 20:57:50 +0000523lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
Lang Hames088d0012017-04-26 18:15:40 +0000524 llvm::ArrayRef<std::pair<ConstString, bool>> names,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 ConstString *name_of_error) {
526 if (names.size() == 0)
527 return GetSP();
528 ValueObjectSP root(GetSP());
529 for (std::pair<ConstString, bool> name : names) {
530 root = root->GetChildMemberWithName(name.first, name.second);
531 if (!root) {
532 if (name_of_error)
533 *name_of_error = name.first;
534 return root;
535 }
536 }
537 return root;
Enrico Granatae2e220a2013-09-12 00:48:47 +0000538}
539
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000540size_t ValueObject::GetIndexOfChildWithName(ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000541 bool omit_empty_base_classes = true;
542 return GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
543 omit_empty_base_classes);
Enrico Granatae2e220a2013-09-12 00:48:47 +0000544}
545
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000546ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547 bool can_create) {
Adrian Prantl05097242018-04-30 16:49:04 +0000548 // when getting a child by name, it could be buried inside some base classes
549 // (which really aren't part of the expression path), so we need a vector of
550 // indexes that can get us down to the correct child
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 ValueObjectSP child_sp;
552
553 // We may need to update our value if we are dynamic
554 if (IsPossibleDynamicType())
555 UpdateValueIfNeeded(false);
556
557 std::vector<uint32_t> child_indexes;
558 bool omit_empty_base_classes = true;
559 const size_t num_child_indexes =
560 GetCompilerType().GetIndexOfChildMemberWithName(
561 name.GetCString(), omit_empty_base_classes, child_indexes);
562 if (num_child_indexes > 0) {
563 std::vector<uint32_t>::const_iterator pos = child_indexes.begin();
564 std::vector<uint32_t>::const_iterator end = child_indexes.end();
565
566 child_sp = GetChildAtIndex(*pos, can_create);
567 for (++pos; pos != end; ++pos) {
568 if (child_sp) {
569 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex(*pos, can_create));
570 child_sp = new_child_sp;
571 } else {
572 child_sp.reset();
573 }
Enrico Granatae2e220a2013-09-12 00:48:47 +0000574 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000575 }
576 return child_sp;
Enrico Granatae2e220a2013-09-12 00:48:47 +0000577}
578
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579size_t ValueObject::GetNumChildren(uint32_t max) {
580 UpdateValueIfNeeded();
581
582 if (max < UINT32_MAX) {
583 if (m_children_count_valid) {
584 size_t children_count = m_children.GetChildrenCount();
585 return children_count <= max ? children_count : max;
586 } else
587 return CalculateNumChildren(max);
588 }
589
590 if (!m_children_count_valid) {
591 SetNumChildren(CalculateNumChildren());
592 }
593 return m_children.GetChildrenCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594}
595
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596bool ValueObject::MightHaveChildren() {
597 bool has_children = false;
598 const uint32_t type_info = GetTypeInfo();
599 if (type_info) {
600 if (type_info & (eTypeHasChildren | eTypeIsPointer | eTypeIsReference))
601 has_children = true;
602 } else {
603 has_children = GetNumChildren() > 0;
604 }
605 return has_children;
Greg Clayton4a792072012-10-23 01:50:10 +0000606}
607
608// Should only be called by ValueObject::GetNumChildren()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000609void ValueObject::SetNumChildren(size_t num_children) {
610 m_children_count_valid = true;
611 m_children.SetChildrenCount(num_children);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000612}
613
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000614void ValueObject::SetName(ConstString name) { m_name = name; }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000615
616ValueObject *ValueObject::CreateChildAtIndex(size_t idx,
617 bool synthetic_array_member,
618 int32_t synthetic_index) {
619 ValueObject *valobj = NULL;
620
621 bool omit_empty_base_classes = true;
622 bool ignore_array_bounds = synthetic_array_member;
623 std::string child_name_str;
624 uint32_t child_byte_size = 0;
625 int32_t child_byte_offset = 0;
626 uint32_t child_bitfield_bit_size = 0;
627 uint32_t child_bitfield_bit_offset = 0;
628 bool child_is_base_class = false;
629 bool child_is_deref_of_parent = false;
630 uint64_t language_flags = 0;
631
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000632 const bool transparent_pointers = !synthetic_array_member;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000633 CompilerType child_compiler_type;
634
635 ExecutionContext exe_ctx(GetExecutionContextRef());
636
637 child_compiler_type = GetCompilerType().GetChildCompilerTypeAtIndex(
638 &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
639 ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
640 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
641 child_is_deref_of_parent, this, language_flags);
642 if (child_compiler_type) {
643 if (synthetic_index)
644 child_byte_offset += child_byte_size * synthetic_index;
645
646 ConstString child_name;
647 if (!child_name_str.empty())
648 child_name.SetCString(child_name_str.c_str());
649
650 valobj = new ValueObjectChild(
651 *this, child_compiler_type, child_name, child_byte_size,
652 child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
653 child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
654 language_flags);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000655 }
656
657 return valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000658}
659
Kate Stoneb9c1b512016-09-06 20:57:50 +0000660bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
661 std::string &destination,
662 lldb::LanguageType lang) {
663 return GetSummaryAsCString(summary_ptr, destination,
664 TypeSummaryOptions().SetLanguage(lang));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000665}
666
Kate Stoneb9c1b512016-09-06 20:57:50 +0000667bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
668 std::string &destination,
669 const TypeSummaryOptions &options) {
670 destination.clear();
671
Adrian Prantl05097242018-04-30 16:49:04 +0000672 // ideally we would like to bail out if passing NULL, but if we do so we end
673 // up not providing the summary for function pointers anymore
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674 if (/*summary_ptr == NULL ||*/ m_is_getting_summary)
675 return false;
676
677 m_is_getting_summary = true;
678
679 TypeSummaryOptions actual_options(options);
680
681 if (actual_options.GetLanguage() == lldb::eLanguageTypeUnknown)
682 actual_options.SetLanguage(GetPreferredDisplayLanguage());
683
684 // this is a hot path in code and we prefer to avoid setting this string all
Adrian Prantl05097242018-04-30 16:49:04 +0000685 // too often also clearing out other information that we might care to see in
686 // a crash log. might be useful in very specific situations though.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687 /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s.
688 Summary provider's description is %s",
689 GetTypeName().GetCString(),
690 GetName().GetCString(),
691 summary_ptr->GetDescription().c_str());*/
692
693 if (UpdateValueIfNeeded(false) && summary_ptr) {
694 if (HasSyntheticValue())
695 m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on
696 // the synthetic children being
697 // up-to-date (e.g. ${svar%#})
698 summary_ptr->FormatObject(this, destination, actual_options);
699 }
700 m_is_getting_summary = false;
701 return !destination.empty();
Enrico Granatac1247f52014-11-06 21:23:20 +0000702}
703
Kate Stoneb9c1b512016-09-06 20:57:50 +0000704const char *ValueObject::GetSummaryAsCString(lldb::LanguageType lang) {
705 if (UpdateValueIfNeeded(true) && m_summary_str.empty()) {
706 TypeSummaryOptions summary_options;
707 summary_options.SetLanguage(lang);
708 GetSummaryAsCString(GetSummaryFormat().get(), m_summary_str,
709 summary_options);
710 }
711 if (m_summary_str.empty())
712 return NULL;
713 return m_summary_str.c_str();
714}
715
716bool ValueObject::GetSummaryAsCString(std::string &destination,
717 const TypeSummaryOptions &options) {
718 return GetSummaryAsCString(GetSummaryFormat().get(), destination, options);
719}
720
721bool ValueObject::IsCStringContainer(bool check_pointer) {
722 CompilerType pointee_or_element_compiler_type;
723 const Flags type_flags(GetTypeInfo(&pointee_or_element_compiler_type));
724 bool is_char_arr_ptr(type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
725 pointee_or_element_compiler_type.IsCharType());
726 if (!is_char_arr_ptr)
727 return false;
728 if (!check_pointer)
729 return true;
730 if (type_flags.Test(eTypeIsArray))
731 return true;
732 addr_t cstr_address = LLDB_INVALID_ADDRESS;
733 AddressType cstr_address_type = eAddressTypeInvalid;
734 cstr_address = GetAddressOf(true, &cstr_address_type);
735 return (cstr_address != LLDB_INVALID_ADDRESS);
736}
737
738size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
739 uint32_t item_count) {
740 CompilerType pointee_or_element_compiler_type;
741 const uint32_t type_info = GetTypeInfo(&pointee_or_element_compiler_type);
742 const bool is_pointer_type = type_info & eTypeIsPointer;
743 const bool is_array_type = type_info & eTypeIsArray;
744 if (!(is_pointer_type || is_array_type))
745 return 0;
746
747 if (item_count == 0)
748 return 0;
749
750 ExecutionContext exe_ctx(GetExecutionContextRef());
751
Adrian Prantld6a9bbf2019-01-15 20:33:58 +0000752 llvm::Optional<uint64_t> item_type_size =
753 pointee_or_element_compiler_type.GetByteSize(
754 exe_ctx.GetBestExecutionContextScope());
Adrian Prantld963a7c2019-01-15 18:07:52 +0000755 if (!item_type_size)
756 return 0;
757 const uint64_t bytes = item_count * *item_type_size;
758 const uint64_t offset = item_idx * *item_type_size;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000759
760 if (item_idx == 0 && item_count == 1) // simply a deref
761 {
762 if (is_pointer_type) {
Zachary Turner97206d52017-05-12 04:51:55 +0000763 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000764 ValueObjectSP pointee_sp = Dereference(error);
765 if (error.Fail() || pointee_sp.get() == NULL)
766 return 0;
767 return pointee_sp->GetData(data, error);
768 } else {
769 ValueObjectSP child_sp = GetChildAtIndex(0, true);
770 if (child_sp.get() == NULL)
771 return 0;
Zachary Turner97206d52017-05-12 04:51:55 +0000772 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000773 return child_sp->GetData(data, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 return true;
776 } else /* (items > 1) */
777 {
Zachary Turner97206d52017-05-12 04:51:55 +0000778 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000779 lldb_private::DataBufferHeap *heap_buf_ptr = NULL;
780 lldb::DataBufferSP data_sp(heap_buf_ptr =
781 new lldb_private::DataBufferHeap());
Enrico Granata0c489f52012-03-01 04:24:26 +0000782
Kate Stoneb9c1b512016-09-06 20:57:50 +0000783 AddressType addr_type;
784 lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type)
785 : GetAddressOf(true, &addr_type);
786
787 switch (addr_type) {
788 case eAddressTypeFile: {
789 ModuleSP module_sp(GetModule());
790 if (module_sp) {
791 addr = addr + offset;
792 Address so_addr;
793 module_sp->ResolveFileAddress(addr, so_addr);
794 ExecutionContext exe_ctx(GetExecutionContextRef());
795 Target *target = exe_ctx.GetTargetPtr();
796 if (target) {
797 heap_buf_ptr->SetByteSize(bytes);
798 size_t bytes_read = target->ReadMemory(
799 so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
800 if (error.Success()) {
801 data.SetData(data_sp);
802 return bytes_read;
803 }
804 }
805 }
806 } break;
807 case eAddressTypeLoad: {
808 ExecutionContext exe_ctx(GetExecutionContextRef());
809 Process *process = exe_ctx.GetProcessPtr();
810 if (process) {
811 heap_buf_ptr->SetByteSize(bytes);
812 size_t bytes_read = process->ReadMemory(
813 addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
814 if (error.Success() || bytes_read > 0) {
815 data.SetData(data_sp);
816 return bytes_read;
817 }
818 }
819 } break;
820 case eAddressTypeHost: {
Adrian Prantld963a7c2019-01-15 18:07:52 +0000821 auto max_bytes =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000822 GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());
Adrian Prantld963a7c2019-01-15 18:07:52 +0000823 if (max_bytes && *max_bytes > offset) {
824 size_t bytes_read = std::min<uint64_t>(*max_bytes - offset, bytes);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000825 addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
826 if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
827 break;
828 heap_buf_ptr->CopyData((uint8_t *)(addr + offset), bytes_read);
829 data.SetData(data_sp);
830 return bytes_read;
831 }
832 } break;
833 case eAddressTypeInvalid:
834 break;
Enrico Granata0c489f52012-03-01 04:24:26 +0000835 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000836 }
837 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000838}
839
Zachary Turner97206d52017-05-12 04:51:55 +0000840uint64_t ValueObject::GetData(DataExtractor &data, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000841 UpdateValueIfNeeded(false);
842 ExecutionContext exe_ctx(GetExecutionContextRef());
843 error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
844 if (error.Fail()) {
845 if (m_data.GetByteSize()) {
846 data = m_data;
847 error.Clear();
848 return data.GetByteSize();
849 } else {
850 return 0;
851 }
852 }
853 data.SetAddressByteSize(m_data.GetAddressByteSize());
854 data.SetByteOrder(m_data.GetByteOrder());
855 return data.GetByteSize();
Enrico Granata49bfafb2014-11-18 23:36:25 +0000856}
857
Zachary Turner97206d52017-05-12 04:51:55 +0000858bool ValueObject::SetData(DataExtractor &data, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000859 error.Clear();
860 // Make sure our value is up to date first so that our location and location
861 // type is valid.
862 if (!UpdateValueIfNeeded(false)) {
863 error.SetErrorString("unable to read value");
864 return false;
865 }
866
867 uint64_t count = 0;
868 const Encoding encoding = GetCompilerType().GetEncoding(count);
869
870 const size_t byte_size = GetByteSize();
871
872 Value::ValueType value_type = m_value.GetValueType();
873
874 switch (value_type) {
875 case Value::eValueTypeScalar: {
Zachary Turner97206d52017-05-12 04:51:55 +0000876 Status set_error =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000877 m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
878
879 if (!set_error.Success()) {
880 error.SetErrorStringWithFormat("unable to set scalar value: %s",
881 set_error.AsCString());
882 return false;
883 }
884 } break;
885 case Value::eValueTypeLoadAddress: {
886 // If it is a load address, then the scalar value is the storage location
887 // of the data, and we have to shove this value down to that load location.
888 ExecutionContext exe_ctx(GetExecutionContextRef());
889 Process *process = exe_ctx.GetProcessPtr();
890 if (process) {
891 addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
892 size_t bytes_written = process->WriteMemory(
893 target_addr, data.GetDataStart(), byte_size, error);
894 if (!error.Success())
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000895 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000896 if (bytes_written != byte_size) {
897 error.SetErrorString("unable to write value to memory");
898 return false;
899 }
900 }
901 } break;
902 case Value::eValueTypeHostAddress: {
903 // If it is a host address, then we stuff the scalar as a DataBuffer into
904 // the Value's data.
905 DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
906 m_data.SetData(buffer_sp, 0);
907 data.CopyByteOrderedData(0, byte_size,
908 const_cast<uint8_t *>(m_data.GetDataStart()),
909 byte_size, m_data.GetByteOrder());
910 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
911 } break;
912 case Value::eValueTypeFileAddress:
913 case Value::eValueTypeVector:
914 break;
915 }
916
Adrian Prantl05097242018-04-30 16:49:04 +0000917 // If we have reached this point, then we have successfully changed the
918 // value.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919 SetNeedsUpdate();
920 return true;
921}
922
923static bool CopyStringDataToBufferSP(const StreamString &source,
924 lldb::DataBufferSP &destination) {
Jonas Devlieghere796ac802019-02-11 23:13:08 +0000925 destination = std::make_shared<DataBufferHeap>(source.GetSize() + 1, 0);
Zachary Turnerc1564272016-11-16 21:15:24 +0000926 memcpy(destination->GetBytes(), source.GetString().data(), source.GetSize());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000927 return true;
928}
929
930std::pair<size_t, bool>
Zachary Turner97206d52017-05-12 04:51:55 +0000931ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000932 uint32_t max_length, bool honor_array,
933 Format item_format) {
934 bool was_capped = false;
935 StreamString s;
936 ExecutionContext exe_ctx(GetExecutionContextRef());
937 Target *target = exe_ctx.GetTargetPtr();
938
939 if (!target) {
940 s << "<no target to read from>";
941 error.SetErrorString("no target to read from");
942 CopyStringDataToBufferSP(s, buffer_sp);
943 return {0, was_capped};
944 }
945
946 if (max_length == 0)
947 max_length = target->GetMaximumSizeOfStringSummary();
948
949 size_t bytes_read = 0;
950 size_t total_bytes_read = 0;
951
952 CompilerType compiler_type = GetCompilerType();
953 CompilerType elem_or_pointee_compiler_type;
954 const Flags type_flags(GetTypeInfo(&elem_or_pointee_compiler_type));
955 if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
956 elem_or_pointee_compiler_type.IsCharType()) {
Greg Claytonafacd142011-09-02 01:15:17 +0000957 addr_t cstr_address = LLDB_INVALID_ADDRESS;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000958 AddressType cstr_address_type = eAddressTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000959
Kate Stoneb9c1b512016-09-06 20:57:50 +0000960 size_t cstr_len = 0;
961 bool capped_data = false;
962 const bool is_array = type_flags.Test(eTypeIsArray);
963 if (is_array) {
964 // We have an array
965 uint64_t array_size = 0;
966 if (compiler_type.IsArrayType(NULL, &array_size, NULL)) {
967 cstr_len = array_size;
968 if (cstr_len > max_length) {
969 capped_data = true;
970 cstr_len = max_length;
Enrico Granata9128ee22011-09-06 19:20:51 +0000971 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000972 }
973 cstr_address = GetAddressOf(true, &cstr_address_type);
974 } else {
975 // We have a pointer
976 cstr_address = GetPointerValue(&cstr_address_type);
Enrico Granata9128ee22011-09-06 19:20:51 +0000977 }
Enrico Granata9128ee22011-09-06 19:20:51 +0000978
Kate Stoneb9c1b512016-09-06 20:57:50 +0000979 if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) {
980 if (cstr_address_type == eAddressTypeHost && is_array) {
981 const char *cstr = GetDataExtractor().PeekCStr(0);
982 if (cstr == nullptr) {
983 s << "<invalid address>";
984 error.SetErrorString("invalid address");
985 CopyStringDataToBufferSP(s, buffer_sp);
986 return {0, was_capped};
Sean Callananed185ab2013-04-19 19:47:32 +0000987 }
Jonas Devlieghere796ac802019-02-11 23:13:08 +0000988 buffer_sp = std::make_shared<DataBufferHeap>(cstr_len, 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000989 memcpy(buffer_sp->GetBytes(), cstr, cstr_len);
990 return {cstr_len, was_capped};
991 } else {
992 s << "<invalid address>";
993 error.SetErrorString("invalid address");
Enrico Granata2206b482014-10-30 18:27:31 +0000994 CopyStringDataToBufferSP(s, buffer_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000995 return {0, was_capped};
996 }
Enrico Granata7e0db2a2013-02-28 22:01:33 +0000997 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000998
999 Address cstr_so_addr(cstr_address);
1000 DataExtractor data;
1001 if (cstr_len > 0 && honor_array) {
1002 // I am using GetPointeeData() here to abstract the fact that some
Adrian Prantl05097242018-04-30 16:49:04 +00001003 // ValueObjects are actually frozen pointers in the host but the pointed-
1004 // to data lives in the debuggee, and GetPointeeData() automatically
1005 // takes care of this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001006 GetPointeeData(data, 0, cstr_len);
1007
1008 if ((bytes_read = data.GetByteSize()) > 0) {
1009 total_bytes_read = bytes_read;
1010 for (size_t offset = 0; offset < bytes_read; offset++)
1011 s.Printf("%c", *data.PeekData(offset, 1));
1012 if (capped_data)
1013 was_capped = true;
1014 }
1015 } else {
1016 cstr_len = max_length;
1017 const size_t k_max_buf_size = 64;
1018
1019 size_t offset = 0;
1020
1021 int cstr_len_displayed = -1;
1022 bool capped_cstr = false;
1023 // I am using GetPointeeData() here to abstract the fact that some
Adrian Prantl05097242018-04-30 16:49:04 +00001024 // ValueObjects are actually frozen pointers in the host but the pointed-
1025 // to data lives in the debuggee, and GetPointeeData() automatically
1026 // takes care of this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001027 while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {
1028 total_bytes_read += bytes_read;
1029 const char *cstr = data.PeekCStr(0);
1030 size_t len = strnlen(cstr, k_max_buf_size);
1031 if (cstr_len_displayed < 0)
1032 cstr_len_displayed = len;
1033
1034 if (len == 0)
1035 break;
1036 cstr_len_displayed += len;
1037 if (len > bytes_read)
1038 len = bytes_read;
1039 if (len > cstr_len)
1040 len = cstr_len;
1041
1042 for (size_t offset = 0; offset < bytes_read; offset++)
1043 s.Printf("%c", *data.PeekData(offset, 1));
1044
1045 if (len < k_max_buf_size)
1046 break;
1047
1048 if (len >= cstr_len) {
1049 capped_cstr = true;
1050 break;
1051 }
1052
1053 cstr_len -= len;
1054 offset += len;
1055 }
1056
1057 if (cstr_len_displayed >= 0) {
1058 if (capped_cstr)
1059 was_capped = true;
1060 }
1061 }
1062 } else {
1063 error.SetErrorString("not a string object");
1064 s << "<not a string object>";
1065 }
1066 CopyStringDataToBufferSP(s, buffer_sp);
1067 return {total_bytes_read, was_capped};
1068}
1069
1070std::pair<TypeValidatorResult, std::string> ValueObject::GetValidationStatus() {
1071 if (!UpdateValueIfNeeded(true))
1072 return {TypeValidatorResult::Success,
1073 ""}; // not the validator's job to discuss update problems
1074
1075 if (m_validation_result.hasValue())
1076 return m_validation_result.getValue();
1077
1078 if (!m_type_validator_sp)
1079 return {TypeValidatorResult::Success, ""}; // no validator no failure
1080
1081 auto outcome = m_type_validator_sp->FormatObject(this);
1082
1083 return (m_validation_result = {outcome.m_result, outcome.m_message})
1084 .getValue();
1085}
1086
1087const char *ValueObject::GetObjectDescription() {
1088
1089 if (!UpdateValueIfNeeded(true))
1090 return NULL;
1091
1092 if (!m_object_desc_str.empty())
1093 return m_object_desc_str.c_str();
1094
1095 ExecutionContext exe_ctx(GetExecutionContextRef());
1096 Process *process = exe_ctx.GetProcessPtr();
1097 if (process == NULL)
1098 return NULL;
1099
1100 StreamString s;
1101
1102 LanguageType language = GetObjectRuntimeLanguage();
1103 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
1104
1105 if (runtime == NULL) {
1106 // Aw, hell, if the things a pointer, or even just an integer, let's try
1107 // ObjC anyway...
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001108 CompilerType compiler_type = GetCompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001109 if (compiler_type) {
1110 bool is_signed;
1111 if (compiler_type.IsIntegerType(is_signed) ||
1112 compiler_type.IsPointerType()) {
1113 runtime = process->GetLanguageRuntime(eLanguageTypeObjC);
1114 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001115 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001116 }
1117
1118 if (runtime && runtime->GetObjectDescription(s, *this)) {
Zachary Turnerc1564272016-11-16 21:15:24 +00001119 m_object_desc_str.append(s.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120 }
1121
1122 if (m_object_desc_str.empty())
1123 return NULL;
1124 else
1125 return m_object_desc_str.c_str();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001126}
1127
Kate Stoneb9c1b512016-09-06 20:57:50 +00001128bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,
1129 std::string &destination) {
1130 if (UpdateValueIfNeeded(false))
1131 return format.FormatObject(this, destination);
1132 else
1133 return false;
Enrico Granata744794a2014-09-05 21:46:22 +00001134}
1135
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136bool ValueObject::GetValueAsCString(lldb::Format format,
1137 std::string &destination) {
1138 return GetValueAsCString(TypeFormatImpl_Format(format), destination);
1139}
Enrico Granata0a3958e2011-07-02 00:25:22 +00001140
Kate Stoneb9c1b512016-09-06 20:57:50 +00001141const char *ValueObject::GetValueAsCString() {
1142 if (UpdateValueIfNeeded(true)) {
1143 lldb::TypeFormatImplSP format_sp;
1144 lldb::Format my_format = GetFormat();
1145 if (my_format == lldb::eFormatDefault) {
1146 if (m_type_format_sp)
1147 format_sp = m_type_format_sp;
1148 else {
1149 if (m_is_bitfield_for_scalar)
1150 my_format = eFormatUnsigned;
1151 else {
1152 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo) {
1153 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1154 if (reg_info)
1155 my_format = reg_info->format;
1156 } else {
1157 my_format = GetValue().GetCompilerType().GetFormat();
1158 }
Jim Inghama2cf2632010-12-23 02:29:54 +00001159 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001160 }
Jim Inghama2cf2632010-12-23 02:29:54 +00001161 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001162 if (my_format != m_last_format || m_value_str.empty()) {
1163 m_last_format = my_format;
1164 if (!format_sp)
Jonas Devlieghere796ac802019-02-11 23:13:08 +00001165 format_sp = std::make_shared<TypeFormatImpl_Format>(my_format);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001166 if (GetValueAsCString(*format_sp.get(), m_value_str)) {
1167 if (!m_value_did_change && m_old_value_valid) {
Adrian Prantl05097242018-04-30 16:49:04 +00001168 // The value was gotten successfully, so we consider the value as
1169 // changed if the value string differs
Kate Stoneb9c1b512016-09-06 20:57:50 +00001170 SetValueDidChange(m_old_value_str != m_value_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001171 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001172 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001173 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001174 }
1175 if (m_value_str.empty())
1176 return NULL;
1177 return m_value_str.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001178}
1179
Adrian Prantl05097242018-04-30 16:49:04 +00001180// if > 8bytes, 0 is returned. this method should mostly be used to read
1181// address values out of pointers
Kate Stoneb9c1b512016-09-06 20:57:50 +00001182uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
1183 // If our byte size is zero this is an aggregate type that has children
1184 if (CanProvideValue()) {
1185 Scalar scalar;
1186 if (ResolveValue(scalar)) {
1187 if (success)
1188 *success = true;
1189 return scalar.ULongLong(fail_value);
Enrico Granatac3e320a2011-08-02 17:27:39 +00001190 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001191 // fallthrough, otherwise...
1192 }
Johnny Chen3f476c42012-06-05 19:37:43 +00001193
Kate Stoneb9c1b512016-09-06 20:57:50 +00001194 if (success)
1195 *success = false;
1196 return fail_value;
Enrico Granatac3e320a2011-08-02 17:27:39 +00001197}
1198
Kate Stoneb9c1b512016-09-06 20:57:50 +00001199int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
1200 // If our byte size is zero this is an aggregate type that has children
1201 if (CanProvideValue()) {
1202 Scalar scalar;
1203 if (ResolveValue(scalar)) {
1204 if (success)
1205 *success = true;
1206 return scalar.SLongLong(fail_value);
Enrico Granatad7373f62013-10-31 18:57:50 +00001207 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001208 // fallthrough, otherwise...
1209 }
1210
1211 if (success)
1212 *success = false;
1213 return fail_value;
Enrico Granatad7373f62013-10-31 18:57:50 +00001214}
1215
Kate Stoneb9c1b512016-09-06 20:57:50 +00001216// if any more "special cases" are added to
Adrian Prantl05097242018-04-30 16:49:04 +00001217// ValueObject::DumpPrintableRepresentation() please keep this call up to date
1218// by returning true for your new special cases. We will eventually move to
1219// checking this call result before trying to display special cases
Kate Stoneb9c1b512016-09-06 20:57:50 +00001220bool ValueObject::HasSpecialPrintableRepresentation(
1221 ValueObjectRepresentationStyle val_obj_display, Format custom_format) {
1222 Flags flags(GetTypeInfo());
1223 if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1224 val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1225 if (IsCStringContainer(true) &&
1226 (custom_format == eFormatCString || custom_format == eFormatCharArray ||
1227 custom_format == eFormatChar || custom_format == eFormatVectorOfChar))
1228 return true;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001229
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230 if (flags.Test(eTypeIsArray)) {
1231 if ((custom_format == eFormatBytes) ||
1232 (custom_format == eFormatBytesWithASCII))
1233 return true;
1234
1235 if ((custom_format == eFormatVectorOfChar) ||
1236 (custom_format == eFormatVectorOfFloat32) ||
1237 (custom_format == eFormatVectorOfFloat64) ||
1238 (custom_format == eFormatVectorOfSInt16) ||
1239 (custom_format == eFormatVectorOfSInt32) ||
1240 (custom_format == eFormatVectorOfSInt64) ||
1241 (custom_format == eFormatVectorOfSInt8) ||
1242 (custom_format == eFormatVectorOfUInt128) ||
1243 (custom_format == eFormatVectorOfUInt16) ||
1244 (custom_format == eFormatVectorOfUInt32) ||
1245 (custom_format == eFormatVectorOfUInt64) ||
1246 (custom_format == eFormatVectorOfUInt8))
1247 return true;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001248 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001249 }
1250 return false;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001251}
1252
Kate Stoneb9c1b512016-09-06 20:57:50 +00001253bool ValueObject::DumpPrintableRepresentation(
1254 Stream &s, ValueObjectRepresentationStyle val_obj_display,
1255 Format custom_format, PrintableRepresentationSpecialCases special,
1256 bool do_dump_error) {
Enrico Granataf4efecd2011-07-12 22:56:10 +00001257
Kate Stoneb9c1b512016-09-06 20:57:50 +00001258 Flags flags(GetTypeInfo());
Enrico Granata86cc9822012-03-19 22:58:49 +00001259
Enrico Granata65d86e42016-11-07 23:32:20 +00001260 bool allow_special =
1261 (special == ValueObject::PrintableRepresentationSpecialCases::eAllow);
1262 const bool only_special = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001263
1264 if (allow_special) {
1265 if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1266 val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1267 // when being asked to get a printable display an array or pointer type
Adrian Prantl05097242018-04-30 16:49:04 +00001268 // directly, try to "do the right thing"
Kate Stoneb9c1b512016-09-06 20:57:50 +00001269
1270 if (IsCStringContainer(true) &&
1271 (custom_format == eFormatCString ||
1272 custom_format == eFormatCharArray || custom_format == eFormatChar ||
1273 custom_format ==
1274 eFormatVectorOfChar)) // print char[] & char* directly
1275 {
Zachary Turner97206d52017-05-12 04:51:55 +00001276 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001277 lldb::DataBufferSP buffer_sp;
1278 std::pair<size_t, bool> read_string = ReadPointedString(
1279 buffer_sp, error, 0, (custom_format == eFormatVectorOfChar) ||
1280 (custom_format == eFormatCharArray));
1281 lldb_private::formatters::StringPrinter::
1282 ReadBufferAndDumpToStreamOptions options(*this);
1283 options.SetData(DataExtractor(
1284 buffer_sp, lldb::eByteOrderInvalid,
1285 8)); // none of this matters for a string - pass some defaults
1286 options.SetStream(&s);
1287 options.SetPrefixToken(0);
1288 options.SetQuote('"');
1289 options.SetSourceSize(buffer_sp->GetByteSize());
1290 options.SetIsTruncated(read_string.second);
1291 formatters::StringPrinter::ReadBufferAndDumpToStream<
1292 lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
1293 options);
1294 return !error.Fail();
1295 }
1296
1297 if (custom_format == eFormatEnum)
Enrico Granata85933ed2011-08-18 16:38:26 +00001298 return false;
Enrico Granata86cc9822012-03-19 22:58:49 +00001299
Adrian Prantl05097242018-04-30 16:49:04 +00001300 // this only works for arrays, because I have no way to know when the
1301 // pointed memory ends, and no special \0 end of data marker
Kate Stoneb9c1b512016-09-06 20:57:50 +00001302 if (flags.Test(eTypeIsArray)) {
1303 if ((custom_format == eFormatBytes) ||
1304 (custom_format == eFormatBytesWithASCII)) {
1305 const size_t count = GetNumChildren();
1306
1307 s << '[';
1308 for (size_t low = 0; low < count; low++) {
1309
1310 if (low)
1311 s << ',';
1312
1313 ValueObjectSP child = GetChildAtIndex(low, true);
1314 if (!child.get()) {
1315 s << "<invalid child>";
1316 continue;
Enrico Granata86cc9822012-03-19 22:58:49 +00001317 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001318 child->DumpPrintableRepresentation(
1319 s, ValueObject::eValueObjectRepresentationStyleValue,
1320 custom_format);
1321 }
1322
1323 s << ']';
1324
1325 return true;
Enrico Granata86cc9822012-03-19 22:58:49 +00001326 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001327
1328 if ((custom_format == eFormatVectorOfChar) ||
1329 (custom_format == eFormatVectorOfFloat32) ||
1330 (custom_format == eFormatVectorOfFloat64) ||
1331 (custom_format == eFormatVectorOfSInt16) ||
1332 (custom_format == eFormatVectorOfSInt32) ||
1333 (custom_format == eFormatVectorOfSInt64) ||
1334 (custom_format == eFormatVectorOfSInt8) ||
1335 (custom_format == eFormatVectorOfUInt128) ||
1336 (custom_format == eFormatVectorOfUInt16) ||
1337 (custom_format == eFormatVectorOfUInt32) ||
1338 (custom_format == eFormatVectorOfUInt64) ||
1339 (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes
1340 // with ASCII or any vector
1341 // format should be printed
1342 // directly
Enrico Granata86cc9822012-03-19 22:58:49 +00001343 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001344 const size_t count = GetNumChildren();
1345
1346 Format format = FormatManager::GetSingleItemFormat(custom_format);
1347
1348 s << '[';
1349 for (size_t low = 0; low < count; low++) {
1350
1351 if (low)
1352 s << ',';
1353
1354 ValueObjectSP child = GetChildAtIndex(low, true);
1355 if (!child.get()) {
1356 s << "<invalid child>";
1357 continue;
Enrico Granata0dba9b32014-01-08 01:36:59 +00001358 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001359 child->DumpPrintableRepresentation(
1360 s, ValueObject::eValueObjectRepresentationStyleValue, format);
1361 }
1362
1363 s << ']';
1364
1365 return true;
Enrico Granata86cc9822012-03-19 22:58:49 +00001366 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001367 }
1368
1369 if ((custom_format == eFormatBoolean) ||
1370 (custom_format == eFormatBinary) || (custom_format == eFormatChar) ||
1371 (custom_format == eFormatCharPrintable) ||
1372 (custom_format == eFormatComplexFloat) ||
1373 (custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||
1374 (custom_format == eFormatHexUppercase) ||
1375 (custom_format == eFormatFloat) || (custom_format == eFormatOctal) ||
1376 (custom_format == eFormatOSType) ||
1377 (custom_format == eFormatUnicode16) ||
1378 (custom_format == eFormatUnicode32) ||
1379 (custom_format == eFormatUnsigned) ||
1380 (custom_format == eFormatPointer) ||
1381 (custom_format == eFormatComplexInteger) ||
1382 (custom_format == eFormatComplex) ||
1383 (custom_format == eFormatDefault)) // use the [] operator
1384 return false;
Enrico Granata86cc9822012-03-19 22:58:49 +00001385 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001386 }
1387
1388 if (only_special)
1389 return false;
1390
1391 bool var_success = false;
1392
1393 {
Zachary Turnerc1564272016-11-16 21:15:24 +00001394 llvm::StringRef str;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001395
1396 // this is a local stream that we are using to ensure that the data pointed
Adrian Prantl05097242018-04-30 16:49:04 +00001397 // to by cstr survives long enough for us to copy it to its destination -
1398 // it is necessary to have this temporary storage area for cases where our
Zachary Turnerc1564272016-11-16 21:15:24 +00001399 // desired output is not backed by some other longer-term storage
Kate Stoneb9c1b512016-09-06 20:57:50 +00001400 StreamString strm;
1401
1402 if (custom_format != eFormatInvalid)
1403 SetFormat(custom_format);
1404
1405 switch (val_obj_display) {
1406 case eValueObjectRepresentationStyleValue:
Zachary Turnerc1564272016-11-16 21:15:24 +00001407 str = GetValueAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001408 break;
1409
1410 case eValueObjectRepresentationStyleSummary:
Zachary Turnerc1564272016-11-16 21:15:24 +00001411 str = GetSummaryAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001412 break;
1413
1414 case eValueObjectRepresentationStyleLanguageSpecific:
Zachary Turnerc1564272016-11-16 21:15:24 +00001415 str = GetObjectDescription();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001416 break;
1417
1418 case eValueObjectRepresentationStyleLocation:
Zachary Turnerc1564272016-11-16 21:15:24 +00001419 str = GetLocationAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001420 break;
1421
1422 case eValueObjectRepresentationStyleChildrenCount:
1423 strm.Printf("%" PRIu64 "", (uint64_t)GetNumChildren());
Zachary Turnerc1564272016-11-16 21:15:24 +00001424 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001425 break;
1426
1427 case eValueObjectRepresentationStyleType:
Zachary Turnerc1564272016-11-16 21:15:24 +00001428 str = GetTypeName().GetStringRef();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001429 break;
1430
1431 case eValueObjectRepresentationStyleName:
Zachary Turnerc1564272016-11-16 21:15:24 +00001432 str = GetName().GetStringRef();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001433 break;
1434
1435 case eValueObjectRepresentationStyleExpressionPath:
1436 GetExpressionPath(strm, false);
Zachary Turnerc1564272016-11-16 21:15:24 +00001437 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001438 break;
1439 }
1440
Zachary Turnerc1564272016-11-16 21:15:24 +00001441 if (str.empty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001442 if (val_obj_display == eValueObjectRepresentationStyleValue)
Zachary Turnerc1564272016-11-16 21:15:24 +00001443 str = GetSummaryAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001444 else if (val_obj_display == eValueObjectRepresentationStyleSummary) {
1445 if (!CanProvideValue()) {
1446 strm.Printf("%s @ %s", GetTypeName().AsCString(),
1447 GetLocationAsCString());
Zachary Turnerc1564272016-11-16 21:15:24 +00001448 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001449 } else
Zachary Turnerc1564272016-11-16 21:15:24 +00001450 str = GetValueAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001451 }
1452 }
1453
Zachary Turnerc1564272016-11-16 21:15:24 +00001454 if (!str.empty())
1455 s << str;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001456 else {
1457 if (m_error.Fail()) {
1458 if (do_dump_error)
1459 s.Printf("<%s>", m_error.AsCString());
1460 else
1461 return false;
1462 } else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1463 s.PutCString("<no summary available>");
1464 else if (val_obj_display == eValueObjectRepresentationStyleValue)
1465 s.PutCString("<no value available>");
1466 else if (val_obj_display ==
1467 eValueObjectRepresentationStyleLanguageSpecific)
1468 s.PutCString("<not a valid Objective-C object>"); // edit this if we
1469 // have other runtimes
1470 // that support a
1471 // description
1472 else
1473 s.PutCString("<no printable representation>");
1474 }
1475
Adrian Prantl05097242018-04-30 16:49:04 +00001476 // we should only return false here if we could not do *anything* even if
1477 // we have an error message as output, that's a success from our callers'
1478 // perspective, so return true
Kate Stoneb9c1b512016-09-06 20:57:50 +00001479 var_success = true;
1480
1481 if (custom_format != eFormatInvalid)
1482 SetFormat(eFormatDefault);
1483 }
1484
1485 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001486}
1487
Kate Stoneb9c1b512016-09-06 20:57:50 +00001488addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
1489 AddressType *address_type) {
1490 // Can't take address of a bitfield
1491 if (IsBitfield())
Greg Clayton73b472d2010-10-27 03:32:59 +00001492 return LLDB_INVALID_ADDRESS;
Greg Clayton73b472d2010-10-27 03:32:59 +00001493
Kate Stoneb9c1b512016-09-06 20:57:50 +00001494 if (!UpdateValueIfNeeded(false))
1495 return LLDB_INVALID_ADDRESS;
Greg Clayton737b9322010-09-13 03:32:57 +00001496
Kate Stoneb9c1b512016-09-06 20:57:50 +00001497 switch (m_value.GetValueType()) {
1498 case Value::eValueTypeScalar:
1499 case Value::eValueTypeVector:
1500 if (scalar_is_load_address) {
1501 if (address_type)
1502 *address_type = eAddressTypeLoad;
1503 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
Greg Clayton737b9322010-09-13 03:32:57 +00001504 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001505 break;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001506
Kate Stoneb9c1b512016-09-06 20:57:50 +00001507 case Value::eValueTypeLoadAddress:
1508 case Value::eValueTypeFileAddress: {
Enrico Granata9128ee22011-09-06 19:20:51 +00001509 if (address_type)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001510 *address_type = m_value.GetValueAddressType();
1511 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1512 } break;
1513 case Value::eValueTypeHostAddress: {
1514 if (address_type)
1515 *address_type = m_value.GetValueAddressType();
1516 return LLDB_INVALID_ADDRESS;
1517 } break;
1518 }
1519 if (address_type)
1520 *address_type = eAddressTypeInvalid;
1521 return LLDB_INVALID_ADDRESS;
1522}
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001523
Kate Stoneb9c1b512016-09-06 20:57:50 +00001524addr_t ValueObject::GetPointerValue(AddressType *address_type) {
1525 addr_t address = LLDB_INVALID_ADDRESS;
1526 if (address_type)
1527 *address_type = eAddressTypeInvalid;
1528
1529 if (!UpdateValueIfNeeded(false))
Greg Clayton737b9322010-09-13 03:32:57 +00001530 return address;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001531
1532 switch (m_value.GetValueType()) {
1533 case Value::eValueTypeScalar:
1534 case Value::eValueTypeVector:
1535 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1536 break;
1537
1538 case Value::eValueTypeHostAddress:
1539 case Value::eValueTypeLoadAddress:
1540 case Value::eValueTypeFileAddress: {
1541 lldb::offset_t data_offset = 0;
1542 address = m_data.GetPointer(&data_offset);
1543 } break;
1544 }
1545
1546 if (address_type)
1547 *address_type = GetAddressTypeOfChildren();
1548
1549 return address;
Greg Clayton737b9322010-09-13 03:32:57 +00001550}
1551
Zachary Turner97206d52017-05-12 04:51:55 +00001552bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001553 error.Clear();
1554 // Make sure our value is up to date first so that our location and location
1555 // type is valid.
1556 if (!UpdateValueIfNeeded(false)) {
1557 error.SetErrorString("unable to read value");
Greg Clayton81e871e2012-02-04 02:27:34 +00001558 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001559 }
1560
1561 uint64_t count = 0;
1562 const Encoding encoding = GetCompilerType().GetEncoding(count);
1563
1564 const size_t byte_size = GetByteSize();
1565
1566 Value::ValueType value_type = m_value.GetValueType();
1567
1568 if (value_type == Value::eValueTypeScalar) {
1569 // If the value is already a scalar, then let the scalar change itself:
1570 m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
1571 } else if (byte_size <= 16) {
1572 // If the value fits in a scalar, then make a new scalar and again let the
1573 // scalar code do the conversion, then figure out where to put the new
1574 // value.
1575 Scalar new_scalar;
1576 error = new_scalar.SetValueFromCString(value_str, encoding, byte_size);
1577 if (error.Success()) {
1578 switch (value_type) {
1579 case Value::eValueTypeLoadAddress: {
1580 // If it is a load address, then the scalar value is the storage
Adrian Prantl05097242018-04-30 16:49:04 +00001581 // location of the data, and we have to shove this value down to that
1582 // load location.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001583 ExecutionContext exe_ctx(GetExecutionContextRef());
1584 Process *process = exe_ctx.GetProcessPtr();
1585 if (process) {
1586 addr_t target_addr =
1587 m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1588 size_t bytes_written = process->WriteScalarToMemory(
1589 target_addr, new_scalar, byte_size, error);
1590 if (!error.Success())
1591 return false;
1592 if (bytes_written != byte_size) {
1593 error.SetErrorString("unable to write value to memory");
1594 return false;
1595 }
1596 }
1597 } break;
1598 case Value::eValueTypeHostAddress: {
1599 // If it is a host address, then we stuff the scalar as a DataBuffer
1600 // into the Value's data.
1601 DataExtractor new_data;
1602 new_data.SetByteOrder(m_data.GetByteOrder());
1603
1604 DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
1605 m_data.SetData(buffer_sp, 0);
1606 bool success = new_scalar.GetData(new_data);
1607 if (success) {
1608 new_data.CopyByteOrderedData(
1609 0, byte_size, const_cast<uint8_t *>(m_data.GetDataStart()),
1610 byte_size, m_data.GetByteOrder());
1611 }
1612 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1613
1614 } break;
1615 case Value::eValueTypeFileAddress:
1616 case Value::eValueTypeScalar:
1617 case Value::eValueTypeVector:
1618 break;
1619 }
1620 } else {
1621 return false;
1622 }
1623 } else {
1624 // We don't support setting things bigger than a scalar at present.
1625 error.SetErrorString("unable to write aggregate data type");
1626 return false;
1627 }
1628
Adrian Prantl05097242018-04-30 16:49:04 +00001629 // If we have reached this point, then we have successfully changed the
1630 // value.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001631 SetNeedsUpdate();
1632 return true;
Greg Clayton81e871e2012-02-04 02:27:34 +00001633}
1634
Kate Stoneb9c1b512016-09-06 20:57:50 +00001635bool ValueObject::GetDeclaration(Declaration &decl) {
1636 decl.Clear();
1637 return false;
Greg Clayton84db9102012-03-26 23:03:23 +00001638}
1639
Kate Stoneb9c1b512016-09-06 20:57:50 +00001640ConstString ValueObject::GetTypeName() {
1641 return GetCompilerType().GetConstTypeName();
Enrico Granatae8daa2f2014-05-17 19:14:17 +00001642}
1643
Kate Stoneb9c1b512016-09-06 20:57:50 +00001644ConstString ValueObject::GetDisplayTypeName() { return GetTypeName(); }
1645
1646ConstString ValueObject::GetQualifiedTypeName() {
1647 return GetCompilerType().GetConstQualifiedTypeName();
Greg Clayton84db9102012-03-26 23:03:23 +00001648}
1649
Kate Stoneb9c1b512016-09-06 20:57:50 +00001650LanguageType ValueObject::GetObjectRuntimeLanguage() {
1651 return GetCompilerType().GetMinimumLanguage();
Jim Ingham5a369122010-09-28 01:25:32 +00001652}
1653
Adrian Prantl0e4c4822019-03-06 21:22:25 +00001654void ValueObject::AddSyntheticChild(ConstString key,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001655 ValueObject *valobj) {
1656 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001657}
1658
Adrian Prantl0e4c4822019-03-06 21:22:25 +00001659ValueObjectSP ValueObject::GetSyntheticChild(ConstString key) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001660 ValueObjectSP synthetic_child_sp;
1661 std::map<ConstString, ValueObject *>::const_iterator pos =
1662 m_synthetic_children.find(key);
1663 if (pos != m_synthetic_children.end())
1664 synthetic_child_sp = pos->second->GetSP();
1665 return synthetic_child_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001666}
1667
Greg Clayton2452ab72013-02-08 22:02:02 +00001668uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001669ValueObject::GetTypeInfo(CompilerType *pointee_or_element_compiler_type) {
1670 return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type);
Greg Clayton2452ab72013-02-08 22:02:02 +00001671}
1672
Kate Stoneb9c1b512016-09-06 20:57:50 +00001673bool ValueObject::IsPointerType() { return GetCompilerType().IsPointerType(); }
1674
1675bool ValueObject::IsArrayType() {
1676 return GetCompilerType().IsArrayType(NULL, NULL, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001677}
1678
Kate Stoneb9c1b512016-09-06 20:57:50 +00001679bool ValueObject::IsScalarType() { return GetCompilerType().IsScalarType(); }
1680
1681bool ValueObject::IsIntegerType(bool &is_signed) {
1682 return GetCompilerType().IsIntegerType(is_signed);
Greg Claytondaf515f2011-07-09 20:12:33 +00001683}
1684
Kate Stoneb9c1b512016-09-06 20:57:50 +00001685bool ValueObject::IsPointerOrReferenceType() {
1686 return GetCompilerType().IsPointerOrReferenceType();
Enrico Granata9fc19442011-07-06 02:13:41 +00001687}
1688
Kate Stoneb9c1b512016-09-06 20:57:50 +00001689bool ValueObject::IsPossibleDynamicType() {
1690 ExecutionContext exe_ctx(GetExecutionContextRef());
1691 Process *process = exe_ctx.GetProcessPtr();
1692 if (process)
1693 return process->IsPossibleDynamicValue(*this);
1694 else
1695 return GetCompilerType().IsPossibleDynamicType(NULL, true, true);
Jim Inghamb7603bb2011-03-18 00:05:18 +00001696}
Greg Clayton73b472d2010-10-27 03:32:59 +00001697
Kate Stoneb9c1b512016-09-06 20:57:50 +00001698bool ValueObject::IsRuntimeSupportValue() {
1699 Process *process(GetProcessSP().get());
1700 if (process) {
1701 LanguageRuntime *runtime =
1702 process->GetLanguageRuntime(GetObjectRuntimeLanguage());
1703 if (!runtime)
1704 runtime = process->GetObjCLanguageRuntime();
1705 if (runtime)
1706 return runtime->IsRuntimeSupportValue(*this);
1707 }
1708 return false;
Greg Clayton007d5be2011-05-30 00:49:24 +00001709}
1710
Kate Stoneb9c1b512016-09-06 20:57:50 +00001711bool ValueObject::IsNilReference() {
1712 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1713 return language->IsNilReference(*this);
1714 }
1715 return false;
Greg Claytondea8cb42011-06-29 22:09:02 +00001716}
1717
Kate Stoneb9c1b512016-09-06 20:57:50 +00001718bool ValueObject::IsUninitializedReference() {
1719 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1720 return language->IsUninitializedReference(*this);
1721 }
1722 return false;
Enrico Granata9e7b3882012-12-13 23:50:33 +00001723}
1724
Adrian Prantl05097242018-04-30 16:49:04 +00001725// This allows you to create an array member using and index that doesn't not
1726// fall in the normal bounds of the array. Many times structure can be defined
1727// as: struct Collection {
Greg Claytondaf515f2011-07-09 20:12:33 +00001728// uint32_t item_count;
1729// Item item_array[0];
1730// };
Adrian Prantl05097242018-04-30 16:49:04 +00001731// The size of the "item_array" is 1, but many times in practice there are more
1732// items in "item_array".
Greg Claytondaf515f2011-07-09 20:12:33 +00001733
Kate Stoneb9c1b512016-09-06 20:57:50 +00001734ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
1735 bool can_create) {
1736 ValueObjectSP synthetic_child_sp;
1737 if (IsPointerType() || IsArrayType()) {
1738 char index_str[64];
1739 snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index);
1740 ConstString index_const_str(index_str);
Adrian Prantl05097242018-04-30 16:49:04 +00001741 // Check if we have already created a synthetic array member in this valid
1742 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001743 synthetic_child_sp = GetSyntheticChild(index_const_str);
1744 if (!synthetic_child_sp) {
1745 ValueObject *synthetic_child;
Adrian Prantl05097242018-04-30 16:49:04 +00001746 // We haven't made a synthetic array member for INDEX yet, so lets make
1747 // one and cache it for any future reference.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001748 synthetic_child = CreateChildAtIndex(0, true, index);
1749
1750 // Cache the value if we got one back...
1751 if (synthetic_child) {
1752 AddSyntheticChild(index_const_str, synthetic_child);
Enrico Granata6f3533f2011-07-29 19:53:35 +00001753 synthetic_child_sp = synthetic_child->GetSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001754 synthetic_child_sp->SetName(ConstString(index_str));
1755 synthetic_child_sp->m_is_array_item_for_pointer = true;
1756 }
Enrico Granata6f3533f2011-07-29 19:53:35 +00001757 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001758 }
1759 return synthetic_child_sp;
Enrico Granata6f3533f2011-07-29 19:53:35 +00001760}
1761
Kate Stoneb9c1b512016-09-06 20:57:50 +00001762ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
1763 bool can_create) {
1764 ValueObjectSP synthetic_child_sp;
1765 if (IsScalarType()) {
1766 char index_str[64];
1767 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1768 ConstString index_const_str(index_str);
Adrian Prantl05097242018-04-30 16:49:04 +00001769 // Check if we have already created a synthetic array member in this valid
1770 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001771 synthetic_child_sp = GetSyntheticChild(index_const_str);
1772 if (!synthetic_child_sp) {
1773 uint32_t bit_field_size = to - from + 1;
1774 uint32_t bit_field_offset = from;
1775 if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
1776 bit_field_offset =
1777 GetByteSize() * 8 - bit_field_size - bit_field_offset;
Adrian Prantl05097242018-04-30 16:49:04 +00001778 // We haven't made a synthetic array member for INDEX yet, so lets make
1779 // one and cache it for any future reference.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001780 ValueObjectChild *synthetic_child = new ValueObjectChild(
1781 *this, GetCompilerType(), index_const_str, GetByteSize(), 0,
1782 bit_field_size, bit_field_offset, false, false, eAddressTypeInvalid,
1783 0);
1784
1785 // Cache the value if we got one back...
1786 if (synthetic_child) {
1787 AddSyntheticChild(index_const_str, synthetic_child);
Enrico Granata32556cd2014-08-26 20:54:04 +00001788 synthetic_child_sp = synthetic_child->GetSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001789 synthetic_child_sp->SetName(ConstString(index_str));
1790 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1791 }
Enrico Granata32556cd2014-08-26 20:54:04 +00001792 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001793 }
1794 return synthetic_child_sp;
Enrico Granata32556cd2014-08-26 20:54:04 +00001795}
1796
Kate Stoneb9c1b512016-09-06 20:57:50 +00001797ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
1798 uint32_t offset, const CompilerType &type, bool can_create,
1799 ConstString name_const_str) {
1800
1801 ValueObjectSP synthetic_child_sp;
1802
1803 if (name_const_str.IsEmpty()) {
1804 char name_str[64];
1805 snprintf(name_str, sizeof(name_str), "@%i", offset);
1806 name_const_str.SetCString(name_str);
1807 }
1808
Adrian Prantl05097242018-04-30 16:49:04 +00001809 // Check if we have already created a synthetic array member in this valid
1810 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001811 synthetic_child_sp = GetSyntheticChild(name_const_str);
1812
1813 if (synthetic_child_sp.get())
1814 return synthetic_child_sp;
1815
1816 if (!can_create)
Adrian Prantld963a7c2019-01-15 18:07:52 +00001817 return {};
Kate Stoneb9c1b512016-09-06 20:57:50 +00001818
1819 ExecutionContext exe_ctx(GetExecutionContextRef());
Adrian Prantld6a9bbf2019-01-15 20:33:58 +00001820 llvm::Optional<uint64_t> size =
1821 type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
Adrian Prantld963a7c2019-01-15 18:07:52 +00001822 if (!size)
1823 return {};
1824 ValueObjectChild *synthetic_child =
1825 new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
1826 false, false, eAddressTypeInvalid, 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001827 if (synthetic_child) {
1828 AddSyntheticChild(name_const_str, synthetic_child);
1829 synthetic_child_sp = synthetic_child->GetSP();
1830 synthetic_child_sp->SetName(name_const_str);
1831 synthetic_child_sp->m_is_child_at_offset = true;
1832 }
1833 return synthetic_child_sp;
1834}
1835
1836ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
1837 const CompilerType &type,
1838 bool can_create,
1839 ConstString name_const_str) {
1840 ValueObjectSP synthetic_child_sp;
1841
1842 if (name_const_str.IsEmpty()) {
1843 char name_str[128];
1844 snprintf(name_str, sizeof(name_str), "base%s@%i",
1845 type.GetTypeName().AsCString("<unknown>"), offset);
1846 name_const_str.SetCString(name_str);
1847 }
1848
Adrian Prantl05097242018-04-30 16:49:04 +00001849 // Check if we have already created a synthetic array member in this valid
1850 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001851 synthetic_child_sp = GetSyntheticChild(name_const_str);
1852
1853 if (synthetic_child_sp.get())
1854 return synthetic_child_sp;
1855
1856 if (!can_create)
Adrian Prantld963a7c2019-01-15 18:07:52 +00001857 return {};
Kate Stoneb9c1b512016-09-06 20:57:50 +00001858
1859 const bool is_base_class = true;
1860
1861 ExecutionContext exe_ctx(GetExecutionContextRef());
Adrian Prantld6a9bbf2019-01-15 20:33:58 +00001862 llvm::Optional<uint64_t> size =
1863 type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
Adrian Prantld963a7c2019-01-15 18:07:52 +00001864 if (!size)
1865 return {};
1866 ValueObjectChild *synthetic_child =
1867 new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
1868 is_base_class, false, eAddressTypeInvalid, 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001869 if (synthetic_child) {
1870 AddSyntheticChild(name_const_str, synthetic_child);
1871 synthetic_child_sp = synthetic_child->GetSP();
1872 synthetic_child_sp->SetName(name_const_str);
1873 }
1874 return synthetic_child_sp;
1875}
Enrico Granata32556cd2014-08-26 20:54:04 +00001876
Adrian Prantl05097242018-04-30 16:49:04 +00001877// your expression path needs to have a leading . or -> (unless it somehow
1878// "looks like" an array, in which case it has a leading [ symbol). while the [
1879// is meaningful and should be shown to the user, . and -> are just parser
1880// design, but by no means added information for the user.. strip them off
Kate Stoneb9c1b512016-09-06 20:57:50 +00001881static const char *SkipLeadingExpressionPathSeparators(const char *expression) {
1882 if (!expression || !expression[0])
Enrico Granatad55546b2011-07-22 00:16:08 +00001883 return expression;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001884 if (expression[0] == '.')
1885 return expression + 1;
1886 if (expression[0] == '-' && expression[1] == '>')
1887 return expression + 2;
1888 return expression;
Enrico Granatad55546b2011-07-22 00:16:08 +00001889}
1890
Greg Claytonafacd142011-09-02 01:15:17 +00001891ValueObjectSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00001892ValueObject::GetSyntheticExpressionPathChild(const char *expression,
1893 bool can_create) {
1894 ValueObjectSP synthetic_child_sp;
1895 ConstString name_const_string(expression);
Adrian Prantl05097242018-04-30 16:49:04 +00001896 // Check if we have already created a synthetic array member in this valid
1897 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001898 synthetic_child_sp = GetSyntheticChild(name_const_string);
1899 if (!synthetic_child_sp) {
Adrian Prantl05097242018-04-30 16:49:04 +00001900 // We haven't made a synthetic array member for expression yet, so lets
1901 // make one and cache it for any future reference.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001902 synthetic_child_sp = GetValueForExpressionPath(
Zachary Turnerd2daca72016-11-18 17:55:04 +00001903 expression, NULL, NULL,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001904 GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(
1905 GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
1906 None));
1907
1908 // Cache the value if we got one back...
1909 if (synthetic_child_sp.get()) {
1910 // FIXME: this causes a "real" child to end up with its name changed to
1911 // the contents of expression
1912 AddSyntheticChild(name_const_string, synthetic_child_sp.get());
1913 synthetic_child_sp->SetName(
1914 ConstString(SkipLeadingExpressionPathSeparators(expression)));
Enrico Granatad55546b2011-07-22 00:16:08 +00001915 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001916 }
1917 return synthetic_child_sp;
Enrico Granatad55546b2011-07-22 00:16:08 +00001918}
1919
Kate Stoneb9c1b512016-09-06 20:57:50 +00001920void ValueObject::CalculateSyntheticValue(bool use_synthetic) {
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001921 if (!use_synthetic)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001922 return;
1923
1924 TargetSP target_sp(GetTargetSP());
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001925 if (target_sp && !target_sp->GetEnableSyntheticValue()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001926 m_synthetic_value = NULL;
1927 return;
1928 }
1929
1930 lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
1931
1932 if (!UpdateFormatsIfNeeded() && m_synthetic_value)
1933 return;
1934
1935 if (m_synthetic_children_sp.get() == NULL)
1936 return;
1937
1938 if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
1939 return;
1940
1941 m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
1942}
1943
1944void ValueObject::CalculateDynamicValue(DynamicValueType use_dynamic) {
1945 if (use_dynamic == eNoDynamicValues)
1946 return;
1947
1948 if (!m_dynamic_value && !IsDynamic()) {
1949 ExecutionContext exe_ctx(GetExecutionContextRef());
1950 Process *process = exe_ctx.GetProcessPtr();
1951 if (process && process->IsPossibleDynamicValue(*this)) {
1952 ClearDynamicTypeInformation();
1953 m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
Enrico Granatac5bc4122012-03-27 02:35:13 +00001954 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001955 }
Enrico Granatad55546b2011-07-22 00:16:08 +00001956}
1957
Kate Stoneb9c1b512016-09-06 20:57:50 +00001958ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) {
1959 if (use_dynamic == eNoDynamicValues)
1960 return ValueObjectSP();
1961
1962 if (!IsDynamic() && m_dynamic_value == NULL) {
1963 CalculateDynamicValue(use_dynamic);
1964 }
1965 if (m_dynamic_value)
1966 return m_dynamic_value->GetSP();
1967 else
1968 return ValueObjectSP();
Jim Ingham78a685a2011-04-16 00:01:13 +00001969}
1970
Kate Stoneb9c1b512016-09-06 20:57:50 +00001971ValueObjectSP ValueObject::GetStaticValue() { return GetSP(); }
1972
1973lldb::ValueObjectSP ValueObject::GetNonSyntheticValue() { return GetSP(); }
1974
1975ValueObjectSP ValueObject::GetSyntheticValue(bool use_synthetic) {
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001976 if (!use_synthetic)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001977 return ValueObjectSP();
1978
1979 CalculateSyntheticValue(use_synthetic);
1980
1981 if (m_synthetic_value)
1982 return m_synthetic_value->GetSP();
1983 else
1984 return ValueObjectSP();
Jim Ingham22777012010-09-23 02:01:19 +00001985}
Greg Clayton1d3afba2010-10-05 00:00:42 +00001986
Kate Stoneb9c1b512016-09-06 20:57:50 +00001987bool ValueObject::HasSyntheticValue() {
1988 UpdateFormatsIfNeeded();
Jim Ingham60dbabb2011-12-08 19:44:08 +00001989
Kate Stoneb9c1b512016-09-06 20:57:50 +00001990 if (m_synthetic_children_sp.get() == NULL)
1991 return false;
Enrico Granata886147f2012-05-08 18:47:08 +00001992
Kate Stoneb9c1b512016-09-06 20:57:50 +00001993 CalculateSyntheticValue(true);
Enrico Granata86cc9822012-03-19 22:58:49 +00001994
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001995 return m_synthetic_value != nullptr;
Greg Claytone221f822011-01-21 01:59:00 +00001996}
1997
Kate Stoneb9c1b512016-09-06 20:57:50 +00001998bool ValueObject::GetBaseClassPath(Stream &s) {
1999 if (IsBaseClass()) {
2000 bool parent_had_base_class =
2001 GetParent() && GetParent()->GetBaseClassPath(s);
2002 CompilerType compiler_type = GetCompilerType();
2003 std::string cxx_class_name;
2004 bool this_had_base_class =
2005 ClangASTContext::GetCXXClassName(compiler_type, cxx_class_name);
2006 if (this_had_base_class) {
2007 if (parent_had_base_class)
2008 s.PutCString("::");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00002009 s.PutCString(cxx_class_name);
Greg Claytone221f822011-01-21 01:59:00 +00002010 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002011 return parent_had_base_class || this_had_base_class;
2012 }
2013 return false;
Greg Claytone221f822011-01-21 01:59:00 +00002014}
Greg Clayton1d3afba2010-10-05 00:00:42 +00002015
Kate Stoneb9c1b512016-09-06 20:57:50 +00002016ValueObject *ValueObject::GetNonBaseClassParent() {
2017 if (GetParent()) {
2018 if (GetParent()->IsBaseClass())
2019 return GetParent()->GetNonBaseClassParent();
2020 else
2021 return GetParent();
2022 }
2023 return NULL;
2024}
Enrico Granataa3c8f042014-08-19 22:29:08 +00002025
Kate Stoneb9c1b512016-09-06 20:57:50 +00002026bool ValueObject::IsBaseClass(uint32_t &depth) {
2027 if (!IsBaseClass()) {
2028 depth = 0;
2029 return false;
2030 }
2031 if (GetParent()) {
2032 GetParent()->IsBaseClass(depth);
2033 depth = depth + 1;
Enrico Granataa3c8f042014-08-19 22:29:08 +00002034 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002035 }
2036 // TODO: a base of no parent? weird..
2037 depth = 1;
2038 return true;
Enrico Granataa3c8f042014-08-19 22:29:08 +00002039}
2040
Kate Stoneb9c1b512016-09-06 20:57:50 +00002041void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes,
2042 GetExpressionPathFormat epformat) {
2043 // synthetic children do not actually "exist" as part of the hierarchy, and
Adrian Prantl05097242018-04-30 16:49:04 +00002044 // sometimes they are consed up in ways that don't make sense from an
2045 // underlying language/API standpoint. So, use a special code path here to
2046 // return something that can hopefully be used in expression
Kate Stoneb9c1b512016-09-06 20:57:50 +00002047 if (m_is_synthetic_children_generated) {
2048 UpdateValueIfNeeded();
2049
2050 if (m_value.GetValueType() == Value::eValueTypeLoadAddress) {
2051 if (IsPointerOrReferenceType()) {
2052 s.Printf("((%s)0x%" PRIx64 ")", GetTypeName().AsCString("void"),
2053 GetValueAsUnsigned(0));
Enrico Granata986fa5f2014-12-09 21:41:16 +00002054 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002055 } else {
2056 uint64_t load_addr =
2057 m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
2058 if (load_addr != LLDB_INVALID_ADDRESS) {
2059 s.Printf("(*( (%s *)0x%" PRIx64 "))", GetTypeName().AsCString("void"),
2060 load_addr);
2061 return;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002062 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002063 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002064 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002065
2066 if (CanProvideValue()) {
2067 s.Printf("((%s)%s)", GetTypeName().AsCString("void"),
2068 GetValueAsCString());
2069 return;
Enrico Granata4becb372011-06-29 22:27:15 +00002070 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002071
2072 return;
2073 }
2074
2075 const bool is_deref_of_parent = IsDereferenceOfParent();
2076
2077 if (is_deref_of_parent &&
2078 epformat == eGetExpressionPathFormatDereferencePointers) {
2079 // this is the original format of GetExpressionPath() producing code like
Adrian Prantl05097242018-04-30 16:49:04 +00002080 // *(a_ptr).memberName, which is entirely fine, until you put this into
Kate Stoneb9c1b512016-09-06 20:57:50 +00002081 // StackFrame::GetValueForVariableExpressionPath() which prefers to see
Adrian Prantl05097242018-04-30 16:49:04 +00002082 // a_ptr->memberName. the eHonorPointers mode is meant to produce strings
2083 // in this latter format
Kate Stoneb9c1b512016-09-06 20:57:50 +00002084 s.PutCString("*(");
2085 }
2086
2087 ValueObject *parent = GetParent();
2088
2089 if (parent)
2090 parent->GetExpressionPath(s, qualify_cxx_base_classes, epformat);
2091
Adrian Prantl05097242018-04-30 16:49:04 +00002092 // if we are a deref_of_parent just because we are synthetic array members
2093 // made up to allow ptr[%d] syntax to work in variable printing, then add our
2094 // name ([%d]) to the expression path
Kate Stoneb9c1b512016-09-06 20:57:50 +00002095 if (m_is_array_item_for_pointer &&
2096 epformat == eGetExpressionPathFormatHonorPointers)
2097 s.PutCString(m_name.AsCString());
2098
2099 if (!IsBaseClass()) {
2100 if (!is_deref_of_parent) {
2101 ValueObject *non_base_class_parent = GetNonBaseClassParent();
2102 if (non_base_class_parent &&
2103 !non_base_class_parent->GetName().IsEmpty()) {
2104 CompilerType non_base_class_parent_compiler_type =
2105 non_base_class_parent->GetCompilerType();
2106 if (non_base_class_parent_compiler_type) {
2107 if (parent && parent->IsDereferenceOfParent() &&
2108 epformat == eGetExpressionPathFormatHonorPointers) {
2109 s.PutCString("->");
2110 } else {
2111 const uint32_t non_base_class_parent_type_info =
2112 non_base_class_parent_compiler_type.GetTypeInfo();
2113
2114 if (non_base_class_parent_type_info & eTypeIsPointer) {
2115 s.PutCString("->");
2116 } else if ((non_base_class_parent_type_info & eTypeHasChildren) &&
2117 !(non_base_class_parent_type_info & eTypeIsArray)) {
2118 s.PutChar('.');
2119 }
2120 }
2121 }
2122 }
2123
2124 const char *name = GetName().GetCString();
2125 if (name) {
2126 if (qualify_cxx_base_classes) {
2127 if (GetBaseClassPath(s))
2128 s.PutCString("::");
2129 }
2130 s.PutCString(name);
2131 }
2132 }
2133 }
2134
2135 if (is_deref_of_parent &&
2136 epformat == eGetExpressionPathFormatDereferencePointers) {
2137 s.PutChar(')');
2138 }
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002139}
2140
Kate Stoneb9c1b512016-09-06 20:57:50 +00002141ValueObjectSP ValueObject::GetValueForExpressionPath(
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002142 llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002143 ExpressionPathEndResultType *final_value_type,
2144 const GetValueForExpressionPathOptions &options,
2145 ExpressionPathAftermath *final_task_on_target) {
Enrico Granata385ad4e2012-03-03 00:45:57 +00002146
Kate Stoneb9c1b512016-09-06 20:57:50 +00002147 ExpressionPathScanEndReason dummy_reason_to_stop =
2148 ValueObject::eExpressionPathScanEndReasonUnknown;
2149 ExpressionPathEndResultType dummy_final_value_type =
2150 ValueObject::eExpressionPathEndResultTypeInvalid;
2151 ExpressionPathAftermath dummy_final_task_on_target =
2152 ValueObject::eExpressionPathAftermathNothing;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002153
Kate Stoneb9c1b512016-09-06 20:57:50 +00002154 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(
Zachary Turnerd2daca72016-11-18 17:55:04 +00002155 expression, reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002156 final_value_type ? final_value_type : &dummy_final_value_type, options,
2157 final_task_on_target ? final_task_on_target
2158 : &dummy_final_task_on_target);
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002159
Kate Stoneb9c1b512016-09-06 20:57:50 +00002160 if (!final_task_on_target ||
2161 *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
2162 return ret_val;
2163
2164 if (ret_val.get() &&
2165 ((final_value_type ? *final_value_type : dummy_final_value_type) ==
2166 eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress
2167 // of plain objects
2168 {
2169 if ((final_task_on_target ? *final_task_on_target
2170 : dummy_final_task_on_target) ==
2171 ValueObject::eExpressionPathAftermathDereference) {
Zachary Turner97206d52017-05-12 04:51:55 +00002172 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002173 ValueObjectSP final_value = ret_val->Dereference(error);
2174 if (error.Fail() || !final_value.get()) {
2175 if (reason_to_stop)
2176 *reason_to_stop =
2177 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2178 if (final_value_type)
2179 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002180 return ValueObjectSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002181 } else {
2182 if (final_task_on_target)
2183 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2184 return final_value;
2185 }
2186 }
2187 if (*final_task_on_target ==
2188 ValueObject::eExpressionPathAftermathTakeAddress) {
Zachary Turner97206d52017-05-12 04:51:55 +00002189 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002190 ValueObjectSP final_value = ret_val->AddressOf(error);
2191 if (error.Fail() || !final_value.get()) {
2192 if (reason_to_stop)
2193 *reason_to_stop =
2194 ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
2195 if (final_value_type)
2196 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2197 return ValueObjectSP();
2198 } else {
2199 if (final_task_on_target)
2200 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2201 return final_value;
2202 }
2203 }
2204 }
2205 return ret_val; // final_task_on_target will still have its original value, so
2206 // you know I did not do it
2207}
2208
Kate Stoneb9c1b512016-09-06 20:57:50 +00002209ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002210 llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002211 ExpressionPathEndResultType *final_result,
2212 const GetValueForExpressionPathOptions &options,
2213 ExpressionPathAftermath *what_next) {
2214 ValueObjectSP root = GetSP();
2215
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002216 if (!root)
2217 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002218
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002219 llvm::StringRef remainder = expression;
Zachary Turner655c4522016-11-18 06:34:45 +00002220
Kate Stoneb9c1b512016-09-06 20:57:50 +00002221 while (true) {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002222 llvm::StringRef temp_expression = remainder;
Zachary Turner655c4522016-11-18 06:34:45 +00002223
Kate Stoneb9c1b512016-09-06 20:57:50 +00002224 CompilerType root_compiler_type = root->GetCompilerType();
2225 CompilerType pointee_compiler_type;
2226 Flags pointee_compiler_type_info;
2227
2228 Flags root_compiler_type_info(
2229 root_compiler_type.GetTypeInfo(&pointee_compiler_type));
2230 if (pointee_compiler_type)
2231 pointee_compiler_type_info.Reset(pointee_compiler_type.GetTypeInfo());
2232
Zachary Turnerd2daca72016-11-18 17:55:04 +00002233 if (temp_expression.empty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002234 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2235 return root;
2236 }
2237
Zachary Turnerd2daca72016-11-18 17:55:04 +00002238 switch (temp_expression.front()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002239 case '-': {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002240 temp_expression = temp_expression.drop_front();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002241 if (options.m_check_dot_vs_arrow_syntax &&
2242 root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2243 // use -> on a
2244 // non-pointer and I
2245 // must catch the error
2246 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002247 *reason_to_stop =
2248 ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
2249 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2250 return ValueObjectSP();
2251 }
2252 if (root_compiler_type_info.Test(eTypeIsObjC) && // if yo are trying to
2253 // extract an ObjC IVar
2254 // when this is forbidden
2255 root_compiler_type_info.Test(eTypeIsPointer) &&
2256 options.m_no_fragile_ivar) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002257 *reason_to_stop =
2258 ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
2259 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2260 return ValueObjectSP();
2261 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002262 if (!temp_expression.startswith(">")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002263 *reason_to_stop =
2264 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2265 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2266 return ValueObjectSP();
2267 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002268 }
2269 LLVM_FALLTHROUGH;
2270 case '.': // or fallthrough from ->
2271 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002272 if (options.m_check_dot_vs_arrow_syntax &&
2273 temp_expression.front() == '.' &&
Kate Stoneb9c1b512016-09-06 20:57:50 +00002274 root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2275 // use . on a pointer
2276 // and I must catch the
2277 // error
2278 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002279 *reason_to_stop =
2280 ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
2281 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002282 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002283 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002284 temp_expression = temp_expression.drop_front(); // skip . or >
2285
2286 size_t next_sep_pos = temp_expression.find_first_of("-.[", 1);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002287 ConstString child_name;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002288 if (next_sep_pos == llvm::StringRef::npos) // if no other separator just
2289 // expand this last layer
Kate Stoneb9c1b512016-09-06 20:57:50 +00002290 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002291 child_name.SetString(temp_expression);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002292 ValueObjectSP child_valobj_sp =
2293 root->GetChildMemberWithName(child_name, true);
2294
2295 if (child_valobj_sp.get()) // we know we are done, so just return
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002296 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002297 *reason_to_stop =
2298 ValueObject::eExpressionPathScanEndReasonEndOfString;
2299 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2300 return child_valobj_sp;
2301 } else {
2302 switch (options.m_synthetic_children_traversal) {
2303 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2304 None:
2305 break;
2306 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2307 FromSynthetic:
2308 if (root->IsSynthetic()) {
2309 child_valobj_sp = root->GetNonSyntheticValue();
2310 if (child_valobj_sp.get())
2311 child_valobj_sp =
2312 child_valobj_sp->GetChildMemberWithName(child_name, true);
2313 }
2314 break;
2315 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2316 ToSynthetic:
2317 if (!root->IsSynthetic()) {
2318 child_valobj_sp = root->GetSyntheticValue();
2319 if (child_valobj_sp.get())
2320 child_valobj_sp =
2321 child_valobj_sp->GetChildMemberWithName(child_name, true);
2322 }
2323 break;
2324 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2325 Both:
2326 if (root->IsSynthetic()) {
2327 child_valobj_sp = root->GetNonSyntheticValue();
2328 if (child_valobj_sp.get())
2329 child_valobj_sp =
2330 child_valobj_sp->GetChildMemberWithName(child_name, true);
2331 } else {
2332 child_valobj_sp = root->GetSyntheticValue();
2333 if (child_valobj_sp.get())
2334 child_valobj_sp =
2335 child_valobj_sp->GetChildMemberWithName(child_name, true);
2336 }
2337 break;
2338 }
2339 }
2340
2341 // if we are here and options.m_no_synthetic_children is true,
Adrian Prantl05097242018-04-30 16:49:04 +00002342 // child_valobj_sp is going to be a NULL SP, so we hit the "else"
2343 // branch, and return an error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002344 if (child_valobj_sp.get()) // if it worked, just return
2345 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002346 *reason_to_stop =
2347 ValueObject::eExpressionPathScanEndReasonEndOfString;
2348 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2349 return child_valobj_sp;
2350 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002351 *reason_to_stop =
2352 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2353 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002354 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002355 }
2356 } else // other layers do expand
2357 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002358 llvm::StringRef next_separator = temp_expression.substr(next_sep_pos);
2359
2360 child_name.SetString(temp_expression.slice(0, next_sep_pos));
2361
Kate Stoneb9c1b512016-09-06 20:57:50 +00002362 ValueObjectSP child_valobj_sp =
2363 root->GetChildMemberWithName(child_name, true);
2364 if (child_valobj_sp.get()) // store the new root and move on
2365 {
2366 root = child_valobj_sp;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002367 remainder = next_separator;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002368 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2369 continue;
2370 } else {
2371 switch (options.m_synthetic_children_traversal) {
2372 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2373 None:
2374 break;
2375 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2376 FromSynthetic:
2377 if (root->IsSynthetic()) {
2378 child_valobj_sp = root->GetNonSyntheticValue();
2379 if (child_valobj_sp.get())
2380 child_valobj_sp =
2381 child_valobj_sp->GetChildMemberWithName(child_name, true);
2382 }
2383 break;
2384 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2385 ToSynthetic:
2386 if (!root->IsSynthetic()) {
2387 child_valobj_sp = root->GetSyntheticValue();
2388 if (child_valobj_sp.get())
2389 child_valobj_sp =
2390 child_valobj_sp->GetChildMemberWithName(child_name, true);
2391 }
2392 break;
2393 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2394 Both:
2395 if (root->IsSynthetic()) {
2396 child_valobj_sp = root->GetNonSyntheticValue();
2397 if (child_valobj_sp.get())
2398 child_valobj_sp =
2399 child_valobj_sp->GetChildMemberWithName(child_name, true);
2400 } else {
2401 child_valobj_sp = root->GetSyntheticValue();
2402 if (child_valobj_sp.get())
2403 child_valobj_sp =
2404 child_valobj_sp->GetChildMemberWithName(child_name, true);
2405 }
2406 break;
2407 }
2408 }
2409
2410 // if we are here and options.m_no_synthetic_children is true,
Adrian Prantl05097242018-04-30 16:49:04 +00002411 // child_valobj_sp is going to be a NULL SP, so we hit the "else"
2412 // branch, and return an error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002413 if (child_valobj_sp.get()) // if it worked, move on
2414 {
2415 root = child_valobj_sp;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002416 remainder = next_separator;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002417 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2418 continue;
2419 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002420 *reason_to_stop =
2421 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2422 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002423 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002424 }
2425 }
2426 break;
2427 }
2428 case '[': {
2429 if (!root_compiler_type_info.Test(eTypeIsArray) &&
2430 !root_compiler_type_info.Test(eTypeIsPointer) &&
2431 !root_compiler_type_info.Test(
2432 eTypeIsVector)) // if this is not a T[] nor a T*
2433 {
2434 if (!root_compiler_type_info.Test(
2435 eTypeIsScalar)) // if this is not even a scalar...
2436 {
2437 if (options.m_synthetic_children_traversal ==
2438 GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2439 None) // ...only chance left is synthetic
2440 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002441 *reason_to_stop =
2442 ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
2443 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2444 return ValueObjectSP();
2445 }
2446 } else if (!options.m_allow_bitfields_syntax) // if this is a scalar,
2447 // check that we can
2448 // expand bitfields
2449 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002450 *reason_to_stop =
2451 ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
2452 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2453 return ValueObjectSP();
2454 }
2455 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002456 if (temp_expression[1] ==
Kate Stoneb9c1b512016-09-06 20:57:50 +00002457 ']') // if this is an unbounded range it only works for arrays
2458 {
2459 if (!root_compiler_type_info.Test(eTypeIsArray)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002460 *reason_to_stop =
2461 ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2462 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002463 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002464 } else // even if something follows, we cannot expand unbounded ranges,
2465 // just let the caller do it
2466 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002467 *reason_to_stop =
2468 ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2469 *final_result =
2470 ValueObject::eExpressionPathEndResultTypeUnboundedRange;
2471 return root;
2472 }
2473 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002474
2475 size_t close_bracket_position = temp_expression.find(']', 1);
2476 if (close_bracket_position ==
2477 llvm::StringRef::npos) // if there is no ], this is a syntax error
Kate Stoneb9c1b512016-09-06 20:57:50 +00002478 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002479 *reason_to_stop =
2480 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2481 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002482 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002483 }
Zachary Turnerc2d55582016-11-18 03:51:19 +00002484
Zachary Turnerd2daca72016-11-18 17:55:04 +00002485 llvm::StringRef bracket_expr =
2486 temp_expression.slice(1, close_bracket_position);
2487
2488 // If this was an empty expression it would have been caught by the if
2489 // above.
2490 assert(!bracket_expr.empty());
2491
2492 if (!bracket_expr.contains('-')) {
Adrian Prantl05097242018-04-30 16:49:04 +00002493 // if no separator, this is of the form [N]. Note that this cannot be
2494 // an unbounded range of the form [], because that case was handled
Zachary Turnerc2d55582016-11-18 03:51:19 +00002495 // above with an unconditional return.
Zachary Turnerd2daca72016-11-18 17:55:04 +00002496 unsigned long index = 0;
2497 if (bracket_expr.getAsInteger(0, index)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002498 *reason_to_stop =
2499 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2500 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002501 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002502 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002503
Kate Stoneb9c1b512016-09-06 20:57:50 +00002504 // from here on we do have a valid index
2505 if (root_compiler_type_info.Test(eTypeIsArray)) {
2506 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2507 if (!child_valobj_sp)
2508 child_valobj_sp = root->GetSyntheticArrayMember(index, true);
2509 if (!child_valobj_sp)
2510 if (root->HasSyntheticValue() &&
2511 root->GetSyntheticValue()->GetNumChildren() > index)
2512 child_valobj_sp =
2513 root->GetSyntheticValue()->GetChildAtIndex(index, true);
2514 if (child_valobj_sp) {
2515 root = child_valobj_sp;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002516 remainder =
2517 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002518 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2519 continue;
2520 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002521 *reason_to_stop =
2522 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2523 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002524 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002525 }
2526 } else if (root_compiler_type_info.Test(eTypeIsPointer)) {
2527 if (*what_next ==
2528 ValueObject::
2529 eExpressionPathAftermathDereference && // if this is a
2530 // ptr-to-scalar, I
2531 // am accessing it
2532 // by index and I
2533 // would have
2534 // deref'ed anyway,
2535 // then do it now
2536 // and use this as
2537 // a bitfield
2538 pointee_compiler_type_info.Test(eTypeIsScalar)) {
Zachary Turner97206d52017-05-12 04:51:55 +00002539 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002540 root = root->Dereference(error);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002541 if (error.Fail() || !root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002542 *reason_to_stop =
2543 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2544 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002545 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002546 } else {
2547 *what_next = eExpressionPathAftermathNothing;
2548 continue;
2549 }
2550 } else {
2551 if (root->GetCompilerType().GetMinimumLanguage() ==
2552 eLanguageTypeObjC &&
2553 pointee_compiler_type_info.AllClear(eTypeIsPointer) &&
2554 root->HasSyntheticValue() &&
2555 (options.m_synthetic_children_traversal ==
2556 GetValueForExpressionPathOptions::
2557 SyntheticChildrenTraversal::ToSynthetic ||
2558 options.m_synthetic_children_traversal ==
2559 GetValueForExpressionPathOptions::
2560 SyntheticChildrenTraversal::Both)) {
2561 root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
2562 } else
2563 root = root->GetSyntheticArrayMember(index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002564 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002565 *reason_to_stop =
2566 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2567 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002568 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002569 } else {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002570 remainder =
2571 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002572 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2573 continue;
2574 }
2575 }
2576 } else if (root_compiler_type_info.Test(eTypeIsScalar)) {
2577 root = root->GetSyntheticBitFieldChild(index, index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002578 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002579 *reason_to_stop =
2580 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2581 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002582 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002583 } else // we do not know how to expand members of bitfields, so we
2584 // just return and let the caller do any further processing
2585 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002586 *reason_to_stop = ValueObject::
2587 eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2588 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2589 return root;
2590 }
2591 } else if (root_compiler_type_info.Test(eTypeIsVector)) {
2592 root = root->GetChildAtIndex(index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002593 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002594 *reason_to_stop =
2595 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2596 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2597 return ValueObjectSP();
2598 } else {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002599 remainder =
2600 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002601 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2602 continue;
2603 }
2604 } else if (options.m_synthetic_children_traversal ==
2605 GetValueForExpressionPathOptions::
2606 SyntheticChildrenTraversal::ToSynthetic ||
2607 options.m_synthetic_children_traversal ==
2608 GetValueForExpressionPathOptions::
2609 SyntheticChildrenTraversal::Both) {
2610 if (root->HasSyntheticValue())
2611 root = root->GetSyntheticValue();
2612 else if (!root->IsSynthetic()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002613 *reason_to_stop =
2614 ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2615 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002616 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002617 }
Adrian Prantl05097242018-04-30 16:49:04 +00002618 // if we are here, then root itself is a synthetic VO.. should be
2619 // good to go
Kate Stoneb9c1b512016-09-06 20:57:50 +00002620
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002621 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002622 *reason_to_stop =
2623 ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2624 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002625 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002626 }
2627 root = root->GetChildAtIndex(index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002628 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002629 *reason_to_stop =
2630 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2631 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002632 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002633 } else {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002634 remainder =
2635 temp_expression.substr(close_bracket_position + 1); // skip ]
Kate Stoneb9c1b512016-09-06 20:57:50 +00002636 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2637 continue;
2638 }
2639 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002640 *reason_to_stop =
2641 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2642 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002643 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002644 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002645 } else {
2646 // we have a low and a high index
2647 llvm::StringRef sleft, sright;
2648 unsigned long low_index, high_index;
2649 std::tie(sleft, sright) = bracket_expr.split('-');
2650 if (sleft.getAsInteger(0, low_index) ||
2651 sright.getAsInteger(0, high_index)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002652 *reason_to_stop =
2653 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2654 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002655 return nullptr;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002656 }
Zachary Turnerd2daca72016-11-18 17:55:04 +00002657
2658 if (low_index > high_index) // swap indices if required
2659 std::swap(low_index, high_index);
Zachary Turnerc2d55582016-11-18 03:51:19 +00002660
Kate Stoneb9c1b512016-09-06 20:57:50 +00002661 if (root_compiler_type_info.Test(
2662 eTypeIsScalar)) // expansion only works for scalars
2663 {
Zachary Turnerd2daca72016-11-18 17:55:04 +00002664 root = root->GetSyntheticBitFieldChild(low_index, high_index, true);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002665 if (!root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002666 *reason_to_stop =
2667 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2668 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002669 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002670 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002671 *reason_to_stop = ValueObject::
2672 eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2673 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2674 return root;
2675 }
2676 } else if (root_compiler_type_info.Test(
2677 eTypeIsPointer) && // if this is a ptr-to-scalar, I am
2678 // accessing it by index and I would
2679 // have deref'ed anyway, then do it
2680 // now and use this as a bitfield
2681 *what_next ==
2682 ValueObject::eExpressionPathAftermathDereference &&
2683 pointee_compiler_type_info.Test(eTypeIsScalar)) {
Zachary Turner97206d52017-05-12 04:51:55 +00002684 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002685 root = root->Dereference(error);
Zachary Turner2a3d10a2016-11-18 19:23:39 +00002686 if (error.Fail() || !root) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002687 *reason_to_stop =
2688 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2689 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002690 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002691 } else {
2692 *what_next = ValueObject::eExpressionPathAftermathNothing;
2693 continue;
2694 }
2695 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002696 *reason_to_stop =
2697 ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2698 *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
2699 return root;
2700 }
2701 }
2702 break;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002703 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002704 default: // some non-separator is in the way
2705 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002706 *reason_to_stop =
2707 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2708 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
Zachary Turnerd2daca72016-11-18 17:55:04 +00002709 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002710 }
2711 }
2712 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00002713}
2714
Kate Stoneb9c1b512016-09-06 20:57:50 +00002715void ValueObject::LogValueObject(Log *log) {
2716 if (log)
2717 return LogValueObject(log, DumpValueObjectOptions(*this));
Enrico Granata538a88a2014-10-09 18:24:30 +00002718}
2719
Kate Stoneb9c1b512016-09-06 20:57:50 +00002720void ValueObject::LogValueObject(Log *log,
2721 const DumpValueObjectOptions &options) {
2722 if (log) {
2723 StreamString s;
2724 Dump(s, options);
2725 if (s.GetSize())
2726 log->PutCString(s.GetData());
2727 }
Greg Clayton759e7442014-07-19 00:12:57 +00002728}
2729
Kate Stoneb9c1b512016-09-06 20:57:50 +00002730void ValueObject::Dump(Stream &s) { Dump(s, DumpValueObjectOptions(*this)); }
Chaoren Lind7bdc272015-07-31 00:35:40 +00002731
Kate Stoneb9c1b512016-09-06 20:57:50 +00002732void ValueObject::Dump(Stream &s, const DumpValueObjectOptions &options) {
2733 ValueObjectPrinter printer(this, &s, options);
2734 printer.PrintValueObject();
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002735}
2736
Adrian Prantl0e4c4822019-03-06 21:22:25 +00002737ValueObjectSP ValueObject::CreateConstantValue(ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002738 ValueObjectSP valobj_sp;
2739
2740 if (UpdateValueIfNeeded(false) && m_error.Success()) {
2741 ExecutionContext exe_ctx(GetExecutionContextRef());
2742
2743 DataExtractor data;
2744 data.SetByteOrder(m_data.GetByteOrder());
2745 data.SetAddressByteSize(m_data.GetAddressByteSize());
2746
2747 if (IsBitfield()) {
2748 Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
2749 m_error = v.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
2750 } else
2751 m_error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
2752
2753 valobj_sp = ValueObjectConstResult::Create(
2754 exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,
2755 GetAddressOf());
2756 }
2757
2758 if (!valobj_sp) {
2759 ExecutionContext exe_ctx(GetExecutionContextRef());
2760 valobj_sp = ValueObjectConstResult::Create(
2761 exe_ctx.GetBestExecutionContextScope(), m_error);
2762 }
2763 return valobj_sp;
2764}
2765
2766ValueObjectSP ValueObject::GetQualifiedRepresentationIfAvailable(
2767 lldb::DynamicValueType dynValue, bool synthValue) {
2768 ValueObjectSP result_sp(GetSP());
2769
2770 switch (dynValue) {
2771 case lldb::eDynamicCanRunTarget:
2772 case lldb::eDynamicDontRunTarget: {
2773 if (!result_sp->IsDynamic()) {
2774 if (result_sp->GetDynamicValue(dynValue))
2775 result_sp = result_sp->GetDynamicValue(dynValue);
2776 }
2777 } break;
2778 case lldb::eNoDynamicValues: {
2779 if (result_sp->IsDynamic()) {
2780 if (result_sp->GetStaticValue())
2781 result_sp = result_sp->GetStaticValue();
2782 }
2783 } break;
2784 }
2785
2786 if (synthValue) {
2787 if (!result_sp->IsSynthetic()) {
2788 if (result_sp->GetSyntheticValue())
2789 result_sp = result_sp->GetSyntheticValue();
2790 }
2791 } else {
2792 if (result_sp->IsSynthetic()) {
2793 if (result_sp->GetNonSyntheticValue())
2794 result_sp = result_sp->GetNonSyntheticValue();
2795 }
2796 }
2797
2798 return result_sp;
2799}
2800
Zachary Turner97206d52017-05-12 04:51:55 +00002801ValueObjectSP ValueObject::Dereference(Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002802 if (m_deref_valobj)
2803 return m_deref_valobj->GetSP();
2804
2805 const bool is_pointer_or_reference_type = IsPointerOrReferenceType();
2806 if (is_pointer_or_reference_type) {
2807 bool omit_empty_base_classes = true;
2808 bool ignore_array_bounds = false;
2809
2810 std::string child_name_str;
2811 uint32_t child_byte_size = 0;
2812 int32_t child_byte_offset = 0;
2813 uint32_t child_bitfield_bit_size = 0;
2814 uint32_t child_bitfield_bit_offset = 0;
2815 bool child_is_base_class = false;
2816 bool child_is_deref_of_parent = false;
2817 const bool transparent_pointers = false;
2818 CompilerType compiler_type = GetCompilerType();
2819 CompilerType child_compiler_type;
2820 uint64_t language_flags;
2821
2822 ExecutionContext exe_ctx(GetExecutionContextRef());
2823
2824 child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex(
2825 &exe_ctx, 0, transparent_pointers, omit_empty_base_classes,
2826 ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
2827 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
2828 child_is_deref_of_parent, this, language_flags);
2829 if (child_compiler_type && child_byte_size) {
2830 ConstString child_name;
2831 if (!child_name_str.empty())
2832 child_name.SetCString(child_name_str.c_str());
2833
2834 m_deref_valobj = new ValueObjectChild(
2835 *this, child_compiler_type, child_name, child_byte_size,
2836 child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
2837 child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
2838 language_flags);
2839 }
Tamas Berghammer4c08fe22017-03-31 20:23:22 +00002840 } else if (HasSyntheticValue()) {
2841 m_deref_valobj =
2842 GetSyntheticValue()
2843 ->GetChildMemberWithName(ConstString("$$dereference$$"), true)
2844 .get();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002845 }
2846
2847 if (m_deref_valobj) {
Greg Clayton54979cd2010-12-15 05:08:08 +00002848 error.Clear();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002849 return m_deref_valobj->GetSP();
2850 } else {
2851 StreamString strm;
2852 GetExpressionPath(strm, true);
Greg Clayton54979cd2010-12-15 05:08:08 +00002853
Kate Stoneb9c1b512016-09-06 20:57:50 +00002854 if (is_pointer_or_reference_type)
2855 error.SetErrorStringWithFormat("dereference failed: (%s) %s",
2856 GetTypeName().AsCString("<invalid type>"),
Zachary Turnerc1564272016-11-16 21:15:24 +00002857 strm.GetData());
Sean Callananed185ab2013-04-19 19:47:32 +00002858 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00002859 error.SetErrorStringWithFormat("not a pointer or reference type: (%s) %s",
2860 GetTypeName().AsCString("<invalid type>"),
Zachary Turnerc1564272016-11-16 21:15:24 +00002861 strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002862 return ValueObjectSP();
2863 }
2864}
2865
Zachary Turner97206d52017-05-12 04:51:55 +00002866ValueObjectSP ValueObject::AddressOf(Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002867 if (m_addr_of_valobj_sp)
Jim Ingham78a685a2011-04-16 00:01:13 +00002868 return m_addr_of_valobj_sp;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00002869
Kate Stoneb9c1b512016-09-06 20:57:50 +00002870 AddressType address_type = eAddressTypeInvalid;
2871 const bool scalar_is_load_address = false;
2872 addr_t addr = GetAddressOf(scalar_is_load_address, &address_type);
2873 error.Clear();
2874 if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {
2875 switch (address_type) {
2876 case eAddressTypeInvalid: {
2877 StreamString expr_path_strm;
2878 GetExpressionPath(expr_path_strm, true);
2879 error.SetErrorStringWithFormat("'%s' is not in memory",
Zachary Turnerc1564272016-11-16 21:15:24 +00002880 expr_path_strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002881 } break;
Greg Claytonb2dcc362011-05-05 23:32:56 +00002882
Kate Stoneb9c1b512016-09-06 20:57:50 +00002883 case eAddressTypeFile:
2884 case eAddressTypeLoad: {
2885 CompilerType compiler_type = GetCompilerType();
2886 if (compiler_type) {
2887 std::string name(1, '&');
2888 name.append(m_name.AsCString(""));
2889 ExecutionContext exe_ctx(GetExecutionContextRef());
2890 m_addr_of_valobj_sp = ValueObjectConstResult::Create(
2891 exe_ctx.GetBestExecutionContextScope(),
2892 compiler_type.GetPointerType(), ConstString(name.c_str()), addr,
2893 eAddressTypeInvalid, m_data.GetAddressByteSize());
2894 }
2895 } break;
2896 default:
2897 break;
Greg Claytonb2dcc362011-05-05 23:32:56 +00002898 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002899 } else {
2900 StreamString expr_path_strm;
2901 GetExpressionPath(expr_path_strm, true);
2902 error.SetErrorStringWithFormat("'%s' doesn't have a valid address",
Zachary Turnerc1564272016-11-16 21:15:24 +00002903 expr_path_strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002904 }
2905
2906 return m_addr_of_valobj_sp;
Greg Claytonb2dcc362011-05-05 23:32:56 +00002907}
2908
Kate Stoneb9c1b512016-09-06 20:57:50 +00002909ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {
2910 return ValueObjectCast::Create(*this, GetName(), compiler_type);
Greg Claytonb2dcc362011-05-05 23:32:56 +00002911}
2912
Adrian Prantl0e4c4822019-03-06 21:22:25 +00002913lldb::ValueObjectSP ValueObject::Clone(ConstString new_name) {
Tamas Berghammer4fbb55b2017-03-31 20:48:00 +00002914 return ValueObjectCast::Create(*this, new_name, GetCompilerType());
2915}
2916
Kate Stoneb9c1b512016-09-06 20:57:50 +00002917ValueObjectSP ValueObject::CastPointerType(const char *name,
2918 CompilerType &compiler_type) {
2919 ValueObjectSP valobj_sp;
2920 AddressType address_type;
2921 addr_t ptr_value = GetPointerValue(&address_type);
2922
2923 if (ptr_value != LLDB_INVALID_ADDRESS) {
2924 Address ptr_addr(ptr_value);
2925 ExecutionContext exe_ctx(GetExecutionContextRef());
2926 valobj_sp = ValueObjectMemory::Create(
2927 exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, compiler_type);
2928 }
2929 return valobj_sp;
Jim Ingham6035b672011-03-31 00:19:25 +00002930}
2931
Kate Stoneb9c1b512016-09-06 20:57:50 +00002932ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {
2933 ValueObjectSP valobj_sp;
2934 AddressType address_type;
2935 addr_t ptr_value = GetPointerValue(&address_type);
2936
2937 if (ptr_value != LLDB_INVALID_ADDRESS) {
2938 Address ptr_addr(ptr_value);
2939 ExecutionContext exe_ctx(GetExecutionContextRef());
2940 valobj_sp = ValueObjectMemory::Create(
2941 exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, type_sp);
2942 }
2943 return valobj_sp;
2944}
2945
2946ValueObject::EvaluationPoint::EvaluationPoint()
2947 : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {}
2948
2949ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope,
2950 bool use_selected)
2951 : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {
2952 ExecutionContext exe_ctx(exe_scope);
2953 TargetSP target_sp(exe_ctx.GetTargetSP());
2954 if (target_sp) {
2955 m_exe_ctx_ref.SetTargetSP(target_sp);
2956 ProcessSP process_sp(exe_ctx.GetProcessSP());
2957 if (!process_sp)
2958 process_sp = target_sp->GetProcessSP();
2959
2960 if (process_sp) {
2961 m_mod_id = process_sp->GetModID();
2962 m_exe_ctx_ref.SetProcessSP(process_sp);
2963
2964 ThreadSP thread_sp(exe_ctx.GetThreadSP());
2965
2966 if (!thread_sp) {
2967 if (use_selected)
2968 thread_sp = process_sp->GetThreadList().GetSelectedThread();
2969 }
2970
2971 if (thread_sp) {
2972 m_exe_ctx_ref.SetThreadSP(thread_sp);
2973
2974 StackFrameSP frame_sp(exe_ctx.GetFrameSP());
2975 if (!frame_sp) {
2976 if (use_selected)
2977 frame_sp = thread_sp->GetSelectedFrame();
Jim Ingham6035b672011-03-31 00:19:25 +00002978 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002979 if (frame_sp)
2980 m_exe_ctx_ref.SetFrameSP(frame_sp);
2981 }
Jim Ingham6035b672011-03-31 00:19:25 +00002982 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002983 }
Jim Ingham6035b672011-03-31 00:19:25 +00002984}
2985
Kate Stoneb9c1b512016-09-06 20:57:50 +00002986ValueObject::EvaluationPoint::EvaluationPoint(
2987 const ValueObject::EvaluationPoint &rhs)
2988 : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref), m_needs_update(true) {}
Jim Ingham6035b672011-03-31 00:19:25 +00002989
Kate Stoneb9c1b512016-09-06 20:57:50 +00002990ValueObject::EvaluationPoint::~EvaluationPoint() {}
Jim Ingham6035b672011-03-31 00:19:25 +00002991
Kate Stoneb9c1b512016-09-06 20:57:50 +00002992// This function checks the EvaluationPoint against the current process state.
Adrian Prantl05097242018-04-30 16:49:04 +00002993// If the current state matches the evaluation point, or the evaluation point
2994// is already invalid, then we return false, meaning "no change". If the
2995// current state is different, we update our state, and return true meaning
2996// "yes, change". If we did see a change, we also set m_needs_update to true,
2997// so future calls to NeedsUpdate will return true. exe_scope will be set to
2998// the current execution context scope.
Jim Ingham6035b672011-03-31 00:19:25 +00002999
Kate Stoneb9c1b512016-09-06 20:57:50 +00003000bool ValueObject::EvaluationPoint::SyncWithProcessState(
3001 bool accept_invalid_exe_ctx) {
Adrian Prantl05097242018-04-30 16:49:04 +00003002 // Start with the target, if it is NULL, then we're obviously not going to
3003 // get any further:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003004 const bool thread_and_frame_only_if_stopped = true;
3005 ExecutionContext exe_ctx(
3006 m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
3007
3008 if (exe_ctx.GetTargetPtr() == NULL)
3009 return false;
3010
3011 // If we don't have a process nothing can change.
3012 Process *process = exe_ctx.GetProcessPtr();
3013 if (process == NULL)
3014 return false;
3015
3016 // If our stop id is the current stop ID, nothing has changed:
3017 ProcessModID current_mod_id = process->GetModID();
3018
3019 // If the current stop id is 0, either we haven't run yet, or the process
Adrian Prantl05097242018-04-30 16:49:04 +00003020 // state has been cleared. In either case, we aren't going to be able to sync
3021 // with the process state.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003022 if (current_mod_id.GetStopID() == 0)
3023 return false;
3024
3025 bool changed = false;
3026 const bool was_valid = m_mod_id.IsValid();
3027 if (was_valid) {
3028 if (m_mod_id == current_mod_id) {
Adrian Prantl05097242018-04-30 16:49:04 +00003029 // Everything is already up to date in this object, no need to update the
3030 // execution context scope.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003031 changed = false;
3032 } else {
3033 m_mod_id = current_mod_id;
3034 m_needs_update = true;
3035 changed = true;
3036 }
3037 }
3038
3039 // Now re-look up the thread and frame in case the underlying objects have
Adrian Prantl05097242018-04-30 16:49:04 +00003040 // gone away & been recreated. That way we'll be sure to return a valid
3041 // exe_scope. If we used to have a thread or a frame but can't find it
3042 // anymore, then mark ourselves as invalid.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003043
3044 if (!accept_invalid_exe_ctx) {
3045 if (m_exe_ctx_ref.HasThreadRef()) {
3046 ThreadSP thread_sp(m_exe_ctx_ref.GetThreadSP());
3047 if (thread_sp) {
3048 if (m_exe_ctx_ref.HasFrameRef()) {
3049 StackFrameSP frame_sp(m_exe_ctx_ref.GetFrameSP());
3050 if (!frame_sp) {
3051 // We used to have a frame, but now it is gone
3052 SetInvalid();
3053 changed = was_valid;
3054 }
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003055 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003056 } else {
3057 // We used to have a thread, but now it is gone
3058 SetInvalid();
3059 changed = was_valid;
3060 }
Greg Clayton7e9b1fd2011-08-12 21:40:01 +00003061 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003062 }
Enrico Granatabb642e52015-05-16 01:27:00 +00003063
Kate Stoneb9c1b512016-09-06 20:57:50 +00003064 return changed;
Jim Ingham6035b672011-03-31 00:19:25 +00003065}
3066
Kate Stoneb9c1b512016-09-06 20:57:50 +00003067void ValueObject::EvaluationPoint::SetUpdated() {
3068 ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
3069 if (process_sp)
3070 m_mod_id = process_sp->GetModID();
3071 m_needs_update = false;
Johnny Chen44805302011-07-19 19:48:13 +00003072}
Enrico Granata9128ee22011-09-06 19:20:51 +00003073
Kate Stoneb9c1b512016-09-06 20:57:50 +00003074void ValueObject::ClearUserVisibleData(uint32_t clear_mask) {
3075 if ((clear_mask & eClearUserVisibleDataItemsValue) ==
3076 eClearUserVisibleDataItemsValue)
3077 m_value_str.clear();
3078
3079 if ((clear_mask & eClearUserVisibleDataItemsLocation) ==
3080 eClearUserVisibleDataItemsLocation)
3081 m_location_str.clear();
3082
3083 if ((clear_mask & eClearUserVisibleDataItemsSummary) ==
3084 eClearUserVisibleDataItemsSummary)
3085 m_summary_str.clear();
3086
3087 if ((clear_mask & eClearUserVisibleDataItemsDescription) ==
3088 eClearUserVisibleDataItemsDescription)
3089 m_object_desc_str.clear();
3090
3091 if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) ==
3092 eClearUserVisibleDataItemsSyntheticChildren) {
3093 if (m_synthetic_value)
3094 m_synthetic_value = NULL;
3095 }
3096
3097 if ((clear_mask & eClearUserVisibleDataItemsValidator) ==
3098 eClearUserVisibleDataItemsValidator)
3099 m_validation_result.reset();
Enrico Granata9128ee22011-09-06 19:20:51 +00003100}
Enrico Granatab2698cd2012-09-13 18:27:09 +00003101
Kate Stoneb9c1b512016-09-06 20:57:50 +00003102SymbolContextScope *ValueObject::GetSymbolContextScope() {
3103 if (m_parent) {
3104 if (!m_parent->IsPointerOrReferenceType())
3105 return m_parent->GetSymbolContextScope();
3106 }
3107 return NULL;
Enrico Granata972be532014-12-17 21:18:43 +00003108}
3109
Zachary Turneraa5611f2016-11-13 03:29:46 +00003110lldb::ValueObjectSP
3111ValueObject::CreateValueObjectFromExpression(llvm::StringRef name,
3112 llvm::StringRef expression,
3113 const ExecutionContext &exe_ctx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003114 return CreateValueObjectFromExpression(name, expression, exe_ctx,
3115 EvaluateExpressionOptions());
3116}
Enrico Granata972be532014-12-17 21:18:43 +00003117
Kate Stoneb9c1b512016-09-06 20:57:50 +00003118lldb::ValueObjectSP ValueObject::CreateValueObjectFromExpression(
Zachary Turneraa5611f2016-11-13 03:29:46 +00003119 llvm::StringRef name, llvm::StringRef expression,
3120 const ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003121 lldb::ValueObjectSP retval_sp;
3122 lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
3123 if (!target_sp)
Enrico Granatab2698cd2012-09-13 18:27:09 +00003124 return retval_sp;
Zachary Turneraa5611f2016-11-13 03:29:46 +00003125 if (expression.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003126 return retval_sp;
3127 target_sp->EvaluateExpression(expression, exe_ctx.GetFrameSP().get(),
3128 retval_sp, options);
Zachary Turneraa5611f2016-11-13 03:29:46 +00003129 if (retval_sp && !name.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003130 retval_sp->SetName(ConstString(name));
3131 return retval_sp;
Enrico Granatab2698cd2012-09-13 18:27:09 +00003132}
3133
Zachary Turneraa5611f2016-11-13 03:29:46 +00003134lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress(
3135 llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
3136 CompilerType type) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00003137 if (type) {
3138 CompilerType pointer_type(type.GetPointerType());
3139 if (pointer_type) {
3140 lldb::DataBufferSP buffer(
3141 new lldb_private::DataBufferHeap(&address, sizeof(lldb::addr_t)));
3142 lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(
3143 exe_ctx.GetBestExecutionContextScope(), pointer_type,
3144 ConstString(name), buffer, exe_ctx.GetByteOrder(),
3145 exe_ctx.GetAddressByteSize()));
3146 if (ptr_result_valobj_sp) {
3147 ptr_result_valobj_sp->GetValue().SetValueType(
3148 Value::eValueTypeLoadAddress);
Zachary Turner97206d52017-05-12 04:51:55 +00003149 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003150 ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
Zachary Turneraa5611f2016-11-13 03:29:46 +00003151 if (ptr_result_valobj_sp && !name.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003152 ptr_result_valobj_sp->SetName(ConstString(name));
3153 }
3154 return ptr_result_valobj_sp;
Enrico Granatab2698cd2012-09-13 18:27:09 +00003155 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003156 }
3157 return lldb::ValueObjectSP();
Enrico Granatab2698cd2012-09-13 18:27:09 +00003158}
3159
Kate Stoneb9c1b512016-09-06 20:57:50 +00003160lldb::ValueObjectSP ValueObject::CreateValueObjectFromData(
Zachary Turneraa5611f2016-11-13 03:29:46 +00003161 llvm::StringRef name, const DataExtractor &data,
Kate Stoneb9c1b512016-09-06 20:57:50 +00003162 const ExecutionContext &exe_ctx, CompilerType type) {
3163 lldb::ValueObjectSP new_value_sp;
3164 new_value_sp = ValueObjectConstResult::Create(
3165 exe_ctx.GetBestExecutionContextScope(), type, ConstString(name), data,
3166 LLDB_INVALID_ADDRESS);
3167 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
Zachary Turneraa5611f2016-11-13 03:29:46 +00003168 if (new_value_sp && !name.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +00003169 new_value_sp->SetName(ConstString(name));
3170 return new_value_sp;
Enrico Granatab2698cd2012-09-13 18:27:09 +00003171}
Enrico Granata4873e522013-04-11 22:48:58 +00003172
Kate Stoneb9c1b512016-09-06 20:57:50 +00003173ModuleSP ValueObject::GetModule() {
3174 ValueObject *root(GetRoot());
3175 if (root != this)
3176 return root->GetModule();
3177 return lldb::ModuleSP();
3178}
3179
3180ValueObject *ValueObject::GetRoot() {
3181 if (m_root)
3182 return m_root;
3183 return (m_root = FollowParentChain([](ValueObject *vo) -> bool {
3184 return (vo->m_parent != nullptr);
3185 }));
3186}
3187
3188ValueObject *
3189ValueObject::FollowParentChain(std::function<bool(ValueObject *)> f) {
3190 ValueObject *vo = this;
3191 while (vo) {
Jonas Devliegherea6682a42018-12-15 00:15:33 +00003192 if (!f(vo))
Kate Stoneb9c1b512016-09-06 20:57:50 +00003193 break;
3194 vo = vo->m_parent;
3195 }
3196 return vo;
3197}
3198
3199AddressType ValueObject::GetAddressTypeOfChildren() {
3200 if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) {
3201 ValueObject *root(GetRoot());
Enrico Granata4873e522013-04-11 22:48:58 +00003202 if (root != this)
Kate Stoneb9c1b512016-09-06 20:57:50 +00003203 return root->GetAddressTypeOfChildren();
3204 }
3205 return m_address_type_of_ptr_or_ref_children;
Enrico Granata4873e522013-04-11 22:48:58 +00003206}
3207
Kate Stoneb9c1b512016-09-06 20:57:50 +00003208lldb::DynamicValueType ValueObject::GetDynamicValueType() {
3209 ValueObject *with_dv_info = this;
3210 while (with_dv_info) {
3211 if (with_dv_info->HasDynamicValueTypeInfo())
3212 return with_dv_info->GetDynamicValueTypeImpl();
3213 with_dv_info = with_dv_info->m_parent;
3214 }
3215 return lldb::eNoDynamicValues;
Enrico Granatade61eba2015-01-22 03:07:34 +00003216}
3217
Kate Stoneb9c1b512016-09-06 20:57:50 +00003218lldb::Format ValueObject::GetFormat() const {
3219 const ValueObject *with_fmt_info = this;
3220 while (with_fmt_info) {
3221 if (with_fmt_info->m_format != lldb::eFormatDefault)
3222 return with_fmt_info->m_format;
3223 with_fmt_info = with_fmt_info->m_parent;
3224 }
3225 return m_format;
Enrico Granata4873e522013-04-11 22:48:58 +00003226}
3227
Kate Stoneb9c1b512016-09-06 20:57:50 +00003228lldb::LanguageType ValueObject::GetPreferredDisplayLanguage() {
3229 lldb::LanguageType type = m_preferred_display_language;
3230 if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
3231 if (GetRoot()) {
3232 if (GetRoot() == this) {
3233 if (StackFrameSP frame_sp = GetFrameSP()) {
3234 const SymbolContext &sc(
3235 frame_sp->GetSymbolContext(eSymbolContextCompUnit));
3236 if (CompileUnit *cu = sc.comp_unit)
3237 type = cu->GetLanguage();
Enrico Granatac1247f52014-11-06 21:23:20 +00003238 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003239 } else {
3240 type = GetRoot()->GetPreferredDisplayLanguage();
3241 }
Enrico Granatac1247f52014-11-06 21:23:20 +00003242 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003243 }
3244 return (m_preferred_display_language = type); // only compute it once
Enrico Granataed3228a2015-01-21 01:47:13 +00003245}
3246
Kate Stoneb9c1b512016-09-06 20:57:50 +00003247void ValueObject::SetPreferredDisplayLanguage(lldb::LanguageType lt) {
3248 m_preferred_display_language = lt;
Enrico Granatac1247f52014-11-06 21:23:20 +00003249}
3250
Kate Stoneb9c1b512016-09-06 20:57:50 +00003251void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {
3252 if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
3253 SetPreferredDisplayLanguage(lt);
Enrico Granata73e8c4d2015-10-07 02:36:35 +00003254}
3255
Kate Stoneb9c1b512016-09-06 20:57:50 +00003256bool ValueObject::CanProvideValue() {
Adrian Prantl05097242018-04-30 16:49:04 +00003257 // we need to support invalid types as providers of values because some bare-
3258 // board debugging scenarios have no notion of types, but still manage to
3259 // have raw numeric values for things like registers. sigh.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003260 const CompilerType &type(GetCompilerType());
Jonas Devliegherea6682a42018-12-15 00:15:33 +00003261 return (!type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue));
Sean Callanan7375f3e2014-12-09 21:18:59 +00003262}
3263
Kate Stoneb9c1b512016-09-06 20:57:50 +00003264bool ValueObject::IsChecksumEmpty() { return m_value_checksum.empty(); }
3265
3266ValueObjectSP ValueObject::Persist() {
3267 if (!UpdateValueIfNeeded())
3268 return nullptr;
3269
3270 TargetSP target_sp(GetTargetSP());
3271 if (!target_sp)
3272 return nullptr;
3273
3274 PersistentExpressionState *persistent_state =
3275 target_sp->GetPersistentExpressionStateForLanguage(
3276 GetPreferredDisplayLanguage());
3277
3278 if (!persistent_state)
3279 return nullptr;
3280
Adrian Prantl03219f72018-04-30 23:59:17 +00003281 auto prefix = persistent_state->GetPersistentVariablePrefix();
3282 ConstString name =
3283 persistent_state->GetNextPersistentVariableName(*target_sp, prefix);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003284
3285 ValueObjectSP const_result_sp =
3286 ValueObjectConstResult::Create(target_sp.get(), GetValue(), name);
3287
3288 ExpressionVariableSP clang_var_sp =
3289 persistent_state->CreatePersistentVariable(const_result_sp);
3290 clang_var_sp->m_live_sp = clang_var_sp->m_frozen_sp;
3291 clang_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference;
3292
3293 return clang_var_sp->GetValueObject();
Enrico Granatad07cfd32014-10-08 18:27:36 +00003294}
Enrico Granata0c10a852014-12-08 23:13:56 +00003295
Kate Stoneb9c1b512016-09-06 20:57:50 +00003296bool ValueObject::IsSyntheticChildrenGenerated() {
3297 return m_is_synthetic_children_generated;
Enrico Granata0c10a852014-12-08 23:13:56 +00003298}
Enrico Granatae29df232014-12-09 19:51:20 +00003299
Kate Stoneb9c1b512016-09-06 20:57:50 +00003300void ValueObject::SetSyntheticChildrenGenerated(bool b) {
3301 m_is_synthetic_children_generated = b;
Enrico Granatae29df232014-12-09 19:51:20 +00003302}
3303
Kate Stoneb9c1b512016-09-06 20:57:50 +00003304uint64_t ValueObject::GetLanguageFlags() { return m_language_flags; }
Enrico Granatadc62ffd2015-11-09 19:27:34 +00003305
Kate Stoneb9c1b512016-09-06 20:57:50 +00003306void ValueObject::SetLanguageFlags(uint64_t flags) { m_language_flags = flags; }
Greg Clayton8369b282016-12-28 21:22:37 +00003307
3308ValueObjectManager::ValueObjectManager(lldb::ValueObjectSP in_valobj_sp,
3309 lldb::DynamicValueType use_dynamic,
3310 bool use_synthetic) : m_root_valobj_sp(),
3311 m_user_valobj_sp(), m_use_dynamic(use_dynamic), m_stop_id(UINT32_MAX),
3312 m_use_synthetic(use_synthetic) {
3313 if (!in_valobj_sp)
3314 return;
3315 // If the user passes in a value object that is dynamic or synthetic, then
3316 // water it down to the static type.
3317 m_root_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(lldb::eNoDynamicValues, false);
3318}
3319
3320bool ValueObjectManager::IsValid() const {
3321 if (!m_root_valobj_sp)
3322 return false;
3323 lldb::TargetSP target_sp = GetTargetSP();
3324 if (target_sp)
3325 return target_sp->IsValid();
3326 return false;
3327}
3328
3329lldb::ValueObjectSP ValueObjectManager::GetSP() {
3330 lldb::ProcessSP process_sp = GetProcessSP();
3331 if (!process_sp)
3332 return lldb::ValueObjectSP();
3333
3334 const uint32_t current_stop_id = process_sp->GetLastNaturalStopID();
3335 if (current_stop_id == m_stop_id)
3336 return m_user_valobj_sp;
3337
3338 m_stop_id = current_stop_id;
3339
3340 if (!m_root_valobj_sp) {
3341 m_user_valobj_sp.reset();
3342 return m_root_valobj_sp;
3343 }
3344
3345 m_user_valobj_sp = m_root_valobj_sp;
3346
3347 if (m_use_dynamic != lldb::eNoDynamicValues) {
3348 lldb::ValueObjectSP dynamic_sp = m_user_valobj_sp->GetDynamicValue(m_use_dynamic);
3349 if (dynamic_sp)
3350 m_user_valobj_sp = dynamic_sp;
3351 }
3352
3353 if (m_use_synthetic) {
3354 lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(m_use_synthetic);
3355 if (synthetic_sp)
3356 m_user_valobj_sp = synthetic_sp;
3357 }
3358
3359 return m_user_valobj_sp;
3360}
3361
3362void ValueObjectManager::SetUseDynamic(lldb::DynamicValueType use_dynamic) {
3363 if (use_dynamic != m_use_dynamic) {
3364 m_use_dynamic = use_dynamic;
3365 m_user_valobj_sp.reset();
3366 m_stop_id = UINT32_MAX;
3367 }
3368}
3369
3370void ValueObjectManager::SetUseSynthetic(bool use_synthetic) {
3371 if (m_use_synthetic != use_synthetic) {
3372 m_use_synthetic = use_synthetic;
3373 m_user_valobj_sp.reset();
3374 m_stop_id = UINT32_MAX;
3375 }
3376}
3377
3378lldb::TargetSP ValueObjectManager::GetTargetSP() const {
3379 if (!m_root_valobj_sp)
3380 return m_root_valobj_sp->GetTargetSP();
3381 return lldb::TargetSP();
3382}
3383
3384lldb::ProcessSP ValueObjectManager::GetProcessSP() const {
3385 if (m_root_valobj_sp)
3386 return m_root_valobj_sp->GetProcessSP();
3387 return lldb::ProcessSP();
3388}
3389
3390lldb::ThreadSP ValueObjectManager::GetThreadSP() const {
3391 if (m_root_valobj_sp)
3392 return m_root_valobj_sp->GetThreadSP();
3393 return lldb::ThreadSP();
3394}
3395
3396lldb::StackFrameSP ValueObjectManager::GetFrameSP() const {
3397 if (m_root_valobj_sp)
3398 return m_root_valobj_sp->GetFrameSP();
3399 return lldb::StackFrameSP();
3400}
3401