1 | //===- llvm/Type.h - Classes for handling data types ------------*- 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 | // This file contains the declaration of the Type class. For more "Type" |
10 | // stuff, look in DerivedTypes.h. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_IR_TYPE_H |
15 | #define LLVM_IR_TYPE_H |
16 | |
17 | #include "llvm/ADT/ArrayRef.h" |
18 | #include "llvm/Support/CBindingWrapping.h" |
19 | #include "llvm/Support/Casting.h" |
20 | #include "llvm/Support/Compiler.h" |
21 | #include "llvm/Support/ErrorHandling.h" |
22 | #include "llvm/Support/TypeSize.h" |
23 | #include <cassert> |
24 | #include <cstdint> |
25 | #include <iterator> |
26 | |
27 | namespace llvm { |
28 | |
29 | class IntegerType; |
30 | struct fltSemantics; |
31 | class LLVMContext; |
32 | class PointerType; |
33 | class raw_ostream; |
34 | class StringRef; |
35 | template <typename PtrType> class SmallPtrSetImpl; |
36 | |
37 | /// The instances of the Type class are immutable: once they are created, |
38 | /// they are never changed. Also note that only one instance of a particular |
39 | /// type is ever created. Thus seeing if two types are equal is a matter of |
40 | /// doing a trivial pointer comparison. To enforce that no two equal instances |
41 | /// are created, Type instances can only be created via static factory methods |
42 | /// in class Type and in derived classes. Once allocated, Types are never |
43 | /// free'd. |
44 | /// |
45 | class Type { |
46 | public: |
47 | //===--------------------------------------------------------------------===// |
48 | /// Definitions of all of the base types for the Type system. Based on this |
49 | /// value, you can cast to a class defined in DerivedTypes.h. |
50 | /// Note: If you add an element to this, you need to add an element to the |
51 | /// Type::getPrimitiveType function, or else things will break! |
52 | /// Also update LLVMTypeKind and LLVMGetTypeKind () in the C binding. |
53 | /// |
54 | enum TypeID { |
55 | // PrimitiveTypes |
56 | HalfTyID = 0, ///< 16-bit floating point type |
57 | BFloatTyID, ///< 16-bit floating point type (7-bit significand) |
58 | FloatTyID, ///< 32-bit floating point type |
59 | DoubleTyID, ///< 64-bit floating point type |
60 | X86_FP80TyID, ///< 80-bit floating point type (X87) |
61 | FP128TyID, ///< 128-bit floating point type (112-bit significand) |
62 | PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, PowerPC) |
63 | VoidTyID, ///< type with no size |
64 | LabelTyID, ///< Labels |
65 | MetadataTyID, ///< Metadata |
66 | X86_MMXTyID, ///< MMX vectors (64 bits, X86 specific) |
67 | X86_AMXTyID, ///< AMX vectors (8192 bits, X86 specific) |
68 | TokenTyID, ///< Tokens |
69 | |
70 | // Derived types... see DerivedTypes.h file. |
71 | IntegerTyID, ///< Arbitrary bit width integers |
72 | FunctionTyID, ///< Functions |
73 | PointerTyID, ///< Pointers |
74 | StructTyID, ///< Structures |
75 | ArrayTyID, ///< Arrays |
76 | FixedVectorTyID, ///< Fixed width SIMD vector type |
77 | ScalableVectorTyID, ///< Scalable SIMD vector type |
78 | TypedPointerTyID, ///< Typed pointer used by some GPU targets |
79 | TargetExtTyID, ///< Target extension type |
80 | }; |
81 | |
82 | private: |
83 | /// This refers to the LLVMContext in which this type was uniqued. |
84 | LLVMContext &Context; |
85 | |
86 | TypeID ID : 8; // The current base type of this type. |
87 | unsigned SubclassData : 24; // Space for subclasses to store data. |
88 | // Note that this should be synchronized with |
89 | // MAX_INT_BITS value in IntegerType class. |
90 | |
91 | protected: |
92 | friend class LLVMContextImpl; |
93 | |
94 | explicit Type(LLVMContext &C, TypeID tid) |
95 | : Context(C), ID(tid), SubclassData(0) {} |
96 | ~Type() = default; |
97 | |
98 | unsigned getSubclassData() const { return SubclassData; } |
99 | |
100 | void setSubclassData(unsigned val) { |
101 | SubclassData = val; |
102 | // Ensure we don't have any accidental truncation. |
103 | assert(getSubclassData() == val && "Subclass data too large for field" ); |
104 | } |
105 | |
106 | /// Keeps track of how many Type*'s there are in the ContainedTys list. |
107 | unsigned NumContainedTys = 0; |
108 | |
109 | /// A pointer to the array of Types contained by this Type. For example, this |
110 | /// includes the arguments of a function type, the elements of a structure, |
111 | /// the pointee of a pointer, the element type of an array, etc. This pointer |
112 | /// may be 0 for types that don't contain other types (Integer, Double, |
113 | /// Float). |
114 | Type * const *ContainedTys = nullptr; |
115 | |
116 | public: |
117 | /// Print the current type. |
118 | /// Omit the type details if \p NoDetails == true. |
119 | /// E.g., let %st = type { i32, i16 } |
120 | /// When \p NoDetails is true, we only print %st. |
121 | /// Put differently, \p NoDetails prints the type as if |
122 | /// inlined with the operands when printing an instruction. |
123 | void print(raw_ostream &O, bool IsForDebug = false, |
124 | bool NoDetails = false) const; |
125 | |
126 | void dump() const; |
127 | |
128 | /// Return the LLVMContext in which this type was uniqued. |
129 | LLVMContext &getContext() const { return Context; } |
130 | |
131 | //===--------------------------------------------------------------------===// |
132 | // Accessors for working with types. |
133 | // |
134 | |
135 | /// Return the type id for the type. This will return one of the TypeID enum |
136 | /// elements defined above. |
137 | TypeID getTypeID() const { return ID; } |
138 | |
139 | /// Return true if this is 'void'. |
140 | bool isVoidTy() const { return getTypeID() == VoidTyID; } |
141 | |
142 | /// Return true if this is 'half', a 16-bit IEEE fp type. |
143 | bool isHalfTy() const { return getTypeID() == HalfTyID; } |
144 | |
145 | /// Return true if this is 'bfloat', a 16-bit bfloat type. |
146 | bool isBFloatTy() const { return getTypeID() == BFloatTyID; } |
147 | |
148 | /// Return true if this is a 16-bit float type. |
149 | bool is16bitFPTy() const { |
150 | return getTypeID() == BFloatTyID || getTypeID() == HalfTyID; |
151 | } |
152 | |
153 | /// Return true if this is 'float', a 32-bit IEEE fp type. |
154 | bool isFloatTy() const { return getTypeID() == FloatTyID; } |
155 | |
156 | /// Return true if this is 'double', a 64-bit IEEE fp type. |
157 | bool isDoubleTy() const { return getTypeID() == DoubleTyID; } |
158 | |
159 | /// Return true if this is x86 long double. |
160 | bool isX86_FP80Ty() const { return getTypeID() == X86_FP80TyID; } |
161 | |
162 | /// Return true if this is 'fp128'. |
163 | bool isFP128Ty() const { return getTypeID() == FP128TyID; } |
164 | |
165 | /// Return true if this is powerpc long double. |
166 | bool isPPC_FP128Ty() const { return getTypeID() == PPC_FP128TyID; } |
167 | |
168 | /// Return true if this is a well-behaved IEEE-like type, which has a IEEE |
169 | /// compatible layout as defined by isIEEE(), and does not have unnormal |
170 | /// values |
171 | bool isIEEELikeFPTy() const { |
172 | switch (getTypeID()) { |
173 | case DoubleTyID: |
174 | case FloatTyID: |
175 | case HalfTyID: |
176 | case BFloatTyID: |
177 | case FP128TyID: |
178 | return true; |
179 | default: |
180 | return false; |
181 | } |
182 | } |
183 | |
184 | /// Return true if this is one of the floating-point types |
185 | bool isFloatingPointTy() const { |
186 | return isIEEELikeFPTy() || getTypeID() == X86_FP80TyID || |
187 | getTypeID() == PPC_FP128TyID; |
188 | } |
189 | |
190 | /// Returns true if this is a floating-point type that is an unevaluated sum |
191 | /// of multiple floating-point units. |
192 | /// An example of such a type is ppc_fp128, also known as double-double, which |
193 | /// consists of two IEEE 754 doubles. |
194 | bool isMultiUnitFPType() const { |
195 | return getTypeID() == PPC_FP128TyID; |
196 | } |
197 | |
198 | const fltSemantics &getFltSemantics() const; |
199 | |
200 | /// Return true if this is X86 MMX. |
201 | bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; } |
202 | |
203 | /// Return true if this is X86 AMX. |
204 | bool isX86_AMXTy() const { return getTypeID() == X86_AMXTyID; } |
205 | |
206 | /// Return true if this is a target extension type. |
207 | bool isTargetExtTy() const { return getTypeID() == TargetExtTyID; } |
208 | |
209 | /// Return true if this is a target extension type with a scalable layout. |
210 | bool isScalableTargetExtTy() const; |
211 | |
212 | /// Return true if this is a scalable vector type or a target extension type |
213 | /// with a scalable layout. |
214 | bool isScalableTy() const; |
215 | |
216 | /// Return true if this is a FP type or a vector of FP. |
217 | bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy(); } |
218 | |
219 | /// Return true if this is 'label'. |
220 | bool isLabelTy() const { return getTypeID() == LabelTyID; } |
221 | |
222 | /// Return true if this is 'metadata'. |
223 | bool isMetadataTy() const { return getTypeID() == MetadataTyID; } |
224 | |
225 | /// Return true if this is 'token'. |
226 | bool isTokenTy() const { return getTypeID() == TokenTyID; } |
227 | |
228 | /// True if this is an instance of IntegerType. |
229 | bool isIntegerTy() const { return getTypeID() == IntegerTyID; } |
230 | |
231 | /// Return true if this is an IntegerType of the given width. |
232 | bool isIntegerTy(unsigned Bitwidth) const; |
233 | |
234 | /// Return true if this is an integer type or a vector of integer types. |
235 | bool isIntOrIntVectorTy() const { return getScalarType()->isIntegerTy(); } |
236 | |
237 | /// Return true if this is an integer type or a vector of integer types of |
238 | /// the given width. |
239 | bool isIntOrIntVectorTy(unsigned BitWidth) const { |
240 | return getScalarType()->isIntegerTy(Bitwidth: BitWidth); |
241 | } |
242 | |
243 | /// Return true if this is an integer type or a pointer type. |
244 | bool isIntOrPtrTy() const { return isIntegerTy() || isPointerTy(); } |
245 | |
246 | /// True if this is an instance of FunctionType. |
247 | bool isFunctionTy() const { return getTypeID() == FunctionTyID; } |
248 | |
249 | /// True if this is an instance of StructType. |
250 | bool isStructTy() const { return getTypeID() == StructTyID; } |
251 | |
252 | /// True if this is an instance of ArrayType. |
253 | bool isArrayTy() const { return getTypeID() == ArrayTyID; } |
254 | |
255 | /// True if this is an instance of PointerType. |
256 | bool isPointerTy() const { return getTypeID() == PointerTyID; } |
257 | |
258 | /// True if this is an instance of an opaque PointerType. |
259 | LLVM_DEPRECATED("Use isPointerTy() instead" , "isPointerTy" ) |
260 | bool isOpaquePointerTy() const { return isPointerTy(); }; |
261 | |
262 | /// Return true if this is a pointer type or a vector of pointer types. |
263 | bool isPtrOrPtrVectorTy() const { return getScalarType()->isPointerTy(); } |
264 | |
265 | /// True if this is an instance of VectorType. |
266 | inline bool isVectorTy() const { |
267 | return getTypeID() == ScalableVectorTyID || getTypeID() == FixedVectorTyID; |
268 | } |
269 | |
270 | /// Return true if this type could be converted with a lossless BitCast to |
271 | /// type 'Ty'. For example, i8* to i32*. BitCasts are valid for types of the |
272 | /// same size only where no re-interpretation of the bits is done. |
273 | /// Determine if this type could be losslessly bitcast to Ty |
274 | bool canLosslesslyBitCastTo(Type *Ty) const; |
275 | |
276 | /// Return true if this type is empty, that is, it has no elements or all of |
277 | /// its elements are empty. |
278 | bool isEmptyTy() const; |
279 | |
280 | /// Return true if the type is "first class", meaning it is a valid type for a |
281 | /// Value. |
282 | bool isFirstClassType() const { |
283 | return getTypeID() != FunctionTyID && getTypeID() != VoidTyID; |
284 | } |
285 | |
286 | /// Return true if the type is a valid type for a register in codegen. This |
287 | /// includes all first-class types except struct and array types. |
288 | bool isSingleValueType() const { |
289 | return isFloatingPointTy() || isX86_MMXTy() || isIntegerTy() || |
290 | isPointerTy() || isVectorTy() || isX86_AMXTy() || isTargetExtTy(); |
291 | } |
292 | |
293 | /// Return true if the type is an aggregate type. This means it is valid as |
294 | /// the first operand of an insertvalue or extractvalue instruction. This |
295 | /// includes struct and array types, but does not include vector types. |
296 | bool isAggregateType() const { |
297 | return getTypeID() == StructTyID || getTypeID() == ArrayTyID; |
298 | } |
299 | |
300 | /// Return true if it makes sense to take the size of this type. To get the |
301 | /// actual size for a particular target, it is reasonable to use the |
302 | /// DataLayout subsystem to do this. |
303 | bool isSized(SmallPtrSetImpl<Type*> *Visited = nullptr) const { |
304 | // If it's a primitive, it is always sized. |
305 | if (getTypeID() == IntegerTyID || isFloatingPointTy() || |
306 | getTypeID() == PointerTyID || getTypeID() == X86_MMXTyID || |
307 | getTypeID() == X86_AMXTyID) |
308 | return true; |
309 | // If it is not something that can have a size (e.g. a function or label), |
310 | // it doesn't have a size. |
311 | if (getTypeID() != StructTyID && getTypeID() != ArrayTyID && |
312 | !isVectorTy() && getTypeID() != TargetExtTyID) |
313 | return false; |
314 | // Otherwise we have to try harder to decide. |
315 | return isSizedDerivedType(Visited); |
316 | } |
317 | |
318 | /// Return the basic size of this type if it is a primitive type. These are |
319 | /// fixed by LLVM and are not target-dependent. |
320 | /// This will return zero if the type does not have a size or is not a |
321 | /// primitive type. |
322 | /// |
323 | /// If this is a scalable vector type, the scalable property will be set and |
324 | /// the runtime size will be a positive integer multiple of the base size. |
325 | /// |
326 | /// Note that this may not reflect the size of memory allocated for an |
327 | /// instance of the type or the number of bytes that are written when an |
328 | /// instance of the type is stored to memory. The DataLayout class provides |
329 | /// additional query functions to provide this information. |
330 | /// |
331 | TypeSize getPrimitiveSizeInBits() const LLVM_READONLY; |
332 | |
333 | /// If this is a vector type, return the getPrimitiveSizeInBits value for the |
334 | /// element type. Otherwise return the getPrimitiveSizeInBits value for this |
335 | /// type. |
336 | unsigned getScalarSizeInBits() const LLVM_READONLY; |
337 | |
338 | /// Return the width of the mantissa of this type. This is only valid on |
339 | /// floating-point types. If the FP type does not have a stable mantissa (e.g. |
340 | /// ppc long double), this method returns -1. |
341 | int getFPMantissaWidth() const; |
342 | |
343 | /// Return whether the type is IEEE compatible, as defined by the eponymous |
344 | /// method in APFloat. |
345 | bool isIEEE() const; |
346 | |
347 | /// If this is a vector type, return the element type, otherwise return |
348 | /// 'this'. |
349 | inline Type *getScalarType() const { |
350 | if (isVectorTy()) |
351 | return getContainedType(i: 0); |
352 | return const_cast<Type *>(this); |
353 | } |
354 | |
355 | //===--------------------------------------------------------------------===// |
356 | // Type Iteration support. |
357 | // |
358 | using subtype_iterator = Type * const *; |
359 | |
360 | subtype_iterator subtype_begin() const { return ContainedTys; } |
361 | subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];} |
362 | ArrayRef<Type*> subtypes() const { |
363 | return ArrayRef(subtype_begin(), subtype_end()); |
364 | } |
365 | |
366 | using subtype_reverse_iterator = std::reverse_iterator<subtype_iterator>; |
367 | |
368 | subtype_reverse_iterator subtype_rbegin() const { |
369 | return subtype_reverse_iterator(subtype_end()); |
370 | } |
371 | subtype_reverse_iterator subtype_rend() const { |
372 | return subtype_reverse_iterator(subtype_begin()); |
373 | } |
374 | |
375 | /// This method is used to implement the type iterator (defined at the end of |
376 | /// the file). For derived types, this returns the types 'contained' in the |
377 | /// derived type. |
378 | Type *getContainedType(unsigned i) const { |
379 | assert(i < NumContainedTys && "Index out of range!" ); |
380 | return ContainedTys[i]; |
381 | } |
382 | |
383 | /// Return the number of types in the derived type. |
384 | unsigned getNumContainedTypes() const { return NumContainedTys; } |
385 | |
386 | //===--------------------------------------------------------------------===// |
387 | // Helper methods corresponding to subclass methods. This forces a cast to |
388 | // the specified subclass and calls its accessor. "getArrayNumElements" (for |
389 | // example) is shorthand for cast<ArrayType>(Ty)->getNumElements(). This is |
390 | // only intended to cover the core methods that are frequently used, helper |
391 | // methods should not be added here. |
392 | |
393 | inline unsigned getIntegerBitWidth() const; |
394 | |
395 | inline Type *getFunctionParamType(unsigned i) const; |
396 | inline unsigned getFunctionNumParams() const; |
397 | inline bool isFunctionVarArg() const; |
398 | |
399 | inline StringRef getStructName() const; |
400 | inline unsigned getStructNumElements() const; |
401 | inline Type *getStructElementType(unsigned N) const; |
402 | |
403 | inline uint64_t getArrayNumElements() const; |
404 | |
405 | Type *getArrayElementType() const { |
406 | assert(getTypeID() == ArrayTyID); |
407 | return ContainedTys[0]; |
408 | } |
409 | |
410 | inline StringRef getTargetExtName() const; |
411 | |
412 | /// Only use this method in code that is not reachable with opaque pointers, |
413 | /// or part of deprecated methods that will be removed as part of the opaque |
414 | /// pointers transition. |
415 | [[deprecated("Pointers no longer have element types" )]] |
416 | Type *getNonOpaquePointerElementType() const { |
417 | llvm_unreachable("Pointers no longer have element types" ); |
418 | } |
419 | |
420 | /// Given vector type, change the element type, |
421 | /// whilst keeping the old number of elements. |
422 | /// For non-vectors simply returns \p EltTy. |
423 | inline Type *getWithNewType(Type *EltTy) const; |
424 | |
425 | /// Given an integer or vector type, change the lane bitwidth to NewBitwidth, |
426 | /// whilst keeping the old number of lanes. |
427 | inline Type *getWithNewBitWidth(unsigned NewBitWidth) const; |
428 | |
429 | /// Given scalar/vector integer type, returns a type with elements twice as |
430 | /// wide as in the original type. For vectors, preserves element count. |
431 | inline Type *getExtendedType() const; |
432 | |
433 | /// Get the address space of this pointer or pointer vector type. |
434 | inline unsigned getPointerAddressSpace() const; |
435 | |
436 | //===--------------------------------------------------------------------===// |
437 | // Static members exported by the Type class itself. Useful for getting |
438 | // instances of Type. |
439 | // |
440 | |
441 | /// Return a type based on an identifier. |
442 | static Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber); |
443 | |
444 | //===--------------------------------------------------------------------===// |
445 | // These are the builtin types that are always available. |
446 | // |
447 | static Type *getVoidTy(LLVMContext &C); |
448 | static Type *getLabelTy(LLVMContext &C); |
449 | static Type *getHalfTy(LLVMContext &C); |
450 | static Type *getBFloatTy(LLVMContext &C); |
451 | static Type *getFloatTy(LLVMContext &C); |
452 | static Type *getDoubleTy(LLVMContext &C); |
453 | static Type *getMetadataTy(LLVMContext &C); |
454 | static Type *getX86_FP80Ty(LLVMContext &C); |
455 | static Type *getFP128Ty(LLVMContext &C); |
456 | static Type *getPPC_FP128Ty(LLVMContext &C); |
457 | static Type *getX86_MMXTy(LLVMContext &C); |
458 | static Type *getX86_AMXTy(LLVMContext &C); |
459 | static Type *getTokenTy(LLVMContext &C); |
460 | static IntegerType *getIntNTy(LLVMContext &C, unsigned N); |
461 | static IntegerType *getInt1Ty(LLVMContext &C); |
462 | static IntegerType *getInt8Ty(LLVMContext &C); |
463 | static IntegerType *getInt16Ty(LLVMContext &C); |
464 | static IntegerType *getInt32Ty(LLVMContext &C); |
465 | static IntegerType *getInt64Ty(LLVMContext &C); |
466 | static IntegerType *getInt128Ty(LLVMContext &C); |
467 | template <typename ScalarTy> static Type *getScalarTy(LLVMContext &C) { |
468 | int noOfBits = sizeof(ScalarTy) * CHAR_BIT; |
469 | if (std::is_integral<ScalarTy>::value) { |
470 | return (Type*) Type::getIntNTy(C, N: noOfBits); |
471 | } else if (std::is_floating_point<ScalarTy>::value) { |
472 | switch (noOfBits) { |
473 | case 32: |
474 | return Type::getFloatTy(C); |
475 | case 64: |
476 | return Type::getDoubleTy(C); |
477 | } |
478 | } |
479 | llvm_unreachable("Unsupported type in Type::getScalarTy" ); |
480 | } |
481 | static Type *getFloatingPointTy(LLVMContext &C, const fltSemantics &S); |
482 | |
483 | //===--------------------------------------------------------------------===// |
484 | // Convenience methods for getting pointer types with one of the above builtin |
485 | // types as pointee. |
486 | // |
487 | static PointerType *getHalfPtrTy(LLVMContext &C, unsigned AS = 0); |
488 | static PointerType *getBFloatPtrTy(LLVMContext &C, unsigned AS = 0); |
489 | static PointerType *getFloatPtrTy(LLVMContext &C, unsigned AS = 0); |
490 | static PointerType *getDoublePtrTy(LLVMContext &C, unsigned AS = 0); |
491 | static PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0); |
492 | static PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0); |
493 | static PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0); |
494 | static PointerType *getX86_MMXPtrTy(LLVMContext &C, unsigned AS = 0); |
495 | static PointerType *getX86_AMXPtrTy(LLVMContext &C, unsigned AS = 0); |
496 | static PointerType *getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS = 0); |
497 | static PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0); |
498 | static PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0); |
499 | static PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0); |
500 | static PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0); |
501 | static PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0); |
502 | static Type *getWasm_ExternrefTy(LLVMContext &C); |
503 | static Type *getWasm_FuncrefTy(LLVMContext &C); |
504 | |
505 | /// Return a pointer to the current type. This is equivalent to |
506 | /// PointerType::get(Foo, AddrSpace). |
507 | /// TODO: Remove this after opaque pointer transition is complete. |
508 | PointerType *getPointerTo(unsigned AddrSpace = 0) const; |
509 | |
510 | private: |
511 | /// Derived types like structures and arrays are sized iff all of the members |
512 | /// of the type are sized as well. Since asking for their size is relatively |
513 | /// uncommon, move this operation out-of-line. |
514 | bool isSizedDerivedType(SmallPtrSetImpl<Type*> *Visited = nullptr) const; |
515 | }; |
516 | |
517 | // Printing of types. |
518 | inline raw_ostream &operator<<(raw_ostream &OS, const Type &T) { |
519 | T.print(O&: OS); |
520 | return OS; |
521 | } |
522 | |
523 | // allow isa<PointerType>(x) to work without DerivedTypes.h included. |
524 | template <> struct isa_impl<PointerType, Type> { |
525 | static inline bool doit(const Type &Ty) { |
526 | return Ty.getTypeID() == Type::PointerTyID; |
527 | } |
528 | }; |
529 | |
530 | // Create wrappers for C Binding types (see CBindingWrapping.h). |
531 | DEFINE_ISA_CONVERSION_FUNCTIONS(Type, LLVMTypeRef) |
532 | |
533 | /* Specialized opaque type conversions. |
534 | */ |
535 | inline Type **unwrap(LLVMTypeRef* Tys) { |
536 | return reinterpret_cast<Type**>(Tys); |
537 | } |
538 | |
539 | inline LLVMTypeRef *wrap(Type **Tys) { |
540 | return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys)); |
541 | } |
542 | |
543 | } // end namespace llvm |
544 | |
545 | #endif // LLVM_IR_TYPE_H |
546 | |