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