From 2cac6d2ef4c0147958fcadb958a5fe8f4e1bf7d2 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 7 Sep 2001 16:19:29 +0000 Subject: [PATCH] * Add new DerivedType base class that goes between Type and the derived types * Implement abstract types * Add new Opaque derived type git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@420 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DerivedTypes.h | 197 ++++++++++++++++++++++++++++++------ 1 file changed, 168 insertions(+), 29 deletions(-) diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index eae4b7357e6..e024ed3edc4 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -14,13 +14,81 @@ #include "llvm/Type.h" #include -// Future derived types: SIMD packed format +class DerivedType : public Type { + // 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 AbstractTypeUsers; + + char isRefining; // Used for recursive types + +protected: + inline DerivedType(const string &Name, PrimitiveID id) : Type(Name, id) { + isRefining = false; + } + + // typeIsRefined - Notify AbstractTypeUsers of this type that the current type + // has been refined a bit. The pointer is still valid and still should be + // used, but the subtypes have changed. + // + void typeIsRefined(); + + // setDerivedTypeProperties - Based on the subtypes, set the name of this + // type so that it is printed nicely by the type printer. Also calculate + // whether this type is abstract or not. Used by the constructor and when + // the type is refined. + // + void setDerivedTypeProperties(); -class MethodType : public Type { public: - typedef vector ParamTypes; + + //===--------------------------------------------------------------------===// + // Abstract Type handling methods - These types have special lifetimes, which + // are managed by (add|remove)AbstractTypeUser. See comments in + // AbstractTypeUser.h for more information. + + // 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); + } + + // 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 + // the PATypeHandle class. When there are no users of the abstract type, it + // is anihilated, because there is no way to get a reference to it ever again. + // + 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 + // type NewType and for 'this' to be deleted. + // + void refineAbstractTypeTo(const Type *NewType); +}; + + + + +class MethodType : public DerivedType { +public: + typedef vector > ParamTypes; private: - const Type *ResultType; + PATypeHandle ResultType; ParamTypes ParamTys; bool isVarArgs; @@ -33,24 +101,33 @@ protected: // Private ctor - Only can be created by a static member... MethodType(const Type *Result, const vector &Params, - bool IsVarArgs, const string &Name); + bool IsVarArgs); + public: inline bool isVarArg() const { return isVarArgs; } inline const Type *getReturnType() const { return ResultType; } inline const ParamTypes &getParamTypes() const { return ParamTys; } - static const MethodType *getMethodType(const Type *Result, - const ParamTypes &Params); - static const MethodType *get(const Type *Result, const ParamTypes &Params) { - return getMethodType(Result, Params); + + virtual const Type *getContainedType(unsigned i) const { + return i == 0 ? ResultType : (i <= ParamTys.size() ? ParamTys[i-1] : 0); } + virtual unsigned getNumContainedTypes() const { return ParamTys.size()+1; } + + // refineAbstractType - Called when a contained type is found to be more + // concrete - this could potentially change us from an abstract type to a + // concrete type. + // + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + + static MethodType *get(const Type *Result, const vector &Params); }; -class ArrayType : public Type { +class ArrayType : public DerivedType { private: - const Type *ElementType; + PATypeHandle ElementType; int NumElements; // >= 0 for sized array, -1 for unbounded/unknown array ArrayType(const ArrayType &); // Do not implement @@ -62,7 +139,8 @@ protected: // Private ctor - Only can be created by a static member... - ArrayType(const Type *ElType, int NumEl, const string &Name); + ArrayType(const Type *ElType, int NumEl); + public: inline const Type *getElementType() const { return ElementType; } @@ -71,44 +149,60 @@ public: inline bool isSized() const { return NumElements >= 0; } inline bool isUnsized() const { return NumElements == -1; } - static const ArrayType *getArrayType(const Type *ElementType, - int NumElements = -1); - static const ArrayType *get(const Type *ElementType, int NumElements = -1) { - return getArrayType(ElementType, NumElements); + virtual const Type *getContainedType(unsigned i) const { + return i == 0 ? ElementType : 0; } + virtual unsigned getNumContainedTypes() const { return 1; } + + // refineAbstractType - Called when a contained type is found to be more + // concrete - this could potentially change us from an abstract type to a + // concrete type. + // + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + + static ArrayType *get(const Type *ElementType, int NumElements = -1); }; -class StructType : public Type { +class StructType : public DerivedType { public: - typedef vector ElementTypes; + typedef vector > ElementTypes; private: - ElementTypes ETypes; + ElementTypes ETypes; // Element types of struct StructType(const StructType &); // Do not implement const StructType &operator=(const StructType &); // 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 // Private ctor - Only can be created by a static member... - StructType(const vector &Types, const string &Name); + StructType(const vector &Types); public: inline const ElementTypes &getElementTypes() const { return ETypes; } - static const StructType *getStructType(const ElementTypes &Params); - static const StructType *get(const ElementTypes &Params) { - return getStructType(Params); + + virtual const Type *getContainedType(unsigned i) const { + return i < ETypes.size() ? ETypes[i] : 0; } + virtual unsigned getNumContainedTypes() const { return ETypes.size(); } + + // refineAbstractType - Called when a contained type is found to be more + // concrete - this could potentially change us from an abstract type to a + // concrete type. + // + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + + static StructType *get(const vector &Params); }; -class PointerType : public Type { +class PointerType : public DerivedType { private: - const Type *ValueType; + PATypeHandle ValueType; PointerType(const PointerType &); // Do not implement const PointerType &operator=(const PointerType &); // Do not implement @@ -120,15 +214,60 @@ protected: // Private ctor - Only can be created by a static member... PointerType(const Type *ElType); + public: inline const Type *getValueType() const { return ValueType; } + virtual const Type *getContainedType(unsigned i) const { + return i == 0 ? ValueType : 0; + } + virtual unsigned getNumContainedTypes() const { return 1; } - static const PointerType *getPointerType(const Type *ElementType); - static const PointerType *get(const Type *ElementType) { - return getPointerType(ElementType); + static PointerType *get(const Type *ElementType); + + // refineAbstractType - Called when a contained type is found to be more + // concrete - this could potentially change us from an abstract type to a + // concrete type. + // + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); +}; + + +class OpaqueType : public DerivedType { +private: + OpaqueType(const OpaqueType &); // Do not implement + const OpaqueType &operator=(const OpaqueType &); // Do not implement +protected: + // This should really be private, but it squelches a bogus warning + // from GCC to make them protected: warning: `class OpaqueType' only + // defines private constructors and has no friends + + // Private ctor - Only can be created by a static member... + OpaqueType(); + +public: + + // get - Static factory method for the OpaqueType class... + static OpaqueType *get() { + return new OpaqueType(); // All opaque types are distinct } }; + +// Define some inline methods for the AbstractTypeUser.h:PATypeHandle class. +// These are defined here because they MUST be inlined, yet are dependant on +// the definition of the Type class. Of course Type derives from Value, which +// contains an AbstractTypeUser instance, so there is no good way to factor out +// the code. Hence this bit of uglyness. +// +template void PATypeHandle::addUser() { + if (Ty->isAbstract()) + Ty->castDerivedTypeAsserting()->addAbstractTypeUser(User); +} +template void PATypeHandle::removeUser() { + if (Ty->isAbstract()) + Ty->castDerivedTypeAsserting()->removeAbstractTypeUser(User); +} + #endif