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 29*0fca6ea1SDimitry Andric llvm::Expected<uint32_t> CalculateNumChildren() override; 300b57cec5SDimitry Andric 31*0fca6ea1SDimitry Andric lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override; 320b57cec5SDimitry Andric 33*0fca6ea1SDimitry Andric lldb::ChildCacheState 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 500b57cec5SDimitry Andric LibStdcppTupleSyntheticFrontEnd::LibStdcppTupleSyntheticFrontEnd( 510b57cec5SDimitry Andric lldb::ValueObjectSP valobj_sp) 520b57cec5SDimitry Andric : SyntheticChildrenFrontEnd(*valobj_sp) { 530b57cec5SDimitry Andric Update(); 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric 56*0fca6ea1SDimitry Andric lldb::ChildCacheState LibStdcppTupleSyntheticFrontEnd::Update() { 570b57cec5SDimitry Andric m_members.clear(); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric ValueObjectSP valobj_backend_sp = m_backend.GetSP(); 600b57cec5SDimitry Andric if (!valobj_backend_sp) 61*0fca6ea1SDimitry Andric return lldb::ChildCacheState::eRefetch; 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 68*0fca6ea1SDimitry Andric size_t child_count = current_child->GetNumChildrenIgnoringErrors(); 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 86*0fca6ea1SDimitry Andric return lldb::ChildCacheState::eRefetch; 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric lldb::ValueObjectSP 92*0fca6ea1SDimitry Andric LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(uint32_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 98*0fca6ea1SDimitry Andric llvm::Expected<uint32_t> 99*0fca6ea1SDimitry Andric LibStdcppTupleSyntheticFrontEnd::CalculateNumChildren() { 1000b57cec5SDimitry Andric return m_members.size(); 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric size_t LibStdcppTupleSyntheticFrontEnd::GetIndexOfChildWithName( 1040b57cec5SDimitry Andric ConstString name) { 1050b57cec5SDimitry Andric return ExtractIndexFromString(name.GetCString()); 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric SyntheticChildrenFrontEnd * 1090b57cec5SDimitry Andric lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator( 1100b57cec5SDimitry Andric CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { 1110b57cec5SDimitry Andric return (valobj_sp ? new LibStdcppTupleSyntheticFrontEnd(valobj_sp) : nullptr); 1120b57cec5SDimitry Andric } 113