#define LLVM_TYPE_H
#include "llvm/AbstractTypeUser.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/System/Atomic.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/iterator.h"
#include <string>
#include <vector>
/// value, you can cast to a "DerivedType" subclass (see DerivedTypes.h)
/// Note: If you add an element to this, you need to add an element to the
/// Type::getPrimitiveType function, or else things will break!
+ /// Also update LLVMTypeKind and LLVMGetTypeKind () in the C binding.
///
enum TypeID {
// PrimitiveTypes .. make sure LastPrimitiveTyID stays up to date
/// has no AbstractTypeUsers, the type is deleted. This is only sensical for
/// derived types.
///
- mutable unsigned RefCount;
+ mutable sys::cas_flag RefCount;
+
+ /// Context - This refers to the LLVMContext in which this type was uniqued.
+ LLVMContext &Context;
+ friend class LLVMContextImpl;
const Type *getForwardedTypeInternal() const;
void destroy() const; // const is a lie, this does "delete this"!
protected:
- explicit Type(TypeID id) : ID(id), Abstract(false), SubclassData(0),
- RefCount(0), ForwardType(0), NumContainedTys(0),
+ explicit Type(LLVMContext &C, TypeID id) :
+ ID(id), Abstract(false), SubclassData(0),
+ RefCount(0), Context(C),
+ ForwardType(0), NumContainedTys(0),
ContainedTys(0) {}
virtual ~Type() {
assert(AbstractTypeUsers.empty() && "Abstract types remain");
public:
void print(raw_ostream &O) const;
- void print(std::ostream &O) const;
/// @brief Debugging support: print to stderr
void dump() const;
/// module).
void dump(const Module *Context) const;
+ /// getContext - Fetch the LLVMContext in which this type was uniqued.
+ LLVMContext &getContext() const { return Context; }
+
//===--------------------------------------------------------------------===//
// Property accessors for dealing with types... Some of these virtual methods
// are defined in private classes defined in Type.cpp for primitive types.
///
inline TypeID getTypeID() const { return ID; }
+ /// isVoidTy - Return true if this is 'void'.
+ bool isVoidTy() const { return ID == VoidTyID; }
+
+ /// isFloatTy - Return true if this is 'float', a 32-bit IEEE fp type.
+ bool isFloatTy() const { return ID == FloatTyID; }
+
+ /// isDoubleTy - Return true if this is 'double', a 64-bit IEEE fp type.
+ bool isDoubleTy() const { return ID == DoubleTyID; }
+
+ /// isX86_FP80Ty - Return true if this is x86 long double.
+ bool isX86_FP80Ty() const { return ID == X86_FP80TyID; }
+
+ /// isFP128Ty - Return true if this is 'fp128'.
+ bool isFP128Ty() const { return ID == FP128TyID; }
+
+ /// isPPC_FP128Ty - Return true if this is powerpc long double.
+ bool isPPC_FP128Ty() const { return ID == PPC_FP128TyID; }
+
+ /// isLabelTy - Return true if this is 'label'.
+ bool isLabelTy() const { return ID == LabelTyID; }
+
+ /// isMetadataTy - Return true if this is 'metadata'.
+ bool isMetadataTy() const { return ID == MetadataTyID; }
+
/// getDescription - Return the string representation of the type.
std::string getDescription() const;
///
bool isIntOrIntVector() const;
- /// isFloatingPoint - Return true if this is one of the two floating point
+ /// isFloatingPoint - Return true if this is one of the five floating point
/// types
bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID ||
ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; }
/// This will return zero if the type does not have a size or is not a
/// primitive type.
///
+ /// Note that this may not reflect the size of memory allocated for an
+ /// instance of the type or the number of bytes that are written when an
+ /// instance of the type is stored to memory. The TargetData class provides
+ /// additional query functions to provide this information.
+ ///
unsigned getPrimitiveSizeInBits() const;
-
+
+ /// getScalarSizeInBits - If this is a vector type, return the
+ /// getPrimitiveSizeInBits value for the element type. Otherwise return the
+ /// getPrimitiveSizeInBits value for this type.
+ unsigned getScalarSizeInBits() const;
+
/// getFPMantissaWidth - Return the width of the mantissa of this type. This
- /// is only valid on scalar floating point types. If the FP type does not
+ /// is only valid on floating point types. If the FP type does not
/// have a stable mantissa (e.g. ppc long double), this method returns -1.
- int getFPMantissaWidth() const {
- assert(isFloatingPoint() && "Not a floating point type!");
- if (ID == FloatTyID) return 24;
- if (ID == DoubleTyID) return 53;
- if (ID == X86_FP80TyID) return 64;
- if (ID == FP128TyID) return 113;
- assert(ID == PPC_FP128TyID && "unknown fp type");
- return -1;
- }
+ int getFPMantissaWidth() const;
/// getForwardedType - Return the type that this type has been resolved to if
/// it has been resolved to anything. This is used to implement the
/// getVAArgsPromotedType - Return the type an argument of this type
/// will be promoted to if passed through a variable argument
/// function.
- const Type *getVAArgsPromotedType() const;
+ const Type *getVAArgsPromotedType(LLVMContext &C) const;
+
+ /// getScalarType - If this is a vector type, return the element type,
+ /// otherwise return this.
+ const Type *getScalarType() const;
//===--------------------------------------------------------------------===//
// Type Iteration support
//
/// getPrimitiveType - Return a type based on an identifier.
- static const Type *getPrimitiveType(TypeID IDNumber);
+ static const Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber);
//===--------------------------------------------------------------------===//
// These are the builtin types that are always available...
//
- static const Type *VoidTy, *LabelTy, *FloatTy, *DoubleTy, *MetadataTy;
- static const Type *X86_FP80Ty, *FP128Ty, *PPC_FP128Ty;
- static const IntegerType *Int1Ty, *Int8Ty, *Int16Ty, *Int32Ty, *Int64Ty;
+ static const Type *getVoidTy(LLVMContext &C);
+ static const Type *getLabelTy(LLVMContext &C);
+ static const Type *getFloatTy(LLVMContext &C);
+ static const Type *getDoubleTy(LLVMContext &C);
+ static const Type *getMetadataTy(LLVMContext &C);
+ static const Type *getX86_FP80Ty(LLVMContext &C);
+ static const Type *getFP128Ty(LLVMContext &C);
+ static const Type *getPPC_FP128Ty(LLVMContext &C);
+ static const IntegerType *getInt1Ty(LLVMContext &C);
+ static const IntegerType *getInt8Ty(LLVMContext &C);
+ static const IntegerType *getInt16Ty(LLVMContext &C);
+ static const IntegerType *getInt32Ty(LLVMContext &C);
+ static const IntegerType *getInt64Ty(LLVMContext &C);
+
+ //===--------------------------------------------------------------------===//
+ // Convenience methods for getting pointer types with one of the above builtin
+ // types as pointee.
+ //
+ static const PointerType *getFloatPtrTy(LLVMContext &C, unsigned AS = 0);
+ static const PointerType *getDoublePtrTy(LLVMContext &C, unsigned AS = 0);
+ static const PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0);
+ static const PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0);
+ static const PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0);
+ static const PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0);
+ static const PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0);
+ static const PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0);
+ static const PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0);
+ static const PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Type *) { return true; }
void addRef() const {
assert(isAbstract() && "Cannot add a reference to a non-abstract type!");
- ++RefCount;
+ sys::AtomicIncrement(&RefCount);
}
void dropRef() const {
// If this is the last PATypeHolder using this object, and there are no
// PATypeHandles using it, the type is dead, delete it now.
- if (--RefCount == 0 && AbstractTypeUsers.empty())
+ sys::cas_flag OldCount = sys::AtomicDecrement(&RefCount);
+ if (OldCount == 0 && AbstractTypeUsers.empty())
this->destroy();
}
/// addAbstractTypeUser - Notify an abstract type that there is a new user of
/// it. This function is called primarily by the PATypeHandle class.
///
- void addAbstractTypeUser(AbstractTypeUser *U) const {
- assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
- AbstractTypeUsers.push_back(U);
- }
+ void addAbstractTypeUser(AbstractTypeUser *U) const;
/// removeAbstractTypeUser - Notify an abstract type that a user of the class
/// no longer has a handle to the type. This function is called primarily by
/// getPointerTo - Return a pointer to the current type. This is equivalent
/// to PointerType::get(Foo, AddrSpace).
- PointerType *getPointerTo(unsigned AddrSpace = 0) const;
+ const PointerType *getPointerTo(unsigned AddrSpace = 0) const;
private:
/// isSizedDerivedType - Derived types like structures and arrays are sized
return Ty.getTypeID() == Type::PointerTyID;
}
-std::ostream &operator<<(std::ostream &OS, const Type &T);
raw_ostream &operator<<(raw_ostream &OS, const Type &T);
} // End llvm namespace