]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / DataFormatters / VectorType.cpp
1 //===-- VectorType.cpp ------------------------------------------*- C++ -*-===//
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 "lldb/DataFormatters/VectorType.h"
10
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"
16
17 #include "lldb/Utility/LLDBAssert.h"
18
19 using namespace lldb;
20 using namespace lldb_private;
21 using namespace lldb_private::formatters;
22
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");
27
28   switch (format) {
29   case lldb::eFormatAddressInfo:
30   case lldb::eFormatPointer:
31     return type_system->GetBuiltinTypeForEncodingAndBitSize(
32         eEncodingUint, 8 * type_system->GetPointerByteSize());
33
34   case lldb::eFormatBoolean:
35     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeBool);
36
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);
43
44   case lldb::eFormatComplex /* lldb::eFormatComplexFloat */:
45     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloatComplex);
46
47   case lldb::eFormatCString:
48     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar)
49         .GetPointerType();
50
51   case lldb::eFormatFloat:
52     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
53
54   case lldb::eFormatHex:
55   case lldb::eFormatHexUppercase:
56   case lldb::eFormatOctal:
57     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeInt);
58
59   case lldb::eFormatHexFloat:
60     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
61
62   case lldb::eFormatUnicode16:
63   case lldb::eFormatUnicode32:
64
65   case lldb::eFormatUnsigned:
66     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeUnsignedInt);
67
68   case lldb::eFormatVectorOfChar:
69     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar);
70
71   case lldb::eFormatVectorOfFloat32:
72     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754,
73                                                             32);
74
75   case lldb::eFormatVectorOfFloat64:
76     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754,
77                                                             64);
78
79   case lldb::eFormatVectorOfSInt16:
80     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 16);
81
82   case lldb::eFormatVectorOfSInt32:
83     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
84
85   case lldb::eFormatVectorOfSInt64:
86     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
87
88   case lldb::eFormatVectorOfSInt8:
89     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 8);
90
91   case lldb::eFormatVectorOfUInt128:
92     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 128);
93
94   case lldb::eFormatVectorOfUInt16:
95     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
96
97   case lldb::eFormatVectorOfUInt32:
98     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
99
100   case lldb::eFormatVectorOfUInt64:
101     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 64);
102
103   case lldb::eFormatVectorOfUInt8:
104     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8);
105
106   case lldb::eFormatDefault:
107     return element_type;
108
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:
116   default:
117     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8);
118   }
119 }
120
121 static lldb::Format GetItemFormatForFormat(lldb::Format format,
122                                            CompilerType element_type) {
123   switch (format) {
124   case lldb::eFormatVectorOfChar:
125     return lldb::eFormatChar;
126
127   case lldb::eFormatVectorOfFloat32:
128   case lldb::eFormatVectorOfFloat64:
129     return lldb::eFormatFloat;
130
131   case lldb::eFormatVectorOfSInt16:
132   case lldb::eFormatVectorOfSInt32:
133   case lldb::eFormatVectorOfSInt64:
134   case lldb::eFormatVectorOfSInt8:
135     return lldb::eFormatDecimal;
136
137   case lldb::eFormatVectorOfUInt128:
138   case lldb::eFormatVectorOfUInt16:
139   case lldb::eFormatVectorOfUInt32:
140   case lldb::eFormatVectorOfUInt64:
141   case lldb::eFormatVectorOfUInt8:
142     return lldb::eFormatUnsigned;
143
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:
151     return eFormatHex;
152
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;
161   } break;
162
163   default:
164     return format;
165   }
166 }
167
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
172     ) {
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);
176
177   if (container_size && element_size && *element_size) {
178     if (*container_size % *element_size)
179       return 0;
180     return *container_size / *element_size;
181   }
182   return 0;
183 }
184
185 namespace lldb_private {
186 namespace formatters {
187
188 class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
189 public:
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) {}
193
194   ~VectorTypeSyntheticFrontEnd() override = default;
195
196   size_t CalculateNumChildren() override { return m_num_children; }
197
198   lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
199     if (idx >= CalculateNumChildren())
200       return {};
201     llvm::Optional<uint64_t> size = m_child_type.GetByteSize(nullptr);
202     if (!size)
203       return {};
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())));
209     if (!child_sp)
210       return child_sp;
211
212     child_sp->SetFormat(m_item_format);
213
214     return child_sp;
215   }
216
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,
225         target_sp
226             ? target_sp->GetScratchTypeSystemForLanguage(nullptr,
227                                                          lldb::eLanguageTypeC)
228             : nullptr);
229     m_num_children = ::CalculateNumChildren(parent_type, m_child_type);
230     m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type);
231     return false;
232   }
233
234   bool MightHaveChildren() override { return true; }
235
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())
240       return UINT32_MAX;
241     return idx;
242   }
243
244 private:
245   lldb::Format m_parent_format;
246   lldb::Format m_item_format;
247   CompilerType m_child_type;
248   size_t m_num_children;
249 };
250
251 } // namespace formatters
252 } // namespace lldb_private
253
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)
259     return false;
260
261   synthetic_children->Update();
262
263   s.PutChar('(');
264   bool first = true;
265
266   size_t idx = 0, len = synthetic_children->CalculateNumChildren();
267
268   for (; idx < len; idx++) {
269     auto child_sp = synthetic_children->GetChildAtIndex(idx);
270     if (!child_sp)
271       continue;
272     child_sp = child_sp->GetQualifiedRepresentationIfAvailable(
273         lldb::eDynamicDontRunTarget, true);
274
275     const char *child_value = child_sp->GetValueAsCString();
276     if (child_value && *child_value) {
277       if (first) {
278         s.Printf("%s", child_value);
279         first = false;
280       } else {
281         s.Printf(", %s", child_value);
282       }
283     }
284   }
285
286   s.PutChar(')');
287
288   return true;
289 }
290
291 lldb_private::SyntheticChildrenFrontEnd *
292 lldb_private::formatters::VectorTypeSyntheticFrontEndCreator(
293     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
294   if (!valobj_sp)
295     return nullptr;
296   return new VectorTypeSyntheticFrontEnd(valobj_sp);
297 }