LLDB mainline
LibCxxTuple.cpp
Go to the documentation of this file.
1//===-- LibCxxTuple.cpp ---------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include "LibCxx.h"
11
12using namespace lldb;
13using namespace lldb_private;
14
15namespace {
16
17class TupleFrontEnd: public SyntheticChildrenFrontEnd {
18public:
19 TupleFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
20 Update();
21 }
22
23 lldb::ChildCacheState Update() override;
24 llvm::Expected<uint32_t> CalculateNumChildren() override {
25 return m_elements.size();
26 }
27 ValueObjectSP GetChildAtIndex(uint32_t idx) override;
28
29private:
30 // The lifetime of a ValueObject and all its derivative ValueObjects
31 // (children, clones, etc.) is managed by a ClusterManager. These
32 // objects are only destroyed when every shared pointer to any of them
33 // is destroyed, so we must not store a shared pointer to any ValueObject
34 // derived from our backend ValueObject (since we're in the same cluster).
35 std::vector<ValueObject*> m_elements;
36 ValueObject* m_base = nullptr;
37};
38}
39
40lldb::ChildCacheState TupleFrontEnd::Update() {
41 m_elements.clear();
42 m_base = nullptr;
43
44 ValueObjectSP base_sp;
45 base_sp = m_backend.GetChildMemberWithName("__base_");
46 if (!base_sp) {
47 // Pre r304382 name of the base element.
48 base_sp = m_backend.GetChildMemberWithName("base_");
49 }
50 if (!base_sp)
52 m_base = base_sp.get();
53 m_elements.assign(base_sp->GetCompilerType().GetNumDirectBaseClasses(),
54 nullptr);
56}
57
58ValueObjectSP TupleFrontEnd::GetChildAtIndex(uint32_t idx) {
59 if (idx >= m_elements.size())
60 return ValueObjectSP();
61 if (!m_base)
62 return ValueObjectSP();
63 if (m_elements[idx])
64 return m_elements[idx]->GetSP();
65
66 CompilerType holder_type =
67 m_base->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
68 if (!holder_type)
69 return ValueObjectSP();
70 ValueObjectSP holder_sp = m_base->GetChildAtIndex(idx);
71 if (!holder_sp)
72 return ValueObjectSP();
73
74 ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0);
75 if (elem_sp)
76 m_elements[idx] =
77 elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())).get();
78
79 if (m_elements[idx])
80 return m_elements[idx]->GetSP();
81 return ValueObjectSP();
82}
83
84SyntheticChildrenFrontEnd *
85formatters::LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
86 lldb::ValueObjectSP valobj_sp) {
87 if (valobj_sp)
88 return new TupleFrontEnd(*valobj_sp);
89 return nullptr;
90}
static std::optional< size_t > CalculateNumChildren(CompilerType container_elem_type, uint64_t num_elements, CompilerType element_type)
Calculates the number of elements stored in a container (with element type 'container_elem_type') as ...
CompilerType GetDirectBaseClassAtIndex(size_t idx, uint32_t *bit_offset_ptr) const
virtual lldb::ValueObjectSP GetChildAtIndex(uint32_t idx, bool can_create=true)
CompilerType GetCompilerType()
SyntheticChildrenFrontEnd * LibcxxTupleFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
A class that represents a running process on the host machine.
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
@ eRefetch
Children need to be recomputed dynamically.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP