Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
39642 views
//===-- LibStdcppTuple.cpp ------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "LibStdcpp.h"910#include "lldb/Core/ValueObject.h"11#include "lldb/DataFormatters/FormattersHelpers.h"12#include "lldb/DataFormatters/TypeSynthetic.h"13#include "lldb/Utility/ConstString.h"1415#include <memory>16#include <vector>1718using namespace lldb;19using namespace lldb_private;20using namespace lldb_private::formatters;2122namespace {2324class LibStdcppTupleSyntheticFrontEnd : public SyntheticChildrenFrontEnd {25public:26explicit LibStdcppTupleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);2728llvm::Expected<uint32_t> CalculateNumChildren() override;2930lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;3132lldb::ChildCacheState Update() override;3334bool MightHaveChildren() override;3536size_t GetIndexOfChildWithName(ConstString name) override;3738private:39// The lifetime of a ValueObject and all its derivative ValueObjects40// (children, clones, etc.) is managed by a ClusterManager. These41// objects are only destroyed when every shared pointer to any of them42// is destroyed, so we must not store a shared pointer to any ValueObject43// derived from our backend ValueObject (since we're in the same cluster).44std::vector<ValueObject*> m_members;45};4647} // end of anonymous namespace4849LibStdcppTupleSyntheticFrontEnd::LibStdcppTupleSyntheticFrontEnd(50lldb::ValueObjectSP valobj_sp)51: SyntheticChildrenFrontEnd(*valobj_sp) {52Update();53}5455lldb::ChildCacheState LibStdcppTupleSyntheticFrontEnd::Update() {56m_members.clear();5758ValueObjectSP valobj_backend_sp = m_backend.GetSP();59if (!valobj_backend_sp)60return lldb::ChildCacheState::eRefetch;6162ValueObjectSP next_child_sp = valobj_backend_sp->GetNonSyntheticValue();63while (next_child_sp != nullptr) {64ValueObjectSP current_child = next_child_sp;65next_child_sp = nullptr;6667size_t child_count = current_child->GetNumChildrenIgnoringErrors();68for (size_t i = 0; i < child_count; ++i) {69ValueObjectSP child_sp = current_child->GetChildAtIndex(i);70llvm::StringRef name_str = child_sp->GetName().GetStringRef();71if (name_str.starts_with("std::_Tuple_impl<")) {72next_child_sp = child_sp;73} else if (name_str.starts_with("std::_Head_base<")) {74ValueObjectSP value_sp =75child_sp->GetChildMemberWithName("_M_head_impl");76if (value_sp) {77StreamString name;78name.Printf("[%zd]", m_members.size());79m_members.push_back(value_sp->Clone(ConstString(name.GetString())).get());80}81}82}83}8485return lldb::ChildCacheState::eRefetch;86}8788bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; }8990lldb::ValueObjectSP91LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(uint32_t idx) {92if (idx < m_members.size() && m_members[idx])93return m_members[idx]->GetSP();94return lldb::ValueObjectSP();95}9697llvm::Expected<uint32_t>98LibStdcppTupleSyntheticFrontEnd::CalculateNumChildren() {99return m_members.size();100}101102size_t LibStdcppTupleSyntheticFrontEnd::GetIndexOfChildWithName(103ConstString name) {104return ExtractIndexFromString(name.GetCString());105}106107SyntheticChildrenFrontEnd *108lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator(109CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {110return (valobj_sp ? new LibStdcppTupleSyntheticFrontEnd(valobj_sp) : nullptr);111}112113114