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/LibStdcppUniquePointer.cpp
39642 views
1
//===-- LibStdcppUniquePointer.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 "LibStdcpp.h"
10
11
#include "lldb/Core/ValueObject.h"
12
#include "lldb/DataFormatters/FormattersHelpers.h"
13
#include "lldb/DataFormatters/TypeSynthetic.h"
14
#include "lldb/Utility/ConstString.h"
15
16
#include <memory>
17
#include <vector>
18
19
using namespace lldb;
20
using namespace lldb_private;
21
using namespace lldb_private::formatters;
22
23
namespace {
24
25
class LibStdcppUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
26
public:
27
explicit LibStdcppUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
28
29
llvm::Expected<uint32_t> CalculateNumChildren() override;
30
31
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
32
33
lldb::ChildCacheState Update() override;
34
35
bool MightHaveChildren() override;
36
37
size_t GetIndexOfChildWithName(ConstString name) override;
38
39
bool GetSummary(Stream &stream, const TypeSummaryOptions &options);
40
41
private:
42
// The lifetime of a ValueObject and all its derivative ValueObjects
43
// (children, clones, etc.) is managed by a ClusterManager. These
44
// objects are only destroyed when every shared pointer to any of them
45
// is destroyed, so we must not store a shared pointer to any ValueObject
46
// derived from our backend ValueObject (since we're in the same cluster).
47
ValueObject* m_ptr_obj = nullptr;
48
ValueObject* m_obj_obj = nullptr;
49
ValueObject* m_del_obj = nullptr;
50
51
ValueObjectSP GetTuple();
52
};
53
54
} // end of anonymous namespace
55
56
LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd(
57
lldb::ValueObjectSP valobj_sp)
58
: SyntheticChildrenFrontEnd(*valobj_sp) {
59
Update();
60
}
61
62
ValueObjectSP LibStdcppUniquePtrSyntheticFrontEnd::GetTuple() {
63
ValueObjectSP valobj_backend_sp = m_backend.GetSP();
64
65
if (!valobj_backend_sp)
66
return nullptr;
67
68
ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue();
69
if (!valobj_sp)
70
return nullptr;
71
72
ValueObjectSP obj_child_sp = valobj_sp->GetChildMemberWithName("_M_t");
73
if (!obj_child_sp)
74
return nullptr;
75
76
ValueObjectSP obj_subchild_sp = obj_child_sp->GetChildMemberWithName("_M_t");
77
78
// if there is a _M_t subchild, the tuple is found in the obj_subchild_sp
79
// (for libstdc++ 6.0.23).
80
if (obj_subchild_sp) {
81
return obj_subchild_sp;
82
}
83
84
return obj_child_sp;
85
}
86
87
lldb::ChildCacheState LibStdcppUniquePtrSyntheticFrontEnd::Update() {
88
ValueObjectSP tuple_sp = GetTuple();
89
90
if (!tuple_sp)
91
return lldb::ChildCacheState::eRefetch;
92
93
std::unique_ptr<SyntheticChildrenFrontEnd> tuple_frontend(
94
LibStdcppTupleSyntheticFrontEndCreator(nullptr, tuple_sp));
95
96
ValueObjectSP ptr_obj = tuple_frontend->GetChildAtIndex(0);
97
if (ptr_obj)
98
m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get();
99
100
// Add a 'deleter' child if there was a non-empty deleter type specified.
101
//
102
// The object might have size=1 in the TypeSystem but occupies no dedicated
103
// storage due to no_unique_address, so infer the actual size from the total
104
// size of the unique_ptr class. If sizeof(unique_ptr) == sizeof(void*) then
105
// the deleter is empty and should be hidden.
106
if (tuple_sp->GetByteSize() > ptr_obj->GetByteSize()) {
107
ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
108
if (del_obj)
109
m_del_obj = del_obj->Clone(ConstString("deleter")).get();
110
}
111
m_obj_obj = nullptr;
112
113
return lldb::ChildCacheState::eRefetch;
114
}
115
116
bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; }
117
118
lldb::ValueObjectSP
119
LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(uint32_t idx) {
120
if (idx == 0 && m_ptr_obj)
121
return m_ptr_obj->GetSP();
122
if (idx == 1 && m_del_obj)
123
return m_del_obj->GetSP();
124
if (idx == 2) {
125
if (m_ptr_obj && !m_obj_obj) {
126
Status error;
127
ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
128
if (error.Success()) {
129
m_obj_obj = obj_obj->Clone(ConstString("object")).get();
130
}
131
}
132
if (m_obj_obj)
133
return m_obj_obj->GetSP();
134
}
135
return lldb::ValueObjectSP();
136
}
137
138
llvm::Expected<uint32_t>
139
LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() {
140
if (m_del_obj)
141
return 2;
142
return 1;
143
}
144
145
size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName(
146
ConstString name) {
147
if (name == "ptr" || name == "pointer")
148
return 0;
149
if (name == "del" || name == "deleter")
150
return 1;
151
if (name == "obj" || name == "object" || name == "$$dereference$$")
152
return 2;
153
return UINT32_MAX;
154
}
155
156
bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary(
157
Stream &stream, const TypeSummaryOptions &options) {
158
if (!m_ptr_obj)
159
return false;
160
161
bool success;
162
uint64_t ptr_value = m_ptr_obj->GetValueAsUnsigned(0, &success);
163
if (!success)
164
return false;
165
if (ptr_value == 0)
166
stream.Printf("nullptr");
167
else
168
stream.Printf("0x%" PRIx64, ptr_value);
169
return true;
170
}
171
172
SyntheticChildrenFrontEnd *
173
lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator(
174
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
175
return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp)
176
: nullptr);
177
}
178
179
bool lldb_private::formatters::LibStdcppUniquePointerSummaryProvider(
180
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
181
LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP());
182
return formatter.GetSummary(stream, options);
183
}
184
185