1 //===-- VectorType.cpp ------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/DataFormatters/VectorType.h"
11 #include "lldb/Core/ValueObject.h"
12 #include "lldb/DataFormatters/FormattersHelpers.h"
13 #include "lldb/Symbol/CompilerType.h"
14 #include "lldb/Symbol/TypeSystem.h"
15 #include "lldb/Target/Target.h"
17 #include "lldb/Utility/LLDBAssert.h"
20 using namespace lldb_private;
21 using namespace lldb_private::formatters;
23 static CompilerType GetCompilerTypeForFormat(lldb::Format format,
24 CompilerType element_type,
25 TypeSystem *type_system) {
26 lldbassert(type_system && "type_system needs to be not NULL");
29 case lldb::eFormatAddressInfo:
30 case lldb::eFormatPointer:
31 return type_system->GetBuiltinTypeForEncodingAndBitSize(
32 eEncodingUint, 8 * type_system->GetPointerByteSize());
34 case lldb::eFormatBoolean:
35 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeBool);
37 case lldb::eFormatBytes:
38 case lldb::eFormatBytesWithASCII:
39 case lldb::eFormatChar:
40 case lldb::eFormatCharArray:
41 case lldb::eFormatCharPrintable:
42 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar);
44 case lldb::eFormatComplex /* lldb::eFormatComplexFloat */:
45 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloatComplex);
47 case lldb::eFormatCString:
48 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar)
51 case lldb::eFormatFloat:
52 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
54 case lldb::eFormatHex:
55 case lldb::eFormatHexUppercase:
56 case lldb::eFormatOctal:
57 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeInt);
59 case lldb::eFormatHexFloat:
60 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
62 case lldb::eFormatUnicode16:
63 case lldb::eFormatUnicode32:
65 case lldb::eFormatUnsigned:
66 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeUnsignedInt);
68 case lldb::eFormatVectorOfChar:
69 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar);
71 case lldb::eFormatVectorOfFloat32:
72 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754,
75 case lldb::eFormatVectorOfFloat64:
76 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754,
79 case lldb::eFormatVectorOfSInt16:
80 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 16);
82 case lldb::eFormatVectorOfSInt32:
83 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
85 case lldb::eFormatVectorOfSInt64:
86 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
88 case lldb::eFormatVectorOfSInt8:
89 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 8);
91 case lldb::eFormatVectorOfUInt128:
92 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 128);
94 case lldb::eFormatVectorOfUInt16:
95 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
97 case lldb::eFormatVectorOfUInt32:
98 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
100 case lldb::eFormatVectorOfUInt64:
101 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 64);
103 case lldb::eFormatVectorOfUInt8:
104 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8);
106 case lldb::eFormatDefault:
109 case lldb::eFormatBinary:
110 case lldb::eFormatComplexInteger:
111 case lldb::eFormatDecimal:
112 case lldb::eFormatEnum:
113 case lldb::eFormatInstruction:
114 case lldb::eFormatOSType:
115 case lldb::eFormatVoid:
117 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8);
121 static lldb::Format GetItemFormatForFormat(lldb::Format format,
122 CompilerType element_type) {
124 case lldb::eFormatVectorOfChar:
125 return lldb::eFormatChar;
127 case lldb::eFormatVectorOfFloat32:
128 case lldb::eFormatVectorOfFloat64:
129 return lldb::eFormatFloat;
131 case lldb::eFormatVectorOfSInt16:
132 case lldb::eFormatVectorOfSInt32:
133 case lldb::eFormatVectorOfSInt64:
134 case lldb::eFormatVectorOfSInt8:
135 return lldb::eFormatDecimal;
137 case lldb::eFormatVectorOfUInt128:
138 case lldb::eFormatVectorOfUInt16:
139 case lldb::eFormatVectorOfUInt32:
140 case lldb::eFormatVectorOfUInt64:
141 case lldb::eFormatVectorOfUInt8:
142 return lldb::eFormatUnsigned;
144 case lldb::eFormatBinary:
145 case lldb::eFormatComplexInteger:
146 case lldb::eFormatDecimal:
147 case lldb::eFormatEnum:
148 case lldb::eFormatInstruction:
149 case lldb::eFormatOSType:
150 case lldb::eFormatVoid:
153 case lldb::eFormatDefault: {
154 // special case the (default, char) combination to actually display as an
155 // integer value most often, you won't want to see the ASCII characters...
156 // (and if you do, eFormatChar is a keystroke away)
157 bool is_char = element_type.IsCharType();
158 bool is_signed = false;
159 element_type.IsIntegerType(is_signed);
160 return is_char ? (is_signed ? lldb::eFormatDecimal : eFormatHex) : format;
168 static size_t CalculateNumChildren(
169 CompilerType container_type, CompilerType element_type,
170 lldb_private::ExecutionContextScope *exe_scope =
171 nullptr // does not matter here because all we trade in are basic types
173 llvm::Optional<uint64_t> container_size =
174 container_type.GetByteSize(exe_scope);
175 llvm::Optional<uint64_t> element_size = element_type.GetByteSize(exe_scope);
177 if (container_size && element_size && *element_size) {
178 if (*container_size % *element_size)
180 return *container_size / *element_size;
185 namespace lldb_private {
186 namespace formatters {
188 class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
190 VectorTypeSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
191 : SyntheticChildrenFrontEnd(*valobj_sp), m_parent_format(eFormatInvalid),
192 m_item_format(eFormatInvalid), m_child_type(), m_num_children(0) {}
194 ~VectorTypeSyntheticFrontEnd() override = default;
196 size_t CalculateNumChildren() override { return m_num_children; }
198 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
199 if (idx >= CalculateNumChildren())
201 llvm::Optional<uint64_t> size = m_child_type.GetByteSize(nullptr);
204 auto offset = idx * *size;
205 StreamString idx_name;
206 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
207 ValueObjectSP child_sp(m_backend.GetSyntheticChildAtOffset(
208 offset, m_child_type, true, ConstString(idx_name.GetString())));
212 child_sp->SetFormat(m_item_format);
217 bool Update() override {
218 m_parent_format = m_backend.GetFormat();
219 CompilerType parent_type(m_backend.GetCompilerType());
220 CompilerType element_type;
221 parent_type.IsVectorType(&element_type, nullptr);
222 TargetSP target_sp(m_backend.GetTargetSP());
223 m_child_type = ::GetCompilerTypeForFormat(
224 m_parent_format, element_type,
226 ? target_sp->GetScratchTypeSystemForLanguage(nullptr,
227 lldb::eLanguageTypeC)
229 m_num_children = ::CalculateNumChildren(parent_type, m_child_type);
230 m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type);
234 bool MightHaveChildren() override { return true; }
236 size_t GetIndexOfChildWithName(ConstString name) override {
237 const char *item_name = name.GetCString();
238 uint32_t idx = ExtractIndexFromString(item_name);
239 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
245 lldb::Format m_parent_format;
246 lldb::Format m_item_format;
247 CompilerType m_child_type;
248 size_t m_num_children;
251 } // namespace formatters
252 } // namespace lldb_private
254 bool lldb_private::formatters::VectorTypeSummaryProvider(
255 ValueObject &valobj, Stream &s, const TypeSummaryOptions &) {
256 auto synthetic_children =
257 VectorTypeSyntheticFrontEndCreator(nullptr, valobj.GetSP());
258 if (!synthetic_children)
261 synthetic_children->Update();
266 size_t idx = 0, len = synthetic_children->CalculateNumChildren();
268 for (; idx < len; idx++) {
269 auto child_sp = synthetic_children->GetChildAtIndex(idx);
272 child_sp = child_sp->GetQualifiedRepresentationIfAvailable(
273 lldb::eDynamicDontRunTarget, true);
275 const char *child_value = child_sp->GetValueAsCString();
276 if (child_value && *child_value) {
278 s.Printf("%s", child_value);
281 s.Printf(", %s", child_value);
291 lldb_private::SyntheticChildrenFrontEnd *
292 lldb_private::formatters::VectorTypeSyntheticFrontEndCreator(
293 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
296 return new VectorTypeSyntheticFrontEnd(valobj_sp);