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
15using namespace lldb;
16
18 if (auto valobj_sp = valobj.GetNonSyntheticValue())
19 return valobj_sp->GetChildMemberWithName("_Ptr") != nullptr;
20
21 return false;
22}
23
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
66namespace lldb_private {
67namespace formatters {
68
70public:
72
73 llvm::Expected<uint32_t> CalculateNumChildren() override;
74
75 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
76
78
79 llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
80
82
83private:
85};
86
88public:
90
91 llvm::Expected<uint32_t> CalculateNumChildren() override;
92
93 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
94
96
97 llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
98
99private:
102};
103
104} // namespace formatters
105} // namespace lldb_private
106
113
118
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
144 m_ptr_obj = nullptr;
145
146 ValueObjectSP valobj_sp = m_backend.GetSP();
147 if (!valobj_sp)
149
150 ValueObjectSP ptr_obj_sp = valobj_sp->GetChildMemberWithName("_Ptr");
151 if (!ptr_obj_sp)
153
154 ValueObjectSP cast_ptr_sp =
155 GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
156 if (!cast_ptr_sp)
158
159 m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();
161}
162
163llvm::Expected<size_t>
166 if (name == "pointer")
167 return 0;
168
169 if (name == "object" || name == "$$dereference$$")
170 return 1;
171
172 return llvm::createStringError("Type has no child named '%s'",
173 name.AsCString());
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::createStringError("Type has no child named '%s'",
274 name.AsCString());
275}
276
279 lldb::ValueObjectSP valobj_sp) {
280 return new MsvcStlUniquePtrSyntheticFrontEnd(valobj_sp);
281}
A uniqued constant string class.
Definition ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
An error handling class.
Definition Status.h:118
bool Success() const
Test for success condition.
Definition Status.cpp:304
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 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
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) 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...
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