1*dda28197Spatrick //===-- LibCxxTuple.cpp ---------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "LibCxx.h"
10061da546Spatrick #include "lldb/DataFormatters/FormattersHelpers.h"
11061da546Spatrick
12061da546Spatrick using namespace lldb;
13061da546Spatrick using namespace lldb_private;
14061da546Spatrick
15061da546Spatrick namespace {
16061da546Spatrick
17061da546Spatrick class TupleFrontEnd: public SyntheticChildrenFrontEnd {
18061da546Spatrick public:
TupleFrontEnd(ValueObject & valobj)19061da546Spatrick TupleFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
20061da546Spatrick Update();
21061da546Spatrick }
22061da546Spatrick
GetIndexOfChildWithName(ConstString name)23061da546Spatrick size_t GetIndexOfChildWithName(ConstString name) override {
24061da546Spatrick return formatters::ExtractIndexFromString(name.GetCString());
25061da546Spatrick }
26061da546Spatrick
MightHaveChildren()27061da546Spatrick bool MightHaveChildren() override { return true; }
28061da546Spatrick bool Update() override;
CalculateNumChildren()29061da546Spatrick size_t CalculateNumChildren() override { return m_elements.size(); }
30061da546Spatrick ValueObjectSP GetChildAtIndex(size_t idx) override;
31061da546Spatrick
32061da546Spatrick private:
33061da546Spatrick // The lifetime of a ValueObject and all its derivative ValueObjects
34061da546Spatrick // (children, clones, etc.) is managed by a ClusterManager. These
35061da546Spatrick // objects are only destroyed when every shared pointer to any of them
36061da546Spatrick // is destroyed, so we must not store a shared pointer to any ValueObject
37061da546Spatrick // derived from our backend ValueObject (since we're in the same cluster).
38061da546Spatrick std::vector<ValueObject*> m_elements;
39061da546Spatrick ValueObject* m_base = nullptr;
40061da546Spatrick };
41061da546Spatrick }
42061da546Spatrick
Update()43061da546Spatrick bool TupleFrontEnd::Update() {
44061da546Spatrick m_elements.clear();
45061da546Spatrick m_base = nullptr;
46061da546Spatrick
47061da546Spatrick ValueObjectSP base_sp;
48061da546Spatrick base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true);
49061da546Spatrick if (!base_sp) {
50061da546Spatrick // Pre r304382 name of the base element.
51061da546Spatrick base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true);
52061da546Spatrick }
53061da546Spatrick if (!base_sp)
54061da546Spatrick return false;
55061da546Spatrick m_base = base_sp.get();
56061da546Spatrick m_elements.assign(base_sp->GetCompilerType().GetNumDirectBaseClasses(),
57061da546Spatrick nullptr);
58061da546Spatrick return false;
59061da546Spatrick }
60061da546Spatrick
GetChildAtIndex(size_t idx)61061da546Spatrick ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) {
62061da546Spatrick if (idx >= m_elements.size())
63061da546Spatrick return ValueObjectSP();
64061da546Spatrick if (!m_base)
65061da546Spatrick return ValueObjectSP();
66061da546Spatrick if (m_elements[idx])
67061da546Spatrick return m_elements[idx]->GetSP();
68061da546Spatrick
69061da546Spatrick CompilerType holder_type =
70061da546Spatrick m_base->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
71061da546Spatrick if (!holder_type)
72061da546Spatrick return ValueObjectSP();
73061da546Spatrick ValueObjectSP holder_sp = m_base->GetChildAtIndex(idx, true);
74061da546Spatrick if (!holder_sp)
75061da546Spatrick return ValueObjectSP();
76061da546Spatrick
77061da546Spatrick ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true);
78061da546Spatrick if (elem_sp)
79061da546Spatrick m_elements[idx] =
80061da546Spatrick elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())).get();
81061da546Spatrick
82061da546Spatrick if (m_elements[idx])
83061da546Spatrick return m_elements[idx]->GetSP();
84061da546Spatrick return ValueObjectSP();
85061da546Spatrick }
86061da546Spatrick
87061da546Spatrick SyntheticChildrenFrontEnd *
LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,lldb::ValueObjectSP valobj_sp)88061da546Spatrick formatters::LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
89061da546Spatrick lldb::ValueObjectSP valobj_sp) {
90061da546Spatrick if (valobj_sp)
91061da546Spatrick return new TupleFrontEnd(*valobj_sp);
92061da546Spatrick return nullptr;
93061da546Spatrick }
94