#include "llvm/Type.h"
class DerivedType : public Type {
+ char isRefining; // Used for recursive types
+
// AbstractTypeUsers - Implement a list of the users that need to be notified
// if I am a type, and I get resolved into a more concrete type.
//
///// FIXME: kill mutable nonsense when Type's are not const
- mutable vector<AbstractTypeUser *> AbstractTypeUsers;
-
- char isRefining; // Used for recursive types
+ mutable std::vector<AbstractTypeUser *> AbstractTypeUsers;
protected:
- inline DerivedType(const string &Name, PrimitiveID id) : Type(Name, id) {
- isRefining = false;
+ inline DerivedType(PrimitiveID id) : Type("", id) {
+ isRefining = 0;
+ }
+ ~DerivedType() {
+ assert(AbstractTypeUsers.empty());
}
// typeIsRefined - Notify AbstractTypeUsers of this type that the current type
// 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!");
-#if 0
- cerr << " addAbstractTypeUser[" << (void*)this << ", " << getDescription()
- << "][" << AbstractTypeUsers.size() << "] User = " << U << endl;
-#endif
- 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
//
void removeAbstractTypeUser(AbstractTypeUser *U) const;
- // getNumAbstractTypeUsers - Return the number of users registered to the type
- inline unsigned getNumAbstractTypeUsers() const {
- assert(isAbstract() && "getNumAbstractTypeUsers: Type not abstract!");
- return AbstractTypeUsers.size();
- }
-
// refineAbstractTypeTo - This function is used to when it is discovered that
// the 'this' abstract type is actually equivalent to the NewType specified.
// This causes all users of 'this' to switch to reference the more concrete
return T->isDerivedType();
}
static inline bool classof(const Value *V) {
- return isa<Type>(V) && classof(cast<const Type>(V));
+ return isa<Type>(V) && classof(cast<Type>(V));
}
};
-class MethodType : public DerivedType {
+class FunctionType : public DerivedType {
public:
- typedef vector<PATypeHandle<Type> > ParamTypes;
+ typedef std::vector<PATypeHandle> ParamTypes;
private:
- PATypeHandle<Type> ResultType;
+ PATypeHandle ResultType;
ParamTypes ParamTys;
bool isVarArgs;
- MethodType(const MethodType &); // Do not implement
- const MethodType &operator=(const MethodType &); // Do not implement
+ FunctionType(const FunctionType &); // Do not implement
+ const FunctionType &operator=(const FunctionType &); // Do not implement
protected:
// This should really be private, but it squelches a bogus warning
- // from GCC to make them protected: warning: `class MethodType' only
+ // from GCC to make them protected: warning: `class FunctionType' only
// defines private constructors and has no friends
// Private ctor - Only can be created by a static member...
- MethodType(const Type *Result, const vector<const Type*> &Params,
- bool IsVarArgs);
+ FunctionType(const Type *Result, const std::vector<const Type*> &Params,
+ bool IsVarArgs);
public:
inline const Type *getReturnType() const { return ResultType; }
inline const ParamTypes &getParamTypes() const { return ParamTys; }
+ // Parameter type accessors...
+ const Type *getParamType(unsigned i) const { return ParamTys[i]; }
+
+ // getNumParams - Return the number of fixed parameters this function type
+ // requires. This does not consider varargs.
+ //
+ unsigned getNumParams() const { return ParamTys.size(); }
+
virtual const Type *getContainedType(unsigned i) const {
return i == 0 ? ResultType :
//
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
- static MethodType *get(const Type *Result, const vector<const Type*> &Params,
- bool isVarArg);
+ static FunctionType *get(const Type *Result,
+ const std::vector<const Type*> &Params,
+ bool isVarArg);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const MethodType *T) { return true; }
+ static inline bool classof(const FunctionType *T) { return true; }
static inline bool classof(const Type *T) {
- return T->getPrimitiveID() == MethodTyID;
+ return T->getPrimitiveID() == FunctionTyID;
}
static inline bool classof(const Value *V) {
- return isa<Type>(V) && classof(cast<const Type>(V));
+ return isa<Type>(V) && classof(cast<Type>(V));
}
};
-// CompositeType - Common super class of ArrayType and StructType...
+// CompositeType - Common super class of ArrayType, StructType, and PointerType
//
class CompositeType : public DerivedType {
protected:
- inline CompositeType(const string &Name, PrimitiveID id)
- : DerivedType(Name, id) { }
+ inline CompositeType(PrimitiveID id) : DerivedType(id) { }
public:
static inline bool classof(const CompositeType *T) { return true; }
static inline bool classof(const Type *T) {
return T->getPrimitiveID() == ArrayTyID ||
- T->getPrimitiveID() == StructTyID;
+ T->getPrimitiveID() == StructTyID ||
+ T->getPrimitiveID() == PointerTyID;
}
static inline bool classof(const Value *V) {
- return isa<Type>(V) && classof(cast<const Type>(V));
+ return isa<Type>(V) && classof(cast<Type>(V));
}
};
-class ArrayType : public CompositeType {
+class StructType : public CompositeType {
+public:
+ typedef std::vector<PATypeHandle> ElementTypes;
+
private:
- PATypeHandle<Type> ElementType;
- int NumElements; // >= 0 for sized array, -1 for unbounded/unknown array
+ ElementTypes ETypes; // Element types of struct
+
+ StructType(const StructType &); // Do not implement
+ const StructType &operator=(const StructType &); // Do not implement
- ArrayType(const ArrayType &); // Do not implement
- const ArrayType &operator=(const ArrayType &); // Do not implement
protected:
// This should really be private, but it squelches a bogus warning
- // from GCC to make them protected: warning: `class ArrayType' only
+ // from GCC to make them protected: warning: `class StructType' only
// defines private constructors and has no friends
-
// Private ctor - Only can be created by a static member...
- ArrayType(const Type *ElType, int NumEl);
+ StructType(const std::vector<const Type*> &Types);
+
public:
-
- inline const Type *getElementType() const { return ElementType; }
- inline int getNumElements() const { return NumElements; }
-
- inline bool isSized() const { return NumElements >= 0; }
- inline bool isUnsized() const { return NumElements == -1; }
+ inline const ElementTypes &getElementTypes() const { return ETypes; }
virtual const Type *getContainedType(unsigned i) const {
- return i == 0 ? ElementType.get() : 0;
+ return i < ETypes.size() ? ETypes[i].get() : 0;
}
- virtual unsigned getNumContainedTypes() const { return 1; }
+ virtual unsigned getNumContainedTypes() const { return ETypes.size(); }
// getTypeAtIndex - Given an index value into the type, return the type of the
- // element. For an arraytype, there is only one subtype...
+ // element. For a structure type, this must be a constant value...
//
- virtual const Type *getTypeAtIndex(const Value *V) const {
- return ElementType.get();
- }
- virtual bool indexValid(const Value *V) const {
- return V->getType() == Type::UIntTy; // Must be an unsigned int index
- }
+ virtual const Type *getTypeAtIndex(const Value *V) const ;
+ virtual bool indexValid(const Value *V) const;
// getIndexType - Return the type required of indices for this composite.
// For structures, this is ubyte, for arrays, this is uint
//
- virtual const Type *getIndexType() const { return Type::UIntTy; }
+ virtual const Type *getIndexType() const { return Type::UByteTy; }
// refineAbstractType - Called when a contained type is found to be more
// concrete - this could potentially change us from an abstract type to a
//
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
- static ArrayType *get(const Type *ElementType, int NumElements = -1);
+ static StructType *get(const std::vector<const Type*> &Params);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ArrayType *T) { return true; }
+ static inline bool classof(const StructType *T) { return true; }
static inline bool classof(const Type *T) {
- return T->getPrimitiveID() == ArrayTyID;
+ return T->getPrimitiveID() == StructTyID;
}
static inline bool classof(const Value *V) {
- return isa<Type>(V) && classof(cast<const Type>(V));
+ return isa<Type>(V) && classof(cast<Type>(V));
}
};
-class StructType : public CompositeType {
-public:
- typedef vector<PATypeHandle<Type> > ElementTypes;
-
-private:
- ElementTypes ETypes; // Element types of struct
-
- StructType(const StructType &); // Do not implement
- const StructType &operator=(const StructType &); // Do not implement
-
+// SequentialType - This is the superclass of the array and pointer type
+// classes. Both of these represent "arrays" in memory. The array type
+// represents a specifically sized array, pointer types are unsized/unknown size
+// arrays. SequentialType holds the common features of both, which stem from
+// the fact that both lay their components out in memory identically.
+//
+class SequentialType : public CompositeType {
+ SequentialType(const SequentialType &); // Do not implement!
+ const SequentialType &operator=(const SequentialType &); // Do not implement!
protected:
- // This should really be private, but it squelches a bogus warning
- // from GCC to make them protected: warning: `class StructType' only
- // defines private constructors and has no friends
+ PATypeHandle ElementType;
- // Private ctor - Only can be created by a static member...
- StructType(const vector<const Type*> &Types);
-
+ SequentialType(PrimitiveID TID, const Type *ElType)
+ : CompositeType(TID), ElementType(PATypeHandle(ElType, this)) {
+ }
public:
- inline const ElementTypes &getElementTypes() const { return ETypes; }
+
+ inline const Type *getElementType() const { return ElementType; }
virtual const Type *getContainedType(unsigned i) const {
- return i < ETypes.size() ? ETypes[i].get() : 0;
+ return i == 0 ? ElementType.get() : 0;
}
- virtual unsigned getNumContainedTypes() const { return ETypes.size(); }
+ virtual unsigned getNumContainedTypes() const { return 1; }
// getTypeAtIndex - Given an index value into the type, return the type of the
- // element. For a structure type, this must be a constant value...
+ // element. For sequential types, there is only one subtype...
//
- virtual const Type *getTypeAtIndex(const Value *V) const ;
- virtual bool indexValid(const Value *V) const;
+ virtual const Type *getTypeAtIndex(const Value *V) const {
+ return ElementType.get();
+ }
+ virtual bool indexValid(const Value *V) const {
+ return V->getType() == Type::LongTy; // Must be a 'long' index
+ }
- // getIndexType - Return the type required of indices for this composite.
+ // getIndexType() - Return the type required of indices for this composite.
// For structures, this is ubyte, for arrays, this is uint
//
- virtual const Type *getIndexType() const { return Type::UByteTy; }
+ virtual const Type *getIndexType() const { return Type::LongTy; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SequentialType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getPrimitiveID() == ArrayTyID ||
+ T->getPrimitiveID() == PointerTyID;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Type>(V) && classof(cast<Type>(V));
+ }
+};
+
+
+class ArrayType : public SequentialType {
+ unsigned NumElements;
+
+ ArrayType(const ArrayType &); // Do not implement
+ const ArrayType &operator=(const ArrayType &); // Do not implement
+protected:
+ // This should really be private, but it squelches a bogus warning
+ // from GCC to make them protected: warning: `class ArrayType' only
+ // defines private constructors and has no friends
+
+
+ // Private ctor - Only can be created by a static member...
+ ArrayType(const Type *ElType, unsigned NumEl);
+public:
+ inline unsigned getNumElements() const { return NumElements; }
// refineAbstractType - Called when a contained type is found to be more
// concrete - this could potentially change us from an abstract type to a
//
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
- static StructType *get(const vector<const Type*> &Params);
+ static ArrayType *get(const Type *ElementType, unsigned NumElements);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const StructType *T) { return true; }
+ static inline bool classof(const ArrayType *T) { return true; }
static inline bool classof(const Type *T) {
- return T->getPrimitiveID() == StructTyID;
+ return T->getPrimitiveID() == ArrayTyID;
}
static inline bool classof(const Value *V) {
- return isa<Type>(V) && classof(cast<const Type>(V));
+ return isa<Type>(V) && classof(cast<Type>(V));
}
};
-class PointerType : public DerivedType {
-private:
- PATypeHandle<Type> ValueType;
+class PointerType : public SequentialType {
PointerType(const PointerType &); // Do not implement
const PointerType &operator=(const PointerType &); // Do not implement
protected:
// Private ctor - Only can be created by a static member...
PointerType(const Type *ElType);
public:
-
- inline const Type *getElementType() const { return ValueType; }
-
- virtual const Type *getContainedType(unsigned i) const {
- return i == 0 ? ValueType.get() : 0;
- }
- virtual unsigned getNumContainedTypes() const { return 1; }
-
+ // PointerType::get - Named constructor for pointer types...
static PointerType *get(const Type *ElementType);
// refineAbstractType - Called when a contained type is found to be more
return T->getPrimitiveID() == PointerTyID;
}
static inline bool classof(const Value *V) {
- return isa<Type>(V) && classof(cast<const Type>(V));
+ return isa<Type>(V) && classof(cast<Type>(V));
}
};
return T->getPrimitiveID() == OpaqueTyID;
}
static inline bool classof(const Value *V) {
- return isa<Type>(V) && classof(cast<const Type>(V));
+ return isa<Type>(V) && classof(cast<Type>(V));
}
};
// contains an AbstractTypeUser instance, so there is no good way to factor out
// the code. Hence this bit of uglyness.
//
-template <class TypeSubClass> void PATypeHandle<TypeSubClass>::addUser() {
+inline void PATypeHandle::addUser() {
+ assert(Ty && "Type Handle has a null type!");
if (Ty->isAbstract())
cast<DerivedType>(Ty)->addAbstractTypeUser(User);
}
-template <class TypeSubClass> void PATypeHandle<TypeSubClass>::removeUser() {
+inline void PATypeHandle::removeUser() {
if (Ty->isAbstract())
cast<DerivedType>(Ty)->removeAbstractTypeUser(User);
}
-template <class TypeSubClass>
-void PATypeHandle<TypeSubClass>::removeUserFromConcrete() {
+inline void PATypeHandle::removeUserFromConcrete() {
if (!Ty->isAbstract())
cast<DerivedType>(Ty)->removeAbstractTypeUser(User);
}