1 //===-- ValueObject.cpp ---------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Core/ValueObject.h"
10
11 #include "lldb/Core/Address.h"
12 #include "lldb/Core/Declaration.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ValueObjectCast.h"
15 #include "lldb/Core/ValueObjectChild.h"
16 #include "lldb/Core/ValueObjectConstResult.h"
17 #include "lldb/Core/ValueObjectDynamicValue.h"
18 #include "lldb/Core/ValueObjectMemory.h"
19 #include "lldb/Core/ValueObjectSyntheticFilter.h"
20 #include "lldb/DataFormatters/DataVisualization.h"
21 #include "lldb/DataFormatters/DumpValueObjectOptions.h"
22 #include "lldb/DataFormatters/FormatManager.h"
23 #include "lldb/DataFormatters/StringPrinter.h"
24 #include "lldb/DataFormatters/TypeFormat.h"
25 #include "lldb/DataFormatters/TypeSummary.h"
26 #include "lldb/DataFormatters/ValueObjectPrinter.h"
27 #include "lldb/Expression/ExpressionVariable.h"
28 #include "lldb/Host/Config.h"
29 #include "lldb/Symbol/CompileUnit.h"
30 #include "lldb/Symbol/CompilerType.h"
31 #include "lldb/Symbol/SymbolContext.h"
32 #include "lldb/Symbol/Type.h"
33 #include "lldb/Symbol/Variable.h"
34 #include "lldb/Target/ExecutionContext.h"
35 #include "lldb/Target/Language.h"
36 #include "lldb/Target/LanguageRuntime.h"
37 #include "lldb/Target/Process.h"
38 #include "lldb/Target/StackFrame.h"
39 #include "lldb/Target/Target.h"
40 #include "lldb/Target/Thread.h"
41 #include "lldb/Target/ThreadList.h"
42 #include "lldb/Utility/DataBuffer.h"
43 #include "lldb/Utility/DataBufferHeap.h"
44 #include "lldb/Utility/Flags.h"
45 #include "lldb/Utility/LLDBLog.h"
46 #include "lldb/Utility/Log.h"
47 #include "lldb/Utility/Scalar.h"
48 #include "lldb/Utility/Stream.h"
49 #include "lldb/Utility/StreamString.h"
50 #include "lldb/lldb-private-types.h"
51
52 #include "llvm/Support/Compiler.h"
53
54 #include <algorithm>
55 #include <cstdint>
56 #include <cstdlib>
57 #include <memory>
58 #include <optional>
59 #include <tuple>
60
61 #include <cassert>
62 #include <cinttypes>
63 #include <cstdio>
64 #include <cstring>
65
66 #include <lldb/Core/ValueObject.h>
67
68 namespace lldb_private {
69 class ExecutionContextScope;
70 }
71 namespace lldb_private {
72 class SymbolContextScope;
73 }
74
75 using namespace lldb;
76 using namespace lldb_private;
77
78 static user_id_t g_value_obj_uid = 0;
79
80 // ValueObject constructor
ValueObject(ValueObject & parent)81 ValueObject::ValueObject(ValueObject &parent)
82 : m_parent(&parent), m_update_point(parent.GetUpdatePoint()),
83 m_manager(parent.GetManager()), m_id(++g_value_obj_uid) {
84 m_flags.m_is_synthetic_children_generated =
85 parent.m_flags.m_is_synthetic_children_generated;
86 m_data.SetByteOrder(parent.GetDataExtractor().GetByteOrder());
87 m_data.SetAddressByteSize(parent.GetDataExtractor().GetAddressByteSize());
88 m_manager->ManageObject(this);
89 }
90
91 // ValueObject constructor
ValueObject(ExecutionContextScope * exe_scope,ValueObjectManager & manager,AddressType child_ptr_or_ref_addr_type)92 ValueObject::ValueObject(ExecutionContextScope *exe_scope,
93 ValueObjectManager &manager,
94 AddressType child_ptr_or_ref_addr_type)
95 : m_update_point(exe_scope), m_manager(&manager),
96 m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
97 m_id(++g_value_obj_uid) {
98 if (exe_scope) {
99 TargetSP target_sp(exe_scope->CalculateTarget());
100 if (target_sp) {
101 const ArchSpec &arch = target_sp->GetArchitecture();
102 m_data.SetByteOrder(arch.GetByteOrder());
103 m_data.SetAddressByteSize(arch.GetAddressByteSize());
104 }
105 }
106 m_manager->ManageObject(this);
107 }
108
109 // Destructor
110 ValueObject::~ValueObject() = default;
111
UpdateValueIfNeeded(bool update_format)112 bool ValueObject::UpdateValueIfNeeded(bool update_format) {
113
114 bool did_change_formats = false;
115
116 if (update_format)
117 did_change_formats = UpdateFormatsIfNeeded();
118
119 // If this is a constant value, then our success is predicated on whether we
120 // have an error or not
121 if (GetIsConstant()) {
122 // if you are constant, things might still have changed behind your back
123 // (e.g. you are a frozen object and things have changed deeper than you
124 // cared to freeze-dry yourself) in this case, your value has not changed,
125 // but "computed" entries might have, so you might now have a different
126 // summary, or a different object description. clear these so we will
127 // recompute them
128 if (update_format && !did_change_formats)
129 ClearUserVisibleData(eClearUserVisibleDataItemsSummary |
130 eClearUserVisibleDataItemsDescription);
131 return m_error.Success();
132 }
133
134 bool first_update = IsChecksumEmpty();
135
136 if (NeedsUpdating()) {
137 m_update_point.SetUpdated();
138
139 // Save the old value using swap to avoid a string copy which also will
140 // clear our m_value_str
141 if (m_value_str.empty()) {
142 m_flags.m_old_value_valid = false;
143 } else {
144 m_flags.m_old_value_valid = true;
145 m_old_value_str.swap(m_value_str);
146 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
147 }
148
149 ClearUserVisibleData();
150
151 if (IsInScope()) {
152 const bool value_was_valid = GetValueIsValid();
153 SetValueDidChange(false);
154
155 m_error.Clear();
156
157 // Call the pure virtual function to update the value
158
159 bool need_compare_checksums = false;
160 llvm::SmallVector<uint8_t, 16> old_checksum;
161
162 if (!first_update && CanProvideValue()) {
163 need_compare_checksums = true;
164 old_checksum.resize(m_value_checksum.size());
165 std::copy(m_value_checksum.begin(), m_value_checksum.end(),
166 old_checksum.begin());
167 }
168
169 bool success = UpdateValue();
170
171 SetValueIsValid(success);
172
173 if (success) {
174 UpdateChildrenAddressType();
175 const uint64_t max_checksum_size = 128;
176 m_data.Checksum(m_value_checksum, max_checksum_size);
177 } else {
178 need_compare_checksums = false;
179 m_value_checksum.clear();
180 }
181
182 assert(!need_compare_checksums ||
183 (!old_checksum.empty() && !m_value_checksum.empty()));
184
185 if (first_update)
186 SetValueDidChange(false);
187 else if (!m_flags.m_value_did_change && !success) {
188 // The value wasn't gotten successfully, so we mark this as changed if
189 // the value used to be valid and now isn't
190 SetValueDidChange(value_was_valid);
191 } else if (need_compare_checksums) {
192 SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0],
193 m_value_checksum.size()));
194 }
195
196 } else {
197 m_error.SetErrorString("out of scope");
198 }
199 }
200 return m_error.Success();
201 }
202
UpdateFormatsIfNeeded()203 bool ValueObject::UpdateFormatsIfNeeded() {
204 Log *log = GetLog(LLDBLog::DataFormatters);
205 LLDB_LOGF(log,
206 "[%s %p] checking for FormatManager revisions. ValueObject "
207 "rev: %d - Global rev: %d",
208 GetName().GetCString(), static_cast<void *>(this),
209 m_last_format_mgr_revision,
210 DataVisualization::GetCurrentRevision());
211
212 bool any_change = false;
213
214 if ((m_last_format_mgr_revision != DataVisualization::GetCurrentRevision())) {
215 m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
216 any_change = true;
217
218 SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues));
219 SetSummaryFormat(
220 DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
221 #if LLDB_ENABLE_PYTHON
222 SetSyntheticChildren(
223 DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));
224 #endif
225 }
226
227 return any_change;
228 }
229
SetNeedsUpdate()230 void ValueObject::SetNeedsUpdate() {
231 m_update_point.SetNeedsUpdate();
232 // We have to clear the value string here so ConstResult children will notice
233 // if their values are changed by hand (i.e. with SetValueAsCString).
234 ClearUserVisibleData(eClearUserVisibleDataItemsValue);
235 }
236
ClearDynamicTypeInformation()237 void ValueObject::ClearDynamicTypeInformation() {
238 m_flags.m_children_count_valid = false;
239 m_flags.m_did_calculate_complete_objc_class_type = false;
240 m_last_format_mgr_revision = 0;
241 m_override_type = CompilerType();
242 SetValueFormat(lldb::TypeFormatImplSP());
243 SetSummaryFormat(lldb::TypeSummaryImplSP());
244 SetSyntheticChildren(lldb::SyntheticChildrenSP());
245 }
246
MaybeCalculateCompleteType()247 CompilerType ValueObject::MaybeCalculateCompleteType() {
248 CompilerType compiler_type(GetCompilerTypeImpl());
249
250 if (m_flags.m_did_calculate_complete_objc_class_type) {
251 if (m_override_type.IsValid())
252 return m_override_type;
253 else
254 return compiler_type;
255 }
256
257 m_flags.m_did_calculate_complete_objc_class_type = true;
258
259 ProcessSP process_sp(
260 GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
261
262 if (!process_sp)
263 return compiler_type;
264
265 if (auto *runtime =
266 process_sp->GetLanguageRuntime(GetObjectRuntimeLanguage())) {
267 if (std::optional<CompilerType> complete_type =
268 runtime->GetRuntimeType(compiler_type)) {
269 m_override_type = *complete_type;
270 if (m_override_type.IsValid())
271 return m_override_type;
272 }
273 }
274 return compiler_type;
275 }
276
277
278
GetDataExtractor()279 DataExtractor &ValueObject::GetDataExtractor() {
280 UpdateValueIfNeeded(false);
281 return m_data;
282 }
283
GetError()284 const Status &ValueObject::GetError() {
285 UpdateValueIfNeeded(false);
286 return m_error;
287 }
288
GetLocationAsCStringImpl(const Value & value,const DataExtractor & data)289 const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
290 const DataExtractor &data) {
291 if (UpdateValueIfNeeded(false)) {
292 if (m_location_str.empty()) {
293 StreamString sstr;
294
295 Value::ValueType value_type = value.GetValueType();
296
297 switch (value_type) {
298 case Value::ValueType::Invalid:
299 m_location_str = "invalid";
300 break;
301 case Value::ValueType::Scalar:
302 if (value.GetContextType() == Value::ContextType::RegisterInfo) {
303 RegisterInfo *reg_info = value.GetRegisterInfo();
304 if (reg_info) {
305 if (reg_info->name)
306 m_location_str = reg_info->name;
307 else if (reg_info->alt_name)
308 m_location_str = reg_info->alt_name;
309 if (m_location_str.empty())
310 m_location_str = (reg_info->encoding == lldb::eEncodingVector)
311 ? "vector"
312 : "scalar";
313 }
314 }
315 if (m_location_str.empty())
316 m_location_str = "scalar";
317 break;
318
319 case Value::ValueType::LoadAddress:
320 case Value::ValueType::FileAddress:
321 case Value::ValueType::HostAddress: {
322 uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
323 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size,
324 value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
325 m_location_str = std::string(sstr.GetString());
326 } break;
327 }
328 }
329 }
330 return m_location_str.c_str();
331 }
332
ResolveValue(Scalar & scalar)333 bool ValueObject::ResolveValue(Scalar &scalar) {
334 if (UpdateValueIfNeeded(
335 false)) // make sure that you are up to date before returning anything
336 {
337 ExecutionContext exe_ctx(GetExecutionContextRef());
338 Value tmp_value(m_value);
339 scalar = tmp_value.ResolveValue(&exe_ctx);
340 if (scalar.IsValid()) {
341 const uint32_t bitfield_bit_size = GetBitfieldBitSize();
342 if (bitfield_bit_size)
343 return scalar.ExtractBitfield(bitfield_bit_size,
344 GetBitfieldBitOffset());
345 return true;
346 }
347 }
348 return false;
349 }
350
IsLogicalTrue(Status & error)351 bool ValueObject::IsLogicalTrue(Status &error) {
352 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
353 LazyBool is_logical_true = language->IsLogicalTrue(*this, error);
354 switch (is_logical_true) {
355 case eLazyBoolYes:
356 case eLazyBoolNo:
357 return (is_logical_true == true);
358 case eLazyBoolCalculate:
359 break;
360 }
361 }
362
363 Scalar scalar_value;
364
365 if (!ResolveValue(scalar_value)) {
366 error.SetErrorString("failed to get a scalar result");
367 return false;
368 }
369
370 bool ret;
371 ret = scalar_value.ULongLong(1) != 0;
372 error.Clear();
373 return ret;
374 }
375
GetChildAtIndex(size_t idx,bool can_create)376 ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) {
377 ValueObjectSP child_sp;
378 // We may need to update our value if we are dynamic
379 if (IsPossibleDynamicType())
380 UpdateValueIfNeeded(false);
381 if (idx < GetNumChildren()) {
382 // Check if we have already made the child value object?
383 if (can_create && !m_children.HasChildAtIndex(idx)) {
384 // No we haven't created the child at this index, so lets have our
385 // subclass do it and cache the result for quick future access.
386 m_children.SetChildAtIndex(idx, CreateChildAtIndex(idx, false, 0));
387 }
388
389 ValueObject *child = m_children.GetChildAtIndex(idx);
390 if (child != nullptr)
391 return child->GetSP();
392 }
393 return child_sp;
394 }
395
396 lldb::ValueObjectSP
GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,size_t * index_of_error)397 ValueObject::GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,
398 size_t *index_of_error) {
399 if (idxs.size() == 0)
400 return GetSP();
401 ValueObjectSP root(GetSP());
402 for (size_t idx : idxs) {
403 root = root->GetChildAtIndex(idx, true);
404 if (!root) {
405 if (index_of_error)
406 *index_of_error = idx;
407 return root;
408 }
409 }
410 return root;
411 }
412
GetChildAtIndexPath(llvm::ArrayRef<std::pair<size_t,bool>> idxs,size_t * index_of_error)413 lldb::ValueObjectSP ValueObject::GetChildAtIndexPath(
414 llvm::ArrayRef<std::pair<size_t, bool>> idxs, size_t *index_of_error) {
415 if (idxs.size() == 0)
416 return GetSP();
417 ValueObjectSP root(GetSP());
418 for (std::pair<size_t, bool> idx : idxs) {
419 root = root->GetChildAtIndex(idx.first, idx.second);
420 if (!root) {
421 if (index_of_error)
422 *index_of_error = idx.first;
423 return root;
424 }
425 }
426 return root;
427 }
428
429 lldb::ValueObjectSP
GetChildAtNamePath(llvm::ArrayRef<ConstString> names,ConstString * name_of_error)430 ValueObject::GetChildAtNamePath(llvm::ArrayRef<ConstString> names,
431 ConstString *name_of_error) {
432 if (names.size() == 0)
433 return GetSP();
434 ValueObjectSP root(GetSP());
435 for (ConstString name : names) {
436 root = root->GetChildMemberWithName(name, true);
437 if (!root) {
438 if (name_of_error)
439 *name_of_error = name;
440 return root;
441 }
442 }
443 return root;
444 }
445
GetChildAtNamePath(llvm::ArrayRef<std::pair<ConstString,bool>> names,ConstString * name_of_error)446 lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
447 llvm::ArrayRef<std::pair<ConstString, bool>> names,
448 ConstString *name_of_error) {
449 if (names.size() == 0)
450 return GetSP();
451 ValueObjectSP root(GetSP());
452 for (std::pair<ConstString, bool> name : names) {
453 root = root->GetChildMemberWithName(name.first, name.second);
454 if (!root) {
455 if (name_of_error)
456 *name_of_error = name.first;
457 return root;
458 }
459 }
460 return root;
461 }
462
GetIndexOfChildWithName(ConstString name)463 size_t ValueObject::GetIndexOfChildWithName(ConstString name) {
464 bool omit_empty_base_classes = true;
465 return GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
466 omit_empty_base_classes);
467 }
468
GetChildMemberWithName(ConstString name,bool can_create)469 ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name,
470 bool can_create) {
471 // We may need to update our value if we are dynamic.
472 if (IsPossibleDynamicType())
473 UpdateValueIfNeeded(false);
474
475 // When getting a child by name, it could be buried inside some base classes
476 // (which really aren't part of the expression path), so we need a vector of
477 // indexes that can get us down to the correct child.
478 std::vector<uint32_t> child_indexes;
479 bool omit_empty_base_classes = true;
480
481 if (!GetCompilerType().IsValid())
482 return ValueObjectSP();
483
484 const size_t num_child_indexes =
485 GetCompilerType().GetIndexOfChildMemberWithName(
486 name.GetCString(), omit_empty_base_classes, child_indexes);
487 if (num_child_indexes == 0)
488 return nullptr;
489
490 ValueObjectSP child_sp = GetSP();
491 for (uint32_t idx : child_indexes)
492 if (child_sp)
493 child_sp = child_sp->GetChildAtIndex(idx, can_create);
494 return child_sp;
495 }
496
GetNumChildren(uint32_t max)497 size_t ValueObject::GetNumChildren(uint32_t max) {
498 UpdateValueIfNeeded();
499
500 if (max < UINT32_MAX) {
501 if (m_flags.m_children_count_valid) {
502 size_t children_count = m_children.GetChildrenCount();
503 return children_count <= max ? children_count : max;
504 } else
505 return CalculateNumChildren(max);
506 }
507
508 if (!m_flags.m_children_count_valid) {
509 SetNumChildren(CalculateNumChildren());
510 }
511 return m_children.GetChildrenCount();
512 }
513
MightHaveChildren()514 bool ValueObject::MightHaveChildren() {
515 bool has_children = false;
516 const uint32_t type_info = GetTypeInfo();
517 if (type_info) {
518 if (type_info & (eTypeHasChildren | eTypeIsPointer | eTypeIsReference))
519 has_children = true;
520 } else {
521 has_children = GetNumChildren() > 0;
522 }
523 return has_children;
524 }
525
526 // Should only be called by ValueObject::GetNumChildren()
SetNumChildren(size_t num_children)527 void ValueObject::SetNumChildren(size_t num_children) {
528 m_flags.m_children_count_valid = true;
529 m_children.SetChildrenCount(num_children);
530 }
531
CreateChildAtIndex(size_t idx,bool synthetic_array_member,int32_t synthetic_index)532 ValueObject *ValueObject::CreateChildAtIndex(size_t idx,
533 bool synthetic_array_member,
534 int32_t synthetic_index) {
535 ValueObject *valobj = nullptr;
536
537 bool omit_empty_base_classes = true;
538 bool ignore_array_bounds = synthetic_array_member;
539 std::string child_name_str;
540 uint32_t child_byte_size = 0;
541 int32_t child_byte_offset = 0;
542 uint32_t child_bitfield_bit_size = 0;
543 uint32_t child_bitfield_bit_offset = 0;
544 bool child_is_base_class = false;
545 bool child_is_deref_of_parent = false;
546 uint64_t language_flags = 0;
547
548 const bool transparent_pointers = !synthetic_array_member;
549 CompilerType child_compiler_type;
550
551 ExecutionContext exe_ctx(GetExecutionContextRef());
552
553 child_compiler_type = GetCompilerType().GetChildCompilerTypeAtIndex(
554 &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
555 ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
556 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
557 child_is_deref_of_parent, this, language_flags);
558 if (child_compiler_type) {
559 if (synthetic_index)
560 child_byte_offset += child_byte_size * synthetic_index;
561
562 ConstString child_name;
563 if (!child_name_str.empty())
564 child_name.SetCString(child_name_str.c_str());
565
566 valobj = new ValueObjectChild(
567 *this, child_compiler_type, child_name, child_byte_size,
568 child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
569 child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
570 language_flags);
571 }
572
573 // In case of an incomplete type, try to use the ValueObject's
574 // synthetic value to create the child ValueObject.
575 if (!valobj && synthetic_array_member) {
576 if (ValueObjectSP synth_valobj_sp = GetSyntheticValue()) {
577 valobj = synth_valobj_sp
578 ->GetChildAtIndex(synthetic_index, synthetic_array_member)
579 .get();
580 }
581 }
582
583 return valobj;
584 }
585
GetSummaryAsCString(TypeSummaryImpl * summary_ptr,std::string & destination,lldb::LanguageType lang)586 bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
587 std::string &destination,
588 lldb::LanguageType lang) {
589 return GetSummaryAsCString(summary_ptr, destination,
590 TypeSummaryOptions().SetLanguage(lang));
591 }
592
GetSummaryAsCString(TypeSummaryImpl * summary_ptr,std::string & destination,const TypeSummaryOptions & options)593 bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
594 std::string &destination,
595 const TypeSummaryOptions &options) {
596 destination.clear();
597
598 // If we have a forcefully completed type, don't try and show a summary from
599 // a valid summary string or function because the type is not complete and
600 // no member variables or member functions will be available.
601 if (GetCompilerType().IsForcefullyCompleted()) {
602 destination = "<incomplete type>";
603 return true;
604 }
605
606 // ideally we would like to bail out if passing NULL, but if we do so we end
607 // up not providing the summary for function pointers anymore
608 if (/*summary_ptr == NULL ||*/ m_flags.m_is_getting_summary)
609 return false;
610
611 m_flags.m_is_getting_summary = true;
612
613 TypeSummaryOptions actual_options(options);
614
615 if (actual_options.GetLanguage() == lldb::eLanguageTypeUnknown)
616 actual_options.SetLanguage(GetPreferredDisplayLanguage());
617
618 // this is a hot path in code and we prefer to avoid setting this string all
619 // too often also clearing out other information that we might care to see in
620 // a crash log. might be useful in very specific situations though.
621 /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s.
622 Summary provider's description is %s",
623 GetTypeName().GetCString(),
624 GetName().GetCString(),
625 summary_ptr->GetDescription().c_str());*/
626
627 if (UpdateValueIfNeeded(false) && summary_ptr) {
628 if (HasSyntheticValue())
629 m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on
630 // the synthetic children being
631 // up-to-date (e.g. ${svar%#})
632 summary_ptr->FormatObject(this, destination, actual_options);
633 }
634 m_flags.m_is_getting_summary = false;
635 return !destination.empty();
636 }
637
GetSummaryAsCString(lldb::LanguageType lang)638 const char *ValueObject::GetSummaryAsCString(lldb::LanguageType lang) {
639 if (UpdateValueIfNeeded(true) && m_summary_str.empty()) {
640 TypeSummaryOptions summary_options;
641 summary_options.SetLanguage(lang);
642 GetSummaryAsCString(GetSummaryFormat().get(), m_summary_str,
643 summary_options);
644 }
645 if (m_summary_str.empty())
646 return nullptr;
647 return m_summary_str.c_str();
648 }
649
GetSummaryAsCString(std::string & destination,const TypeSummaryOptions & options)650 bool ValueObject::GetSummaryAsCString(std::string &destination,
651 const TypeSummaryOptions &options) {
652 return GetSummaryAsCString(GetSummaryFormat().get(), destination, options);
653 }
654
IsCStringContainer(bool check_pointer)655 bool ValueObject::IsCStringContainer(bool check_pointer) {
656 CompilerType pointee_or_element_compiler_type;
657 const Flags type_flags(GetTypeInfo(&pointee_or_element_compiler_type));
658 bool is_char_arr_ptr(type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
659 pointee_or_element_compiler_type.IsCharType());
660 if (!is_char_arr_ptr)
661 return false;
662 if (!check_pointer)
663 return true;
664 if (type_flags.Test(eTypeIsArray))
665 return true;
666 addr_t cstr_address = LLDB_INVALID_ADDRESS;
667 AddressType cstr_address_type = eAddressTypeInvalid;
668 cstr_address = GetPointerValue(&cstr_address_type);
669 return (cstr_address != LLDB_INVALID_ADDRESS);
670 }
671
GetPointeeData(DataExtractor & data,uint32_t item_idx,uint32_t item_count)672 size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
673 uint32_t item_count) {
674 CompilerType pointee_or_element_compiler_type;
675 const uint32_t type_info = GetTypeInfo(&pointee_or_element_compiler_type);
676 const bool is_pointer_type = type_info & eTypeIsPointer;
677 const bool is_array_type = type_info & eTypeIsArray;
678 if (!(is_pointer_type || is_array_type))
679 return 0;
680
681 if (item_count == 0)
682 return 0;
683
684 ExecutionContext exe_ctx(GetExecutionContextRef());
685
686 std::optional<uint64_t> item_type_size =
687 pointee_or_element_compiler_type.GetByteSize(
688 exe_ctx.GetBestExecutionContextScope());
689 if (!item_type_size)
690 return 0;
691 const uint64_t bytes = item_count * *item_type_size;
692 const uint64_t offset = item_idx * *item_type_size;
693
694 if (item_idx == 0 && item_count == 1) // simply a deref
695 {
696 if (is_pointer_type) {
697 Status error;
698 ValueObjectSP pointee_sp = Dereference(error);
699 if (error.Fail() || pointee_sp.get() == nullptr)
700 return 0;
701 return pointee_sp->GetData(data, error);
702 } else {
703 ValueObjectSP child_sp = GetChildAtIndex(0, true);
704 if (child_sp.get() == nullptr)
705 return 0;
706 Status error;
707 return child_sp->GetData(data, error);
708 }
709 return true;
710 } else /* (items > 1) */
711 {
712 Status error;
713 lldb_private::DataBufferHeap *heap_buf_ptr = nullptr;
714 lldb::DataBufferSP data_sp(heap_buf_ptr =
715 new lldb_private::DataBufferHeap());
716
717 AddressType addr_type;
718 lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type)
719 : GetAddressOf(true, &addr_type);
720
721 switch (addr_type) {
722 case eAddressTypeFile: {
723 ModuleSP module_sp(GetModule());
724 if (module_sp) {
725 addr = addr + offset;
726 Address so_addr;
727 module_sp->ResolveFileAddress(addr, so_addr);
728 ExecutionContext exe_ctx(GetExecutionContextRef());
729 Target *target = exe_ctx.GetTargetPtr();
730 if (target) {
731 heap_buf_ptr->SetByteSize(bytes);
732 size_t bytes_read = target->ReadMemory(
733 so_addr, heap_buf_ptr->GetBytes(), bytes, error, true);
734 if (error.Success()) {
735 data.SetData(data_sp);
736 return bytes_read;
737 }
738 }
739 }
740 } break;
741 case eAddressTypeLoad: {
742 ExecutionContext exe_ctx(GetExecutionContextRef());
743 Process *process = exe_ctx.GetProcessPtr();
744 if (process) {
745 heap_buf_ptr->SetByteSize(bytes);
746 size_t bytes_read = process->ReadMemory(
747 addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
748 if (error.Success() || bytes_read > 0) {
749 data.SetData(data_sp);
750 return bytes_read;
751 }
752 }
753 } break;
754 case eAddressTypeHost: {
755 auto max_bytes =
756 GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());
757 if (max_bytes && *max_bytes > offset) {
758 size_t bytes_read = std::min<uint64_t>(*max_bytes - offset, bytes);
759 addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
760 if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
761 break;
762 heap_buf_ptr->CopyData((uint8_t *)(addr + offset), bytes_read);
763 data.SetData(data_sp);
764 return bytes_read;
765 }
766 } break;
767 case eAddressTypeInvalid:
768 break;
769 }
770 }
771 return 0;
772 }
773
GetData(DataExtractor & data,Status & error)774 uint64_t ValueObject::GetData(DataExtractor &data, Status &error) {
775 UpdateValueIfNeeded(false);
776 ExecutionContext exe_ctx(GetExecutionContextRef());
777 error = m_value.GetValueAsData(&exe_ctx, data, GetModule().get());
778 if (error.Fail()) {
779 if (m_data.GetByteSize()) {
780 data = m_data;
781 error.Clear();
782 return data.GetByteSize();
783 } else {
784 return 0;
785 }
786 }
787 data.SetAddressByteSize(m_data.GetAddressByteSize());
788 data.SetByteOrder(m_data.GetByteOrder());
789 return data.GetByteSize();
790 }
791
SetData(DataExtractor & data,Status & error)792 bool ValueObject::SetData(DataExtractor &data, Status &error) {
793 error.Clear();
794 // Make sure our value is up to date first so that our location and location
795 // type is valid.
796 if (!UpdateValueIfNeeded(false)) {
797 error.SetErrorString("unable to read value");
798 return false;
799 }
800
801 uint64_t count = 0;
802 const Encoding encoding = GetCompilerType().GetEncoding(count);
803
804 const size_t byte_size = GetByteSize().value_or(0);
805
806 Value::ValueType value_type = m_value.GetValueType();
807
808 switch (value_type) {
809 case Value::ValueType::Invalid:
810 error.SetErrorString("invalid location");
811 return false;
812 case Value::ValueType::Scalar: {
813 Status set_error =
814 m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
815
816 if (!set_error.Success()) {
817 error.SetErrorStringWithFormat("unable to set scalar value: %s",
818 set_error.AsCString());
819 return false;
820 }
821 } break;
822 case Value::ValueType::LoadAddress: {
823 // If it is a load address, then the scalar value is the storage location
824 // of the data, and we have to shove this value down to that load location.
825 ExecutionContext exe_ctx(GetExecutionContextRef());
826 Process *process = exe_ctx.GetProcessPtr();
827 if (process) {
828 addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
829 size_t bytes_written = process->WriteMemory(
830 target_addr, data.GetDataStart(), byte_size, error);
831 if (!error.Success())
832 return false;
833 if (bytes_written != byte_size) {
834 error.SetErrorString("unable to write value to memory");
835 return false;
836 }
837 }
838 } break;
839 case Value::ValueType::HostAddress: {
840 // If it is a host address, then we stuff the scalar as a DataBuffer into
841 // the Value's data.
842 DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
843 m_data.SetData(buffer_sp, 0);
844 data.CopyByteOrderedData(0, byte_size,
845 const_cast<uint8_t *>(m_data.GetDataStart()),
846 byte_size, m_data.GetByteOrder());
847 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
848 } break;
849 case Value::ValueType::FileAddress:
850 break;
851 }
852
853 // If we have reached this point, then we have successfully changed the
854 // value.
855 SetNeedsUpdate();
856 return true;
857 }
858
CopyStringDataToBufferSP(const StreamString & source,lldb::WritableDataBufferSP & destination)859 static bool CopyStringDataToBufferSP(const StreamString &source,
860 lldb::WritableDataBufferSP &destination) {
861 llvm::StringRef src = source.GetString();
862 src = src.rtrim('\0');
863 destination = std::make_shared<DataBufferHeap>(src.size(), 0);
864 memcpy(destination->GetBytes(), src.data(), src.size());
865 return true;
866 }
867
868 std::pair<size_t, bool>
ReadPointedString(lldb::WritableDataBufferSP & buffer_sp,Status & error,uint32_t max_length,bool honor_array,Format item_format)869 ValueObject::ReadPointedString(lldb::WritableDataBufferSP &buffer_sp,
870 Status &error, uint32_t max_length,
871 bool honor_array, Format item_format) {
872 bool was_capped = false;
873 StreamString s;
874 ExecutionContext exe_ctx(GetExecutionContextRef());
875 Target *target = exe_ctx.GetTargetPtr();
876
877 if (!target) {
878 s << "<no target to read from>";
879 error.SetErrorString("no target to read from");
880 CopyStringDataToBufferSP(s, buffer_sp);
881 return {0, was_capped};
882 }
883
884 if (max_length == 0)
885 max_length = target->GetMaximumSizeOfStringSummary();
886
887 size_t bytes_read = 0;
888 size_t total_bytes_read = 0;
889
890 CompilerType compiler_type = GetCompilerType();
891 CompilerType elem_or_pointee_compiler_type;
892 const Flags type_flags(GetTypeInfo(&elem_or_pointee_compiler_type));
893 if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
894 elem_or_pointee_compiler_type.IsCharType()) {
895 addr_t cstr_address = LLDB_INVALID_ADDRESS;
896 AddressType cstr_address_type = eAddressTypeInvalid;
897
898 size_t cstr_len = 0;
899 bool capped_data = false;
900 const bool is_array = type_flags.Test(eTypeIsArray);
901 if (is_array) {
902 // We have an array
903 uint64_t array_size = 0;
904 if (compiler_type.IsArrayType(nullptr, &array_size)) {
905 cstr_len = array_size;
906 if (cstr_len > max_length) {
907 capped_data = true;
908 cstr_len = max_length;
909 }
910 }
911 cstr_address = GetAddressOf(true, &cstr_address_type);
912 } else {
913 // We have a pointer
914 cstr_address = GetPointerValue(&cstr_address_type);
915 }
916
917 if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) {
918 if (cstr_address_type == eAddressTypeHost && is_array) {
919 const char *cstr = GetDataExtractor().PeekCStr(0);
920 if (cstr == nullptr) {
921 s << "<invalid address>";
922 error.SetErrorString("invalid address");
923 CopyStringDataToBufferSP(s, buffer_sp);
924 return {0, was_capped};
925 }
926 s << llvm::StringRef(cstr, cstr_len);
927 CopyStringDataToBufferSP(s, buffer_sp);
928 return {cstr_len, was_capped};
929 } else {
930 s << "<invalid address>";
931 error.SetErrorString("invalid address");
932 CopyStringDataToBufferSP(s, buffer_sp);
933 return {0, was_capped};
934 }
935 }
936
937 Address cstr_so_addr(cstr_address);
938 DataExtractor data;
939 if (cstr_len > 0 && honor_array) {
940 // I am using GetPointeeData() here to abstract the fact that some
941 // ValueObjects are actually frozen pointers in the host but the pointed-
942 // to data lives in the debuggee, and GetPointeeData() automatically
943 // takes care of this
944 GetPointeeData(data, 0, cstr_len);
945
946 if ((bytes_read = data.GetByteSize()) > 0) {
947 total_bytes_read = bytes_read;
948 for (size_t offset = 0; offset < bytes_read; offset++)
949 s.Printf("%c", *data.PeekData(offset, 1));
950 if (capped_data)
951 was_capped = true;
952 }
953 } else {
954 cstr_len = max_length;
955 const size_t k_max_buf_size = 64;
956
957 size_t offset = 0;
958
959 int cstr_len_displayed = -1;
960 bool capped_cstr = false;
961 // I am using GetPointeeData() here to abstract the fact that some
962 // ValueObjects are actually frozen pointers in the host but the pointed-
963 // to data lives in the debuggee, and GetPointeeData() automatically
964 // takes care of this
965 while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {
966 total_bytes_read += bytes_read;
967 const char *cstr = data.PeekCStr(0);
968 size_t len = strnlen(cstr, k_max_buf_size);
969 if (cstr_len_displayed < 0)
970 cstr_len_displayed = len;
971
972 if (len == 0)
973 break;
974 cstr_len_displayed += len;
975 if (len > bytes_read)
976 len = bytes_read;
977 if (len > cstr_len)
978 len = cstr_len;
979
980 for (size_t offset = 0; offset < bytes_read; offset++)
981 s.Printf("%c", *data.PeekData(offset, 1));
982
983 if (len < k_max_buf_size)
984 break;
985
986 if (len >= cstr_len) {
987 capped_cstr = true;
988 break;
989 }
990
991 cstr_len -= len;
992 offset += len;
993 }
994
995 if (cstr_len_displayed >= 0) {
996 if (capped_cstr)
997 was_capped = true;
998 }
999 }
1000 } else {
1001 error.SetErrorString("not a string object");
1002 s << "<not a string object>";
1003 }
1004 CopyStringDataToBufferSP(s, buffer_sp);
1005 return {total_bytes_read, was_capped};
1006 }
1007
GetObjectDescription()1008 const char *ValueObject::GetObjectDescription() {
1009 if (!UpdateValueIfNeeded(true))
1010 return nullptr;
1011
1012 // Return cached value.
1013 if (!m_object_desc_str.empty())
1014 return m_object_desc_str.c_str();
1015
1016 ExecutionContext exe_ctx(GetExecutionContextRef());
1017 Process *process = exe_ctx.GetProcessPtr();
1018 if (!process)
1019 return nullptr;
1020
1021 // Returns the object description produced by one language runtime.
1022 auto get_object_description = [&](LanguageType language) -> const char * {
1023 if (LanguageRuntime *runtime = process->GetLanguageRuntime(language)) {
1024 StreamString s;
1025 if (runtime->GetObjectDescription(s, *this)) {
1026 m_object_desc_str.append(std::string(s.GetString()));
1027 return m_object_desc_str.c_str();
1028 }
1029 }
1030 return nullptr;
1031 };
1032
1033 // Try the native language runtime first.
1034 LanguageType native_language = GetObjectRuntimeLanguage();
1035 if (const char *desc = get_object_description(native_language))
1036 return desc;
1037
1038 // Try the Objective-C language runtime. This fallback is necessary
1039 // for Objective-C++ and mixed Objective-C / C++ programs.
1040 if (Language::LanguageIsCFamily(native_language))
1041 return get_object_description(eLanguageTypeObjC);
1042 return nullptr;
1043 }
1044
GetValueAsCString(const lldb_private::TypeFormatImpl & format,std::string & destination)1045 bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,
1046 std::string &destination) {
1047 if (UpdateValueIfNeeded(false))
1048 return format.FormatObject(this, destination);
1049 else
1050 return false;
1051 }
1052
GetValueAsCString(lldb::Format format,std::string & destination)1053 bool ValueObject::GetValueAsCString(lldb::Format format,
1054 std::string &destination) {
1055 return GetValueAsCString(TypeFormatImpl_Format(format), destination);
1056 }
1057
GetValueAsCString()1058 const char *ValueObject::GetValueAsCString() {
1059 if (UpdateValueIfNeeded(true)) {
1060 lldb::TypeFormatImplSP format_sp;
1061 lldb::Format my_format = GetFormat();
1062 if (my_format == lldb::eFormatDefault) {
1063 if (m_type_format_sp)
1064 format_sp = m_type_format_sp;
1065 else {
1066 if (m_flags.m_is_bitfield_for_scalar)
1067 my_format = eFormatUnsigned;
1068 else {
1069 if (m_value.GetContextType() == Value::ContextType::RegisterInfo) {
1070 const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1071 if (reg_info)
1072 my_format = reg_info->format;
1073 } else {
1074 my_format = GetValue().GetCompilerType().GetFormat();
1075 }
1076 }
1077 }
1078 }
1079 if (my_format != m_last_format || m_value_str.empty()) {
1080 m_last_format = my_format;
1081 if (!format_sp)
1082 format_sp = std::make_shared<TypeFormatImpl_Format>(my_format);
1083 if (GetValueAsCString(*format_sp.get(), m_value_str)) {
1084 if (!m_flags.m_value_did_change && m_flags.m_old_value_valid) {
1085 // The value was gotten successfully, so we consider the value as
1086 // changed if the value string differs
1087 SetValueDidChange(m_old_value_str != m_value_str);
1088 }
1089 }
1090 }
1091 }
1092 if (m_value_str.empty())
1093 return nullptr;
1094 return m_value_str.c_str();
1095 }
1096
1097 // if > 8bytes, 0 is returned. this method should mostly be used to read
1098 // address values out of pointers
GetValueAsUnsigned(uint64_t fail_value,bool * success)1099 uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
1100 // If our byte size is zero this is an aggregate type that has children
1101 if (CanProvideValue()) {
1102 Scalar scalar;
1103 if (ResolveValue(scalar)) {
1104 if (success)
1105 *success = true;
1106 scalar.MakeUnsigned();
1107 return scalar.ULongLong(fail_value);
1108 }
1109 // fallthrough, otherwise...
1110 }
1111
1112 if (success)
1113 *success = false;
1114 return fail_value;
1115 }
1116
GetValueAsSigned(int64_t fail_value,bool * success)1117 int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
1118 // If our byte size is zero this is an aggregate type that has children
1119 if (CanProvideValue()) {
1120 Scalar scalar;
1121 if (ResolveValue(scalar)) {
1122 if (success)
1123 *success = true;
1124 scalar.MakeSigned();
1125 return scalar.SLongLong(fail_value);
1126 }
1127 // fallthrough, otherwise...
1128 }
1129
1130 if (success)
1131 *success = false;
1132 return fail_value;
1133 }
1134
1135 // if any more "special cases" are added to
1136 // ValueObject::DumpPrintableRepresentation() please keep this call up to date
1137 // by returning true for your new special cases. We will eventually move to
1138 // checking this call result before trying to display special cases
HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,Format custom_format)1139 bool ValueObject::HasSpecialPrintableRepresentation(
1140 ValueObjectRepresentationStyle val_obj_display, Format custom_format) {
1141 Flags flags(GetTypeInfo());
1142 if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1143 val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1144 if (IsCStringContainer(true) &&
1145 (custom_format == eFormatCString || custom_format == eFormatCharArray ||
1146 custom_format == eFormatChar || custom_format == eFormatVectorOfChar))
1147 return true;
1148
1149 if (flags.Test(eTypeIsArray)) {
1150 if ((custom_format == eFormatBytes) ||
1151 (custom_format == eFormatBytesWithASCII))
1152 return true;
1153
1154 if ((custom_format == eFormatVectorOfChar) ||
1155 (custom_format == eFormatVectorOfFloat32) ||
1156 (custom_format == eFormatVectorOfFloat64) ||
1157 (custom_format == eFormatVectorOfSInt16) ||
1158 (custom_format == eFormatVectorOfSInt32) ||
1159 (custom_format == eFormatVectorOfSInt64) ||
1160 (custom_format == eFormatVectorOfSInt8) ||
1161 (custom_format == eFormatVectorOfUInt128) ||
1162 (custom_format == eFormatVectorOfUInt16) ||
1163 (custom_format == eFormatVectorOfUInt32) ||
1164 (custom_format == eFormatVectorOfUInt64) ||
1165 (custom_format == eFormatVectorOfUInt8))
1166 return true;
1167 }
1168 }
1169 return false;
1170 }
1171
DumpPrintableRepresentation(Stream & s,ValueObjectRepresentationStyle val_obj_display,Format custom_format,PrintableRepresentationSpecialCases special,bool do_dump_error)1172 bool ValueObject::DumpPrintableRepresentation(
1173 Stream &s, ValueObjectRepresentationStyle val_obj_display,
1174 Format custom_format, PrintableRepresentationSpecialCases special,
1175 bool do_dump_error) {
1176
1177 Flags flags(GetTypeInfo());
1178
1179 bool allow_special =
1180 (special == ValueObject::PrintableRepresentationSpecialCases::eAllow);
1181 const bool only_special = false;
1182
1183 if (allow_special) {
1184 if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1185 val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1186 // when being asked to get a printable display an array or pointer type
1187 // directly, try to "do the right thing"
1188
1189 if (IsCStringContainer(true) &&
1190 (custom_format == eFormatCString ||
1191 custom_format == eFormatCharArray || custom_format == eFormatChar ||
1192 custom_format ==
1193 eFormatVectorOfChar)) // print char[] & char* directly
1194 {
1195 Status error;
1196 lldb::WritableDataBufferSP buffer_sp;
1197 std::pair<size_t, bool> read_string = ReadPointedString(
1198 buffer_sp, error, 0, (custom_format == eFormatVectorOfChar) ||
1199 (custom_format == eFormatCharArray));
1200 lldb_private::formatters::StringPrinter::
1201 ReadBufferAndDumpToStreamOptions options(*this);
1202 options.SetData(DataExtractor(
1203 buffer_sp, lldb::eByteOrderInvalid,
1204 8)); // none of this matters for a string - pass some defaults
1205 options.SetStream(&s);
1206 options.SetPrefixToken(nullptr);
1207 options.SetQuote('"');
1208 options.SetSourceSize(buffer_sp->GetByteSize());
1209 options.SetIsTruncated(read_string.second);
1210 options.SetBinaryZeroIsTerminator(custom_format != eFormatVectorOfChar);
1211 formatters::StringPrinter::ReadBufferAndDumpToStream<
1212 lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
1213 options);
1214 return !error.Fail();
1215 }
1216
1217 if (custom_format == eFormatEnum)
1218 return false;
1219
1220 // this only works for arrays, because I have no way to know when the
1221 // pointed memory ends, and no special \0 end of data marker
1222 if (flags.Test(eTypeIsArray)) {
1223 if ((custom_format == eFormatBytes) ||
1224 (custom_format == eFormatBytesWithASCII)) {
1225 const size_t count = GetNumChildren();
1226
1227 s << '[';
1228 for (size_t low = 0; low < count; low++) {
1229
1230 if (low)
1231 s << ',';
1232
1233 ValueObjectSP child = GetChildAtIndex(low, true);
1234 if (!child.get()) {
1235 s << "<invalid child>";
1236 continue;
1237 }
1238 child->DumpPrintableRepresentation(
1239 s, ValueObject::eValueObjectRepresentationStyleValue,
1240 custom_format);
1241 }
1242
1243 s << ']';
1244
1245 return true;
1246 }
1247
1248 if ((custom_format == eFormatVectorOfChar) ||
1249 (custom_format == eFormatVectorOfFloat32) ||
1250 (custom_format == eFormatVectorOfFloat64) ||
1251 (custom_format == eFormatVectorOfSInt16) ||
1252 (custom_format == eFormatVectorOfSInt32) ||
1253 (custom_format == eFormatVectorOfSInt64) ||
1254 (custom_format == eFormatVectorOfSInt8) ||
1255 (custom_format == eFormatVectorOfUInt128) ||
1256 (custom_format == eFormatVectorOfUInt16) ||
1257 (custom_format == eFormatVectorOfUInt32) ||
1258 (custom_format == eFormatVectorOfUInt64) ||
1259 (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes
1260 // with ASCII or any vector
1261 // format should be printed
1262 // directly
1263 {
1264 const size_t count = GetNumChildren();
1265
1266 Format format = FormatManager::GetSingleItemFormat(custom_format);
1267
1268 s << '[';
1269 for (size_t low = 0; low < count; low++) {
1270
1271 if (low)
1272 s << ',';
1273
1274 ValueObjectSP child = GetChildAtIndex(low, true);
1275 if (!child.get()) {
1276 s << "<invalid child>";
1277 continue;
1278 }
1279 child->DumpPrintableRepresentation(
1280 s, ValueObject::eValueObjectRepresentationStyleValue, format);
1281 }
1282
1283 s << ']';
1284
1285 return true;
1286 }
1287 }
1288
1289 if ((custom_format == eFormatBoolean) ||
1290 (custom_format == eFormatBinary) || (custom_format == eFormatChar) ||
1291 (custom_format == eFormatCharPrintable) ||
1292 (custom_format == eFormatComplexFloat) ||
1293 (custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||
1294 (custom_format == eFormatHexUppercase) ||
1295 (custom_format == eFormatFloat) || (custom_format == eFormatOctal) ||
1296 (custom_format == eFormatOSType) ||
1297 (custom_format == eFormatUnicode16) ||
1298 (custom_format == eFormatUnicode32) ||
1299 (custom_format == eFormatUnsigned) ||
1300 (custom_format == eFormatPointer) ||
1301 (custom_format == eFormatComplexInteger) ||
1302 (custom_format == eFormatComplex) ||
1303 (custom_format == eFormatDefault)) // use the [] operator
1304 return false;
1305 }
1306 }
1307
1308 if (only_special)
1309 return false;
1310
1311 bool var_success = false;
1312
1313 {
1314 llvm::StringRef str;
1315
1316 // this is a local stream that we are using to ensure that the data pointed
1317 // to by cstr survives long enough for us to copy it to its destination -
1318 // it is necessary to have this temporary storage area for cases where our
1319 // desired output is not backed by some other longer-term storage
1320 StreamString strm;
1321
1322 if (custom_format != eFormatInvalid)
1323 SetFormat(custom_format);
1324
1325 switch (val_obj_display) {
1326 case eValueObjectRepresentationStyleValue:
1327 str = GetValueAsCString();
1328 break;
1329
1330 case eValueObjectRepresentationStyleSummary:
1331 str = GetSummaryAsCString();
1332 break;
1333
1334 case eValueObjectRepresentationStyleLanguageSpecific:
1335 str = GetObjectDescription();
1336 break;
1337
1338 case eValueObjectRepresentationStyleLocation:
1339 str = GetLocationAsCString();
1340 break;
1341
1342 case eValueObjectRepresentationStyleChildrenCount:
1343 strm.Printf("%" PRIu64 "", (uint64_t)GetNumChildren());
1344 str = strm.GetString();
1345 break;
1346
1347 case eValueObjectRepresentationStyleType:
1348 str = GetTypeName().GetStringRef();
1349 break;
1350
1351 case eValueObjectRepresentationStyleName:
1352 str = GetName().GetStringRef();
1353 break;
1354
1355 case eValueObjectRepresentationStyleExpressionPath:
1356 GetExpressionPath(strm);
1357 str = strm.GetString();
1358 break;
1359 }
1360
1361 if (str.empty()) {
1362 if (val_obj_display == eValueObjectRepresentationStyleValue)
1363 str = GetSummaryAsCString();
1364 else if (val_obj_display == eValueObjectRepresentationStyleSummary) {
1365 if (!CanProvideValue()) {
1366 strm.Printf("%s @ %s", GetTypeName().AsCString(),
1367 GetLocationAsCString());
1368 str = strm.GetString();
1369 } else
1370 str = GetValueAsCString();
1371 }
1372 }
1373
1374 if (!str.empty())
1375 s << str;
1376 else {
1377 if (m_error.Fail()) {
1378 if (do_dump_error)
1379 s.Printf("<%s>", m_error.AsCString());
1380 else
1381 return false;
1382 } else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1383 s.PutCString("<no summary available>");
1384 else if (val_obj_display == eValueObjectRepresentationStyleValue)
1385 s.PutCString("<no value available>");
1386 else if (val_obj_display ==
1387 eValueObjectRepresentationStyleLanguageSpecific)
1388 s.PutCString("<not a valid Objective-C object>"); // edit this if we
1389 // have other runtimes
1390 // that support a
1391 // description
1392 else
1393 s.PutCString("<no printable representation>");
1394 }
1395
1396 // we should only return false here if we could not do *anything* even if
1397 // we have an error message as output, that's a success from our callers'
1398 // perspective, so return true
1399 var_success = true;
1400
1401 if (custom_format != eFormatInvalid)
1402 SetFormat(eFormatDefault);
1403 }
1404
1405 return var_success;
1406 }
1407
GetAddressOf(bool scalar_is_load_address,AddressType * address_type)1408 addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
1409 AddressType *address_type) {
1410 // Can't take address of a bitfield
1411 if (IsBitfield())
1412 return LLDB_INVALID_ADDRESS;
1413
1414 if (!UpdateValueIfNeeded(false))
1415 return LLDB_INVALID_ADDRESS;
1416
1417 switch (m_value.GetValueType()) {
1418 case Value::ValueType::Invalid:
1419 return LLDB_INVALID_ADDRESS;
1420 case Value::ValueType::Scalar:
1421 if (scalar_is_load_address) {
1422 if (address_type)
1423 *address_type = eAddressTypeLoad;
1424 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1425 }
1426 break;
1427
1428 case Value::ValueType::LoadAddress:
1429 case Value::ValueType::FileAddress: {
1430 if (address_type)
1431 *address_type = m_value.GetValueAddressType();
1432 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1433 } break;
1434 case Value::ValueType::HostAddress: {
1435 if (address_type)
1436 *address_type = m_value.GetValueAddressType();
1437 return LLDB_INVALID_ADDRESS;
1438 } break;
1439 }
1440 if (address_type)
1441 *address_type = eAddressTypeInvalid;
1442 return LLDB_INVALID_ADDRESS;
1443 }
1444
GetPointerValue(AddressType * address_type)1445 addr_t ValueObject::GetPointerValue(AddressType *address_type) {
1446 addr_t address = LLDB_INVALID_ADDRESS;
1447 if (address_type)
1448 *address_type = eAddressTypeInvalid;
1449
1450 if (!UpdateValueIfNeeded(false))
1451 return address;
1452
1453 switch (m_value.GetValueType()) {
1454 case Value::ValueType::Invalid:
1455 return LLDB_INVALID_ADDRESS;
1456 case Value::ValueType::Scalar:
1457 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1458 break;
1459
1460 case Value::ValueType::HostAddress:
1461 case Value::ValueType::LoadAddress:
1462 case Value::ValueType::FileAddress: {
1463 lldb::offset_t data_offset = 0;
1464 address = m_data.GetAddress(&data_offset);
1465 } break;
1466 }
1467
1468 if (address_type)
1469 *address_type = GetAddressTypeOfChildren();
1470
1471 return address;
1472 }
1473
SetValueFromCString(const char * value_str,Status & error)1474 bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
1475 error.Clear();
1476 // Make sure our value is up to date first so that our location and location
1477 // type is valid.
1478 if (!UpdateValueIfNeeded(false)) {
1479 error.SetErrorString("unable to read value");
1480 return false;
1481 }
1482
1483 uint64_t count = 0;
1484 const Encoding encoding = GetCompilerType().GetEncoding(count);
1485
1486 const size_t byte_size = GetByteSize().value_or(0);
1487
1488 Value::ValueType value_type = m_value.GetValueType();
1489
1490 if (value_type == Value::ValueType::Scalar) {
1491 // If the value is already a scalar, then let the scalar change itself:
1492 m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
1493 } else if (byte_size <= 16) {
1494 // If the value fits in a scalar, then make a new scalar and again let the
1495 // scalar code do the conversion, then figure out where to put the new
1496 // value.
1497 Scalar new_scalar;
1498 error = new_scalar.SetValueFromCString(value_str, encoding, byte_size);
1499 if (error.Success()) {
1500 switch (value_type) {
1501 case Value::ValueType::LoadAddress: {
1502 // If it is a load address, then the scalar value is the storage
1503 // location of the data, and we have to shove this value down to that
1504 // load location.
1505 ExecutionContext exe_ctx(GetExecutionContextRef());
1506 Process *process = exe_ctx.GetProcessPtr();
1507 if (process) {
1508 addr_t target_addr =
1509 m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1510 size_t bytes_written = process->WriteScalarToMemory(
1511 target_addr, new_scalar, byte_size, error);
1512 if (!error.Success())
1513 return false;
1514 if (bytes_written != byte_size) {
1515 error.SetErrorString("unable to write value to memory");
1516 return false;
1517 }
1518 }
1519 } break;
1520 case Value::ValueType::HostAddress: {
1521 // If it is a host address, then we stuff the scalar as a DataBuffer
1522 // into the Value's data.
1523 DataExtractor new_data;
1524 new_data.SetByteOrder(m_data.GetByteOrder());
1525
1526 DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
1527 m_data.SetData(buffer_sp, 0);
1528 bool success = new_scalar.GetData(new_data);
1529 if (success) {
1530 new_data.CopyByteOrderedData(
1531 0, byte_size, const_cast<uint8_t *>(m_data.GetDataStart()),
1532 byte_size, m_data.GetByteOrder());
1533 }
1534 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1535
1536 } break;
1537 case Value::ValueType::Invalid:
1538 error.SetErrorString("invalid location");
1539 return false;
1540 case Value::ValueType::FileAddress:
1541 case Value::ValueType::Scalar:
1542 break;
1543 }
1544 } else {
1545 return false;
1546 }
1547 } else {
1548 // We don't support setting things bigger than a scalar at present.
1549 error.SetErrorString("unable to write aggregate data type");
1550 return false;
1551 }
1552
1553 // If we have reached this point, then we have successfully changed the
1554 // value.
1555 SetNeedsUpdate();
1556 return true;
1557 }
1558
GetDeclaration(Declaration & decl)1559 bool ValueObject::GetDeclaration(Declaration &decl) {
1560 decl.Clear();
1561 return false;
1562 }
1563
AddSyntheticChild(ConstString key,ValueObject * valobj)1564 void ValueObject::AddSyntheticChild(ConstString key,
1565 ValueObject *valobj) {
1566 m_synthetic_children[key] = valobj;
1567 }
1568
GetSyntheticChild(ConstString key) const1569 ValueObjectSP ValueObject::GetSyntheticChild(ConstString key) const {
1570 ValueObjectSP synthetic_child_sp;
1571 std::map<ConstString, ValueObject *>::const_iterator pos =
1572 m_synthetic_children.find(key);
1573 if (pos != m_synthetic_children.end())
1574 synthetic_child_sp = pos->second->GetSP();
1575 return synthetic_child_sp;
1576 }
1577
IsPossibleDynamicType()1578 bool ValueObject::IsPossibleDynamicType() {
1579 ExecutionContext exe_ctx(GetExecutionContextRef());
1580 Process *process = exe_ctx.GetProcessPtr();
1581 if (process)
1582 return process->IsPossibleDynamicValue(*this);
1583 else
1584 return GetCompilerType().IsPossibleDynamicType(nullptr, true, true);
1585 }
1586
IsRuntimeSupportValue()1587 bool ValueObject::IsRuntimeSupportValue() {
1588 Process *process(GetProcessSP().get());
1589 if (!process)
1590 return false;
1591
1592 // We trust that the compiler did the right thing and marked runtime support
1593 // values as artificial.
1594 if (!GetVariable() || !GetVariable()->IsArtificial())
1595 return false;
1596
1597 if (auto *runtime = process->GetLanguageRuntime(GetVariable()->GetLanguage()))
1598 if (runtime->IsAllowedRuntimeValue(GetName()))
1599 return false;
1600
1601 return true;
1602 }
1603
IsNilReference()1604 bool ValueObject::IsNilReference() {
1605 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1606 return language->IsNilReference(*this);
1607 }
1608 return false;
1609 }
1610
IsUninitializedReference()1611 bool ValueObject::IsUninitializedReference() {
1612 if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1613 return language->IsUninitializedReference(*this);
1614 }
1615 return false;
1616 }
1617
1618 // This allows you to create an array member using and index that doesn't not
1619 // fall in the normal bounds of the array. Many times structure can be defined
1620 // as: struct Collection {
1621 // uint32_t item_count;
1622 // Item item_array[0];
1623 // };
1624 // The size of the "item_array" is 1, but many times in practice there are more
1625 // items in "item_array".
1626
GetSyntheticArrayMember(size_t index,bool can_create)1627 ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
1628 bool can_create) {
1629 ValueObjectSP synthetic_child_sp;
1630 if (IsPointerType() || IsArrayType()) {
1631 std::string index_str = llvm::formatv("[{0}]", index);
1632 ConstString index_const_str(index_str);
1633 // Check if we have already created a synthetic array member in this valid
1634 // object. If we have we will re-use it.
1635 synthetic_child_sp = GetSyntheticChild(index_const_str);
1636 if (!synthetic_child_sp) {
1637 ValueObject *synthetic_child;
1638 // We haven't made a synthetic array member for INDEX yet, so lets make
1639 // one and cache it for any future reference.
1640 synthetic_child = CreateChildAtIndex(0, true, index);
1641
1642 // Cache the value if we got one back...
1643 if (synthetic_child) {
1644 AddSyntheticChild(index_const_str, synthetic_child);
1645 synthetic_child_sp = synthetic_child->GetSP();
1646 synthetic_child_sp->SetName(ConstString(index_str));
1647 synthetic_child_sp->m_flags.m_is_array_item_for_pointer = true;
1648 }
1649 }
1650 }
1651 return synthetic_child_sp;
1652 }
1653
GetSyntheticBitFieldChild(uint32_t from,uint32_t to,bool can_create)1654 ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
1655 bool can_create) {
1656 ValueObjectSP synthetic_child_sp;
1657 if (IsScalarType()) {
1658 std::string index_str = llvm::formatv("[{0}-{1}]", from, to);
1659 ConstString index_const_str(index_str);
1660 // Check if we have already created a synthetic array member in this valid
1661 // object. If we have we will re-use it.
1662 synthetic_child_sp = GetSyntheticChild(index_const_str);
1663 if (!synthetic_child_sp) {
1664 uint32_t bit_field_size = to - from + 1;
1665 uint32_t bit_field_offset = from;
1666 if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
1667 bit_field_offset =
1668 GetByteSize().value_or(0) * 8 - bit_field_size - bit_field_offset;
1669 // We haven't made a synthetic array member for INDEX yet, so lets make
1670 // one and cache it for any future reference.
1671 ValueObjectChild *synthetic_child = new ValueObjectChild(
1672 *this, GetCompilerType(), index_const_str, GetByteSize().value_or(0),
1673 0, bit_field_size, bit_field_offset, false, false,
1674 eAddressTypeInvalid, 0);
1675
1676 // Cache the value if we got one back...
1677 if (synthetic_child) {
1678 AddSyntheticChild(index_const_str, synthetic_child);
1679 synthetic_child_sp = synthetic_child->GetSP();
1680 synthetic_child_sp->SetName(ConstString(index_str));
1681 synthetic_child_sp->m_flags.m_is_bitfield_for_scalar = true;
1682 }
1683 }
1684 }
1685 return synthetic_child_sp;
1686 }
1687
GetSyntheticChildAtOffset(uint32_t offset,const CompilerType & type,bool can_create,ConstString name_const_str)1688 ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
1689 uint32_t offset, const CompilerType &type, bool can_create,
1690 ConstString name_const_str) {
1691
1692 ValueObjectSP synthetic_child_sp;
1693
1694 if (name_const_str.IsEmpty()) {
1695 name_const_str.SetString("@" + std::to_string(offset));
1696 }
1697
1698 // Check if we have already created a synthetic array member in this valid
1699 // object. If we have we will re-use it.
1700 synthetic_child_sp = GetSyntheticChild(name_const_str);
1701
1702 if (synthetic_child_sp.get())
1703 return synthetic_child_sp;
1704
1705 if (!can_create)
1706 return {};
1707
1708 ExecutionContext exe_ctx(GetExecutionContextRef());
1709 std::optional<uint64_t> size =
1710 type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
1711 if (!size)
1712 return {};
1713 ValueObjectChild *synthetic_child =
1714 new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
1715 false, false, eAddressTypeInvalid, 0);
1716 if (synthetic_child) {
1717 AddSyntheticChild(name_const_str, synthetic_child);
1718 synthetic_child_sp = synthetic_child->GetSP();
1719 synthetic_child_sp->SetName(name_const_str);
1720 synthetic_child_sp->m_flags.m_is_child_at_offset = true;
1721 }
1722 return synthetic_child_sp;
1723 }
1724
GetSyntheticBase(uint32_t offset,const CompilerType & type,bool can_create,ConstString name_const_str)1725 ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
1726 const CompilerType &type,
1727 bool can_create,
1728 ConstString name_const_str) {
1729 ValueObjectSP synthetic_child_sp;
1730
1731 if (name_const_str.IsEmpty()) {
1732 char name_str[128];
1733 snprintf(name_str, sizeof(name_str), "base%s@%i",
1734 type.GetTypeName().AsCString("<unknown>"), offset);
1735 name_const_str.SetCString(name_str);
1736 }
1737
1738 // Check if we have already created a synthetic array member in this valid
1739 // object. If we have we will re-use it.
1740 synthetic_child_sp = GetSyntheticChild(name_const_str);
1741
1742 if (synthetic_child_sp.get())
1743 return synthetic_child_sp;
1744
1745 if (!can_create)
1746 return {};
1747
1748 const bool is_base_class = true;
1749
1750 ExecutionContext exe_ctx(GetExecutionContextRef());
1751 std::optional<uint64_t> size =
1752 type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
1753 if (!size)
1754 return {};
1755 ValueObjectChild *synthetic_child =
1756 new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
1757 is_base_class, false, eAddressTypeInvalid, 0);
1758 if (synthetic_child) {
1759 AddSyntheticChild(name_const_str, synthetic_child);
1760 synthetic_child_sp = synthetic_child->GetSP();
1761 synthetic_child_sp->SetName(name_const_str);
1762 }
1763 return synthetic_child_sp;
1764 }
1765
1766 // your expression path needs to have a leading . or -> (unless it somehow
1767 // "looks like" an array, in which case it has a leading [ symbol). while the [
1768 // is meaningful and should be shown to the user, . and -> are just parser
1769 // design, but by no means added information for the user.. strip them off
SkipLeadingExpressionPathSeparators(const char * expression)1770 static const char *SkipLeadingExpressionPathSeparators(const char *expression) {
1771 if (!expression || !expression[0])
1772 return expression;
1773 if (expression[0] == '.')
1774 return expression + 1;
1775 if (expression[0] == '-' && expression[1] == '>')
1776 return expression + 2;
1777 return expression;
1778 }
1779
1780 ValueObjectSP
GetSyntheticExpressionPathChild(const char * expression,bool can_create)1781 ValueObject::GetSyntheticExpressionPathChild(const char *expression,
1782 bool can_create) {
1783 ValueObjectSP synthetic_child_sp;
1784 ConstString name_const_string(expression);
1785 // Check if we have already created a synthetic array member in this valid
1786 // object. If we have we will re-use it.
1787 synthetic_child_sp = GetSyntheticChild(name_const_string);
1788 if (!synthetic_child_sp) {
1789 // We haven't made a synthetic array member for expression yet, so lets
1790 // make one and cache it for any future reference.
1791 synthetic_child_sp = GetValueForExpressionPath(
1792 expression, nullptr, nullptr,
1793 GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(
1794 GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
1795 None));
1796
1797 // Cache the value if we got one back...
1798 if (synthetic_child_sp.get()) {
1799 // FIXME: this causes a "real" child to end up with its name changed to
1800 // the contents of expression
1801 AddSyntheticChild(name_const_string, synthetic_child_sp.get());
1802 synthetic_child_sp->SetName(
1803 ConstString(SkipLeadingExpressionPathSeparators(expression)));
1804 }
1805 }
1806 return synthetic_child_sp;
1807 }
1808
CalculateSyntheticValue()1809 void ValueObject::CalculateSyntheticValue() {
1810 TargetSP target_sp(GetTargetSP());
1811 if (target_sp && !target_sp->GetEnableSyntheticValue()) {
1812 m_synthetic_value = nullptr;
1813 return;
1814 }
1815
1816 lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
1817
1818 if (!UpdateFormatsIfNeeded() && m_synthetic_value)
1819 return;
1820
1821 if (m_synthetic_children_sp.get() == nullptr)
1822 return;
1823
1824 if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
1825 return;
1826
1827 m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
1828 }
1829
CalculateDynamicValue(DynamicValueType use_dynamic)1830 void ValueObject::CalculateDynamicValue(DynamicValueType use_dynamic) {
1831 if (use_dynamic == eNoDynamicValues)
1832 return;
1833
1834 if (!m_dynamic_value && !IsDynamic()) {
1835 ExecutionContext exe_ctx(GetExecutionContextRef());
1836 Process *process = exe_ctx.GetProcessPtr();
1837 if (process && process->IsPossibleDynamicValue(*this)) {
1838 ClearDynamicTypeInformation();
1839 m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
1840 }
1841 }
1842 }
1843
GetDynamicValue(DynamicValueType use_dynamic)1844 ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) {
1845 if (use_dynamic == eNoDynamicValues)
1846 return ValueObjectSP();
1847
1848 if (!IsDynamic() && m_dynamic_value == nullptr) {
1849 CalculateDynamicValue(use_dynamic);
1850 }
1851 if (m_dynamic_value)
1852 return m_dynamic_value->GetSP();
1853 else
1854 return ValueObjectSP();
1855 }
1856
GetSyntheticValue()1857 ValueObjectSP ValueObject::GetSyntheticValue() {
1858 CalculateSyntheticValue();
1859
1860 if (m_synthetic_value)
1861 return m_synthetic_value->GetSP();
1862 else
1863 return ValueObjectSP();
1864 }
1865
HasSyntheticValue()1866 bool ValueObject::HasSyntheticValue() {
1867 UpdateFormatsIfNeeded();
1868
1869 if (m_synthetic_children_sp.get() == nullptr)
1870 return false;
1871
1872 CalculateSyntheticValue();
1873
1874 return m_synthetic_value != nullptr;
1875 }
1876
GetNonBaseClassParent()1877 ValueObject *ValueObject::GetNonBaseClassParent() {
1878 if (GetParent()) {
1879 if (GetParent()->IsBaseClass())
1880 return GetParent()->GetNonBaseClassParent();
1881 else
1882 return GetParent();
1883 }
1884 return nullptr;
1885 }
1886
IsBaseClass(uint32_t & depth)1887 bool ValueObject::IsBaseClass(uint32_t &depth) {
1888 if (!IsBaseClass()) {
1889 depth = 0;
1890 return false;
1891 }
1892 if (GetParent()) {
1893 GetParent()->IsBaseClass(depth);
1894 depth = depth + 1;
1895 return true;
1896 }
1897 // TODO: a base of no parent? weird..
1898 depth = 1;
1899 return true;
1900 }
1901
GetExpressionPath(Stream & s,GetExpressionPathFormat epformat)1902 void ValueObject::GetExpressionPath(Stream &s,
1903 GetExpressionPathFormat epformat) {
1904 // synthetic children do not actually "exist" as part of the hierarchy, and
1905 // sometimes they are consed up in ways that don't make sense from an
1906 // underlying language/API standpoint. So, use a special code path here to
1907 // return something that can hopefully be used in expression
1908 if (m_flags.m_is_synthetic_children_generated) {
1909 UpdateValueIfNeeded();
1910
1911 if (m_value.GetValueType() == Value::ValueType::LoadAddress) {
1912 if (IsPointerOrReferenceType()) {
1913 s.Printf("((%s)0x%" PRIx64 ")", GetTypeName().AsCString("void"),
1914 GetValueAsUnsigned(0));
1915 return;
1916 } else {
1917 uint64_t load_addr =
1918 m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1919 if (load_addr != LLDB_INVALID_ADDRESS) {
1920 s.Printf("(*( (%s *)0x%" PRIx64 "))", GetTypeName().AsCString("void"),
1921 load_addr);
1922 return;
1923 }
1924 }
1925 }
1926
1927 if (CanProvideValue()) {
1928 s.Printf("((%s)%s)", GetTypeName().AsCString("void"),
1929 GetValueAsCString());
1930 return;
1931 }
1932
1933 return;
1934 }
1935
1936 const bool is_deref_of_parent = IsDereferenceOfParent();
1937
1938 if (is_deref_of_parent &&
1939 epformat == eGetExpressionPathFormatDereferencePointers) {
1940 // this is the original format of GetExpressionPath() producing code like
1941 // *(a_ptr).memberName, which is entirely fine, until you put this into
1942 // StackFrame::GetValueForVariableExpressionPath() which prefers to see
1943 // a_ptr->memberName. the eHonorPointers mode is meant to produce strings
1944 // in this latter format
1945 s.PutCString("*(");
1946 }
1947
1948 ValueObject *parent = GetParent();
1949
1950 if (parent)
1951 parent->GetExpressionPath(s, epformat);
1952
1953 // if we are a deref_of_parent just because we are synthetic array members
1954 // made up to allow ptr[%d] syntax to work in variable printing, then add our
1955 // name ([%d]) to the expression path
1956 if (m_flags.m_is_array_item_for_pointer &&
1957 epformat == eGetExpressionPathFormatHonorPointers)
1958 s.PutCString(m_name.GetStringRef());
1959
1960 if (!IsBaseClass()) {
1961 if (!is_deref_of_parent) {
1962 ValueObject *non_base_class_parent = GetNonBaseClassParent();
1963 if (non_base_class_parent &&
1964 !non_base_class_parent->GetName().IsEmpty()) {
1965 CompilerType non_base_class_parent_compiler_type =
1966 non_base_class_parent->GetCompilerType();
1967 if (non_base_class_parent_compiler_type) {
1968 if (parent && parent->IsDereferenceOfParent() &&
1969 epformat == eGetExpressionPathFormatHonorPointers) {
1970 s.PutCString("->");
1971 } else {
1972 const uint32_t non_base_class_parent_type_info =
1973 non_base_class_parent_compiler_type.GetTypeInfo();
1974
1975 if (non_base_class_parent_type_info & eTypeIsPointer) {
1976 s.PutCString("->");
1977 } else if ((non_base_class_parent_type_info & eTypeHasChildren) &&
1978 !(non_base_class_parent_type_info & eTypeIsArray)) {
1979 s.PutChar('.');
1980 }
1981 }
1982 }
1983 }
1984
1985 const char *name = GetName().GetCString();
1986 if (name)
1987 s.PutCString(name);
1988 }
1989 }
1990
1991 if (is_deref_of_parent &&
1992 epformat == eGetExpressionPathFormatDereferencePointers) {
1993 s.PutChar(')');
1994 }
1995 }
1996
GetValueForExpressionPath(llvm::StringRef expression,ExpressionPathScanEndReason * reason_to_stop,ExpressionPathEndResultType * final_value_type,const GetValueForExpressionPathOptions & options,ExpressionPathAftermath * final_task_on_target)1997 ValueObjectSP ValueObject::GetValueForExpressionPath(
1998 llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
1999 ExpressionPathEndResultType *final_value_type,
2000 const GetValueForExpressionPathOptions &options,
2001 ExpressionPathAftermath *final_task_on_target) {
2002
2003 ExpressionPathScanEndReason dummy_reason_to_stop =
2004 ValueObject::eExpressionPathScanEndReasonUnknown;
2005 ExpressionPathEndResultType dummy_final_value_type =
2006 ValueObject::eExpressionPathEndResultTypeInvalid;
2007 ExpressionPathAftermath dummy_final_task_on_target =
2008 ValueObject::eExpressionPathAftermathNothing;
2009
2010 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(
2011 expression, reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
2012 final_value_type ? final_value_type : &dummy_final_value_type, options,
2013 final_task_on_target ? final_task_on_target
2014 : &dummy_final_task_on_target);
2015
2016 if (!final_task_on_target ||
2017 *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
2018 return ret_val;
2019
2020 if (ret_val.get() &&
2021 ((final_value_type ? *final_value_type : dummy_final_value_type) ==
2022 eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress
2023 // of plain objects
2024 {
2025 if ((final_task_on_target ? *final_task_on_target
2026 : dummy_final_task_on_target) ==
2027 ValueObject::eExpressionPathAftermathDereference) {
2028 Status error;
2029 ValueObjectSP final_value = ret_val->Dereference(error);
2030 if (error.Fail() || !final_value.get()) {
2031 if (reason_to_stop)
2032 *reason_to_stop =
2033 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2034 if (final_value_type)
2035 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2036 return ValueObjectSP();
2037 } else {
2038 if (final_task_on_target)
2039 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2040 return final_value;
2041 }
2042 }
2043 if (*final_task_on_target ==
2044 ValueObject::eExpressionPathAftermathTakeAddress) {
2045 Status error;
2046 ValueObjectSP final_value = ret_val->AddressOf(error);
2047 if (error.Fail() || !final_value.get()) {
2048 if (reason_to_stop)
2049 *reason_to_stop =
2050 ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
2051 if (final_value_type)
2052 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2053 return ValueObjectSP();
2054 } else {
2055 if (final_task_on_target)
2056 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2057 return final_value;
2058 }
2059 }
2060 }
2061 return ret_val; // final_task_on_target will still have its original value, so
2062 // you know I did not do it
2063 }
2064
GetValueForExpressionPath_Impl(llvm::StringRef expression,ExpressionPathScanEndReason * reason_to_stop,ExpressionPathEndResultType * final_result,const GetValueForExpressionPathOptions & options,ExpressionPathAftermath * what_next)2065 ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
2066 llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
2067 ExpressionPathEndResultType *final_result,
2068 const GetValueForExpressionPathOptions &options,
2069 ExpressionPathAftermath *what_next) {
2070 ValueObjectSP root = GetSP();
2071
2072 if (!root)
2073 return nullptr;
2074
2075 llvm::StringRef remainder = expression;
2076
2077 while (true) {
2078 llvm::StringRef temp_expression = remainder;
2079
2080 CompilerType root_compiler_type = root->GetCompilerType();
2081 CompilerType pointee_compiler_type;
2082 Flags pointee_compiler_type_info;
2083
2084 Flags root_compiler_type_info(
2085 root_compiler_type.GetTypeInfo(&pointee_compiler_type));
2086 if (pointee_compiler_type)
2087 pointee_compiler_type_info.Reset(pointee_compiler_type.GetTypeInfo());
2088
2089 if (temp_expression.empty()) {
2090 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2091 return root;
2092 }
2093
2094 switch (temp_expression.front()) {
2095 case '-': {
2096 temp_expression = temp_expression.drop_front();
2097 if (options.m_check_dot_vs_arrow_syntax &&
2098 root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2099 // use -> on a
2100 // non-pointer and I
2101 // must catch the error
2102 {
2103 *reason_to_stop =
2104 ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
2105 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2106 return ValueObjectSP();
2107 }
2108 if (root_compiler_type_info.Test(eTypeIsObjC) && // if yo are trying to
2109 // extract an ObjC IVar
2110 // when this is forbidden
2111 root_compiler_type_info.Test(eTypeIsPointer) &&
2112 options.m_no_fragile_ivar) {
2113 *reason_to_stop =
2114 ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
2115 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2116 return ValueObjectSP();
2117 }
2118 if (!temp_expression.startswith(">")) {
2119 *reason_to_stop =
2120 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2121 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2122 return ValueObjectSP();
2123 }
2124 }
2125 [[fallthrough]];
2126 case '.': // or fallthrough from ->
2127 {
2128 if (options.m_check_dot_vs_arrow_syntax &&
2129 temp_expression.front() == '.' &&
2130 root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2131 // use . on a pointer
2132 // and I must catch the
2133 // error
2134 {
2135 *reason_to_stop =
2136 ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
2137 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2138 return nullptr;
2139 }
2140 temp_expression = temp_expression.drop_front(); // skip . or >
2141
2142 size_t next_sep_pos = temp_expression.find_first_of("-.[", 1);
2143 ConstString child_name;
2144 if (next_sep_pos == llvm::StringRef::npos) // if no other separator just
2145 // expand this last layer
2146 {
2147 child_name.SetString(temp_expression);
2148 ValueObjectSP child_valobj_sp =
2149 root->GetChildMemberWithName(child_name, true);
2150
2151 if (child_valobj_sp.get()) // we know we are done, so just return
2152 {
2153 *reason_to_stop =
2154 ValueObject::eExpressionPathScanEndReasonEndOfString;
2155 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2156 return child_valobj_sp;
2157 } else {
2158 switch (options.m_synthetic_children_traversal) {
2159 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2160 None:
2161 break;
2162 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2163 FromSynthetic:
2164 if (root->IsSynthetic()) {
2165 child_valobj_sp = root->GetNonSyntheticValue();
2166 if (child_valobj_sp.get())
2167 child_valobj_sp =
2168 child_valobj_sp->GetChildMemberWithName(child_name, true);
2169 }
2170 break;
2171 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2172 ToSynthetic:
2173 if (!root->IsSynthetic()) {
2174 child_valobj_sp = root->GetSyntheticValue();
2175 if (child_valobj_sp.get())
2176 child_valobj_sp =
2177 child_valobj_sp->GetChildMemberWithName(child_name, true);
2178 }
2179 break;
2180 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2181 Both:
2182 if (root->IsSynthetic()) {
2183 child_valobj_sp = root->GetNonSyntheticValue();
2184 if (child_valobj_sp.get())
2185 child_valobj_sp =
2186 child_valobj_sp->GetChildMemberWithName(child_name, true);
2187 } else {
2188 child_valobj_sp = root->GetSyntheticValue();
2189 if (child_valobj_sp.get())
2190 child_valobj_sp =
2191 child_valobj_sp->GetChildMemberWithName(child_name, true);
2192 }
2193 break;
2194 }
2195 }
2196
2197 // if we are here and options.m_no_synthetic_children is true,
2198 // child_valobj_sp is going to be a NULL SP, so we hit the "else"
2199 // branch, and return an error
2200 if (child_valobj_sp.get()) // if it worked, just return
2201 {
2202 *reason_to_stop =
2203 ValueObject::eExpressionPathScanEndReasonEndOfString;
2204 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2205 return child_valobj_sp;
2206 } else {
2207 *reason_to_stop =
2208 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2209 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2210 return nullptr;
2211 }
2212 } else // other layers do expand
2213 {
2214 llvm::StringRef next_separator = temp_expression.substr(next_sep_pos);
2215
2216 child_name.SetString(temp_expression.slice(0, next_sep_pos));
2217
2218 ValueObjectSP child_valobj_sp =
2219 root->GetChildMemberWithName(child_name, true);
2220 if (child_valobj_sp.get()) // store the new root and move on
2221 {
2222 root = child_valobj_sp;
2223 remainder = next_separator;
2224 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2225 continue;
2226 } else {
2227 switch (options.m_synthetic_children_traversal) {
2228 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2229 None:
2230 break;
2231 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2232 FromSynthetic:
2233 if (root->IsSynthetic()) {
2234 child_valobj_sp = root->GetNonSyntheticValue();
2235 if (child_valobj_sp.get())
2236 child_valobj_sp =
2237 child_valobj_sp->GetChildMemberWithName(child_name, true);
2238 }
2239 break;
2240 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2241 ToSynthetic:
2242 if (!root->IsSynthetic()) {
2243 child_valobj_sp = root->GetSyntheticValue();
2244 if (child_valobj_sp.get())
2245 child_valobj_sp =
2246 child_valobj_sp->GetChildMemberWithName(child_name, true);
2247 }
2248 break;
2249 case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2250 Both:
2251 if (root->IsSynthetic()) {
2252 child_valobj_sp = root->GetNonSyntheticValue();
2253 if (child_valobj_sp.get())
2254 child_valobj_sp =
2255 child_valobj_sp->GetChildMemberWithName(child_name, true);
2256 } else {
2257 child_valobj_sp = root->GetSyntheticValue();
2258 if (child_valobj_sp.get())
2259 child_valobj_sp =
2260 child_valobj_sp->GetChildMemberWithName(child_name, true);
2261 }
2262 break;
2263 }
2264 }
2265
2266 // if we are here and options.m_no_synthetic_children is true,
2267 // child_valobj_sp is going to be a NULL SP, so we hit the "else"
2268 // branch, and return an error
2269 if (child_valobj_sp.get()) // if it worked, move on
2270 {
2271 root = child_valobj_sp;
2272 remainder = next_separator;
2273 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2274 continue;
2275 } else {
2276 *reason_to_stop =
2277 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2278 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2279 return nullptr;
2280 }
2281 }
2282 break;
2283 }
2284 case '[': {
2285 if (!root_compiler_type_info.Test(eTypeIsArray) &&
2286 !root_compiler_type_info.Test(eTypeIsPointer) &&
2287 !root_compiler_type_info.Test(
2288 eTypeIsVector)) // if this is not a T[] nor a T*
2289 {
2290 if (!root_compiler_type_info.Test(
2291 eTypeIsScalar)) // if this is not even a scalar...
2292 {
2293 if (options.m_synthetic_children_traversal ==
2294 GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2295 None) // ...only chance left is synthetic
2296 {
2297 *reason_to_stop =
2298 ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
2299 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2300 return ValueObjectSP();
2301 }
2302 } else if (!options.m_allow_bitfields_syntax) // if this is a scalar,
2303 // check that we can
2304 // expand bitfields
2305 {
2306 *reason_to_stop =
2307 ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
2308 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2309 return ValueObjectSP();
2310 }
2311 }
2312 if (temp_expression[1] ==
2313 ']') // if this is an unbounded range it only works for arrays
2314 {
2315 if (!root_compiler_type_info.Test(eTypeIsArray)) {
2316 *reason_to_stop =
2317 ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2318 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2319 return nullptr;
2320 } else // even if something follows, we cannot expand unbounded ranges,
2321 // just let the caller do it
2322 {
2323 *reason_to_stop =
2324 ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2325 *final_result =
2326 ValueObject::eExpressionPathEndResultTypeUnboundedRange;
2327 return root;
2328 }
2329 }
2330
2331 size_t close_bracket_position = temp_expression.find(']', 1);
2332 if (close_bracket_position ==
2333 llvm::StringRef::npos) // if there is no ], this is a syntax error
2334 {
2335 *reason_to_stop =
2336 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2337 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2338 return nullptr;
2339 }
2340
2341 llvm::StringRef bracket_expr =
2342 temp_expression.slice(1, close_bracket_position);
2343
2344 // If this was an empty expression it would have been caught by the if
2345 // above.
2346 assert(!bracket_expr.empty());
2347
2348 if (!bracket_expr.contains('-')) {
2349 // if no separator, this is of the form [N]. Note that this cannot be
2350 // an unbounded range of the form [], because that case was handled
2351 // above with an unconditional return.
2352 unsigned long index = 0;
2353 if (bracket_expr.getAsInteger(0, index)) {
2354 *reason_to_stop =
2355 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2356 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2357 return nullptr;
2358 }
2359
2360 // from here on we do have a valid index
2361 if (root_compiler_type_info.Test(eTypeIsArray)) {
2362 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2363 if (!child_valobj_sp)
2364 child_valobj_sp = root->GetSyntheticArrayMember(index, true);
2365 if (!child_valobj_sp)
2366 if (root->HasSyntheticValue() &&
2367 root->GetSyntheticValue()->GetNumChildren() > index)
2368 child_valobj_sp =
2369 root->GetSyntheticValue()->GetChildAtIndex(index, true);
2370 if (child_valobj_sp) {
2371 root = child_valobj_sp;
2372 remainder =
2373 temp_expression.substr(close_bracket_position + 1); // skip ]
2374 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2375 continue;
2376 } else {
2377 *reason_to_stop =
2378 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2379 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2380 return nullptr;
2381 }
2382 } else if (root_compiler_type_info.Test(eTypeIsPointer)) {
2383 if (*what_next ==
2384 ValueObject::
2385 eExpressionPathAftermathDereference && // if this is a
2386 // ptr-to-scalar, I
2387 // am accessing it
2388 // by index and I
2389 // would have
2390 // deref'ed anyway,
2391 // then do it now
2392 // and use this as
2393 // a bitfield
2394 pointee_compiler_type_info.Test(eTypeIsScalar)) {
2395 Status error;
2396 root = root->Dereference(error);
2397 if (error.Fail() || !root) {
2398 *reason_to_stop =
2399 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2400 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2401 return nullptr;
2402 } else {
2403 *what_next = eExpressionPathAftermathNothing;
2404 continue;
2405 }
2406 } else {
2407 if (root->GetCompilerType().GetMinimumLanguage() ==
2408 eLanguageTypeObjC &&
2409 pointee_compiler_type_info.AllClear(eTypeIsPointer) &&
2410 root->HasSyntheticValue() &&
2411 (options.m_synthetic_children_traversal ==
2412 GetValueForExpressionPathOptions::
2413 SyntheticChildrenTraversal::ToSynthetic ||
2414 options.m_synthetic_children_traversal ==
2415 GetValueForExpressionPathOptions::
2416 SyntheticChildrenTraversal::Both)) {
2417 root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
2418 } else
2419 root = root->GetSyntheticArrayMember(index, true);
2420 if (!root) {
2421 *reason_to_stop =
2422 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2423 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2424 return nullptr;
2425 } else {
2426 remainder =
2427 temp_expression.substr(close_bracket_position + 1); // skip ]
2428 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2429 continue;
2430 }
2431 }
2432 } else if (root_compiler_type_info.Test(eTypeIsScalar)) {
2433 root = root->GetSyntheticBitFieldChild(index, index, true);
2434 if (!root) {
2435 *reason_to_stop =
2436 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2437 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2438 return nullptr;
2439 } else // we do not know how to expand members of bitfields, so we
2440 // just return and let the caller do any further processing
2441 {
2442 *reason_to_stop = ValueObject::
2443 eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2444 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2445 return root;
2446 }
2447 } else if (root_compiler_type_info.Test(eTypeIsVector)) {
2448 root = root->GetChildAtIndex(index, true);
2449 if (!root) {
2450 *reason_to_stop =
2451 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2452 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2453 return ValueObjectSP();
2454 } else {
2455 remainder =
2456 temp_expression.substr(close_bracket_position + 1); // skip ]
2457 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2458 continue;
2459 }
2460 } else if (options.m_synthetic_children_traversal ==
2461 GetValueForExpressionPathOptions::
2462 SyntheticChildrenTraversal::ToSynthetic ||
2463 options.m_synthetic_children_traversal ==
2464 GetValueForExpressionPathOptions::
2465 SyntheticChildrenTraversal::Both) {
2466 if (root->HasSyntheticValue())
2467 root = root->GetSyntheticValue();
2468 else if (!root->IsSynthetic()) {
2469 *reason_to_stop =
2470 ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2471 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2472 return nullptr;
2473 }
2474 // if we are here, then root itself is a synthetic VO.. should be
2475 // good to go
2476
2477 if (!root) {
2478 *reason_to_stop =
2479 ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2480 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2481 return nullptr;
2482 }
2483 root = root->GetChildAtIndex(index, true);
2484 if (!root) {
2485 *reason_to_stop =
2486 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2487 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2488 return nullptr;
2489 } else {
2490 remainder =
2491 temp_expression.substr(close_bracket_position + 1); // skip ]
2492 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2493 continue;
2494 }
2495 } else {
2496 *reason_to_stop =
2497 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2498 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2499 return nullptr;
2500 }
2501 } else {
2502 // we have a low and a high index
2503 llvm::StringRef sleft, sright;
2504 unsigned long low_index, high_index;
2505 std::tie(sleft, sright) = bracket_expr.split('-');
2506 if (sleft.getAsInteger(0, low_index) ||
2507 sright.getAsInteger(0, high_index)) {
2508 *reason_to_stop =
2509 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2510 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2511 return nullptr;
2512 }
2513
2514 if (low_index > high_index) // swap indices if required
2515 std::swap(low_index, high_index);
2516
2517 if (root_compiler_type_info.Test(
2518 eTypeIsScalar)) // expansion only works for scalars
2519 {
2520 root = root->GetSyntheticBitFieldChild(low_index, high_index, true);
2521 if (!root) {
2522 *reason_to_stop =
2523 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2524 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2525 return nullptr;
2526 } else {
2527 *reason_to_stop = ValueObject::
2528 eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2529 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2530 return root;
2531 }
2532 } else if (root_compiler_type_info.Test(
2533 eTypeIsPointer) && // if this is a ptr-to-scalar, I am
2534 // accessing it by index and I would
2535 // have deref'ed anyway, then do it
2536 // now and use this as a bitfield
2537 *what_next ==
2538 ValueObject::eExpressionPathAftermathDereference &&
2539 pointee_compiler_type_info.Test(eTypeIsScalar)) {
2540 Status error;
2541 root = root->Dereference(error);
2542 if (error.Fail() || !root) {
2543 *reason_to_stop =
2544 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2545 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2546 return nullptr;
2547 } else {
2548 *what_next = ValueObject::eExpressionPathAftermathNothing;
2549 continue;
2550 }
2551 } else {
2552 *reason_to_stop =
2553 ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2554 *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
2555 return root;
2556 }
2557 }
2558 break;
2559 }
2560 default: // some non-separator is in the way
2561 {
2562 *reason_to_stop =
2563 ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2564 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2565 return nullptr;
2566 }
2567 }
2568 }
2569 }
2570
Dump(Stream & s)2571 void ValueObject::Dump(Stream &s) { Dump(s, DumpValueObjectOptions(*this)); }
2572
Dump(Stream & s,const DumpValueObjectOptions & options)2573 void ValueObject::Dump(Stream &s, const DumpValueObjectOptions &options) {
2574 ValueObjectPrinter printer(this, &s, options);
2575 printer.PrintValueObject();
2576 }
2577
CreateConstantValue(ConstString name)2578 ValueObjectSP ValueObject::CreateConstantValue(ConstString name) {
2579 ValueObjectSP valobj_sp;
2580
2581 if (UpdateValueIfNeeded(false) && m_error.Success()) {
2582 ExecutionContext exe_ctx(GetExecutionContextRef());
2583
2584 DataExtractor data;
2585 data.SetByteOrder(m_data.GetByteOrder());
2586 data.SetAddressByteSize(m_data.GetAddressByteSize());
2587
2588 if (IsBitfield()) {
2589 Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
2590 m_error = v.GetValueAsData(&exe_ctx, data, GetModule().get());
2591 } else
2592 m_error = m_value.GetValueAsData(&exe_ctx, data, GetModule().get());
2593
2594 valobj_sp = ValueObjectConstResult::Create(
2595 exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,
2596 GetAddressOf());
2597 }
2598
2599 if (!valobj_sp) {
2600 ExecutionContext exe_ctx(GetExecutionContextRef());
2601 valobj_sp = ValueObjectConstResult::Create(
2602 exe_ctx.GetBestExecutionContextScope(), m_error);
2603 }
2604 return valobj_sp;
2605 }
2606
GetQualifiedRepresentationIfAvailable(lldb::DynamicValueType dynValue,bool synthValue)2607 ValueObjectSP ValueObject::GetQualifiedRepresentationIfAvailable(
2608 lldb::DynamicValueType dynValue, bool synthValue) {
2609 ValueObjectSP result_sp(GetSP());
2610
2611 switch (dynValue) {
2612 case lldb::eDynamicCanRunTarget:
2613 case lldb::eDynamicDontRunTarget: {
2614 if (!result_sp->IsDynamic()) {
2615 if (result_sp->GetDynamicValue(dynValue))
2616 result_sp = result_sp->GetDynamicValue(dynValue);
2617 }
2618 } break;
2619 case lldb::eNoDynamicValues: {
2620 if (result_sp->IsDynamic()) {
2621 if (result_sp->GetStaticValue())
2622 result_sp = result_sp->GetStaticValue();
2623 }
2624 } break;
2625 }
2626
2627 if (synthValue) {
2628 if (!result_sp->IsSynthetic()) {
2629 if (result_sp->GetSyntheticValue())
2630 result_sp = result_sp->GetSyntheticValue();
2631 }
2632 } else {
2633 if (result_sp->IsSynthetic()) {
2634 if (result_sp->GetNonSyntheticValue())
2635 result_sp = result_sp->GetNonSyntheticValue();
2636 }
2637 }
2638
2639 return result_sp;
2640 }
2641
Dereference(Status & error)2642 ValueObjectSP ValueObject::Dereference(Status &error) {
2643 if (m_deref_valobj)
2644 return m_deref_valobj->GetSP();
2645
2646 const bool is_pointer_or_reference_type = IsPointerOrReferenceType();
2647 if (is_pointer_or_reference_type) {
2648 bool omit_empty_base_classes = true;
2649 bool ignore_array_bounds = false;
2650
2651 std::string child_name_str;
2652 uint32_t child_byte_size = 0;
2653 int32_t child_byte_offset = 0;
2654 uint32_t child_bitfield_bit_size = 0;
2655 uint32_t child_bitfield_bit_offset = 0;
2656 bool child_is_base_class = false;
2657 bool child_is_deref_of_parent = false;
2658 const bool transparent_pointers = false;
2659 CompilerType compiler_type = GetCompilerType();
2660 CompilerType child_compiler_type;
2661 uint64_t language_flags = 0;
2662
2663 ExecutionContext exe_ctx(GetExecutionContextRef());
2664
2665 child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex(
2666 &exe_ctx, 0, transparent_pointers, omit_empty_base_classes,
2667 ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
2668 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
2669 child_is_deref_of_parent, this, language_flags);
2670 if (child_compiler_type && child_byte_size) {
2671 ConstString child_name;
2672 if (!child_name_str.empty())
2673 child_name.SetCString(child_name_str.c_str());
2674
2675 m_deref_valobj = new ValueObjectChild(
2676 *this, child_compiler_type, child_name, child_byte_size,
2677 child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
2678 child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
2679 language_flags);
2680 }
2681
2682 // In case of incomplete child compiler type, use the pointee type and try
2683 // to recreate a new ValueObjectChild using it.
2684 if (!m_deref_valobj) {
2685 // FIXME(#59012): C++ stdlib formatters break with incomplete types (e.g.
2686 // `std::vector<int> &`). Remove ObjC restriction once that's resolved.
2687 if (Language::LanguageIsObjC(GetPreferredDisplayLanguage()) &&
2688 HasSyntheticValue()) {
2689 child_compiler_type = compiler_type.GetPointeeType();
2690
2691 if (child_compiler_type) {
2692 ConstString child_name;
2693 if (!child_name_str.empty())
2694 child_name.SetCString(child_name_str.c_str());
2695
2696 m_deref_valobj = new ValueObjectChild(
2697 *this, child_compiler_type, child_name, child_byte_size,
2698 child_byte_offset, child_bitfield_bit_size,
2699 child_bitfield_bit_offset, child_is_base_class,
2700 child_is_deref_of_parent, eAddressTypeInvalid, language_flags);
2701 }
2702 }
2703 }
2704
2705 } else if (HasSyntheticValue()) {
2706 m_deref_valobj =
2707 GetSyntheticValue()
2708 ->GetChildMemberWithName(ConstString("$$dereference$$"), true)
2709 .get();
2710 } else if (IsSynthetic()) {
2711 m_deref_valobj =
2712 GetChildMemberWithName(ConstString("$$dereference$$"), true).get();
2713 }
2714
2715 if (m_deref_valobj) {
2716 error.Clear();
2717 return m_deref_valobj->GetSP();
2718 } else {
2719 StreamString strm;
2720 GetExpressionPath(strm);
2721
2722 if (is_pointer_or_reference_type)
2723 error.SetErrorStringWithFormat("dereference failed: (%s) %s",
2724 GetTypeName().AsCString("<invalid type>"),
2725 strm.GetData());
2726 else
2727 error.SetErrorStringWithFormat("not a pointer or reference type: (%s) %s",
2728 GetTypeName().AsCString("<invalid type>"),
2729 strm.GetData());
2730 return ValueObjectSP();
2731 }
2732 }
2733
AddressOf(Status & error)2734 ValueObjectSP ValueObject::AddressOf(Status &error) {
2735 if (m_addr_of_valobj_sp)
2736 return m_addr_of_valobj_sp;
2737
2738 AddressType address_type = eAddressTypeInvalid;
2739 const bool scalar_is_load_address = false;
2740 addr_t addr = GetAddressOf(scalar_is_load_address, &address_type);
2741 error.Clear();
2742 if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {
2743 switch (address_type) {
2744 case eAddressTypeInvalid: {
2745 StreamString expr_path_strm;
2746 GetExpressionPath(expr_path_strm);
2747 error.SetErrorStringWithFormat("'%s' is not in memory",
2748 expr_path_strm.GetData());
2749 } break;
2750
2751 case eAddressTypeFile:
2752 case eAddressTypeLoad: {
2753 CompilerType compiler_type = GetCompilerType();
2754 if (compiler_type) {
2755 std::string name(1, '&');
2756 name.append(m_name.AsCString(""));
2757 ExecutionContext exe_ctx(GetExecutionContextRef());
2758 m_addr_of_valobj_sp = ValueObjectConstResult::Create(
2759 exe_ctx.GetBestExecutionContextScope(),
2760 compiler_type.GetPointerType(), ConstString(name.c_str()), addr,
2761 eAddressTypeInvalid, m_data.GetAddressByteSize());
2762 }
2763 } break;
2764 default:
2765 break;
2766 }
2767 } else {
2768 StreamString expr_path_strm;
2769 GetExpressionPath(expr_path_strm);
2770 error.SetErrorStringWithFormat("'%s' doesn't have a valid address",
2771 expr_path_strm.GetData());
2772 }
2773
2774 return m_addr_of_valobj_sp;
2775 }
2776
Cast(const CompilerType & compiler_type)2777 ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {
2778 return ValueObjectCast::Create(*this, GetName(), compiler_type);
2779 }
2780
Clone(ConstString new_name)2781 lldb::ValueObjectSP ValueObject::Clone(ConstString new_name) {
2782 return ValueObjectCast::Create(*this, new_name, GetCompilerType());
2783 }
2784
CastPointerType(const char * name,CompilerType & compiler_type)2785 ValueObjectSP ValueObject::CastPointerType(const char *name,
2786 CompilerType &compiler_type) {
2787 ValueObjectSP valobj_sp;
2788 AddressType address_type;
2789 addr_t ptr_value = GetPointerValue(&address_type);
2790
2791 if (ptr_value != LLDB_INVALID_ADDRESS) {
2792 Address ptr_addr(ptr_value);
2793 ExecutionContext exe_ctx(GetExecutionContextRef());
2794 valobj_sp = ValueObjectMemory::Create(
2795 exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, compiler_type);
2796 }
2797 return valobj_sp;
2798 }
2799
CastPointerType(const char * name,TypeSP & type_sp)2800 ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {
2801 ValueObjectSP valobj_sp;
2802 AddressType address_type;
2803 addr_t ptr_value = GetPointerValue(&address_type);
2804
2805 if (ptr_value != LLDB_INVALID_ADDRESS) {
2806 Address ptr_addr(ptr_value);
2807 ExecutionContext exe_ctx(GetExecutionContextRef());
2808 valobj_sp = ValueObjectMemory::Create(
2809 exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, type_sp);
2810 }
2811 return valobj_sp;
2812 }
2813
EvaluationPoint()2814 ValueObject::EvaluationPoint::EvaluationPoint() : m_mod_id(), m_exe_ctx_ref() {}
2815
EvaluationPoint(ExecutionContextScope * exe_scope,bool use_selected)2816 ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope,
2817 bool use_selected)
2818 : m_mod_id(), m_exe_ctx_ref() {
2819 ExecutionContext exe_ctx(exe_scope);
2820 TargetSP target_sp(exe_ctx.GetTargetSP());
2821 if (target_sp) {
2822 m_exe_ctx_ref.SetTargetSP(target_sp);
2823 ProcessSP process_sp(exe_ctx.GetProcessSP());
2824 if (!process_sp)
2825 process_sp = target_sp->GetProcessSP();
2826
2827 if (process_sp) {
2828 m_mod_id = process_sp->GetModID();
2829 m_exe_ctx_ref.SetProcessSP(process_sp);
2830
2831 ThreadSP thread_sp(exe_ctx.GetThreadSP());
2832
2833 if (!thread_sp) {
2834 if (use_selected)
2835 thread_sp = process_sp->GetThreadList().GetSelectedThread();
2836 }
2837
2838 if (thread_sp) {
2839 m_exe_ctx_ref.SetThreadSP(thread_sp);
2840
2841 StackFrameSP frame_sp(exe_ctx.GetFrameSP());
2842 if (!frame_sp) {
2843 if (use_selected)
2844 frame_sp = thread_sp->GetSelectedFrame();
2845 }
2846 if (frame_sp)
2847 m_exe_ctx_ref.SetFrameSP(frame_sp);
2848 }
2849 }
2850 }
2851 }
2852
EvaluationPoint(const ValueObject::EvaluationPoint & rhs)2853 ValueObject::EvaluationPoint::EvaluationPoint(
2854 const ValueObject::EvaluationPoint &rhs)
2855 : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref) {}
2856
2857 ValueObject::EvaluationPoint::~EvaluationPoint() = default;
2858
2859 // This function checks the EvaluationPoint against the current process state.
2860 // If the current state matches the evaluation point, or the evaluation point
2861 // is already invalid, then we return false, meaning "no change". If the
2862 // current state is different, we update our state, and return true meaning
2863 // "yes, change". If we did see a change, we also set m_needs_update to true,
2864 // so future calls to NeedsUpdate will return true. exe_scope will be set to
2865 // the current execution context scope.
2866
SyncWithProcessState(bool accept_invalid_exe_ctx)2867 bool ValueObject::EvaluationPoint::SyncWithProcessState(
2868 bool accept_invalid_exe_ctx) {
2869 // Start with the target, if it is NULL, then we're obviously not going to
2870 // get any further:
2871 const bool thread_and_frame_only_if_stopped = true;
2872 ExecutionContext exe_ctx(
2873 m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
2874
2875 if (exe_ctx.GetTargetPtr() == nullptr)
2876 return false;
2877
2878 // If we don't have a process nothing can change.
2879 Process *process = exe_ctx.GetProcessPtr();
2880 if (process == nullptr)
2881 return false;
2882
2883 // If our stop id is the current stop ID, nothing has changed:
2884 ProcessModID current_mod_id = process->GetModID();
2885
2886 // If the current stop id is 0, either we haven't run yet, or the process
2887 // state has been cleared. In either case, we aren't going to be able to sync
2888 // with the process state.
2889 if (current_mod_id.GetStopID() == 0)
2890 return false;
2891
2892 bool changed = false;
2893 const bool was_valid = m_mod_id.IsValid();
2894 if (was_valid) {
2895 if (m_mod_id == current_mod_id) {
2896 // Everything is already up to date in this object, no need to update the
2897 // execution context scope.
2898 changed = false;
2899 } else {
2900 m_mod_id = current_mod_id;
2901 m_needs_update = true;
2902 changed = true;
2903 }
2904 }
2905
2906 // Now re-look up the thread and frame in case the underlying objects have
2907 // gone away & been recreated. That way we'll be sure to return a valid
2908 // exe_scope. If we used to have a thread or a frame but can't find it
2909 // anymore, then mark ourselves as invalid.
2910
2911 if (!accept_invalid_exe_ctx) {
2912 if (m_exe_ctx_ref.HasThreadRef()) {
2913 ThreadSP thread_sp(m_exe_ctx_ref.GetThreadSP());
2914 if (thread_sp) {
2915 if (m_exe_ctx_ref.HasFrameRef()) {
2916 StackFrameSP frame_sp(m_exe_ctx_ref.GetFrameSP());
2917 if (!frame_sp) {
2918 // We used to have a frame, but now it is gone
2919 SetInvalid();
2920 changed = was_valid;
2921 }
2922 }
2923 } else {
2924 // We used to have a thread, but now it is gone
2925 SetInvalid();
2926 changed = was_valid;
2927 }
2928 }
2929 }
2930
2931 return changed;
2932 }
2933
SetUpdated()2934 void ValueObject::EvaluationPoint::SetUpdated() {
2935 ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
2936 if (process_sp)
2937 m_mod_id = process_sp->GetModID();
2938 m_needs_update = false;
2939 }
2940
ClearUserVisibleData(uint32_t clear_mask)2941 void ValueObject::ClearUserVisibleData(uint32_t clear_mask) {
2942 if ((clear_mask & eClearUserVisibleDataItemsValue) ==
2943 eClearUserVisibleDataItemsValue)
2944 m_value_str.clear();
2945
2946 if ((clear_mask & eClearUserVisibleDataItemsLocation) ==
2947 eClearUserVisibleDataItemsLocation)
2948 m_location_str.clear();
2949
2950 if ((clear_mask & eClearUserVisibleDataItemsSummary) ==
2951 eClearUserVisibleDataItemsSummary)
2952 m_summary_str.clear();
2953
2954 if ((clear_mask & eClearUserVisibleDataItemsDescription) ==
2955 eClearUserVisibleDataItemsDescription)
2956 m_object_desc_str.clear();
2957
2958 if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) ==
2959 eClearUserVisibleDataItemsSyntheticChildren) {
2960 if (m_synthetic_value)
2961 m_synthetic_value = nullptr;
2962 }
2963 }
2964
GetSymbolContextScope()2965 SymbolContextScope *ValueObject::GetSymbolContextScope() {
2966 if (m_parent) {
2967 if (!m_parent->IsPointerOrReferenceType())
2968 return m_parent->GetSymbolContextScope();
2969 }
2970 return nullptr;
2971 }
2972
2973 lldb::ValueObjectSP
CreateValueObjectFromExpression(llvm::StringRef name,llvm::StringRef expression,const ExecutionContext & exe_ctx)2974 ValueObject::CreateValueObjectFromExpression(llvm::StringRef name,
2975 llvm::StringRef expression,
2976 const ExecutionContext &exe_ctx) {
2977 return CreateValueObjectFromExpression(name, expression, exe_ctx,
2978 EvaluateExpressionOptions());
2979 }
2980
CreateValueObjectFromExpression(llvm::StringRef name,llvm::StringRef expression,const ExecutionContext & exe_ctx,const EvaluateExpressionOptions & options)2981 lldb::ValueObjectSP ValueObject::CreateValueObjectFromExpression(
2982 llvm::StringRef name, llvm::StringRef expression,
2983 const ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options) {
2984 lldb::ValueObjectSP retval_sp;
2985 lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
2986 if (!target_sp)
2987 return retval_sp;
2988 if (expression.empty())
2989 return retval_sp;
2990 target_sp->EvaluateExpression(expression, exe_ctx.GetFrameSP().get(),
2991 retval_sp, options);
2992 if (retval_sp && !name.empty())
2993 retval_sp->SetName(ConstString(name));
2994 return retval_sp;
2995 }
2996
CreateValueObjectFromAddress(llvm::StringRef name,uint64_t address,const ExecutionContext & exe_ctx,CompilerType type)2997 lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress(
2998 llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
2999 CompilerType type) {
3000 if (type) {
3001 CompilerType pointer_type(type.GetPointerType());
3002 if (pointer_type) {
3003 lldb::DataBufferSP buffer(
3004 new lldb_private::DataBufferHeap(&address, sizeof(lldb::addr_t)));
3005 lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(
3006 exe_ctx.GetBestExecutionContextScope(), pointer_type,
3007 ConstString(name), buffer, exe_ctx.GetByteOrder(),
3008 exe_ctx.GetAddressByteSize()));
3009 if (ptr_result_valobj_sp) {
3010 ptr_result_valobj_sp->GetValue().SetValueType(
3011 Value::ValueType::LoadAddress);
3012 Status err;
3013 ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
3014 if (ptr_result_valobj_sp && !name.empty())
3015 ptr_result_valobj_sp->SetName(ConstString(name));
3016 }
3017 return ptr_result_valobj_sp;
3018 }
3019 }
3020 return lldb::ValueObjectSP();
3021 }
3022
CreateValueObjectFromData(llvm::StringRef name,const DataExtractor & data,const ExecutionContext & exe_ctx,CompilerType type)3023 lldb::ValueObjectSP ValueObject::CreateValueObjectFromData(
3024 llvm::StringRef name, const DataExtractor &data,
3025 const ExecutionContext &exe_ctx, CompilerType type) {
3026 lldb::ValueObjectSP new_value_sp;
3027 new_value_sp = ValueObjectConstResult::Create(
3028 exe_ctx.GetBestExecutionContextScope(), type, ConstString(name), data,
3029 LLDB_INVALID_ADDRESS);
3030 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
3031 if (new_value_sp && !name.empty())
3032 new_value_sp->SetName(ConstString(name));
3033 return new_value_sp;
3034 }
3035
GetModule()3036 ModuleSP ValueObject::GetModule() {
3037 ValueObject *root(GetRoot());
3038 if (root != this)
3039 return root->GetModule();
3040 return lldb::ModuleSP();
3041 }
3042
GetRoot()3043 ValueObject *ValueObject::GetRoot() {
3044 if (m_root)
3045 return m_root;
3046 return (m_root = FollowParentChain([](ValueObject *vo) -> bool {
3047 return (vo->m_parent != nullptr);
3048 }));
3049 }
3050
3051 ValueObject *
FollowParentChain(std::function<bool (ValueObject *)> f)3052 ValueObject::FollowParentChain(std::function<bool(ValueObject *)> f) {
3053 ValueObject *vo = this;
3054 while (vo) {
3055 if (!f(vo))
3056 break;
3057 vo = vo->m_parent;
3058 }
3059 return vo;
3060 }
3061
GetAddressTypeOfChildren()3062 AddressType ValueObject::GetAddressTypeOfChildren() {
3063 if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) {
3064 ValueObject *root(GetRoot());
3065 if (root != this)
3066 return root->GetAddressTypeOfChildren();
3067 }
3068 return m_address_type_of_ptr_or_ref_children;
3069 }
3070
GetDynamicValueType()3071 lldb::DynamicValueType ValueObject::GetDynamicValueType() {
3072 ValueObject *with_dv_info = this;
3073 while (with_dv_info) {
3074 if (with_dv_info->HasDynamicValueTypeInfo())
3075 return with_dv_info->GetDynamicValueTypeImpl();
3076 with_dv_info = with_dv_info->m_parent;
3077 }
3078 return lldb::eNoDynamicValues;
3079 }
3080
GetFormat() const3081 lldb::Format ValueObject::GetFormat() const {
3082 const ValueObject *with_fmt_info = this;
3083 while (with_fmt_info) {
3084 if (with_fmt_info->m_format != lldb::eFormatDefault)
3085 return with_fmt_info->m_format;
3086 with_fmt_info = with_fmt_info->m_parent;
3087 }
3088 return m_format;
3089 }
3090
GetPreferredDisplayLanguage()3091 lldb::LanguageType ValueObject::GetPreferredDisplayLanguage() {
3092 lldb::LanguageType type = m_preferred_display_language;
3093 if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
3094 if (GetRoot()) {
3095 if (GetRoot() == this) {
3096 if (StackFrameSP frame_sp = GetFrameSP()) {
3097 const SymbolContext &sc(
3098 frame_sp->GetSymbolContext(eSymbolContextCompUnit));
3099 if (CompileUnit *cu = sc.comp_unit)
3100 type = cu->GetLanguage();
3101 }
3102 } else {
3103 type = GetRoot()->GetPreferredDisplayLanguage();
3104 }
3105 }
3106 }
3107 return (m_preferred_display_language = type); // only compute it once
3108 }
3109
SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt)3110 void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {
3111 if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
3112 SetPreferredDisplayLanguage(lt);
3113 }
3114
CanProvideValue()3115 bool ValueObject::CanProvideValue() {
3116 // we need to support invalid types as providers of values because some bare-
3117 // board debugging scenarios have no notion of types, but still manage to
3118 // have raw numeric values for things like registers. sigh.
3119 CompilerType type = GetCompilerType();
3120 return (!type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue));
3121 }
3122
3123
3124
Persist()3125 ValueObjectSP ValueObject::Persist() {
3126 if (!UpdateValueIfNeeded())
3127 return nullptr;
3128
3129 TargetSP target_sp(GetTargetSP());
3130 if (!target_sp)
3131 return nullptr;
3132
3133 PersistentExpressionState *persistent_state =
3134 target_sp->GetPersistentExpressionStateForLanguage(
3135 GetPreferredDisplayLanguage());
3136
3137 if (!persistent_state)
3138 return nullptr;
3139
3140 ConstString name = persistent_state->GetNextPersistentVariableName();
3141
3142 ValueObjectSP const_result_sp =
3143 ValueObjectConstResult::Create(target_sp.get(), GetValue(), name);
3144
3145 ExpressionVariableSP persistent_var_sp =
3146 persistent_state->CreatePersistentVariable(const_result_sp);
3147 persistent_var_sp->m_live_sp = persistent_var_sp->m_frozen_sp;
3148 persistent_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference;
3149
3150 return persistent_var_sp->GetValueObject();
3151 }
3152