| 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 |  |