xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp (revision dda2819751e49c83612958492e38917049128b41)
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