1 //===-- LibStdcppUniquePointer.cpp ------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "LibStdcpp.h" 11 12 #include "lldb/Core/ConstString.h" 13 #include "lldb/Core/ValueObject.h" 14 #include "lldb/DataFormatters/FormattersHelpers.h" 15 #include "lldb/DataFormatters/TypeSynthetic.h" 16 17 #include <memory> 18 #include <vector> 19 20 using namespace lldb; 21 using namespace lldb_private; 22 using namespace lldb_private::formatters; 23 24 namespace { 25 26 class LibStdcppUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { 27 public: 28 explicit LibStdcppUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 29 30 size_t CalculateNumChildren() override; 31 32 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; 33 34 bool Update() override; 35 36 bool MightHaveChildren() override; 37 38 size_t GetIndexOfChildWithName(const ConstString &name) override; 39 40 bool GetSummary(Stream &stream, const TypeSummaryOptions &options); 41 42 private: 43 ValueObjectSP m_ptr_obj; 44 ValueObjectSP m_obj_obj; 45 ValueObjectSP m_del_obj; 46 }; 47 48 } // end of anonymous namespace 49 50 LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd( 51 lldb::ValueObjectSP valobj_sp) 52 : SyntheticChildrenFrontEnd(*valobj_sp) { 53 Update(); 54 } 55 56 bool LibStdcppUniquePtrSyntheticFrontEnd::Update() { 57 ValueObjectSP valobj_backend_sp = m_backend.GetSP(); 58 if (!valobj_backend_sp) 59 return false; 60 61 ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue(); 62 if (!valobj_sp) 63 return false; 64 65 ValueObjectSP tuple_sp = 66 valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true); 67 if (!tuple_sp) 68 return false; 69 70 std::unique_ptr<SyntheticChildrenFrontEnd> tuple_frontend( 71 LibStdcppTupleSyntheticFrontEndCreator(nullptr, tuple_sp)); 72 73 m_ptr_obj = tuple_frontend->GetChildAtIndex(0); 74 if (m_ptr_obj) 75 m_ptr_obj->SetName(ConstString("pointer")); 76 77 m_del_obj = tuple_frontend->GetChildAtIndex(1); 78 if (m_del_obj) 79 m_del_obj->SetName(ConstString("deleter")); 80 81 if (m_ptr_obj) { 82 Error error; 83 m_obj_obj = m_ptr_obj->Dereference(error); 84 if (error.Success()) { 85 m_obj_obj->SetName(ConstString("object")); 86 } 87 } 88 89 return false; 90 } 91 92 bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; } 93 94 lldb::ValueObjectSP 95 LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) { 96 if (idx == 0) 97 return m_obj_obj; 98 if (idx == 1) 99 return m_del_obj; 100 if (idx == 2) 101 return m_ptr_obj; 102 return lldb::ValueObjectSP(); 103 } 104 105 size_t LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() { 106 if (m_del_obj) 107 return 2; 108 if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0) 109 return 1; 110 return 0; 111 } 112 113 size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName( 114 const ConstString &name) { 115 if (name == ConstString("obj") || name == ConstString("object")) 116 return 0; 117 if (name == ConstString("del") || name == ConstString("deleter")) 118 return 1; 119 if (name == ConstString("ptr") || name == ConstString("pointer")) 120 return 2; 121 return UINT32_MAX; 122 } 123 124 bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary( 125 Stream &stream, const TypeSummaryOptions &options) { 126 if (!m_ptr_obj) 127 return false; 128 129 bool success; 130 uint64_t ptr_value = m_ptr_obj->GetValueAsUnsigned(0, &success); 131 if (!success) 132 return false; 133 if (ptr_value == 0) 134 stream.Printf("nullptr"); 135 else 136 stream.Printf("0x%" PRIx64, ptr_value); 137 return true; 138 } 139 140 SyntheticChildrenFrontEnd * 141 lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator( 142 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { 143 return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp) 144 : nullptr); 145 } 146 147 bool lldb_private::formatters::LibStdcppUniquePointerSummaryProvider( 148 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { 149 LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP()); 150 return formatter.GetSummary(stream, options); 151 } 152