#ifndef LLVM_DERIVED_TYPES_H
#define LLVM_DERIVED_TYPES_H
#include "llvm/Type.h"
namespace llvm {
class Value;
template<class ValType, class TypeClass> class TypeMap;
class FunctionValType;
class ArrayValType;
class StructValType;
class UnionValType;
class PointerValType;
class VectorValType;
class IntegerValType;
class APInt;
class LLVMContext;
class DerivedType : public Type {
friend class Type;
protected:
explicit DerivedType(LLVMContext &C, TypeID id) : Type(C, id) {}
void notifyUsesThatTypeBecameConcrete();
void dropAllTypeUses();
void unlockedRefineAbstractTypeTo(const Type *NewType);
public:
void refineAbstractTypeTo(const Type *NewType);
void dump() const { Type::dump(); }
static inline bool classof(const DerivedType *) { return true; }
static inline bool classof(const Type *T) {
return T->isDerivedType();
}
};
class IntegerType : public DerivedType {
friend class LLVMContextImpl;
protected:
explicit IntegerType(LLVMContext &C, unsigned NumBits) :
DerivedType(C, IntegerTyID) {
setSubclassData(NumBits);
}
friend class TypeMap<IntegerValType, IntegerType>;
public:
enum {
MIN_INT_BITS = 1, MAX_INT_BITS = (1<<23)-1 };
static const IntegerType* get(LLVMContext &C, unsigned NumBits);
unsigned getBitWidth() const { return getSubclassData(); }
uint64_t getBitMask() const {
return ~uint64_t(0UL) >> (64-getBitWidth());
}
uint64_t getSignBit() const {
return 1ULL << (getBitWidth()-1);
}
APInt getMask() const;
bool isPowerOf2ByteWidth() const;
static inline bool classof(const IntegerType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == IntegerTyID;
}
};
class FunctionType : public DerivedType {
friend class TypeMap<FunctionValType, FunctionType>;
bool isVarArgs;
FunctionType(const FunctionType &); const FunctionType &operator=(const FunctionType &); FunctionType(const Type *Result, const std::vector<const Type*> &Params,
bool IsVarArgs);
public:
static FunctionType *get(
const Type *Result, const std::vector<const Type*> &Params, bool isVarArg );
static FunctionType *get(
const Type *Result, bool isVarArg ) {
return get(Result, std::vector<const Type *>(), isVarArg);
}
static bool isValidReturnType(const Type *RetTy);
static bool isValidArgumentType(const Type *ArgTy);
inline bool isVarArg() const { return isVarArgs; }
inline const Type *getReturnType() const { return ContainedTys[0]; }
typedef Type::subtype_iterator param_iterator;
param_iterator param_begin() const { return ContainedTys + 1; }
param_iterator param_end() const { return &ContainedTys[NumContainedTys]; }
const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
unsigned getNumParams() const { return NumContainedTys - 1; }
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
static inline bool classof(const FunctionType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == FunctionTyID;
}
};
class CompositeType : public DerivedType {
protected:
inline explicit CompositeType(LLVMContext &C, TypeID id) :
DerivedType(C, id) { }
public:
virtual const Type *getTypeAtIndex(const Value *V) const = 0;
virtual const Type *getTypeAtIndex(unsigned Idx) const = 0;
virtual bool indexValid(const Value *V) const = 0;
virtual bool indexValid(unsigned Idx) const = 0;
static inline bool classof(const CompositeType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID ||
T->getTypeID() == StructTyID ||
T->getTypeID() == PointerTyID ||
T->getTypeID() == VectorTyID ||
T->getTypeID() == UnionTyID;
}
};
class StructType : public CompositeType {
friend class TypeMap<StructValType, StructType>;
StructType(const StructType &); const StructType &operator=(const StructType &); StructType(LLVMContext &C,
const std::vector<const Type*> &Types, bool isPacked);
public:
static StructType *get(LLVMContext &Context,
const std::vector<const Type*> &Params,
bool isPacked=false);
static StructType *get(LLVMContext &Context, bool isPacked=false) {
return get(Context, std::vector<const Type*>(), isPacked);
}
static StructType *get(LLVMContext &Context,
const Type *type, ...) END_WITH_NULL;
static bool isValidElementType(const Type *ElemTy);
typedef Type::subtype_iterator element_iterator;
element_iterator element_begin() const { return ContainedTys; }
element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
unsigned getNumElements() const { return NumContainedTys; }
const Type *getElementType(unsigned N) const {
assert(N < NumContainedTys && "Element number out of range!");
return ContainedTys[N];
}
virtual const Type *getTypeAtIndex(const Value *V) const;
virtual const Type *getTypeAtIndex(unsigned Idx) const;
virtual bool indexValid(const Value *V) const;
virtual bool indexValid(unsigned Idx) const;
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
static inline bool classof(const StructType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == StructTyID;
}
bool isPacked() const { return (0 != getSubclassData()) ? true : false; }
};
class UnionType : public CompositeType {
friend class TypeMap<UnionValType, UnionType>;
UnionType(const UnionType &); const UnionType &operator=(const UnionType &); UnionType(LLVMContext &C, const Type* const* Types, unsigned NumTypes);
public:
static UnionType *get(const Type* const* Types, unsigned NumTypes);
static UnionType *get(const Type *type, ...) END_WITH_NULL;
static bool isValidElementType(const Type *ElemTy);
int getElementTypeIndex(const Type *ElemTy) const;
typedef Type::subtype_iterator element_iterator;
element_iterator element_begin() const { return ContainedTys; }
element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
unsigned getNumElements() const { return NumContainedTys; }
const Type *getElementType(unsigned N) const {
assert(N < NumContainedTys && "Element number out of range!");
return ContainedTys[N];
}
virtual const Type *getTypeAtIndex(const Value *V) const;
virtual const Type *getTypeAtIndex(unsigned Idx) const;
virtual bool indexValid(const Value *V) const;
virtual bool indexValid(unsigned Idx) const;
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
static inline bool classof(const UnionType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == UnionTyID;
}
};
class SequentialType : public CompositeType {
PATypeHandle ContainedType; SequentialType(const SequentialType &); const SequentialType &operator=(const SequentialType &);
SequentialType* this_() { return this; }
protected:
SequentialType(TypeID TID, const Type *ElType)
: CompositeType(ElType->getContext(), TID), ContainedType(ElType, this_()) {
ContainedTys = &ContainedType;
NumContainedTys = 1;
}
public:
inline const Type *getElementType() const { return ContainedTys[0]; }
virtual bool indexValid(const Value *V) const;
virtual bool indexValid(unsigned) const {
return true;
}
virtual const Type *getTypeAtIndex(const Value *) const {
return ContainedTys[0];
}
virtual const Type *getTypeAtIndex(unsigned) const {
return ContainedTys[0];
}
static inline bool classof(const SequentialType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID ||
T->getTypeID() == PointerTyID ||
T->getTypeID() == VectorTyID;
}
};
class ArrayType : public SequentialType {
friend class TypeMap<ArrayValType, ArrayType>;
uint64_t NumElements;
ArrayType(const ArrayType &); const ArrayType &operator=(const ArrayType &); ArrayType(const Type *ElType, uint64_t NumEl);
public:
static ArrayType *get(const Type *ElementType, uint64_t NumElements);
static bool isValidElementType(const Type *ElemTy);
inline uint64_t getNumElements() const { return NumElements; }
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
static inline bool classof(const ArrayType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID;
}
};
class VectorType : public SequentialType {
friend class TypeMap<VectorValType, VectorType>;
unsigned NumElements;
VectorType(const VectorType &); const VectorType &operator=(const VectorType &); VectorType(const Type *ElType, unsigned NumEl);
public:
static VectorType *get(const Type *ElementType, unsigned NumElements);
static VectorType *getInteger(const VectorType *VTy) {
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits);
return VectorType::get(EltTy, VTy->getNumElements());
}
static VectorType *getExtendedElementVectorType(const VectorType *VTy) {
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2);
return VectorType::get(EltTy, VTy->getNumElements());
}
static VectorType *getTruncatedElementVectorType(const VectorType *VTy) {
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
assert((EltBits & 1) == 0 &&
"Cannot truncate vector element with odd bit-width");
const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2);
return VectorType::get(EltTy, VTy->getNumElements());
}
static bool isValidElementType(const Type *ElemTy);
inline unsigned getNumElements() const { return NumElements; }
inline unsigned getBitWidth() const {
return NumElements * getElementType()->getPrimitiveSizeInBits();
}
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
static inline bool classof(const VectorType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == VectorTyID;
}
};
class PointerType : public SequentialType {
friend class TypeMap<PointerValType, PointerType>;
unsigned AddressSpace;
PointerType(const PointerType &); const PointerType &operator=(const PointerType &); explicit PointerType(const Type *ElType, unsigned AddrSpace);
public:
static PointerType *get(const Type *ElementType, unsigned AddressSpace);
static PointerType *getUnqual(const Type *ElementType) {
return PointerType::get(ElementType, 0);
}
static bool isValidElementType(const Type *ElemTy);
inline unsigned getAddressSpace() const { return AddressSpace; }
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
static inline bool classof(const PointerType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == PointerTyID;
}
};
class OpaqueType : public DerivedType {
friend class LLVMContextImpl;
OpaqueType(const OpaqueType &); const OpaqueType &operator=(const OpaqueType &); OpaqueType(LLVMContext &C);
public:
static OpaqueType *get(LLVMContext &C);
static inline bool classof(const OpaqueType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == OpaqueTyID;
}
};
}
#endif