LLDB mainline
VectorType.cpp
Go to the documentation of this file.
1//===-- VectorType.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
10
14#include "lldb/Target/Target.h"
17
19#include "lldb/Utility/Log.h"
20#include <optional>
21
22using namespace lldb;
23using namespace lldb_private;
24using namespace lldb_private::formatters;
25
27 CompilerType element_type,
28 TypeSystemSP type_system) {
29 lldbassert(type_system && "type_system needs to be not NULL");
30 if (!type_system)
31 return {};
32
33 switch (format) {
36 return type_system->GetBuiltinTypeForEncodingAndBitSize(
37 eEncodingUint, 8 * type_system->GetPointerByteSize());
38
40 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeBool);
41
47 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar);
48
49 case lldb::eFormatComplex /* lldb::eFormatComplexFloat */:
50 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloatComplex);
51
53 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar)
54 .GetPointerType();
55
57 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
59 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat128);
60
64 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeInt);
65
67 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
68
71
73 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeUnsignedInt);
74
76 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar);
77
79 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754,
80 32);
81
83 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754,
84 64);
85
87 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 16);
88
90 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
91
93 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
94
96 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 8);
97
99 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 128);
100
102 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
103
105 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
106
108 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 64);
109
111 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8);
112
114 return element_type;
115
123 default:
124 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8);
125 }
126}
127
129 CompilerType element_type) {
130 switch (format) {
132 return lldb::eFormatChar;
133
136 return lldb::eFormatFloat;
137
143
150
158 return eFormatHex;
159
161 // special case the (default, char) combination to actually display as an
162 // integer value most often, you won't want to see the ASCII characters...
163 // (and if you do, eFormatChar is a keystroke away)
164 bool is_char = element_type.IsCharType();
165 bool is_signed = false;
166 element_type.IsIntegerType(is_signed);
167 return is_char ? (is_signed ? lldb::eFormatDecimal : eFormatHex) : format;
168 } break;
169
170 default:
171 return format;
172 }
173}
174
175/// Calculates the number of elements stored in a container (with
176/// element type 'container_elem_type') as if it had elements of type
177/// 'element_type'.
178///
179/// For example, a container of type
180/// `uint8_t __attribute__((vector_size(16)))` has 16 elements.
181/// But calling `CalculateNumChildren` with an 'element_type'
182/// of `float` (4-bytes) will return `4` because we are interpreting
183/// the byte-array as a `float32[]`.
184///
185/// \param[in] container_elem_type The type of the elements stored
186/// in the container we are calculating the children of.
187///
188/// \param[in] num_elements Number of 'container_elem_type's our
189/// container stores.
190///
191/// \param[in] element_type The type of elements we interpret
192/// container_type to contain for the purposes of calculating
193/// the number of children.
194///
195/// \returns The number of elements stored in a container of
196/// type 'element_type'. Returns a std::nullopt if the
197/// size of the container is not a multiple of 'element_type'
198/// or if an error occurs.
199static std::optional<size_t>
200CalculateNumChildren(CompilerType container_elem_type, uint64_t num_elements,
201 CompilerType element_type) {
202 std::optional<uint64_t> container_elem_size = llvm::expectedToOptional(
203 container_elem_type.GetByteSize(/* exe_scope */ nullptr));
204 if (!container_elem_size)
205 return {};
206
207 auto container_size = *container_elem_size * num_elements;
208
209 std::optional<uint64_t> element_size = llvm::expectedToOptional(
210 element_type.GetByteSize(/* exe_scope */ nullptr));
211 if (!element_size || !*element_size)
212 return {};
213
214 if (container_size % *element_size)
215 return {};
216
217 return container_size / *element_size;
218}
219
220namespace lldb_private {
221namespace formatters {
222
224public:
227
228 ~VectorTypeSyntheticFrontEnd() override = default;
229
230 llvm::Expected<uint32_t> CalculateNumChildren() override {
231 return m_num_children;
232 }
233
234 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override {
235 auto num_children_or_err = CalculateNumChildren();
236 if (!num_children_or_err)
238 nullptr, Status::FromError(num_children_or_err.takeError()));
239 if (idx >= *num_children_or_err)
240 return {};
241 auto size_or_err = m_child_type.GetByteSize(nullptr);
242 if (!size_or_err)
244 nullptr, Status::FromError(size_or_err.takeError()));
245 auto offset = idx * *size_or_err;
246 StreamString idx_name;
247 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
248 ValueObjectSP child_sp(m_backend.GetSyntheticChildAtOffset(
249 offset, m_child_type, true, ConstString(idx_name.GetString())));
250 if (!child_sp)
251 return child_sp;
252
253 child_sp->SetFormat(m_item_format);
254
255 return child_sp;
256 }
257
259 m_parent_format = m_backend.GetFormat();
260 CompilerType parent_type(m_backend.GetCompilerType());
261 CompilerType element_type;
262 uint64_t num_elements;
263 parent_type.IsVectorType(&element_type, &num_elements);
265 m_parent_format, element_type,
266 parent_type.GetTypeSystem().GetSharedPointer());
268 ::CalculateNumChildren(element_type, num_elements, m_child_type)
269 .value_or(0);
272 }
273
274 llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override {
275 auto optional_idx = ExtractIndexFromString(name.AsCString());
276 if (!optional_idx) {
277 return llvm::createStringError("Type has no child named '%s'",
278 name.AsCString());
279 }
280 uint32_t idx = *optional_idx;
282 return llvm::createStringError("Type has no child named '%s'",
283 name.AsCString());
284 return idx;
285 }
286
287private:
291 size_t m_num_children = 0;
292};
293
294} // namespace formatters
295} // namespace lldb_private
296
298 ValueObject &valobj, Stream &s, const TypeSummaryOptions &) {
299 auto synthetic_children =
300 VectorTypeSyntheticFrontEndCreator(nullptr, valobj.GetSP());
301 if (!synthetic_children)
302 return false;
303
304 synthetic_children->Update();
305
306 s.PutChar('(');
307 bool first = true;
308
309 size_t idx = 0,
310 len = synthetic_children->CalculateNumChildrenIgnoringErrors();
311
312 for (; idx < len; idx++) {
313 auto child_sp = synthetic_children->GetChildAtIndex(idx);
314 if (!child_sp)
315 continue;
316 child_sp = child_sp->GetQualifiedRepresentationIfAvailable(
318
319 const char *child_value = child_sp->GetValueAsCString();
320 if (child_value && *child_value) {
321 if (first) {
322 s.Printf("%s", child_value);
323 first = false;
324 } else {
325 s.Printf(", %s", child_value);
326 }
327 }
328 }
329
330 s.PutChar(')');
331
332 return true;
333}
334
338 if (!valobj_sp)
339 return nullptr;
340 return new VectorTypeSyntheticFrontEnd(valobj_sp);
341}
#define lldbassert(x)
Definition LLDBAssert.h:16
static lldb::Format GetItemFormatForFormat(lldb::Format format, CompilerType element_type)
static CompilerType GetCompilerTypeForFormat(lldb::Format format, CompilerType element_type, TypeSystemSP type_system)
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 ...
Generic representation of a type in a programming language.
TypeSystemSPWrapper GetTypeSystem() const
Accessors.
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
bool IsIntegerType(bool &is_signed) const
bool IsVectorType(CompilerType *element_type=nullptr, uint64_t *size=nullptr) const
A uniqued constant string class.
Definition ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:137
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutChar(char ch)
Definition Stream.cpp:131
uint32_t CalculateNumChildrenIgnoringErrors(uint32_t max=UINT32_MAX)
SyntheticChildrenFrontEnd(ValueObject &backend)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
lldb::ValueObjectSP GetSP()
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
llvm::Expected< uint32_t > CalculateNumChildren() override
VectorTypeSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
std::optional< size_t > ExtractIndexFromString(const char *item_name)
bool VectorTypeSummaryProvider(ValueObject &, Stream &, const TypeSummaryOptions &)
SyntheticChildrenFrontEnd * VectorTypeSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::TypeSystem > TypeSystemSP
@ eBasicTypeFloatComplex
@ eBasicTypeUnsignedInt
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
Format
Display format definitions.
@ eFormatCString
NULL terminated C strings.
@ eFormatCharArray
Print characters with no single quotes, used for character arrays that can contain non printable char...
@ eFormatInstruction
Disassemble an opcode.
@ eFormatVectorOfChar
@ eFormatVectorOfUInt64
@ eFormatVoid
Do not print this.
@ eFormatVectorOfSInt64
@ eFormatComplex
Floating point complex type.
@ eFormatHexFloat
ISO C99 hex float string.
@ eFormatBytesWithASCII
@ eFormatOSType
OS character codes encoded into an integer 'PICT' 'text' etc...
@ eFormatAddressInfo
Describe what an address points to (func + offset with file/line, symbol + offset,...
@ eFormatVectorOfUInt128
@ eFormatVectorOfUInt8
@ eFormatVectorOfFloat32
@ eFormatVectorOfSInt32
@ eFormatVectorOfSInt8
@ eFormatVectorOfUInt16
@ eFormatHexUppercase
@ eFormatVectorOfFloat64
@ eFormatCharPrintable
Only printable characters, '.' if not printable.
@ eFormatComplexInteger
Integer complex type.
@ eFormatVectorOfSInt16
@ eFormatFloat128
Disambiguate between 128-bit long double (which uses eFormatFloat) and __float128 (which uses eFormat...
@ eFormatVectorOfUInt32
@ eEncodingIEEE754
float
@ eEncodingUint
unsigned integer
@ eEncodingSint
signed integer
@ eDynamicDontRunTarget