e0ccffd5fb7e9371e01d48b437a86e5a0b3bab8b
[oota-llvm.git] / include / llvm / DerivedTypes.h
1 //===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===//
2 //
3 // This file contains the declarations of classes that represent "derived 
4 // types".  These are things like "arrays of x" or "structure of x, y, z" or
5 // "method returning x taking (y,z) as parameters", etc...
6 //
7 // The implementations of these classes live in the Type.cpp file.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #ifndef LLVM_DERIVED_TYPES_H
12 #define LLVM_DERIVED_TYPES_H
13
14 #include "llvm/Type.h"
15
16 template<class ValType, class TypeClass> class TypeMap;
17 class FunctionValType;
18 class ArrayValType;
19 class StructValType;
20 class PointerValType;
21
22 class DerivedType : public Type, public AbstractTypeUser {
23   /// RefCount - This counts the number of PATypeHolders that are pointing to
24   /// this type.  When this number falls to zero, if the type is abstract and
25   /// has no AbstractTypeUsers, the type is deleted.
26   ///
27   mutable unsigned RefCount;
28   
29   // AbstractTypeUsers - Implement a list of the users that need to be notified
30   // if I am a type, and I get resolved into a more concrete type.
31   //
32   ///// FIXME: kill mutable nonsense when Type's are not const
33   mutable std::vector<AbstractTypeUser *> AbstractTypeUsers;
34
35 protected:
36   DerivedType(PrimitiveID id) : Type("", id), RefCount(0) {
37   }
38   ~DerivedType() {
39     assert(AbstractTypeUsers.empty());
40   }
41
42   /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type
43   /// that the current type has transitioned from being abstract to being
44   /// concrete.
45   ///
46   void notifyUsesThatTypeBecameConcrete();
47
48   // dropAllTypeUses - When this (abstract) type is resolved to be equal to
49   // another (more concrete) type, we must eliminate all references to other
50   // types, to avoid some circular reference problems.
51   virtual void dropAllTypeUses() = 0;
52   
53 public:
54
55   //===--------------------------------------------------------------------===//
56   // Abstract Type handling methods - These types have special lifetimes, which
57   // are managed by (add|remove)AbstractTypeUser. See comments in
58   // AbstractTypeUser.h for more information.
59
60   // addAbstractTypeUser - Notify an abstract type that there is a new user of
61   // it.  This function is called primarily by the PATypeHandle class.
62   //
63   void addAbstractTypeUser(AbstractTypeUser *U) const {
64     assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
65     AbstractTypeUsers.push_back(U);
66   }
67
68   // removeAbstractTypeUser - Notify an abstract type that a user of the class
69   // no longer has a handle to the type.  This function is called primarily by
70   // the PATypeHandle class.  When there are no users of the abstract type, it
71   // is annihilated, because there is no way to get a reference to it ever
72   // again.
73   //
74   void removeAbstractTypeUser(AbstractTypeUser *U) const;
75
76   // refineAbstractTypeTo - This function is used to when it is discovered that
77   // the 'this' abstract type is actually equivalent to the NewType specified.
78   // This causes all users of 'this' to switch to reference the more concrete
79   // type NewType and for 'this' to be deleted.
80   //
81   void refineAbstractTypeTo(const Type *NewType);
82
83   void addRef() const {
84     assert(isAbstract() && "Cannot add a reference to a non-abstract type!");
85     ++RefCount;
86   }
87
88   void dropRef() const {
89     assert(isAbstract() && "Cannot drop a refernce to a non-abstract type!");
90     assert(RefCount && "No objects are currently referencing this object!");
91
92     // If this is the last PATypeHolder using this object, and there are no
93     // PATypeHandles using it, the type is dead, delete it now.
94     if (--RefCount == 0 && AbstractTypeUsers.empty())
95       delete this;
96   }
97
98
99   void dump() const { Value::dump(); }
100
101   // Methods for support type inquiry through isa, cast, and dyn_cast:
102   static inline bool classof(const DerivedType *T) { return true; }
103   static inline bool classof(const Type *T) {
104     return T->isDerivedType();
105   }
106   static inline bool classof(const Value *V) {
107     return isa<Type>(V) && classof(cast<Type>(V));
108   }
109 };
110
111
112
113
114 struct FunctionType : public DerivedType {
115   typedef std::vector<PATypeHandle> ParamTypes;
116   friend class TypeMap<FunctionValType, FunctionType>;
117 private:
118   PATypeHandle ResultType;
119   ParamTypes ParamTys;
120   bool isVarArgs;
121
122   FunctionType(const FunctionType &);                   // Do not implement
123   const FunctionType &operator=(const FunctionType &);  // Do not implement
124 protected:
125   // This should really be private, but it squelches a bogus warning
126   // from GCC to make them protected:  warning: `class FunctionType' only 
127   // defines private constructors and has no friends
128
129   // Private ctor - Only can be created by a static member...
130   FunctionType(const Type *Result, const std::vector<const Type*> &Params, 
131                bool IsVarArgs);
132
133   // dropAllTypeUses - When this (abstract) type is resolved to be equal to
134   // another (more concrete) type, we must eliminate all references to other
135   // types, to avoid some circular reference problems.
136   virtual void dropAllTypeUses();
137
138 public:
139   /// FunctionType::get - This static method is the primary way of constructing
140   /// a FunctionType
141   static FunctionType *get(const Type *Result,
142                            const std::vector<const Type*> &Params,
143                            bool isVarArg);
144
145   inline bool isVarArg() const { return isVarArgs; }
146   inline const Type *getReturnType() const { return ResultType; }
147   inline const ParamTypes &getParamTypes() const { return ParamTys; }
148
149   // Parameter type accessors...
150   const Type *getParamType(unsigned i) const { return ParamTys[i]; }
151
152   // getNumParams - Return the number of fixed parameters this function type
153   // requires.  This does not consider varargs.
154   //
155   unsigned getNumParams() const { return ParamTys.size(); }
156
157
158   virtual const Type *getContainedType(unsigned i) const {
159     return i == 0 ? ResultType.get() : ParamTys[i-1].get();
160   }
161   virtual unsigned getNumContainedTypes() const { return ParamTys.size()+1; }
162
163   // Implement the AbstractTypeUser interface.
164   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
165   virtual void typeBecameConcrete(const DerivedType *AbsTy);
166   
167   // Methods for support type inquiry through isa, cast, and dyn_cast:
168   static inline bool classof(const FunctionType *T) { return true; }
169   static inline bool classof(const Type *T) {
170     return T->getPrimitiveID() == FunctionTyID;
171   }
172   static inline bool classof(const Value *V) {
173     return isa<Type>(V) && classof(cast<Type>(V));
174   }
175 };
176
177
178 // CompositeType - Common super class of ArrayType, StructType, and PointerType
179 //
180 class CompositeType : public DerivedType {
181 protected:
182   inline CompositeType(PrimitiveID id) : DerivedType(id) { }
183 public:
184
185   // getTypeAtIndex - Given an index value into the type, return the type of the
186   // element.
187   //
188   virtual const Type *getTypeAtIndex(const Value *V) const = 0;
189   virtual bool indexValid(const Value *V) const = 0;
190
191   // getIndexType - Return the type required of indices for this composite.
192   // For structures, this is ubyte, for arrays, this is uint
193   //
194   virtual const Type *getIndexType() const = 0;
195
196
197   // Methods for support type inquiry through isa, cast, and dyn_cast:
198   static inline bool classof(const CompositeType *T) { return true; }
199   static inline bool classof(const Type *T) {
200     return T->getPrimitiveID() == ArrayTyID || 
201            T->getPrimitiveID() == StructTyID ||
202            T->getPrimitiveID() == PointerTyID;
203   }
204   static inline bool classof(const Value *V) {
205     return isa<Type>(V) && classof(cast<Type>(V));
206   }
207 };
208
209
210 struct StructType : public CompositeType {
211   friend class TypeMap<StructValType, StructType>;
212   typedef std::vector<PATypeHandle> ElementTypes;
213
214 private:
215   ElementTypes ETypes;                              // Element types of struct
216
217   StructType(const StructType &);                   // Do not implement
218   const StructType &operator=(const StructType &);  // Do not implement
219
220 protected:
221   // This should really be private, but it squelches a bogus warning
222   // from GCC to make them protected:  warning: `class StructType' only 
223   // defines private constructors and has no friends
224
225   // Private ctor - Only can be created by a static member...
226   StructType(const std::vector<const Type*> &Types);
227
228   // dropAllTypeUses - When this (abstract) type is resolved to be equal to
229   // another (more concrete) type, we must eliminate all references to other
230   // types, to avoid some circular reference problems.
231   virtual void dropAllTypeUses();
232   
233 public:
234   /// StructType::get - This static method is the primary way to create a
235   /// StructType.
236   static StructType *get(const std::vector<const Type*> &Params);
237
238   inline const ElementTypes &getElementTypes() const { return ETypes; }
239
240   virtual const Type *getContainedType(unsigned i) const { 
241     return ETypes[i].get();
242   }
243   virtual unsigned getNumContainedTypes() const { return ETypes.size(); }
244
245   // getTypeAtIndex - Given an index value into the type, return the type of the
246   // element.  For a structure type, this must be a constant value...
247   //
248   virtual const Type *getTypeAtIndex(const Value *V) const ;
249   virtual bool indexValid(const Value *V) const;
250
251   // getIndexType - Return the type required of indices for this composite.
252   // For structures, this is ubyte, for arrays, this is uint
253   //
254   virtual const Type *getIndexType() const { return Type::UByteTy; }
255
256   // Implement the AbstractTypeUser interface.
257   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
258   virtual void typeBecameConcrete(const DerivedType *AbsTy);
259
260   // Methods for support type inquiry through isa, cast, and dyn_cast:
261   static inline bool classof(const StructType *T) { return true; }
262   static inline bool classof(const Type *T) {
263     return T->getPrimitiveID() == StructTyID;
264   }
265   static inline bool classof(const Value *V) {
266     return isa<Type>(V) && classof(cast<Type>(V));
267   }
268 };
269
270
271 // SequentialType - This is the superclass of the array and pointer type
272 // classes.  Both of these represent "arrays" in memory.  The array type
273 // represents a specifically sized array, pointer types are unsized/unknown size
274 // arrays.  SequentialType holds the common features of both, which stem from
275 // the fact that both lay their components out in memory identically.
276 //
277 class SequentialType : public CompositeType {
278   SequentialType(const SequentialType &);                  // Do not implement!
279   const SequentialType &operator=(const SequentialType &); // Do not implement!
280 protected:
281   PATypeHandle ElementType;
282
283   SequentialType(PrimitiveID TID, const Type *ElType)
284     : CompositeType(TID), ElementType(PATypeHandle(ElType, this)) {
285   }
286
287 public:
288   inline const Type *getElementType() const { return ElementType; }
289
290   virtual const Type *getContainedType(unsigned i) const { 
291     return ElementType.get();
292   }
293   virtual unsigned getNumContainedTypes() const { return 1; }
294
295   // getTypeAtIndex - Given an index value into the type, return the type of the
296   // element.  For sequential types, there is only one subtype...
297   //
298   virtual const Type *getTypeAtIndex(const Value *V) const {
299     return ElementType.get();
300   }
301   virtual bool indexValid(const Value *V) const {
302     return V->getType() == Type::LongTy;   // Must be a 'long' index
303   }
304
305   // getIndexType() - Return the type required of indices for this composite.
306   // For structures, this is ubyte, for arrays, this is uint
307   //
308   virtual const Type *getIndexType() const { return Type::LongTy; }
309
310   // Methods for support type inquiry through isa, cast, and dyn_cast:
311   static inline bool classof(const SequentialType *T) { return true; }
312   static inline bool classof(const Type *T) {
313     return T->getPrimitiveID() == ArrayTyID ||
314            T->getPrimitiveID() == PointerTyID;
315   }
316   static inline bool classof(const Value *V) {
317     return isa<Type>(V) && classof(cast<Type>(V));
318   }
319 };
320
321
322 class ArrayType : public SequentialType {
323   friend class TypeMap<ArrayValType, ArrayType>;
324   unsigned NumElements;
325
326   ArrayType(const ArrayType &);                   // Do not implement
327   const ArrayType &operator=(const ArrayType &);  // Do not implement
328 protected:
329   // This should really be private, but it squelches a bogus warning
330   // from GCC to make them protected:  warning: `class ArrayType' only 
331   // defines private constructors and has no friends
332
333   // Private ctor - Only can be created by a static member...
334   ArrayType(const Type *ElType, unsigned NumEl);
335
336   // dropAllTypeUses - When this (abstract) type is resolved to be equal to
337   // another (more concrete) type, we must eliminate all references to other
338   // types, to avoid some circular reference problems.
339   virtual void dropAllTypeUses();
340
341 public:
342   /// ArrayType::get - This static method is the primary way to construct an
343   /// ArrayType
344   static ArrayType *get(const Type *ElementType, unsigned NumElements);
345
346   inline unsigned    getNumElements() const { return NumElements; }
347
348   // Implement the AbstractTypeUser interface.
349   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
350   virtual void typeBecameConcrete(const DerivedType *AbsTy);
351
352   // Methods for support type inquiry through isa, cast, and dyn_cast:
353   static inline bool classof(const ArrayType *T) { return true; }
354   static inline bool classof(const Type *T) {
355     return T->getPrimitiveID() == ArrayTyID;
356   }
357   static inline bool classof(const Value *V) {
358     return isa<Type>(V) && classof(cast<Type>(V));
359   }
360 };
361
362
363
364 class PointerType : public SequentialType {
365   friend class TypeMap<PointerValType, PointerType>;
366   PointerType(const PointerType &);                   // Do not implement
367   const PointerType &operator=(const PointerType &);  // Do not implement
368 protected:
369   // This should really be private, but it squelches a bogus warning
370   // from GCC to make them protected:  warning: `class PointerType' only 
371   // defines private constructors and has no friends
372
373   // Private ctor - Only can be created by a static member...
374   PointerType(const Type *ElType);
375
376   // dropAllTypeUses - When this (abstract) type is resolved to be equal to
377   // another (more concrete) type, we must eliminate all references to other
378   // types, to avoid some circular reference problems.
379   virtual void dropAllTypeUses();
380 public:
381   /// PointerType::get - This is the only way to construct a new pointer type.
382   static PointerType *get(const Type *ElementType);
383
384   // Implement the AbstractTypeUser interface.
385   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
386   virtual void typeBecameConcrete(const DerivedType *AbsTy);
387
388   // Implement support type inquiry through isa, cast, and dyn_cast:
389   static inline bool classof(const PointerType *T) { return true; }
390   static inline bool classof(const Type *T) {
391     return T->getPrimitiveID() == PointerTyID;
392   }
393   static inline bool classof(const Value *V) {
394     return isa<Type>(V) && classof(cast<Type>(V));
395   }
396 };
397
398
399 class OpaqueType : public DerivedType {
400   OpaqueType(const OpaqueType &);                   // DO NOT IMPLEMENT
401   const OpaqueType &operator=(const OpaqueType &);  // DO NOT IMPLEMENT
402 protected:
403   // This should really be private, but it squelches a bogus warning
404   // from GCC to make them protected:  warning: `class OpaqueType' only 
405   // defines private constructors and has no friends
406
407   // Private ctor - Only can be created by a static member...
408   OpaqueType();
409
410   // dropAllTypeUses - When this (abstract) type is resolved to be equal to
411   // another (more concrete) type, we must eliminate all references to other
412   // types, to avoid some circular reference problems.
413   virtual void dropAllTypeUses() {
414     // FIXME: THIS IS NOT AN ABSTRACT TYPE USER!
415   }  // No type uses
416
417 public:
418   // OpaqueType::get - Static factory method for the OpaqueType class...
419   static OpaqueType *get() {
420     return new OpaqueType();           // All opaque types are distinct
421   }
422
423   // Implement the AbstractTypeUser interface.
424   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
425     abort();   // FIXME: this is not really an AbstractTypeUser!
426   }
427   virtual void typeBecameConcrete(const DerivedType *AbsTy) {
428     abort();   // FIXME: this is not really an AbstractTypeUser!
429   }
430
431   // Implement support for type inquiry through isa, cast, and dyn_cast:
432   static inline bool classof(const OpaqueType *T) { return true; }
433   static inline bool classof(const Type *T) {
434     return T->getPrimitiveID() == OpaqueTyID;
435   }
436   static inline bool classof(const Value *V) {
437     return isa<Type>(V) && classof(cast<Type>(V));
438   }
439 };
440
441
442 // Define some inline methods for the AbstractTypeUser.h:PATypeHandle class.
443 // These are defined here because they MUST be inlined, yet are dependent on 
444 // the definition of the Type class.  Of course Type derives from Value, which
445 // contains an AbstractTypeUser instance, so there is no good way to factor out
446 // the code.  Hence this bit of uglyness.
447 //
448 inline void PATypeHandle::addUser() {
449   assert(Ty && "Type Handle has a null type!");
450   if (Ty->isAbstract())
451     cast<DerivedType>(Ty)->addAbstractTypeUser(User);
452 }
453 inline void PATypeHandle::removeUser() {
454   if (Ty->isAbstract())
455     cast<DerivedType>(Ty)->removeAbstractTypeUser(User);
456 }
457
458 inline void PATypeHandle::removeUserFromConcrete() {
459   if (!Ty->isAbstract())
460     cast<DerivedType>(Ty)->removeAbstractTypeUser(User);
461 }
462
463 // Define inline methods for PATypeHolder...
464
465 inline void PATypeHolder::addRef() {
466   if (Ty->isAbstract())
467     cast<DerivedType>(Ty)->addRef();
468 }
469
470 inline void PATypeHolder::dropRef() {
471   if (Ty->isAbstract())
472     cast<DerivedType>(Ty)->dropRef();
473 }
474
475 /// get - This implements the forwarding part of the union-find algorithm for
476 /// abstract types.  Before every access to the Type*, we check to see if the
477 /// type we are pointing to is forwarding to a new type.  If so, we drop our
478 /// reference to the type.
479 inline const Type* PATypeHolder::get() const {
480   const Type *NewTy = Ty->getForwardedType();
481   if (!NewTy) return Ty;
482   return *const_cast<PATypeHolder*>(this) = NewTy;
483 }
484
485 #endif