1 //===-- LibStdcppTuple.cpp ------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
11 #include "lldb/DataFormatters/FormattersHelpers.h"
12 #include "lldb/DataFormatters/TypeSynthetic.h"
13 #include "lldb/Utility/ConstString.h"
14 #include "lldb/ValueObject/ValueObject.h"
20 using namespace lldb_private
;
21 using namespace lldb_private::formatters
;
25 class LibStdcppTupleSyntheticFrontEnd
: public SyntheticChildrenFrontEnd
{
27 explicit LibStdcppTupleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp
);
29 llvm::Expected
<uint32_t> CalculateNumChildren() override
;
31 lldb::ValueObjectSP
GetChildAtIndex(uint32_t idx
) override
;
33 lldb::ChildCacheState
Update() override
;
35 bool MightHaveChildren() override
;
37 size_t GetIndexOfChildWithName(ConstString name
) override
;
40 // The lifetime of a ValueObject and all its derivative ValueObjects
41 // (children, clones, etc.) is managed by a ClusterManager. These
42 // objects are only destroyed when every shared pointer to any of them
43 // is destroyed, so we must not store a shared pointer to any ValueObject
44 // derived from our backend ValueObject (since we're in the same cluster).
45 std::vector
<ValueObject
*> m_members
;
48 } // end of anonymous namespace
50 LibStdcppTupleSyntheticFrontEnd::LibStdcppTupleSyntheticFrontEnd(
51 lldb::ValueObjectSP valobj_sp
)
52 : SyntheticChildrenFrontEnd(*valobj_sp
) {
56 lldb::ChildCacheState
LibStdcppTupleSyntheticFrontEnd::Update() {
59 ValueObjectSP valobj_backend_sp
= m_backend
.GetSP();
60 if (!valobj_backend_sp
)
61 return lldb::ChildCacheState::eRefetch
;
63 ValueObjectSP next_child_sp
= valobj_backend_sp
->GetNonSyntheticValue();
64 while (next_child_sp
!= nullptr) {
65 ValueObjectSP current_child
= next_child_sp
;
66 next_child_sp
= nullptr;
68 size_t child_count
= current_child
->GetNumChildrenIgnoringErrors();
69 for (size_t i
= 0; i
< child_count
; ++i
) {
70 ValueObjectSP child_sp
= current_child
->GetChildAtIndex(i
);
71 llvm::StringRef name_str
= child_sp
->GetName().GetStringRef();
72 if (name_str
.starts_with("std::_Tuple_impl<")) {
73 next_child_sp
= child_sp
;
74 } else if (name_str
.starts_with("std::_Head_base<")) {
75 ValueObjectSP value_sp
=
76 child_sp
->GetChildMemberWithName("_M_head_impl");
79 name
.Printf("[%zd]", m_members
.size());
80 m_members
.push_back(value_sp
->Clone(ConstString(name
.GetString())).get());
86 return lldb::ChildCacheState::eRefetch
;
89 bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; }
92 LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(uint32_t idx
) {
93 if (idx
< m_members
.size() && m_members
[idx
])
94 return m_members
[idx
]->GetSP();
95 return lldb::ValueObjectSP();
98 llvm::Expected
<uint32_t>
99 LibStdcppTupleSyntheticFrontEnd::CalculateNumChildren() {
100 return m_members
.size();
103 size_t LibStdcppTupleSyntheticFrontEnd::GetIndexOfChildWithName(
105 return ExtractIndexFromString(name
.GetCString());
108 SyntheticChildrenFrontEnd
*
109 lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator(
110 CXXSyntheticChildren
*, lldb::ValueObjectSP valobj_sp
) {
111 return (valobj_sp
? new LibStdcppTupleSyntheticFrontEnd(valobj_sp
) : nullptr);