LLVM API Documentation
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