1//===-- LibCxxValarray.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"
10
11#include "lldb/Core/ValueObject.h"
12#include "lldb/DataFormatters/FormattersHelpers.h"
13#include <optional>
14
15using namespace lldb;
16using namespace lldb_private;
17using namespace lldb_private::formatters;
18
19namespace lldb_private {
20namespace formatters {
21class LibcxxStdValarraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
22public:
23 LibcxxStdValarraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
24
25 ~LibcxxStdValarraySyntheticFrontEnd() override;
26
27 llvm::Expected<uint32_t> CalculateNumChildren() override;
28
29 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
30
31 lldb::ChildCacheState Update() override;
32
33 bool MightHaveChildren() override;
34
35 size_t GetIndexOfChildWithName(ConstString name) override;
36
37private:
38 /// A non-owning pointer to valarray's __begin_ member.
39 ValueObject *m_start = nullptr;
40 /// A non-owning pointer to valarray's __end_ member.
41 ValueObject *m_finish = nullptr;
42 /// The type of valarray's template argument T.
43 CompilerType m_element_type;
44 /// The sizeof valarray's template argument T.
45 uint32_t m_element_size = 0;
46};
47
48} // namespace formatters
49} // namespace lldb_private
50
51lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd::
52 LibcxxStdValarraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
53 : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {
54 if (valobj_sp)
55 Update();
56}
57
58lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd::
59 ~LibcxxStdValarraySyntheticFrontEnd() {
60 // these need to stay around because they are child objects who will follow
61 // their parent's life cycle
62 // delete m_start;
63 // delete m_finish;
64}
65
66llvm::Expected<uint32_t> lldb_private::formatters::
67 LibcxxStdValarraySyntheticFrontEnd::CalculateNumChildren() {
68 if (!m_start || !m_finish)
69 return 0;
70 uint64_t start_val = m_start->GetValueAsUnsigned(fail_value: 0);
71 uint64_t finish_val = m_finish->GetValueAsUnsigned(fail_value: 0);
72
73 if (start_val == 0 || finish_val == 0)
74 return 0;
75
76 if (start_val >= finish_val)
77 return 0;
78
79 size_t num_children = (finish_val - start_val);
80 if (num_children % m_element_size)
81 return 0;
82 return num_children / m_element_size;
83}
84
85lldb::ValueObjectSP
86lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd::GetChildAtIndex(
87 uint32_t idx) {
88 if (!m_start || !m_finish)
89 return lldb::ValueObjectSP();
90
91 uint64_t offset = idx * m_element_size;
92 offset = offset + m_start->GetValueAsUnsigned(fail_value: 0);
93 StreamString name;
94 name.Printf(format: "[%" PRIu64 "]", (uint64_t)idx);
95 return CreateValueObjectFromAddress(name: name.GetString(), address: offset,
96 exe_ctx: m_backend.GetExecutionContextRef(),
97 type: m_element_type);
98}
99
100lldb::ChildCacheState
101lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd::Update() {
102 m_start = m_finish = nullptr;
103
104 CompilerType type = m_backend.GetCompilerType();
105 if (type.GetNumTemplateArguments() == 0)
106 return ChildCacheState::eRefetch;
107
108 m_element_type = type.GetTypeTemplateArgument(idx: 0);
109 if (std::optional<uint64_t> size = m_element_type.GetByteSize(exe_scope: nullptr))
110 m_element_size = *size;
111
112 if (m_element_size == 0)
113 return ChildCacheState::eRefetch;
114
115 ValueObjectSP start = m_backend.GetChildMemberWithName(name: "__begin_");
116 ValueObjectSP finish = m_backend.GetChildMemberWithName(name: "__end_");
117
118 if (!start || !finish)
119 return ChildCacheState::eRefetch;
120
121 m_start = start.get();
122 m_finish = finish.get();
123
124 return ChildCacheState::eRefetch;
125}
126
127bool lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd::
128 MightHaveChildren() {
129 return true;
130}
131
132size_t lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd::
133 GetIndexOfChildWithName(ConstString name) {
134 if (!m_start || !m_finish)
135 return std::numeric_limits<size_t>::max();
136 return ExtractIndexFromString(item_name: name.GetCString());
137}
138
139lldb_private::SyntheticChildrenFrontEnd *
140lldb_private::formatters::LibcxxStdValarraySyntheticFrontEndCreator(
141 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
142 if (!valobj_sp)
143 return nullptr;
144 return new LibcxxStdValarraySyntheticFrontEnd(valobj_sp);
145}
146

source code of lldb/source/Plugins/Language/CPlusPlus/LibCxxValarray.cpp