#ifndef LLVM_CONSTANTS_H
#define LLVM_CONSTANTS_H
#include "llvm/Constant.h"
#include "llvm/OperandTraits.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
namespace llvm {
class ArrayType;
class IntegerType;
class StructType;
class PointerType;
class VectorType;
template<class ConstantClass, class TypeClass, class ValType>
struct ConstantCreator;
template<class ConstantClass, class TypeClass>
struct ConvertConstantType;
class ConstantInt : public Constant {
void *operator new(size_t, unsigned); ConstantInt(const ConstantInt &); ConstantInt(const IntegerType *Ty, const APInt& V);
APInt Val;
protected:
void *operator new(size_t s) {
return User::operator new(s, 0);
}
public:
static ConstantInt *getTrue(LLVMContext &Context);
static ConstantInt *getFalse(LLVMContext &Context);
static Constant *getTrue(const Type *Ty);
static Constant *getFalse(const Type *Ty);
static Constant *get(const Type *Ty, uint64_t V, bool isSigned = false);
static ConstantInt *get(const IntegerType *Ty, uint64_t V,
bool isSigned = false);
static ConstantInt *getSigned(const IntegerType *Ty, int64_t V);
static Constant *getSigned(const Type *Ty, int64_t V);
static ConstantInt *get(LLVMContext &Context, const APInt &V);
static ConstantInt *get(const IntegerType *Ty, StringRef Str,
uint8_t radix);
static Constant *get(const Type* Ty, const APInt& V);
inline const APInt &getValue() const {
return Val;
}
unsigned getBitWidth() const { return Val.getBitWidth(); }
inline uint64_t getZExtValue() const {
return Val.getZExtValue();
}
inline int64_t getSExtValue() const {
return Val.getSExtValue();
}
bool equalsInt(uint64_t V) const {
return Val == V;
}
inline const IntegerType *getType() const {
return reinterpret_cast<const IntegerType*>(Value::getType());
}
static bool isValueValidForType(const Type *Ty, uint64_t V);
static bool isValueValidForType(const Type *Ty, int64_t V);
virtual bool isNullValue() const {
return Val == 0;
}
bool isZero() const {
return Val == 0;
}
bool isOne() const {
return Val == 1;
}
bool isAllOnesValue() const {
return Val.isAllOnesValue();
}
bool isMaxValue(bool isSigned) const {
if (isSigned)
return Val.isMaxSignedValue();
else
return Val.isMaxValue();
}
bool isMinValue(bool isSigned) const {
if (isSigned)
return Val.isMinSignedValue();
else
return Val.isMinValue();
}
bool uge(uint64_t Num) {
return Val.getActiveBits() > 64 || Val.getZExtValue() >= Num;
}
uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
return Val.getLimitedValue(Limit);
}
static inline bool classof(const ConstantInt *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantIntVal;
}
};
class ConstantFP : public Constant {
APFloat Val;
void *operator new(size_t, unsigned); ConstantFP(const ConstantFP &); friend class LLVMContextImpl;
protected:
ConstantFP(const Type *Ty, const APFloat& V);
protected:
void *operator new(size_t s) {
return User::operator new(s, 0);
}
public:
static Constant *getZeroValueForNegation(const Type *Ty);
static Constant *get(const Type* Ty, double V);
static Constant *get(const Type* Ty, StringRef Str);
static ConstantFP *get(LLVMContext &Context, const APFloat &V);
static ConstantFP *getNegativeZero(const Type* Ty);
static ConstantFP *getInfinity(const Type *Ty, bool Negative = false);
static bool isValueValidForType(const Type *Ty, const APFloat &V);
inline const APFloat& getValueAPF() const { return Val; }
virtual bool isNullValue() const;
virtual bool isNegativeZeroValue() const {
return Val.isZero() && Val.isNegative();
}
bool isZero() const { return Val.isZero(); }
bool isNaN() const { return Val.isNaN(); }
bool isExactlyValue(const APFloat &V) const;
bool isExactlyValue(double V) const {
bool ignored;
if (&Val.getSemantics() == &APFloat::PPCDoubleDouble)
return false;
APFloat FV(V);
FV.convert(Val.getSemantics(), APFloat::rmNearestTiesToEven, &ignored);
return isExactlyValue(FV);
}
static inline bool classof(const ConstantFP *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantFPVal;
}
};
class ConstantAggregateZero : public Constant {
friend struct ConstantCreator<ConstantAggregateZero, Type, char>;
void *operator new(size_t, unsigned); ConstantAggregateZero(const ConstantAggregateZero &); protected:
explicit ConstantAggregateZero(const Type *ty)
: Constant(ty, ConstantAggregateZeroVal, 0, 0) {}
protected:
void *operator new(size_t s) {
return User::operator new(s, 0);
}
public:
static ConstantAggregateZero* get(const Type *Ty);
virtual bool isNullValue() const { return true; }
virtual void destroyConstant();
static bool classof(const ConstantAggregateZero *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantAggregateZeroVal;
}
};
class ConstantArray : public Constant {
friend struct ConstantCreator<ConstantArray, ArrayType,
std::vector<Constant*> >;
ConstantArray(const ConstantArray &); protected:
ConstantArray(const ArrayType *T, const std::vector<Constant*> &Val);
public:
static Constant *get(const ArrayType *T, const std::vector<Constant*> &V);
static Constant *get(const ArrayType *T, Constant *const *Vals,
unsigned NumVals);
static Constant *get(LLVMContext &Context, StringRef Initializer,
bool AddNull = true);
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
inline const ArrayType *getType() const {
return reinterpret_cast<const ArrayType*>(Value::getType());
}
bool isString() const;
bool isCString() const;
std::string getAsString() const;
virtual bool isNullValue() const { return false; }
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
static inline bool classof(const ConstantArray *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantArrayVal;
}
};
template <>
struct OperandTraits<ConstantArray> :
public VariadicOperandTraits<ConstantArray> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantArray, Constant)
class ConstantStruct : public Constant {
friend struct ConstantCreator<ConstantStruct, StructType,
std::vector<Constant*> >;
ConstantStruct(const ConstantStruct &); protected:
ConstantStruct(const StructType *T, const std::vector<Constant*> &Val);
public:
static Constant *get(const StructType *T, const std::vector<Constant*> &V);
static Constant *get(LLVMContext &Context,
const std::vector<Constant*> &V, bool Packed);
static Constant *get(LLVMContext &Context,
Constant *const *Vals, unsigned NumVals, bool Packed);
static Constant *get(LLVMContext &Context, bool Packed,
Constant * Val, ...) END_WITH_NULL;
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
inline const StructType *getType() const {
return reinterpret_cast<const StructType*>(Value::getType());
}
virtual bool isNullValue() const {
return false;
}
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
static inline bool classof(const ConstantStruct *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantStructVal;
}
};
template <>
struct OperandTraits<ConstantStruct> :
public VariadicOperandTraits<ConstantStruct> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant)
class ConstantVector : public Constant {
friend struct ConstantCreator<ConstantVector, VectorType,
std::vector<Constant*> >;
ConstantVector(const ConstantVector &); protected:
ConstantVector(const VectorType *T, const std::vector<Constant*> &Val);
public:
static Constant *get(ArrayRef<Constant*> V);
static Constant *get(const VectorType *T, const std::vector<Constant*> &V);
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
inline const VectorType *getType() const {
return reinterpret_cast<const VectorType*>(Value::getType());
}
virtual bool isNullValue() const { return false; }
bool isAllOnesValue() const;
Constant *getSplatValue() const;
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
static inline bool classof(const ConstantVector *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantVectorVal;
}
};
template <>
struct OperandTraits<ConstantVector> :
public VariadicOperandTraits<ConstantVector> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantVector, Constant)
class ConstantPointerNull : public Constant {
friend struct ConstantCreator<ConstantPointerNull, PointerType, char>;
void *operator new(size_t, unsigned); ConstantPointerNull(const ConstantPointerNull &); protected:
explicit ConstantPointerNull(const PointerType *T)
: Constant(reinterpret_cast<const Type*>(T),
Value::ConstantPointerNullVal, 0, 0) {}
protected:
void *operator new(size_t s) {
return User::operator new(s, 0);
}
public:
static ConstantPointerNull *get(const PointerType *T);
virtual bool isNullValue() const { return true; }
virtual void destroyConstant();
inline const PointerType *getType() const {
return reinterpret_cast<const PointerType*>(Value::getType());
}
static inline bool classof(const ConstantPointerNull *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantPointerNullVal;
}
};
class BlockAddress : public Constant {
void *operator new(size_t, unsigned); void *operator new(size_t s) { return User::operator new(s, 2); }
BlockAddress(Function *F, BasicBlock *BB);
public:
static BlockAddress *get(Function *F, BasicBlock *BB);
static BlockAddress *get(BasicBlock *BB);
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
Function *getFunction() const { return (Function*)Op<0>().get(); }
BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); }
virtual bool isNullValue() const { return false; }
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
static inline bool classof(const BlockAddress *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == BlockAddressVal;
}
};
template <>
struct OperandTraits<BlockAddress> :
public FixedNumOperandTraits<BlockAddress, 2> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Value)
class ConstantExpr : public Constant {
friend struct ConstantCreator<ConstantExpr,Type,
std::pair<unsigned, std::vector<Constant*> > >;
friend struct ConvertConstantType<ConstantExpr, Type>;
protected:
ConstantExpr(const Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps)
: Constant(ty, ConstantExprVal, Ops, NumOps) {
setValueSubclassData(Opcode);
}
static Constant *getTy(const Type *Ty, unsigned Opcode,
Constant *C1, Constant *C2,
unsigned Flags = 0);
static Constant *getCompareTy(unsigned short pred, Constant *C1,
Constant *C2);
static Constant *getSelectTy(const Type *Ty,
Constant *C1, Constant *C2, Constant *C3);
template<typename IndexTy>
static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
IndexTy const *Idxs, unsigned NumIdxs,
bool InBounds);
static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
Constant *Idx);
static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
Constant *Elt, Constant *Idx);
static Constant *getShuffleVectorTy(const Type *Ty, Constant *V1,
Constant *V2, Constant *Mask);
static Constant *getExtractValueTy(const Type *Ty, Constant *Agg,
const unsigned *Idxs, unsigned NumIdxs);
static Constant *getInsertValueTy(const Type *Ty, Constant *Agg,
Constant *Val,
const unsigned *Idxs, unsigned NumIdxs);
template<typename IndexTy>
static Constant *getGetElementPtrImpl(Constant *C,
IndexTy const *IdxList,
unsigned NumIdx, bool InBounds);
public:
static Constant *getAlignOf(const Type *Ty);
static Constant *getSizeOf(const Type *Ty);
static Constant *getOffsetOf(const StructType *STy, unsigned FieldNo);
static Constant *getOffsetOf(const Type *Ty, Constant *FieldNo);
static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false);
static Constant *getFNeg(Constant *C);
static Constant *getNot(Constant *C);
static Constant *getAdd(Constant *C1, Constant *C2,
bool HasNUW = false, bool HasNSW = false);
static Constant *getFAdd(Constant *C1, Constant *C2);
static Constant *getSub(Constant *C1, Constant *C2,
bool HasNUW = false, bool HasNSW = false);
static Constant *getFSub(Constant *C1, Constant *C2);
static Constant *getMul(Constant *C1, Constant *C2,
bool HasNUW = false, bool HasNSW = false);
static Constant *getFMul(Constant *C1, Constant *C2);
static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getFDiv(Constant *C1, Constant *C2);
static Constant *getURem(Constant *C1, Constant *C2);
static Constant *getSRem(Constant *C1, Constant *C2);
static Constant *getFRem(Constant *C1, Constant *C2);
static Constant *getAnd(Constant *C1, Constant *C2);
static Constant *getOr(Constant *C1, Constant *C2);
static Constant *getXor(Constant *C1, Constant *C2);
static Constant *getShl(Constant *C1, Constant *C2,
bool HasNUW = false, bool HasNSW = false);
static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getTrunc (Constant *C, const Type *Ty);
static Constant *getSExt (Constant *C, const Type *Ty);
static Constant *getZExt (Constant *C, const Type *Ty);
static Constant *getFPTrunc (Constant *C, const Type *Ty);
static Constant *getFPExtend(Constant *C, const Type *Ty);
static Constant *getUIToFP (Constant *C, const Type *Ty);
static Constant *getSIToFP (Constant *C, const Type *Ty);
static Constant *getFPToUI (Constant *C, const Type *Ty);
static Constant *getFPToSI (Constant *C, const Type *Ty);
static Constant *getPtrToInt(Constant *C, const Type *Ty);
static Constant *getIntToPtr(Constant *C, const Type *Ty);
static Constant *getBitCast (Constant *C, const Type *Ty);
static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
static Constant *getNSWAdd(Constant *C1, Constant *C2) {
return getAdd(C1, C2, false, true);
}
static Constant *getNUWAdd(Constant *C1, Constant *C2) {
return getAdd(C1, C2, true, false);
}
static Constant *getNSWSub(Constant *C1, Constant *C2) {
return getSub(C1, C2, false, true);
}
static Constant *getNUWSub(Constant *C1, Constant *C2) {
return getSub(C1, C2, true, false);
}
static Constant *getNSWMul(Constant *C1, Constant *C2) {
return getMul(C1, C2, false, true);
}
static Constant *getNUWMul(Constant *C1, Constant *C2) {
return getMul(C1, C2, true, false);
}
static Constant *getNSWShl(Constant *C1, Constant *C2) {
return getShl(C1, C2, false, true);
}
static Constant *getNUWShl(Constant *C1, Constant *C2) {
return getShl(C1, C2, true, false);
}
static Constant *getExactSDiv(Constant *C1, Constant *C2) {
return getSDiv(C1, C2, true);
}
static Constant *getExactUDiv(Constant *C1, Constant *C2) {
return getUDiv(C1, C2, true);
}
static Constant *getExactAShr(Constant *C1, Constant *C2) {
return getAShr(C1, C2, true);
}
static Constant *getExactLShr(Constant *C1, Constant *C2) {
return getLShr(C1, C2, true);
}
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
static Constant *getCast(
unsigned ops, Constant *C, const Type *Ty );
static Constant *getZExtOrBitCast(
Constant *C, const Type *Ty );
static Constant *getSExtOrBitCast(
Constant *C, const Type *Ty );
static Constant *getTruncOrBitCast(
Constant *C, const Type *Ty );
static Constant *getPointerCast(
Constant *C, const Type *Ty );
static Constant *getIntegerCast(
Constant *C, const Type *Ty, bool isSigned );
static Constant *getFPCast(
Constant *C, const Type *Ty );
bool isCast() const;
bool isCompare() const;
bool hasIndices() const;
bool isGEPWithNoNotionalOverIndexing() const;
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) {
return getSelectTy(V1->getType(), C, V1, V2);
}
static Constant *get(unsigned Opcode, Constant *C1, Constant *C2,
unsigned Flags = 0);
static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS);
static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
static Constant *getGetElementPtr(Constant *C,
Constant *const *IdxList, unsigned NumIdx,
bool InBounds = false);
static Constant *getGetElementPtr(Constant *C,
Value *const *IdxList, unsigned NumIdx,
bool InBounds = false);
static Constant *getInBoundsGetElementPtr(Constant *C,
Constant *const *IdxList,
unsigned NumIdx) {
return getGetElementPtr(C, IdxList, NumIdx, true);
}
static Constant *getInBoundsGetElementPtr(Constant *C,
Value* const *IdxList,
unsigned NumIdx) {
return getGetElementPtr(C, IdxList, NumIdx, true);
}
static Constant *getExtractElement(Constant *Vec, Constant *Idx);
static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
static Constant *getExtractValue(Constant *Agg,
const unsigned *IdxList, unsigned NumIdx);
static Constant *getInsertValue(Constant *Agg, Constant *Val,
const unsigned *IdxList, unsigned NumIdx);
virtual bool isNullValue() const { return false; }
unsigned getOpcode() const { return getSubclassDataFromValue(); }
unsigned getPredicate() const;
ArrayRef<unsigned> getIndices() const;
const char *getOpcodeName() const;
Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const;
Constant *getWithOperands(ArrayRef<Constant*> Ops) const;
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
static inline bool classof(const ConstantExpr *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == ConstantExprVal;
}
private:
void setValueSubclassData(unsigned short D) {
Value::setValueSubclassData(D);
}
};
template <>
struct OperandTraits<ConstantExpr> :
public VariadicOperandTraits<ConstantExpr, 1> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantExpr, Constant)
class UndefValue : public Constant {
friend struct ConstantCreator<UndefValue, Type, char>;
void *operator new(size_t, unsigned); UndefValue(const UndefValue &); protected:
explicit UndefValue(const Type *T) : Constant(T, UndefValueVal, 0, 0) {}
protected:
void *operator new(size_t s) {
return User::operator new(s, 0);
}
public:
static UndefValue *get(const Type *T);
virtual bool isNullValue() const { return false; }
virtual void destroyConstant();
static inline bool classof(const UndefValue *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == UndefValueVal;
}
};
}
#endif