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

source code of lldb/source/Core/ValueObject.cpp