Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Core/ValueObject.cpp
39587 views
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
69
namespace lldb_private {
70
class ExecutionContextScope;
71
}
72
namespace lldb_private {
73
class SymbolContextScope;
74
}
75
76
using namespace lldb;
77
using namespace lldb_private;
78
79
static user_id_t g_value_obj_uid = 0;
80
81
// ValueObject constructor
82
ValueObject::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(this);
90
}
91
92
// ValueObject constructor
93
ValueObject::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(this);
108
}
109
110
// Destructor
111
ValueObject::~ValueObject() = default;
112
113
bool 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(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(m_value_str);
147
ClearUserVisibleData(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(m_value_checksum.size());
166
std::copy(m_value_checksum.begin(), m_value_checksum.end(),
167
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(m_value_checksum, 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(&old_checksum[0], &m_value_checksum[0],
194
m_value_checksum.size()));
195
}
196
197
} else {
198
m_error.SetErrorString("out of scope");
199
}
200
}
201
return m_error.Success();
202
}
203
204
bool ValueObject::UpdateFormatsIfNeeded() {
205
Log *log = GetLog(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(*this, GetDynamicValueType()));
220
SetSummaryFormat(
221
DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
222
SetSyntheticChildren(
223
DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));
224
}
225
226
return any_change;
227
}
228
229
void 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(eClearUserVisibleDataItemsValue);
234
}
235
236
void 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
246
CompilerType 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(GetObjectRuntimeLanguage())) {
266
if (std::optional<CompilerType> complete_type =
267
runtime->GetRuntimeType(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
278
DataExtractor &ValueObject::GetDataExtractor() {
279
UpdateValueIfNeeded(false);
280
return m_data;
281
}
282
283
const Status &ValueObject::GetError() {
284
UpdateValueIfNeeded(false);
285
return m_error;
286
}
287
288
const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
289
const DataExtractor &data) {
290
if (UpdateValueIfNeeded(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("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
332
bool ValueObject::ResolveValue(Scalar &scalar) {
333
if (UpdateValueIfNeeded(
334
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, GetModule().get());
339
if (scalar.IsValid()) {
340
const uint32_t bitfield_bit_size = GetBitfieldBitSize();
341
if (bitfield_bit_size)
342
return scalar.ExtractBitfield(bitfield_bit_size,
343
GetBitfieldBitOffset());
344
return true;
345
}
346
}
347
return false;
348
}
349
350
bool ValueObject::IsLogicalTrue(Status &error) {
351
if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
352
LazyBool is_logical_true = language->IsLogicalTrue(*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_value)) {
365
error.SetErrorString("failed to get a scalar result");
366
return false;
367
}
368
369
bool ret;
370
ret = scalar_value.ULongLong(1) != 0;
371
error.Clear();
372
return ret;
373
}
374
375
ValueObjectSP ValueObject::GetChildAtIndex(uint32_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(false);
380
if (idx < GetNumChildrenIgnoringErrors()) {
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, CreateChildAtIndex(idx));
386
}
387
388
ValueObject *child = m_children.GetChildAtIndex(idx);
389
if (child != nullptr)
390
return child->GetSP();
391
}
392
return child_sp;
393
}
394
395
lldb::ValueObjectSP
396
ValueObject::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
409
size_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
415
ValueObjectSP 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(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
443
llvm::Expected<uint32_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
auto num_children_or_err = CalculateNumChildren();
456
if (num_children_or_err)
457
SetNumChildren(*num_children_or_err);
458
else
459
return num_children_or_err;
460
}
461
return m_children.GetChildrenCount();
462
}
463
464
uint32_t ValueObject::GetNumChildrenIgnoringErrors(uint32_t max) {
465
auto value_or_err = GetNumChildren(max);
466
if (value_or_err)
467
return *value_or_err;
468
LLDB_LOG_ERRORV(GetLog(LLDBLog::DataFormatters), value_or_err.takeError(),
469
"{0}");
470
return 0;
471
}
472
473
bool ValueObject::MightHaveChildren() {
474
bool has_children = false;
475
const uint32_t type_info = GetTypeInfo();
476
if (type_info) {
477
if (type_info & (eTypeHasChildren | eTypeIsPointer | eTypeIsReference))
478
has_children = true;
479
} else {
480
has_children = GetNumChildrenIgnoringErrors() > 0;
481
}
482
return has_children;
483
}
484
485
// Should only be called by ValueObject::GetNumChildren()
486
void ValueObject::SetNumChildren(uint32_t num_children) {
487
m_flags.m_children_count_valid = true;
488
m_children.SetChildrenCount(num_children);
489
}
490
491
ValueObject *ValueObject::CreateChildAtIndex(size_t idx) {
492
bool omit_empty_base_classes = true;
493
bool ignore_array_bounds = false;
494
std::string child_name;
495
uint32_t child_byte_size = 0;
496
int32_t child_byte_offset = 0;
497
uint32_t child_bitfield_bit_size = 0;
498
uint32_t child_bitfield_bit_offset = 0;
499
bool child_is_base_class = false;
500
bool child_is_deref_of_parent = false;
501
uint64_t language_flags = 0;
502
const bool transparent_pointers = true;
503
504
ExecutionContext exe_ctx(GetExecutionContextRef());
505
506
auto child_compiler_type_or_err =
507
GetCompilerType().GetChildCompilerTypeAtIndex(
508
&exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
509
ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
510
child_bitfield_bit_size, child_bitfield_bit_offset,
511
child_is_base_class, child_is_deref_of_parent, this, language_flags);
512
if (!child_compiler_type_or_err || !child_compiler_type_or_err->IsValid()) {
513
LLDB_LOG_ERROR(GetLog(LLDBLog::Types),
514
child_compiler_type_or_err.takeError(),
515
"could not find child: {0}");
516
return nullptr;
517
}
518
519
return new ValueObjectChild(
520
*this, *child_compiler_type_or_err, ConstString(child_name),
521
child_byte_size, child_byte_offset, child_bitfield_bit_size,
522
child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent,
523
eAddressTypeInvalid, language_flags);
524
}
525
526
ValueObject *ValueObject::CreateSyntheticArrayMember(size_t idx) {
527
bool omit_empty_base_classes = true;
528
bool ignore_array_bounds = true;
529
std::string child_name;
530
uint32_t child_byte_size = 0;
531
int32_t child_byte_offset = 0;
532
uint32_t child_bitfield_bit_size = 0;
533
uint32_t child_bitfield_bit_offset = 0;
534
bool child_is_base_class = false;
535
bool child_is_deref_of_parent = false;
536
uint64_t language_flags = 0;
537
const bool transparent_pointers = false;
538
539
ExecutionContext exe_ctx(GetExecutionContextRef());
540
541
auto child_compiler_type_or_err =
542
GetCompilerType().GetChildCompilerTypeAtIndex(
543
&exe_ctx, 0, transparent_pointers, omit_empty_base_classes,
544
ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
545
child_bitfield_bit_size, child_bitfield_bit_offset,
546
child_is_base_class, child_is_deref_of_parent, this, language_flags);
547
if (!child_compiler_type_or_err) {
548
LLDB_LOG_ERROR(GetLog(LLDBLog::Types),
549
child_compiler_type_or_err.takeError(),
550
"could not find child: {0}");
551
return nullptr;
552
}
553
554
if (child_compiler_type_or_err->IsValid()) {
555
child_byte_offset += child_byte_size * idx;
556
557
return new ValueObjectChild(
558
*this, *child_compiler_type_or_err, ConstString(child_name),
559
child_byte_size, child_byte_offset, child_bitfield_bit_size,
560
child_bitfield_bit_offset, child_is_base_class,
561
child_is_deref_of_parent, eAddressTypeInvalid, language_flags);
562
}
563
564
// In case of an incomplete type, try to use the ValueObject's
565
// synthetic value to create the child ValueObject.
566
if (ValueObjectSP synth_valobj_sp = GetSyntheticValue())
567
return synth_valobj_sp->GetChildAtIndex(idx, /*can_create=*/true).get();
568
569
return nullptr;
570
}
571
572
bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
573
std::string &destination,
574
lldb::LanguageType lang) {
575
return GetSummaryAsCString(summary_ptr, destination,
576
TypeSummaryOptions().SetLanguage(lang));
577
}
578
579
bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
580
std::string &destination,
581
const TypeSummaryOptions &options) {
582
destination.clear();
583
584
// If we have a forcefully completed type, don't try and show a summary from
585
// a valid summary string or function because the type is not complete and
586
// no member variables or member functions will be available.
587
if (GetCompilerType().IsForcefullyCompleted()) {
588
destination = "<incomplete type>";
589
return true;
590
}
591
592
// ideally we would like to bail out if passing NULL, but if we do so we end
593
// up not providing the summary for function pointers anymore
594
if (/*summary_ptr == NULL ||*/ m_flags.m_is_getting_summary)
595
return false;
596
597
m_flags.m_is_getting_summary = true;
598
599
TypeSummaryOptions actual_options(options);
600
601
if (actual_options.GetLanguage() == lldb::eLanguageTypeUnknown)
602
actual_options.SetLanguage(GetPreferredDisplayLanguage());
603
604
// this is a hot path in code and we prefer to avoid setting this string all
605
// too often also clearing out other information that we might care to see in
606
// a crash log. might be useful in very specific situations though.
607
/*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s.
608
Summary provider's description is %s",
609
GetTypeName().GetCString(),
610
GetName().GetCString(),
611
summary_ptr->GetDescription().c_str());*/
612
613
if (UpdateValueIfNeeded(false) && summary_ptr) {
614
if (HasSyntheticValue())
615
m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on
616
// the synthetic children being
617
// up-to-date (e.g. ${svar%#})
618
summary_ptr->FormatObject(this, destination, actual_options);
619
}
620
m_flags.m_is_getting_summary = false;
621
return !destination.empty();
622
}
623
624
const char *ValueObject::GetSummaryAsCString(lldb::LanguageType lang) {
625
if (UpdateValueIfNeeded(true) && m_summary_str.empty()) {
626
TypeSummaryOptions summary_options;
627
summary_options.SetLanguage(lang);
628
GetSummaryAsCString(GetSummaryFormat().get(), m_summary_str,
629
summary_options);
630
}
631
if (m_summary_str.empty())
632
return nullptr;
633
return m_summary_str.c_str();
634
}
635
636
bool ValueObject::GetSummaryAsCString(std::string &destination,
637
const TypeSummaryOptions &options) {
638
return GetSummaryAsCString(GetSummaryFormat().get(), destination, options);
639
}
640
641
bool ValueObject::IsCStringContainer(bool check_pointer) {
642
CompilerType pointee_or_element_compiler_type;
643
const Flags type_flags(GetTypeInfo(&pointee_or_element_compiler_type));
644
bool is_char_arr_ptr(type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
645
pointee_or_element_compiler_type.IsCharType());
646
if (!is_char_arr_ptr)
647
return false;
648
if (!check_pointer)
649
return true;
650
if (type_flags.Test(eTypeIsArray))
651
return true;
652
addr_t cstr_address = LLDB_INVALID_ADDRESS;
653
AddressType cstr_address_type = eAddressTypeInvalid;
654
cstr_address = GetPointerValue(&cstr_address_type);
655
return (cstr_address != LLDB_INVALID_ADDRESS);
656
}
657
658
size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
659
uint32_t item_count) {
660
CompilerType pointee_or_element_compiler_type;
661
const uint32_t type_info = GetTypeInfo(&pointee_or_element_compiler_type);
662
const bool is_pointer_type = type_info & eTypeIsPointer;
663
const bool is_array_type = type_info & eTypeIsArray;
664
if (!(is_pointer_type || is_array_type))
665
return 0;
666
667
if (item_count == 0)
668
return 0;
669
670
ExecutionContext exe_ctx(GetExecutionContextRef());
671
672
std::optional<uint64_t> item_type_size =
673
pointee_or_element_compiler_type.GetByteSize(
674
exe_ctx.GetBestExecutionContextScope());
675
if (!item_type_size)
676
return 0;
677
const uint64_t bytes = item_count * *item_type_size;
678
const uint64_t offset = item_idx * *item_type_size;
679
680
if (item_idx == 0 && item_count == 1) // simply a deref
681
{
682
if (is_pointer_type) {
683
Status error;
684
ValueObjectSP pointee_sp = Dereference(error);
685
if (error.Fail() || pointee_sp.get() == nullptr)
686
return 0;
687
return pointee_sp->GetData(data, error);
688
} else {
689
ValueObjectSP child_sp = GetChildAtIndex(0);
690
if (child_sp.get() == nullptr)
691
return 0;
692
Status error;
693
return child_sp->GetData(data, error);
694
}
695
return true;
696
} else /* (items > 1) */
697
{
698
Status error;
699
lldb_private::DataBufferHeap *heap_buf_ptr = nullptr;
700
lldb::DataBufferSP data_sp(heap_buf_ptr =
701
new lldb_private::DataBufferHeap());
702
703
AddressType addr_type;
704
lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type)
705
: GetAddressOf(true, &addr_type);
706
707
switch (addr_type) {
708
case eAddressTypeFile: {
709
ModuleSP module_sp(GetModule());
710
if (module_sp) {
711
addr = addr + offset;
712
Address so_addr;
713
module_sp->ResolveFileAddress(addr, so_addr);
714
ExecutionContext exe_ctx(GetExecutionContextRef());
715
Target *target = exe_ctx.GetTargetPtr();
716
if (target) {
717
heap_buf_ptr->SetByteSize(bytes);
718
size_t bytes_read = target->ReadMemory(
719
so_addr, heap_buf_ptr->GetBytes(), bytes, error, true);
720
if (error.Success()) {
721
data.SetData(data_sp);
722
return bytes_read;
723
}
724
}
725
}
726
} break;
727
case eAddressTypeLoad: {
728
ExecutionContext exe_ctx(GetExecutionContextRef());
729
Process *process = exe_ctx.GetProcessPtr();
730
if (process) {
731
heap_buf_ptr->SetByteSize(bytes);
732
size_t bytes_read = process->ReadMemory(
733
addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
734
if (error.Success() || bytes_read > 0) {
735
data.SetData(data_sp);
736
return bytes_read;
737
}
738
}
739
} break;
740
case eAddressTypeHost: {
741
auto max_bytes =
742
GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());
743
if (max_bytes && *max_bytes > offset) {
744
size_t bytes_read = std::min<uint64_t>(*max_bytes - offset, bytes);
745
addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
746
if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
747
break;
748
heap_buf_ptr->CopyData((uint8_t *)(addr + offset), bytes_read);
749
data.SetData(data_sp);
750
return bytes_read;
751
}
752
} break;
753
case eAddressTypeInvalid:
754
break;
755
}
756
}
757
return 0;
758
}
759
760
uint64_t ValueObject::GetData(DataExtractor &data, Status &error) {
761
UpdateValueIfNeeded(false);
762
ExecutionContext exe_ctx(GetExecutionContextRef());
763
error = m_value.GetValueAsData(&exe_ctx, data, GetModule().get());
764
if (error.Fail()) {
765
if (m_data.GetByteSize()) {
766
data = m_data;
767
error.Clear();
768
return data.GetByteSize();
769
} else {
770
return 0;
771
}
772
}
773
data.SetAddressByteSize(m_data.GetAddressByteSize());
774
data.SetByteOrder(m_data.GetByteOrder());
775
return data.GetByteSize();
776
}
777
778
bool ValueObject::SetData(DataExtractor &data, Status &error) {
779
error.Clear();
780
// Make sure our value is up to date first so that our location and location
781
// type is valid.
782
if (!UpdateValueIfNeeded(false)) {
783
error.SetErrorString("unable to read value");
784
return false;
785
}
786
787
uint64_t count = 0;
788
const Encoding encoding = GetCompilerType().GetEncoding(count);
789
790
const size_t byte_size = GetByteSize().value_or(0);
791
792
Value::ValueType value_type = m_value.GetValueType();
793
794
switch (value_type) {
795
case Value::ValueType::Invalid:
796
error.SetErrorString("invalid location");
797
return false;
798
case Value::ValueType::Scalar: {
799
Status set_error =
800
m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
801
802
if (!set_error.Success()) {
803
error.SetErrorStringWithFormat("unable to set scalar value: %s",
804
set_error.AsCString());
805
return false;
806
}
807
} break;
808
case Value::ValueType::LoadAddress: {
809
// If it is a load address, then the scalar value is the storage location
810
// of the data, and we have to shove this value down to that load location.
811
ExecutionContext exe_ctx(GetExecutionContextRef());
812
Process *process = exe_ctx.GetProcessPtr();
813
if (process) {
814
addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
815
size_t bytes_written = process->WriteMemory(
816
target_addr, data.GetDataStart(), byte_size, error);
817
if (!error.Success())
818
return false;
819
if (bytes_written != byte_size) {
820
error.SetErrorString("unable to write value to memory");
821
return false;
822
}
823
}
824
} break;
825
case Value::ValueType::HostAddress: {
826
// If it is a host address, then we stuff the scalar as a DataBuffer into
827
// the Value's data.
828
DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
829
m_data.SetData(buffer_sp, 0);
830
data.CopyByteOrderedData(0, byte_size,
831
const_cast<uint8_t *>(m_data.GetDataStart()),
832
byte_size, m_data.GetByteOrder());
833
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
834
} break;
835
case Value::ValueType::FileAddress:
836
break;
837
}
838
839
// If we have reached this point, then we have successfully changed the
840
// value.
841
SetNeedsUpdate();
842
return true;
843
}
844
845
static bool CopyStringDataToBufferSP(const StreamString &source,
846
lldb::WritableDataBufferSP &destination) {
847
llvm::StringRef src = source.GetString();
848
src = src.rtrim('\0');
849
destination = std::make_shared<DataBufferHeap>(src.size(), 0);
850
memcpy(destination->GetBytes(), src.data(), src.size());
851
return true;
852
}
853
854
std::pair<size_t, bool>
855
ValueObject::ReadPointedString(lldb::WritableDataBufferSP &buffer_sp,
856
Status &error, bool honor_array) {
857
bool was_capped = false;
858
StreamString s;
859
ExecutionContext exe_ctx(GetExecutionContextRef());
860
Target *target = exe_ctx.GetTargetPtr();
861
862
if (!target) {
863
s << "<no target to read from>";
864
error.SetErrorString("no target to read from");
865
CopyStringDataToBufferSP(s, buffer_sp);
866
return {0, was_capped};
867
}
868
869
const auto max_length = target->GetMaximumSizeOfStringSummary();
870
871
size_t bytes_read = 0;
872
size_t total_bytes_read = 0;
873
874
CompilerType compiler_type = GetCompilerType();
875
CompilerType elem_or_pointee_compiler_type;
876
const Flags type_flags(GetTypeInfo(&elem_or_pointee_compiler_type));
877
if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
878
elem_or_pointee_compiler_type.IsCharType()) {
879
addr_t cstr_address = LLDB_INVALID_ADDRESS;
880
AddressType cstr_address_type = eAddressTypeInvalid;
881
882
size_t cstr_len = 0;
883
bool capped_data = false;
884
const bool is_array = type_flags.Test(eTypeIsArray);
885
if (is_array) {
886
// We have an array
887
uint64_t array_size = 0;
888
if (compiler_type.IsArrayType(nullptr, &array_size)) {
889
cstr_len = array_size;
890
if (cstr_len > max_length) {
891
capped_data = true;
892
cstr_len = max_length;
893
}
894
}
895
cstr_address = GetAddressOf(true, &cstr_address_type);
896
} else {
897
// We have a pointer
898
cstr_address = GetPointerValue(&cstr_address_type);
899
}
900
901
if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) {
902
if (cstr_address_type == eAddressTypeHost && is_array) {
903
const char *cstr = GetDataExtractor().PeekCStr(0);
904
if (cstr == nullptr) {
905
s << "<invalid address>";
906
error.SetErrorString("invalid address");
907
CopyStringDataToBufferSP(s, buffer_sp);
908
return {0, was_capped};
909
}
910
s << llvm::StringRef(cstr, cstr_len);
911
CopyStringDataToBufferSP(s, buffer_sp);
912
return {cstr_len, was_capped};
913
} else {
914
s << "<invalid address>";
915
error.SetErrorString("invalid address");
916
CopyStringDataToBufferSP(s, buffer_sp);
917
return {0, was_capped};
918
}
919
}
920
921
Address cstr_so_addr(cstr_address);
922
DataExtractor data;
923
if (cstr_len > 0 && honor_array) {
924
// I am using GetPointeeData() here to abstract the fact that some
925
// ValueObjects are actually frozen pointers in the host but the pointed-
926
// to data lives in the debuggee, and GetPointeeData() automatically
927
// takes care of this
928
GetPointeeData(data, 0, cstr_len);
929
930
if ((bytes_read = data.GetByteSize()) > 0) {
931
total_bytes_read = bytes_read;
932
for (size_t offset = 0; offset < bytes_read; offset++)
933
s.Printf("%c", *data.PeekData(offset, 1));
934
if (capped_data)
935
was_capped = true;
936
}
937
} else {
938
cstr_len = max_length;
939
const size_t k_max_buf_size = 64;
940
941
size_t offset = 0;
942
943
int cstr_len_displayed = -1;
944
bool capped_cstr = false;
945
// I am using GetPointeeData() here to abstract the fact that some
946
// ValueObjects are actually frozen pointers in the host but the pointed-
947
// to data lives in the debuggee, and GetPointeeData() automatically
948
// takes care of this
949
while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {
950
total_bytes_read += bytes_read;
951
const char *cstr = data.PeekCStr(0);
952
size_t len = strnlen(cstr, k_max_buf_size);
953
if (cstr_len_displayed < 0)
954
cstr_len_displayed = len;
955
956
if (len == 0)
957
break;
958
cstr_len_displayed += len;
959
if (len > bytes_read)
960
len = bytes_read;
961
if (len > cstr_len)
962
len = cstr_len;
963
964
for (size_t offset = 0; offset < bytes_read; offset++)
965
s.Printf("%c", *data.PeekData(offset, 1));
966
967
if (len < k_max_buf_size)
968
break;
969
970
if (len >= cstr_len) {
971
capped_cstr = true;
972
break;
973
}
974
975
cstr_len -= len;
976
offset += len;
977
}
978
979
if (cstr_len_displayed >= 0) {
980
if (capped_cstr)
981
was_capped = true;
982
}
983
}
984
} else {
985
error.SetErrorString("not a string object");
986
s << "<not a string object>";
987
}
988
CopyStringDataToBufferSP(s, buffer_sp);
989
return {total_bytes_read, was_capped};
990
}
991
992
llvm::Expected<std::string> ValueObject::GetObjectDescription() {
993
if (!UpdateValueIfNeeded(true))
994
return llvm::createStringError("could not update value");
995
996
// Return cached value.
997
if (!m_object_desc_str.empty())
998
return m_object_desc_str;
999
1000
ExecutionContext exe_ctx(GetExecutionContextRef());
1001
Process *process = exe_ctx.GetProcessPtr();
1002
if (!process)
1003
return llvm::createStringError("no process");
1004
1005
// Returns the object description produced by one language runtime.
1006
auto get_object_description =
1007
[&](LanguageType language) -> llvm::Expected<std::string> {
1008
if (LanguageRuntime *runtime = process->GetLanguageRuntime(language)) {
1009
StreamString s;
1010
if (llvm::Error error = runtime->GetObjectDescription(s, *this))
1011
return error;
1012
m_object_desc_str = s.GetString();
1013
return m_object_desc_str;
1014
}
1015
return llvm::createStringError("no native language runtime");
1016
};
1017
1018
// Try the native language runtime first.
1019
LanguageType native_language = GetObjectRuntimeLanguage();
1020
llvm::Expected<std::string> desc = get_object_description(native_language);
1021
if (desc)
1022
return desc;
1023
1024
// Try the Objective-C language runtime. This fallback is necessary
1025
// for Objective-C++ and mixed Objective-C / C++ programs.
1026
if (Language::LanguageIsCFamily(native_language)) {
1027
// We're going to try again, so let's drop the first error.
1028
llvm::consumeError(desc.takeError());
1029
return get_object_description(eLanguageTypeObjC);
1030
}
1031
return desc;
1032
}
1033
1034
bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,
1035
std::string &destination) {
1036
if (UpdateValueIfNeeded(false))
1037
return format.FormatObject(this, destination);
1038
else
1039
return false;
1040
}
1041
1042
bool ValueObject::GetValueAsCString(lldb::Format format,
1043
std::string &destination) {
1044
return GetValueAsCString(TypeFormatImpl_Format(format), destination);
1045
}
1046
1047
const char *ValueObject::GetValueAsCString() {
1048
if (UpdateValueIfNeeded(true)) {
1049
lldb::TypeFormatImplSP format_sp;
1050
lldb::Format my_format = GetFormat();
1051
if (my_format == lldb::eFormatDefault) {
1052
if (m_type_format_sp)
1053
format_sp = m_type_format_sp;
1054
else {
1055
if (m_flags.m_is_bitfield_for_scalar)
1056
my_format = eFormatUnsigned;
1057
else {
1058
if (m_value.GetContextType() == Value::ContextType::RegisterInfo) {
1059
const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1060
if (reg_info)
1061
my_format = reg_info->format;
1062
} else {
1063
my_format = GetValue().GetCompilerType().GetFormat();
1064
}
1065
}
1066
}
1067
}
1068
if (my_format != m_last_format || m_value_str.empty()) {
1069
m_last_format = my_format;
1070
if (!format_sp)
1071
format_sp = std::make_shared<TypeFormatImpl_Format>(my_format);
1072
if (GetValueAsCString(*format_sp.get(), m_value_str)) {
1073
if (!m_flags.m_value_did_change && m_flags.m_old_value_valid) {
1074
// The value was gotten successfully, so we consider the value as
1075
// changed if the value string differs
1076
SetValueDidChange(m_old_value_str != m_value_str);
1077
}
1078
}
1079
}
1080
}
1081
if (m_value_str.empty())
1082
return nullptr;
1083
return m_value_str.c_str();
1084
}
1085
1086
// if > 8bytes, 0 is returned. this method should mostly be used to read
1087
// address values out of pointers
1088
uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
1089
// If our byte size is zero this is an aggregate type that has children
1090
if (CanProvideValue()) {
1091
Scalar scalar;
1092
if (ResolveValue(scalar)) {
1093
if (success)
1094
*success = true;
1095
scalar.MakeUnsigned();
1096
return scalar.ULongLong(fail_value);
1097
}
1098
// fallthrough, otherwise...
1099
}
1100
1101
if (success)
1102
*success = false;
1103
return fail_value;
1104
}
1105
1106
int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
1107
// If our byte size is zero this is an aggregate type that has children
1108
if (CanProvideValue()) {
1109
Scalar scalar;
1110
if (ResolveValue(scalar)) {
1111
if (success)
1112
*success = true;
1113
scalar.MakeSigned();
1114
return scalar.SLongLong(fail_value);
1115
}
1116
// fallthrough, otherwise...
1117
}
1118
1119
if (success)
1120
*success = false;
1121
return fail_value;
1122
}
1123
1124
llvm::Expected<llvm::APSInt> ValueObject::GetValueAsAPSInt() {
1125
// Make sure the type can be converted to an APSInt.
1126
if (!GetCompilerType().IsInteger() &&
1127
!GetCompilerType().IsScopedEnumerationType() &&
1128
!GetCompilerType().IsEnumerationType() &&
1129
!GetCompilerType().IsPointerType() &&
1130
!GetCompilerType().IsNullPtrType() &&
1131
!GetCompilerType().IsReferenceType() && !GetCompilerType().IsBoolean())
1132
return llvm::make_error<llvm::StringError>(
1133
"type cannot be converted to APSInt", llvm::inconvertibleErrorCode());
1134
1135
if (CanProvideValue()) {
1136
Scalar scalar;
1137
if (ResolveValue(scalar))
1138
return scalar.GetAPSInt();
1139
}
1140
1141
return llvm::make_error<llvm::StringError>(
1142
"error occurred; unable to convert to APSInt",
1143
llvm::inconvertibleErrorCode());
1144
}
1145
1146
llvm::Expected<llvm::APFloat> ValueObject::GetValueAsAPFloat() {
1147
if (!GetCompilerType().IsFloat())
1148
return llvm::make_error<llvm::StringError>(
1149
"type cannot be converted to APFloat", llvm::inconvertibleErrorCode());
1150
1151
if (CanProvideValue()) {
1152
Scalar scalar;
1153
if (ResolveValue(scalar))
1154
return scalar.GetAPFloat();
1155
}
1156
1157
return llvm::make_error<llvm::StringError>(
1158
"error occurred; unable to convert to APFloat",
1159
llvm::inconvertibleErrorCode());
1160
}
1161
1162
llvm::Expected<bool> ValueObject::GetValueAsBool() {
1163
CompilerType val_type = GetCompilerType();
1164
if (val_type.IsInteger() || val_type.IsUnscopedEnumerationType() ||
1165
val_type.IsPointerType()) {
1166
auto value_or_err = GetValueAsAPSInt();
1167
if (value_or_err)
1168
return value_or_err->getBoolValue();
1169
}
1170
if (val_type.IsFloat()) {
1171
auto value_or_err = GetValueAsAPFloat();
1172
if (value_or_err)
1173
return value_or_err->isNonZero();
1174
}
1175
if (val_type.IsArrayType())
1176
return GetAddressOf() != 0;
1177
1178
return llvm::make_error<llvm::StringError>("type cannot be converted to bool",
1179
llvm::inconvertibleErrorCode());
1180
}
1181
1182
void ValueObject::SetValueFromInteger(const llvm::APInt &value, Status &error) {
1183
// Verify the current object is an integer object
1184
CompilerType val_type = GetCompilerType();
1185
if (!val_type.IsInteger() && !val_type.IsUnscopedEnumerationType() &&
1186
!val_type.IsFloat() && !val_type.IsPointerType() &&
1187
!val_type.IsScalarType()) {
1188
error.SetErrorString("current value object is not an integer objet");
1189
return;
1190
}
1191
1192
// Verify the current object is not actually associated with any program
1193
// variable.
1194
if (GetVariable()) {
1195
error.SetErrorString("current value object is not a temporary object");
1196
return;
1197
}
1198
1199
// Verify the proposed new value is the right size.
1200
lldb::TargetSP target = GetTargetSP();
1201
uint64_t byte_size = 0;
1202
if (auto temp = GetCompilerType().GetByteSize(target.get()))
1203
byte_size = temp.value();
1204
if (value.getBitWidth() != byte_size * CHAR_BIT) {
1205
error.SetErrorString(
1206
"illegal argument: new value should be of the same size");
1207
return;
1208
}
1209
1210
lldb::DataExtractorSP data_sp;
1211
data_sp->SetData(value.getRawData(), byte_size,
1212
target->GetArchitecture().GetByteOrder());
1213
data_sp->SetAddressByteSize(
1214
static_cast<uint8_t>(target->GetArchitecture().GetAddressByteSize()));
1215
SetData(*data_sp, error);
1216
}
1217
1218
void ValueObject::SetValueFromInteger(lldb::ValueObjectSP new_val_sp,
1219
Status &error) {
1220
// Verify the current object is an integer object
1221
CompilerType val_type = GetCompilerType();
1222
if (!val_type.IsInteger() && !val_type.IsUnscopedEnumerationType() &&
1223
!val_type.IsFloat() && !val_type.IsPointerType() &&
1224
!val_type.IsScalarType()) {
1225
error.SetErrorString("current value object is not an integer objet");
1226
return;
1227
}
1228
1229
// Verify the current object is not actually associated with any program
1230
// variable.
1231
if (GetVariable()) {
1232
error.SetErrorString("current value object is not a temporary object");
1233
return;
1234
}
1235
1236
// Verify the proposed new value is the right type.
1237
CompilerType new_val_type = new_val_sp->GetCompilerType();
1238
if (!new_val_type.IsInteger() && !new_val_type.IsFloat() &&
1239
!new_val_type.IsPointerType()) {
1240
error.SetErrorString(
1241
"illegal argument: new value should be of the same size");
1242
return;
1243
}
1244
1245
if (new_val_type.IsInteger()) {
1246
auto value_or_err = new_val_sp->GetValueAsAPSInt();
1247
if (value_or_err)
1248
SetValueFromInteger(*value_or_err, error);
1249
else
1250
error.SetErrorString("error getting APSInt from new_val_sp");
1251
} else if (new_val_type.IsFloat()) {
1252
auto value_or_err = new_val_sp->GetValueAsAPFloat();
1253
if (value_or_err)
1254
SetValueFromInteger(value_or_err->bitcastToAPInt(), error);
1255
else
1256
error.SetErrorString("error getting APFloat from new_val_sp");
1257
} else if (new_val_type.IsPointerType()) {
1258
bool success = true;
1259
uint64_t int_val = new_val_sp->GetValueAsUnsigned(0, &success);
1260
if (success) {
1261
lldb::TargetSP target = GetTargetSP();
1262
uint64_t num_bits = 0;
1263
if (auto temp = new_val_sp->GetCompilerType().GetBitSize(target.get()))
1264
num_bits = temp.value();
1265
SetValueFromInteger(llvm::APInt(num_bits, int_val), error);
1266
} else
1267
error.SetErrorString("error converting new_val_sp to integer");
1268
}
1269
}
1270
1271
// if any more "special cases" are added to
1272
// ValueObject::DumpPrintableRepresentation() please keep this call up to date
1273
// by returning true for your new special cases. We will eventually move to
1274
// checking this call result before trying to display special cases
1275
bool ValueObject::HasSpecialPrintableRepresentation(
1276
ValueObjectRepresentationStyle val_obj_display, Format custom_format) {
1277
Flags flags(GetTypeInfo());
1278
if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1279
val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1280
if (IsCStringContainer(true) &&
1281
(custom_format == eFormatCString || custom_format == eFormatCharArray ||
1282
custom_format == eFormatChar || custom_format == eFormatVectorOfChar))
1283
return true;
1284
1285
if (flags.Test(eTypeIsArray)) {
1286
if ((custom_format == eFormatBytes) ||
1287
(custom_format == eFormatBytesWithASCII))
1288
return true;
1289
1290
if ((custom_format == eFormatVectorOfChar) ||
1291
(custom_format == eFormatVectorOfFloat32) ||
1292
(custom_format == eFormatVectorOfFloat64) ||
1293
(custom_format == eFormatVectorOfSInt16) ||
1294
(custom_format == eFormatVectorOfSInt32) ||
1295
(custom_format == eFormatVectorOfSInt64) ||
1296
(custom_format == eFormatVectorOfSInt8) ||
1297
(custom_format == eFormatVectorOfUInt128) ||
1298
(custom_format == eFormatVectorOfUInt16) ||
1299
(custom_format == eFormatVectorOfUInt32) ||
1300
(custom_format == eFormatVectorOfUInt64) ||
1301
(custom_format == eFormatVectorOfUInt8))
1302
return true;
1303
}
1304
}
1305
return false;
1306
}
1307
1308
bool ValueObject::DumpPrintableRepresentation(
1309
Stream &s, ValueObjectRepresentationStyle val_obj_display,
1310
Format custom_format, PrintableRepresentationSpecialCases special,
1311
bool do_dump_error) {
1312
1313
// If the ValueObject has an error, we might end up dumping the type, which
1314
// is useful, but if we don't even have a type, then don't examine the object
1315
// further as that's not meaningful, only the error is.
1316
if (m_error.Fail() && !GetCompilerType().IsValid()) {
1317
if (do_dump_error)
1318
s.Printf("<%s>", m_error.AsCString());
1319
return false;
1320
}
1321
1322
Flags flags(GetTypeInfo());
1323
1324
bool allow_special =
1325
(special == ValueObject::PrintableRepresentationSpecialCases::eAllow);
1326
const bool only_special = false;
1327
1328
if (allow_special) {
1329
if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1330
val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1331
// when being asked to get a printable display an array or pointer type
1332
// directly, try to "do the right thing"
1333
1334
if (IsCStringContainer(true) &&
1335
(custom_format == eFormatCString ||
1336
custom_format == eFormatCharArray || custom_format == eFormatChar ||
1337
custom_format ==
1338
eFormatVectorOfChar)) // print char[] & char* directly
1339
{
1340
Status error;
1341
lldb::WritableDataBufferSP buffer_sp;
1342
std::pair<size_t, bool> read_string =
1343
ReadPointedString(buffer_sp, error,
1344
(custom_format == eFormatVectorOfChar) ||
1345
(custom_format == eFormatCharArray));
1346
lldb_private::formatters::StringPrinter::
1347
ReadBufferAndDumpToStreamOptions options(*this);
1348
options.SetData(DataExtractor(
1349
buffer_sp, lldb::eByteOrderInvalid,
1350
8)); // none of this matters for a string - pass some defaults
1351
options.SetStream(&s);
1352
options.SetPrefixToken(nullptr);
1353
options.SetQuote('"');
1354
options.SetSourceSize(buffer_sp->GetByteSize());
1355
options.SetIsTruncated(read_string.second);
1356
options.SetBinaryZeroIsTerminator(custom_format != eFormatVectorOfChar);
1357
formatters::StringPrinter::ReadBufferAndDumpToStream<
1358
lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
1359
options);
1360
return !error.Fail();
1361
}
1362
1363
if (custom_format == eFormatEnum)
1364
return false;
1365
1366
// this only works for arrays, because I have no way to know when the
1367
// pointed memory ends, and no special \0 end of data marker
1368
if (flags.Test(eTypeIsArray)) {
1369
if ((custom_format == eFormatBytes) ||
1370
(custom_format == eFormatBytesWithASCII)) {
1371
const size_t count = GetNumChildrenIgnoringErrors();
1372
1373
s << '[';
1374
for (size_t low = 0; low < count; low++) {
1375
1376
if (low)
1377
s << ',';
1378
1379
ValueObjectSP child = GetChildAtIndex(low);
1380
if (!child.get()) {
1381
s << "<invalid child>";
1382
continue;
1383
}
1384
child->DumpPrintableRepresentation(
1385
s, ValueObject::eValueObjectRepresentationStyleValue,
1386
custom_format);
1387
}
1388
1389
s << ']';
1390
1391
return true;
1392
}
1393
1394
if ((custom_format == eFormatVectorOfChar) ||
1395
(custom_format == eFormatVectorOfFloat32) ||
1396
(custom_format == eFormatVectorOfFloat64) ||
1397
(custom_format == eFormatVectorOfSInt16) ||
1398
(custom_format == eFormatVectorOfSInt32) ||
1399
(custom_format == eFormatVectorOfSInt64) ||
1400
(custom_format == eFormatVectorOfSInt8) ||
1401
(custom_format == eFormatVectorOfUInt128) ||
1402
(custom_format == eFormatVectorOfUInt16) ||
1403
(custom_format == eFormatVectorOfUInt32) ||
1404
(custom_format == eFormatVectorOfUInt64) ||
1405
(custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes
1406
// with ASCII or any vector
1407
// format should be printed
1408
// directly
1409
{
1410
const size_t count = GetNumChildrenIgnoringErrors();
1411
1412
Format format = FormatManager::GetSingleItemFormat(custom_format);
1413
1414
s << '[';
1415
for (size_t low = 0; low < count; low++) {
1416
1417
if (low)
1418
s << ',';
1419
1420
ValueObjectSP child = GetChildAtIndex(low);
1421
if (!child.get()) {
1422
s << "<invalid child>";
1423
continue;
1424
}
1425
child->DumpPrintableRepresentation(
1426
s, ValueObject::eValueObjectRepresentationStyleValue, format);
1427
}
1428
1429
s << ']';
1430
1431
return true;
1432
}
1433
}
1434
1435
if ((custom_format == eFormatBoolean) ||
1436
(custom_format == eFormatBinary) || (custom_format == eFormatChar) ||
1437
(custom_format == eFormatCharPrintable) ||
1438
(custom_format == eFormatComplexFloat) ||
1439
(custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||
1440
(custom_format == eFormatHexUppercase) ||
1441
(custom_format == eFormatFloat) || (custom_format == eFormatOctal) ||
1442
(custom_format == eFormatOSType) ||
1443
(custom_format == eFormatUnicode16) ||
1444
(custom_format == eFormatUnicode32) ||
1445
(custom_format == eFormatUnsigned) ||
1446
(custom_format == eFormatPointer) ||
1447
(custom_format == eFormatComplexInteger) ||
1448
(custom_format == eFormatComplex) ||
1449
(custom_format == eFormatDefault)) // use the [] operator
1450
return false;
1451
}
1452
}
1453
1454
if (only_special)
1455
return false;
1456
1457
bool var_success = false;
1458
1459
{
1460
llvm::StringRef str;
1461
1462
// this is a local stream that we are using to ensure that the data pointed
1463
// to by cstr survives long enough for us to copy it to its destination -
1464
// it is necessary to have this temporary storage area for cases where our
1465
// desired output is not backed by some other longer-term storage
1466
StreamString strm;
1467
1468
if (custom_format != eFormatInvalid)
1469
SetFormat(custom_format);
1470
1471
switch (val_obj_display) {
1472
case eValueObjectRepresentationStyleValue:
1473
str = GetValueAsCString();
1474
break;
1475
1476
case eValueObjectRepresentationStyleSummary:
1477
str = GetSummaryAsCString();
1478
break;
1479
1480
case eValueObjectRepresentationStyleLanguageSpecific: {
1481
llvm::Expected<std::string> desc = GetObjectDescription();
1482
if (!desc) {
1483
strm << "error: " << toString(desc.takeError());
1484
str = strm.GetString();
1485
} else {
1486
strm << *desc;
1487
str = strm.GetString();
1488
}
1489
} break;
1490
1491
case eValueObjectRepresentationStyleLocation:
1492
str = GetLocationAsCString();
1493
break;
1494
1495
case eValueObjectRepresentationStyleChildrenCount:
1496
strm.Printf("%" PRIu64 "", (uint64_t)GetNumChildrenIgnoringErrors());
1497
str = strm.GetString();
1498
break;
1499
1500
case eValueObjectRepresentationStyleType:
1501
str = GetTypeName().GetStringRef();
1502
break;
1503
1504
case eValueObjectRepresentationStyleName:
1505
str = GetName().GetStringRef();
1506
break;
1507
1508
case eValueObjectRepresentationStyleExpressionPath:
1509
GetExpressionPath(strm);
1510
str = strm.GetString();
1511
break;
1512
}
1513
1514
// If the requested display style produced no output, try falling back to
1515
// alternative presentations.
1516
if (str.empty()) {
1517
if (val_obj_display == eValueObjectRepresentationStyleValue)
1518
str = GetSummaryAsCString();
1519
else if (val_obj_display == eValueObjectRepresentationStyleSummary) {
1520
if (!CanProvideValue()) {
1521
strm.Printf("%s @ %s", GetTypeName().AsCString(),
1522
GetLocationAsCString());
1523
str = strm.GetString();
1524
} else
1525
str = GetValueAsCString();
1526
}
1527
}
1528
1529
if (!str.empty())
1530
s << str;
1531
else {
1532
// We checked for errors at the start, but do it again here in case
1533
// realizing the value for dumping produced an error.
1534
if (m_error.Fail()) {
1535
if (do_dump_error)
1536
s.Printf("<%s>", m_error.AsCString());
1537
else
1538
return false;
1539
} else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1540
s.PutCString("<no summary available>");
1541
else if (val_obj_display == eValueObjectRepresentationStyleValue)
1542
s.PutCString("<no value available>");
1543
else if (val_obj_display ==
1544
eValueObjectRepresentationStyleLanguageSpecific)
1545
s.PutCString("<not a valid Objective-C object>"); // edit this if we
1546
// have other runtimes
1547
// that support a
1548
// description
1549
else
1550
s.PutCString("<no printable representation>");
1551
}
1552
1553
// we should only return false here if we could not do *anything* even if
1554
// we have an error message as output, that's a success from our callers'
1555
// perspective, so return true
1556
var_success = true;
1557
1558
if (custom_format != eFormatInvalid)
1559
SetFormat(eFormatDefault);
1560
}
1561
1562
return var_success;
1563
}
1564
1565
addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
1566
AddressType *address_type) {
1567
// Can't take address of a bitfield
1568
if (IsBitfield())
1569
return LLDB_INVALID_ADDRESS;
1570
1571
if (!UpdateValueIfNeeded(false))
1572
return LLDB_INVALID_ADDRESS;
1573
1574
switch (m_value.GetValueType()) {
1575
case Value::ValueType::Invalid:
1576
return LLDB_INVALID_ADDRESS;
1577
case Value::ValueType::Scalar:
1578
if (scalar_is_load_address) {
1579
if (address_type)
1580
*address_type = eAddressTypeLoad;
1581
return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1582
}
1583
break;
1584
1585
case Value::ValueType::LoadAddress:
1586
case Value::ValueType::FileAddress: {
1587
if (address_type)
1588
*address_type = m_value.GetValueAddressType();
1589
return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1590
} break;
1591
case Value::ValueType::HostAddress: {
1592
if (address_type)
1593
*address_type = m_value.GetValueAddressType();
1594
return LLDB_INVALID_ADDRESS;
1595
} break;
1596
}
1597
if (address_type)
1598
*address_type = eAddressTypeInvalid;
1599
return LLDB_INVALID_ADDRESS;
1600
}
1601
1602
addr_t ValueObject::GetPointerValue(AddressType *address_type) {
1603
addr_t address = LLDB_INVALID_ADDRESS;
1604
if (address_type)
1605
*address_type = eAddressTypeInvalid;
1606
1607
if (!UpdateValueIfNeeded(false))
1608
return address;
1609
1610
switch (m_value.GetValueType()) {
1611
case Value::ValueType::Invalid:
1612
return LLDB_INVALID_ADDRESS;
1613
case Value::ValueType::Scalar:
1614
address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1615
break;
1616
1617
case Value::ValueType::HostAddress:
1618
case Value::ValueType::LoadAddress:
1619
case Value::ValueType::FileAddress: {
1620
lldb::offset_t data_offset = 0;
1621
address = m_data.GetAddress(&data_offset);
1622
} break;
1623
}
1624
1625
if (address_type)
1626
*address_type = GetAddressTypeOfChildren();
1627
1628
return address;
1629
}
1630
1631
bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
1632
error.Clear();
1633
// Make sure our value is up to date first so that our location and location
1634
// type is valid.
1635
if (!UpdateValueIfNeeded(false)) {
1636
error.SetErrorString("unable to read value");
1637
return false;
1638
}
1639
1640
uint64_t count = 0;
1641
const Encoding encoding = GetCompilerType().GetEncoding(count);
1642
1643
const size_t byte_size = GetByteSize().value_or(0);
1644
1645
Value::ValueType value_type = m_value.GetValueType();
1646
1647
if (value_type == Value::ValueType::Scalar) {
1648
// If the value is already a scalar, then let the scalar change itself:
1649
m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
1650
} else if (byte_size <= 16) {
1651
// If the value fits in a scalar, then make a new scalar and again let the
1652
// scalar code do the conversion, then figure out where to put the new
1653
// value.
1654
Scalar new_scalar;
1655
error = new_scalar.SetValueFromCString(value_str, encoding, byte_size);
1656
if (error.Success()) {
1657
switch (value_type) {
1658
case Value::ValueType::LoadAddress: {
1659
// If it is a load address, then the scalar value is the storage
1660
// location of the data, and we have to shove this value down to that
1661
// load location.
1662
ExecutionContext exe_ctx(GetExecutionContextRef());
1663
Process *process = exe_ctx.GetProcessPtr();
1664
if (process) {
1665
addr_t target_addr =
1666
m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1667
size_t bytes_written = process->WriteScalarToMemory(
1668
target_addr, new_scalar, byte_size, error);
1669
if (!error.Success())
1670
return false;
1671
if (bytes_written != byte_size) {
1672
error.SetErrorString("unable to write value to memory");
1673
return false;
1674
}
1675
}
1676
} break;
1677
case Value::ValueType::HostAddress: {
1678
// If it is a host address, then we stuff the scalar as a DataBuffer
1679
// into the Value's data.
1680
DataExtractor new_data;
1681
new_data.SetByteOrder(m_data.GetByteOrder());
1682
1683
DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
1684
m_data.SetData(buffer_sp, 0);
1685
bool success = new_scalar.GetData(new_data);
1686
if (success) {
1687
new_data.CopyByteOrderedData(
1688
0, byte_size, const_cast<uint8_t *>(m_data.GetDataStart()),
1689
byte_size, m_data.GetByteOrder());
1690
}
1691
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1692
1693
} break;
1694
case Value::ValueType::Invalid:
1695
error.SetErrorString("invalid location");
1696
return false;
1697
case Value::ValueType::FileAddress:
1698
case Value::ValueType::Scalar:
1699
break;
1700
}
1701
} else {
1702
return false;
1703
}
1704
} else {
1705
// We don't support setting things bigger than a scalar at present.
1706
error.SetErrorString("unable to write aggregate data type");
1707
return false;
1708
}
1709
1710
// If we have reached this point, then we have successfully changed the
1711
// value.
1712
SetNeedsUpdate();
1713
return true;
1714
}
1715
1716
bool ValueObject::GetDeclaration(Declaration &decl) {
1717
decl.Clear();
1718
return false;
1719
}
1720
1721
void ValueObject::AddSyntheticChild(ConstString key,
1722
ValueObject *valobj) {
1723
m_synthetic_children[key] = valobj;
1724
}
1725
1726
ValueObjectSP ValueObject::GetSyntheticChild(ConstString key) const {
1727
ValueObjectSP synthetic_child_sp;
1728
std::map<ConstString, ValueObject *>::const_iterator pos =
1729
m_synthetic_children.find(key);
1730
if (pos != m_synthetic_children.end())
1731
synthetic_child_sp = pos->second->GetSP();
1732
return synthetic_child_sp;
1733
}
1734
1735
bool ValueObject::IsPossibleDynamicType() {
1736
ExecutionContext exe_ctx(GetExecutionContextRef());
1737
Process *process = exe_ctx.GetProcessPtr();
1738
if (process)
1739
return process->IsPossibleDynamicValue(*this);
1740
else
1741
return GetCompilerType().IsPossibleDynamicType(nullptr, true, true);
1742
}
1743
1744
bool ValueObject::IsRuntimeSupportValue() {
1745
Process *process(GetProcessSP().get());
1746
if (!process)
1747
return false;
1748
1749
// We trust that the compiler did the right thing and marked runtime support
1750
// values as artificial.
1751
if (!GetVariable() || !GetVariable()->IsArtificial())
1752
return false;
1753
1754
if (auto *runtime = process->GetLanguageRuntime(GetVariable()->GetLanguage()))
1755
if (runtime->IsAllowedRuntimeValue(GetName()))
1756
return false;
1757
1758
return true;
1759
}
1760
1761
bool ValueObject::IsNilReference() {
1762
if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1763
return language->IsNilReference(*this);
1764
}
1765
return false;
1766
}
1767
1768
bool ValueObject::IsUninitializedReference() {
1769
if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1770
return language->IsUninitializedReference(*this);
1771
}
1772
return false;
1773
}
1774
1775
// This allows you to create an array member using and index that doesn't not
1776
// fall in the normal bounds of the array. Many times structure can be defined
1777
// as: struct Collection {
1778
// uint32_t item_count;
1779
// Item item_array[0];
1780
// };
1781
// The size of the "item_array" is 1, but many times in practice there are more
1782
// items in "item_array".
1783
1784
ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
1785
bool can_create) {
1786
ValueObjectSP synthetic_child_sp;
1787
if (IsPointerType() || IsArrayType()) {
1788
std::string index_str = llvm::formatv("[{0}]", index);
1789
ConstString index_const_str(index_str);
1790
// Check if we have already created a synthetic array member in this valid
1791
// object. If we have we will re-use it.
1792
synthetic_child_sp = GetSyntheticChild(index_const_str);
1793
if (!synthetic_child_sp) {
1794
ValueObject *synthetic_child;
1795
// We haven't made a synthetic array member for INDEX yet, so lets make
1796
// one and cache it for any future reference.
1797
synthetic_child = CreateSyntheticArrayMember(index);
1798
1799
// Cache the value if we got one back...
1800
if (synthetic_child) {
1801
AddSyntheticChild(index_const_str, synthetic_child);
1802
synthetic_child_sp = synthetic_child->GetSP();
1803
synthetic_child_sp->SetName(ConstString(index_str));
1804
synthetic_child_sp->m_flags.m_is_array_item_for_pointer = true;
1805
}
1806
}
1807
}
1808
return synthetic_child_sp;
1809
}
1810
1811
ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
1812
bool can_create) {
1813
ValueObjectSP synthetic_child_sp;
1814
if (IsScalarType()) {
1815
std::string index_str = llvm::formatv("[{0}-{1}]", from, to);
1816
ConstString index_const_str(index_str);
1817
// Check if we have already created a synthetic array member in this valid
1818
// object. If we have we will re-use it.
1819
synthetic_child_sp = GetSyntheticChild(index_const_str);
1820
if (!synthetic_child_sp) {
1821
uint32_t bit_field_size = to - from + 1;
1822
uint32_t bit_field_offset = from;
1823
if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
1824
bit_field_offset =
1825
GetByteSize().value_or(0) * 8 - bit_field_size - bit_field_offset;
1826
// We haven't made a synthetic array member for INDEX yet, so lets make
1827
// one and cache it for any future reference.
1828
ValueObjectChild *synthetic_child = new ValueObjectChild(
1829
*this, GetCompilerType(), index_const_str, GetByteSize().value_or(0),
1830
0, bit_field_size, bit_field_offset, false, false,
1831
eAddressTypeInvalid, 0);
1832
1833
// Cache the value if we got one back...
1834
if (synthetic_child) {
1835
AddSyntheticChild(index_const_str, synthetic_child);
1836
synthetic_child_sp = synthetic_child->GetSP();
1837
synthetic_child_sp->SetName(ConstString(index_str));
1838
synthetic_child_sp->m_flags.m_is_bitfield_for_scalar = true;
1839
}
1840
}
1841
}
1842
return synthetic_child_sp;
1843
}
1844
1845
ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
1846
uint32_t offset, const CompilerType &type, bool can_create,
1847
ConstString name_const_str) {
1848
1849
ValueObjectSP synthetic_child_sp;
1850
1851
if (name_const_str.IsEmpty()) {
1852
name_const_str.SetString("@" + std::to_string(offset));
1853
}
1854
1855
// Check if we have already created a synthetic array member in this valid
1856
// object. If we have we will re-use it.
1857
synthetic_child_sp = GetSyntheticChild(name_const_str);
1858
1859
if (synthetic_child_sp.get())
1860
return synthetic_child_sp;
1861
1862
if (!can_create)
1863
return {};
1864
1865
ExecutionContext exe_ctx(GetExecutionContextRef());
1866
std::optional<uint64_t> size =
1867
type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
1868
if (!size)
1869
return {};
1870
ValueObjectChild *synthetic_child =
1871
new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
1872
false, false, eAddressTypeInvalid, 0);
1873
if (synthetic_child) {
1874
AddSyntheticChild(name_const_str, synthetic_child);
1875
synthetic_child_sp = synthetic_child->GetSP();
1876
synthetic_child_sp->SetName(name_const_str);
1877
synthetic_child_sp->m_flags.m_is_child_at_offset = true;
1878
}
1879
return synthetic_child_sp;
1880
}
1881
1882
ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
1883
const CompilerType &type,
1884
bool can_create,
1885
ConstString name_const_str) {
1886
ValueObjectSP synthetic_child_sp;
1887
1888
if (name_const_str.IsEmpty()) {
1889
char name_str[128];
1890
snprintf(name_str, sizeof(name_str), "base%s@%i",
1891
type.GetTypeName().AsCString("<unknown>"), offset);
1892
name_const_str.SetCString(name_str);
1893
}
1894
1895
// Check if we have already created a synthetic array member in this valid
1896
// object. If we have we will re-use it.
1897
synthetic_child_sp = GetSyntheticChild(name_const_str);
1898
1899
if (synthetic_child_sp.get())
1900
return synthetic_child_sp;
1901
1902
if (!can_create)
1903
return {};
1904
1905
const bool is_base_class = true;
1906
1907
ExecutionContext exe_ctx(GetExecutionContextRef());
1908
std::optional<uint64_t> size =
1909
type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
1910
if (!size)
1911
return {};
1912
ValueObjectChild *synthetic_child =
1913
new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
1914
is_base_class, false, eAddressTypeInvalid, 0);
1915
if (synthetic_child) {
1916
AddSyntheticChild(name_const_str, synthetic_child);
1917
synthetic_child_sp = synthetic_child->GetSP();
1918
synthetic_child_sp->SetName(name_const_str);
1919
}
1920
return synthetic_child_sp;
1921
}
1922
1923
// your expression path needs to have a leading . or -> (unless it somehow
1924
// "looks like" an array, in which case it has a leading [ symbol). while the [
1925
// is meaningful and should be shown to the user, . and -> are just parser
1926
// design, but by no means added information for the user.. strip them off
1927
static const char *SkipLeadingExpressionPathSeparators(const char *expression) {
1928
if (!expression || !expression[0])
1929
return expression;
1930
if (expression[0] == '.')
1931
return expression + 1;
1932
if (expression[0] == '-' && expression[1] == '>')
1933
return expression + 2;
1934
return expression;
1935
}
1936
1937
ValueObjectSP
1938
ValueObject::GetSyntheticExpressionPathChild(const char *expression,
1939
bool can_create) {
1940
ValueObjectSP synthetic_child_sp;
1941
ConstString name_const_string(expression);
1942
// Check if we have already created a synthetic array member in this valid
1943
// object. If we have we will re-use it.
1944
synthetic_child_sp = GetSyntheticChild(name_const_string);
1945
if (!synthetic_child_sp) {
1946
// We haven't made a synthetic array member for expression yet, so lets
1947
// make one and cache it for any future reference.
1948
synthetic_child_sp = GetValueForExpressionPath(
1949
expression, nullptr, nullptr,
1950
GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(
1951
GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
1952
None));
1953
1954
// Cache the value if we got one back...
1955
if (synthetic_child_sp.get()) {
1956
// FIXME: this causes a "real" child to end up with its name changed to
1957
// the contents of expression
1958
AddSyntheticChild(name_const_string, synthetic_child_sp.get());
1959
synthetic_child_sp->SetName(
1960
ConstString(SkipLeadingExpressionPathSeparators(expression)));
1961
}
1962
}
1963
return synthetic_child_sp;
1964
}
1965
1966
void ValueObject::CalculateSyntheticValue() {
1967
TargetSP target_sp(GetTargetSP());
1968
if (target_sp && !target_sp->GetEnableSyntheticValue()) {
1969
m_synthetic_value = nullptr;
1970
return;
1971
}
1972
1973
lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
1974
1975
if (!UpdateFormatsIfNeeded() && m_synthetic_value)
1976
return;
1977
1978
if (m_synthetic_children_sp.get() == nullptr)
1979
return;
1980
1981
if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
1982
return;
1983
1984
m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
1985
}
1986
1987
void ValueObject::CalculateDynamicValue(DynamicValueType use_dynamic) {
1988
if (use_dynamic == eNoDynamicValues)
1989
return;
1990
1991
if (!m_dynamic_value && !IsDynamic()) {
1992
ExecutionContext exe_ctx(GetExecutionContextRef());
1993
Process *process = exe_ctx.GetProcessPtr();
1994
if (process && process->IsPossibleDynamicValue(*this)) {
1995
ClearDynamicTypeInformation();
1996
m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
1997
}
1998
}
1999
}
2000
2001
ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) {
2002
if (use_dynamic == eNoDynamicValues)
2003
return ValueObjectSP();
2004
2005
if (!IsDynamic() && m_dynamic_value == nullptr) {
2006
CalculateDynamicValue(use_dynamic);
2007
}
2008
if (m_dynamic_value && m_dynamic_value->GetError().Success())
2009
return m_dynamic_value->GetSP();
2010
else
2011
return ValueObjectSP();
2012
}
2013
2014
ValueObjectSP ValueObject::GetSyntheticValue() {
2015
CalculateSyntheticValue();
2016
2017
if (m_synthetic_value)
2018
return m_synthetic_value->GetSP();
2019
else
2020
return ValueObjectSP();
2021
}
2022
2023
bool ValueObject::HasSyntheticValue() {
2024
UpdateFormatsIfNeeded();
2025
2026
if (m_synthetic_children_sp.get() == nullptr)
2027
return false;
2028
2029
CalculateSyntheticValue();
2030
2031
return m_synthetic_value != nullptr;
2032
}
2033
2034
ValueObject *ValueObject::GetNonBaseClassParent() {
2035
if (GetParent()) {
2036
if (GetParent()->IsBaseClass())
2037
return GetParent()->GetNonBaseClassParent();
2038
else
2039
return GetParent();
2040
}
2041
return nullptr;
2042
}
2043
2044
bool ValueObject::IsBaseClass(uint32_t &depth) {
2045
if (!IsBaseClass()) {
2046
depth = 0;
2047
return false;
2048
}
2049
if (GetParent()) {
2050
GetParent()->IsBaseClass(depth);
2051
depth = depth + 1;
2052
return true;
2053
}
2054
// TODO: a base of no parent? weird..
2055
depth = 1;
2056
return true;
2057
}
2058
2059
void ValueObject::GetExpressionPath(Stream &s,
2060
GetExpressionPathFormat epformat) {
2061
// synthetic children do not actually "exist" as part of the hierarchy, and
2062
// sometimes they are consed up in ways that don't make sense from an
2063
// underlying language/API standpoint. So, use a special code path here to
2064
// return something that can hopefully be used in expression
2065
if (m_flags.m_is_synthetic_children_generated) {
2066
UpdateValueIfNeeded();
2067
2068
if (m_value.GetValueType() == Value::ValueType::LoadAddress) {
2069
if (IsPointerOrReferenceType()) {
2070
s.Printf("((%s)0x%" PRIx64 ")", GetTypeName().AsCString("void"),
2071
GetValueAsUnsigned(0));
2072
return;
2073
} else {
2074
uint64_t load_addr =
2075
m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
2076
if (load_addr != LLDB_INVALID_ADDRESS) {
2077
s.Printf("(*( (%s *)0x%" PRIx64 "))", GetTypeName().AsCString("void"),
2078
load_addr);
2079
return;
2080
}
2081
}
2082
}
2083
2084
if (CanProvideValue()) {
2085
s.Printf("((%s)%s)", GetTypeName().AsCString("void"),
2086
GetValueAsCString());
2087
return;
2088
}
2089
2090
return;
2091
}
2092
2093
const bool is_deref_of_parent = IsDereferenceOfParent();
2094
2095
if (is_deref_of_parent &&
2096
epformat == eGetExpressionPathFormatDereferencePointers) {
2097
// this is the original format of GetExpressionPath() producing code like
2098
// *(a_ptr).memberName, which is entirely fine, until you put this into
2099
// StackFrame::GetValueForVariableExpressionPath() which prefers to see
2100
// a_ptr->memberName. the eHonorPointers mode is meant to produce strings
2101
// in this latter format
2102
s.PutCString("*(");
2103
}
2104
2105
ValueObject *parent = GetParent();
2106
2107
if (parent)
2108
parent->GetExpressionPath(s, epformat);
2109
2110
// if we are a deref_of_parent just because we are synthetic array members
2111
// made up to allow ptr[%d] syntax to work in variable printing, then add our
2112
// name ([%d]) to the expression path
2113
if (m_flags.m_is_array_item_for_pointer &&
2114
epformat == eGetExpressionPathFormatHonorPointers)
2115
s.PutCString(m_name.GetStringRef());
2116
2117
if (!IsBaseClass()) {
2118
if (!is_deref_of_parent) {
2119
ValueObject *non_base_class_parent = GetNonBaseClassParent();
2120
if (non_base_class_parent &&
2121
!non_base_class_parent->GetName().IsEmpty()) {
2122
CompilerType non_base_class_parent_compiler_type =
2123
non_base_class_parent->GetCompilerType();
2124
if (non_base_class_parent_compiler_type) {
2125
if (parent && parent->IsDereferenceOfParent() &&
2126
epformat == eGetExpressionPathFormatHonorPointers) {
2127
s.PutCString("->");
2128
} else {
2129
const uint32_t non_base_class_parent_type_info =
2130
non_base_class_parent_compiler_type.GetTypeInfo();
2131
2132
if (non_base_class_parent_type_info & eTypeIsPointer) {
2133
s.PutCString("->");
2134
} else if ((non_base_class_parent_type_info & eTypeHasChildren) &&
2135
!(non_base_class_parent_type_info & eTypeIsArray)) {
2136
s.PutChar('.');
2137
}
2138
}
2139
}
2140
}
2141
2142
const char *name = GetName().GetCString();
2143
if (name)
2144
s.PutCString(name);
2145
}
2146
}
2147
2148
if (is_deref_of_parent &&
2149
epformat == eGetExpressionPathFormatDereferencePointers) {
2150
s.PutChar(')');
2151
}
2152
}
2153
2154
ValueObjectSP ValueObject::GetValueForExpressionPath(
2155
llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
2156
ExpressionPathEndResultType *final_value_type,
2157
const GetValueForExpressionPathOptions &options,
2158
ExpressionPathAftermath *final_task_on_target) {
2159
2160
ExpressionPathScanEndReason dummy_reason_to_stop =
2161
ValueObject::eExpressionPathScanEndReasonUnknown;
2162
ExpressionPathEndResultType dummy_final_value_type =
2163
ValueObject::eExpressionPathEndResultTypeInvalid;
2164
ExpressionPathAftermath dummy_final_task_on_target =
2165
ValueObject::eExpressionPathAftermathNothing;
2166
2167
ValueObjectSP ret_val = GetValueForExpressionPath_Impl(
2168
expression, reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
2169
final_value_type ? final_value_type : &dummy_final_value_type, options,
2170
final_task_on_target ? final_task_on_target
2171
: &dummy_final_task_on_target);
2172
2173
if (!final_task_on_target ||
2174
*final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
2175
return ret_val;
2176
2177
if (ret_val.get() &&
2178
((final_value_type ? *final_value_type : dummy_final_value_type) ==
2179
eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress
2180
// of plain objects
2181
{
2182
if ((final_task_on_target ? *final_task_on_target
2183
: dummy_final_task_on_target) ==
2184
ValueObject::eExpressionPathAftermathDereference) {
2185
Status error;
2186
ValueObjectSP final_value = ret_val->Dereference(error);
2187
if (error.Fail() || !final_value.get()) {
2188
if (reason_to_stop)
2189
*reason_to_stop =
2190
ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2191
if (final_value_type)
2192
*final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2193
return ValueObjectSP();
2194
} else {
2195
if (final_task_on_target)
2196
*final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2197
return final_value;
2198
}
2199
}
2200
if (*final_task_on_target ==
2201
ValueObject::eExpressionPathAftermathTakeAddress) {
2202
Status error;
2203
ValueObjectSP final_value = ret_val->AddressOf(error);
2204
if (error.Fail() || !final_value.get()) {
2205
if (reason_to_stop)
2206
*reason_to_stop =
2207
ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
2208
if (final_value_type)
2209
*final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2210
return ValueObjectSP();
2211
} else {
2212
if (final_task_on_target)
2213
*final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2214
return final_value;
2215
}
2216
}
2217
}
2218
return ret_val; // final_task_on_target will still have its original value, so
2219
// you know I did not do it
2220
}
2221
2222
ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
2223
llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
2224
ExpressionPathEndResultType *final_result,
2225
const GetValueForExpressionPathOptions &options,
2226
ExpressionPathAftermath *what_next) {
2227
ValueObjectSP root = GetSP();
2228
2229
if (!root)
2230
return nullptr;
2231
2232
llvm::StringRef remainder = expression;
2233
2234
while (true) {
2235
llvm::StringRef temp_expression = remainder;
2236
2237
CompilerType root_compiler_type = root->GetCompilerType();
2238
CompilerType pointee_compiler_type;
2239
Flags pointee_compiler_type_info;
2240
2241
Flags root_compiler_type_info(
2242
root_compiler_type.GetTypeInfo(&pointee_compiler_type));
2243
if (pointee_compiler_type)
2244
pointee_compiler_type_info.Reset(pointee_compiler_type.GetTypeInfo());
2245
2246
if (temp_expression.empty()) {
2247
*reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2248
return root;
2249
}
2250
2251
switch (temp_expression.front()) {
2252
case '-': {
2253
temp_expression = temp_expression.drop_front();
2254
if (options.m_check_dot_vs_arrow_syntax &&
2255
root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2256
// use -> on a
2257
// non-pointer and I
2258
// must catch the error
2259
{
2260
*reason_to_stop =
2261
ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
2262
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2263
return ValueObjectSP();
2264
}
2265
if (root_compiler_type_info.Test(eTypeIsObjC) && // if yo are trying to
2266
// extract an ObjC IVar
2267
// when this is forbidden
2268
root_compiler_type_info.Test(eTypeIsPointer) &&
2269
options.m_no_fragile_ivar) {
2270
*reason_to_stop =
2271
ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
2272
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2273
return ValueObjectSP();
2274
}
2275
if (!temp_expression.starts_with(">")) {
2276
*reason_to_stop =
2277
ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2278
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2279
return ValueObjectSP();
2280
}
2281
}
2282
[[fallthrough]];
2283
case '.': // or fallthrough from ->
2284
{
2285
if (options.m_check_dot_vs_arrow_syntax &&
2286
temp_expression.front() == '.' &&
2287
root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2288
// use . on a pointer
2289
// and I must catch the
2290
// error
2291
{
2292
*reason_to_stop =
2293
ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
2294
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2295
return nullptr;
2296
}
2297
temp_expression = temp_expression.drop_front(); // skip . or >
2298
2299
size_t next_sep_pos = temp_expression.find_first_of("-.[", 1);
2300
if (next_sep_pos == llvm::StringRef::npos) // if no other separator just
2301
// expand this last layer
2302
{
2303
llvm::StringRef child_name = temp_expression;
2304
ValueObjectSP child_valobj_sp =
2305
root->GetChildMemberWithName(child_name);
2306
2307
if (child_valobj_sp.get()) // we know we are done, so just return
2308
{
2309
*reason_to_stop =
2310
ValueObject::eExpressionPathScanEndReasonEndOfString;
2311
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
2312
return child_valobj_sp;
2313
} else {
2314
switch (options.m_synthetic_children_traversal) {
2315
case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2316
None:
2317
break;
2318
case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2319
FromSynthetic:
2320
if (root->IsSynthetic()) {
2321
child_valobj_sp = root->GetNonSyntheticValue();
2322
if (child_valobj_sp.get())
2323
child_valobj_sp =
2324
child_valobj_sp->GetChildMemberWithName(child_name);
2325
}
2326
break;
2327
case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2328
ToSynthetic:
2329
if (!root->IsSynthetic()) {
2330
child_valobj_sp = root->GetSyntheticValue();
2331
if (child_valobj_sp.get())
2332
child_valobj_sp =
2333
child_valobj_sp->GetChildMemberWithName(child_name);
2334
}
2335
break;
2336
case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2337
Both:
2338
if (root->IsSynthetic()) {
2339
child_valobj_sp = root->GetNonSyntheticValue();
2340
if (child_valobj_sp.get())
2341
child_valobj_sp =
2342
child_valobj_sp->GetChildMemberWithName(child_name);
2343
} else {
2344
child_valobj_sp = root->GetSyntheticValue();
2345
if (child_valobj_sp.get())
2346
child_valobj_sp =
2347
child_valobj_sp->GetChildMemberWithName(child_name);
2348
}
2349
break;
2350
}
2351
}
2352
2353
// if we are here and options.m_no_synthetic_children is true,
2354
// child_valobj_sp is going to be a NULL SP, so we hit the "else"
2355
// branch, and return an error
2356
if (child_valobj_sp.get()) // if it worked, just return
2357
{
2358
*reason_to_stop =
2359
ValueObject::eExpressionPathScanEndReasonEndOfString;
2360
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
2361
return child_valobj_sp;
2362
} else {
2363
*reason_to_stop =
2364
ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2365
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2366
return nullptr;
2367
}
2368
} else // other layers do expand
2369
{
2370
llvm::StringRef next_separator = temp_expression.substr(next_sep_pos);
2371
llvm::StringRef child_name = temp_expression.slice(0, next_sep_pos);
2372
2373
ValueObjectSP child_valobj_sp =
2374
root->GetChildMemberWithName(child_name);
2375
if (child_valobj_sp.get()) // store the new root and move on
2376
{
2377
root = child_valobj_sp;
2378
remainder = next_separator;
2379
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
2380
continue;
2381
} else {
2382
switch (options.m_synthetic_children_traversal) {
2383
case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2384
None:
2385
break;
2386
case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2387
FromSynthetic:
2388
if (root->IsSynthetic()) {
2389
child_valobj_sp = root->GetNonSyntheticValue();
2390
if (child_valobj_sp.get())
2391
child_valobj_sp =
2392
child_valobj_sp->GetChildMemberWithName(child_name);
2393
}
2394
break;
2395
case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2396
ToSynthetic:
2397
if (!root->IsSynthetic()) {
2398
child_valobj_sp = root->GetSyntheticValue();
2399
if (child_valobj_sp.get())
2400
child_valobj_sp =
2401
child_valobj_sp->GetChildMemberWithName(child_name);
2402
}
2403
break;
2404
case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2405
Both:
2406
if (root->IsSynthetic()) {
2407
child_valobj_sp = root->GetNonSyntheticValue();
2408
if (child_valobj_sp.get())
2409
child_valobj_sp =
2410
child_valobj_sp->GetChildMemberWithName(child_name);
2411
} else {
2412
child_valobj_sp = root->GetSyntheticValue();
2413
if (child_valobj_sp.get())
2414
child_valobj_sp =
2415
child_valobj_sp->GetChildMemberWithName(child_name);
2416
}
2417
break;
2418
}
2419
}
2420
2421
// if we are here and options.m_no_synthetic_children is true,
2422
// child_valobj_sp is going to be a NULL SP, so we hit the "else"
2423
// branch, and return an error
2424
if (child_valobj_sp.get()) // if it worked, move on
2425
{
2426
root = child_valobj_sp;
2427
remainder = next_separator;
2428
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
2429
continue;
2430
} else {
2431
*reason_to_stop =
2432
ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2433
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2434
return nullptr;
2435
}
2436
}
2437
break;
2438
}
2439
case '[': {
2440
if (!root_compiler_type_info.Test(eTypeIsArray) &&
2441
!root_compiler_type_info.Test(eTypeIsPointer) &&
2442
!root_compiler_type_info.Test(
2443
eTypeIsVector)) // if this is not a T[] nor a T*
2444
{
2445
if (!root_compiler_type_info.Test(
2446
eTypeIsScalar)) // if this is not even a scalar...
2447
{
2448
if (options.m_synthetic_children_traversal ==
2449
GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2450
None) // ...only chance left is synthetic
2451
{
2452
*reason_to_stop =
2453
ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
2454
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2455
return ValueObjectSP();
2456
}
2457
} else if (!options.m_allow_bitfields_syntax) // if this is a scalar,
2458
// check that we can
2459
// expand bitfields
2460
{
2461
*reason_to_stop =
2462
ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
2463
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2464
return ValueObjectSP();
2465
}
2466
}
2467
if (temp_expression[1] ==
2468
']') // if this is an unbounded range it only works for arrays
2469
{
2470
if (!root_compiler_type_info.Test(eTypeIsArray)) {
2471
*reason_to_stop =
2472
ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2473
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2474
return nullptr;
2475
} else // even if something follows, we cannot expand unbounded ranges,
2476
// just let the caller do it
2477
{
2478
*reason_to_stop =
2479
ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2480
*final_result =
2481
ValueObject::eExpressionPathEndResultTypeUnboundedRange;
2482
return root;
2483
}
2484
}
2485
2486
size_t close_bracket_position = temp_expression.find(']', 1);
2487
if (close_bracket_position ==
2488
llvm::StringRef::npos) // if there is no ], this is a syntax error
2489
{
2490
*reason_to_stop =
2491
ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2492
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2493
return nullptr;
2494
}
2495
2496
llvm::StringRef bracket_expr =
2497
temp_expression.slice(1, close_bracket_position);
2498
2499
// If this was an empty expression it would have been caught by the if
2500
// above.
2501
assert(!bracket_expr.empty());
2502
2503
if (!bracket_expr.contains('-')) {
2504
// if no separator, this is of the form [N]. Note that this cannot be
2505
// an unbounded range of the form [], because that case was handled
2506
// above with an unconditional return.
2507
unsigned long index = 0;
2508
if (bracket_expr.getAsInteger(0, index)) {
2509
*reason_to_stop =
2510
ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2511
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2512
return nullptr;
2513
}
2514
2515
// from here on we do have a valid index
2516
if (root_compiler_type_info.Test(eTypeIsArray)) {
2517
ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index);
2518
if (!child_valobj_sp)
2519
child_valobj_sp = root->GetSyntheticArrayMember(index, true);
2520
if (!child_valobj_sp)
2521
if (root->HasSyntheticValue() &&
2522
llvm::expectedToStdOptional(
2523
root->GetSyntheticValue()->GetNumChildren())
2524
.value_or(0) > index)
2525
child_valobj_sp =
2526
root->GetSyntheticValue()->GetChildAtIndex(index);
2527
if (child_valobj_sp) {
2528
root = child_valobj_sp;
2529
remainder =
2530
temp_expression.substr(close_bracket_position + 1); // skip ]
2531
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
2532
continue;
2533
} else {
2534
*reason_to_stop =
2535
ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2536
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2537
return nullptr;
2538
}
2539
} else if (root_compiler_type_info.Test(eTypeIsPointer)) {
2540
if (*what_next ==
2541
ValueObject::
2542
eExpressionPathAftermathDereference && // if this is a
2543
// ptr-to-scalar, I
2544
// am accessing it
2545
// by index and I
2546
// would have
2547
// deref'ed anyway,
2548
// then do it now
2549
// and use this as
2550
// a bitfield
2551
pointee_compiler_type_info.Test(eTypeIsScalar)) {
2552
Status error;
2553
root = root->Dereference(error);
2554
if (error.Fail() || !root) {
2555
*reason_to_stop =
2556
ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2557
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2558
return nullptr;
2559
} else {
2560
*what_next = eExpressionPathAftermathNothing;
2561
continue;
2562
}
2563
} else {
2564
if (root->GetCompilerType().GetMinimumLanguage() ==
2565
eLanguageTypeObjC &&
2566
pointee_compiler_type_info.AllClear(eTypeIsPointer) &&
2567
root->HasSyntheticValue() &&
2568
(options.m_synthetic_children_traversal ==
2569
GetValueForExpressionPathOptions::
2570
SyntheticChildrenTraversal::ToSynthetic ||
2571
options.m_synthetic_children_traversal ==
2572
GetValueForExpressionPathOptions::
2573
SyntheticChildrenTraversal::Both)) {
2574
root = root->GetSyntheticValue()->GetChildAtIndex(index);
2575
} else
2576
root = root->GetSyntheticArrayMember(index, true);
2577
if (!root) {
2578
*reason_to_stop =
2579
ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2580
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2581
return nullptr;
2582
} else {
2583
remainder =
2584
temp_expression.substr(close_bracket_position + 1); // skip ]
2585
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
2586
continue;
2587
}
2588
}
2589
} else if (root_compiler_type_info.Test(eTypeIsScalar)) {
2590
root = root->GetSyntheticBitFieldChild(index, index, true);
2591
if (!root) {
2592
*reason_to_stop =
2593
ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2594
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2595
return nullptr;
2596
} else // we do not know how to expand members of bitfields, so we
2597
// just return and let the caller do any further processing
2598
{
2599
*reason_to_stop = ValueObject::
2600
eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2601
*final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2602
return root;
2603
}
2604
} else if (root_compiler_type_info.Test(eTypeIsVector)) {
2605
root = root->GetChildAtIndex(index);
2606
if (!root) {
2607
*reason_to_stop =
2608
ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2609
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2610
return ValueObjectSP();
2611
} else {
2612
remainder =
2613
temp_expression.substr(close_bracket_position + 1); // skip ]
2614
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
2615
continue;
2616
}
2617
} else if (options.m_synthetic_children_traversal ==
2618
GetValueForExpressionPathOptions::
2619
SyntheticChildrenTraversal::ToSynthetic ||
2620
options.m_synthetic_children_traversal ==
2621
GetValueForExpressionPathOptions::
2622
SyntheticChildrenTraversal::Both) {
2623
if (root->HasSyntheticValue())
2624
root = root->GetSyntheticValue();
2625
else if (!root->IsSynthetic()) {
2626
*reason_to_stop =
2627
ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2628
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2629
return nullptr;
2630
}
2631
// if we are here, then root itself is a synthetic VO.. should be
2632
// good to go
2633
2634
if (!root) {
2635
*reason_to_stop =
2636
ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2637
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2638
return nullptr;
2639
}
2640
root = root->GetChildAtIndex(index);
2641
if (!root) {
2642
*reason_to_stop =
2643
ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2644
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2645
return nullptr;
2646
} else {
2647
remainder =
2648
temp_expression.substr(close_bracket_position + 1); // skip ]
2649
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
2650
continue;
2651
}
2652
} else {
2653
*reason_to_stop =
2654
ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2655
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2656
return nullptr;
2657
}
2658
} else {
2659
// we have a low and a high index
2660
llvm::StringRef sleft, sright;
2661
unsigned long low_index, high_index;
2662
std::tie(sleft, sright) = bracket_expr.split('-');
2663
if (sleft.getAsInteger(0, low_index) ||
2664
sright.getAsInteger(0, high_index)) {
2665
*reason_to_stop =
2666
ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2667
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2668
return nullptr;
2669
}
2670
2671
if (low_index > high_index) // swap indices if required
2672
std::swap(low_index, high_index);
2673
2674
if (root_compiler_type_info.Test(
2675
eTypeIsScalar)) // expansion only works for scalars
2676
{
2677
root = root->GetSyntheticBitFieldChild(low_index, high_index, true);
2678
if (!root) {
2679
*reason_to_stop =
2680
ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2681
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2682
return nullptr;
2683
} else {
2684
*reason_to_stop = ValueObject::
2685
eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2686
*final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2687
return root;
2688
}
2689
} else if (root_compiler_type_info.Test(
2690
eTypeIsPointer) && // if this is a ptr-to-scalar, I am
2691
// accessing it by index and I would
2692
// have deref'ed anyway, then do it
2693
// now and use this as a bitfield
2694
*what_next ==
2695
ValueObject::eExpressionPathAftermathDereference &&
2696
pointee_compiler_type_info.Test(eTypeIsScalar)) {
2697
Status error;
2698
root = root->Dereference(error);
2699
if (error.Fail() || !root) {
2700
*reason_to_stop =
2701
ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2702
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2703
return nullptr;
2704
} else {
2705
*what_next = ValueObject::eExpressionPathAftermathNothing;
2706
continue;
2707
}
2708
} else {
2709
*reason_to_stop =
2710
ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2711
*final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
2712
return root;
2713
}
2714
}
2715
break;
2716
}
2717
default: // some non-separator is in the way
2718
{
2719
*reason_to_stop =
2720
ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2721
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2722
return nullptr;
2723
}
2724
}
2725
}
2726
}
2727
2728
llvm::Error ValueObject::Dump(Stream &s) {
2729
return Dump(s, DumpValueObjectOptions(*this));
2730
}
2731
2732
llvm::Error ValueObject::Dump(Stream &s,
2733
const DumpValueObjectOptions &options) {
2734
ValueObjectPrinter printer(*this, &s, options);
2735
return printer.PrintValueObject();
2736
}
2737
2738
ValueObjectSP ValueObject::CreateConstantValue(ConstString name) {
2739
ValueObjectSP valobj_sp;
2740
2741
if (UpdateValueIfNeeded(false) && m_error.Success()) {
2742
ExecutionContext exe_ctx(GetExecutionContextRef());
2743
2744
DataExtractor data;
2745
data.SetByteOrder(m_data.GetByteOrder());
2746
data.SetAddressByteSize(m_data.GetAddressByteSize());
2747
2748
if (IsBitfield()) {
2749
Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
2750
m_error = v.GetValueAsData(&exe_ctx, data, GetModule().get());
2751
} else
2752
m_error = m_value.GetValueAsData(&exe_ctx, data, GetModule().get());
2753
2754
valobj_sp = ValueObjectConstResult::Create(
2755
exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,
2756
GetAddressOf());
2757
}
2758
2759
if (!valobj_sp) {
2760
ExecutionContext exe_ctx(GetExecutionContextRef());
2761
valobj_sp = ValueObjectConstResult::Create(
2762
exe_ctx.GetBestExecutionContextScope(), m_error);
2763
}
2764
return valobj_sp;
2765
}
2766
2767
ValueObjectSP ValueObject::GetQualifiedRepresentationIfAvailable(
2768
lldb::DynamicValueType dynValue, bool synthValue) {
2769
ValueObjectSP result_sp;
2770
switch (dynValue) {
2771
case lldb::eDynamicCanRunTarget:
2772
case lldb::eDynamicDontRunTarget: {
2773
if (!IsDynamic())
2774
result_sp = GetDynamicValue(dynValue);
2775
} break;
2776
case lldb::eNoDynamicValues: {
2777
if (IsDynamic())
2778
result_sp = GetStaticValue();
2779
} break;
2780
}
2781
if (!result_sp)
2782
result_sp = GetSP();
2783
assert(result_sp);
2784
2785
bool is_synthetic = result_sp->IsSynthetic();
2786
if (synthValue && !is_synthetic) {
2787
if (auto synth_sp = result_sp->GetSyntheticValue())
2788
return synth_sp;
2789
}
2790
if (!synthValue && is_synthetic) {
2791
if (auto non_synth_sp = result_sp->GetNonSyntheticValue())
2792
return non_synth_sp;
2793
}
2794
2795
return result_sp;
2796
}
2797
2798
ValueObjectSP ValueObject::Dereference(Status &error) {
2799
if (m_deref_valobj)
2800
return m_deref_valobj->GetSP();
2801
2802
const bool is_pointer_or_reference_type = IsPointerOrReferenceType();
2803
if (is_pointer_or_reference_type) {
2804
bool omit_empty_base_classes = true;
2805
bool ignore_array_bounds = false;
2806
2807
std::string child_name_str;
2808
uint32_t child_byte_size = 0;
2809
int32_t child_byte_offset = 0;
2810
uint32_t child_bitfield_bit_size = 0;
2811
uint32_t child_bitfield_bit_offset = 0;
2812
bool child_is_base_class = false;
2813
bool child_is_deref_of_parent = false;
2814
const bool transparent_pointers = false;
2815
CompilerType compiler_type = GetCompilerType();
2816
uint64_t language_flags = 0;
2817
2818
ExecutionContext exe_ctx(GetExecutionContextRef());
2819
2820
CompilerType child_compiler_type;
2821
auto child_compiler_type_or_err = compiler_type.GetChildCompilerTypeAtIndex(
2822
&exe_ctx, 0, transparent_pointers, omit_empty_base_classes,
2823
ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
2824
child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
2825
child_is_deref_of_parent, this, language_flags);
2826
if (!child_compiler_type_or_err)
2827
LLDB_LOG_ERROR(GetLog(LLDBLog::Types),
2828
child_compiler_type_or_err.takeError(),
2829
"could not find child: {0}");
2830
else
2831
child_compiler_type = *child_compiler_type_or_err;
2832
2833
if (child_compiler_type && child_byte_size) {
2834
ConstString child_name;
2835
if (!child_name_str.empty())
2836
child_name.SetCString(child_name_str.c_str());
2837
2838
m_deref_valobj = new ValueObjectChild(
2839
*this, child_compiler_type, child_name, child_byte_size,
2840
child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
2841
child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
2842
language_flags);
2843
}
2844
2845
// In case of incomplete child compiler type, use the pointee type and try
2846
// to recreate a new ValueObjectChild using it.
2847
if (!m_deref_valobj) {
2848
// FIXME(#59012): C++ stdlib formatters break with incomplete types (e.g.
2849
// `std::vector<int> &`). Remove ObjC restriction once that's resolved.
2850
if (Language::LanguageIsObjC(GetPreferredDisplayLanguage()) &&
2851
HasSyntheticValue()) {
2852
child_compiler_type = compiler_type.GetPointeeType();
2853
2854
if (child_compiler_type) {
2855
ConstString child_name;
2856
if (!child_name_str.empty())
2857
child_name.SetCString(child_name_str.c_str());
2858
2859
m_deref_valobj = new ValueObjectChild(
2860
*this, child_compiler_type, child_name, child_byte_size,
2861
child_byte_offset, child_bitfield_bit_size,
2862
child_bitfield_bit_offset, child_is_base_class,
2863
child_is_deref_of_parent, eAddressTypeInvalid, language_flags);
2864
}
2865
}
2866
}
2867
2868
} else if (HasSyntheticValue()) {
2869
m_deref_valobj =
2870
GetSyntheticValue()->GetChildMemberWithName("$$dereference$$").get();
2871
} else if (IsSynthetic()) {
2872
m_deref_valobj = GetChildMemberWithName("$$dereference$$").get();
2873
}
2874
2875
if (m_deref_valobj) {
2876
error.Clear();
2877
return m_deref_valobj->GetSP();
2878
} else {
2879
StreamString strm;
2880
GetExpressionPath(strm);
2881
2882
if (is_pointer_or_reference_type)
2883
error.SetErrorStringWithFormat("dereference failed: (%s) %s",
2884
GetTypeName().AsCString("<invalid type>"),
2885
strm.GetData());
2886
else
2887
error.SetErrorStringWithFormat("not a pointer or reference type: (%s) %s",
2888
GetTypeName().AsCString("<invalid type>"),
2889
strm.GetData());
2890
return ValueObjectSP();
2891
}
2892
}
2893
2894
ValueObjectSP ValueObject::AddressOf(Status &error) {
2895
if (m_addr_of_valobj_sp)
2896
return m_addr_of_valobj_sp;
2897
2898
AddressType address_type = eAddressTypeInvalid;
2899
const bool scalar_is_load_address = false;
2900
addr_t addr = GetAddressOf(scalar_is_load_address, &address_type);
2901
error.Clear();
2902
if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {
2903
switch (address_type) {
2904
case eAddressTypeInvalid: {
2905
StreamString expr_path_strm;
2906
GetExpressionPath(expr_path_strm);
2907
error.SetErrorStringWithFormat("'%s' is not in memory",
2908
expr_path_strm.GetData());
2909
} break;
2910
2911
case eAddressTypeFile:
2912
case eAddressTypeLoad: {
2913
CompilerType compiler_type = GetCompilerType();
2914
if (compiler_type) {
2915
std::string name(1, '&');
2916
name.append(m_name.AsCString(""));
2917
ExecutionContext exe_ctx(GetExecutionContextRef());
2918
m_addr_of_valobj_sp = ValueObjectConstResult::Create(
2919
exe_ctx.GetBestExecutionContextScope(),
2920
compiler_type.GetPointerType(), ConstString(name.c_str()), addr,
2921
eAddressTypeInvalid, m_data.GetAddressByteSize());
2922
}
2923
} break;
2924
default:
2925
break;
2926
}
2927
} else {
2928
StreamString expr_path_strm;
2929
GetExpressionPath(expr_path_strm);
2930
error.SetErrorStringWithFormat("'%s' doesn't have a valid address",
2931
expr_path_strm.GetData());
2932
}
2933
2934
return m_addr_of_valobj_sp;
2935
}
2936
2937
ValueObjectSP ValueObject::DoCast(const CompilerType &compiler_type) {
2938
return ValueObjectCast::Create(*this, GetName(), compiler_type);
2939
}
2940
2941
ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {
2942
// Only allow casts if the original type is equal or larger than the cast
2943
// type, unless we know this is a load address. Getting the size wrong for
2944
// a host side storage could leak lldb memory, so we absolutely want to
2945
// prevent that. We may not always get the right value, for instance if we
2946
// have an expression result value that's copied into a storage location in
2947
// the target may not have copied enough memory. I'm not trying to fix that
2948
// here, I'm just making Cast from a smaller to a larger possible in all the
2949
// cases where that doesn't risk making a Value out of random lldb memory.
2950
// You have to check the ValueObject's Value for the address types, since
2951
// ValueObjects that use live addresses will tell you they fetch data from the
2952
// live address, but once they are made, they actually don't.
2953
// FIXME: Can we make ValueObject's with a live address fetch "more data" from
2954
// the live address if it is still valid?
2955
2956
Status error;
2957
CompilerType my_type = GetCompilerType();
2958
2959
ExecutionContextScope *exe_scope
2960
= ExecutionContext(GetExecutionContextRef())
2961
.GetBestExecutionContextScope();
2962
if (compiler_type.GetByteSize(exe_scope)
2963
<= GetCompilerType().GetByteSize(exe_scope)
2964
|| m_value.GetValueType() == Value::ValueType::LoadAddress)
2965
return DoCast(compiler_type);
2966
2967
error.SetErrorString("Can only cast to a type that is equal to or smaller "
2968
"than the orignal type.");
2969
2970
return ValueObjectConstResult::Create(
2971
ExecutionContext(GetExecutionContextRef()).GetBestExecutionContextScope(),
2972
error);
2973
}
2974
2975
lldb::ValueObjectSP ValueObject::Clone(ConstString new_name) {
2976
return ValueObjectCast::Create(*this, new_name, GetCompilerType());
2977
}
2978
2979
ValueObjectSP ValueObject::CastPointerType(const char *name,
2980
CompilerType &compiler_type) {
2981
ValueObjectSP valobj_sp;
2982
AddressType address_type;
2983
addr_t ptr_value = GetPointerValue(&address_type);
2984
2985
if (ptr_value != LLDB_INVALID_ADDRESS) {
2986
Address ptr_addr(ptr_value);
2987
ExecutionContext exe_ctx(GetExecutionContextRef());
2988
valobj_sp = ValueObjectMemory::Create(
2989
exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, compiler_type);
2990
}
2991
return valobj_sp;
2992
}
2993
2994
ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {
2995
ValueObjectSP valobj_sp;
2996
AddressType address_type;
2997
addr_t ptr_value = GetPointerValue(&address_type);
2998
2999
if (ptr_value != LLDB_INVALID_ADDRESS) {
3000
Address ptr_addr(ptr_value);
3001
ExecutionContext exe_ctx(GetExecutionContextRef());
3002
valobj_sp = ValueObjectMemory::Create(
3003
exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, type_sp);
3004
}
3005
return valobj_sp;
3006
}
3007
3008
lldb::addr_t ValueObject::GetLoadAddress() {
3009
lldb::addr_t addr_value = LLDB_INVALID_ADDRESS;
3010
if (auto target_sp = GetTargetSP()) {
3011
const bool scalar_is_load_address = true;
3012
AddressType addr_type;
3013
addr_value = GetAddressOf(scalar_is_load_address, &addr_type);
3014
if (addr_type == eAddressTypeFile) {
3015
lldb::ModuleSP module_sp(GetModule());
3016
if (!module_sp)
3017
addr_value = LLDB_INVALID_ADDRESS;
3018
else {
3019
Address tmp_addr;
3020
module_sp->ResolveFileAddress(addr_value, tmp_addr);
3021
addr_value = tmp_addr.GetLoadAddress(target_sp.get());
3022
}
3023
} else if (addr_type == eAddressTypeHost ||
3024
addr_type == eAddressTypeInvalid)
3025
addr_value = LLDB_INVALID_ADDRESS;
3026
}
3027
return addr_value;
3028
}
3029
3030
llvm::Expected<lldb::ValueObjectSP> ValueObject::CastDerivedToBaseType(
3031
CompilerType type, const llvm::ArrayRef<uint32_t> &base_type_indices) {
3032
// Make sure the starting type and the target type are both valid for this
3033
// type of cast; otherwise return the shared pointer to the original
3034
// (unchanged) ValueObject.
3035
if (!type.IsPointerType() && !type.IsReferenceType())
3036
return llvm::make_error<llvm::StringError>(
3037
"Invalid target type: should be a pointer or a reference",
3038
llvm::inconvertibleErrorCode());
3039
3040
CompilerType start_type = GetCompilerType();
3041
if (start_type.IsReferenceType())
3042
start_type = start_type.GetNonReferenceType();
3043
3044
auto target_record_type =
3045
type.IsPointerType() ? type.GetPointeeType() : type.GetNonReferenceType();
3046
auto start_record_type =
3047
start_type.IsPointerType() ? start_type.GetPointeeType() : start_type;
3048
3049
if (!target_record_type.IsRecordType() || !start_record_type.IsRecordType())
3050
return llvm::make_error<llvm::StringError>(
3051
"Underlying start & target types should be record types",
3052
llvm::inconvertibleErrorCode());
3053
3054
if (target_record_type.CompareTypes(start_record_type))
3055
return llvm::make_error<llvm::StringError>(
3056
"Underlying start & target types should be different",
3057
llvm::inconvertibleErrorCode());
3058
3059
if (base_type_indices.empty())
3060
return llvm::make_error<llvm::StringError>(
3061
"Children sequence must be non-empty", llvm::inconvertibleErrorCode());
3062
3063
// Both the starting & target types are valid for the cast, and the list of
3064
// base class indices is non-empty, so we can proceed with the cast.
3065
3066
lldb::TargetSP target = GetTargetSP();
3067
// The `value` can be a pointer, but GetChildAtIndex works for pointers too.
3068
lldb::ValueObjectSP inner_value = GetSP();
3069
3070
for (const uint32_t i : base_type_indices)
3071
// Create synthetic value if needed.
3072
inner_value =
3073
inner_value->GetChildAtIndex(i, /*can_create_synthetic*/ true);
3074
3075
// At this point type of `inner_value` should be the dereferenced target
3076
// type.
3077
CompilerType inner_value_type = inner_value->GetCompilerType();
3078
if (type.IsPointerType()) {
3079
if (!inner_value_type.CompareTypes(type.GetPointeeType()))
3080
return llvm::make_error<llvm::StringError>(
3081
"casted value doesn't match the desired type",
3082
llvm::inconvertibleErrorCode());
3083
3084
uintptr_t addr = inner_value->GetLoadAddress();
3085
llvm::StringRef name = "";
3086
ExecutionContext exe_ctx(target.get(), false);
3087
return ValueObject::CreateValueObjectFromAddress(name, addr, exe_ctx, type,
3088
/* do deref */ false);
3089
}
3090
3091
// At this point the target type should be a reference.
3092
if (!inner_value_type.CompareTypes(type.GetNonReferenceType()))
3093
return llvm::make_error<llvm::StringError>(
3094
"casted value doesn't match the desired type",
3095
llvm::inconvertibleErrorCode());
3096
3097
return lldb::ValueObjectSP(inner_value->Cast(type.GetNonReferenceType()));
3098
}
3099
3100
llvm::Expected<lldb::ValueObjectSP>
3101
ValueObject::CastBaseToDerivedType(CompilerType type, uint64_t offset) {
3102
// Make sure the starting type and the target type are both valid for this
3103
// type of cast; otherwise return the shared pointer to the original
3104
// (unchanged) ValueObject.
3105
if (!type.IsPointerType() && !type.IsReferenceType())
3106
return llvm::make_error<llvm::StringError>(
3107
"Invalid target type: should be a pointer or a reference",
3108
llvm::inconvertibleErrorCode());
3109
3110
CompilerType start_type = GetCompilerType();
3111
if (start_type.IsReferenceType())
3112
start_type = start_type.GetNonReferenceType();
3113
3114
auto target_record_type =
3115
type.IsPointerType() ? type.GetPointeeType() : type.GetNonReferenceType();
3116
auto start_record_type =
3117
start_type.IsPointerType() ? start_type.GetPointeeType() : start_type;
3118
3119
if (!target_record_type.IsRecordType() || !start_record_type.IsRecordType())
3120
return llvm::make_error<llvm::StringError>(
3121
"Underlying start & target types should be record types",
3122
llvm::inconvertibleErrorCode());
3123
3124
if (target_record_type.CompareTypes(start_record_type))
3125
return llvm::make_error<llvm::StringError>(
3126
"Underlying start & target types should be different",
3127
llvm::inconvertibleErrorCode());
3128
3129
CompilerType virtual_base;
3130
if (target_record_type.IsVirtualBase(start_record_type, &virtual_base)) {
3131
if (!virtual_base.IsValid())
3132
return llvm::make_error<llvm::StringError>(
3133
"virtual base should be valid", llvm::inconvertibleErrorCode());
3134
return llvm::make_error<llvm::StringError>(
3135
llvm::Twine("cannot cast " + start_type.TypeDescription() + " to " +
3136
type.TypeDescription() + " via virtual base " +
3137
virtual_base.TypeDescription()),
3138
llvm::inconvertibleErrorCode());
3139
}
3140
3141
// Both the starting & target types are valid for the cast, so we can
3142
// proceed with the cast.
3143
3144
lldb::TargetSP target = GetTargetSP();
3145
auto pointer_type =
3146
type.IsPointerType() ? type : type.GetNonReferenceType().GetPointerType();
3147
3148
uintptr_t addr =
3149
type.IsPointerType() ? GetValueAsUnsigned(0) : GetLoadAddress();
3150
3151
llvm::StringRef name = "";
3152
ExecutionContext exe_ctx(target.get(), false);
3153
lldb::ValueObjectSP value = ValueObject::CreateValueObjectFromAddress(
3154
name, addr - offset, exe_ctx, pointer_type, /* do_deref */ false);
3155
3156
if (type.IsPointerType())
3157
return value;
3158
3159
// At this point the target type is a reference. Since `value` is a pointer,
3160
// it has to be dereferenced.
3161
Status error;
3162
return value->Dereference(error);
3163
}
3164
3165
lldb::ValueObjectSP ValueObject::CastToBasicType(CompilerType type) {
3166
bool is_scalar = GetCompilerType().IsScalarType();
3167
bool is_enum = GetCompilerType().IsEnumerationType();
3168
bool is_pointer =
3169
GetCompilerType().IsPointerType() || GetCompilerType().IsNullPtrType();
3170
bool is_float = GetCompilerType().IsFloat();
3171
bool is_integer = GetCompilerType().IsInteger();
3172
3173
if (!type.IsScalarType()) {
3174
m_error.SetErrorString("target type must be a scalar");
3175
return GetSP();
3176
}
3177
3178
if (!is_scalar && !is_enum && !is_pointer) {
3179
m_error.SetErrorString("argument must be a scalar, enum, or pointer");
3180
return GetSP();
3181
}
3182
3183
lldb::TargetSP target = GetTargetSP();
3184
uint64_t type_byte_size = 0;
3185
uint64_t val_byte_size = 0;
3186
if (auto temp = type.GetByteSize(target.get()))
3187
type_byte_size = temp.value();
3188
if (auto temp = GetCompilerType().GetByteSize(target.get()))
3189
val_byte_size = temp.value();
3190
3191
if (is_pointer) {
3192
if (!type.IsInteger() && !type.IsBoolean()) {
3193
m_error.SetErrorString("target type must be an integer or boolean");
3194
return GetSP();
3195
}
3196
if (!type.IsBoolean() && type_byte_size < val_byte_size) {
3197
m_error.SetErrorString(
3198
"target type cannot be smaller than the pointer type");
3199
return GetSP();
3200
}
3201
}
3202
3203
if (type.IsBoolean()) {
3204
if (!is_scalar || is_integer)
3205
return ValueObject::CreateValueObjectFromBool(
3206
target, GetValueAsUnsigned(0) != 0, "result");
3207
else if (is_scalar && is_float) {
3208
auto float_value_or_err = GetValueAsAPFloat();
3209
if (float_value_or_err)
3210
return ValueObject::CreateValueObjectFromBool(
3211
target, !float_value_or_err->isZero(), "result");
3212
else {
3213
m_error.SetErrorStringWithFormat(
3214
"cannot get value as APFloat: %s",
3215
llvm::toString(float_value_or_err.takeError()).c_str());
3216
return GetSP();
3217
}
3218
}
3219
}
3220
3221
if (type.IsInteger()) {
3222
if (!is_scalar || is_integer) {
3223
auto int_value_or_err = GetValueAsAPSInt();
3224
if (int_value_or_err) {
3225
// Get the value as APSInt and extend or truncate it to the requested
3226
// size.
3227
llvm::APSInt ext =
3228
int_value_or_err->extOrTrunc(type_byte_size * CHAR_BIT);
3229
return ValueObject::CreateValueObjectFromAPInt(target, ext, type,
3230
"result");
3231
} else {
3232
m_error.SetErrorStringWithFormat(
3233
"cannot get value as APSInt: %s",
3234
llvm::toString(int_value_or_err.takeError()).c_str());
3235
;
3236
return GetSP();
3237
}
3238
} else if (is_scalar && is_float) {
3239
llvm::APSInt integer(type_byte_size * CHAR_BIT, !type.IsSigned());
3240
bool is_exact;
3241
auto float_value_or_err = GetValueAsAPFloat();
3242
if (float_value_or_err) {
3243
llvm::APFloatBase::opStatus status =
3244
float_value_or_err->convertToInteger(
3245
integer, llvm::APFloat::rmTowardZero, &is_exact);
3246
3247
// Casting floating point values that are out of bounds of the target
3248
// type is undefined behaviour.
3249
if (status & llvm::APFloatBase::opInvalidOp) {
3250
m_error.SetErrorStringWithFormat(
3251
"invalid type cast detected: %s",
3252
llvm::toString(float_value_or_err.takeError()).c_str());
3253
return GetSP();
3254
}
3255
return ValueObject::CreateValueObjectFromAPInt(target, integer, type,
3256
"result");
3257
}
3258
}
3259
}
3260
3261
if (type.IsFloat()) {
3262
if (!is_scalar) {
3263
auto int_value_or_err = GetValueAsAPSInt();
3264
if (int_value_or_err) {
3265
llvm::APSInt ext =
3266
int_value_or_err->extOrTrunc(type_byte_size * CHAR_BIT);
3267
Scalar scalar_int(ext);
3268
llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(
3269
type.GetCanonicalType().GetBasicTypeEnumeration());
3270
return ValueObject::CreateValueObjectFromAPFloat(target, f, type,
3271
"result");
3272
} else {
3273
m_error.SetErrorStringWithFormat(
3274
"cannot get value as APSInt: %s",
3275
llvm::toString(int_value_or_err.takeError()).c_str());
3276
return GetSP();
3277
}
3278
} else {
3279
if (is_integer) {
3280
auto int_value_or_err = GetValueAsAPSInt();
3281
if (int_value_or_err) {
3282
Scalar scalar_int(*int_value_or_err);
3283
llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(
3284
type.GetCanonicalType().GetBasicTypeEnumeration());
3285
return ValueObject::CreateValueObjectFromAPFloat(target, f, type,
3286
"result");
3287
} else {
3288
m_error.SetErrorStringWithFormat(
3289
"cannot get value as APSInt: %s",
3290
llvm::toString(int_value_or_err.takeError()).c_str());
3291
return GetSP();
3292
}
3293
}
3294
if (is_float) {
3295
auto float_value_or_err = GetValueAsAPFloat();
3296
if (float_value_or_err) {
3297
Scalar scalar_float(*float_value_or_err);
3298
llvm::APFloat f = scalar_float.CreateAPFloatFromAPFloat(
3299
type.GetCanonicalType().GetBasicTypeEnumeration());
3300
return ValueObject::CreateValueObjectFromAPFloat(target, f, type,
3301
"result");
3302
} else {
3303
m_error.SetErrorStringWithFormat(
3304
"cannot get value as APFloat: %s",
3305
llvm::toString(float_value_or_err.takeError()).c_str());
3306
return GetSP();
3307
}
3308
}
3309
}
3310
}
3311
3312
m_error.SetErrorString("Unable to perform requested cast");
3313
return GetSP();
3314
}
3315
3316
lldb::ValueObjectSP ValueObject::CastToEnumType(CompilerType type) {
3317
bool is_enum = GetCompilerType().IsEnumerationType();
3318
bool is_integer = GetCompilerType().IsInteger();
3319
bool is_float = GetCompilerType().IsFloat();
3320
3321
if (!is_enum && !is_integer && !is_float) {
3322
m_error.SetErrorString("argument must be an integer, a float, or an enum");
3323
return GetSP();
3324
}
3325
3326
if (!type.IsEnumerationType()) {
3327
m_error.SetErrorString("target type must be an enum");
3328
return GetSP();
3329
}
3330
3331
lldb::TargetSP target = GetTargetSP();
3332
uint64_t byte_size = 0;
3333
if (auto temp = type.GetByteSize(target.get()))
3334
byte_size = temp.value();
3335
3336
if (is_float) {
3337
llvm::APSInt integer(byte_size * CHAR_BIT, !type.IsSigned());
3338
bool is_exact;
3339
auto value_or_err = GetValueAsAPFloat();
3340
if (value_or_err) {
3341
llvm::APFloatBase::opStatus status = value_or_err->convertToInteger(
3342
integer, llvm::APFloat::rmTowardZero, &is_exact);
3343
3344
// Casting floating point values that are out of bounds of the target
3345
// type is undefined behaviour.
3346
if (status & llvm::APFloatBase::opInvalidOp) {
3347
m_error.SetErrorStringWithFormat(
3348
"invalid type cast detected: %s",
3349
llvm::toString(value_or_err.takeError()).c_str());
3350
return GetSP();
3351
}
3352
return ValueObject::CreateValueObjectFromAPInt(target, integer, type,
3353
"result");
3354
} else {
3355
m_error.SetErrorString("cannot get value as APFloat");
3356
return GetSP();
3357
}
3358
} else {
3359
// Get the value as APSInt and extend or truncate it to the requested size.
3360
auto value_or_err = GetValueAsAPSInt();
3361
if (value_or_err) {
3362
llvm::APSInt ext = value_or_err->extOrTrunc(byte_size * CHAR_BIT);
3363
return ValueObject::CreateValueObjectFromAPInt(target, ext, type,
3364
"result");
3365
} else {
3366
m_error.SetErrorStringWithFormat(
3367
"cannot get value as APSInt: %s",
3368
llvm::toString(value_or_err.takeError()).c_str());
3369
return GetSP();
3370
}
3371
}
3372
m_error.SetErrorString("Cannot perform requested cast");
3373
return GetSP();
3374
}
3375
3376
ValueObject::EvaluationPoint::EvaluationPoint() : m_mod_id(), m_exe_ctx_ref() {}
3377
3378
ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope,
3379
bool use_selected)
3380
: m_mod_id(), m_exe_ctx_ref() {
3381
ExecutionContext exe_ctx(exe_scope);
3382
TargetSP target_sp(exe_ctx.GetTargetSP());
3383
if (target_sp) {
3384
m_exe_ctx_ref.SetTargetSP(target_sp);
3385
ProcessSP process_sp(exe_ctx.GetProcessSP());
3386
if (!process_sp)
3387
process_sp = target_sp->GetProcessSP();
3388
3389
if (process_sp) {
3390
m_mod_id = process_sp->GetModID();
3391
m_exe_ctx_ref.SetProcessSP(process_sp);
3392
3393
ThreadSP thread_sp(exe_ctx.GetThreadSP());
3394
3395
if (!thread_sp) {
3396
if (use_selected)
3397
thread_sp = process_sp->GetThreadList().GetSelectedThread();
3398
}
3399
3400
if (thread_sp) {
3401
m_exe_ctx_ref.SetThreadSP(thread_sp);
3402
3403
StackFrameSP frame_sp(exe_ctx.GetFrameSP());
3404
if (!frame_sp) {
3405
if (use_selected)
3406
frame_sp = thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);
3407
}
3408
if (frame_sp)
3409
m_exe_ctx_ref.SetFrameSP(frame_sp);
3410
}
3411
}
3412
}
3413
}
3414
3415
ValueObject::EvaluationPoint::EvaluationPoint(
3416
const ValueObject::EvaluationPoint &rhs)
3417
: m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref) {}
3418
3419
ValueObject::EvaluationPoint::~EvaluationPoint() = default;
3420
3421
// This function checks the EvaluationPoint against the current process state.
3422
// If the current state matches the evaluation point, or the evaluation point
3423
// is already invalid, then we return false, meaning "no change". If the
3424
// current state is different, we update our state, and return true meaning
3425
// "yes, change". If we did see a change, we also set m_needs_update to true,
3426
// so future calls to NeedsUpdate will return true. exe_scope will be set to
3427
// the current execution context scope.
3428
3429
bool ValueObject::EvaluationPoint::SyncWithProcessState(
3430
bool accept_invalid_exe_ctx) {
3431
// Start with the target, if it is NULL, then we're obviously not going to
3432
// get any further:
3433
const bool thread_and_frame_only_if_stopped = true;
3434
ExecutionContext exe_ctx(
3435
m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
3436
3437
if (exe_ctx.GetTargetPtr() == nullptr)
3438
return false;
3439
3440
// If we don't have a process nothing can change.
3441
Process *process = exe_ctx.GetProcessPtr();
3442
if (process == nullptr)
3443
return false;
3444
3445
// If our stop id is the current stop ID, nothing has changed:
3446
ProcessModID current_mod_id = process->GetModID();
3447
3448
// If the current stop id is 0, either we haven't run yet, or the process
3449
// state has been cleared. In either case, we aren't going to be able to sync
3450
// with the process state.
3451
if (current_mod_id.GetStopID() == 0)
3452
return false;
3453
3454
bool changed = false;
3455
const bool was_valid = m_mod_id.IsValid();
3456
if (was_valid) {
3457
if (m_mod_id == current_mod_id) {
3458
// Everything is already up to date in this object, no need to update the
3459
// execution context scope.
3460
changed = false;
3461
} else {
3462
m_mod_id = current_mod_id;
3463
m_needs_update = true;
3464
changed = true;
3465
}
3466
}
3467
3468
// Now re-look up the thread and frame in case the underlying objects have
3469
// gone away & been recreated. That way we'll be sure to return a valid
3470
// exe_scope. If we used to have a thread or a frame but can't find it
3471
// anymore, then mark ourselves as invalid.
3472
3473
if (!accept_invalid_exe_ctx) {
3474
if (m_exe_ctx_ref.HasThreadRef()) {
3475
ThreadSP thread_sp(m_exe_ctx_ref.GetThreadSP());
3476
if (thread_sp) {
3477
if (m_exe_ctx_ref.HasFrameRef()) {
3478
StackFrameSP frame_sp(m_exe_ctx_ref.GetFrameSP());
3479
if (!frame_sp) {
3480
// We used to have a frame, but now it is gone
3481
SetInvalid();
3482
changed = was_valid;
3483
}
3484
}
3485
} else {
3486
// We used to have a thread, but now it is gone
3487
SetInvalid();
3488
changed = was_valid;
3489
}
3490
}
3491
}
3492
3493
return changed;
3494
}
3495
3496
void ValueObject::EvaluationPoint::SetUpdated() {
3497
ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
3498
if (process_sp)
3499
m_mod_id = process_sp->GetModID();
3500
m_needs_update = false;
3501
}
3502
3503
void ValueObject::ClearUserVisibleData(uint32_t clear_mask) {
3504
if ((clear_mask & eClearUserVisibleDataItemsValue) ==
3505
eClearUserVisibleDataItemsValue)
3506
m_value_str.clear();
3507
3508
if ((clear_mask & eClearUserVisibleDataItemsLocation) ==
3509
eClearUserVisibleDataItemsLocation)
3510
m_location_str.clear();
3511
3512
if ((clear_mask & eClearUserVisibleDataItemsSummary) ==
3513
eClearUserVisibleDataItemsSummary)
3514
m_summary_str.clear();
3515
3516
if ((clear_mask & eClearUserVisibleDataItemsDescription) ==
3517
eClearUserVisibleDataItemsDescription)
3518
m_object_desc_str.clear();
3519
3520
if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) ==
3521
eClearUserVisibleDataItemsSyntheticChildren) {
3522
if (m_synthetic_value)
3523
m_synthetic_value = nullptr;
3524
}
3525
}
3526
3527
SymbolContextScope *ValueObject::GetSymbolContextScope() {
3528
if (m_parent) {
3529
if (!m_parent->IsPointerOrReferenceType())
3530
return m_parent->GetSymbolContextScope();
3531
}
3532
return nullptr;
3533
}
3534
3535
lldb::ValueObjectSP
3536
ValueObject::CreateValueObjectFromExpression(llvm::StringRef name,
3537
llvm::StringRef expression,
3538
const ExecutionContext &exe_ctx) {
3539
return CreateValueObjectFromExpression(name, expression, exe_ctx,
3540
EvaluateExpressionOptions());
3541
}
3542
3543
lldb::ValueObjectSP ValueObject::CreateValueObjectFromExpression(
3544
llvm::StringRef name, llvm::StringRef expression,
3545
const ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options) {
3546
lldb::ValueObjectSP retval_sp;
3547
lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
3548
if (!target_sp)
3549
return retval_sp;
3550
if (expression.empty())
3551
return retval_sp;
3552
target_sp->EvaluateExpression(expression, exe_ctx.GetFrameSP().get(),
3553
retval_sp, options);
3554
if (retval_sp && !name.empty())
3555
retval_sp->SetName(ConstString(name));
3556
return retval_sp;
3557
}
3558
3559
lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress(
3560
llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
3561
CompilerType type, bool do_deref) {
3562
if (type) {
3563
CompilerType pointer_type(type.GetPointerType());
3564
if (!do_deref)
3565
pointer_type = type;
3566
if (pointer_type) {
3567
lldb::DataBufferSP buffer(
3568
new lldb_private::DataBufferHeap(&address, sizeof(lldb::addr_t)));
3569
lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(
3570
exe_ctx.GetBestExecutionContextScope(), pointer_type,
3571
ConstString(name), buffer, exe_ctx.GetByteOrder(),
3572
exe_ctx.GetAddressByteSize()));
3573
if (ptr_result_valobj_sp) {
3574
if (do_deref)
3575
ptr_result_valobj_sp->GetValue().SetValueType(
3576
Value::ValueType::LoadAddress);
3577
Status err;
3578
if (do_deref)
3579
ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
3580
if (ptr_result_valobj_sp && !name.empty())
3581
ptr_result_valobj_sp->SetName(ConstString(name));
3582
}
3583
return ptr_result_valobj_sp;
3584
}
3585
}
3586
return lldb::ValueObjectSP();
3587
}
3588
3589
lldb::ValueObjectSP ValueObject::CreateValueObjectFromData(
3590
llvm::StringRef name, const DataExtractor &data,
3591
const ExecutionContext &exe_ctx, CompilerType type) {
3592
lldb::ValueObjectSP new_value_sp;
3593
new_value_sp = ValueObjectConstResult::Create(
3594
exe_ctx.GetBestExecutionContextScope(), type, ConstString(name), data,
3595
LLDB_INVALID_ADDRESS);
3596
new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
3597
if (new_value_sp && !name.empty())
3598
new_value_sp->SetName(ConstString(name));
3599
return new_value_sp;
3600
}
3601
3602
lldb::ValueObjectSP
3603
ValueObject::CreateValueObjectFromAPInt(lldb::TargetSP target,
3604
const llvm::APInt &v, CompilerType type,
3605
llvm::StringRef name) {
3606
ExecutionContext exe_ctx(target.get(), false);
3607
uint64_t byte_size = 0;
3608
if (auto temp = type.GetByteSize(target.get()))
3609
byte_size = temp.value();
3610
lldb::DataExtractorSP data_sp = std::make_shared<DataExtractor>(
3611
reinterpret_cast<const void *>(v.getRawData()), byte_size,
3612
exe_ctx.GetByteOrder(), exe_ctx.GetAddressByteSize());
3613
return ValueObject::CreateValueObjectFromData(name, *data_sp, exe_ctx, type);
3614
}
3615
3616
lldb::ValueObjectSP ValueObject::CreateValueObjectFromAPFloat(
3617
lldb::TargetSP target, const llvm::APFloat &v, CompilerType type,
3618
llvm::StringRef name) {
3619
return CreateValueObjectFromAPInt(target, v.bitcastToAPInt(), type, name);
3620
}
3621
3622
lldb::ValueObjectSP
3623
ValueObject::CreateValueObjectFromBool(lldb::TargetSP target, bool value,
3624
llvm::StringRef name) {
3625
CompilerType target_type;
3626
if (target) {
3627
for (auto type_system_sp : target->GetScratchTypeSystems())
3628
if (auto compiler_type =
3629
type_system_sp->GetBasicTypeFromAST(lldb::eBasicTypeBool)) {
3630
target_type = compiler_type;
3631
break;
3632
}
3633
}
3634
ExecutionContext exe_ctx(target.get(), false);
3635
uint64_t byte_size = 0;
3636
if (auto temp = target_type.GetByteSize(target.get()))
3637
byte_size = temp.value();
3638
lldb::DataExtractorSP data_sp = std::make_shared<DataExtractor>(
3639
reinterpret_cast<const void *>(&value), byte_size, exe_ctx.GetByteOrder(),
3640
exe_ctx.GetAddressByteSize());
3641
return ValueObject::CreateValueObjectFromData(name, *data_sp, exe_ctx,
3642
target_type);
3643
}
3644
3645
lldb::ValueObjectSP ValueObject::CreateValueObjectFromNullptr(
3646
lldb::TargetSP target, CompilerType type, llvm::StringRef name) {
3647
if (!type.IsNullPtrType()) {
3648
lldb::ValueObjectSP ret_val;
3649
return ret_val;
3650
}
3651
uintptr_t zero = 0;
3652
ExecutionContext exe_ctx(target.get(), false);
3653
uint64_t byte_size = 0;
3654
if (auto temp = type.GetByteSize(target.get()))
3655
byte_size = temp.value();
3656
lldb::DataExtractorSP data_sp = std::make_shared<DataExtractor>(
3657
reinterpret_cast<const void *>(zero), byte_size, exe_ctx.GetByteOrder(),
3658
exe_ctx.GetAddressByteSize());
3659
return ValueObject::CreateValueObjectFromData(name, *data_sp, exe_ctx, type);
3660
}
3661
3662
ModuleSP ValueObject::GetModule() {
3663
ValueObject *root(GetRoot());
3664
if (root != this)
3665
return root->GetModule();
3666
return lldb::ModuleSP();
3667
}
3668
3669
ValueObject *ValueObject::GetRoot() {
3670
if (m_root)
3671
return m_root;
3672
return (m_root = FollowParentChain([](ValueObject *vo) -> bool {
3673
return (vo->m_parent != nullptr);
3674
}));
3675
}
3676
3677
ValueObject *
3678
ValueObject::FollowParentChain(std::function<bool(ValueObject *)> f) {
3679
ValueObject *vo = this;
3680
while (vo) {
3681
if (!f(vo))
3682
break;
3683
vo = vo->m_parent;
3684
}
3685
return vo;
3686
}
3687
3688
AddressType ValueObject::GetAddressTypeOfChildren() {
3689
if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) {
3690
ValueObject *root(GetRoot());
3691
if (root != this)
3692
return root->GetAddressTypeOfChildren();
3693
}
3694
return m_address_type_of_ptr_or_ref_children;
3695
}
3696
3697
lldb::DynamicValueType ValueObject::GetDynamicValueType() {
3698
ValueObject *with_dv_info = this;
3699
while (with_dv_info) {
3700
if (with_dv_info->HasDynamicValueTypeInfo())
3701
return with_dv_info->GetDynamicValueTypeImpl();
3702
with_dv_info = with_dv_info->m_parent;
3703
}
3704
return lldb::eNoDynamicValues;
3705
}
3706
3707
lldb::Format ValueObject::GetFormat() const {
3708
const ValueObject *with_fmt_info = this;
3709
while (with_fmt_info) {
3710
if (with_fmt_info->m_format != lldb::eFormatDefault)
3711
return with_fmt_info->m_format;
3712
with_fmt_info = with_fmt_info->m_parent;
3713
}
3714
return m_format;
3715
}
3716
3717
lldb::LanguageType ValueObject::GetPreferredDisplayLanguage() {
3718
lldb::LanguageType type = m_preferred_display_language;
3719
if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
3720
if (GetRoot()) {
3721
if (GetRoot() == this) {
3722
if (StackFrameSP frame_sp = GetFrameSP()) {
3723
const SymbolContext &sc(
3724
frame_sp->GetSymbolContext(eSymbolContextCompUnit));
3725
if (CompileUnit *cu = sc.comp_unit)
3726
type = cu->GetLanguage();
3727
}
3728
} else {
3729
type = GetRoot()->GetPreferredDisplayLanguage();
3730
}
3731
}
3732
}
3733
return (m_preferred_display_language = type); // only compute it once
3734
}
3735
3736
void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {
3737
if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
3738
SetPreferredDisplayLanguage(lt);
3739
}
3740
3741
bool ValueObject::CanProvideValue() {
3742
// we need to support invalid types as providers of values because some bare-
3743
// board debugging scenarios have no notion of types, but still manage to
3744
// have raw numeric values for things like registers. sigh.
3745
CompilerType type = GetCompilerType();
3746
return (!type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue));
3747
}
3748
3749
3750
3751
ValueObjectSP ValueObject::Persist() {
3752
if (!UpdateValueIfNeeded())
3753
return nullptr;
3754
3755
TargetSP target_sp(GetTargetSP());
3756
if (!target_sp)
3757
return nullptr;
3758
3759
PersistentExpressionState *persistent_state =
3760
target_sp->GetPersistentExpressionStateForLanguage(
3761
GetPreferredDisplayLanguage());
3762
3763
if (!persistent_state)
3764
return nullptr;
3765
3766
ConstString name = persistent_state->GetNextPersistentVariableName();
3767
3768
ValueObjectSP const_result_sp =
3769
ValueObjectConstResult::Create(target_sp.get(), GetValue(), name);
3770
3771
ExpressionVariableSP persistent_var_sp =
3772
persistent_state->CreatePersistentVariable(const_result_sp);
3773
persistent_var_sp->m_live_sp = persistent_var_sp->m_frozen_sp;
3774
persistent_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference;
3775
3776
return persistent_var_sp->GetValueObject();
3777
}
3778
3779
lldb::ValueObjectSP ValueObject::GetVTable() {
3780
return ValueObjectVTable::Create(*this);
3781
}
3782
3783