File indexing completed on 2026-05-10 08:44:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_IR_TYPE_H
0015 #define LLVM_IR_TYPE_H
0016
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/Support/CBindingWrapping.h"
0019 #include "llvm/Support/Casting.h"
0020 #include "llvm/Support/Compiler.h"
0021 #include "llvm/Support/ErrorHandling.h"
0022 #include "llvm/Support/TypeSize.h"
0023 #include <cassert>
0024 #include <cstdint>
0025 #include <iterator>
0026
0027 namespace llvm {
0028
0029 class IntegerType;
0030 struct fltSemantics;
0031 class LLVMContext;
0032 class PointerType;
0033 class raw_ostream;
0034 class StringRef;
0035 template <typename PtrType> class SmallPtrSetImpl;
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 class Type {
0046 public:
0047
0048
0049
0050
0051
0052
0053
0054 enum TypeID {
0055
0056 HalfTyID = 0,
0057 BFloatTyID,
0058 FloatTyID,
0059 DoubleTyID,
0060 X86_FP80TyID,
0061 FP128TyID,
0062 PPC_FP128TyID,
0063 VoidTyID,
0064 LabelTyID,
0065 MetadataTyID,
0066 X86_AMXTyID,
0067 TokenTyID,
0068
0069
0070 IntegerTyID,
0071 FunctionTyID,
0072 PointerTyID,
0073 StructTyID,
0074 ArrayTyID,
0075 FixedVectorTyID,
0076 ScalableVectorTyID,
0077 TypedPointerTyID,
0078 TargetExtTyID,
0079 };
0080
0081 private:
0082
0083 LLVMContext &Context;
0084
0085 TypeID ID : 8;
0086 unsigned SubclassData : 24;
0087
0088
0089
0090 protected:
0091 friend class LLVMContextImpl;
0092
0093 explicit Type(LLVMContext &C, TypeID tid)
0094 : Context(C), ID(tid), SubclassData(0) {}
0095 ~Type() = default;
0096
0097 unsigned getSubclassData() const { return SubclassData; }
0098
0099 void setSubclassData(unsigned val) {
0100 SubclassData = val;
0101
0102 assert(getSubclassData() == val && "Subclass data too large for field");
0103 }
0104
0105
0106 unsigned NumContainedTys = 0;
0107
0108
0109
0110
0111
0112
0113 Type * const *ContainedTys = nullptr;
0114
0115 public:
0116
0117
0118
0119
0120
0121
0122 void print(raw_ostream &O, bool IsForDebug = false,
0123 bool NoDetails = false) const;
0124
0125 void dump() const;
0126
0127
0128 LLVMContext &getContext() const { return Context; }
0129
0130
0131
0132
0133
0134
0135
0136 TypeID getTypeID() const { return ID; }
0137
0138
0139 bool isVoidTy() const { return getTypeID() == VoidTyID; }
0140
0141
0142 bool isHalfTy() const { return getTypeID() == HalfTyID; }
0143
0144
0145 bool isBFloatTy() const { return getTypeID() == BFloatTyID; }
0146
0147
0148 bool is16bitFPTy() const {
0149 return getTypeID() == BFloatTyID || getTypeID() == HalfTyID;
0150 }
0151
0152
0153 bool isFloatTy() const { return getTypeID() == FloatTyID; }
0154
0155
0156 bool isDoubleTy() const { return getTypeID() == DoubleTyID; }
0157
0158
0159 bool isX86_FP80Ty() const { return getTypeID() == X86_FP80TyID; }
0160
0161
0162 bool isFP128Ty() const { return getTypeID() == FP128TyID; }
0163
0164
0165 bool isPPC_FP128Ty() const { return getTypeID() == PPC_FP128TyID; }
0166
0167
0168
0169
0170 bool isIEEELikeFPTy() const {
0171 switch (getTypeID()) {
0172 case DoubleTyID:
0173 case FloatTyID:
0174 case HalfTyID:
0175 case BFloatTyID:
0176 case FP128TyID:
0177 return true;
0178 default:
0179 return false;
0180 }
0181 }
0182
0183
0184 bool isFloatingPointTy() const {
0185 return isIEEELikeFPTy() || getTypeID() == X86_FP80TyID ||
0186 getTypeID() == PPC_FP128TyID;
0187 }
0188
0189
0190
0191
0192
0193 bool isMultiUnitFPType() const {
0194 return getTypeID() == PPC_FP128TyID;
0195 }
0196
0197 const fltSemantics &getFltSemantics() const;
0198
0199
0200 bool isX86_AMXTy() const { return getTypeID() == X86_AMXTyID; }
0201
0202
0203 bool isTargetExtTy() const { return getTypeID() == TargetExtTyID; }
0204
0205
0206 bool isScalableTargetExtTy() const;
0207
0208
0209 bool isScalableTy(SmallPtrSetImpl<const Type *> &Visited) const;
0210 bool isScalableTy() const;
0211
0212
0213
0214 bool
0215 containsNonGlobalTargetExtType(SmallPtrSetImpl<const Type *> &Visited) const;
0216 bool containsNonGlobalTargetExtType() const;
0217
0218
0219
0220 bool
0221 containsNonLocalTargetExtType(SmallPtrSetImpl<const Type *> &Visited) const;
0222 bool containsNonLocalTargetExtType() const;
0223
0224
0225 bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy(); }
0226
0227
0228 bool isLabelTy() const { return getTypeID() == LabelTyID; }
0229
0230
0231 bool isMetadataTy() const { return getTypeID() == MetadataTyID; }
0232
0233
0234 bool isTokenTy() const { return getTypeID() == TokenTyID; }
0235
0236
0237 bool isIntegerTy() const { return getTypeID() == IntegerTyID; }
0238
0239
0240 bool isIntegerTy(unsigned Bitwidth) const;
0241
0242
0243 bool isIntOrIntVectorTy() const { return getScalarType()->isIntegerTy(); }
0244
0245
0246
0247 bool isIntOrIntVectorTy(unsigned BitWidth) const {
0248 return getScalarType()->isIntegerTy(BitWidth);
0249 }
0250
0251
0252 bool isIntOrPtrTy() const { return isIntegerTy() || isPointerTy(); }
0253
0254
0255 bool isFunctionTy() const { return getTypeID() == FunctionTyID; }
0256
0257
0258 bool isStructTy() const { return getTypeID() == StructTyID; }
0259
0260
0261 bool isArrayTy() const { return getTypeID() == ArrayTyID; }
0262
0263
0264 bool isPointerTy() const { return getTypeID() == PointerTyID; }
0265
0266
0267 bool isPtrOrPtrVectorTy() const { return getScalarType()->isPointerTy(); }
0268
0269
0270 inline bool isVectorTy() const {
0271 return getTypeID() == ScalableVectorTyID || getTypeID() == FixedVectorTyID;
0272 }
0273
0274
0275 bool isRISCVVectorTupleTy() const;
0276
0277
0278
0279
0280
0281 bool canLosslesslyBitCastTo(Type *Ty) const;
0282
0283
0284
0285 bool isEmptyTy() const;
0286
0287
0288
0289 bool isFirstClassType() const {
0290 return getTypeID() != FunctionTyID && getTypeID() != VoidTyID;
0291 }
0292
0293
0294
0295 bool isSingleValueType() const {
0296 return isFloatingPointTy() || isIntegerTy() || isPointerTy() ||
0297 isVectorTy() || isX86_AMXTy() || isTargetExtTy();
0298 }
0299
0300
0301
0302
0303 bool isAggregateType() const {
0304 return getTypeID() == StructTyID || getTypeID() == ArrayTyID;
0305 }
0306
0307
0308
0309
0310 bool isSized(SmallPtrSetImpl<Type*> *Visited = nullptr) const {
0311
0312 if (getTypeID() == IntegerTyID || isFloatingPointTy() ||
0313 getTypeID() == PointerTyID || getTypeID() == X86_AMXTyID)
0314 return true;
0315
0316
0317 if (getTypeID() != StructTyID && getTypeID() != ArrayTyID &&
0318 !isVectorTy() && getTypeID() != TargetExtTyID)
0319 return false;
0320
0321 return isSizedDerivedType(Visited);
0322 }
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 TypeSize getPrimitiveSizeInBits() const LLVM_READONLY;
0338
0339
0340
0341
0342 unsigned getScalarSizeInBits() const LLVM_READONLY;
0343
0344
0345
0346
0347 int getFPMantissaWidth() const;
0348
0349
0350
0351 bool isIEEE() const;
0352
0353
0354
0355 inline Type *getScalarType() const {
0356 if (isVectorTy())
0357 return getContainedType(0);
0358 return const_cast<Type *>(this);
0359 }
0360
0361
0362
0363
0364 using subtype_iterator = Type * const *;
0365
0366 subtype_iterator subtype_begin() const { return ContainedTys; }
0367 subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];}
0368 ArrayRef<Type*> subtypes() const {
0369 return ArrayRef(subtype_begin(), subtype_end());
0370 }
0371
0372 using subtype_reverse_iterator = std::reverse_iterator<subtype_iterator>;
0373
0374 subtype_reverse_iterator subtype_rbegin() const {
0375 return subtype_reverse_iterator(subtype_end());
0376 }
0377 subtype_reverse_iterator subtype_rend() const {
0378 return subtype_reverse_iterator(subtype_begin());
0379 }
0380
0381
0382
0383
0384 Type *getContainedType(unsigned i) const {
0385 assert(i < NumContainedTys && "Index out of range!");
0386 return ContainedTys[i];
0387 }
0388
0389
0390 unsigned getNumContainedTypes() const { return NumContainedTys; }
0391
0392
0393
0394
0395
0396
0397
0398
0399 inline unsigned getIntegerBitWidth() const;
0400
0401 inline Type *getFunctionParamType(unsigned i) const;
0402 inline unsigned getFunctionNumParams() const;
0403 inline bool isFunctionVarArg() const;
0404
0405 inline StringRef getStructName() const;
0406 inline unsigned getStructNumElements() const;
0407 inline Type *getStructElementType(unsigned N) const;
0408
0409 inline uint64_t getArrayNumElements() const;
0410
0411 Type *getArrayElementType() const {
0412 assert(getTypeID() == ArrayTyID);
0413 return ContainedTys[0];
0414 }
0415
0416 inline StringRef getTargetExtName() const;
0417
0418
0419
0420
0421 inline Type *getWithNewType(Type *EltTy) const;
0422
0423
0424
0425 inline Type *getWithNewBitWidth(unsigned NewBitWidth) const;
0426
0427
0428
0429 inline Type *getExtendedType() const;
0430
0431
0432 inline unsigned getPointerAddressSpace() const;
0433
0434
0435
0436
0437
0438
0439
0440 static Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber);
0441
0442
0443
0444
0445 static Type *getVoidTy(LLVMContext &C);
0446 static Type *getLabelTy(LLVMContext &C);
0447 static Type *getHalfTy(LLVMContext &C);
0448 static Type *getBFloatTy(LLVMContext &C);
0449 static Type *getFloatTy(LLVMContext &C);
0450 static Type *getDoubleTy(LLVMContext &C);
0451 static Type *getMetadataTy(LLVMContext &C);
0452 static Type *getX86_FP80Ty(LLVMContext &C);
0453 static Type *getFP128Ty(LLVMContext &C);
0454 static Type *getPPC_FP128Ty(LLVMContext &C);
0455 static Type *getX86_AMXTy(LLVMContext &C);
0456 static Type *getTokenTy(LLVMContext &C);
0457 static IntegerType *getIntNTy(LLVMContext &C, unsigned N);
0458 static IntegerType *getInt1Ty(LLVMContext &C);
0459 static IntegerType *getInt8Ty(LLVMContext &C);
0460 static IntegerType *getInt16Ty(LLVMContext &C);
0461 static IntegerType *getInt32Ty(LLVMContext &C);
0462 static IntegerType *getInt64Ty(LLVMContext &C);
0463 static IntegerType *getInt128Ty(LLVMContext &C);
0464 template <typename ScalarTy> static Type *getScalarTy(LLVMContext &C) {
0465 int noOfBits = sizeof(ScalarTy) * CHAR_BIT;
0466 if (std::is_integral<ScalarTy>::value) {
0467 return (Type*) Type::getIntNTy(C, noOfBits);
0468 } else if (std::is_floating_point<ScalarTy>::value) {
0469 switch (noOfBits) {
0470 case 32:
0471 return Type::getFloatTy(C);
0472 case 64:
0473 return Type::getDoubleTy(C);
0474 }
0475 }
0476 llvm_unreachable("Unsupported type in Type::getScalarTy");
0477 }
0478 static Type *getFloatingPointTy(LLVMContext &C, const fltSemantics &S);
0479
0480
0481
0482
0483 static Type *getWasm_ExternrefTy(LLVMContext &C);
0484 static Type *getWasm_FuncrefTy(LLVMContext &C);
0485
0486
0487
0488
0489 LLVM_DEPRECATED("Use PointerType::get instead", "PointerType::get")
0490 PointerType *getPointerTo(unsigned AddrSpace = 0) const;
0491
0492 private:
0493
0494
0495
0496 bool isSizedDerivedType(SmallPtrSetImpl<Type*> *Visited = nullptr) const;
0497 };
0498
0499
0500 inline raw_ostream &operator<<(raw_ostream &OS, const Type &T) {
0501 T.print(OS);
0502 return OS;
0503 }
0504
0505
0506 template <> struct isa_impl<PointerType, Type> {
0507 static inline bool doit(const Type &Ty) {
0508 return Ty.getTypeID() == Type::PointerTyID;
0509 }
0510 };
0511
0512
0513 DEFINE_ISA_CONVERSION_FUNCTIONS(Type, LLVMTypeRef)
0514
0515
0516
0517 inline Type **unwrap(LLVMTypeRef* Tys) {
0518 return reinterpret_cast<Type**>(Tys);
0519 }
0520
0521 inline LLVMTypeRef *wrap(Type **Tys) {
0522 return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
0523 }
0524
0525 }
0526
0527 #endif