LLDB mainline
LibCxxSpan.cpp
Go to the documentation of this file.
1//===-- LibCxxSpan.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
14#include "llvm/ADT/APSInt.h"
15#include <optional>
16
17using namespace lldb;
18using namespace lldb_private;
19using namespace lldb_private::formatters;
20
21namespace lldb_private {
22namespace formatters {
23
25public:
27
28 ~LibcxxStdSpanSyntheticFrontEnd() override = default;
29
30 llvm::Expected<uint32_t> CalculateNumChildren() override;
31
32 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
33
34 /// Determines properties of the std::span<> associated with this object
35 //
36 // std::span can either be instantiated with a compile-time known
37 // extent or a std::dynamic_extent (this is the default if only the
38 // type template argument is provided). The layout of std::span
39 // depends on whether the extent is dynamic or not. For static
40 // extents (e.g., std::span<int, 9>):
41 //
42 // (std::__1::span<const int, 9>) s = {
43 // __data = 0x000000016fdff494
44 // }
45 //
46 // For dynamic extents, e.g., std::span<int>, the layout is:
47 //
48 // (std::__1::span<const int, 18446744073709551615>) s = {
49 // __data = 0x000000016fdff494
50 // __size = 6
51 // }
52 //
53 // This function checks for a '__size' member to determine the number
54 // of elements in the span. If no such member exists, we get the size
55 // from the only other place it can be: the template argument.
57
58 bool MightHaveChildren() override;
59
60 size_t GetIndexOfChildWithName(ConstString name) override;
61
62private:
63 ValueObject *m_start = nullptr; ///< First element of span. Held, not owned.
64 CompilerType m_element_type{}; ///< Type of span elements.
65 size_t m_num_elements = 0; ///< Number of elements in span.
66 uint32_t m_element_size = 0; ///< Size in bytes of each span element.
67};
68
71 : SyntheticChildrenFrontEnd(*valobj_sp) {
72 if (valobj_sp)
73 Update();
74}
75
76llvm::Expected<uint32_t> lldb_private::formatters::
78 return m_num_elements;
79}
80
83 uint32_t idx) {
84 if (!m_start)
85 return {};
86
87 uint64_t offset = idx * m_element_size;
88 offset = offset + m_start->GetValueAsUnsigned(0);
89 StreamString name;
90 name.Printf("[%" PRIu64 "]", (uint64_t)idx);
91 return CreateValueObjectFromAddress(name.GetString(), offset,
92 m_backend.GetExecutionContextRef(),
93 m_element_type);
94}
95
98 // Get element type.
99 ValueObjectSP data_type_finder_sp = GetChildMemberWithName(
100 m_backend, {ConstString("__data_"), ConstString("__data")});
101 if (!data_type_finder_sp)
103
104 m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType();
105
106 // Get element size.
107 if (std::optional<uint64_t> size = m_element_type.GetByteSize(nullptr)) {
108 m_element_size = *size;
109
110 // Get data.
111 if (m_element_size > 0) {
112 m_start = data_type_finder_sp.get();
113 }
114
115 // Get number of elements.
116 if (auto size_sp = GetChildMemberWithName(
117 m_backend, {ConstString("__size_"), ConstString("__size")})) {
118 m_num_elements = size_sp->GetValueAsUnsigned(0);
119 } else if (auto arg =
120 m_backend.GetCompilerType().GetIntegralTemplateArgument(1)) {
121
122 m_num_elements = arg->value.getLimitedValue();
123 }
124 }
125
127}
128
131 return true;
132}
133
136 if (!m_start)
137 return UINT32_MAX;
138 return ExtractIndexFromString(name.GetCString());
139}
140
143 lldb::ValueObjectSP valobj_sp) {
144 if (!valobj_sp)
145 return nullptr;
146 CompilerType type = valobj_sp->GetCompilerType();
147 if (!type.IsValid() || type.GetNumTemplateArguments() != 2)
148 return nullptr;
149 return new LibcxxStdSpanSyntheticFrontEnd(valobj_sp);
150}
151
152} // namespace formatters
153} // namespace lldb_private
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
size_t GetNumTemplateArguments(bool expand_pack=false) const
Return the number of template arguments the type has.
A uniqued constant string class.
Definition: ConstString.h:40
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:214
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:134
LibcxxStdSpanSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition: LibCxxSpan.cpp:70
CompilerType m_element_type
Type of span elements.
Definition: LibCxxSpan.cpp:64
lldb::ChildCacheState Update() override
Determines properties of the std::span<> associated with this object.
Definition: LibCxxSpan.cpp:97
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
Definition: LibCxxSpan.cpp:82
ValueObject * m_start
First element of span. Held, not owned.
Definition: LibCxxSpan.cpp:63
llvm::Expected< uint32_t > CalculateNumChildren() override
Definition: LibCxxSpan.cpp:77
size_t m_num_elements
Number of elements in span.
Definition: LibCxxSpan.cpp:65
uint32_t m_element_size
Size in bytes of each span element.
Definition: LibCxxSpan.cpp:66
size_t GetIndexOfChildWithName(ConstString name) override
Definition: LibCxxSpan.cpp:135
#define UINT32_MAX
Definition: lldb-defines.h:19
SyntheticChildrenFrontEnd * LibcxxStdSpanSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxxSpan.cpp:142
lldb::ValueObjectSP GetChildMemberWithName(ValueObject &obj, llvm::ArrayRef< ConstString > alternative_names)
Find a child member of obj_sp, trying all alternative names in order.
Definition: LibCxx.cpp:37
size_t ExtractIndexFromString(const char *item_name)
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Definition: SBAddress.h:15
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
@ eRefetch
Children need to be recomputed dynamically.
@ eReuse
Children did not change and don't need to be recomputed; re-use what we computed the last time we cal...
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Definition: lldb-forward.h:472