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