Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/MsvcStlSmartPointer.cpp
213845 views
1
//===-- MsvcStlSmartPointer.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 "Generic.h"
10
#include "MsvcStl.h"
11
12
#include "lldb/DataFormatters/FormattersHelpers.h"
13
#include "lldb/DataFormatters/TypeSynthetic.h"
14
15
using namespace lldb;
16
17
bool lldb_private::formatters::IsMsvcStlSmartPointer(ValueObject &valobj) {
18
if (auto valobj_sp = valobj.GetNonSyntheticValue())
19
return valobj_sp->GetChildMemberWithName("_Ptr") != nullptr;
20
21
return false;
22
}
23
24
bool lldb_private::formatters::MsvcStlSmartPointerSummaryProvider(
25
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
26
ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
27
if (!valobj_sp)
28
return false;
29
30
ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("_Ptr"));
31
ValueObjectSP ctrl_sp(valobj_sp->GetChildMemberWithName("_Rep"));
32
if (!ctrl_sp || !ptr_sp)
33
return false;
34
35
DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);
36
37
bool success;
38
uint64_t ctrl_addr = ctrl_sp->GetValueAsUnsigned(0, &success);
39
// Empty control field (expired)
40
if (!success || ctrl_addr == 0)
41
return true;
42
43
uint64_t uses = 0;
44
if (auto uses_sp = ctrl_sp->GetChildMemberWithName("_Uses")) {
45
bool success;
46
uses = uses_sp->GetValueAsUnsigned(0, &success);
47
if (!success)
48
return false;
49
50
stream.Printf(" strong=%" PRIu64, uses);
51
}
52
53
// _Weaks is the number of weak references - (_Uses != 0).
54
if (auto weak_count_sp = ctrl_sp->GetChildMemberWithName("_Weaks")) {
55
bool success;
56
uint64_t count = weak_count_sp->GetValueAsUnsigned(0, &success);
57
if (!success)
58
return false;
59
60
stream.Printf(" weak=%" PRIu64, count - (uses != 0));
61
}
62
63
return true;
64
}
65
66
namespace lldb_private {
67
namespace formatters {
68
69
class MsvcStlSmartPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
70
public:
71
MsvcStlSmartPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
72
73
llvm::Expected<uint32_t> CalculateNumChildren() override;
74
75
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
76
77
lldb::ChildCacheState Update() override;
78
79
llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
80
81
~MsvcStlSmartPointerSyntheticFrontEnd() override;
82
83
private:
84
ValueObject *m_ptr_obj = nullptr;
85
};
86
87
class MsvcStlUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
88
public:
89
MsvcStlUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
90
91
llvm::Expected<uint32_t> CalculateNumChildren() override;
92
93
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
94
95
lldb::ChildCacheState Update() override;
96
97
llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
98
99
private:
100
lldb::ValueObjectSP m_value_ptr_sp;
101
lldb::ValueObjectSP m_deleter_sp;
102
};
103
104
} // namespace formatters
105
} // namespace lldb_private
106
107
lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::
108
MsvcStlSmartPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
109
: SyntheticChildrenFrontEnd(*valobj_sp) {
110
if (valobj_sp)
111
Update();
112
}
113
114
llvm::Expected<uint32_t> lldb_private::formatters::
115
MsvcStlSmartPointerSyntheticFrontEnd::CalculateNumChildren() {
116
return (m_ptr_obj ? 1 : 0);
117
}
118
119
lldb::ValueObjectSP
120
lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::GetChildAtIndex(
121
uint32_t idx) {
122
if (!m_ptr_obj)
123
return lldb::ValueObjectSP();
124
125
ValueObjectSP valobj_sp = m_backend.GetSP();
126
if (!valobj_sp)
127
return lldb::ValueObjectSP();
128
129
if (idx == 0)
130
return m_ptr_obj->GetSP();
131
132
if (idx == 1) {
133
Status status;
134
ValueObjectSP value_sp = m_ptr_obj->Dereference(status);
135
if (status.Success())
136
return value_sp;
137
}
138
139
return lldb::ValueObjectSP();
140
}
141
142
lldb::ChildCacheState
143
lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::Update() {
144
m_ptr_obj = nullptr;
145
146
ValueObjectSP valobj_sp = m_backend.GetSP();
147
if (!valobj_sp)
148
return lldb::ChildCacheState::eRefetch;
149
150
auto ptr_obj_sp = valobj_sp->GetChildMemberWithName("_Ptr");
151
if (!ptr_obj_sp)
152
return lldb::ChildCacheState::eRefetch;
153
154
auto cast_ptr_sp = GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
155
if (!cast_ptr_sp)
156
return lldb::ChildCacheState::eRefetch;
157
158
m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();
159
return lldb::ChildCacheState::eRefetch;
160
}
161
162
llvm::Expected<size_t>
163
lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::
164
GetIndexOfChildWithName(ConstString name) {
165
if (name == "pointer")
166
return 0;
167
168
if (name == "object" || name == "$$dereference$$")
169
return 1;
170
171
return llvm::createStringError("Type has no child named '%s'",
172
name.AsCString());
173
}
174
175
lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::
176
~MsvcStlSmartPointerSyntheticFrontEnd() = default;
177
178
lldb_private::SyntheticChildrenFrontEnd *
179
lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEndCreator(
180
lldb::ValueObjectSP valobj_sp) {
181
return new MsvcStlSmartPointerSyntheticFrontEnd(valobj_sp);
182
}
183
184
bool lldb_private::formatters::IsMsvcStlUniquePtr(ValueObject &valobj) {
185
if (auto valobj_sp = valobj.GetNonSyntheticValue())
186
return valobj_sp->GetChildMemberWithName("_Mypair") != nullptr;
187
188
return false;
189
}
190
191
bool lldb_private::formatters::MsvcStlUniquePtrSummaryProvider(
192
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
193
ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
194
if (!valobj_sp)
195
return false;
196
197
ValueObjectSP ptr_sp(valobj_sp->GetChildAtNamePath({"_Mypair", "_Myval2"}));
198
if (!ptr_sp)
199
return false;
200
201
DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);
202
203
return true;
204
}
205
206
lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEnd::
207
MsvcStlUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
208
: SyntheticChildrenFrontEnd(*valobj_sp) {
209
if (valobj_sp)
210
Update();
211
}
212
213
llvm::Expected<uint32_t> lldb_private::formatters::
214
MsvcStlUniquePtrSyntheticFrontEnd::CalculateNumChildren() {
215
if (m_value_ptr_sp)
216
return m_deleter_sp ? 2 : 1;
217
return 0;
218
}
219
220
lldb::ValueObjectSP
221
lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEnd::GetChildAtIndex(
222
uint32_t idx) {
223
if (!m_value_ptr_sp)
224
return lldb::ValueObjectSP();
225
226
if (idx == 0)
227
return m_value_ptr_sp;
228
229
if (idx == 1)
230
return m_deleter_sp;
231
232
if (idx == 2) {
233
Status status;
234
auto value_sp = m_value_ptr_sp->Dereference(status);
235
if (status.Success()) {
236
return value_sp;
237
}
238
}
239
240
return lldb::ValueObjectSP();
241
}
242
243
lldb::ChildCacheState
244
lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEnd::Update() {
245
ValueObjectSP valobj_sp = m_backend.GetSP();
246
if (!valobj_sp)
247
return lldb::ChildCacheState::eRefetch;
248
249
ValueObjectSP pair_sp = valobj_sp->GetChildMemberWithName("_Mypair");
250
if (!pair_sp)
251
return lldb::ChildCacheState::eRefetch;
252
253
if (auto value_ptr_sp = pair_sp->GetChildMemberWithName("_Myval2"))
254
m_value_ptr_sp = value_ptr_sp->Clone(ConstString("pointer"));
255
256
// Only present if the deleter is non-empty
257
if (auto deleter_sp = pair_sp->GetChildMemberWithName("_Myval1"))
258
m_deleter_sp = deleter_sp->Clone(ConstString("deleter"));
259
260
return lldb::ChildCacheState::eRefetch;
261
}
262
263
llvm::Expected<size_t>
264
lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEnd::
265
GetIndexOfChildWithName(ConstString name) {
266
if (name == "pointer")
267
return 0;
268
if (name == "deleter")
269
return 1;
270
if (name == "obj" || name == "object" || name == "$$dereference$$")
271
return 2;
272
return llvm::createStringError("Type has no child named '%s'",
273
name.AsCString());
274
}
275
276
lldb_private::SyntheticChildrenFrontEnd *
277
lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEndCreator(
278
lldb::ValueObjectSP valobj_sp) {
279
return new MsvcStlUniquePtrSyntheticFrontEnd(valobj_sp);
280
}
281
282