LLDB mainline
MsvcStlSmartPointer.cpp
Go to the documentation of this file.
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
14#include "llvm/Support/ErrorExtras.h"
15
16using namespace lldb;
17
19 if (auto valobj_sp = valobj.GetNonSyntheticValue())
20 return valobj_sp->GetChildMemberWithName("_Ptr") != nullptr;
21
22 return false;
23}
24
26 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
27 ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
28 if (!valobj_sp)
29 return false;
30
31 ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("_Ptr"));
32 ValueObjectSP ctrl_sp(valobj_sp->GetChildMemberWithName("_Rep"));
33 if (!ctrl_sp || !ptr_sp)
34 return false;
35
36 DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);
37
38 bool success;
39 uint64_t ctrl_addr = ctrl_sp->GetValueAsUnsigned(0, &success);
40 // Empty control field (expired)
41 if (!success || ctrl_addr == 0)
42 return true;
43
44 uint64_t uses = 0;
45 if (auto uses_sp = ctrl_sp->GetChildMemberWithName("_Uses")) {
46 bool success;
47 uses = uses_sp->GetValueAsUnsigned(0, &success);
48 if (!success)
49 return false;
50
51 stream.Printf(" strong=%" PRIu64, uses);
52 }
53
54 // _Weaks is the number of weak references - (_Uses != 0).
55 if (auto weak_count_sp = ctrl_sp->GetChildMemberWithName("_Weaks")) {
56 bool success;
57 uint64_t count = weak_count_sp->GetValueAsUnsigned(0, &success);
58 if (!success)
59 return false;
60
61 stream.Printf(" weak=%" PRIu64, count - (uses != 0));
62 }
63
64 return true;
65}
66
67namespace lldb_private {
68namespace formatters {
69
71public:
73
74 llvm::Expected<uint32_t> CalculateNumChildren() override;
75
76 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
77
79
80 llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
81
83
84private:
86};
87
89public:
91
92 llvm::Expected<uint32_t> CalculateNumChildren() override;
93
94 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
95
97
98 llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
99
100private:
103};
104
105} // namespace formatters
106} // namespace lldb_private
107
114
119
122 uint32_t idx) {
123 if (!m_ptr_obj)
124 return lldb::ValueObjectSP();
125
126 ValueObjectSP valobj_sp = m_backend.GetSP();
127 if (!valobj_sp)
128 return lldb::ValueObjectSP();
129
130 if (idx == 0)
131 return m_ptr_obj->GetSP();
132
133 if (idx == 1) {
134 Status status;
135 ValueObjectSP value_sp = m_ptr_obj->Dereference(status);
136 if (status.Success())
137 return value_sp;
138 }
139
140 return lldb::ValueObjectSP();
141}
142
145 m_ptr_obj = nullptr;
146
147 ValueObjectSP valobj_sp = m_backend.GetSP();
148 if (!valobj_sp)
150
151 ValueObjectSP ptr_obj_sp = valobj_sp->GetChildMemberWithName("_Ptr");
152 if (!ptr_obj_sp)
154
155 ValueObjectSP cast_ptr_sp =
156 GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
157 if (!cast_ptr_sp)
159
160 m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();
162}
163
164llvm::Expected<size_t>
167 if (name == "pointer")
168 return 0;
169
170 if (name == "object" || name == "$$dereference$$")
171 return 1;
172
173 return llvm::createStringErrorV("type has no child named '{0}'", name);
174}
175
178
181 lldb::ValueObjectSP valobj_sp) {
182 return new MsvcStlSmartPointerSyntheticFrontEnd(valobj_sp);
183}
184
186 if (auto valobj_sp = valobj.GetNonSyntheticValue())
187 return valobj_sp->GetChildMemberWithName("_Mypair") != nullptr;
188
189 return false;
190}
191
193 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
194 ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
195 if (!valobj_sp)
196 return false;
197
198 ValueObjectSP ptr_sp(valobj_sp->GetChildAtNamePath({"_Mypair", "_Myval2"}));
199 if (!ptr_sp)
200 return false;
201
202 DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);
203
204 return true;
205}
206
213
214llvm::Expected<uint32_t> lldb_private::formatters::
216 if (m_value_ptr_sp)
217 return m_deleter_sp ? 2 : 1;
218 return 0;
219}
220
223 uint32_t idx) {
224 if (!m_value_ptr_sp)
225 return lldb::ValueObjectSP();
226
227 if (idx == 0)
228 return m_value_ptr_sp;
229
230 if (idx == 1)
231 return m_deleter_sp;
232
233 if (idx == 2) {
234 Status status;
235 auto value_sp = m_value_ptr_sp->Dereference(status);
236 if (status.Success()) {
237 return value_sp;
238 }
239 }
240
241 return lldb::ValueObjectSP();
242}
243
246 ValueObjectSP valobj_sp = m_backend.GetSP();
247 if (!valobj_sp)
249
250 ValueObjectSP pair_sp = valobj_sp->GetChildMemberWithName("_Mypair");
251 if (!pair_sp)
253
254 if (auto value_ptr_sp = pair_sp->GetChildMemberWithName("_Myval2"))
255 m_value_ptr_sp = value_ptr_sp->Clone(ConstString("pointer"));
256
257 // Only present if the deleter is non-empty
258 if (auto deleter_sp = pair_sp->GetChildMemberWithName("_Myval1"))
259 m_deleter_sp = deleter_sp->Clone(ConstString("deleter"));
260
262}
263
264llvm::Expected<size_t>
267 if (name == "pointer")
268 return 0;
269 if (name == "deleter")
270 return 1;
271 if (name == "obj" || name == "object" || name == "$$dereference$$")
272 return 2;
273 return llvm::createStringErrorV("type has no child named '{0}'", name);
274}
275
278 lldb::ValueObjectSP valobj_sp) {
279 return new MsvcStlUniquePtrSyntheticFrontEnd(valobj_sp);
280}
A uniqued constant string class.
Definition ConstString.h:40
An error handling class.
Definition Status.h:118
bool Success() const
Test for success condition.
Definition Status.cpp:303
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:132
SyntheticChildrenFrontEnd(ValueObject &backend)
virtual lldb::ValueObjectSP GetNonSyntheticValue()
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Determine the index of a named child.
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Determine the index of a named child.
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
lldb::ValueObjectSP GetDesugaredSmartPointerValue(ValueObject &ptr, ValueObject &container)
Return the ValueObjectSP of the underlying pointer member whose type is a desugared 'std::shared_ptr:...
Definition Generic.cpp:13
bool MsvcStlUniquePtrSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool MsvcStlSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool IsMsvcStlUniquePtr(ValueObject &valobj)
lldb_private::SyntheticChildrenFrontEnd * MsvcStlSmartPointerSyntheticFrontEndCreator(lldb::ValueObjectSP valobj_sp)
lldb_private::SyntheticChildrenFrontEnd * MsvcStlUniquePtrSyntheticFrontEndCreator(lldb::ValueObjectSP valobj_sp)
void DumpCxxSmartPtrPointerSummary(Stream &stream, ValueObject &ptr, const TypeSummaryOptions &options)
Prints the summary for the pointer value of a C++ std::unique_ptr/stdshared_ptr/stdweak_ptr.
bool IsMsvcStlSmartPointer(ValueObject &valobj)
A class that represents a running process on the host machine.
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
@ eRefetch
Children need to be recomputed dynamically.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP