blob: b0dd04ab9a03c41608d0217a601540c342902ba5 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ValueObject.cpp -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/ValueObject.h"
11
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000012#include "lldb/Core/Address.h"
Greg Clayton1f746072012-08-29 21:13:06 +000013#include "lldb/Core/Module.h"
Enrico Granata21fd13f2012-10-27 02:05:48 +000014#include "lldb/Core/ValueObjectCast.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Core/ValueObjectChild.h"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000016#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000017#include "lldb/Core/ValueObjectDynamicValue.h"
Greg Claytonb2dcc362011-05-05 23:32:56 +000018#include "lldb/Core/ValueObjectMemory.h"
Enrico Granatad55546b2011-07-22 00:16:08 +000019#include "lldb/Core/ValueObjectSyntheticFilter.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000020#include "lldb/DataFormatters/DataVisualization.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000021#include "lldb/DataFormatters/DumpValueObjectOptions.h"
22#include "lldb/DataFormatters/FormatManager.h"
Enrico Granata2206b482014-10-30 18:27:31 +000023#include "lldb/DataFormatters/StringPrinter.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000024#include "lldb/DataFormatters/TypeFormat.h"
25#include "lldb/DataFormatters/TypeSummary.h"
26#include "lldb/DataFormatters/TypeValidator.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000027#include "lldb/DataFormatters/ValueObjectPrinter.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000028#include "lldb/Expression/ExpressionVariable.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Symbol/ClangASTContext.h"
Enrico Granatac1247f52014-11-06 21:23:20 +000030#include "lldb/Symbol/CompileUnit.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000031#include "lldb/Symbol/CompilerType.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000032#include "lldb/Symbol/Declaration.h"
33#include "lldb/Symbol/SymbolContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Symbol/Type.h"
Jim Ingham53c47f12010-09-10 23:12:17 +000035#include "lldb/Target/ExecutionContext.h"
Enrico Granata407b5c62015-11-02 21:52:05 +000036#include "lldb/Target/Language.h"
Jim Ingham5a369122010-09-28 01:25:32 +000037#include "lldb/Target/LanguageRuntime.h"
Enrico Granatac3e320a2011-08-02 17:27:39 +000038#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Target/Process.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000040#include "lldb/Target/StackFrame.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000041#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042#include "lldb/Target/Thread.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000043#include "lldb/Target/ThreadList.h"
44#include "lldb/Utility/DataBuffer.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000045#include "lldb/Utility/DataBufferHeap.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000046#include "lldb/Utility/Flags.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000047#include "lldb/Utility/Log.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000048#include "lldb/Utility/Logging.h"
49#include "lldb/Utility/Scalar.h"
50#include "lldb/Utility/SharingPtr.h"
51#include "lldb/Utility/Stream.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000052#include "lldb/Utility/StreamString.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000053#include "lldb/lldb-private-types.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000054
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000055#include "llvm/Support/Compiler.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000056
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000057#include <algorithm>
58#include <cstdint>
59#include <cstdlib>
60#include <memory>
61#include <tuple>
Zachary Turner2f3df612017-04-06 21:28:29 +000062
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000063#include <assert.h>
64#include <inttypes.h>
65#include <stdio.h>
66#include <string.h>
Zachary Turner2f3df612017-04-06 21:28:29 +000067
68namespace lldb_private {
69class ExecutionContextScope;
70}
71namespace lldb_private {
72class SymbolContextScope;
73}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000074
75using namespace lldb;
76using namespace lldb_private;
Enrico Granataf4efecd2011-07-12 22:56:10 +000077using namespace lldb_utility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078
Greg Claytonafacd142011-09-02 01:15:17 +000079static user_id_t g_value_obj_uid = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080
81//----------------------------------------------------------------------
82// ValueObject constructor
83//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000084ValueObject::ValueObject(ValueObject &parent)
85 : UserID(++g_value_obj_uid), // Unique identifier for every value object
86 m_parent(&parent), m_root(NULL), m_update_point(parent.GetUpdatePoint()),
87 m_name(), m_data(), m_value(), m_error(), m_value_str(),
88 m_old_value_str(), m_location_str(), m_summary_str(), m_object_desc_str(),
89 m_validation_result(), m_manager(parent.GetManager()), m_children(),
90 m_synthetic_children(), m_dynamic_value(NULL), m_synthetic_value(NULL),
91 m_deref_valobj(NULL), m_format(eFormatDefault),
92 m_last_format(eFormatDefault), m_last_format_mgr_revision(0),
93 m_type_summary_sp(), m_type_format_sp(), m_synthetic_children_sp(),
94 m_type_validator_sp(), m_user_id_of_forced_summary(),
95 m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid),
96 m_value_checksum(),
97 m_preferred_display_language(lldb::eLanguageTypeUnknown),
98 m_language_flags(0), m_value_is_valid(false), m_value_did_change(false),
99 m_children_count_valid(false), m_old_value_valid(false),
100 m_is_deref_of_parent(false), m_is_array_item_for_pointer(false),
101 m_is_bitfield_for_scalar(false), m_is_child_at_offset(false),
102 m_is_getting_summary(false),
103 m_did_calculate_complete_objc_class_type(false),
104 m_is_synthetic_children_generated(
105 parent.m_is_synthetic_children_generated) {
106 m_manager->ManageObject(this);
Jim Ingham6035b672011-03-31 00:19:25 +0000107}
108
109//----------------------------------------------------------------------
110// ValueObject constructor
111//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112ValueObject::ValueObject(ExecutionContextScope *exe_scope,
113 AddressType child_ptr_or_ref_addr_type)
114 : UserID(++g_value_obj_uid), // Unique identifier for every value object
115 m_parent(NULL), m_root(NULL), m_update_point(exe_scope), m_name(),
116 m_data(), m_value(), m_error(), m_value_str(), m_old_value_str(),
117 m_location_str(), m_summary_str(), m_object_desc_str(),
118 m_validation_result(), m_manager(), m_children(), m_synthetic_children(),
119 m_dynamic_value(NULL), m_synthetic_value(NULL), m_deref_valobj(NULL),
120 m_format(eFormatDefault), m_last_format(eFormatDefault),
121 m_last_format_mgr_revision(0), m_type_summary_sp(), m_type_format_sp(),
122 m_synthetic_children_sp(), m_type_validator_sp(),
123 m_user_id_of_forced_summary(),
124 m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
125 m_value_checksum(),
126 m_preferred_display_language(lldb::eLanguageTypeUnknown),
127 m_language_flags(0), m_value_is_valid(false), m_value_did_change(false),
128 m_children_count_valid(false), m_old_value_valid(false),
129 m_is_deref_of_parent(false), m_is_array_item_for_pointer(false),
130 m_is_bitfield_for_scalar(false), m_is_child_at_offset(false),
131 m_is_getting_summary(false),
132 m_did_calculate_complete_objc_class_type(false),
133 m_is_synthetic_children_generated(false) {
134 m_manager = new ValueObjectManager();
135 m_manager->ManageObject(this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000136}
137
138//----------------------------------------------------------------------
139// Destructor
140//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141ValueObject::~ValueObject() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000142
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143bool ValueObject::UpdateValueIfNeeded(bool update_format) {
Greg Claytonb71f3842010-10-05 03:13:51 +0000144
Kate Stoneb9c1b512016-09-06 20:57:50 +0000145 bool did_change_formats = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 if (update_format)
148 did_change_formats = UpdateFormatsIfNeeded();
Greg Claytonefbc7d22012-03-09 04:23:44 +0000149
Adrian Prantl05097242018-04-30 16:49:04 +0000150 // If this is a constant value, then our success is predicated on whether we
151 // have an error or not
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152 if (GetIsConstant()) {
153 // if you are constant, things might still have changed behind your back
154 // (e.g. you are a frozen object and things have changed deeper than you
Adrian Prantl05097242018-04-30 16:49:04 +0000155 // cared to freeze-dry yourself) in this case, your value has not changed,
156 // but "computed" entries might have, so you might now have a different
157 // summary, or a different object description. clear these so we will
158 // recompute them
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 if (update_format && !did_change_formats)
160 ClearUserVisibleData(eClearUserVisibleDataItemsSummary |
161 eClearUserVisibleDataItemsDescription);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162 return m_error.Success();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 }
164
165 bool first_update = IsChecksumEmpty();
166
167 if (NeedsUpdating()) {
168 m_update_point.SetUpdated();
169
Adrian Prantl05097242018-04-30 16:49:04 +0000170 // Save the old value using swap to avoid a string copy which also will
171 // clear our m_value_str
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172 if (m_value_str.empty()) {
173 m_old_value_valid = false;
174 } else {
175 m_old_value_valid = true;
176 m_old_value_str.swap(m_value_str);
177 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
178 }
179
180 ClearUserVisibleData();
181
182 if (IsInScope()) {
183 const bool value_was_valid = GetValueIsValid();
184 SetValueDidChange(false);
185
186 m_error.Clear();
187
188 // Call the pure virtual function to update the value
189
190 bool need_compare_checksums = false;
191 llvm::SmallVector<uint8_t, 16> old_checksum;
192
193 if (!first_update && CanProvideValue()) {
194 need_compare_checksums = true;
195 old_checksum.resize(m_value_checksum.size());
196 std::copy(m_value_checksum.begin(), m_value_checksum.end(),
197 old_checksum.begin());
198 }
199
200 bool success = UpdateValue();
201
202 SetValueIsValid(success);
203
204 if (success) {
205 const uint64_t max_checksum_size = 128;
206 m_data.Checksum(m_value_checksum, max_checksum_size);
207 } else {
208 need_compare_checksums = false;
209 m_value_checksum.clear();
210 }
211
212 assert(!need_compare_checksums ||
213 (!old_checksum.empty() && !m_value_checksum.empty()));
214
215 if (first_update)
216 SetValueDidChange(false);
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000217 else if (!m_value_did_change && !success) {
Adrian Prantl05097242018-04-30 16:49:04 +0000218 // The value wasn't gotten successfully, so we mark this as changed if
219 // the value used to be valid and now isn't
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220 SetValueDidChange(value_was_valid);
221 } else if (need_compare_checksums) {
222 SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0],
223 m_value_checksum.size()));
224 }
225
226 } else {
227 m_error.SetErrorString("out of scope");
228 }
229 }
230 return m_error.Success();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000231}
232
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233bool ValueObject::UpdateFormatsIfNeeded() {
234 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
235 if (log)
236 log->Printf("[%s %p] checking for FormatManager revisions. ValueObject "
237 "rev: %d - Global rev: %d",
238 GetName().GetCString(), static_cast<void *>(this),
239 m_last_format_mgr_revision,
240 DataVisualization::GetCurrentRevision());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000241
Kate Stoneb9c1b512016-09-06 20:57:50 +0000242 bool any_change = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000243
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244 if ((m_last_format_mgr_revision != DataVisualization::GetCurrentRevision())) {
245 m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
246 any_change = true;
247
248 SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues));
249 SetSummaryFormat(
250 DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000251#ifndef LLDB_DISABLE_PYTHON
Kate Stoneb9c1b512016-09-06 20:57:50 +0000252 SetSyntheticChildren(
253 DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000254#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000255 SetValidator(DataVisualization::GetValidator(*this, GetDynamicValueType()));
256 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000257
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 return any_change;
Enrico Granata4becb372011-06-29 22:27:15 +0000259}
260
Kate Stoneb9c1b512016-09-06 20:57:50 +0000261void ValueObject::SetNeedsUpdate() {
262 m_update_point.SetNeedsUpdate();
263 // We have to clear the value string here so ConstResult children will notice
Adrian Prantl05097242018-04-30 16:49:04 +0000264 // if their values are changed by hand (i.e. with SetValueAsCString).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
Jim Ingham16e0c682011-08-12 23:34:31 +0000266}
267
Kate Stoneb9c1b512016-09-06 20:57:50 +0000268void ValueObject::ClearDynamicTypeInformation() {
269 m_children_count_valid = false;
270 m_did_calculate_complete_objc_class_type = false;
271 m_last_format_mgr_revision = 0;
272 m_override_type = CompilerType();
273 SetValueFormat(lldb::TypeFormatImplSP());
274 SetSummaryFormat(lldb::TypeSummaryImplSP());
275 SetSyntheticChildren(lldb::SyntheticChildrenSP());
Enrico Granata13ac0e22012-10-17 19:03:34 +0000276}
277
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278CompilerType ValueObject::MaybeCalculateCompleteType() {
279 CompilerType compiler_type(GetCompilerTypeImpl());
280
281 if (m_did_calculate_complete_objc_class_type) {
282 if (m_override_type.IsValid())
283 return m_override_type;
Sean Callanan72772842012-02-22 23:57:45 +0000284 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000285 return compiler_type;
286 }
287
288 CompilerType class_type;
289 bool is_pointer_type = false;
290
291 if (ClangASTContext::IsObjCObjectPointerType(compiler_type, &class_type)) {
292 is_pointer_type = true;
293 } else if (ClangASTContext::IsObjCObjectOrInterfaceType(compiler_type)) {
294 class_type = compiler_type;
295 } else {
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000296 return compiler_type;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000297 }
298
299 m_did_calculate_complete_objc_class_type = true;
300
301 if (class_type) {
302 ConstString class_name(class_type.GetConstTypeName());
303
304 if (class_name) {
305 ProcessSP process_sp(
306 GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
307
308 if (process_sp) {
309 ObjCLanguageRuntime *objc_language_runtime(
310 process_sp->GetObjCLanguageRuntime());
311
312 if (objc_language_runtime) {
313 TypeSP complete_objc_class_type_sp =
314 objc_language_runtime->LookupInCompleteClassCache(class_name);
315
316 if (complete_objc_class_type_sp) {
317 CompilerType complete_class(
318 complete_objc_class_type_sp->GetFullCompilerType());
319
320 if (complete_class.GetCompleteType()) {
321 if (is_pointer_type) {
322 m_override_type = complete_class.GetPointerType();
323 } else {
324 m_override_type = complete_class;
325 }
326
327 if (m_override_type.IsValid())
328 return m_override_type;
329 }
330 }
331 }
332 }
333 }
334 }
335 return compiler_type;
Sean Callanan72772842012-02-22 23:57:45 +0000336}
337
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338CompilerType ValueObject::GetCompilerType() {
339 return MaybeCalculateCompleteType();
Sean Callanan72772842012-02-22 23:57:45 +0000340}
341
Kate Stoneb9c1b512016-09-06 20:57:50 +0000342TypeImpl ValueObject::GetTypeImpl() { return TypeImpl(GetCompilerType()); }
343
344DataExtractor &ValueObject::GetDataExtractor() {
345 UpdateValueIfNeeded(false);
346 return m_data;
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000347}
348
Zachary Turner97206d52017-05-12 04:51:55 +0000349const Status &ValueObject::GetError() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350 UpdateValueIfNeeded(false);
351 return m_error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352}
353
Kate Stoneb9c1b512016-09-06 20:57:50 +0000354const ConstString &ValueObject::GetName() const { return m_name; }
355
356const char *ValueObject::GetLocationAsCString() {
357 return GetLocationAsCStringImpl(m_value, m_data);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358}
359
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
361 const DataExtractor &data) {
362 if (UpdateValueIfNeeded(false)) {
363 if (m_location_str.empty()) {
364 StreamString sstr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000365
Kate Stoneb9c1b512016-09-06 20:57:50 +0000366 Value::ValueType value_type = value.GetValueType();
Enrico Granata82fabf82013-04-30 20:45:04 +0000367
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368 switch (value_type) {
369 case Value::eValueTypeScalar:
370 case Value::eValueTypeVector:
371 if (value.GetContextType() == Value::eContextTypeRegisterInfo) {
372 RegisterInfo *reg_info = value.GetRegisterInfo();
373 if (reg_info) {
374 if (reg_info->name)
375 m_location_str = reg_info->name;
376 else if (reg_info->alt_name)
377 m_location_str = reg_info->alt_name;
378 if (m_location_str.empty())
379 m_location_str = (reg_info->encoding == lldb::eEncodingVector)
380 ? "vector"
381 : "scalar";
382 }
383 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 if (m_location_str.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000385 m_location_str =
386 (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
387 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388
Kate Stoneb9c1b512016-09-06 20:57:50 +0000389 case Value::eValueTypeLoadAddress:
390 case Value::eValueTypeFileAddress:
391 case Value::eValueTypeHostAddress: {
392 uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
393 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size,
394 value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
Zachary Turnerc1564272016-11-16 21:15:24 +0000395 m_location_str = sstr.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000396 } break;
397 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000399 }
400 return m_location_str.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000401}
402
Kate Stoneb9c1b512016-09-06 20:57:50 +0000403Value &ValueObject::GetValue() { return m_value; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404
Kate Stoneb9c1b512016-09-06 20:57:50 +0000405const Value &ValueObject::GetValue() const { return m_value; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406
Kate Stoneb9c1b512016-09-06 20:57:50 +0000407bool ValueObject::ResolveValue(Scalar &scalar) {
408 if (UpdateValueIfNeeded(
409 false)) // make sure that you are up to date before returning anything
410 {
411 ExecutionContext exe_ctx(GetExecutionContextRef());
412 Value tmp_value(m_value);
413 scalar = tmp_value.ResolveValue(&exe_ctx);
414 if (scalar.IsValid()) {
415 const uint32_t bitfield_bit_size = GetBitfieldBitSize();
416 if (bitfield_bit_size)
417 return scalar.ExtractBitfield(bitfield_bit_size,
418 GetBitfieldBitOffset());
419 return true;
Enrico Granata6fd87d52011-08-04 01:41:02 +0000420 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421 }
422 return false;
423}
424
Zachary Turner97206d52017-05-12 04:51:55 +0000425bool ValueObject::IsLogicalTrue(Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
427 LazyBool is_logical_true = language->IsLogicalTrue(*this, error);
428 switch (is_logical_true) {
429 case eLazyBoolYes:
430 case eLazyBoolNo:
431 return (is_logical_true == true);
432 case eLazyBoolCalculate:
433 break;
434 }
435 }
436
437 Scalar scalar_value;
438
439 if (!ResolveValue(scalar_value)) {
440 error.SetErrorString("failed to get a scalar result");
Greg Claytondcad5022011-12-29 01:26:56 +0000441 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 }
443
444 bool ret;
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000445 ret = scalar_value.ULongLong(1) != 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000446 error.Clear();
447 return ret;
Greg Clayton8f343b02010-11-04 01:54:29 +0000448}
449
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450bool ValueObject::GetValueIsValid() const { return m_value_is_valid; }
451
452void ValueObject::SetValueIsValid(bool b) { m_value_is_valid = b; }
453
454bool ValueObject::GetValueDidChange() { return m_value_did_change; }
455
456void ValueObject::SetValueDidChange(bool value_changed) {
457 m_value_did_change = value_changed;
458}
459
460ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) {
461 ValueObjectSP child_sp;
462 // We may need to update our value if we are dynamic
463 if (IsPossibleDynamicType())
464 UpdateValueIfNeeded(false);
465 if (idx < GetNumChildren()) {
466 // Check if we have already made the child value object?
467 if (can_create && !m_children.HasChildAtIndex(idx)) {
468 // No we haven't created the child at this index, so lets have our
469 // subclass do it and cache the result for quick future access.
470 m_children.SetChildAtIndex(idx, CreateChildAtIndex(idx, false, 0));
Enrico Granata407b5c62015-11-02 21:52:05 +0000471 }
Jim Ingham98e6daf2015-10-31 00:02:18 +0000472
Kate Stoneb9c1b512016-09-06 20:57:50 +0000473 ValueObject *child = m_children.GetChildAtIndex(idx);
474 if (child != NULL)
475 return child->GetSP();
476 }
477 return child_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478}
479
Enrico Granata3309d882013-01-12 01:00:22 +0000480lldb::ValueObjectSP
Lang Hames088d0012017-04-26 18:15:40 +0000481ValueObject::GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000482 size_t *index_of_error) {
483 if (idxs.size() == 0)
484 return GetSP();
485 ValueObjectSP root(GetSP());
486 for (size_t idx : idxs) {
487 root = root->GetChildAtIndex(idx, true);
488 if (!root) {
489 if (index_of_error)
490 *index_of_error = idx;
491 return root;
Enrico Granata3309d882013-01-12 01:00:22 +0000492 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000493 }
494 return root;
495}
496
497lldb::ValueObjectSP ValueObject::GetChildAtIndexPath(
Lang Hames088d0012017-04-26 18:15:40 +0000498 llvm::ArrayRef<std::pair<size_t, bool>> idxs, size_t *index_of_error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000499 if (idxs.size() == 0)
500 return GetSP();
501 ValueObjectSP root(GetSP());
502 for (std::pair<size_t, bool> idx : idxs) {
503 root = root->GetChildAtIndex(idx.first, idx.second);
504 if (!root) {
505 if (index_of_error)
506 *index_of_error = idx.first;
507 return root;
508 }
509 }
510 return root;
Enrico Granata3309d882013-01-12 01:00:22 +0000511}
512
513lldb::ValueObjectSP
Lang Hames088d0012017-04-26 18:15:40 +0000514ValueObject::GetChildAtNamePath(llvm::ArrayRef<ConstString> names,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515 ConstString *name_of_error) {
516 if (names.size() == 0)
517 return GetSP();
518 ValueObjectSP root(GetSP());
519 for (ConstString name : names) {
520 root = root->GetChildMemberWithName(name, true);
521 if (!root) {
522 if (name_of_error)
523 *name_of_error = name;
524 return root;
525 }
526 }
527 return root;
Enrico Granataef8dde62015-12-21 23:10:17 +0000528}
529
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
Lang Hames088d0012017-04-26 18:15:40 +0000531 llvm::ArrayRef<std::pair<ConstString, bool>> names,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000532 ConstString *name_of_error) {
533 if (names.size() == 0)
534 return GetSP();
535 ValueObjectSP root(GetSP());
536 for (std::pair<ConstString, bool> name : names) {
537 root = root->GetChildMemberWithName(name.first, name.second);
538 if (!root) {
539 if (name_of_error)
540 *name_of_error = name.first;
541 return root;
542 }
543 }
544 return root;
Enrico Granatae2e220a2013-09-12 00:48:47 +0000545}
546
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547size_t ValueObject::GetIndexOfChildWithName(const ConstString &name) {
548 bool omit_empty_base_classes = true;
549 return GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
550 omit_empty_base_classes);
Enrico Granatae2e220a2013-09-12 00:48:47 +0000551}
552
Kate Stoneb9c1b512016-09-06 20:57:50 +0000553ValueObjectSP ValueObject::GetChildMemberWithName(const ConstString &name,
554 bool can_create) {
Adrian Prantl05097242018-04-30 16:49:04 +0000555 // when getting a child by name, it could be buried inside some base classes
556 // (which really aren't part of the expression path), so we need a vector of
557 // indexes that can get us down to the correct child
Kate Stoneb9c1b512016-09-06 20:57:50 +0000558 ValueObjectSP child_sp;
559
560 // We may need to update our value if we are dynamic
561 if (IsPossibleDynamicType())
562 UpdateValueIfNeeded(false);
563
564 std::vector<uint32_t> child_indexes;
565 bool omit_empty_base_classes = true;
566 const size_t num_child_indexes =
567 GetCompilerType().GetIndexOfChildMemberWithName(
568 name.GetCString(), omit_empty_base_classes, child_indexes);
569 if (num_child_indexes > 0) {
570 std::vector<uint32_t>::const_iterator pos = child_indexes.begin();
571 std::vector<uint32_t>::const_iterator end = child_indexes.end();
572
573 child_sp = GetChildAtIndex(*pos, can_create);
574 for (++pos; pos != end; ++pos) {
575 if (child_sp) {
576 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex(*pos, can_create));
577 child_sp = new_child_sp;
578 } else {
579 child_sp.reset();
580 }
Enrico Granatae2e220a2013-09-12 00:48:47 +0000581 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000582 }
583 return child_sp;
Enrico Granatae2e220a2013-09-12 00:48:47 +0000584}
585
Kate Stoneb9c1b512016-09-06 20:57:50 +0000586size_t ValueObject::GetNumChildren(uint32_t max) {
587 UpdateValueIfNeeded();
588
589 if (max < UINT32_MAX) {
590 if (m_children_count_valid) {
591 size_t children_count = m_children.GetChildrenCount();
592 return children_count <= max ? children_count : max;
593 } else
594 return CalculateNumChildren(max);
595 }
596
597 if (!m_children_count_valid) {
598 SetNumChildren(CalculateNumChildren());
599 }
600 return m_children.GetChildrenCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000601}
602
Kate Stoneb9c1b512016-09-06 20:57:50 +0000603bool ValueObject::MightHaveChildren() {
604 bool has_children = false;
605 const uint32_t type_info = GetTypeInfo();
606 if (type_info) {
607 if (type_info & (eTypeHasChildren | eTypeIsPointer | eTypeIsReference))
608 has_children = true;
609 } else {
610 has_children = GetNumChildren() > 0;
611 }
612 return has_children;
Greg Clayton4a792072012-10-23 01:50:10 +0000613}
614
615// Should only be called by ValueObject::GetNumChildren()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000616void ValueObject::SetNumChildren(size_t num_children) {
617 m_children_count_valid = true;
618 m_children.SetChildrenCount(num_children);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000619}
620
Kate Stoneb9c1b512016-09-06 20:57:50 +0000621void ValueObject::SetName(const ConstString &name) { m_name = name; }
622
623ValueObject *ValueObject::CreateChildAtIndex(size_t idx,
624 bool synthetic_array_member,
625 int32_t synthetic_index) {
626 ValueObject *valobj = NULL;
627
628 bool omit_empty_base_classes = true;
629 bool ignore_array_bounds = synthetic_array_member;
630 std::string child_name_str;
631 uint32_t child_byte_size = 0;
632 int32_t child_byte_offset = 0;
633 uint32_t child_bitfield_bit_size = 0;
634 uint32_t child_bitfield_bit_offset = 0;
635 bool child_is_base_class = false;
636 bool child_is_deref_of_parent = false;
637 uint64_t language_flags = 0;
638
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000639 const bool transparent_pointers = !synthetic_array_member;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000640 CompilerType child_compiler_type;
641
642 ExecutionContext exe_ctx(GetExecutionContextRef());
643
644 child_compiler_type = GetCompilerType().GetChildCompilerTypeAtIndex(
645 &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
646 ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
647 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
648 child_is_deref_of_parent, this, language_flags);
649 if (child_compiler_type) {
650 if (synthetic_index)
651 child_byte_offset += child_byte_size * synthetic_index;
652
653 ConstString child_name;
654 if (!child_name_str.empty())
655 child_name.SetCString(child_name_str.c_str());
656
657 valobj = new ValueObjectChild(
658 *this, child_compiler_type, child_name, child_byte_size,
659 child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
660 child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
661 language_flags);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000662 }
663
664 return valobj;
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 lldb::LanguageType lang) {
670 return GetSummaryAsCString(summary_ptr, destination,
671 TypeSummaryOptions().SetLanguage(lang));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672}
673
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
675 std::string &destination,
676 const TypeSummaryOptions &options) {
677 destination.clear();
678
Adrian Prantl05097242018-04-30 16:49:04 +0000679 // ideally we would like to bail out if passing NULL, but if we do so we end
680 // up not providing the summary for function pointers anymore
Kate Stoneb9c1b512016-09-06 20:57:50 +0000681 if (/*summary_ptr == NULL ||*/ m_is_getting_summary)
682 return false;
683
684 m_is_getting_summary = true;
685
686 TypeSummaryOptions actual_options(options);
687
688 if (actual_options.GetLanguage() == lldb::eLanguageTypeUnknown)
689 actual_options.SetLanguage(GetPreferredDisplayLanguage());
690
691 // this is a hot path in code and we prefer to avoid setting this string all
Adrian Prantl05097242018-04-30 16:49:04 +0000692 // too often also clearing out other information that we might care to see in
693 // a crash log. might be useful in very specific situations though.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000694 /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s.
695 Summary provider's description is %s",
696 GetTypeName().GetCString(),
697 GetName().GetCString(),
698 summary_ptr->GetDescription().c_str());*/
699
700 if (UpdateValueIfNeeded(false) && summary_ptr) {
701 if (HasSyntheticValue())
702 m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on
703 // the synthetic children being
704 // up-to-date (e.g. ${svar%#})
705 summary_ptr->FormatObject(this, destination, actual_options);
706 }
707 m_is_getting_summary = false;
708 return !destination.empty();
Enrico Granatac1247f52014-11-06 21:23:20 +0000709}
710
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711const char *ValueObject::GetSummaryAsCString(lldb::LanguageType lang) {
712 if (UpdateValueIfNeeded(true) && m_summary_str.empty()) {
713 TypeSummaryOptions summary_options;
714 summary_options.SetLanguage(lang);
715 GetSummaryAsCString(GetSummaryFormat().get(), m_summary_str,
716 summary_options);
717 }
718 if (m_summary_str.empty())
719 return NULL;
720 return m_summary_str.c_str();
721}
722
723bool ValueObject::GetSummaryAsCString(std::string &destination,
724 const TypeSummaryOptions &options) {
725 return GetSummaryAsCString(GetSummaryFormat().get(), destination, options);
726}
727
728bool ValueObject::IsCStringContainer(bool check_pointer) {
729 CompilerType pointee_or_element_compiler_type;
730 const Flags type_flags(GetTypeInfo(&pointee_or_element_compiler_type));
731 bool is_char_arr_ptr(type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
732 pointee_or_element_compiler_type.IsCharType());
733 if (!is_char_arr_ptr)
734 return false;
735 if (!check_pointer)
736 return true;
737 if (type_flags.Test(eTypeIsArray))
738 return true;
739 addr_t cstr_address = LLDB_INVALID_ADDRESS;
740 AddressType cstr_address_type = eAddressTypeInvalid;
741 cstr_address = GetAddressOf(true, &cstr_address_type);
742 return (cstr_address != LLDB_INVALID_ADDRESS);
743}
744
745size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
746 uint32_t item_count) {
747 CompilerType pointee_or_element_compiler_type;
748 const uint32_t type_info = GetTypeInfo(&pointee_or_element_compiler_type);
749 const bool is_pointer_type = type_info & eTypeIsPointer;
750 const bool is_array_type = type_info & eTypeIsArray;
751 if (!(is_pointer_type || is_array_type))
752 return 0;
753
754 if (item_count == 0)
755 return 0;
756
757 ExecutionContext exe_ctx(GetExecutionContextRef());
758
759 const uint64_t item_type_size = pointee_or_element_compiler_type.GetByteSize(
760 exe_ctx.GetBestExecutionContextScope());
761 const uint64_t bytes = item_count * item_type_size;
762 const uint64_t offset = item_idx * item_type_size;
763
764 if (item_idx == 0 && item_count == 1) // simply a deref
765 {
766 if (is_pointer_type) {
Zachary Turner97206d52017-05-12 04:51:55 +0000767 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768 ValueObjectSP pointee_sp = Dereference(error);
769 if (error.Fail() || pointee_sp.get() == NULL)
770 return 0;
771 return pointee_sp->GetData(data, error);
772 } else {
773 ValueObjectSP child_sp = GetChildAtIndex(0, true);
774 if (child_sp.get() == NULL)
775 return 0;
Zachary Turner97206d52017-05-12 04:51:55 +0000776 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000777 return child_sp->GetData(data, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000778 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000779 return true;
780 } else /* (items > 1) */
781 {
Zachary Turner97206d52017-05-12 04:51:55 +0000782 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000783 lldb_private::DataBufferHeap *heap_buf_ptr = NULL;
784 lldb::DataBufferSP data_sp(heap_buf_ptr =
785 new lldb_private::DataBufferHeap());
Enrico Granata0c489f52012-03-01 04:24:26 +0000786
Kate Stoneb9c1b512016-09-06 20:57:50 +0000787 AddressType addr_type;
788 lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type)
789 : GetAddressOf(true, &addr_type);
790
791 switch (addr_type) {
792 case eAddressTypeFile: {
793 ModuleSP module_sp(GetModule());
794 if (module_sp) {
795 addr = addr + offset;
796 Address so_addr;
797 module_sp->ResolveFileAddress(addr, so_addr);
798 ExecutionContext exe_ctx(GetExecutionContextRef());
799 Target *target = exe_ctx.GetTargetPtr();
800 if (target) {
801 heap_buf_ptr->SetByteSize(bytes);
802 size_t bytes_read = target->ReadMemory(
803 so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
804 if (error.Success()) {
805 data.SetData(data_sp);
806 return bytes_read;
807 }
808 }
809 }
810 } break;
811 case eAddressTypeLoad: {
812 ExecutionContext exe_ctx(GetExecutionContextRef());
813 Process *process = exe_ctx.GetProcessPtr();
814 if (process) {
815 heap_buf_ptr->SetByteSize(bytes);
816 size_t bytes_read = process->ReadMemory(
817 addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
818 if (error.Success() || bytes_read > 0) {
819 data.SetData(data_sp);
820 return bytes_read;
821 }
822 }
823 } break;
824 case eAddressTypeHost: {
825 const uint64_t max_bytes =
826 GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());
827 if (max_bytes > offset) {
828 size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes);
829 addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
830 if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
831 break;
832 heap_buf_ptr->CopyData((uint8_t *)(addr + offset), bytes_read);
833 data.SetData(data_sp);
834 return bytes_read;
835 }
836 } break;
837 case eAddressTypeInvalid:
838 break;
Enrico Granata0c489f52012-03-01 04:24:26 +0000839 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000840 }
841 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842}
843
Zachary Turner97206d52017-05-12 04:51:55 +0000844uint64_t ValueObject::GetData(DataExtractor &data, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000845 UpdateValueIfNeeded(false);
846 ExecutionContext exe_ctx(GetExecutionContextRef());
847 error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
848 if (error.Fail()) {
849 if (m_data.GetByteSize()) {
850 data = m_data;
851 error.Clear();
852 return data.GetByteSize();
853 } else {
854 return 0;
855 }
856 }
857 data.SetAddressByteSize(m_data.GetAddressByteSize());
858 data.SetByteOrder(m_data.GetByteOrder());
859 return data.GetByteSize();
Enrico Granata49bfafb2014-11-18 23:36:25 +0000860}
861
Zachary Turner97206d52017-05-12 04:51:55 +0000862bool ValueObject::SetData(DataExtractor &data, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000863 error.Clear();
864 // Make sure our value is up to date first so that our location and location
865 // type is valid.
866 if (!UpdateValueIfNeeded(false)) {
867 error.SetErrorString("unable to read value");
868 return false;
869 }
870
871 uint64_t count = 0;
872 const Encoding encoding = GetCompilerType().GetEncoding(count);
873
874 const size_t byte_size = GetByteSize();
875
876 Value::ValueType value_type = m_value.GetValueType();
877
878 switch (value_type) {
879 case Value::eValueTypeScalar: {
Zachary Turner97206d52017-05-12 04:51:55 +0000880 Status set_error =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000881 m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
882
883 if (!set_error.Success()) {
884 error.SetErrorStringWithFormat("unable to set scalar value: %s",
885 set_error.AsCString());
886 return false;
887 }
888 } break;
889 case Value::eValueTypeLoadAddress: {
890 // If it is a load address, then the scalar value is the storage location
891 // of the data, and we have to shove this value down to that load location.
892 ExecutionContext exe_ctx(GetExecutionContextRef());
893 Process *process = exe_ctx.GetProcessPtr();
894 if (process) {
895 addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
896 size_t bytes_written = process->WriteMemory(
897 target_addr, data.GetDataStart(), byte_size, error);
898 if (!error.Success())
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000899 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000900 if (bytes_written != byte_size) {
901 error.SetErrorString("unable to write value to memory");
902 return false;
903 }
904 }
905 } break;
906 case Value::eValueTypeHostAddress: {
907 // If it is a host address, then we stuff the scalar as a DataBuffer into
908 // the Value's data.
909 DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
910 m_data.SetData(buffer_sp, 0);
911 data.CopyByteOrderedData(0, byte_size,
912 const_cast<uint8_t *>(m_data.GetDataStart()),
913 byte_size, m_data.GetByteOrder());
914 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
915 } break;
916 case Value::eValueTypeFileAddress:
917 case Value::eValueTypeVector:
918 break;
919 }
920
Adrian Prantl05097242018-04-30 16:49:04 +0000921 // If we have reached this point, then we have successfully changed the
922 // value.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000923 SetNeedsUpdate();
924 return true;
925}
926
927static bool CopyStringDataToBufferSP(const StreamString &source,
928 lldb::DataBufferSP &destination) {
929 destination.reset(new DataBufferHeap(source.GetSize() + 1, 0));
Zachary Turnerc1564272016-11-16 21:15:24 +0000930 memcpy(destination->GetBytes(), source.GetString().data(), source.GetSize());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000931 return true;
932}
933
934std::pair<size_t, bool>
Zachary Turner97206d52017-05-12 04:51:55 +0000935ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000936 uint32_t max_length, bool honor_array,
937 Format item_format) {
938 bool was_capped = false;
939 StreamString s;
940 ExecutionContext exe_ctx(GetExecutionContextRef());
941 Target *target = exe_ctx.GetTargetPtr();
942
943 if (!target) {
944 s << "<no target to read from>";
945 error.SetErrorString("no target to read from");
946 CopyStringDataToBufferSP(s, buffer_sp);
947 return {0, was_capped};
948 }
949
950 if (max_length == 0)
951 max_length = target->GetMaximumSizeOfStringSummary();
952
953 size_t bytes_read = 0;
954 size_t total_bytes_read = 0;
955
956 CompilerType compiler_type = GetCompilerType();
957 CompilerType elem_or_pointee_compiler_type;
958 const Flags type_flags(GetTypeInfo(&elem_or_pointee_compiler_type));
959 if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
960 elem_or_pointee_compiler_type.IsCharType()) {
Greg Claytonafacd142011-09-02 01:15:17 +0000961 addr_t cstr_address = LLDB_INVALID_ADDRESS;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000962 AddressType cstr_address_type = eAddressTypeInvalid;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +0000963
Kate Stoneb9c1b512016-09-06 20:57:50 +0000964 size_t cstr_len = 0;
965 bool capped_data = false;
966 const bool is_array = type_flags.Test(eTypeIsArray);
967 if (is_array) {
968 // We have an array
969 uint64_t array_size = 0;
970 if (compiler_type.IsArrayType(NULL, &array_size, NULL)) {
971 cstr_len = array_size;
972 if (cstr_len > max_length) {
973 capped_data = true;
974 cstr_len = max_length;
Enrico Granata9128ee22011-09-06 19:20:51 +0000975 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000976 }
977 cstr_address = GetAddressOf(true, &cstr_address_type);
978 } else {
979 // We have a pointer
980 cstr_address = GetPointerValue(&cstr_address_type);
Enrico Granata9128ee22011-09-06 19:20:51 +0000981 }
Enrico Granata9128ee22011-09-06 19:20:51 +0000982
Kate Stoneb9c1b512016-09-06 20:57:50 +0000983 if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) {
984 if (cstr_address_type == eAddressTypeHost && is_array) {
985 const char *cstr = GetDataExtractor().PeekCStr(0);
986 if (cstr == nullptr) {
987 s << "<invalid address>";
988 error.SetErrorString("invalid address");
989 CopyStringDataToBufferSP(s, buffer_sp);
990 return {0, was_capped};
Sean Callananed185ab2013-04-19 19:47:32 +0000991 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000992 buffer_sp.reset(new DataBufferHeap(cstr_len, 0));
993 memcpy(buffer_sp->GetBytes(), cstr, cstr_len);
994 return {cstr_len, was_capped};
995 } else {
996 s << "<invalid address>";
997 error.SetErrorString("invalid address");
Enrico Granata2206b482014-10-30 18:27:31 +0000998 CopyStringDataToBufferSP(s, buffer_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000999 return {0, was_capped};
1000 }
Enrico Granata7e0db2a2013-02-28 22:01:33 +00001001 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002
1003 Address cstr_so_addr(cstr_address);
1004 DataExtractor data;
1005 if (cstr_len > 0 && honor_array) {
1006 // I am using GetPointeeData() here to abstract the fact that some
Adrian Prantl05097242018-04-30 16:49:04 +00001007 // ValueObjects are actually frozen pointers in the host but the pointed-
1008 // to data lives in the debuggee, and GetPointeeData() automatically
1009 // takes care of this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001010 GetPointeeData(data, 0, cstr_len);
1011
1012 if ((bytes_read = data.GetByteSize()) > 0) {
1013 total_bytes_read = bytes_read;
1014 for (size_t offset = 0; offset < bytes_read; offset++)
1015 s.Printf("%c", *data.PeekData(offset, 1));
1016 if (capped_data)
1017 was_capped = true;
1018 }
1019 } else {
1020 cstr_len = max_length;
1021 const size_t k_max_buf_size = 64;
1022
1023 size_t offset = 0;
1024
1025 int cstr_len_displayed = -1;
1026 bool capped_cstr = false;
1027 // I am using GetPointeeData() here to abstract the fact that some
Adrian Prantl05097242018-04-30 16:49:04 +00001028 // ValueObjects are actually frozen pointers in the host but the pointed-
1029 // to data lives in the debuggee, and GetPointeeData() automatically
1030 // takes care of this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031 while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {
1032 total_bytes_read += bytes_read;
1033 const char *cstr = data.PeekCStr(0);
1034 size_t len = strnlen(cstr, k_max_buf_size);
1035 if (cstr_len_displayed < 0)
1036 cstr_len_displayed = len;
1037
1038 if (len == 0)
1039 break;
1040 cstr_len_displayed += len;
1041 if (len > bytes_read)
1042 len = bytes_read;
1043 if (len > cstr_len)
1044 len = cstr_len;
1045
1046 for (size_t offset = 0; offset < bytes_read; offset++)
1047 s.Printf("%c", *data.PeekData(offset, 1));
1048
1049 if (len < k_max_buf_size)
1050 break;
1051
1052 if (len >= cstr_len) {
1053 capped_cstr = true;
1054 break;
1055 }
1056
1057 cstr_len -= len;
1058 offset += len;
1059 }
1060
1061 if (cstr_len_displayed >= 0) {
1062 if (capped_cstr)
1063 was_capped = true;
1064 }
1065 }
1066 } else {
1067 error.SetErrorString("not a string object");
1068 s << "<not a string object>";
1069 }
1070 CopyStringDataToBufferSP(s, buffer_sp);
1071 return {total_bytes_read, was_capped};
1072}
1073
1074std::pair<TypeValidatorResult, std::string> ValueObject::GetValidationStatus() {
1075 if (!UpdateValueIfNeeded(true))
1076 return {TypeValidatorResult::Success,
1077 ""}; // not the validator's job to discuss update problems
1078
1079 if (m_validation_result.hasValue())
1080 return m_validation_result.getValue();
1081
1082 if (!m_type_validator_sp)
1083 return {TypeValidatorResult::Success, ""}; // no validator no failure
1084
1085 auto outcome = m_type_validator_sp->FormatObject(this);
1086
1087 return (m_validation_result = {outcome.m_result, outcome.m_message})
1088 .getValue();
1089}
1090
1091const char *ValueObject::GetObjectDescription() {
1092
1093 if (!UpdateValueIfNeeded(true))
1094 return NULL;
1095
1096 if (!m_object_desc_str.empty())
1097 return m_object_desc_str.c_str();
1098
1099 ExecutionContext exe_ctx(GetExecutionContextRef());
1100 Process *process = exe_ctx.GetProcessPtr();
1101 if (process == NULL)
1102 return NULL;
1103
1104 StreamString s;
1105
1106 LanguageType language = GetObjectRuntimeLanguage();
1107 LanguageRuntime *runtime = process->GetLanguageRuntime(language);
1108
1109 if (runtime == NULL) {
1110 // Aw, hell, if the things a pointer, or even just an integer, let's try
1111 // ObjC anyway...
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001112 CompilerType compiler_type = GetCompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001113 if (compiler_type) {
1114 bool is_signed;
1115 if (compiler_type.IsIntegerType(is_signed) ||
1116 compiler_type.IsPointerType()) {
1117 runtime = process->GetLanguageRuntime(eLanguageTypeObjC);
1118 }
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001119 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120 }
1121
1122 if (runtime && runtime->GetObjectDescription(s, *this)) {
Zachary Turnerc1564272016-11-16 21:15:24 +00001123 m_object_desc_str.append(s.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001124 }
1125
1126 if (m_object_desc_str.empty())
1127 return NULL;
1128 else
1129 return m_object_desc_str.c_str();
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00001130}
1131
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,
1133 std::string &destination) {
1134 if (UpdateValueIfNeeded(false))
1135 return format.FormatObject(this, destination);
1136 else
1137 return false;
Enrico Granata744794a2014-09-05 21:46:22 +00001138}
1139
Kate Stoneb9c1b512016-09-06 20:57:50 +00001140bool ValueObject::GetValueAsCString(lldb::Format format,
1141 std::string &destination) {
1142 return GetValueAsCString(TypeFormatImpl_Format(format), destination);
1143}
Enrico Granata0a3958e2011-07-02 00:25:22 +00001144
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145const char *ValueObject::GetValueAsCString() {
1146 if (UpdateValueIfNeeded(true)) {
1147 lldb::TypeFormatImplSP format_sp;
1148 lldb::Format my_format = GetFormat();
1149 if (my_format == lldb::eFormatDefault) {
1150 if (m_type_format_sp)
1151 format_sp = m_type_format_sp;
1152 else {
1153 if (m_is_bitfield_for_scalar)
1154 my_format = eFormatUnsigned;
1155 else {
1156 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo) {
1157 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1158 if (reg_info)
1159 my_format = reg_info->format;
1160 } else {
1161 my_format = GetValue().GetCompilerType().GetFormat();
1162 }
Jim Inghama2cf2632010-12-23 02:29:54 +00001163 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001164 }
Jim Inghama2cf2632010-12-23 02:29:54 +00001165 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001166 if (my_format != m_last_format || m_value_str.empty()) {
1167 m_last_format = my_format;
1168 if (!format_sp)
1169 format_sp.reset(new TypeFormatImpl_Format(my_format));
1170 if (GetValueAsCString(*format_sp.get(), m_value_str)) {
1171 if (!m_value_did_change && m_old_value_valid) {
Adrian Prantl05097242018-04-30 16:49:04 +00001172 // The value was gotten successfully, so we consider the value as
1173 // changed if the value string differs
Kate Stoneb9c1b512016-09-06 20:57:50 +00001174 SetValueDidChange(m_old_value_str != m_value_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001175 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001176 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001177 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001178 }
1179 if (m_value_str.empty())
1180 return NULL;
1181 return m_value_str.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001182}
1183
Adrian Prantl05097242018-04-30 16:49:04 +00001184// if > 8bytes, 0 is returned. this method should mostly be used to read
1185// address values out of pointers
Kate Stoneb9c1b512016-09-06 20:57:50 +00001186uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
1187 // If our byte size is zero this is an aggregate type that has children
1188 if (CanProvideValue()) {
1189 Scalar scalar;
1190 if (ResolveValue(scalar)) {
1191 if (success)
1192 *success = true;
1193 return scalar.ULongLong(fail_value);
Enrico Granatac3e320a2011-08-02 17:27:39 +00001194 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001195 // fallthrough, otherwise...
1196 }
Johnny Chen3f476c42012-06-05 19:37:43 +00001197
Kate Stoneb9c1b512016-09-06 20:57:50 +00001198 if (success)
1199 *success = false;
1200 return fail_value;
Enrico Granatac3e320a2011-08-02 17:27:39 +00001201}
1202
Kate Stoneb9c1b512016-09-06 20:57:50 +00001203int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
1204 // If our byte size is zero this is an aggregate type that has children
1205 if (CanProvideValue()) {
1206 Scalar scalar;
1207 if (ResolveValue(scalar)) {
1208 if (success)
1209 *success = true;
1210 return scalar.SLongLong(fail_value);
Enrico Granatad7373f62013-10-31 18:57:50 +00001211 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001212 // fallthrough, otherwise...
1213 }
1214
1215 if (success)
1216 *success = false;
1217 return fail_value;
Enrico Granatad7373f62013-10-31 18:57:50 +00001218}
1219
Kate Stoneb9c1b512016-09-06 20:57:50 +00001220// if any more "special cases" are added to
Adrian Prantl05097242018-04-30 16:49:04 +00001221// ValueObject::DumpPrintableRepresentation() please keep this call up to date
1222// by returning true for your new special cases. We will eventually move to
1223// checking this call result before trying to display special cases
Kate Stoneb9c1b512016-09-06 20:57:50 +00001224bool ValueObject::HasSpecialPrintableRepresentation(
1225 ValueObjectRepresentationStyle val_obj_display, Format custom_format) {
1226 Flags flags(GetTypeInfo());
1227 if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1228 val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1229 if (IsCStringContainer(true) &&
1230 (custom_format == eFormatCString || custom_format == eFormatCharArray ||
1231 custom_format == eFormatChar || custom_format == eFormatVectorOfChar))
1232 return true;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001233
Kate Stoneb9c1b512016-09-06 20:57:50 +00001234 if (flags.Test(eTypeIsArray)) {
1235 if ((custom_format == eFormatBytes) ||
1236 (custom_format == eFormatBytesWithASCII))
1237 return true;
1238
1239 if ((custom_format == eFormatVectorOfChar) ||
1240 (custom_format == eFormatVectorOfFloat32) ||
1241 (custom_format == eFormatVectorOfFloat64) ||
1242 (custom_format == eFormatVectorOfSInt16) ||
1243 (custom_format == eFormatVectorOfSInt32) ||
1244 (custom_format == eFormatVectorOfSInt64) ||
1245 (custom_format == eFormatVectorOfSInt8) ||
1246 (custom_format == eFormatVectorOfUInt128) ||
1247 (custom_format == eFormatVectorOfUInt16) ||
1248 (custom_format == eFormatVectorOfUInt32) ||
1249 (custom_format == eFormatVectorOfUInt64) ||
1250 (custom_format == eFormatVectorOfUInt8))
1251 return true;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001252 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001253 }
1254 return false;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001255}
1256
Kate Stoneb9c1b512016-09-06 20:57:50 +00001257bool ValueObject::DumpPrintableRepresentation(
1258 Stream &s, ValueObjectRepresentationStyle val_obj_display,
1259 Format custom_format, PrintableRepresentationSpecialCases special,
1260 bool do_dump_error) {
Enrico Granataf4efecd2011-07-12 22:56:10 +00001261
Kate Stoneb9c1b512016-09-06 20:57:50 +00001262 Flags flags(GetTypeInfo());
Enrico Granata86cc9822012-03-19 22:58:49 +00001263
Enrico Granata65d86e42016-11-07 23:32:20 +00001264 bool allow_special =
1265 (special == ValueObject::PrintableRepresentationSpecialCases::eAllow);
1266 const bool only_special = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001267
1268 if (allow_special) {
1269 if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1270 val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1271 // when being asked to get a printable display an array or pointer type
Adrian Prantl05097242018-04-30 16:49:04 +00001272 // directly, try to "do the right thing"
Kate Stoneb9c1b512016-09-06 20:57:50 +00001273
1274 if (IsCStringContainer(true) &&
1275 (custom_format == eFormatCString ||
1276 custom_format == eFormatCharArray || custom_format == eFormatChar ||
1277 custom_format ==
1278 eFormatVectorOfChar)) // print char[] & char* directly
1279 {
Zachary Turner97206d52017-05-12 04:51:55 +00001280 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001281 lldb::DataBufferSP buffer_sp;
1282 std::pair<size_t, bool> read_string = ReadPointedString(
1283 buffer_sp, error, 0, (custom_format == eFormatVectorOfChar) ||
1284 (custom_format == eFormatCharArray));
1285 lldb_private::formatters::StringPrinter::
1286 ReadBufferAndDumpToStreamOptions options(*this);
1287 options.SetData(DataExtractor(
1288 buffer_sp, lldb::eByteOrderInvalid,
1289 8)); // none of this matters for a string - pass some defaults
1290 options.SetStream(&s);
1291 options.SetPrefixToken(0);
1292 options.SetQuote('"');
1293 options.SetSourceSize(buffer_sp->GetByteSize());
1294 options.SetIsTruncated(read_string.second);
1295 formatters::StringPrinter::ReadBufferAndDumpToStream<
1296 lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
1297 options);
1298 return !error.Fail();
1299 }
1300
1301 if (custom_format == eFormatEnum)
Enrico Granata85933ed2011-08-18 16:38:26 +00001302 return false;
Enrico Granata86cc9822012-03-19 22:58:49 +00001303
Adrian Prantl05097242018-04-30 16:49:04 +00001304 // this only works for arrays, because I have no way to know when the
1305 // pointed memory ends, and no special \0 end of data marker
Kate Stoneb9c1b512016-09-06 20:57:50 +00001306 if (flags.Test(eTypeIsArray)) {
1307 if ((custom_format == eFormatBytes) ||
1308 (custom_format == eFormatBytesWithASCII)) {
1309 const size_t count = GetNumChildren();
1310
1311 s << '[';
1312 for (size_t low = 0; low < count; low++) {
1313
1314 if (low)
1315 s << ',';
1316
1317 ValueObjectSP child = GetChildAtIndex(low, true);
1318 if (!child.get()) {
1319 s << "<invalid child>";
1320 continue;
Enrico Granata86cc9822012-03-19 22:58:49 +00001321 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001322 child->DumpPrintableRepresentation(
1323 s, ValueObject::eValueObjectRepresentationStyleValue,
1324 custom_format);
1325 }
1326
1327 s << ']';
1328
1329 return true;
Enrico Granata86cc9822012-03-19 22:58:49 +00001330 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001331
1332 if ((custom_format == eFormatVectorOfChar) ||
1333 (custom_format == eFormatVectorOfFloat32) ||
1334 (custom_format == eFormatVectorOfFloat64) ||
1335 (custom_format == eFormatVectorOfSInt16) ||
1336 (custom_format == eFormatVectorOfSInt32) ||
1337 (custom_format == eFormatVectorOfSInt64) ||
1338 (custom_format == eFormatVectorOfSInt8) ||
1339 (custom_format == eFormatVectorOfUInt128) ||
1340 (custom_format == eFormatVectorOfUInt16) ||
1341 (custom_format == eFormatVectorOfUInt32) ||
1342 (custom_format == eFormatVectorOfUInt64) ||
1343 (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes
1344 // with ASCII or any vector
1345 // format should be printed
1346 // directly
Enrico Granata86cc9822012-03-19 22:58:49 +00001347 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001348 const size_t count = GetNumChildren();
1349
1350 Format format = FormatManager::GetSingleItemFormat(custom_format);
1351
1352 s << '[';
1353 for (size_t low = 0; low < count; low++) {
1354
1355 if (low)
1356 s << ',';
1357
1358 ValueObjectSP child = GetChildAtIndex(low, true);
1359 if (!child.get()) {
1360 s << "<invalid child>";
1361 continue;
Enrico Granata0dba9b32014-01-08 01:36:59 +00001362 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001363 child->DumpPrintableRepresentation(
1364 s, ValueObject::eValueObjectRepresentationStyleValue, format);
1365 }
1366
1367 s << ']';
1368
1369 return true;
Enrico Granata86cc9822012-03-19 22:58:49 +00001370 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001371 }
1372
1373 if ((custom_format == eFormatBoolean) ||
1374 (custom_format == eFormatBinary) || (custom_format == eFormatChar) ||
1375 (custom_format == eFormatCharPrintable) ||
1376 (custom_format == eFormatComplexFloat) ||
1377 (custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||
1378 (custom_format == eFormatHexUppercase) ||
1379 (custom_format == eFormatFloat) || (custom_format == eFormatOctal) ||
1380 (custom_format == eFormatOSType) ||
1381 (custom_format == eFormatUnicode16) ||
1382 (custom_format == eFormatUnicode32) ||
1383 (custom_format == eFormatUnsigned) ||
1384 (custom_format == eFormatPointer) ||
1385 (custom_format == eFormatComplexInteger) ||
1386 (custom_format == eFormatComplex) ||
1387 (custom_format == eFormatDefault)) // use the [] operator
1388 return false;
Enrico Granata86cc9822012-03-19 22:58:49 +00001389 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001390 }
1391
1392 if (only_special)
1393 return false;
1394
1395 bool var_success = false;
1396
1397 {
Zachary Turnerc1564272016-11-16 21:15:24 +00001398 llvm::StringRef str;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001399
1400 // this is a local stream that we are using to ensure that the data pointed
Adrian Prantl05097242018-04-30 16:49:04 +00001401 // to by cstr survives long enough for us to copy it to its destination -
1402 // it is necessary to have this temporary storage area for cases where our
Zachary Turnerc1564272016-11-16 21:15:24 +00001403 // desired output is not backed by some other longer-term storage
Kate Stoneb9c1b512016-09-06 20:57:50 +00001404 StreamString strm;
1405
1406 if (custom_format != eFormatInvalid)
1407 SetFormat(custom_format);
1408
1409 switch (val_obj_display) {
1410 case eValueObjectRepresentationStyleValue:
Zachary Turnerc1564272016-11-16 21:15:24 +00001411 str = GetValueAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001412 break;
1413
1414 case eValueObjectRepresentationStyleSummary:
Zachary Turnerc1564272016-11-16 21:15:24 +00001415 str = GetSummaryAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001416 break;
1417
1418 case eValueObjectRepresentationStyleLanguageSpecific:
Zachary Turnerc1564272016-11-16 21:15:24 +00001419 str = GetObjectDescription();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001420 break;
1421
1422 case eValueObjectRepresentationStyleLocation:
Zachary Turnerc1564272016-11-16 21:15:24 +00001423 str = GetLocationAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001424 break;
1425
1426 case eValueObjectRepresentationStyleChildrenCount:
1427 strm.Printf("%" PRIu64 "", (uint64_t)GetNumChildren());
Zachary Turnerc1564272016-11-16 21:15:24 +00001428 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001429 break;
1430
1431 case eValueObjectRepresentationStyleType:
Zachary Turnerc1564272016-11-16 21:15:24 +00001432 str = GetTypeName().GetStringRef();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001433 break;
1434
1435 case eValueObjectRepresentationStyleName:
Zachary Turnerc1564272016-11-16 21:15:24 +00001436 str = GetName().GetStringRef();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001437 break;
1438
1439 case eValueObjectRepresentationStyleExpressionPath:
1440 GetExpressionPath(strm, false);
Zachary Turnerc1564272016-11-16 21:15:24 +00001441 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001442 break;
1443 }
1444
Zachary Turnerc1564272016-11-16 21:15:24 +00001445 if (str.empty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001446 if (val_obj_display == eValueObjectRepresentationStyleValue)
Zachary Turnerc1564272016-11-16 21:15:24 +00001447 str = GetSummaryAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001448 else if (val_obj_display == eValueObjectRepresentationStyleSummary) {
1449 if (!CanProvideValue()) {
1450 strm.Printf("%s @ %s", GetTypeName().AsCString(),
1451 GetLocationAsCString());
Zachary Turnerc1564272016-11-16 21:15:24 +00001452 str = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001453 } else
Zachary Turnerc1564272016-11-16 21:15:24 +00001454 str = GetValueAsCString();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001455 }
1456 }
1457
Zachary Turnerc1564272016-11-16 21:15:24 +00001458 if (!str.empty())
1459 s << str;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001460 else {
1461 if (m_error.Fail()) {
1462 if (do_dump_error)
1463 s.Printf("<%s>", m_error.AsCString());
1464 else
1465 return false;
1466 } else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1467 s.PutCString("<no summary available>");
1468 else if (val_obj_display == eValueObjectRepresentationStyleValue)
1469 s.PutCString("<no value available>");
1470 else if (val_obj_display ==
1471 eValueObjectRepresentationStyleLanguageSpecific)
1472 s.PutCString("<not a valid Objective-C object>"); // edit this if we
1473 // have other runtimes
1474 // that support a
1475 // description
1476 else
1477 s.PutCString("<no printable representation>");
1478 }
1479
Adrian Prantl05097242018-04-30 16:49:04 +00001480 // we should only return false here if we could not do *anything* even if
1481 // we have an error message as output, that's a success from our callers'
1482 // perspective, so return true
Kate Stoneb9c1b512016-09-06 20:57:50 +00001483 var_success = true;
1484
1485 if (custom_format != eFormatInvalid)
1486 SetFormat(eFormatDefault);
1487 }
1488
1489 return var_success;
Enrico Granata9fc19442011-07-06 02:13:41 +00001490}
1491
Kate Stoneb9c1b512016-09-06 20:57:50 +00001492addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
1493 AddressType *address_type) {
1494 // Can't take address of a bitfield
1495 if (IsBitfield())
Greg Clayton73b472d2010-10-27 03:32:59 +00001496 return LLDB_INVALID_ADDRESS;
Greg Clayton73b472d2010-10-27 03:32:59 +00001497
Kate Stoneb9c1b512016-09-06 20:57:50 +00001498 if (!UpdateValueIfNeeded(false))
1499 return LLDB_INVALID_ADDRESS;
Greg Clayton737b9322010-09-13 03:32:57 +00001500
Kate Stoneb9c1b512016-09-06 20:57:50 +00001501 switch (m_value.GetValueType()) {
1502 case Value::eValueTypeScalar:
1503 case Value::eValueTypeVector:
1504 if (scalar_is_load_address) {
1505 if (address_type)
1506 *address_type = eAddressTypeLoad;
1507 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
Greg Clayton737b9322010-09-13 03:32:57 +00001508 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001509 break;
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001510
Kate Stoneb9c1b512016-09-06 20:57:50 +00001511 case Value::eValueTypeLoadAddress:
1512 case Value::eValueTypeFileAddress: {
Enrico Granata9128ee22011-09-06 19:20:51 +00001513 if (address_type)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001514 *address_type = m_value.GetValueAddressType();
1515 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1516 } break;
1517 case Value::eValueTypeHostAddress: {
1518 if (address_type)
1519 *address_type = m_value.GetValueAddressType();
1520 return LLDB_INVALID_ADDRESS;
1521 } break;
1522 }
1523 if (address_type)
1524 *address_type = eAddressTypeInvalid;
1525 return LLDB_INVALID_ADDRESS;
1526}
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001527
Kate Stoneb9c1b512016-09-06 20:57:50 +00001528addr_t ValueObject::GetPointerValue(AddressType *address_type) {
1529 addr_t address = LLDB_INVALID_ADDRESS;
1530 if (address_type)
1531 *address_type = eAddressTypeInvalid;
1532
1533 if (!UpdateValueIfNeeded(false))
Greg Clayton737b9322010-09-13 03:32:57 +00001534 return address;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001535
1536 switch (m_value.GetValueType()) {
1537 case Value::eValueTypeScalar:
1538 case Value::eValueTypeVector:
1539 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1540 break;
1541
1542 case Value::eValueTypeHostAddress:
1543 case Value::eValueTypeLoadAddress:
1544 case Value::eValueTypeFileAddress: {
1545 lldb::offset_t data_offset = 0;
1546 address = m_data.GetPointer(&data_offset);
1547 } break;
1548 }
1549
1550 if (address_type)
1551 *address_type = GetAddressTypeOfChildren();
1552
1553 return address;
Greg Clayton737b9322010-09-13 03:32:57 +00001554}
1555
Zachary Turner97206d52017-05-12 04:51:55 +00001556bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001557 error.Clear();
1558 // Make sure our value is up to date first so that our location and location
1559 // type is valid.
1560 if (!UpdateValueIfNeeded(false)) {
1561 error.SetErrorString("unable to read value");
Greg Clayton81e871e2012-02-04 02:27:34 +00001562 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001563 }
1564
1565 uint64_t count = 0;
1566 const Encoding encoding = GetCompilerType().GetEncoding(count);
1567
1568 const size_t byte_size = GetByteSize();
1569
1570 Value::ValueType value_type = m_value.GetValueType();
1571
1572 if (value_type == Value::eValueTypeScalar) {
1573 // If the value is already a scalar, then let the scalar change itself:
1574 m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
1575 } else if (byte_size <= 16) {
1576 // If the value fits in a scalar, then make a new scalar and again let the
1577 // scalar code do the conversion, then figure out where to put the new
1578 // value.
1579 Scalar new_scalar;
1580 error = new_scalar.SetValueFromCString(value_str, encoding, byte_size);
1581 if (error.Success()) {
1582 switch (value_type) {
1583 case Value::eValueTypeLoadAddress: {
1584 // If it is a load address, then the scalar value is the storage
Adrian Prantl05097242018-04-30 16:49:04 +00001585 // location of the data, and we have to shove this value down to that
1586 // load location.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001587 ExecutionContext exe_ctx(GetExecutionContextRef());
1588 Process *process = exe_ctx.GetProcessPtr();
1589 if (process) {
1590 addr_t target_addr =
1591 m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1592 size_t bytes_written = process->WriteScalarToMemory(
1593 target_addr, new_scalar, byte_size, error);
1594 if (!error.Success())
1595 return false;
1596 if (bytes_written != byte_size) {
1597 error.SetErrorString("unable to write value to memory");
1598 return false;
1599 }
1600 }
1601 } break;
1602 case Value::eValueTypeHostAddress: {
1603 // If it is a host address, then we stuff the scalar as a DataBuffer
1604 // into the Value's data.
1605 DataExtractor new_data;
1606 new_data.SetByteOrder(m_data.GetByteOrder());
1607
1608 DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
1609 m_data.SetData(buffer_sp, 0);
1610 bool success = new_scalar.GetData(new_data);
1611 if (success) {
1612 new_data.CopyByteOrderedData(
1613 0, byte_size, const_cast<uint8_t *>(m_data.GetDataStart()),
1614 byte_size, m_data.GetByteOrder());
1615 }
1616 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1617
1618 } break;
1619 case Value::eValueTypeFileAddress:
1620 case Value::eValueTypeScalar:
1621 case Value::eValueTypeVector:
1622 break;
1623 }
1624 } else {
1625 return false;
1626 }
1627 } else {
1628 // We don't support setting things bigger than a scalar at present.
1629 error.SetErrorString("unable to write aggregate data type");
1630 return false;
1631 }
1632
Adrian Prantl05097242018-04-30 16:49:04 +00001633 // If we have reached this point, then we have successfully changed the
1634 // value.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001635 SetNeedsUpdate();
1636 return true;
Greg Clayton81e871e2012-02-04 02:27:34 +00001637}
1638
Kate Stoneb9c1b512016-09-06 20:57:50 +00001639bool ValueObject::GetDeclaration(Declaration &decl) {
1640 decl.Clear();
1641 return false;
Greg Clayton84db9102012-03-26 23:03:23 +00001642}
1643
Kate Stoneb9c1b512016-09-06 20:57:50 +00001644ConstString ValueObject::GetTypeName() {
1645 return GetCompilerType().GetConstTypeName();
Enrico Granatae8daa2f2014-05-17 19:14:17 +00001646}
1647
Kate Stoneb9c1b512016-09-06 20:57:50 +00001648ConstString ValueObject::GetDisplayTypeName() { return GetTypeName(); }
1649
1650ConstString ValueObject::GetQualifiedTypeName() {
1651 return GetCompilerType().GetConstQualifiedTypeName();
Greg Clayton84db9102012-03-26 23:03:23 +00001652}
1653
Kate Stoneb9c1b512016-09-06 20:57:50 +00001654LanguageType ValueObject::GetObjectRuntimeLanguage() {
1655 return GetCompilerType().GetMinimumLanguage();
Jim Ingham5a369122010-09-28 01:25:32 +00001656}
1657
Kate Stoneb9c1b512016-09-06 20:57:50 +00001658void ValueObject::AddSyntheticChild(const ConstString &key,
1659 ValueObject *valobj) {
1660 m_synthetic_children[key] = valobj;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001661}
1662
Kate Stoneb9c1b512016-09-06 20:57:50 +00001663ValueObjectSP ValueObject::GetSyntheticChild(const ConstString &key) const {
1664 ValueObjectSP synthetic_child_sp;
1665 std::map<ConstString, ValueObject *>::const_iterator pos =
1666 m_synthetic_children.find(key);
1667 if (pos != m_synthetic_children.end())
1668 synthetic_child_sp = pos->second->GetSP();
1669 return synthetic_child_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001670}
1671
Greg Clayton2452ab72013-02-08 22:02:02 +00001672uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001673ValueObject::GetTypeInfo(CompilerType *pointee_or_element_compiler_type) {
1674 return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type);
Greg Clayton2452ab72013-02-08 22:02:02 +00001675}
1676
Kate Stoneb9c1b512016-09-06 20:57:50 +00001677bool ValueObject::IsPointerType() { return GetCompilerType().IsPointerType(); }
1678
1679bool ValueObject::IsArrayType() {
1680 return GetCompilerType().IsArrayType(NULL, NULL, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001681}
1682
Kate Stoneb9c1b512016-09-06 20:57:50 +00001683bool ValueObject::IsScalarType() { return GetCompilerType().IsScalarType(); }
1684
1685bool ValueObject::IsIntegerType(bool &is_signed) {
1686 return GetCompilerType().IsIntegerType(is_signed);
Greg Claytondaf515f2011-07-09 20:12:33 +00001687}
1688
Kate Stoneb9c1b512016-09-06 20:57:50 +00001689bool ValueObject::IsPointerOrReferenceType() {
1690 return GetCompilerType().IsPointerOrReferenceType();
Enrico Granata9fc19442011-07-06 02:13:41 +00001691}
1692
Kate Stoneb9c1b512016-09-06 20:57:50 +00001693bool ValueObject::IsPossibleDynamicType() {
1694 ExecutionContext exe_ctx(GetExecutionContextRef());
1695 Process *process = exe_ctx.GetProcessPtr();
1696 if (process)
1697 return process->IsPossibleDynamicValue(*this);
1698 else
1699 return GetCompilerType().IsPossibleDynamicType(NULL, true, true);
Jim Inghamb7603bb2011-03-18 00:05:18 +00001700}
Greg Clayton73b472d2010-10-27 03:32:59 +00001701
Kate Stoneb9c1b512016-09-06 20:57:50 +00001702bool ValueObject::IsRuntimeSupportValue() {
1703 Process *process(GetProcessSP().get());
1704 if (process) {
1705 LanguageRuntime *runtime =
1706 process->GetLanguageRuntime(GetObjectRuntimeLanguage());
1707 if (!runtime)
1708 runtime = process->GetObjCLanguageRuntime();
1709 if (runtime)
1710 return runtime->IsRuntimeSupportValue(*this);
1711 }
1712 return false;
Greg Clayton007d5be2011-05-30 00:49:24 +00001713}
1714
Kate Stoneb9c1b512016-09-06 20:57:50 +00001715bool ValueObject::IsNilReference() {
1716 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1717 return language->IsNilReference(*this);
1718 }
1719 return false;
Greg Claytondea8cb42011-06-29 22:09:02 +00001720}
1721
Kate Stoneb9c1b512016-09-06 20:57:50 +00001722bool ValueObject::IsUninitializedReference() {
1723 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1724 return language->IsUninitializedReference(*this);
1725 }
1726 return false;
Enrico Granata9e7b3882012-12-13 23:50:33 +00001727}
1728
Adrian Prantl05097242018-04-30 16:49:04 +00001729// This allows you to create an array member using and index that doesn't not
1730// fall in the normal bounds of the array. Many times structure can be defined
1731// as: struct Collection {
Greg Claytondaf515f2011-07-09 20:12:33 +00001732// uint32_t item_count;
1733// Item item_array[0];
1734// };
Adrian Prantl05097242018-04-30 16:49:04 +00001735// The size of the "item_array" is 1, but many times in practice there are more
1736// items in "item_array".
Greg Claytondaf515f2011-07-09 20:12:33 +00001737
Kate Stoneb9c1b512016-09-06 20:57:50 +00001738ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
1739 bool can_create) {
1740 ValueObjectSP synthetic_child_sp;
1741 if (IsPointerType() || IsArrayType()) {
1742 char index_str[64];
1743 snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index);
1744 ConstString index_const_str(index_str);
Adrian Prantl05097242018-04-30 16:49:04 +00001745 // Check if we have already created a synthetic array member in this valid
1746 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001747 synthetic_child_sp = GetSyntheticChild(index_const_str);
1748 if (!synthetic_child_sp) {
1749 ValueObject *synthetic_child;
Adrian Prantl05097242018-04-30 16:49:04 +00001750 // We haven't made a synthetic array member for INDEX yet, so lets make
1751 // one and cache it for any future reference.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001752 synthetic_child = CreateChildAtIndex(0, true, index);
1753
1754 // Cache the value if we got one back...
1755 if (synthetic_child) {
1756 AddSyntheticChild(index_const_str, synthetic_child);
Enrico Granata6f3533f2011-07-29 19:53:35 +00001757 synthetic_child_sp = synthetic_child->GetSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001758 synthetic_child_sp->SetName(ConstString(index_str));
1759 synthetic_child_sp->m_is_array_item_for_pointer = true;
1760 }
Enrico Granata6f3533f2011-07-29 19:53:35 +00001761 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001762 }
1763 return synthetic_child_sp;
Enrico Granata6f3533f2011-07-29 19:53:35 +00001764}
1765
Kate Stoneb9c1b512016-09-06 20:57:50 +00001766ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
1767 bool can_create) {
1768 ValueObjectSP synthetic_child_sp;
1769 if (IsScalarType()) {
1770 char index_str[64];
1771 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1772 ConstString index_const_str(index_str);
Adrian Prantl05097242018-04-30 16:49:04 +00001773 // Check if we have already created a synthetic array member in this valid
1774 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001775 synthetic_child_sp = GetSyntheticChild(index_const_str);
1776 if (!synthetic_child_sp) {
1777 uint32_t bit_field_size = to - from + 1;
1778 uint32_t bit_field_offset = from;
1779 if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
1780 bit_field_offset =
1781 GetByteSize() * 8 - bit_field_size - bit_field_offset;
Adrian Prantl05097242018-04-30 16:49:04 +00001782 // We haven't made a synthetic array member for INDEX yet, so lets make
1783 // one and cache it for any future reference.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001784 ValueObjectChild *synthetic_child = new ValueObjectChild(
1785 *this, GetCompilerType(), index_const_str, GetByteSize(), 0,
1786 bit_field_size, bit_field_offset, false, false, eAddressTypeInvalid,
1787 0);
1788
1789 // Cache the value if we got one back...
1790 if (synthetic_child) {
1791 AddSyntheticChild(index_const_str, synthetic_child);
Enrico Granata32556cd2014-08-26 20:54:04 +00001792 synthetic_child_sp = synthetic_child->GetSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001793 synthetic_child_sp->SetName(ConstString(index_str));
1794 synthetic_child_sp->m_is_bitfield_for_scalar = true;
1795 }
Enrico Granata32556cd2014-08-26 20:54:04 +00001796 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001797 }
1798 return synthetic_child_sp;
Enrico Granata32556cd2014-08-26 20:54:04 +00001799}
1800
Kate Stoneb9c1b512016-09-06 20:57:50 +00001801ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
1802 uint32_t offset, const CompilerType &type, bool can_create,
1803 ConstString name_const_str) {
1804
1805 ValueObjectSP synthetic_child_sp;
1806
1807 if (name_const_str.IsEmpty()) {
1808 char name_str[64];
1809 snprintf(name_str, sizeof(name_str), "@%i", offset);
1810 name_const_str.SetCString(name_str);
1811 }
1812
Adrian Prantl05097242018-04-30 16:49:04 +00001813 // Check if we have already created a synthetic array member in this valid
1814 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001815 synthetic_child_sp = GetSyntheticChild(name_const_str);
1816
1817 if (synthetic_child_sp.get())
1818 return synthetic_child_sp;
1819
1820 if (!can_create)
1821 return ValueObjectSP();
1822
1823 ExecutionContext exe_ctx(GetExecutionContextRef());
1824
1825 ValueObjectChild *synthetic_child = new ValueObjectChild(
1826 *this, type, name_const_str,
1827 type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0,
1828 false, false, eAddressTypeInvalid, 0);
1829 if (synthetic_child) {
1830 AddSyntheticChild(name_const_str, synthetic_child);
1831 synthetic_child_sp = synthetic_child->GetSP();
1832 synthetic_child_sp->SetName(name_const_str);
1833 synthetic_child_sp->m_is_child_at_offset = true;
1834 }
1835 return synthetic_child_sp;
1836}
1837
1838ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
1839 const CompilerType &type,
1840 bool can_create,
1841 ConstString name_const_str) {
1842 ValueObjectSP synthetic_child_sp;
1843
1844 if (name_const_str.IsEmpty()) {
1845 char name_str[128];
1846 snprintf(name_str, sizeof(name_str), "base%s@%i",
1847 type.GetTypeName().AsCString("<unknown>"), offset);
1848 name_const_str.SetCString(name_str);
1849 }
1850
Adrian Prantl05097242018-04-30 16:49:04 +00001851 // Check if we have already created a synthetic array member in this valid
1852 // object. If we have we will re-use it.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001853 synthetic_child_sp = GetSyntheticChild(name_const_str);
1854
1855 if (synthetic_child_sp.get())
1856 return synthetic_child_sp;
1857
1858 if (!can_create)
1859 return ValueObjectSP();
1860
1861 const bool is_base_class = true;
1862
1863 ExecutionContext exe_ctx(GetExecutionContextRef());
1864
1865 ValueObjectChild *synthetic_child = new ValueObjectChild(
1866 *this, type, name_const_str,
1867 type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0,
1868 is_base_class, false, eAddressTypeInvalid, 0);
1869 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
Kate Stoneb9c1b512016-09-06 20:57:50 +00002737ValueObjectSP ValueObject::CreateConstantValue(const ConstString &name) {
2738 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
Tamas Berghammer4fbb55b2017-03-31 20:48:00 +00002913lldb::ValueObjectSP ValueObject::Clone(const ConstString &new_name) {
2914 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