LLDB  mainline
LibStdcppUniquePointer.cpp
Go to the documentation of this file.
1 //===-- LibStdcppUniquePointer.cpp ------------------------------*- C++ -*-===//
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"
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  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(ConstString name) override;
38 
39  bool GetSummary(Stream &stream, const TypeSummaryOptions &options);
40 
41 private:
42  ValueObjectSP m_ptr_obj;
43  ValueObjectSP m_obj_obj;
44  ValueObjectSP m_del_obj;
45 
46  ValueObjectSP GetTuple();
47 };
48 
49 } // end of anonymous namespace
50 
51 LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd(
52  lldb::ValueObjectSP valobj_sp)
53  : SyntheticChildrenFrontEnd(*valobj_sp) {
54  Update();
55 }
56 
57 ValueObjectSP LibStdcppUniquePtrSyntheticFrontEnd::GetTuple() {
58  ValueObjectSP valobj_backend_sp = m_backend.GetSP();
59 
60  if (!valobj_backend_sp)
61  return nullptr;
62 
63  ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue();
64  if (!valobj_sp)
65  return nullptr;
66 
67  ValueObjectSP obj_child_sp =
68  valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true);
69  if (!obj_child_sp)
70  return nullptr;
71 
72  ValueObjectSP obj_subchild_sp =
73  obj_child_sp->GetChildMemberWithName(ConstString("_M_t"), true);
74 
75  // if there is a _M_t subchild, the tuple is found in the obj_subchild_sp
76  // (for libstdc++ 6.0.23).
77  if (obj_subchild_sp) {
78  return obj_subchild_sp;
79  }
80 
81  return obj_child_sp;
82 }
83 
84 bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
85  ValueObjectSP tuple_sp = GetTuple();
86 
87  if (!tuple_sp)
88  return false;
89 
90  std::unique_ptr<SyntheticChildrenFrontEnd> tuple_frontend(
91  LibStdcppTupleSyntheticFrontEndCreator(nullptr, tuple_sp));
92 
93  ValueObjectSP ptr_obj = tuple_frontend->GetChildAtIndex(0);
94  if (ptr_obj)
95  m_ptr_obj = ptr_obj->Clone(ConstString("pointer"));
96 
97  ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
98  if (del_obj)
99  m_del_obj = del_obj->Clone(ConstString("deleter"));
100 
101  if (m_ptr_obj) {
102  Status error;
103  ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
104  if (error.Success()) {
105  m_obj_obj = obj_obj->Clone(ConstString("object"));
106  }
107  }
108 
109  return false;
110 }
111 
112 bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; }
113 
114 lldb::ValueObjectSP
115 LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
116  if (idx == 0)
117  return m_ptr_obj;
118  if (idx == 1)
119  return m_del_obj;
120  if (idx == 2)
121  return m_obj_obj;
122  return lldb::ValueObjectSP();
123 }
124 
126  if (m_del_obj)
127  return 2;
128  return 1;
129 }
130 
131 size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName(
132  ConstString name) {
133  if (name == "ptr" || name == "pointer")
134  return 0;
135  if (name == "del" || name == "deleter")
136  return 1;
137  if (name == "obj" || name == "object" || name == "$$dereference$$")
138  return 2;
139  return UINT32_MAX;
140 }
141 
142 bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary(
143  Stream &stream, const TypeSummaryOptions &options) {
144  if (!m_ptr_obj)
145  return false;
146 
147  bool success;
148  uint64_t ptr_value = m_ptr_obj->GetValueAsUnsigned(0, &success);
149  if (!success)
150  return false;
151  if (ptr_value == 0)
152  stream.Printf("nullptr");
153  else
154  stream.Printf("0x%" PRIx64, ptr_value);
155  return true;
156 }
157 
160  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
161  return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp)
162  : nullptr);
163 }
164 
166  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
167  LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP());
168  return formatter.GetSummary(stream, options);
169 }
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
bool LibStdcppUniquePointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
SyntheticChildrenFrontEnd * LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
#define UINT32_MAX
Definition: lldb-defines.h:31
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
bool Success() const
Test for success condition.
Definition: Status.cpp:287
static size_t CalculateNumChildren(CompilerType container_type, CompilerType element_type, lldb_private::ExecutionContextScope *exe_scope=nullptr)
Definition: VectorType.cpp:168
A uniqued constant string class.
Definition: ConstString.h:38
Definition: SBAddress.h:15
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:565
SyntheticChildrenFrontEnd * LibStdcppTupleSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
An error handling class.
Definition: Status.h:44