blob: 335523e10b2633a7022f9494224bfc1bbe96e642 [file] [log] [blame]
Tamas Berghammerd161b212016-10-21 15:02:44 +00001//===-- LibStdcppUniquePointer.cpp ------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Tamas Berghammerd161b212016-10-21 15:02:44 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "LibStdcpp.h"
10
Tamas Berghammerd161b212016-10-21 15:02:44 +000011#include "lldb/Core/ValueObject.h"
12#include "lldb/DataFormatters/FormattersHelpers.h"
13#include "lldb/DataFormatters/TypeSynthetic.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000014#include "lldb/Utility/ConstString.h"
Tamas Berghammerd161b212016-10-21 15:02:44 +000015
Tamas Berghammerde2cc6e2016-10-21 15:05:03 +000016#include <memory>
17#include <vector>
18
Tamas Berghammerd161b212016-10-21 15:02:44 +000019using namespace lldb;
20using namespace lldb_private;
21using namespace lldb_private::formatters;
22
23namespace {
24
25class LibStdcppUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
26public:
27 explicit LibStdcppUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
28
29 size_t CalculateNumChildren() override;
30
31 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
32
33 bool Update() override;
34
35 bool MightHaveChildren() override;
36
37 size_t GetIndexOfChildWithName(const ConstString &name) override;
38
39 bool GetSummary(Stream &stream, const TypeSummaryOptions &options);
40
41private:
42 ValueObjectSP m_ptr_obj;
43 ValueObjectSP m_obj_obj;
44 ValueObjectSP m_del_obj;
Pavel Labathb312b132018-03-08 16:03:09 +000045
46 ValueObjectSP GetTuple();
Tamas Berghammerd161b212016-10-21 15:02:44 +000047};
48
49} // end of anonymous namespace
50
51LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd(
52 lldb::ValueObjectSP valobj_sp)
53 : SyntheticChildrenFrontEnd(*valobj_sp) {
54 Update();
55}
56
Pavel Labathb312b132018-03-08 16:03:09 +000057ValueObjectSP LibStdcppUniquePtrSyntheticFrontEnd::GetTuple() {
Tamas Berghammerd161b212016-10-21 15:02:44 +000058 ValueObjectSP valobj_backend_sp = m_backend.GetSP();
Pavel Labathb312b132018-03-08 16:03:09 +000059
Tamas Berghammerd161b212016-10-21 15:02:44 +000060 if (!valobj_backend_sp)
Pavel Labathb312b132018-03-08 16:03:09 +000061 return nullptr;
Tamas Berghammerd161b212016-10-21 15:02:44 +000062
63 ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue();
64 if (!valobj_sp)
Pavel Labathb312b132018-03-08 16:03:09 +000065 return nullptr;
Tamas Berghammerd161b212016-10-21 15:02:44 +000066
Pavel Labathb312b132018-03-08 16:03:09 +000067 ValueObjectSP obj_child_sp =
Tamas Berghammerd161b212016-10-21 15:02:44 +000068 valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true);
Pavel Labathcb512a32018-06-11 14:52:52 +000069 if (!obj_child_sp)
70 return nullptr;
Pavel Labathb312b132018-03-08 16:03:09 +000071
72 ValueObjectSP obj_subchild_sp =
73 obj_child_sp->GetChildMemberWithName(ConstString("_M_t"), true);
74
Adrian Prantl05097242018-04-30 16:49:04 +000075 // if there is a _M_t subchild, the tuple is found in the obj_subchild_sp
76 // (for libstdc++ 6.0.23).
Pavel Labathb312b132018-03-08 16:03:09 +000077 if (obj_subchild_sp) {
78 return obj_subchild_sp;
79 }
80
81 return obj_child_sp;
82}
83
84bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
85 ValueObjectSP tuple_sp = GetTuple();
86
Tamas Berghammerd161b212016-10-21 15:02:44 +000087 if (!tuple_sp)
88 return false;
89
90 std::unique_ptr<SyntheticChildrenFrontEnd> tuple_frontend(
91 LibStdcppTupleSyntheticFrontEndCreator(nullptr, tuple_sp));
92
Tamas Berghammer4fbb55b2017-03-31 20:48:00 +000093 ValueObjectSP ptr_obj = tuple_frontend->GetChildAtIndex(0);
94 if (ptr_obj)
95 m_ptr_obj = ptr_obj->Clone(ConstString("pointer"));
Tamas Berghammerd161b212016-10-21 15:02:44 +000096
Tamas Berghammer4fbb55b2017-03-31 20:48:00 +000097 ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
98 if (del_obj)
99 m_del_obj = del_obj->Clone(ConstString("deleter"));
Tamas Berghammerd161b212016-10-21 15:02:44 +0000100
101 if (m_ptr_obj) {
Zachary Turner97206d52017-05-12 04:51:55 +0000102 Status error;
Tamas Berghammer4fbb55b2017-03-31 20:48:00 +0000103 ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
Tamas Berghammerd161b212016-10-21 15:02:44 +0000104 if (error.Success()) {
Tamas Berghammer4fbb55b2017-03-31 20:48:00 +0000105 m_obj_obj = obj_obj->Clone(ConstString("object"));
Tamas Berghammerd161b212016-10-21 15:02:44 +0000106 }
107 }
108
109 return false;
110}
111
112bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; }
113
114lldb::ValueObjectSP
115LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
116 if (idx == 0)
Tamas Berghammeraf8953a2017-03-31 20:07:20 +0000117 return m_ptr_obj;
Tamas Berghammerd161b212016-10-21 15:02:44 +0000118 if (idx == 1)
119 return m_del_obj;
120 if (idx == 2)
Tamas Berghammeraf8953a2017-03-31 20:07:20 +0000121 return m_obj_obj;
Tamas Berghammerd161b212016-10-21 15:02:44 +0000122 return lldb::ValueObjectSP();
123}
124
125size_t LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() {
126 if (m_del_obj)
127 return 2;
Tamas Berghammeraf8953a2017-03-31 20:07:20 +0000128 return 1;
Tamas Berghammerd161b212016-10-21 15:02:44 +0000129}
130
131size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName(
132 const ConstString &name) {
Tamas Berghammeraf8953a2017-03-31 20:07:20 +0000133 if (name == ConstString("ptr") || name == ConstString("pointer"))
Tamas Berghammerd161b212016-10-21 15:02:44 +0000134 return 0;
135 if (name == ConstString("del") || name == ConstString("deleter"))
136 return 1;
Tamas Berghammer4c08fe22017-03-31 20:23:22 +0000137 if (name == ConstString("obj") || name == ConstString("object") ||
138 name == ConstString("$$dereference$$"))
Tamas Berghammerd161b212016-10-21 15:02:44 +0000139 return 2;
140 return UINT32_MAX;
141}
142
143bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary(
144 Stream &stream, const TypeSummaryOptions &options) {
145 if (!m_ptr_obj)
146 return false;
147
Pavel Labath833e3d12016-11-09 10:42:29 +0000148 bool success;
149 uint64_t ptr_value = m_ptr_obj->GetValueAsUnsigned(0, &success);
150 if (!success)
151 return false;
152 if (ptr_value == 0)
Tamas Berghammerd161b212016-10-21 15:02:44 +0000153 stream.Printf("nullptr");
Pavel Labath833e3d12016-11-09 10:42:29 +0000154 else
155 stream.Printf("0x%" PRIx64, ptr_value);
Tamas Berghammerd161b212016-10-21 15:02:44 +0000156 return true;
157}
158
159SyntheticChildrenFrontEnd *
160lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator(
161 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
162 return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp)
163 : nullptr);
164}
165
166bool lldb_private::formatters::LibStdcppUniquePointerSummaryProvider(
167 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
168 LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP());
169 return formatter.GetSummary(stream, options);
170}