LLDB  mainline
LibStdcppUniquePointer.cpp
Go to the documentation of this file.
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"
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  // 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 =
73  valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true);
74  if (!obj_child_sp)
75  return nullptr;
76 
77  ValueObjectSP obj_subchild_sp =
78  obj_child_sp->GetChildMemberWithName(ConstString("_M_t"), true);
79 
80  // if there is a _M_t subchild, the tuple is found in the obj_subchild_sp
81  // (for libstdc++ 6.0.23).
82  if (obj_subchild_sp) {
83  return obj_subchild_sp;
84  }
85 
86  return obj_child_sp;
87 }
88 
89 bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
90  ValueObjectSP tuple_sp = GetTuple();
91 
92  if (!tuple_sp)
93  return false;
94 
95  std::unique_ptr<SyntheticChildrenFrontEnd> tuple_frontend(
96  LibStdcppTupleSyntheticFrontEndCreator(nullptr, tuple_sp));
97 
98  ValueObjectSP ptr_obj = tuple_frontend->GetChildAtIndex(0);
99  if (ptr_obj)
100  m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get();
101 
102  // Add a 'deleter' child if there was a non-empty deleter type specified.
103  //
104  // The object might have size=1 in the TypeSystem but occupies no dedicated
105  // storage due to no_unique_address, so infer the actual size from the total
106  // size of the unique_ptr class. If sizeof(unique_ptr) == sizeof(void*) then
107  // the deleter is empty and should be hidden.
108  if (tuple_sp->GetByteSize() > ptr_obj->GetByteSize()) {
109  ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
110  if (del_obj)
111  m_del_obj = del_obj->Clone(ConstString("deleter")).get();
112  }
113 
114  if (m_ptr_obj) {
115  Status error;
116  ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
117  if (error.Success()) {
118  m_obj_obj = obj_obj->Clone(ConstString("object")).get();
119  }
120  }
121 
122  return false;
123 }
124 
125 bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; }
126 
127 lldb::ValueObjectSP
128 LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
129  if (idx == 0 && m_ptr_obj)
130  return m_ptr_obj->GetSP();
131  if (idx == 1 && m_del_obj)
132  return m_del_obj->GetSP();
133  if (idx == 2 && m_obj_obj)
134  return m_obj_obj->GetSP();
135  return lldb::ValueObjectSP();
136 }
137 
139  if (m_del_obj)
140  return 2;
141  return 1;
142 }
143 
144 size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName(
145  ConstString name) {
146  if (name == "ptr" || name == "pointer")
147  return 0;
148  if (name == "del" || name == "deleter")
149  return 1;
150  if (name == "obj" || name == "object" || name == "$$dereference$$")
151  return 2;
152  return UINT32_MAX;
153 }
154 
155 bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary(
156  Stream &stream, const TypeSummaryOptions &options) {
157  if (!m_ptr_obj)
158  return false;
159 
160  bool success;
161  uint64_t ptr_value = m_ptr_obj->GetValueAsUnsigned(0, &success);
162  if (!success)
163  return false;
164  if (ptr_value == 0)
165  stream.Printf("nullptr");
166  else
167  stream.Printf("0x%" PRIx64, ptr_value);
168  return true;
169 }
170 
173  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
174  return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp)
175  : nullptr);
176 }
177 
179  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
180  LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP());
181  return formatter.GetSummary(stream, options);
182 }
CalculateNumChildren
static size_t CalculateNumChildren(CompilerType container_type, CompilerType element_type, lldb_private::ExecutionContextScope *exe_scope=nullptr)
Definition: VectorType.cpp:169
lldb_private::SyntheticChildrenFrontEnd
Definition: TypeSynthetic.h:27
lldb_private::Stream
Definition: Stream.h:28
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::formatters::LibStdcppUniquePointerSummaryProvider
bool LibStdcppUniquePointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibStdcppUniquePointer.cpp:178
lldb_private::ValueObject::GetSP
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:555
lldb_private::ConstString
Definition: ConstString.h:40
ValueObject.h
lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator
SyntheticChildrenFrontEnd * LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibStdcppUniquePointer.cpp:172
lldb_private::Status
Definition: Status.h:44
lldb_private::ValueObject
ValueObject:
Definition: ValueObject.h:105
TypeSynthetic.h
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator
SyntheticChildrenFrontEnd * LibStdcppTupleSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibStdcppTuple.cpp:108
lldb_private::TypeSummaryOptions
Definition: TypeSummary.h:26
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private::formatters
Definition: CXXFunctionPointer.h:15
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
ConstString.h
lldb_private::CXXSyntheticChildren
Definition: TypeSynthetic.h:358
FormattersHelpers.h
lldb
Definition: SBAddress.h:15
LibStdcpp.h