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 auto ptr_obj_sp = valobj_sp->GetChildMemberWithName("_Ptr");
151 if (!ptr_obj_sp)
153
154 auto cast_ptr_sp = GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
155 if (!cast_ptr_sp)
157
158 m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();
160}
161
162llvm::Expected<size_t>
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
177
183
185 if (auto valobj_sp = valobj.GetNonSyntheticValue())
186 return valobj_sp->GetChildMemberWithName("_Mypair") != nullptr;
187
188 return false;
189}
190
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
212
213llvm::Expected<uint32_t> lldb_private::formatters::
215 if (m_value_ptr_sp)
216 return m_deleter_sp ? 2 : 1;
217 return 0;
218}
219
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
245 ValueObjectSP valobj_sp = m_backend.GetSP();
246 if (!valobj_sp)
248
249 ValueObjectSP pair_sp = valobj_sp->GetChildMemberWithName("_Mypair");
250 if (!pair_sp)
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
261}
262
263llvm::Expected<size_t>
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
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