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