xref: /src/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1ac9a064cSDimitry Andric //===-- LibCxxSliceArray.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 
LibcxxStdSliceArraySummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions & options)22ac9a064cSDimitry Andric bool LibcxxStdSliceArraySummaryProvider(ValueObject &valobj, Stream &stream,
23ac9a064cSDimitry Andric                                         const TypeSummaryOptions &options) {
24ac9a064cSDimitry Andric   ValueObjectSP obj = valobj.GetNonSyntheticValue();
25ac9a064cSDimitry Andric   if (!obj)
26ac9a064cSDimitry Andric     return false;
27ac9a064cSDimitry Andric 
28ac9a064cSDimitry Andric   ValueObjectSP ptr_sp = obj->GetChildMemberWithName("__size_");
29ac9a064cSDimitry Andric   if (!ptr_sp)
30ac9a064cSDimitry Andric     return false;
31ac9a064cSDimitry Andric   const size_t size = ptr_sp->GetValueAsUnsigned(0);
32ac9a064cSDimitry Andric 
33ac9a064cSDimitry Andric   ptr_sp = obj->GetChildMemberWithName("__stride_");
34ac9a064cSDimitry Andric   if (!ptr_sp)
35ac9a064cSDimitry Andric     return false;
36ac9a064cSDimitry Andric   const size_t stride = ptr_sp->GetValueAsUnsigned(0);
37ac9a064cSDimitry Andric 
38ac9a064cSDimitry Andric   stream.Printf("stride=%zu size=%zu", stride, size);
39ac9a064cSDimitry Andric 
40ac9a064cSDimitry Andric   return true;
41ac9a064cSDimitry Andric }
42ac9a064cSDimitry Andric 
43ac9a064cSDimitry Andric /// Data formatter for libc++'s std::slice_array.
44ac9a064cSDimitry Andric ///
45ac9a064cSDimitry Andric /// A slice_array is created by using:
46ac9a064cSDimitry Andric ///   operator[](std::slice slicearr);
47ac9a064cSDimitry Andric /// and std::slice is created by:
48ac9a064cSDimitry Andric ///   slice(std::size_t start, std::size_t size, std::size_t stride);
49ac9a064cSDimitry Andric /// The std::slice_array has the following members:
50ac9a064cSDimitry Andric /// - __vp_ points to std::valarray::__begin_ + @a start
51ac9a064cSDimitry Andric /// - __size_ is @a size
52ac9a064cSDimitry Andric /// - __stride_is @a stride
53ac9a064cSDimitry Andric class LibcxxStdSliceArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
54ac9a064cSDimitry Andric public:
55ac9a064cSDimitry Andric   LibcxxStdSliceArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
56ac9a064cSDimitry Andric 
57ac9a064cSDimitry Andric   ~LibcxxStdSliceArraySyntheticFrontEnd() override;
58ac9a064cSDimitry Andric 
59ac9a064cSDimitry Andric   llvm::Expected<uint32_t> CalculateNumChildren() override;
60ac9a064cSDimitry Andric 
61ac9a064cSDimitry Andric   lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
62ac9a064cSDimitry Andric 
63ac9a064cSDimitry Andric   lldb::ChildCacheState Update() override;
64ac9a064cSDimitry Andric 
65ac9a064cSDimitry Andric   bool MightHaveChildren() override;
66ac9a064cSDimitry Andric 
67ac9a064cSDimitry Andric   size_t GetIndexOfChildWithName(ConstString name) override;
68ac9a064cSDimitry Andric 
69ac9a064cSDimitry Andric private:
70ac9a064cSDimitry Andric   /// A non-owning pointer to slice_array.__vp_.
71ac9a064cSDimitry Andric   ValueObject *m_start = nullptr;
72ac9a064cSDimitry Andric   /// slice_array.__size_.
73ac9a064cSDimitry Andric   size_t m_size = 0;
74ac9a064cSDimitry Andric   /// slice_array.__stride_.
75ac9a064cSDimitry Andric   size_t m_stride = 0;
76ac9a064cSDimitry Andric   /// The type of slice_array's template argument T.
77ac9a064cSDimitry Andric   CompilerType m_element_type;
78ac9a064cSDimitry Andric   /// The sizeof slice_array's template argument T.
79ac9a064cSDimitry Andric   uint32_t m_element_size = 0;
80ac9a064cSDimitry Andric };
81ac9a064cSDimitry Andric 
82ac9a064cSDimitry Andric } // namespace formatters
83ac9a064cSDimitry Andric } // namespace lldb_private
84ac9a064cSDimitry Andric 
85ac9a064cSDimitry Andric lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
LibcxxStdSliceArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)86ac9a064cSDimitry Andric     LibcxxStdSliceArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
87ac9a064cSDimitry Andric     : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {
88ac9a064cSDimitry Andric   if (valobj_sp)
89ac9a064cSDimitry Andric     Update();
90ac9a064cSDimitry Andric }
91ac9a064cSDimitry Andric 
92ac9a064cSDimitry Andric lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
~LibcxxStdSliceArraySyntheticFrontEnd()93ac9a064cSDimitry Andric     ~LibcxxStdSliceArraySyntheticFrontEnd() {
94ac9a064cSDimitry Andric   // these need to stay around because they are child objects who will follow
95ac9a064cSDimitry Andric   // their parent's life cycle
96ac9a064cSDimitry Andric   // delete m_start;
97ac9a064cSDimitry Andric }
98ac9a064cSDimitry Andric 
99ac9a064cSDimitry Andric llvm::Expected<uint32_t> lldb_private::formatters::
CalculateNumChildren()100ac9a064cSDimitry Andric     LibcxxStdSliceArraySyntheticFrontEnd::CalculateNumChildren() {
101ac9a064cSDimitry Andric   return m_size;
102ac9a064cSDimitry Andric }
103ac9a064cSDimitry Andric 
104ac9a064cSDimitry Andric lldb::ValueObjectSP
GetChildAtIndex(uint32_t idx)105ac9a064cSDimitry Andric lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::GetChildAtIndex(
106ac9a064cSDimitry Andric     uint32_t idx) {
107ac9a064cSDimitry Andric   if (!m_start)
108ac9a064cSDimitry Andric     return lldb::ValueObjectSP();
109ac9a064cSDimitry Andric 
110ac9a064cSDimitry Andric   uint64_t offset = idx * m_stride * m_element_size;
111ac9a064cSDimitry Andric   offset = offset + m_start->GetValueAsUnsigned(0);
112ac9a064cSDimitry Andric   StreamString name;
113ac9a064cSDimitry Andric   name.Printf("[%" PRIu64 "]", (uint64_t)idx);
114ac9a064cSDimitry Andric   return CreateValueObjectFromAddress(name.GetString(), offset,
115ac9a064cSDimitry Andric                                       m_backend.GetExecutionContextRef(),
116ac9a064cSDimitry Andric                                       m_element_type);
117ac9a064cSDimitry Andric }
118ac9a064cSDimitry Andric 
119ac9a064cSDimitry Andric lldb::ChildCacheState
Update()120ac9a064cSDimitry Andric lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::Update() {
121ac9a064cSDimitry Andric   m_start = nullptr;
122ac9a064cSDimitry Andric 
123ac9a064cSDimitry Andric   CompilerType type = m_backend.GetCompilerType();
124ac9a064cSDimitry Andric   if (type.GetNumTemplateArguments() == 0)
125ac9a064cSDimitry Andric     return ChildCacheState::eRefetch;
126ac9a064cSDimitry Andric 
127ac9a064cSDimitry Andric   m_element_type = type.GetTypeTemplateArgument(0);
128ac9a064cSDimitry Andric   if (std::optional<uint64_t> size = m_element_type.GetByteSize(nullptr))
129ac9a064cSDimitry Andric     m_element_size = *size;
130ac9a064cSDimitry Andric 
131ac9a064cSDimitry Andric   if (m_element_size == 0)
132ac9a064cSDimitry Andric     return ChildCacheState::eRefetch;
133ac9a064cSDimitry Andric 
134ac9a064cSDimitry Andric   ValueObjectSP start = m_backend.GetChildMemberWithName("__vp_");
135ac9a064cSDimitry Andric   ValueObjectSP size = m_backend.GetChildMemberWithName("__size_");
136ac9a064cSDimitry Andric   ValueObjectSP stride = m_backend.GetChildMemberWithName("__stride_");
137ac9a064cSDimitry Andric 
138ac9a064cSDimitry Andric   if (!start || !size || !stride)
139ac9a064cSDimitry Andric     return ChildCacheState::eRefetch;
140ac9a064cSDimitry Andric 
141ac9a064cSDimitry Andric   m_start = start.get();
142ac9a064cSDimitry Andric   m_size = size->GetValueAsUnsigned(0);
143ac9a064cSDimitry Andric   m_stride = stride->GetValueAsUnsigned(0);
144ac9a064cSDimitry Andric 
145ac9a064cSDimitry Andric   return ChildCacheState::eRefetch;
146ac9a064cSDimitry Andric }
147ac9a064cSDimitry Andric 
148ac9a064cSDimitry Andric bool lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
MightHaveChildren()149ac9a064cSDimitry Andric     MightHaveChildren() {
150ac9a064cSDimitry Andric   return true;
151ac9a064cSDimitry Andric }
152ac9a064cSDimitry Andric 
153ac9a064cSDimitry Andric size_t lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
GetIndexOfChildWithName(ConstString name)154ac9a064cSDimitry Andric     GetIndexOfChildWithName(ConstString name) {
155ac9a064cSDimitry Andric   if (!m_start)
156ac9a064cSDimitry Andric     return std::numeric_limits<size_t>::max();
157ac9a064cSDimitry Andric   return ExtractIndexFromString(name.GetCString());
158ac9a064cSDimitry Andric }
159ac9a064cSDimitry Andric 
160ac9a064cSDimitry Andric lldb_private::SyntheticChildrenFrontEnd *
LibcxxStdSliceArraySyntheticFrontEndCreator(CXXSyntheticChildren *,lldb::ValueObjectSP valobj_sp)161ac9a064cSDimitry Andric lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator(
162ac9a064cSDimitry Andric     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
163ac9a064cSDimitry Andric   if (!valobj_sp)
164ac9a064cSDimitry Andric     return nullptr;
165ac9a064cSDimitry Andric   return new LibcxxStdSliceArraySyntheticFrontEnd(valobj_sp);
166ac9a064cSDimitry Andric }
167