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 uint64_t ctrl_addr = ctrl_sp->GetValueAsUnsigned(0);
37
38 return DumpMsvcStlSmartPointerSummary(*ptr_sp, *ctrl_sp, ctrl_addr, stream,
39 options);
40}
41
43 ValueObject &ptr, ValueObject &rep, uint64_t ctrl_addr, Stream &stream,
44 const TypeSummaryOptions &options) {
45 DumpCxxSmartPtrPointerSummary(stream, ptr, options);
46
47 // Empty control field (expired)
48 if (ctrl_addr == 0)
49 return true;
50
51 uint64_t uses = 0;
52 if (auto uses_sp = rep.GetChildMemberWithName("_Uses")) {
53 bool success;
54 uses = uses_sp->GetValueAsUnsigned(0, &success);
55 if (!success)
56 return false;
57
58 stream.Printf(" strong=%" PRIu64, uses);
59 }
60
61 // _Weaks is the number of weak references - (_Uses != 0).
62 if (auto weak_count_sp = rep.GetChildMemberWithName("_Weaks")) {
63 bool success;
64 uint64_t count = weak_count_sp->GetValueAsUnsigned(0, &success);
65 if (!success)
66 return false;
67
68 stream.Printf(" weak=%" PRIu64, count - (uses != 0));
69 }
70
71 return true;
72}
73
74namespace lldb_private {
75namespace formatters {
76
78public:
80
81 llvm::Expected<uint32_t> CalculateNumChildren() override;
82
83 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
84
86
87 llvm::Expected<size_t> GetIndexOfChildWithName(llvm::StringRef name) override;
88
90
91private:
93};
94
96public:
98
99 llvm::Expected<uint32_t> CalculateNumChildren() override;
100
101 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
102
103 lldb::ChildCacheState Update() override;
104
105 llvm::Expected<size_t> GetIndexOfChildWithName(llvm::StringRef name) override;
106
107private:
110};
111
112} // namespace formatters
113} // namespace lldb_private
114
121
126
129 uint32_t idx) {
130 if (!m_ptr_obj)
131 return lldb::ValueObjectSP();
132
133 ValueObjectSP valobj_sp = m_backend.GetSP();
134 if (!valobj_sp)
135 return lldb::ValueObjectSP();
136
137 if (idx == 0)
138 return m_ptr_obj->GetSP();
139
140 if (idx == 1) {
141 Status status;
142 ValueObjectSP value_sp = m_ptr_obj->Dereference(status);
143 if (status.Success())
144 return value_sp;
145 }
146
147 return lldb::ValueObjectSP();
148}
149
152 m_ptr_obj = nullptr;
153
154 ValueObjectSP valobj_sp = m_backend.GetSP();
155 if (!valobj_sp)
157
158 ValueObjectSP ptr_obj_sp = valobj_sp->GetChildMemberWithName("_Ptr");
159 if (!ptr_obj_sp)
161
162 ValueObjectSP cast_ptr_sp =
163 GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
164 if (!cast_ptr_sp)
166
167 m_ptr_obj = cast_ptr_sp->Clone("pointer").get();
169}
170
171llvm::Expected<size_t>
173 GetIndexOfChildWithName(llvm::StringRef name) {
174 if (name == "pointer")
175 return 0;
176
177 if (name == "object" || name == "$$dereference$$")
178 return 1;
179
180 return llvm::createStringErrorV("type has no child named '{0}'", name);
181}
182
185
188 lldb::ValueObjectSP valobj_sp) {
189 return new MsvcStlSmartPointerSyntheticFrontEnd(valobj_sp);
190}
191
193 if (auto valobj_sp = valobj.GetNonSyntheticValue())
194 return valobj_sp->GetChildMemberWithName("_Mypair") != nullptr;
195
196 return false;
197}
198
200 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
201 ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
202 if (!valobj_sp)
203 return false;
204
205 ValueObjectSP ptr_sp(valobj_sp->GetChildAtNamePath({"_Mypair", "_Myval2"}));
206 if (!ptr_sp)
207 return false;
208
209 DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);
210
211 return true;
212}
213
220
221llvm::Expected<uint32_t> lldb_private::formatters::
223 if (m_value_ptr_sp)
224 return m_deleter_sp ? 2 : 1;
225 return 0;
226}
227
230 uint32_t idx) {
231 if (!m_value_ptr_sp)
232 return lldb::ValueObjectSP();
233
234 if (idx == 0)
235 return m_value_ptr_sp;
236
237 if (idx == 1)
238 return m_deleter_sp;
239
240 if (idx == 2) {
241 Status status;
242 auto value_sp = m_value_ptr_sp->Dereference(status);
243 if (status.Success()) {
244 return value_sp;
245 }
246 }
247
248 return lldb::ValueObjectSP();
249}
250
253 ValueObjectSP valobj_sp = m_backend.GetSP();
254 if (!valobj_sp)
256
257 ValueObjectSP pair_sp = valobj_sp->GetChildMemberWithName("_Mypair");
258 if (!pair_sp)
260
261 if (auto value_ptr_sp = pair_sp->GetChildMemberWithName("_Myval2"))
262 m_value_ptr_sp = value_ptr_sp->Clone("pointer");
263
264 // Only present if the deleter is non-empty
265 if (auto deleter_sp = pair_sp->GetChildMemberWithName("_Myval1"))
266 m_deleter_sp = deleter_sp->Clone("deleter");
267
269}
270
271llvm::Expected<size_t>
273 GetIndexOfChildWithName(llvm::StringRef name) {
274 if (name == "pointer")
275 return 0;
276 if (name == "deleter")
277 return 1;
278 if (name == "obj" || name == "object" || name == "$$dereference$$")
279 return 2;
280 return llvm::createStringErrorV("type has no child named '{0}'", name);
281}
282
285 lldb::ValueObjectSP valobj_sp) {
286 return new MsvcStlUniquePtrSyntheticFrontEnd(valobj_sp);
287}
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:134
SyntheticChildrenFrontEnd(ValueObject &backend)
virtual lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name, bool can_create=true)
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(llvm::StringRef name) override
Determine the index of a named child.
llvm::Expected< size_t > GetIndexOfChildWithName(llvm::StringRef name) override
Determine the index of a named child.
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
bool DumpMsvcStlSmartPointerSummary(ValueObject &ptr, ValueObject &rep, uint64_t ctrl_addr, Stream &stream, const TypeSummaryOptions &options)
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