]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[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 #include "lldb/Utility/Log.h"
19
20 using namespace lldb;
21 using namespace lldb_private;
22 using namespace lldb_private::formatters;
23
24 static CompilerType GetCompilerTypeForFormat(lldb::Format format,
25                                              CompilerType element_type,
26                                              TypeSystem *type_system) {
27   lldbassert(type_system && "type_system needs to be not NULL");
28
29   switch (format) {
30   case lldb::eFormatAddressInfo:
31   case lldb::eFormatPointer:
32     return type_system->GetBuiltinTypeForEncodingAndBitSize(
33         eEncodingUint, 8 * type_system->GetPointerByteSize());
34
35   case lldb::eFormatBoolean:
36     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeBool);
37
38   case lldb::eFormatBytes:
39   case lldb::eFormatBytesWithASCII:
40   case lldb::eFormatChar:
41   case lldb::eFormatCharArray:
42   case lldb::eFormatCharPrintable:
43     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar);
44
45   case lldb::eFormatComplex /* lldb::eFormatComplexFloat */:
46     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloatComplex);
47
48   case lldb::eFormatCString:
49     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar)
50         .GetPointerType();
51
52   case lldb::eFormatFloat:
53     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
54
55   case lldb::eFormatHex:
56   case lldb::eFormatHexUppercase:
57   case lldb::eFormatOctal:
58     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeInt);
59
60   case lldb::eFormatHexFloat:
61     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
62
63   case lldb::eFormatUnicode16:
64   case lldb::eFormatUnicode32:
65
66   case lldb::eFormatUnsigned:
67     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeUnsignedInt);
68
69   case lldb::eFormatVectorOfChar:
70     return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar);
71
72   case lldb::eFormatVectorOfFloat32:
73     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754,
74                                                             32);
75
76   case lldb::eFormatVectorOfFloat64:
77     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754,
78                                                             64);
79
80   case lldb::eFormatVectorOfSInt16:
81     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 16);
82
83   case lldb::eFormatVectorOfSInt32:
84     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
85
86   case lldb::eFormatVectorOfSInt64:
87     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
88
89   case lldb::eFormatVectorOfSInt8:
90     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 8);
91
92   case lldb::eFormatVectorOfUInt128:
93     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 128);
94
95   case lldb::eFormatVectorOfUInt16:
96     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
97
98   case lldb::eFormatVectorOfUInt32:
99     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
100
101   case lldb::eFormatVectorOfUInt64:
102     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 64);
103
104   case lldb::eFormatVectorOfUInt8:
105     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8);
106
107   case lldb::eFormatDefault:
108     return element_type;
109
110   case lldb::eFormatBinary:
111   case lldb::eFormatComplexInteger:
112   case lldb::eFormatDecimal:
113   case lldb::eFormatEnum:
114   case lldb::eFormatInstruction:
115   case lldb::eFormatOSType:
116   case lldb::eFormatVoid:
117   default:
118     return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8);
119   }
120 }
121
122 static lldb::Format GetItemFormatForFormat(lldb::Format format,
123                                            CompilerType element_type) {
124   switch (format) {
125   case lldb::eFormatVectorOfChar:
126     return lldb::eFormatChar;
127
128   case lldb::eFormatVectorOfFloat32:
129   case lldb::eFormatVectorOfFloat64:
130     return lldb::eFormatFloat;
131
132   case lldb::eFormatVectorOfSInt16:
133   case lldb::eFormatVectorOfSInt32:
134   case lldb::eFormatVectorOfSInt64:
135   case lldb::eFormatVectorOfSInt8:
136     return lldb::eFormatDecimal;
137
138   case lldb::eFormatVectorOfUInt128:
139   case lldb::eFormatVectorOfUInt16:
140   case lldb::eFormatVectorOfUInt32:
141   case lldb::eFormatVectorOfUInt64:
142   case lldb::eFormatVectorOfUInt8:
143     return lldb::eFormatUnsigned;
144
145   case lldb::eFormatBinary:
146   case lldb::eFormatComplexInteger:
147   case lldb::eFormatDecimal:
148   case lldb::eFormatEnum:
149   case lldb::eFormatInstruction:
150   case lldb::eFormatOSType:
151   case lldb::eFormatVoid:
152     return eFormatHex;
153
154   case lldb::eFormatDefault: {
155     // special case the (default, char) combination to actually display as an
156     // integer value most often, you won't want to see the ASCII characters...
157     // (and if you do, eFormatChar is a keystroke away)
158     bool is_char = element_type.IsCharType();
159     bool is_signed = false;
160     element_type.IsIntegerType(is_signed);
161     return is_char ? (is_signed ? lldb::eFormatDecimal : eFormatHex) : format;
162   } break;
163
164   default:
165     return format;
166   }
167 }
168
169 static size_t CalculateNumChildren(
170     CompilerType container_type, CompilerType element_type,
171     lldb_private::ExecutionContextScope *exe_scope =
172         nullptr // does not matter here because all we trade in are basic types
173     ) {
174   llvm::Optional<uint64_t> container_size =
175       container_type.GetByteSize(exe_scope);
176   llvm::Optional<uint64_t> element_size = element_type.GetByteSize(exe_scope);
177
178   if (container_size && element_size && *element_size) {
179     if (*container_size % *element_size)
180       return 0;
181     return *container_size / *element_size;
182   }
183   return 0;
184 }
185
186 namespace lldb_private {
187 namespace formatters {
188
189 class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
190 public:
191   VectorTypeSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
192       : SyntheticChildrenFrontEnd(*valobj_sp), m_parent_format(eFormatInvalid),
193         m_item_format(eFormatInvalid), m_child_type(), m_num_children(0) {}
194
195   ~VectorTypeSyntheticFrontEnd() override = default;
196
197   size_t CalculateNumChildren() override { return m_num_children; }
198
199   lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
200     if (idx >= CalculateNumChildren())
201       return {};
202     llvm::Optional<uint64_t> size = m_child_type.GetByteSize(nullptr);
203     if (!size)
204       return {};
205     auto offset = idx * *size;
206     StreamString idx_name;
207     idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
208     ValueObjectSP child_sp(m_backend.GetSyntheticChildAtOffset(
209         offset, m_child_type, true, ConstString(idx_name.GetString())));
210     if (!child_sp)
211       return child_sp;
212
213     child_sp->SetFormat(m_item_format);
214
215     return child_sp;
216   }
217
218   bool Update() override {
219     m_parent_format = m_backend.GetFormat();
220     CompilerType parent_type(m_backend.GetCompilerType());
221     CompilerType element_type;
222     parent_type.IsVectorType(&element_type, nullptr);
223     TypeSystem *type_system = nullptr;
224     if (auto target_sp = m_backend.GetTargetSP()) {
225       auto type_system_or_err =
226           target_sp->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC);
227       if (auto err = type_system_or_err.takeError()) {
228         LLDB_LOG_ERROR(
229             lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS),
230             std::move(err), "Unable to update from scratch TypeSystem");
231       } else {
232         type_system = &type_system_or_err.get();
233       }
234     }
235     m_child_type =
236         ::GetCompilerTypeForFormat(m_parent_format, element_type, type_system);
237     m_num_children = ::CalculateNumChildren(parent_type, m_child_type);
238     m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type);
239     return false;
240   }
241
242   bool MightHaveChildren() override { return true; }
243
244   size_t GetIndexOfChildWithName(ConstString name) override {
245     const char *item_name = name.GetCString();
246     uint32_t idx = ExtractIndexFromString(item_name);
247     if (idx < UINT32_MAX && idx >= CalculateNumChildren())
248       return UINT32_MAX;
249     return idx;
250   }
251
252 private:
253   lldb::Format m_parent_format;
254   lldb::Format m_item_format;
255   CompilerType m_child_type;
256   size_t m_num_children;
257 };
258
259 } // namespace formatters
260 } // namespace lldb_private
261
262 bool lldb_private::formatters::VectorTypeSummaryProvider(
263     ValueObject &valobj, Stream &s, const TypeSummaryOptions &) {
264   auto synthetic_children =
265       VectorTypeSyntheticFrontEndCreator(nullptr, valobj.GetSP());
266   if (!synthetic_children)
267     return false;
268
269   synthetic_children->Update();
270
271   s.PutChar('(');
272   bool first = true;
273
274   size_t idx = 0, len = synthetic_children->CalculateNumChildren();
275
276   for (; idx < len; idx++) {
277     auto child_sp = synthetic_children->GetChildAtIndex(idx);
278     if (!child_sp)
279       continue;
280     child_sp = child_sp->GetQualifiedRepresentationIfAvailable(
281         lldb::eDynamicDontRunTarget, true);
282
283     const char *child_value = child_sp->GetValueAsCString();
284     if (child_value && *child_value) {
285       if (first) {
286         s.Printf("%s", child_value);
287         first = false;
288       } else {
289         s.Printf(", %s", child_value);
290       }
291     }
292   }
293
294   s.PutChar(')');
295
296   return true;
297 }
298
299 lldb_private::SyntheticChildrenFrontEnd *
300 lldb_private::formatters::VectorTypeSyntheticFrontEndCreator(
301     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
302   if (!valobj_sp)
303     return nullptr;
304   return new VectorTypeSyntheticFrontEnd(valobj_sp);
305 }