1 //===-- LibCxxInitializerList.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 "LibCxx.h" 11 12 #include "lldb/Core/ValueObject.h" 13 #include "lldb/DataFormatters/FormattersHelpers.h" 14 #include "lldb/Utility/ConstString.h" 15 16 using namespace lldb; 17 using namespace lldb_private; 18 using namespace lldb_private::formatters; 19 20 namespace lldb_private { 21 namespace formatters { 22 class LibcxxInitializerListSyntheticFrontEnd 23 : public SyntheticChildrenFrontEnd { 24 public: 25 LibcxxInitializerListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 26 27 ~LibcxxInitializerListSyntheticFrontEnd() override; 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 private: 40 ValueObject *m_start; 41 CompilerType m_element_type; 42 uint32_t m_element_size; 43 size_t m_num_elements; 44 }; 45 } // namespace formatters 46 } // namespace lldb_private 47 48 lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: 49 LibcxxInitializerListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) 50 : SyntheticChildrenFrontEnd(*valobj_sp), m_start(nullptr), m_element_type(), 51 m_element_size(0), m_num_elements(0) { 52 if (valobj_sp) 53 Update(); 54 } 55 56 lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: 57 ~LibcxxInitializerListSyntheticFrontEnd() { 58 // this needs to stay around because it's a child object who will follow its 59 // parent's life cycle 60 // delete m_start; 61 } 62 63 size_t lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: 64 CalculateNumChildren() { 65 static ConstString g___size_("__size_"); 66 m_num_elements = 0; 67 ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g___size_, true)); 68 if (size_sp) 69 m_num_elements = size_sp->GetValueAsUnsigned(0); 70 return m_num_elements; 71 } 72 73 lldb::ValueObjectSP lldb_private::formatters:: 74 LibcxxInitializerListSyntheticFrontEnd::GetChildAtIndex(size_t idx) { 75 if (!m_start) 76 return lldb::ValueObjectSP(); 77 78 uint64_t offset = idx * m_element_size; 79 offset = offset + m_start->GetValueAsUnsigned(0); 80 StreamString name; 81 name.Printf("[%" PRIu64 "]", (uint64_t)idx); 82 return CreateValueObjectFromAddress(name.GetString(), offset, 83 m_backend.GetExecutionContextRef(), 84 m_element_type); 85 } 86 87 bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: 88 Update() { 89 static ConstString g___begin_("__begin_"); 90 91 m_start = nullptr; 92 m_num_elements = 0; 93 m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0); 94 if (!m_element_type.IsValid()) 95 return false; 96 97 m_element_size = m_element_type.GetByteSize(nullptr); 98 99 if (m_element_size > 0) 100 m_start = 101 m_backend.GetChildMemberWithName(g___begin_, true) 102 .get(); // store raw pointers or end up with a circular dependency 103 104 return false; 105 } 106 107 bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: 108 MightHaveChildren() { 109 return true; 110 } 111 112 size_t lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: 113 GetIndexOfChildWithName(const ConstString &name) { 114 if (!m_start) 115 return UINT32_MAX; 116 return ExtractIndexFromString(name.GetCString()); 117 } 118 119 lldb_private::SyntheticChildrenFrontEnd * 120 lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator( 121 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { 122 return (valobj_sp ? new LibcxxInitializerListSyntheticFrontEnd(valobj_sp) 123 : nullptr); 124 } 125