X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FType.h;h=5900b402dcc4931e278388d21bfd679a4fb4badf;hb=1c5164e9cff87b9682fcf620c7aac099ff378e18;hp=5854062df0c8a660435822736e57cdd33fa93b1e;hpb=3ff4387113d7e74a8aa73f80c3518cb95f09a64b;p=oota-llvm.git diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 5854062df0c..5900b402dcc 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -1,7 +1,7 @@ -//===-- llvm/Type.h - Classes for handling data types ------------*- C++ -*--=// +//===-- llvm/Type.h - Classes for handling data types -----------*- C++ -*-===// // // This file contains the declaration of the Type class. For more "Type" type -// stuff, look in DerivedTypes.h and Opt/ConstantHandling.h +// stuff, look in DerivedTypes.h. // // Note that instances of the Type class are immutable: once they are created, // they are never changed. Also note that only one instance of a particular @@ -27,23 +27,23 @@ #define LLVM_TYPE_H #include "llvm/Value.h" -#include "llvm/Support/GraphTraits.h" +#include "Support/GraphTraits.h" +#include "Support/iterator" class DerivedType; -class MethodType; +class FunctionType; class ArrayType; class PointerType; class StructType; class OpaqueType; -class Type : public Value { -public: - //===--------------------------------------------------------------------===// - // Definitions of all of the base types for the Type system. Based on this - // 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! - // +struct Type : public Value { + ///===-------------------------------------------------------------------===// + /// Definitions of all of the base types for the Type system. Based on this + /// 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! + /// enum PrimitiveID { VoidTyID = 0 , BoolTyID, // 0, 1: Basics... UByteTyID , SByteTyID, // 2, 3: 8 bit types... @@ -58,88 +58,139 @@ public: // Derived types... see DerivedTypes.h file... // Make sure FirstDerivedTyID stays up to date!!! - MethodTyID , StructTyID, // Methods... Structs... + FunctionTyID , StructTyID, // Functions... Structs... ArrayTyID , PointerTyID, // Array... pointer... OpaqueTyID, // Opaque type instances... //PackedTyID , // SIMD 'packed' format... TODO //... NumPrimitiveIDs, // Must remain as last defined ID - FirstDerivedTyID = MethodTyID, + FirstDerivedTyID = FunctionTyID, }; private: PrimitiveID ID; // The current base type of this type... unsigned UID; // The unique ID number for this class - string Desc; // The printed name of the string... bool Abstract; // True if type contains an OpaqueType - bool Recursive; // True if the type is recursive + const Type *getForwardedTypeInternal() const; protected: - // ctor is protected, so only subclasses can create Type objects... - Type(const string &Name, PrimitiveID id); + /// ctor is protected, so only subclasses can create Type objects... + Type(const std::string &Name, PrimitiveID id); virtual ~Type() {} - // When types are refined, they update their description to be more concrete. - // - inline void setDescription(const string &D) { Desc = D; } - - // setName - Associate the name with this type in the symbol table, but don't - // set the local name to be equal specified name. - // - virtual void setName(const string &Name, SymbolTable *ST = 0); + /// setName - Associate the name with this type in the symbol table, but don't + /// set the local name to be equal specified name. + /// + virtual void setName(const std::string &Name, SymbolTable *ST = 0); - // Types can become nonabstract later, if they are refined. - // + /// Types can become nonabstract later, if they are refined. + /// inline void setAbstract(bool Val) { Abstract = Val; } - // Types can become recursive later, if they are refined. - // - inline void setRecursive(bool Val) { Recursive = Val; } + /// isTypeAbstract - This method is used to calculate the Abstract bit. + /// + bool isTypeAbstract(); + + /// ForwardType - This field is used to implement the union find scheme for + /// abstract types. When types are refined to other types, this field is set + /// to the more refined type. Only abstract types can be forwarded. + mutable const Type *ForwardType; public: + virtual void print(std::ostream &O) const; //===--------------------------------------------------------------------===// - // Property accessors for dealing with types... + // Property accessors for dealing with types... Some of these virtual methods + // are defined in private classes defined in Type.cpp for primitive types. // - // getPrimitiveID - Return the base type of the type. This will return one - // of the PrimitiveID enum elements defined above. - // + /// getPrimitiveID - Return the base type of the type. This will return one + /// of the PrimitiveID enum elements defined above. + /// inline PrimitiveID getPrimitiveID() const { return ID; } - // getUniqueID - Returns the UID of the type. This can be thought of as a - // small integer version of the pointer to the type class. Two types that are - // structurally different have different UIDs. This can be used for indexing - // types into an array. - // + /// getUniqueID - Returns the UID of the type. This can be thought of as a + /// small integer version of the pointer to the type class. Two types that + /// are structurally different have different UIDs. This can be used for + /// indexing types into an array. + /// inline unsigned getUniqueID() const { return UID; } - // getDescription - Return the string representation of the type... - inline const string &getDescription() const { return Desc; } + /// getDescription - Return the string representation of the type... + const std::string &getDescription() const; - // isSigned - Return whether a numeric type is signed. + /// isSigned - Return whether an integral numeric type is signed. This is + /// true for SByteTy, ShortTy, IntTy, LongTy. Note that this is not true for + /// Float and Double. + // virtual bool isSigned() const { return 0; } - // isUnsigned - Return whether a numeric type is unsigned. This is not - // quite the complement of isSigned... nonnumeric types return false as they - // do with isSigned. - // + /// isUnsigned - Return whether a numeric type is unsigned. This is not quite + /// the complement of isSigned... nonnumeric types return false as they do + /// with isSigned. This returns true for UByteTy, UShortTy, UIntTy, and + /// ULongTy + /// virtual bool isUnsigned() const { return 0; } - // isIntegral - Equilivent to isSigned() || isUnsigned, but with only a single - // virtual function invocation. - // - virtual bool isIntegral() const { return 0; } + /// isInteger - Equilivent to isSigned() || isUnsigned(), but with only a + /// single virtual function invocation. + /// + virtual bool isInteger() const { return 0; } - // isAbstract - True if the type is either an Opaque type, or is a derived - // type that includes an opaque type somewhere in it. - // + /// isIntegral - Returns true if this is an integral type, which is either + /// BoolTy or one of the Integer types. + /// + bool isIntegral() const { return isInteger() || this == BoolTy; } + + /// isFloatingPoint - Return true if this is one of the two floating point + /// types + bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID; } + + /// isAbstract - True if the type is either an Opaque type, or is a derived + /// type that includes an opaque type somewhere in it. + /// inline bool isAbstract() const { return Abstract; } - // isRecursive - True if the type graph contains a cycle. - // - inline bool isRecursive() const { return Recursive; } + /// isLosslesslyConvertibleTo - Return true if this type can be converted to + /// 'Ty' without any reinterpretation of bits. For example, uint to int. + /// + bool isLosslesslyConvertibleTo(const Type *Ty) const; + + + /// Here are some useful little methods to query what type derived types are + /// Note that all other types can just compare to see if this == Type::xxxTy; + /// + inline bool isPrimitiveType() const { return ID < FirstDerivedTyID; } + inline bool isDerivedType() const { return ID >= FirstDerivedTyID; } + + /// isFirstClassType - Return true if the value is holdable in a register. + inline bool isFirstClassType() const { + return isPrimitiveType() || ID == PointerTyID; + } + + /// isSized - Return true if it makes sense to take the size of this type. To + /// get the actual size for a particular target, it is reasonable to use the + /// TargetData subsystem to do this. + /// + bool isSized() const { + return ID != VoidTyID && ID != TypeTyID && + ID != FunctionTyID && ID != LabelTyID && ID != OpaqueTyID; + } + + /// getPrimitiveSize - Return the basic size of this type if it is a primative + /// type. These are fixed by LLVM and are not target dependent. This will + /// return zero if the type does not have a size or is not a primitive type. + /// + unsigned getPrimitiveSize() const; + + /// getForwaredType - Return the type that this type has been resolved to if + /// it has been resolved to anything. This is used to implement the + /// union-find algorithm for type resolution. + const Type *getForwardedType() const { + if (!ForwardType) return 0; + return getForwardedTypeInternal(); + } //===--------------------------------------------------------------------===// // Type Iteration support @@ -149,15 +200,15 @@ public: inline subtype_iterator subtype_begin() const; // DEFINED BELOW inline subtype_iterator subtype_end() const; // DEFINED BELOW - // getContainedType - This method is used to implement the type iterator - // (defined a the end of the file). For derived types, this returns the types - // 'contained' in the derived type, returning 0 when 'i' becomes invalid. This - // allows the user to iterate over the types in a struct, for example, really - // easily. - // + /// getContainedType - This method is used to implement the type iterator + /// (defined a the end of the file). For derived types, this returns the + /// types 'contained' in the derived type, returning 0 when 'i' becomes + /// invalid. This allows the user to iterate over the types in a struct, for + /// example, really easily. + /// virtual const Type *getContainedType(unsigned i) const { return 0; } - // getNumContainedTypes - Return the number of types in the derived type + /// getNumContainedTypes - Return the number of types in the derived type virtual unsigned getNumContainedTypes() const { return 0; } //===--------------------------------------------------------------------===// @@ -165,7 +216,7 @@ public: // instances of Type. // - // getPrimitiveType/getUniqueIDType - Return a type based on an identifier. + /// getPrimitiveType/getUniqueIDType - Return a type based on an identifier. static const Type *getPrimitiveType(PrimitiveID IDNumber); static const Type *getUniqueIDType(unsigned UID); @@ -181,56 +232,16 @@ public: static Type *TypeTy , *LabelTy; - // Here are some useful little methods to query what type derived types are - // Note that all other types can just compare to see if this == Type::xxxTy; - // - inline bool isPrimitiveType() const { return ID < FirstDerivedTyID; } - - inline bool isDerivedType() const { return ID >= FirstDerivedTyID; } - inline const DerivedType *castDerivedType() const { - return isDerivedType() ? (const DerivedType*)this : 0; - } - inline const DerivedType *castDerivedTypeAsserting() const { - assert(isDerivedType()); - return (const DerivedType*)this; + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Type *T) { return true; } + static inline bool classof(const Value *V) { + return V->getValueType() == Value::TypeVal; } - // Methods for determining the subtype of this Type. The cast*() methods are - // equilivent to using dynamic_cast<>... if the cast is successful, this is - // returned, otherwise you get a null pointer, allowing expressions like this: - // - // if (MethodType *MTy = Ty->dyncastMethodType()) { ... } - // - // This section also defines a family of isArrayType(), isLabelType(), - // etc functions... - // - // The family of functions Ty->cast() is used in the same way as the - // Ty->dyncast() instructions, but they assert the expected type instead - // of checking it at runtime. - // -#define HANDLE_PRIM_TYPE(NAME, SIZE) \ - inline bool is##NAME##Type() const { return ID == NAME##TyID; } -#define HANDLE_DERV_TYPE(NAME, CLASS) \ - inline bool is##NAME##Type() const { return ID == NAME##TyID; } \ - inline const CLASS *dyncast##NAME##Type() const { /*const version */ \ - return is##NAME##Type() ? (const CLASS*)this : 0; \ - } \ - inline CLASS *dyncast##NAME##Type() { /* nonconst version */ \ - return is##NAME##Type() ? (CLASS*)this : 0; \ - } \ - inline const CLASS *cast##NAME##Type() const { /*const version */ \ - assert(is##NAME##Type() && "Expected TypeTy: " #NAME); \ - return (const CLASS*)this; \ - } \ - inline CLASS *cast##NAME##Type() { /* nonconst version */ \ - assert(is##NAME##Type() && "Expected TypeTy: " #NAME); \ - return (CLASS*)this; \ - } #include "llvm/Type.def" private: - class TypeIterator : public std::bidirectional_iterator { + class TypeIterator : public bidirectional_iterator { const Type * const Ty; unsigned Idx; @@ -295,4 +306,8 @@ template <> struct GraphTraits { } }; +template <> inline bool isa_impl(const Type &Ty) { + return Ty.getPrimitiveID() == Type::PointerTyID; +} + #endif