Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp
39587 views
1
//===-- ValueObjectConstResultImpl.cpp ------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "lldb/Core/ValueObjectConstResultImpl.h"
10
11
#include "lldb/Core/Value.h"
12
#include "lldb/Core/ValueObject.h"
13
#include "lldb/Core/ValueObjectConstResult.h"
14
#include "lldb/Core/ValueObjectConstResultCast.h"
15
#include "lldb/Core/ValueObjectConstResultChild.h"
16
#include "lldb/Symbol/CompilerType.h"
17
#include "lldb/Target/ExecutionContext.h"
18
#include "lldb/Utility/DataBufferHeap.h"
19
#include "lldb/Utility/Endian.h"
20
#include "lldb/Utility/LLDBLog.h"
21
#include "lldb/Utility/Log.h"
22
#include "lldb/Utility/Scalar.h"
23
24
#include <string>
25
26
namespace lldb_private {
27
class DataExtractor;
28
}
29
namespace lldb_private {
30
class Status;
31
}
32
33
using namespace lldb;
34
using namespace lldb_private;
35
36
ValueObjectConstResultImpl::ValueObjectConstResultImpl(
37
ValueObject *valobj, lldb::addr_t live_address)
38
: m_impl_backend(valobj), m_live_address(live_address),
39
m_live_address_type(eAddressTypeLoad),
40
m_address_of_backend() {}
41
42
lldb::ValueObjectSP ValueObjectConstResultImpl::Dereference(Status &error) {
43
if (m_impl_backend == nullptr)
44
return lldb::ValueObjectSP();
45
46
return m_impl_backend->ValueObject::Dereference(error);
47
}
48
49
ValueObject *ValueObjectConstResultImpl::CreateChildAtIndex(size_t idx) {
50
if (m_impl_backend == nullptr)
51
return nullptr;
52
53
m_impl_backend->UpdateValueIfNeeded(false);
54
55
bool omit_empty_base_classes = true;
56
bool ignore_array_bounds = false;
57
std::string child_name;
58
uint32_t child_byte_size = 0;
59
int32_t child_byte_offset = 0;
60
uint32_t child_bitfield_bit_size = 0;
61
uint32_t child_bitfield_bit_offset = 0;
62
bool child_is_base_class = false;
63
bool child_is_deref_of_parent = false;
64
uint64_t language_flags;
65
const bool transparent_pointers = true;
66
CompilerType compiler_type = m_impl_backend->GetCompilerType();
67
68
ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef());
69
70
auto child_compiler_type_or_err = compiler_type.GetChildCompilerTypeAtIndex(
71
&exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
72
ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
73
child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
74
child_is_deref_of_parent, m_impl_backend, language_flags);
75
76
// One might think we should check that the size of the children
77
// is always strictly positive, hence we could avoid creating a
78
// ValueObject if that's not the case, but it turns out there
79
// are languages out there which allow zero-size types with
80
// children (e.g. Swift).
81
if (!child_compiler_type_or_err || !child_compiler_type_or_err->IsValid()) {
82
LLDB_LOG_ERROR(GetLog(LLDBLog::Types),
83
child_compiler_type_or_err.takeError(),
84
"could not find child: {0}");
85
return nullptr;
86
}
87
88
lldb::addr_t child_live_addr = LLDB_INVALID_ADDRESS;
89
// Transfer the live address (with offset) to the child. But if
90
// the parent is a pointer, the live address is where that pointer
91
// value lives in memory, so the children live addresses aren't
92
// offsets from that value, they are just other load addresses that
93
// are recorded in the Value of the child ValueObjects.
94
if (m_live_address != LLDB_INVALID_ADDRESS && !compiler_type.IsPointerType())
95
child_live_addr = m_live_address + child_byte_offset;
96
97
return new ValueObjectConstResultChild(
98
*m_impl_backend, *child_compiler_type_or_err, ConstString(child_name),
99
child_byte_size, child_byte_offset, child_bitfield_bit_size,
100
child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent,
101
child_live_addr, language_flags);
102
}
103
104
ValueObject *
105
ValueObjectConstResultImpl::CreateSyntheticArrayMember(size_t idx) {
106
if (m_impl_backend == nullptr)
107
return nullptr;
108
109
m_impl_backend->UpdateValueIfNeeded(false);
110
111
bool omit_empty_base_classes = true;
112
bool ignore_array_bounds = true;
113
std::string child_name;
114
uint32_t child_byte_size = 0;
115
int32_t child_byte_offset = 0;
116
uint32_t child_bitfield_bit_size = 0;
117
uint32_t child_bitfield_bit_offset = 0;
118
bool child_is_base_class = false;
119
bool child_is_deref_of_parent = false;
120
uint64_t language_flags;
121
122
const bool transparent_pointers = false;
123
CompilerType compiler_type = m_impl_backend->GetCompilerType();
124
125
ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef());
126
127
auto child_compiler_type_or_err = compiler_type.GetChildCompilerTypeAtIndex(
128
&exe_ctx, 0, transparent_pointers, omit_empty_base_classes,
129
ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
130
child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
131
child_is_deref_of_parent, m_impl_backend, language_flags);
132
// One might think we should check that the size of the children
133
// is always strictly positive, hence we could avoid creating a
134
// ValueObject if that's not the case, but it turns out there
135
// are languages out there which allow zero-size types with
136
// children (e.g. Swift).
137
if (!child_compiler_type_or_err || !child_compiler_type_or_err->IsValid()) {
138
LLDB_LOG_ERROR(GetLog(LLDBLog::Types),
139
child_compiler_type_or_err.takeError(),
140
"could not find child: {0}");
141
return nullptr;
142
}
143
144
child_byte_offset += child_byte_size * idx;
145
146
lldb::addr_t child_live_addr = LLDB_INVALID_ADDRESS;
147
// Transfer the live address (with offset) to the child. But if
148
// the parent is a pointer, the live address is where that pointer
149
// value lives in memory, so the children live addresses aren't
150
// offsets from that value, they are just other load addresses that
151
// are recorded in the Value of the child ValueObjects.
152
if (m_live_address != LLDB_INVALID_ADDRESS && !compiler_type.IsPointerType())
153
child_live_addr = m_live_address + child_byte_offset;
154
return new ValueObjectConstResultChild(
155
*m_impl_backend, *child_compiler_type_or_err, ConstString(child_name),
156
child_byte_size, child_byte_offset, child_bitfield_bit_size,
157
child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent,
158
child_live_addr, language_flags);
159
}
160
161
lldb::ValueObjectSP ValueObjectConstResultImpl::GetSyntheticChildAtOffset(
162
uint32_t offset, const CompilerType &type, bool can_create,
163
ConstString name_const_str) {
164
if (m_impl_backend == nullptr)
165
return lldb::ValueObjectSP();
166
167
return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(
168
offset, type, can_create, name_const_str);
169
}
170
171
lldb::ValueObjectSP ValueObjectConstResultImpl::AddressOf(Status &error) {
172
if (m_address_of_backend.get() != nullptr)
173
return m_address_of_backend;
174
175
if (m_impl_backend == nullptr)
176
return lldb::ValueObjectSP();
177
if (m_live_address != LLDB_INVALID_ADDRESS) {
178
CompilerType compiler_type(m_impl_backend->GetCompilerType());
179
180
lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(
181
&m_live_address, sizeof(lldb::addr_t)));
182
183
std::string new_name("&");
184
new_name.append(m_impl_backend->GetName().AsCString(""));
185
ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef());
186
m_address_of_backend = ValueObjectConstResult::Create(
187
exe_ctx.GetBestExecutionContextScope(), compiler_type.GetPointerType(),
188
ConstString(new_name.c_str()), buffer, endian::InlHostByteOrder(),
189
exe_ctx.GetAddressByteSize());
190
191
m_address_of_backend->GetValue().SetValueType(Value::ValueType::Scalar);
192
m_address_of_backend->GetValue().GetScalar() = m_live_address;
193
194
return m_address_of_backend;
195
} else
196
return m_impl_backend->ValueObject::AddressOf(error);
197
}
198
199
lldb::ValueObjectSP
200
ValueObjectConstResultImpl::Cast(const CompilerType &compiler_type) {
201
if (m_impl_backend == nullptr)
202
return lldb::ValueObjectSP();
203
204
ValueObjectConstResultCast *result_cast =
205
new ValueObjectConstResultCast(*m_impl_backend, m_impl_backend->GetName(),
206
compiler_type, m_live_address);
207
return result_cast->GetSP();
208
}
209
210
lldb::addr_t
211
ValueObjectConstResultImpl::GetAddressOf(bool scalar_is_load_address,
212
AddressType *address_type) {
213
214
if (m_impl_backend == nullptr)
215
return 0;
216
217
if (m_live_address == LLDB_INVALID_ADDRESS) {
218
return m_impl_backend->ValueObject::GetAddressOf(scalar_is_load_address,
219
address_type);
220
}
221
222
if (address_type)
223
*address_type = m_live_address_type;
224
225
return m_live_address;
226
}
227
228
size_t ValueObjectConstResultImpl::GetPointeeData(DataExtractor &data,
229
uint32_t item_idx,
230
uint32_t item_count) {
231
if (m_impl_backend == nullptr)
232
return 0;
233
return m_impl_backend->ValueObject::GetPointeeData(data, item_idx,
234
item_count);
235
}
236
237