1 | //===-- CompilerType.h ------------------------------------------*- 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 | #ifndef LLDB_SYMBOL_COMPILERTYPE_H |
10 | #define LLDB_SYMBOL_COMPILERTYPE_H |
11 | |
12 | #include <functional> |
13 | #include <optional> |
14 | #include <string> |
15 | #include <vector> |
16 | |
17 | #include "lldb/lldb-private.h" |
18 | #include "llvm/ADT/APSInt.h" |
19 | #include "llvm/Support/Casting.h" |
20 | |
21 | namespace lldb_private { |
22 | |
23 | class ; |
24 | class TypeSystem; |
25 | |
26 | /// Generic representation of a type in a programming language. |
27 | /// |
28 | /// This class serves as an abstraction for a type inside one of the TypeSystems |
29 | /// implemented by the language plugins. It does not have any actual logic in it |
30 | /// but only stores an opaque pointer and a pointer to the TypeSystem that |
31 | /// gives meaning to this opaque pointer. All methods of this class should call |
32 | /// their respective method in the TypeSystem interface and pass the opaque |
33 | /// pointer along. |
34 | /// |
35 | /// \see lldb_private::TypeSystem |
36 | class CompilerType { |
37 | public: |
38 | /// Creates a CompilerType with the given TypeSystem and opaque compiler type. |
39 | /// |
40 | /// This constructor should only be called from the respective TypeSystem |
41 | /// implementation. |
42 | /// |
43 | /// \see lldb_private::TypeSystemClang::GetType(clang::QualType) |
44 | CompilerType(lldb::TypeSystemWP type_system, |
45 | lldb::opaque_compiler_type_t type); |
46 | |
47 | /// This is a minimal wrapper of a TypeSystem shared pointer as |
48 | /// returned by CompilerType which conventien dyn_cast support. |
49 | class TypeSystemSPWrapper { |
50 | lldb::TypeSystemSP m_typesystem_sp; |
51 | |
52 | public: |
53 | TypeSystemSPWrapper() = default; |
54 | TypeSystemSPWrapper(lldb::TypeSystemSP typesystem_sp) |
55 | : m_typesystem_sp(typesystem_sp) {} |
56 | |
57 | template <class TypeSystemType> bool isa_and_nonnull() { |
58 | if (auto *ts = m_typesystem_sp.get()) |
59 | return llvm::isa<TypeSystemType>(ts); |
60 | return false; |
61 | } |
62 | |
63 | /// Return a shared_ptr<TypeSystemType> if dyn_cast succeeds. |
64 | template <class TypeSystemType> |
65 | std::shared_ptr<TypeSystemType> dyn_cast_or_null() { |
66 | if (isa_and_nonnull<TypeSystemType>()) |
67 | return std::shared_ptr<TypeSystemType>( |
68 | m_typesystem_sp, llvm::cast<TypeSystemType>(m_typesystem_sp.get())); |
69 | return nullptr; |
70 | } |
71 | |
72 | explicit operator bool() const { |
73 | return static_cast<bool>(m_typesystem_sp); |
74 | } |
75 | bool operator==(const TypeSystemSPWrapper &other) const; |
76 | bool operator!=(const TypeSystemSPWrapper &other) const { |
77 | return !(*this == other); |
78 | } |
79 | |
80 | /// Only to be used in a one-off situations like |
81 | /// if (typesystem && typesystem->method()) |
82 | /// Do not store this pointer! |
83 | TypeSystem *operator->() const; |
84 | |
85 | lldb::TypeSystemSP GetSharedPointer() const { return m_typesystem_sp; } |
86 | }; |
87 | |
88 | CompilerType(TypeSystemSPWrapper type_system, |
89 | lldb::opaque_compiler_type_t type); |
90 | |
91 | CompilerType(const CompilerType &rhs) |
92 | : m_type_system(rhs.m_type_system), m_type(rhs.m_type) {} |
93 | |
94 | CompilerType() = default; |
95 | |
96 | /// Operators. |
97 | /// \{ |
98 | const CompilerType &operator=(const CompilerType &rhs) { |
99 | m_type_system = rhs.m_type_system; |
100 | m_type = rhs.m_type; |
101 | return *this; |
102 | } |
103 | |
104 | bool operator<(const CompilerType &rhs) const { |
105 | auto lts = m_type_system.lock(); |
106 | auto rts = rhs.m_type_system.lock(); |
107 | if (lts.get() == rts.get()) |
108 | return m_type < rhs.m_type; |
109 | return lts.get() < rts.get(); |
110 | } |
111 | /// \} |
112 | |
113 | /// Tests. |
114 | /// \{ |
115 | explicit operator bool() const { |
116 | return m_type_system.lock() && m_type; |
117 | } |
118 | |
119 | bool IsValid() const { return (bool)*this; } |
120 | |
121 | bool IsArrayType(CompilerType *element_type = nullptr, |
122 | uint64_t *size = nullptr, |
123 | bool *is_incomplete = nullptr) const; |
124 | |
125 | bool IsVectorType(CompilerType *element_type = nullptr, |
126 | uint64_t *size = nullptr) const; |
127 | |
128 | bool IsArrayOfScalarType() const; |
129 | |
130 | bool IsAggregateType() const; |
131 | |
132 | bool IsAnonymousType() const; |
133 | |
134 | bool IsScopedEnumerationType() const; |
135 | |
136 | bool IsBeingDefined() const; |
137 | |
138 | bool IsCharType() const; |
139 | |
140 | bool IsCompleteType() const; |
141 | |
142 | bool IsConst() const; |
143 | |
144 | bool IsDefined() const; |
145 | |
146 | bool IsFloatingPointType(uint32_t &count, bool &is_complex) const; |
147 | |
148 | bool IsFunctionType() const; |
149 | |
150 | uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const; |
151 | |
152 | size_t GetNumberOfFunctionArguments() const; |
153 | |
154 | CompilerType GetFunctionArgumentAtIndex(const size_t index) const; |
155 | |
156 | bool IsVariadicFunctionType() const; |
157 | |
158 | bool IsFunctionPointerType() const; |
159 | |
160 | bool IsMemberFunctionPointerType() const; |
161 | |
162 | bool |
163 | IsBlockPointerType(CompilerType *function_pointer_type_ptr = nullptr) const; |
164 | |
165 | bool IsIntegerType(bool &is_signed) const; |
166 | |
167 | bool IsEnumerationType(bool &is_signed) const; |
168 | |
169 | bool IsIntegerOrEnumerationType(bool &is_signed) const; |
170 | |
171 | bool IsPolymorphicClass() const; |
172 | |
173 | /// \param target_type Can pass nullptr. |
174 | bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus, |
175 | bool check_objc) const; |
176 | |
177 | bool IsPointerToScalarType() const; |
178 | |
179 | bool IsRuntimeGeneratedType() const; |
180 | |
181 | bool IsPointerType(CompilerType *pointee_type = nullptr) const; |
182 | |
183 | bool IsPointerOrReferenceType(CompilerType *pointee_type = nullptr) const; |
184 | |
185 | bool IsReferenceType(CompilerType *pointee_type = nullptr, |
186 | bool *is_rvalue = nullptr) const; |
187 | |
188 | bool ShouldTreatScalarValueAsAddress() const; |
189 | |
190 | bool IsScalarType() const; |
191 | |
192 | bool IsTemplateType() const; |
193 | |
194 | bool IsTypedefType() const; |
195 | |
196 | bool IsVoidType() const; |
197 | |
198 | /// This is used when you don't care about the signedness of the integer. |
199 | bool IsInteger() const; |
200 | |
201 | bool IsFloat() const; |
202 | |
203 | /// This is used when you don't care about the signedness of the enum. |
204 | bool IsEnumerationType() const; |
205 | |
206 | bool IsUnscopedEnumerationType() const; |
207 | |
208 | bool IsIntegerOrUnscopedEnumerationType() const; |
209 | |
210 | bool IsSigned() const; |
211 | |
212 | bool IsNullPtrType() const; |
213 | |
214 | bool IsBoolean() const; |
215 | |
216 | bool IsEnumerationIntegerTypeSigned() const; |
217 | |
218 | bool IsScalarOrUnscopedEnumerationType() const; |
219 | |
220 | bool IsPromotableIntegerType() const; |
221 | |
222 | bool IsPointerToVoid() const; |
223 | |
224 | bool IsRecordType() const; |
225 | |
226 | //// Checks whether `target_base` is a virtual base of `type` (direct or |
227 | /// indirect). If it is, stores the first virtual base type on the path from |
228 | /// `type` to `target_type`. Parameter "virtual_base" is where the first |
229 | /// virtual base type gets stored. Parameter "carry_virtual" is used to |
230 | /// denote that we're in a recursive check of virtual base classes and we |
231 | /// have already seen a virtual base class (so should only check direct |
232 | /// base classes). |
233 | /// Note: This may only be defined in TypeSystemClang. |
234 | bool IsVirtualBase(CompilerType target_base, CompilerType *virtual_base, |
235 | bool carry_virtual = false) const; |
236 | |
237 | /// This may only be defined in TypeSystemClang. |
238 | bool IsContextuallyConvertibleToBool() const; |
239 | |
240 | bool IsBasicType() const; |
241 | |
242 | std::string TypeDescription(); |
243 | |
244 | bool CompareTypes(CompilerType rhs) const; |
245 | |
246 | const char *GetTypeTag(); |
247 | |
248 | /// Go through the base classes and count non-empty ones. |
249 | uint32_t GetNumberOfNonEmptyBaseClasses(); |
250 | |
251 | /// \} |
252 | |
253 | /// Type Completion. |
254 | /// \{ |
255 | bool GetCompleteType() const; |
256 | /// \} |
257 | |
258 | bool IsForcefullyCompleted() const; |
259 | |
260 | /// AST related queries. |
261 | /// \{ |
262 | size_t GetPointerByteSize() const; |
263 | /// \} |
264 | |
265 | /// Accessors. |
266 | /// \{ |
267 | |
268 | /// Returns a shared pointer to the type system. The |
269 | /// TypeSystem::TypeSystemSPWrapper can be compared for equality. |
270 | TypeSystemSPWrapper GetTypeSystem() const; |
271 | |
272 | ConstString GetTypeName(bool BaseOnly = false) const; |
273 | |
274 | ConstString GetDisplayTypeName() const; |
275 | |
276 | uint32_t |
277 | GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) const; |
278 | |
279 | lldb::LanguageType GetMinimumLanguage(); |
280 | |
281 | lldb::opaque_compiler_type_t GetOpaqueQualType() const { return m_type; } |
282 | |
283 | lldb::TypeClass GetTypeClass() const; |
284 | |
285 | void SetCompilerType(lldb::TypeSystemWP type_system, |
286 | lldb::opaque_compiler_type_t type); |
287 | void SetCompilerType(TypeSystemSPWrapper type_system, |
288 | lldb::opaque_compiler_type_t type); |
289 | |
290 | unsigned GetTypeQualifiers() const; |
291 | /// \} |
292 | |
293 | /// Creating related types. |
294 | /// \{ |
295 | CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const; |
296 | |
297 | CompilerType GetArrayType(uint64_t size) const; |
298 | |
299 | CompilerType GetCanonicalType() const; |
300 | |
301 | CompilerType GetFullyUnqualifiedType() const; |
302 | |
303 | CompilerType GetEnumerationIntegerType() const; |
304 | |
305 | /// Returns -1 if this isn't a function of if the function doesn't |
306 | /// have a prototype Returns a value >= 0 if there is a prototype. |
307 | int GetFunctionArgumentCount() const; |
308 | |
309 | CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const; |
310 | |
311 | CompilerType GetFunctionReturnType() const; |
312 | |
313 | size_t GetNumMemberFunctions() const; |
314 | |
315 | TypeMemberFunctionImpl GetMemberFunctionAtIndex(size_t idx); |
316 | |
317 | /// If this type is a reference to a type (L value or R value reference), |
318 | /// return a new type with the reference removed, else return the current type |
319 | /// itself. |
320 | CompilerType GetNonReferenceType() const; |
321 | |
322 | /// If this type is a pointer type, return the type that the pointer points |
323 | /// to, else return an invalid type. |
324 | CompilerType GetPointeeType() const; |
325 | |
326 | /// Return a new CompilerType that is a pointer to this type |
327 | CompilerType GetPointerType() const; |
328 | |
329 | /// Return a new CompilerType that is a L value reference to this type if this |
330 | /// type is valid and the type system supports L value references, else return |
331 | /// an invalid type. |
332 | CompilerType GetLValueReferenceType() const; |
333 | |
334 | /// Return a new CompilerType that is a R value reference to this type if this |
335 | /// type is valid and the type system supports R value references, else return |
336 | /// an invalid type. |
337 | CompilerType GetRValueReferenceType() const; |
338 | |
339 | /// Return a new CompilerType adds a const modifier to this type if this type |
340 | /// is valid and the type system supports const modifiers, else return an |
341 | /// invalid type. |
342 | CompilerType AddConstModifier() const; |
343 | |
344 | /// Return a new CompilerType adds a volatile modifier to this type if this |
345 | /// type is valid and the type system supports volatile modifiers, else return |
346 | /// an invalid type. |
347 | CompilerType AddVolatileModifier() const; |
348 | |
349 | /// Return a new CompilerType that is the atomic type of this type. If this |
350 | /// type is not valid or the type system doesn't support atomic types, this |
351 | /// returns an invalid type. |
352 | CompilerType GetAtomicType() const; |
353 | |
354 | /// Return a new CompilerType adds a restrict modifier to this type if this |
355 | /// type is valid and the type system supports restrict modifiers, else return |
356 | /// an invalid type. |
357 | CompilerType AddRestrictModifier() const; |
358 | |
359 | /// Create a typedef to this type using "name" as the name of the typedef this |
360 | /// type is valid and the type system supports typedefs, else return an |
361 | /// invalid type. |
362 | /// \param payload The typesystem-specific \p lldb::Type payload. |
363 | CompilerType CreateTypedef(const char *name, |
364 | const CompilerDeclContext &decl_ctx, |
365 | uint32_t payload) const; |
366 | |
367 | /// If the current object represents a typedef type, get the underlying type |
368 | CompilerType GetTypedefedType() const; |
369 | |
370 | /// Create related types using the current type's AST |
371 | CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const; |
372 | /// \} |
373 | |
374 | /// Exploring the type. |
375 | /// \{ |
376 | struct IntegralTemplateArgument; |
377 | |
378 | /// Return the size of the type in bytes. |
379 | std::optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope) const; |
380 | /// Return the size of the type in bits. |
381 | std::optional<uint64_t> GetBitSize(ExecutionContextScope *exe_scope) const; |
382 | |
383 | lldb::Encoding GetEncoding(uint64_t &count) const; |
384 | |
385 | lldb::Format GetFormat() const; |
386 | |
387 | std::optional<size_t> GetTypeBitAlign(ExecutionContextScope *exe_scope) const; |
388 | |
389 | uint32_t GetNumChildren(bool omit_empty_base_classes, |
390 | const ExecutionContext *exe_ctx) const; |
391 | |
392 | lldb::BasicType GetBasicTypeEnumeration() const; |
393 | |
394 | /// If this type is an enumeration, iterate through all of its enumerators |
395 | /// using a callback. If the callback returns true, keep iterating, else abort |
396 | /// the iteration. |
397 | void ForEachEnumerator( |
398 | std::function<bool(const CompilerType &integer_type, ConstString name, |
399 | const llvm::APSInt &value)> const &callback) const; |
400 | |
401 | uint32_t GetNumFields() const; |
402 | |
403 | CompilerType GetFieldAtIndex(size_t idx, std::string &name, |
404 | uint64_t *bit_offset_ptr, |
405 | uint32_t *bitfield_bit_size_ptr, |
406 | bool *is_bitfield_ptr) const; |
407 | |
408 | uint32_t GetNumDirectBaseClasses() const; |
409 | |
410 | uint32_t GetNumVirtualBaseClasses() const; |
411 | |
412 | CompilerType GetDirectBaseClassAtIndex(size_t idx, |
413 | uint32_t *bit_offset_ptr) const; |
414 | |
415 | CompilerType GetVirtualBaseClassAtIndex(size_t idx, |
416 | uint32_t *bit_offset_ptr) const; |
417 | |
418 | uint32_t GetIndexOfFieldWithName(const char *name, |
419 | CompilerType *field_compiler_type = nullptr, |
420 | uint64_t *bit_offset_ptr = nullptr, |
421 | uint32_t *bitfield_bit_size_ptr = nullptr, |
422 | bool *is_bitfield_ptr = nullptr) const; |
423 | |
424 | CompilerType GetChildCompilerTypeAtIndex( |
425 | ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, |
426 | bool omit_empty_base_classes, bool ignore_array_bounds, |
427 | std::string &child_name, uint32_t &child_byte_size, |
428 | int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, |
429 | uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, |
430 | bool &child_is_deref_of_parent, ValueObject *valobj, |
431 | uint64_t &language_flags) const; |
432 | |
433 | /// Lookup a child given a name. This function will match base class names and |
434 | /// member member names in "clang_type" only, not descendants. |
435 | uint32_t GetIndexOfChildWithName(llvm::StringRef name, |
436 | bool omit_empty_base_classes) const; |
437 | |
438 | /// Lookup a child member given a name. This function will match member names |
439 | /// only and will descend into "clang_type" children in search for the first |
440 | /// member in this class, or any base class that matches "name". |
441 | /// TODO: Return all matches for a given name by returning a |
442 | /// vector<vector<uint32_t>> |
443 | /// so we catch all names that match a given child name, not just the first. |
444 | size_t |
445 | GetIndexOfChildMemberWithName(llvm::StringRef name, |
446 | bool omit_empty_base_classes, |
447 | std::vector<uint32_t> &child_indexes) const; |
448 | |
449 | /// Return the number of template arguments the type has. |
450 | /// If expand_pack is true, then variadic argument packs are automatically |
451 | /// expanded to their supplied arguments. If it is false an argument pack |
452 | /// will only count as 1 argument. |
453 | size_t GetNumTemplateArguments(bool expand_pack = false) const; |
454 | |
455 | // Return the TemplateArgumentKind of the template argument at index idx. |
456 | // If expand_pack is true, then variadic argument packs are automatically |
457 | // expanded to their supplied arguments. With expand_pack set to false, an |
458 | // arguement pack will count as 1 argument and return a type of Pack. |
459 | lldb::TemplateArgumentKind |
460 | GetTemplateArgumentKind(size_t idx, bool expand_pack = false) const; |
461 | CompilerType GetTypeTemplateArgument(size_t idx, |
462 | bool expand_pack = false) const; |
463 | |
464 | /// Returns the value of the template argument and its type. |
465 | /// If expand_pack is true, then variadic argument packs are automatically |
466 | /// expanded to their supplied arguments. With expand_pack set to false, an |
467 | /// arguement pack will count as 1 argument and it is invalid to call this |
468 | /// method on the pack argument. |
469 | std::optional<IntegralTemplateArgument> |
470 | GetIntegralTemplateArgument(size_t idx, bool expand_pack = false) const; |
471 | |
472 | CompilerType GetTypeForFormatters() const; |
473 | |
474 | LazyBool ShouldPrintAsOneLiner(ValueObject *valobj) const; |
475 | |
476 | bool IsMeaninglessWithoutDynamicResolution() const; |
477 | /// \} |
478 | |
479 | /// Dumping types. |
480 | /// \{ |
481 | #ifndef NDEBUG |
482 | /// Convenience LLVM-style dump method for use in the debugger only. |
483 | /// Don't call this function from actual code. |
484 | LLVM_DUMP_METHOD void dump() const; |
485 | #endif |
486 | |
487 | bool (Stream *s, lldb::Format format, const DataExtractor &data, |
488 | lldb::offset_t data_offset, size_t data_byte_size, |
489 | uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, |
490 | ExecutionContextScope *exe_scope); |
491 | |
492 | /// Dump to stdout. |
493 | void DumpTypeDescription(lldb::DescriptionLevel level = |
494 | lldb::eDescriptionLevelFull) const; |
495 | |
496 | /// Print a description of the type to a stream. The exact implementation |
497 | /// varies, but the expectation is that eDescriptionLevelFull returns a |
498 | /// source-like representation of the type, whereas eDescriptionLevelVerbose |
499 | /// does a dump of the underlying AST if applicable. |
500 | void DumpTypeDescription(Stream *s, lldb::DescriptionLevel level = |
501 | lldb::eDescriptionLevelFull) const; |
502 | /// \} |
503 | |
504 | bool (const DataExtractor &data, lldb::offset_t data_offset, |
505 | size_t data_byte_size, Scalar &value, |
506 | ExecutionContextScope *exe_scope) const; |
507 | void Clear() { |
508 | m_type_system = {}; |
509 | m_type = nullptr; |
510 | } |
511 | |
512 | private: |
513 | #ifndef NDEBUG |
514 | /// If the type is valid, ask the TypeSystem to verify the integrity |
515 | /// of the type to catch CompilerTypes that mix and match invalid |
516 | /// TypeSystem/Opaque type pairs. |
517 | bool Verify() const; |
518 | #endif |
519 | |
520 | lldb::TypeSystemWP m_type_system; |
521 | lldb::opaque_compiler_type_t m_type = nullptr; |
522 | }; |
523 | |
524 | bool operator==(const CompilerType &lhs, const CompilerType &rhs); |
525 | bool operator!=(const CompilerType &lhs, const CompilerType &rhs); |
526 | |
527 | struct CompilerType::IntegralTemplateArgument { |
528 | llvm::APSInt value; |
529 | CompilerType type; |
530 | }; |
531 | |
532 | } // namespace lldb_private |
533 | |
534 | #endif // LLDB_SYMBOL_COMPILERTYPE_H |
535 | |