15ffd83dbSDimitry Andric //===-- LibStdcppTuple.cpp ------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "LibStdcpp.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h" 120b57cec5SDimitry Andric #include "lldb/DataFormatters/FormattersHelpers.h" 130b57cec5SDimitry Andric #include "lldb/DataFormatters/TypeSynthetic.h" 140b57cec5SDimitry Andric #include "lldb/Utility/ConstString.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include <memory> 170b57cec5SDimitry Andric #include <vector> 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric using namespace lldb; 200b57cec5SDimitry Andric using namespace lldb_private; 210b57cec5SDimitry Andric using namespace lldb_private::formatters; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace { 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric class LibStdcppTupleSyntheticFrontEnd : public SyntheticChildrenFrontEnd { 260b57cec5SDimitry Andric public: 270b57cec5SDimitry Andric explicit LibStdcppTupleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric size_t CalculateNumChildren() override; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric bool Update() override; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric bool MightHaveChildren() override; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric size_t GetIndexOfChildWithName(ConstString name) override; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric private: 409dba64beSDimitry Andric // The lifetime of a ValueObject and all its derivative ValueObjects 419dba64beSDimitry Andric // (children, clones, etc.) is managed by a ClusterManager. These 429dba64beSDimitry Andric // objects are only destroyed when every shared pointer to any of them 439dba64beSDimitry Andric // is destroyed, so we must not store a shared pointer to any ValueObject 449dba64beSDimitry Andric // derived from our backend ValueObject (since we're in the same cluster). 459dba64beSDimitry Andric std::vector<ValueObject*> m_members; 460b57cec5SDimitry Andric }; 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric } // end of anonymous namespace 490b57cec5SDimitry Andric LibStdcppTupleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)500b57cec5SDimitry AndricLibStdcppTupleSyntheticFrontEnd::LibStdcppTupleSyntheticFrontEnd( 510b57cec5SDimitry Andric lldb::ValueObjectSP valobj_sp) 520b57cec5SDimitry Andric : SyntheticChildrenFrontEnd(*valobj_sp) { 530b57cec5SDimitry Andric Update(); 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric Update()560b57cec5SDimitry Andricbool LibStdcppTupleSyntheticFrontEnd::Update() { 570b57cec5SDimitry Andric m_members.clear(); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric ValueObjectSP valobj_backend_sp = m_backend.GetSP(); 600b57cec5SDimitry Andric if (!valobj_backend_sp) 610b57cec5SDimitry Andric return false; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric ValueObjectSP next_child_sp = valobj_backend_sp->GetNonSyntheticValue(); 640b57cec5SDimitry Andric while (next_child_sp != nullptr) { 650b57cec5SDimitry Andric ValueObjectSP current_child = next_child_sp; 660b57cec5SDimitry Andric next_child_sp = nullptr; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric size_t child_count = current_child->GetNumChildren(); 690b57cec5SDimitry Andric for (size_t i = 0; i < child_count; ++i) { 7006c3fb27SDimitry Andric ValueObjectSP child_sp = current_child->GetChildAtIndex(i); 710b57cec5SDimitry Andric llvm::StringRef name_str = child_sp->GetName().GetStringRef(); 725f757f3fSDimitry Andric if (name_str.starts_with("std::_Tuple_impl<")) { 730b57cec5SDimitry Andric next_child_sp = child_sp; 745f757f3fSDimitry Andric } else if (name_str.starts_with("std::_Head_base<")) { 750b57cec5SDimitry Andric ValueObjectSP value_sp = 7606c3fb27SDimitry Andric child_sp->GetChildMemberWithName("_M_head_impl"); 770b57cec5SDimitry Andric if (value_sp) { 780b57cec5SDimitry Andric StreamString name; 790b57cec5SDimitry Andric name.Printf("[%zd]", m_members.size()); 809dba64beSDimitry Andric m_members.push_back(value_sp->Clone(ConstString(name.GetString())).get()); 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric return false; 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric MightHaveChildren()890b57cec5SDimitry Andricbool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric lldb::ValueObjectSP GetChildAtIndex(size_t idx)920b57cec5SDimitry AndricLibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(size_t idx) { 939dba64beSDimitry Andric if (idx < m_members.size() && m_members[idx]) 949dba64beSDimitry Andric return m_members[idx]->GetSP(); 950b57cec5SDimitry Andric return lldb::ValueObjectSP(); 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric CalculateNumChildren()980b57cec5SDimitry Andricsize_t LibStdcppTupleSyntheticFrontEnd::CalculateNumChildren() { 990b57cec5SDimitry Andric return m_members.size(); 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric GetIndexOfChildWithName(ConstString name)1020b57cec5SDimitry Andricsize_t LibStdcppTupleSyntheticFrontEnd::GetIndexOfChildWithName( 1030b57cec5SDimitry Andric ConstString name) { 1040b57cec5SDimitry Andric return ExtractIndexFromString(name.GetCString()); 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric SyntheticChildrenFrontEnd * LibStdcppTupleSyntheticFrontEndCreator(CXXSyntheticChildren *,lldb::ValueObjectSP valobj_sp)1080b57cec5SDimitry Andriclldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator( 1090b57cec5SDimitry Andric CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { 1100b57cec5SDimitry Andric return (valobj_sp ? new LibStdcppTupleSyntheticFrontEnd(valobj_sp) : nullptr); 1110b57cec5SDimitry Andric } 112