180814287SRaphael Isemann //===-- LibStdcppUniquePointer.cpp ----------------------------------------===//
2d161b214STamas Berghammer //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d161b214STamas Berghammer //
7d161b214STamas Berghammer //===----------------------------------------------------------------------===//
8d161b214STamas Berghammer
9d161b214STamas Berghammer #include "LibStdcpp.h"
10d161b214STamas Berghammer
11d161b214STamas Berghammer #include "lldb/Core/ValueObject.h"
12d161b214STamas Berghammer #include "lldb/DataFormatters/FormattersHelpers.h"
13d161b214STamas Berghammer #include "lldb/DataFormatters/TypeSynthetic.h"
14bf9a7730SZachary Turner #include "lldb/Utility/ConstString.h"
15d161b214STamas Berghammer
16de2cc6e4STamas Berghammer #include <memory>
17de2cc6e4STamas Berghammer #include <vector>
18de2cc6e4STamas Berghammer
19d161b214STamas Berghammer using namespace lldb;
20d161b214STamas Berghammer using namespace lldb_private;
21d161b214STamas Berghammer using namespace lldb_private::formatters;
22d161b214STamas Berghammer
23d161b214STamas Berghammer namespace {
24d161b214STamas Berghammer
25d161b214STamas Berghammer class LibStdcppUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
26d161b214STamas Berghammer public:
27d161b214STamas Berghammer explicit LibStdcppUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
28d161b214STamas Berghammer
29d161b214STamas Berghammer size_t CalculateNumChildren() override;
30d161b214STamas Berghammer
31d161b214STamas Berghammer lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
32d161b214STamas Berghammer
33d161b214STamas Berghammer bool Update() override;
34d161b214STamas Berghammer
35d161b214STamas Berghammer bool MightHaveChildren() override;
36d161b214STamas Berghammer
370e4c4821SAdrian Prantl size_t GetIndexOfChildWithName(ConstString name) override;
38d161b214STamas Berghammer
39d161b214STamas Berghammer bool GetSummary(Stream &stream, const TypeSummaryOptions &options);
40d161b214STamas Berghammer
41d161b214STamas Berghammer private:
4289386daaSCameron Desrochers // The lifetime of a ValueObject and all its derivative ValueObjects
4389386daaSCameron Desrochers // (children, clones, etc.) is managed by a ClusterManager. These
4489386daaSCameron Desrochers // objects are only destroyed when every shared pointer to any of them
4589386daaSCameron Desrochers // is destroyed, so we must not store a shared pointer to any ValueObject
4689386daaSCameron Desrochers // derived from our backend ValueObject (since we're in the same cluster).
4789386daaSCameron Desrochers ValueObject* m_ptr_obj = nullptr;
4889386daaSCameron Desrochers ValueObject* m_obj_obj = nullptr;
4989386daaSCameron Desrochers ValueObject* m_del_obj = nullptr;
50b312b139SPavel Labath
51b312b139SPavel Labath ValueObjectSP GetTuple();
52d161b214STamas Berghammer };
53d161b214STamas Berghammer
54d161b214STamas Berghammer } // end of anonymous namespace
55d161b214STamas Berghammer
LibStdcppUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)56d161b214STamas Berghammer LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd(
57d161b214STamas Berghammer lldb::ValueObjectSP valobj_sp)
58d161b214STamas Berghammer : SyntheticChildrenFrontEnd(*valobj_sp) {
59d161b214STamas Berghammer Update();
60d161b214STamas Berghammer }
61d161b214STamas Berghammer
GetTuple()62b312b139SPavel Labath ValueObjectSP LibStdcppUniquePtrSyntheticFrontEnd::GetTuple() {
63d161b214STamas Berghammer ValueObjectSP valobj_backend_sp = m_backend.GetSP();
64b312b139SPavel Labath
65d161b214STamas Berghammer if (!valobj_backend_sp)
66b312b139SPavel Labath return nullptr;
67d161b214STamas Berghammer
68d161b214STamas Berghammer ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue();
69d161b214STamas Berghammer if (!valobj_sp)
70b312b139SPavel Labath return nullptr;
71d161b214STamas Berghammer
72b312b139SPavel Labath ValueObjectSP obj_child_sp =
73d161b214STamas Berghammer valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true);
74cb512a30SPavel Labath if (!obj_child_sp)
75cb512a30SPavel Labath return nullptr;
76b312b139SPavel Labath
77b312b139SPavel Labath ValueObjectSP obj_subchild_sp =
78b312b139SPavel Labath obj_child_sp->GetChildMemberWithName(ConstString("_M_t"), true);
79b312b139SPavel Labath
8005097246SAdrian Prantl // if there is a _M_t subchild, the tuple is found in the obj_subchild_sp
8105097246SAdrian Prantl // (for libstdc++ 6.0.23).
82b312b139SPavel Labath if (obj_subchild_sp) {
83b312b139SPavel Labath return obj_subchild_sp;
84b312b139SPavel Labath }
85b312b139SPavel Labath
86b312b139SPavel Labath return obj_child_sp;
87b312b139SPavel Labath }
88b312b139SPavel Labath
Update()89b312b139SPavel Labath bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
90b312b139SPavel Labath ValueObjectSP tuple_sp = GetTuple();
91b312b139SPavel Labath
92d161b214STamas Berghammer if (!tuple_sp)
93d161b214STamas Berghammer return false;
94d161b214STamas Berghammer
95d161b214STamas Berghammer std::unique_ptr<SyntheticChildrenFrontEnd> tuple_frontend(
96d161b214STamas Berghammer LibStdcppTupleSyntheticFrontEndCreator(nullptr, tuple_sp));
97d161b214STamas Berghammer
984fbb55b7STamas Berghammer ValueObjectSP ptr_obj = tuple_frontend->GetChildAtIndex(0);
994fbb55b7STamas Berghammer if (ptr_obj)
10089386daaSCameron Desrochers m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get();
101d161b214STamas Berghammer
102*fffb9750SJan Kratochvil // Add a 'deleter' child if there was a non-empty deleter type specified.
103*fffb9750SJan Kratochvil //
104*fffb9750SJan Kratochvil // The object might have size=1 in the TypeSystem but occupies no dedicated
105*fffb9750SJan Kratochvil // storage due to no_unique_address, so infer the actual size from the total
106*fffb9750SJan Kratochvil // size of the unique_ptr class. If sizeof(unique_ptr) == sizeof(void*) then
107*fffb9750SJan Kratochvil // the deleter is empty and should be hidden.
108*fffb9750SJan Kratochvil if (tuple_sp->GetByteSize() > ptr_obj->GetByteSize()) {
1094fbb55b7STamas Berghammer ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
1104fbb55b7STamas Berghammer if (del_obj)
11189386daaSCameron Desrochers m_del_obj = del_obj->Clone(ConstString("deleter")).get();
112*fffb9750SJan Kratochvil }
113d161b214STamas Berghammer
114d161b214STamas Berghammer if (m_ptr_obj) {
11597206d57SZachary Turner Status error;
1164fbb55b7STamas Berghammer ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
117d161b214STamas Berghammer if (error.Success()) {
11889386daaSCameron Desrochers m_obj_obj = obj_obj->Clone(ConstString("object")).get();
119d161b214STamas Berghammer }
120d161b214STamas Berghammer }
121d161b214STamas Berghammer
122d161b214STamas Berghammer return false;
123d161b214STamas Berghammer }
124d161b214STamas Berghammer
MightHaveChildren()125d161b214STamas Berghammer bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; }
126d161b214STamas Berghammer
127d161b214STamas Berghammer lldb::ValueObjectSP
GetChildAtIndex(size_t idx)128d161b214STamas Berghammer LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
129745e57c5SCameron Desrochers if (idx == 0 && m_ptr_obj)
13089386daaSCameron Desrochers return m_ptr_obj->GetSP();
131745e57c5SCameron Desrochers if (idx == 1 && m_del_obj)
13289386daaSCameron Desrochers return m_del_obj->GetSP();
133745e57c5SCameron Desrochers if (idx == 2 && m_obj_obj)
13489386daaSCameron Desrochers return m_obj_obj->GetSP();
135d161b214STamas Berghammer return lldb::ValueObjectSP();
136d161b214STamas Berghammer }
137d161b214STamas Berghammer
CalculateNumChildren()138d161b214STamas Berghammer size_t LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() {
139d161b214STamas Berghammer if (m_del_obj)
140d161b214STamas Berghammer return 2;
141d161b214STamas Berghammer return 1;
142d161b214STamas Berghammer }
143d161b214STamas Berghammer
GetIndexOfChildWithName(ConstString name)144d161b214STamas Berghammer size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName(
1450e4c4821SAdrian Prantl ConstString name) {
14605cfdb0eSRaphael Isemann if (name == "ptr" || name == "pointer")
147d161b214STamas Berghammer return 0;
14805cfdb0eSRaphael Isemann if (name == "del" || name == "deleter")
149d161b214STamas Berghammer return 1;
15005cfdb0eSRaphael Isemann if (name == "obj" || name == "object" || name == "$$dereference$$")
151d161b214STamas Berghammer return 2;
152d161b214STamas Berghammer return UINT32_MAX;
153d161b214STamas Berghammer }
154d161b214STamas Berghammer
GetSummary(Stream & stream,const TypeSummaryOptions & options)155d161b214STamas Berghammer bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary(
156d161b214STamas Berghammer Stream &stream, const TypeSummaryOptions &options) {
157d161b214STamas Berghammer if (!m_ptr_obj)
158d161b214STamas Berghammer return false;
159d161b214STamas Berghammer
160833e3d10SPavel Labath bool success;
161833e3d10SPavel Labath uint64_t ptr_value = m_ptr_obj->GetValueAsUnsigned(0, &success);
162833e3d10SPavel Labath if (!success)
163833e3d10SPavel Labath return false;
164833e3d10SPavel Labath if (ptr_value == 0)
165d161b214STamas Berghammer stream.Printf("nullptr");
166833e3d10SPavel Labath else
167833e3d10SPavel Labath stream.Printf("0x%" PRIx64, ptr_value);
168d161b214STamas Berghammer return true;
169d161b214STamas Berghammer }
170d161b214STamas Berghammer
171d161b214STamas Berghammer SyntheticChildrenFrontEnd *
LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *,lldb::ValueObjectSP valobj_sp)172d161b214STamas Berghammer lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator(
173d161b214STamas Berghammer CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
174d161b214STamas Berghammer return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp)
175d161b214STamas Berghammer : nullptr);
176d161b214STamas Berghammer }
177d161b214STamas Berghammer
LibStdcppUniquePointerSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions & options)178d161b214STamas Berghammer bool lldb_private::formatters::LibStdcppUniquePointerSummaryProvider(
179d161b214STamas Berghammer ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
180d161b214STamas Berghammer LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP());
181d161b214STamas Berghammer return formatter.GetSummary(stream, options);
182d161b214STamas Berghammer }
183