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/ValueObject.h" 13 #include "lldb/DataFormatters/FormattersHelpers.h" 14 #include "lldb/DataFormatters/TypeSynthetic.h" 15 #include "lldb/Utility/ConstString.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 ValueObjectSP ptr_obj = tuple_frontend->GetChildAtIndex(0); 74 if (ptr_obj) 75 m_ptr_obj = ptr_obj->Clone(ConstString("pointer")); 76 77 ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1); 78 if (del_obj) 79 m_del_obj = del_obj->Clone(ConstString("deleter")); 80 81 if (m_ptr_obj) { 82 Status error; 83 ValueObjectSP obj_obj = m_ptr_obj->Dereference(error); 84 if (error.Success()) { 85 m_obj_obj = obj_obj->Clone(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_ptr_obj; 98 if (idx == 1) 99 return m_del_obj; 100 if (idx == 2) 101 return m_obj_obj; 102 return lldb::ValueObjectSP(); 103 } 104 105 size_t LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() { 106 if (m_del_obj) 107 return 2; 108 return 1; 109 } 110 111 size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName( 112 const ConstString &name) { 113 if (name == ConstString("ptr") || name == ConstString("pointer")) 114 return 0; 115 if (name == ConstString("del") || name == ConstString("deleter")) 116 return 1; 117 if (name == ConstString("obj") || name == ConstString("object") || 118 name == ConstString("$$dereference$$")) 119 return 2; 120 return UINT32_MAX; 121 } 122 123 bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary( 124 Stream &stream, const TypeSummaryOptions &options) { 125 if (!m_ptr_obj) 126 return false; 127 128 bool success; 129 uint64_t ptr_value = m_ptr_obj->GetValueAsUnsigned(0, &success); 130 if (!success) 131 return false; 132 if (ptr_value == 0) 133 stream.Printf("nullptr"); 134 else 135 stream.Printf("0x%" PRIx64, ptr_value); 136 return true; 137 } 138 139 SyntheticChildrenFrontEnd * 140 lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator( 141 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { 142 return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp) 143 : nullptr); 144 } 145 146 bool lldb_private::formatters::LibStdcppUniquePointerSummaryProvider( 147 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { 148 LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP()); 149 return formatter.GetSummary(stream, options); 150 } 151