1 //===-- LibCxxTuple.cpp -----------------------------------------*- C++ -*-===// 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 #include "lldb/DataFormatters/FormattersHelpers.h" 11 12 using namespace lldb; 13 using namespace lldb_private; 14 15 namespace { 16 17 class TupleFrontEnd: public SyntheticChildrenFrontEnd { 18 public: 19 TupleFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) { 20 Update(); 21 } 22 23 size_t GetIndexOfChildWithName(ConstString name) override { 24 return formatters::ExtractIndexFromString(name.GetCString()); 25 } 26 27 bool MightHaveChildren() override { return true; } 28 bool Update() override; 29 size_t CalculateNumChildren() override { return m_elements.size(); } 30 ValueObjectSP GetChildAtIndex(size_t idx) override; 31 32 private: 33 std::vector<ValueObjectSP> m_elements; 34 ValueObjectSP m_base_sp; 35 }; 36 } 37 38 bool TupleFrontEnd::Update() { 39 m_elements.clear(); 40 m_base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true); 41 if (! m_base_sp) { 42 // Pre r304382 name of the base element. 43 m_base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true); 44 } 45 if (! m_base_sp) 46 return false; 47 m_elements.assign(m_base_sp->GetCompilerType().GetNumDirectBaseClasses(), 48 ValueObjectSP()); 49 return false; 50 } 51 52 ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) { 53 if (idx >= m_elements.size()) 54 return ValueObjectSP(); 55 if (!m_base_sp) 56 return ValueObjectSP(); 57 if (m_elements[idx]) 58 return m_elements[idx]; 59 60 CompilerType holder_type = 61 m_base_sp->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr); 62 if (!holder_type) 63 return ValueObjectSP(); 64 ValueObjectSP holder_sp = m_base_sp->GetChildAtIndex(idx, true); 65 if (!holder_sp) 66 return ValueObjectSP(); 67 68 ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true); 69 if (elem_sp) 70 m_elements[idx] = 71 elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())); 72 73 return m_elements[idx]; 74 } 75 76 SyntheticChildrenFrontEnd * 77 formatters::LibcxxTupleFrontEndCreator(CXXSyntheticChildren *, 78 lldb::ValueObjectSP valobj_sp) { 79 if (valobj_sp) 80 return new TupleFrontEnd(*valobj_sp); 81 return nullptr; 82 } 83