LLVM API Documentation

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

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