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 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 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 PackedValType;
00032 
00033 class DerivedType : public Type {
00034   friend class Type;
00035 
00036 protected:
00037   DerivedType(TypeID id) : Type(id) {}
00038 
00039   /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type
00040   /// that the current type has transitioned from being abstract to being
00041   /// concrete.
00042   ///
00043   void notifyUsesThatTypeBecameConcrete();
00044 
00045   /// dropAllTypeUses - When this (abstract) type is resolved to be equal to
00046   /// another (more concrete) type, we must eliminate all references to other
00047   /// types, to avoid some circular reference problems.
00048   ///
00049   void dropAllTypeUses();
00050 
00051 public:
00052 
00053   //===--------------------------------------------------------------------===//
00054   // Abstract Type handling methods - These types have special lifetimes, which
00055   // are managed by (add|remove)AbstractTypeUser. See comments in
00056   // AbstractTypeUser.h for more information.
00057 
00058   /// refineAbstractTypeTo - This function is used to when it is discovered that
00059   /// the 'this' abstract type is actually equivalent to the NewType specified.
00060   /// This causes all users of 'this' to switch to reference the more concrete
00061   /// type NewType and for 'this' to be deleted.
00062   ///
00063   void refineAbstractTypeTo(const Type *NewType);
00064 
00065   void dump() const { Type::dump(); }
00066 
00067   // Methods for support type inquiry through isa, cast, and dyn_cast:
00068   static inline bool classof(const DerivedType *T) { return true; }
00069   static inline bool classof(const Type *T) {
00070     return T->isDerivedType();
00071   }
00072 };
00073 
00074 
00075 /// FunctionType - Class to represent function types
00076 ///
00077 class FunctionType : public DerivedType {
00078   friend class TypeMap<FunctionValType, FunctionType>;
00079   bool isVarArgs;
00080 
00081   FunctionType(const FunctionType &);                   // Do not implement
00082   const FunctionType &operator=(const FunctionType &);  // Do not implement
00083 protected:
00084   /// This should really be private, but it squelches a bogus warning
00085   /// from GCC to make them protected:  warning: `class FunctionType' only
00086   /// defines private constructors and has no friends
00087   ///
00088   /// Private ctor - Only can be created by a static member...
00089   ///
00090   FunctionType(const Type *Result, const std::vector<const Type*> &Params,
00091                bool IsVarArgs);
00092 
00093 public:
00094   /// FunctionType::get - This static method is the primary way of constructing
00095   /// a FunctionType
00096   ///
00097   static FunctionType *get(const Type *Result,
00098                            const std::vector<const Type*> &Params,
00099                            bool isVarArg);
00100 
00101   inline bool isVarArg() const { return isVarArgs; }
00102   inline const Type *getReturnType() const { return ContainedTys[0]; }
00103 
00104   typedef std::vector<PATypeHandle>::const_iterator param_iterator;
00105   param_iterator param_begin() const { return ContainedTys.begin()+1; }
00106   param_iterator param_end() const { return ContainedTys.end(); }
00107 
00108   // Parameter type accessors...
00109   const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
00110 
00111   /// getNumParams - Return the number of fixed parameters this function type
00112   /// requires.  This does not consider varargs.
00113   ///
00114   unsigned getNumParams() const { return unsigned(ContainedTys.size()-1); }
00115 
00116   // Implement the AbstractTypeUser interface.
00117   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
00118   virtual void typeBecameConcrete(const DerivedType *AbsTy);
00119 
00120   // Methods for support type inquiry through isa, cast, and dyn_cast:
00121   static inline bool classof(const FunctionType *T) { return true; }
00122   static inline bool classof(const Type *T) {
00123     return T->getTypeID() == FunctionTyID;
00124   }
00125 };
00126 
00127 
00128 /// CompositeType - Common super class of ArrayType, StructType, PointerType
00129 /// and PackedType
00130 class CompositeType : public DerivedType {
00131 protected:
00132   inline CompositeType(TypeID id) : DerivedType(id) { }
00133 public:
00134 
00135   /// getTypeAtIndex - Given an index value into the type, return the type of
00136   /// the element.
00137   ///
00138   virtual const Type *getTypeAtIndex(const Value *V) const = 0;
00139   virtual bool indexValid(const Value *V) const = 0;
00140 
00141   // Methods for support type inquiry through isa, cast, and dyn_cast:
00142   static inline bool classof(const CompositeType *T) { return true; }
00143   static inline bool classof(const Type *T) {
00144     return T->getTypeID() == ArrayTyID ||
00145            T->getTypeID() == StructTyID ||
00146            T->getTypeID() == PointerTyID ||
00147            T->getTypeID() == PackedTyID;
00148   }
00149 };
00150 
00151 
00152 /// StructType - Class to represent struct types
00153 ///
00154 class StructType : public CompositeType {
00155   friend class TypeMap<StructValType, StructType>;
00156   StructType(const StructType &);                   // Do not implement
00157   const StructType &operator=(const StructType &);  // Do not implement
00158 
00159 protected:
00160   /// This should really be private, but it squelches a bogus warning
00161   /// from GCC to make them protected:  warning: `class StructType' only
00162   /// defines private constructors and has no friends
00163   ///
00164   /// Private ctor - Only can be created by a static member...
00165   ///
00166   StructType(const std::vector<const Type*> &Types);
00167 
00168 public:
00169   /// StructType::get - This static method is the primary way to create a
00170   /// StructType.
00171   ///
00172   static StructType *get(const std::vector<const Type*> &Params);
00173 
00174   // Iterator access to the elements
00175   typedef std::vector<PATypeHandle>::const_iterator element_iterator;
00176   element_iterator element_begin() const { return ContainedTys.begin(); }
00177   element_iterator element_end() const { return ContainedTys.end(); }
00178 
00179   // Random access to the elements
00180   unsigned getNumElements() const { return unsigned(ContainedTys.size()); }
00181   const Type *getElementType(unsigned N) const {
00182     assert(N < ContainedTys.size() && "Element number out of range!");
00183     return ContainedTys[N];
00184   }
00185 
00186   /// getTypeAtIndex - Given an index value into the type, return the type of
00187   /// the element.  For a structure type, this must be a constant value...
00188   ///
00189   virtual const Type *getTypeAtIndex(const Value *V) const ;
00190   virtual bool indexValid(const Value *V) const;
00191 
00192   // Implement the AbstractTypeUser interface.
00193   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
00194   virtual void typeBecameConcrete(const DerivedType *AbsTy);
00195 
00196   // Methods for support type inquiry through isa, cast, and dyn_cast:
00197   static inline bool classof(const StructType *T) { return true; }
00198   static inline bool classof(const Type *T) {
00199     return T->getTypeID() == StructTyID;
00200   }
00201 };
00202 
00203 
00204 /// SequentialType - This is the superclass of the array, pointer and packed
00205 /// type classes.  All of these represent "arrays" in memory.  The array type
00206 /// represents a specifically sized array, pointer types are unsized/unknown
00207 /// size arrays, packed types represent specifically sized arrays that
00208 /// allow for use of SIMD instructions.  SequentialType holds the common
00209 /// features of all, which stem from the fact that all three lay their
00210 /// components out in memory identically.
00211 ///
00212 class SequentialType : public CompositeType {
00213   SequentialType(const SequentialType &);                  // Do not implement!
00214   const SequentialType &operator=(const SequentialType &); // Do not implement!
00215 protected:
00216   SequentialType(TypeID TID, const Type *ElType) : CompositeType(TID) {
00217     ContainedTys.reserve(1);
00218     ContainedTys.push_back(PATypeHandle(ElType, this));
00219   }
00220 
00221 public:
00222   inline const Type *getElementType() const { return ContainedTys[0]; }
00223 
00224   virtual bool indexValid(const Value *V) const;
00225 
00226   /// getTypeAtIndex - Given an index value into the type, return the type of
00227   /// the element.  For sequential types, there is only one subtype...
00228   ///
00229   virtual const Type *getTypeAtIndex(const Value *V) const {
00230     return ContainedTys[0];
00231   }
00232 
00233   // Methods for support type inquiry through isa, cast, and dyn_cast:
00234   static inline bool classof(const SequentialType *T) { return true; }
00235   static inline bool classof(const Type *T) {
00236     return T->getTypeID() == ArrayTyID ||
00237            T->getTypeID() == PointerTyID ||
00238            T->getTypeID() == PackedTyID;
00239   }
00240 };
00241 
00242 
00243 /// ArrayType - Class to represent array types
00244 ///
00245 class ArrayType : public SequentialType {
00246   friend class TypeMap<ArrayValType, ArrayType>;
00247   uint64_t NumElements;
00248 
00249   ArrayType(const ArrayType &);                   // Do not implement
00250   const ArrayType &operator=(const ArrayType &);  // Do not implement
00251 protected:
00252   /// This should really be private, but it squelches a bogus warning
00253   /// from GCC to make them protected:  warning: `class ArrayType' only
00254   /// defines private constructors and has no friends
00255   ///
00256   /// Private ctor - Only can be created by a static member...
00257   ///
00258   ArrayType(const Type *ElType, uint64_t NumEl);
00259 
00260 public:
00261   /// ArrayType::get - This static method is the primary way to construct an
00262   /// ArrayType
00263   ///
00264   static ArrayType *get(const Type *ElementType, uint64_t NumElements);
00265 
00266   inline uint64_t getNumElements() const { return NumElements; }
00267 
00268   // Implement the AbstractTypeUser interface.
00269   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
00270   virtual void typeBecameConcrete(const DerivedType *AbsTy);
00271 
00272   // Methods for support type inquiry through isa, cast, and dyn_cast:
00273   static inline bool classof(const ArrayType *T) { return true; }
00274   static inline bool classof(const Type *T) {
00275     return T->getTypeID() == ArrayTyID;
00276   }
00277 };
00278 
00279 /// PackedType - Class to represent packed types
00280 ///
00281 class PackedType : public SequentialType {
00282   friend class TypeMap<PackedValType, PackedType>;
00283   unsigned NumElements;
00284 
00285   PackedType(const PackedType &);                   // Do not implement
00286   const PackedType &operator=(const PackedType &);  // Do not implement
00287 protected:
00288   /// This should really be private, but it squelches a bogus warning
00289   /// from GCC to make them protected:  warning: `class PackedType' only
00290   /// defines private constructors and has no friends
00291   ///
00292   /// Private ctor - Only can be created by a static member...
00293   ///
00294   PackedType(const Type *ElType, unsigned NumEl);
00295 
00296 public:
00297   /// PackedType::get - This static method is the primary way to construct an
00298   /// PackedType
00299   ///
00300   static PackedType *get(const Type *ElementType, unsigned NumElements);
00301 
00302   inline unsigned getNumElements() const { return NumElements; }
00303 
00304   // Implement the AbstractTypeUser interface.
00305   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
00306   virtual void typeBecameConcrete(const DerivedType *AbsTy);
00307 
00308   // Methods for support type inquiry through isa, cast, and dyn_cast:
00309   static inline bool classof(const PackedType *T) { return true; }
00310   static inline bool classof(const Type *T) {
00311     return T->getTypeID() == PackedTyID;
00312   }
00313 };
00314 
00315 
00316 /// PointerType - Class to represent pointers
00317 ///
00318 class PointerType : public SequentialType {
00319   friend class TypeMap<PointerValType, PointerType>;
00320   PointerType(const PointerType &);                   // Do not implement
00321   const PointerType &operator=(const PointerType &);  // Do not implement
00322 protected:
00323   // This should really be private, but it squelches a bogus warning
00324   // from GCC to make them protected:  warning: `class PointerType' only
00325   // defines private constructors and has no friends
00326 
00327   // Private ctor - Only can be created by a static member...
00328   PointerType(const Type *ElType);
00329 
00330 public:
00331   /// PointerType::get - This is the only way to construct a new pointer type.
00332   static PointerType *get(const Type *ElementType);
00333 
00334   // Implement the AbstractTypeUser interface.
00335   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
00336   virtual void typeBecameConcrete(const DerivedType *AbsTy);
00337 
00338   // Implement support type inquiry through isa, cast, and dyn_cast:
00339   static inline bool classof(const PointerType *T) { return true; }
00340   static inline bool classof(const Type *T) {
00341     return T->getTypeID() == PointerTyID;
00342   }
00343 };
00344 
00345 
00346 /// OpaqueType - Class to represent abstract types
00347 ///
00348 class OpaqueType : public DerivedType {
00349   OpaqueType(const OpaqueType &);                   // DO NOT IMPLEMENT
00350   const OpaqueType &operator=(const OpaqueType &);  // DO NOT IMPLEMENT
00351 protected:
00352   /// This should really be private, but it squelches a bogus warning
00353   /// from GCC to make them protected:  warning: `class OpaqueType' only
00354   /// defines private constructors and has no friends
00355   ///
00356   /// Private ctor - Only can be created by a static member...
00357   OpaqueType();
00358 
00359 public:
00360   /// OpaqueType::get - Static factory method for the OpaqueType class...
00361   ///
00362   static OpaqueType *get() {
00363     return new OpaqueType();           // All opaque types are distinct
00364   }
00365 
00366   // Implement the AbstractTypeUser interface.
00367   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
00368     abort();   // FIXME: this is not really an AbstractTypeUser!
00369   }
00370   virtual void typeBecameConcrete(const DerivedType *AbsTy) {
00371     abort();   // FIXME: this is not really an AbstractTypeUser!
00372   }
00373 
00374   // Implement support for type inquiry through isa, cast, and dyn_cast:
00375   static inline bool classof(const OpaqueType *T) { return true; }
00376   static inline bool classof(const Type *T) {
00377     return T->getTypeID() == OpaqueTyID;
00378   }
00379 };
00380 
00381 } // End llvm namespace
00382 
00383 #endif