LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Type.h

Go to the documentation of this file.
00001 //===-- llvm/Type.h - Classes for handling data types -----------*- C++ -*-===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the declaration of the Type class.  For more "Type" type
00011 // stuff, look in DerivedTypes.h.
00012 //
00013 // Note that instances of the Type class are immutable: once they are created,
00014 // they are never changed.  Also note that only one instance of a particular 
00015 // type is ever created.  Thus seeing if two types are equal is a matter of 
00016 // doing a trivial pointer comparison.
00017 //
00018 // Types, once allocated, are never free'd, unless they are an abstract type
00019 // that is resolved to a more concrete type.
00020 //
00021 // Opaque types are simple derived types with no state.  There may be many
00022 // different Opaque type objects floating around, but two are only considered
00023 // identical if they are pointer equals of each other.  This allows us to have 
00024 // two opaque types that end up resolving to different concrete types later.
00025 //
00026 // Opaque types are also kinda wierd and scary and different because they have
00027 // to keep a list of uses of the type.  When, through linking, parsing, or
00028 // bytecode reading, they become resolved, they need to find and update all
00029 // users of the unknown type, causing them to reference a new, more concrete
00030 // type.  Opaque types are deleted when their use list dwindles to zero users.
00031 //
00032 //===----------------------------------------------------------------------===//
00033 
00034 #ifndef LLVM_TYPE_H
00035 #define LLVM_TYPE_H
00036 
00037 #include "AbstractTypeUser.h"
00038 #include "llvm/Support/Casting.h"
00039 #include "llvm/ADT/GraphTraits.h"
00040 #include "llvm/ADT/iterator"
00041 #include <vector>
00042 
00043 namespace llvm {
00044 
00045 class ArrayType;
00046 class DerivedType;
00047 class FunctionType;
00048 class OpaqueType;
00049 class PointerType;
00050 class StructType;
00051 class PackedType;
00052 
00053 class Type {
00054 public:
00055   ///===-------------------------------------------------------------------===//
00056   /// Definitions of all of the base types for the Type system.  Based on this
00057   /// value, you can cast to a "DerivedType" subclass (see DerivedTypes.h)
00058   /// Note: If you add an element to this, you need to add an element to the 
00059   /// Type::getPrimitiveType function, or else things will break!
00060   ///
00061   enum TypeID {
00062     // PrimitiveTypes .. make sure LastPrimitiveTyID stays up to date
00063     VoidTyID = 0  , BoolTyID,           //  0, 1: Basics...
00064     UByteTyID     , SByteTyID,          //  2, 3: 8 bit types...
00065     UShortTyID    , ShortTyID,          //  4, 5: 16 bit types...
00066     UIntTyID      , IntTyID,            //  6, 7: 32 bit types...
00067     ULongTyID     , LongTyID,           //  8, 9: 64 bit types...
00068     FloatTyID     , DoubleTyID,         // 10,11: Floating point types...
00069     LabelTyID     ,                     // 12   : Labels... 
00070 
00071     // Derived types... see DerivedTypes.h file...
00072     // Make sure FirstDerivedTyID stays up to date!!!
00073     FunctionTyID  , StructTyID,         // Functions... Structs...
00074     ArrayTyID     , PointerTyID,        // Array... pointer...
00075     OpaqueTyID,                         // Opaque type instances...
00076     PackedTyID,                         // SIMD 'packed' format... 
00077     //...
00078 
00079     NumTypeIDs,                         // Must remain as last defined ID
00080     LastPrimitiveTyID = LabelTyID,
00081     FirstDerivedTyID = FunctionTyID,
00082   };
00083 
00084 private:
00085   TypeID   ID : 8;    // The current base type of this type.
00086   bool     Abstract;  // True if type contains an OpaqueType
00087 
00088   /// RefCount - This counts the number of PATypeHolders that are pointing to
00089   /// this type.  When this number falls to zero, if the type is abstract and
00090   /// has no AbstractTypeUsers, the type is deleted.  This is only sensical for
00091   /// derived types.
00092   ///
00093   mutable unsigned RefCount;
00094 
00095   const Type *getForwardedTypeInternal() const;
00096 protected:
00097   Type(const std::string& Name, TypeID id);
00098   virtual ~Type() {}
00099 
00100   /// Types can become nonabstract later, if they are refined.
00101   ///
00102   inline void setAbstract(bool Val) { Abstract = Val; }
00103 
00104   // PromoteAbstractToConcrete - This is an internal method used to calculate
00105   // change "Abstract" from true to false when types are refined.
00106   void PromoteAbstractToConcrete();
00107 
00108   unsigned getRefCount() const { return RefCount; }
00109 
00110   /// ForwardType - This field is used to implement the union find scheme for
00111   /// abstract types.  When types are refined to other types, this field is set
00112   /// to the more refined type.  Only abstract types can be forwarded.
00113   mutable const Type *ForwardType;
00114 
00115   /// ContainedTys - The list of types contained by this one.  For example, this
00116   /// includes the arguments of a function type, the elements of the structure,
00117   /// the pointee of a pointer, etc.  Note that keeping this vector in the Type
00118   /// class wastes some space for types that do not contain anything (such as
00119   /// primitive types).  However, keeping it here allows the subtype_* members
00120   /// to be implemented MUCH more efficiently, and dynamically very few types do
00121   /// not contain any elements (most are derived).
00122   std::vector<PATypeHandle> ContainedTys;
00123 
00124 public:
00125   virtual void print(std::ostream &O) const;
00126 
00127   /// @brief Debugging support: print to stderr
00128   virtual void dump() const;
00129 
00130   //===--------------------------------------------------------------------===//
00131   // Property accessors for dealing with types... Some of these virtual methods
00132   // are defined in private classes defined in Type.cpp for primitive types.
00133   //
00134 
00135   /// getTypeID - Return the type id for the type.  This will return one
00136   /// of the TypeID enum elements defined above.
00137   ///
00138   inline TypeID getTypeID() const { return ID; }
00139 
00140   /// getDescription - Return the string representation of the type...
00141   const std::string &getDescription() const;
00142 
00143   /// isSigned - Return whether an integral numeric type is signed.  This is
00144   /// true for SByteTy, ShortTy, IntTy, LongTy.  Note that this is not true for
00145   /// Float and Double.
00146   ///
00147   bool isSigned() const {
00148     return ID == SByteTyID || ID == ShortTyID || 
00149            ID == IntTyID || ID == LongTyID; 
00150   }
00151   
00152   /// isUnsigned - Return whether a numeric type is unsigned.  This is not quite
00153   /// the complement of isSigned... nonnumeric types return false as they do
00154   /// with isSigned.  This returns true for UByteTy, UShortTy, UIntTy, and
00155   /// ULongTy
00156   /// 
00157   bool isUnsigned() const {
00158     return ID == UByteTyID || ID == UShortTyID || 
00159            ID == UIntTyID || ID == ULongTyID; 
00160   }
00161 
00162   /// isInteger - Equivalent to isSigned() || isUnsigned()
00163   ///
00164   bool isInteger() const { return ID >= UByteTyID && ID <= LongTyID; }
00165 
00166   /// isIntegral - Returns true if this is an integral type, which is either
00167   /// BoolTy or one of the Integer types.
00168   ///
00169   bool isIntegral() const { return isInteger() || this == BoolTy; }
00170 
00171   /// isFloatingPoint - Return true if this is one of the two floating point
00172   /// types
00173   bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID; }
00174 
00175   /// isAbstract - True if the type is either an Opaque type, or is a derived
00176   /// type that includes an opaque type somewhere in it.  
00177   ///
00178   inline bool isAbstract() const { return Abstract; }
00179 
00180   /// isLosslesslyConvertibleTo - Return true if this type can be converted to
00181   /// 'Ty' without any reinterpretation of bits.  For example, uint to int.
00182   ///
00183   bool isLosslesslyConvertibleTo(const Type *Ty) const;
00184 
00185 
00186   /// Here are some useful little methods to query what type derived types are
00187   /// Note that all other types can just compare to see if this == Type::xxxTy;
00188   ///
00189   inline bool isPrimitiveType() const { return ID <= LastPrimitiveTyID; }
00190   inline bool isDerivedType()   const { return ID >= FirstDerivedTyID; }
00191 
00192   /// isFirstClassType - Return true if the value is holdable in a register.
00193   ///
00194   inline bool isFirstClassType() const {
00195     return (ID != VoidTyID && ID <= LastPrimitiveTyID) || 
00196             ID == PointerTyID || ID == PackedTyID;
00197   }
00198 
00199   /// isSized - Return true if it makes sense to take the size of this type.  To
00200   /// get the actual size for a particular target, it is reasonable to use the
00201   /// TargetData subsystem to do this.
00202   ///
00203   bool isSized() const {
00204     return (ID >= BoolTyID && ID <= DoubleTyID) || ID == PointerTyID || 
00205            isSizedDerivedType();
00206   }
00207 
00208   /// getPrimitiveSize - Return the basic size of this type if it is a primitive
00209   /// type.  These are fixed by LLVM and are not target dependent.  This will
00210   /// return zero if the type does not have a size or is not a primitive type.
00211   ///
00212   unsigned getPrimitiveSize() const;
00213 
00214   /// getUnsignedVersion - If this is an integer type, return the unsigned
00215   /// variant of this type.  For example int -> uint.
00216   const Type *getUnsignedVersion() const;
00217 
00218   /// getSignedVersion - If this is an integer type, return the signed variant
00219   /// of this type.  For example uint -> int.
00220   const Type *getSignedVersion() const;
00221 
00222   /// getForwaredType - Return the type that this type has been resolved to if
00223   /// it has been resolved to anything.  This is used to implement the
00224   /// union-find algorithm for type resolution, and shouldn't be used by general
00225   /// purpose clients.
00226   const Type *getForwardedType() const {
00227     if (!ForwardType) return 0;
00228     return getForwardedTypeInternal();
00229   }
00230 
00231   //===--------------------------------------------------------------------===//
00232   // Type Iteration support
00233   //
00234   typedef std::vector<PATypeHandle>::const_iterator subtype_iterator;
00235   subtype_iterator subtype_begin() const { return ContainedTys.begin(); }
00236   subtype_iterator subtype_end() const { return ContainedTys.end(); }
00237 
00238   /// getContainedType - This method is used to implement the type iterator
00239   /// (defined a the end of the file).  For derived types, this returns the
00240   /// types 'contained' in the derived type.
00241   ///
00242   const Type *getContainedType(unsigned i) const {
00243     assert(i < ContainedTys.size() && "Index out of range!");
00244     return ContainedTys[i];
00245   }
00246 
00247   /// getNumContainedTypes - Return the number of types in the derived type.
00248   ///
00249   unsigned getNumContainedTypes() const { return ContainedTys.size(); }
00250 
00251   //===--------------------------------------------------------------------===//
00252   // Static members exported by the Type class itself.  Useful for getting
00253   // instances of Type.
00254   //
00255 
00256   /// getPrimitiveType - Return a type based on an identifier.
00257   static const Type *getPrimitiveType(TypeID IDNumber);
00258 
00259   //===--------------------------------------------------------------------===//
00260   // These are the builtin types that are always available...
00261   //
00262   static Type *VoidTy , *BoolTy;
00263   static Type *SByteTy, *UByteTy,
00264               *ShortTy, *UShortTy,
00265               *IntTy  , *UIntTy, 
00266               *LongTy , *ULongTy;
00267   static Type *FloatTy, *DoubleTy;
00268 
00269   static Type* LabelTy;
00270 
00271   /// Methods for support type inquiry through isa, cast, and dyn_cast:
00272   static inline bool classof(const Type *T) { return true; }
00273 
00274 #include "llvm/Type.def"
00275 
00276   // Virtual methods used by callbacks below.  These should only be implemented
00277   // in the DerivedType class.
00278   virtual void addAbstractTypeUser(AbstractTypeUser *U) const {
00279     abort(); // Only on derived types!
00280   }
00281   virtual void removeAbstractTypeUser(AbstractTypeUser *U) const {
00282     abort(); // Only on derived types!
00283   }
00284 
00285   void addRef() const {
00286     assert(isAbstract() && "Cannot add a reference to a non-abstract type!");
00287     ++RefCount;
00288   }
00289   
00290   void dropRef() const {
00291     assert(isAbstract() && "Cannot drop a reference to a non-abstract type!");
00292     assert(RefCount && "No objects are currently referencing this object!");
00293 
00294     // If this is the last PATypeHolder using this object, and there are no
00295     // PATypeHandles using it, the type is dead, delete it now.
00296     if (--RefCount == 0)
00297       RefCountIsZero();
00298   }
00299 
00300   /// clearAllTypeMaps - This method frees all internal memory used by the
00301   /// type subsystem, which can be used in environments where this memory is
00302   /// otherwise reported as a leak.
00303   static void clearAllTypeMaps();
00304 
00305 private:
00306   /// isSizedDerivedType - Derived types like structures and arrays are sized
00307   /// iff all of the members of the type are sized as well.  Since asking for
00308   /// their size is relatively uncommon, move this operation out of line.
00309   bool isSizedDerivedType() const;
00310 
00311   virtual void RefCountIsZero() const {
00312     abort(); // only on derived types!
00313   }
00314 
00315 };
00316 
00317 //===----------------------------------------------------------------------===//
00318 // Define some inline methods for the AbstractTypeUser.h:PATypeHandle class.
00319 // These are defined here because they MUST be inlined, yet are dependent on 
00320 // the definition of the Type class.  Of course Type derives from Value, which
00321 // contains an AbstractTypeUser instance, so there is no good way to factor out
00322 // the code.  Hence this bit of uglyness.
00323 //
00324 // In the long term, Type should not derive from Value, allowing
00325 // AbstractTypeUser.h to #include Type.h, allowing us to eliminate this
00326 // nastyness entirely.
00327 //
00328 inline void PATypeHandle::addUser() {
00329   assert(Ty && "Type Handle has a null type!");
00330   if (Ty->isAbstract())
00331     Ty->addAbstractTypeUser(User);
00332 }
00333 inline void PATypeHandle::removeUser() {
00334   if (Ty->isAbstract())
00335     Ty->removeAbstractTypeUser(User);
00336 }
00337 
00338 inline void PATypeHandle::removeUserFromConcrete() {
00339   if (!Ty->isAbstract())
00340     Ty->removeAbstractTypeUser(User);
00341 }
00342 
00343 // Define inline methods for PATypeHolder...
00344 
00345 inline void PATypeHolder::addRef() {
00346   if (Ty->isAbstract())
00347     Ty->addRef();
00348 }
00349 
00350 inline void PATypeHolder::dropRef() {
00351   if (Ty->isAbstract())
00352     Ty->dropRef();
00353 }
00354 
00355 /// get - This implements the forwarding part of the union-find algorithm for
00356 /// abstract types.  Before every access to the Type*, we check to see if the
00357 /// type we are pointing to is forwarding to a new type.  If so, we drop our
00358 /// reference to the type.
00359 ///
00360 inline Type* PATypeHolder::get() const {
00361   const Type *NewTy = Ty->getForwardedType();
00362   if (!NewTy) return const_cast<Type*>(Ty);
00363   return *const_cast<PATypeHolder*>(this) = NewTy;
00364 }
00365 
00366 
00367 
00368 //===----------------------------------------------------------------------===//
00369 // Provide specializations of GraphTraits to be able to treat a type as a 
00370 // graph of sub types...
00371 
00372 template <> struct GraphTraits<Type*> {
00373   typedef Type NodeType;
00374   typedef Type::subtype_iterator ChildIteratorType;
00375 
00376   static inline NodeType *getEntryNode(Type *T) { return T; }
00377   static inline ChildIteratorType child_begin(NodeType *N) { 
00378     return N->subtype_begin(); 
00379   }
00380   static inline ChildIteratorType child_end(NodeType *N) { 
00381     return N->subtype_end();
00382   }
00383 };
00384 
00385 template <> struct GraphTraits<const Type*> {
00386   typedef const Type NodeType;
00387   typedef Type::subtype_iterator ChildIteratorType;
00388 
00389   static inline NodeType *getEntryNode(const Type *T) { return T; }
00390   static inline ChildIteratorType child_begin(NodeType *N) { 
00391     return N->subtype_begin(); 
00392   }
00393   static inline ChildIteratorType child_end(NodeType *N) { 
00394     return N->subtype_end();
00395   }
00396 };
00397 
00398 template <> inline bool isa_impl<PointerType, Type>(const Type &Ty) { 
00399   return Ty.getTypeID() == Type::PointerTyID;
00400 }
00401 
00402 std::ostream &operator<<(std::ostream &OS, const Type &T);
00403 
00404 } // End llvm namespace
00405 
00406 #endif