LLVM API Documentation

DerivedTypes.h

Go to the documentation of this file.
00001 //===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the declarations of classes that represent "derived
00011 // types".  These are things like "arrays of x" or "structure of x, y, z" or
00012 // "method returning x taking (y,z) as parameters", etc...
00013 //
00014 // The implementations of these classes live in the Type.cpp file.
00015 //
00016 //===----------------------------------------------------------------------===//
00017 
00018 #ifndef LLVM_DERIVED_TYPES_H
00019 #define LLVM_DERIVED_TYPES_H
00020 
00021 #include "llvm/Type.h"
00022 
00023 namespace llvm {
00024 
00025 class Value;
00026 template<class ValType, class TypeClass> class TypeMap;
00027 class FunctionValType;
00028 class ArrayValType;
00029 class StructValType;
00030 class PointerValType;
00031 class VectorValType;
00032 class IntegerValType;
00033 class APInt;
00034 
00035 class DerivedType : public Type {
00036   friend class Type;
00037 
00038 protected:
00039   explicit DerivedType(TypeID id) : Type(id) {}
00040 
00041   /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type
00042   /// that the current type has transitioned from being abstract to being
00043   /// concrete.
00044   ///
00045   void notifyUsesThatTypeBecameConcrete();
00046 
00047   /// dropAllTypeUses - When this (abstract) type is resolved to be equal to
00048   /// another (more concrete) type, we must eliminate all references to other
00049   /// types, to avoid some circular reference problems.
00050   ///
00051   void dropAllTypeUses();
00052 
00053 public:
00054 
00055   //===--------------------------------------------------------------------===//
00056   // Abstract Type handling methods - These types have special lifetimes, which
00057   // are managed by (add|remove)AbstractTypeUser. See comments in
00058   // AbstractTypeUser.h for more information.
00059 
00060   /// refineAbstractTypeTo - This function is used to when it is discovered that
00061   /// the 'this' abstract type is actually equivalent to the NewType specified.
00062   /// This causes all users of 'this' to switch to reference the more concrete
00063   /// type NewType and for 'this' to be deleted.
00064   ///
00065   void refineAbstractTypeTo(const Type *NewType);
00066 
00067   void dump() const { Type::dump(); }
00068 
00069   // Methods for support type inquiry through isa, cast, and dyn_cast:
00070   static inline bool classof(const DerivedType *) { return true; }
00071   static inline bool classof(const Type *T) {
00072     return T->isDerivedType();
00073   }
00074 };
00075 
00076 /// Class to represent integer types. Note that this class is also used to
00077 /// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
00078 /// Int64Ty. 
00079 /// @brief Integer representation type
00080 class IntegerType : public DerivedType {
00081 protected:
00082   explicit IntegerType(unsigned NumBits) : DerivedType(IntegerTyID) {
00083     setSubclassData(NumBits);
00084   }
00085   friend class TypeMap<IntegerValType, IntegerType>;
00086 public:
00087   /// This enum is just used to hold constants we need for IntegerType.
00088   enum {
00089     MIN_INT_BITS = 1,        ///< Minimum number of bits that can be specified
00090     MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified
00091       ///< Note that bit width is stored in the Type classes SubclassData field
00092       ///< which has 23 bits. This yields a maximum bit width of 8,388,607 bits.
00093   };
00094 
00095   /// This static method is the primary way of constructing an IntegerType. 
00096   /// If an IntegerType with the same NumBits value was previously instantiated,
00097   /// that instance will be returned. Otherwise a new one will be created. Only
00098   /// one instance with a given NumBits value is ever created.
00099   /// @brief Get or create an IntegerType instance.
00100   static const IntegerType* get(unsigned NumBits);
00101 
00102   /// @brief Get the number of bits in this IntegerType
00103   unsigned getBitWidth() const { return getSubclassData(); }
00104 
00105   /// getBitMask - Return a bitmask with ones set for all of the bits
00106   /// that can be set by an unsigned version of this type.  This is 0xFF for
00107   /// i8, 0xFFFF for i16, etc.
00108   uint64_t getBitMask() const {
00109     return ~uint64_t(0UL) >> (64-getBitWidth());
00110   }
00111 
00112   /// getSignBit - Return a uint64_t with just the most significant bit set (the
00113   /// sign bit, if the value is treated as a signed number).
00114   uint64_t getSignBit() const {
00115     return 1ULL << (getBitWidth()-1);
00116   }
00117   
00118   /// For example, this is 0xFF for an 8 bit integer, 0xFFFF for i16, etc.
00119   /// @returns a bit mask with ones set for all the bits of this type.
00120   /// @brief Get a bit mask for this type.
00121   APInt getMask() const;
00122 
00123   /// This method determines if the width of this IntegerType is a power-of-2
00124   /// in terms of 8 bit bytes. 
00125   /// @returns true if this is a power-of-2 byte width.
00126   /// @brief Is this a power-of-2 byte-width IntegerType ?
00127   bool isPowerOf2ByteWidth() const;
00128 
00129   // Methods for support type inquiry through isa, cast, and dyn_cast:
00130   static inline bool classof(const IntegerType *) { return true; }
00131   static inline bool classof(const Type *T) {
00132     return T->getTypeID() == IntegerTyID;
00133   }
00134 };
00135 
00136 
00137 /// FunctionType - Class to represent function types
00138 ///
00139 class FunctionType : public DerivedType {
00140   friend class TypeMap<FunctionValType, FunctionType>;
00141   bool isVarArgs;
00142 
00143   FunctionType(const FunctionType &);                   // Do not implement
00144   const FunctionType &operator=(const FunctionType &);  // Do not implement
00145   FunctionType(const Type *Result, const std::vector<const Type*> &Params,
00146                bool IsVarArgs);
00147 
00148 public:
00149   /// FunctionType::get - This static method is the primary way of constructing
00150   /// a FunctionType. 
00151   ///
00152   static FunctionType *get(
00153     const Type *Result, ///< The result type
00154     const std::vector<const Type*> &Params, ///< The types of the parameters
00155     bool isVarArg  ///< Whether this is a variable argument length function
00156   );
00157   
00158   /// isValidReturnType - Return true if the specified type is valid as a return
00159   /// type.
00160   static bool isValidReturnType(const Type *RetTy);
00161 
00162   inline bool isVarArg() const { return isVarArgs; }
00163   inline const Type *getReturnType() const { return ContainedTys[0]; }
00164 
00165   typedef Type::subtype_iterator param_iterator;
00166   param_iterator param_begin() const { return ContainedTys + 1; }
00167   param_iterator param_end() const { return &ContainedTys[NumContainedTys]; }
00168 
00169   // Parameter type accessors...
00170   const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
00171 
00172   /// getNumParams - Return the number of fixed parameters this function type
00173   /// requires.  This does not consider varargs.
00174   ///
00175   unsigned getNumParams() const { return NumContainedTys - 1; }
00176 
00177   // Implement the AbstractTypeUser interface.
00178   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
00179   virtual void typeBecameConcrete(const DerivedType *AbsTy);
00180 
00181   // Methods for support type inquiry through isa, cast, and dyn_cast:
00182   static inline bool classof(const FunctionType *) { return true; }
00183   static inline bool classof(const Type *T) {
00184     return T->getTypeID() == FunctionTyID;
00185   }
00186 };
00187 
00188 
00189 /// CompositeType - Common super class of ArrayType, StructType, PointerType
00190 /// and VectorType
00191 class CompositeType : public DerivedType {
00192 protected:
00193   inline explicit CompositeType(TypeID id) : DerivedType(id) { }
00194 public:
00195 
00196   /// getTypeAtIndex - Given an index value into the type, return the type of
00197   /// the element.
00198   ///
00199   virtual const Type *getTypeAtIndex(const Value *V) const = 0;
00200   virtual const Type *getTypeAtIndex(unsigned Idx) const = 0;
00201   virtual bool indexValid(const Value *V) const = 0;
00202   virtual bool indexValid(unsigned Idx) const = 0;
00203 
00204   // Methods for support type inquiry through isa, cast, and dyn_cast:
00205   static inline bool classof(const CompositeType *) { return true; }
00206   static inline bool classof(const Type *T) {
00207     return T->getTypeID() == ArrayTyID ||
00208            T->getTypeID() == StructTyID ||
00209            T->getTypeID() == PointerTyID ||
00210            T->getTypeID() == VectorTyID;
00211   }
00212 };
00213 
00214 
00215 /// StructType - Class to represent struct types
00216 ///
00217 class StructType : public CompositeType {
00218   friend class TypeMap<StructValType, StructType>;
00219   StructType(const StructType &);                   // Do not implement
00220   const StructType &operator=(const StructType &);  // Do not implement
00221   StructType(const std::vector<const Type*> &Types, bool isPacked);
00222 public:
00223   /// StructType::get - This static method is the primary way to create a
00224   /// StructType.
00225   ///
00226   static StructType *get(const std::vector<const Type*> &Params, 
00227                          bool isPacked=false);
00228 
00229   /// StructType::get - This static method is a convenience method for
00230   /// creating structure types by specifying the elements as arguments.
00231   /// Note that this method always returns a non-packed struct.  To get
00232   /// an empty struct, pass NULL, NULL.
00233   static StructType *get(const Type *type, ...) END_WITH_NULL;
00234 
00235   // Iterator access to the elements
00236   typedef Type::subtype_iterator element_iterator;
00237   element_iterator element_begin() const { return ContainedTys; }
00238   element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
00239 
00240   // Random access to the elements
00241   unsigned getNumElements() const { return NumContainedTys; }
00242   const Type *getElementType(unsigned N) const {
00243     assert(N < NumContainedTys && "Element number out of range!");
00244     return ContainedTys[N];
00245   }
00246 
00247   /// getTypeAtIndex - Given an index value into the type, return the type of
00248   /// the element.  For a structure type, this must be a constant value...
00249   ///
00250   virtual const Type *getTypeAtIndex(const Value *V) const;
00251   virtual const Type *getTypeAtIndex(unsigned Idx) const;
00252   virtual bool indexValid(const Value *V) const;
00253   virtual bool indexValid(unsigned Idx) const;
00254 
00255   // Implement the AbstractTypeUser interface.
00256   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
00257   virtual void typeBecameConcrete(const DerivedType *AbsTy);
00258 
00259   // Methods for support type inquiry through isa, cast, and dyn_cast:
00260   static inline bool classof(const StructType *) { return true; }
00261   static inline bool classof(const Type *T) {
00262     return T->getTypeID() == StructTyID;
00263   }
00264 
00265   bool isPacked() const { return (0 != getSubclassData()) ? true : false; }
00266 };
00267 
00268 
00269 /// SequentialType - This is the superclass of the array, pointer and vector
00270 /// type classes.  All of these represent "arrays" in memory.  The array type
00271 /// represents a specifically sized array, pointer types are unsized/unknown
00272 /// size arrays, vector types represent specifically sized arrays that
00273 /// allow for use of SIMD instructions.  SequentialType holds the common
00274 /// features of all, which stem from the fact that all three lay their
00275 /// components out in memory identically.
00276 ///
00277 class SequentialType : public CompositeType {
00278   PATypeHandle ContainedType; ///< Storage for the single contained type
00279   SequentialType(const SequentialType &);                  // Do not implement!
00280   const SequentialType &operator=(const SequentialType &); // Do not implement!
00281 
00282   // avoiding warning: 'this' : used in base member initializer list
00283   SequentialType* this_() { return this; }
00284 protected:
00285   SequentialType(TypeID TID, const Type *ElType) 
00286     : CompositeType(TID), ContainedType(ElType, this_()) {
00287     ContainedTys = &ContainedType; 
00288     NumContainedTys = 1;
00289   }
00290 
00291 public:
00292   inline const Type *getElementType() const { return ContainedTys[0]; }
00293 
00294   virtual bool indexValid(const Value *V) const;
00295   virtual bool indexValid(unsigned) const {
00296     return true;
00297   }
00298 
00299   /// getTypeAtIndex - Given an index value into the type, return the type of
00300   /// the element.  For sequential types, there is only one subtype...
00301   ///
00302   virtual const Type *getTypeAtIndex(const Value *) const {
00303     return ContainedTys[0];
00304   }
00305   virtual const Type *getTypeAtIndex(unsigned) const {
00306     return ContainedTys[0];
00307   }
00308 
00309   // Methods for support type inquiry through isa, cast, and dyn_cast:
00310   static inline bool classof(const SequentialType *) { return true; }
00311   static inline bool classof(const Type *T) {
00312     return T->getTypeID() == ArrayTyID ||
00313            T->getTypeID() == PointerTyID ||
00314            T->getTypeID() == VectorTyID;
00315   }
00316 };
00317 
00318 
00319 /// ArrayType - Class to represent array types
00320 ///
00321 class ArrayType : public SequentialType {
00322   friend class TypeMap<ArrayValType, ArrayType>;
00323   uint64_t NumElements;
00324 
00325   ArrayType(const ArrayType &);                   // Do not implement
00326   const ArrayType &operator=(const ArrayType &);  // Do not implement
00327   ArrayType(const Type *ElType, uint64_t NumEl);
00328 public:
00329   /// ArrayType::get - This static method is the primary way to construct an
00330   /// ArrayType
00331   ///
00332   static ArrayType *get(const Type *ElementType, uint64_t NumElements);
00333 
00334   inline uint64_t getNumElements() const { return NumElements; }
00335 
00336   // Implement the AbstractTypeUser interface.
00337   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
00338   virtual void typeBecameConcrete(const DerivedType *AbsTy);
00339 
00340   // Methods for support type inquiry through isa, cast, and dyn_cast:
00341   static inline bool classof(const ArrayType *) { return true; }
00342   static inline bool classof(const Type *T) {
00343     return T->getTypeID() == ArrayTyID;
00344   }
00345 };
00346 
00347 /// VectorType - Class to represent vector types
00348 ///
00349 class VectorType : public SequentialType {
00350   friend class TypeMap<VectorValType, VectorType>;
00351   unsigned NumElements;
00352 
00353   VectorType(const VectorType &);                   // Do not implement
00354   const VectorType &operator=(const VectorType &);  // Do not implement
00355   VectorType(const Type *ElType, unsigned NumEl);
00356 public:
00357   /// VectorType::get - This static method is the primary way to construct an
00358   /// VectorType
00359   ///
00360   static VectorType *get(const Type *ElementType, unsigned NumElements);
00361 
00362   /// VectorType::getInteger - This static method gets a VectorType with the
00363   /// same number of elements as the input type, and the element type is an
00364   /// integer type of the same width as the input element type.
00365   ///
00366   static VectorType *getInteger(const VectorType *VTy) {
00367     unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
00368     const Type *EltTy = IntegerType::get(EltBits);
00369     return VectorType::get(EltTy, VTy->getNumElements());
00370   }
00371 
00372   /// VectorType::getExtendedElementVectorType - This static method is like
00373   /// getInteger except that the element types are twice as wide as the
00374   /// elements in the input type.
00375   ///
00376   static VectorType *getExtendedElementVectorType(const VectorType *VTy) {
00377     unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
00378     const Type *EltTy = IntegerType::get(EltBits * 2);
00379     return VectorType::get(EltTy, VTy->getNumElements());
00380   }
00381 
00382   /// VectorType::getTruncatedElementVectorType - This static method is like
00383   /// getInteger except that the element types are half as wide as the
00384   /// elements in the input type.
00385   ///
00386   static VectorType *getTruncatedElementVectorType(const VectorType *VTy) {
00387     unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
00388     const Type *EltTy = IntegerType::get(EltBits / 2);
00389     return VectorType::get(EltTy, VTy->getNumElements());
00390   }
00391 
00392   /// @brief Return the number of elements in the Vector type.
00393   inline unsigned getNumElements() const { return NumElements; }
00394 
00395   /// @brief Return the number of bits in the Vector type.
00396   inline unsigned getBitWidth() const { 
00397     return NumElements *getElementType()->getPrimitiveSizeInBits();
00398   }
00399 
00400   // Implement the AbstractTypeUser interface.
00401   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
00402   virtual void typeBecameConcrete(const DerivedType *AbsTy);
00403 
00404   // Methods for support type inquiry through isa, cast, and dyn_cast:
00405   static inline bool classof(const VectorType *) { return true; }
00406   static inline bool classof(const Type *T) {
00407     return T->getTypeID() == VectorTyID;
00408   }
00409 };
00410 
00411 
00412 /// PointerType - Class to represent pointers
00413 ///
00414 class PointerType : public SequentialType {
00415   friend class TypeMap<PointerValType, PointerType>;
00416   unsigned AddressSpace;
00417   
00418   PointerType(const PointerType &);                   // Do not implement
00419   const PointerType &operator=(const PointerType &);  // Do not implement
00420   explicit PointerType(const Type *ElType, unsigned AddrSpace);
00421 public:
00422   /// PointerType::get - This constructs a pointer to an object of the specified 
00423   /// type in a numbered address space.
00424   static PointerType *get(const Type *ElementType, unsigned AddressSpace);
00425   
00426   /// PointerType::getUnqual - This constructs a pointer to an object of the  
00427   /// specified type in the generic address space (address space zero).
00428   static PointerType *getUnqual(const Type *ElementType) { 
00429     return PointerType::get(ElementType, 0);
00430   }
00431   
00432   /// @brief Return the address space of the Pointer type.
00433   inline unsigned getAddressSpace() const { return AddressSpace; }
00434 
00435   // Implement the AbstractTypeUser interface.
00436   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
00437   virtual void typeBecameConcrete(const DerivedType *AbsTy);
00438 
00439   // Implement support type inquiry through isa, cast, and dyn_cast:
00440   static inline bool classof(const PointerType *) { return true; }
00441   static inline bool classof(const Type *T) {
00442     return T->getTypeID() == PointerTyID;
00443   }
00444 };
00445 
00446 
00447 /// OpaqueType - Class to represent abstract types
00448 ///
00449 class OpaqueType : public DerivedType {
00450   OpaqueType(const OpaqueType &);                   // DO NOT IMPLEMENT
00451   const OpaqueType &operator=(const OpaqueType &);  // DO NOT IMPLEMENT
00452   OpaqueType();
00453 public:
00454   /// OpaqueType::get - Static factory method for the OpaqueType class...
00455   ///
00456   static OpaqueType *get() {
00457     return new OpaqueType();           // All opaque types are distinct
00458   }
00459 
00460   // Implement support for type inquiry through isa, cast, and dyn_cast:
00461   static inline bool classof(const OpaqueType *) { return true; }
00462   static inline bool classof(const Type *T) {
00463     return T->getTypeID() == OpaqueTyID;
00464   }
00465 };
00466 
00467 } // End llvm namespace
00468 
00469 #endif



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.