Fix VC++ compilation error
[oota-llvm.git] / include / llvm / DerivedTypes.h
1 //===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the declarations of classes that represent "derived 
11 // types".  These are things like "arrays of x" or "structure of x, y, z" or
12 // "method returning x taking (y,z) as parameters", etc...
13 //
14 // The implementations of these classes live in the Type.cpp file.
15 //
16 //===----------------------------------------------------------------------===//
17
18 #ifndef LLVM_DERIVED_TYPES_H
19 #define LLVM_DERIVED_TYPES_H
20
21 #include "llvm/Type.h"
22 #include "llvm/Support/DataTypes.h"
23
24 namespace llvm {
25
26 class Value;
27 template<class ValType, class TypeClass> class TypeMap;
28 class FunctionValType;
29 class ArrayValType;
30 class StructValType;
31 class PointerValType;
32 class PackedValType;
33
34 class DerivedType : public Type, public AbstractTypeUser {
35   // AbstractTypeUsers - Implement a list of the users that need to be notified
36   // if I am a type, and I get resolved into a more concrete type.
37   //
38   mutable std::vector<AbstractTypeUser *> AbstractTypeUsers;
39   friend class Type;
40
41 protected:
42   DerivedType(TypeID id) : Type("", id) {}
43   ~DerivedType() {
44     assert(AbstractTypeUsers.empty());
45   }
46
47   /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type
48   /// that the current type has transitioned from being abstract to being
49   /// concrete.
50   ///
51   void notifyUsesThatTypeBecameConcrete();
52
53   /// dropAllTypeUses - When this (abstract) type is resolved to be equal to
54   /// another (more concrete) type, we must eliminate all references to other
55   /// types, to avoid some circular reference problems.
56   ///
57   void dropAllTypeUses();
58
59   void RefCountIsZero() const {
60     if (AbstractTypeUsers.empty())
61       delete this;
62   }
63
64   
65 public:
66
67   //===--------------------------------------------------------------------===//
68   // Abstract Type handling methods - These types have special lifetimes, which
69   // are managed by (add|remove)AbstractTypeUser. See comments in
70   // AbstractTypeUser.h for more information.
71
72   /// addAbstractTypeUser - Notify an abstract type that there is a new user of
73   /// it.  This function is called primarily by the PATypeHandle class.
74   ///
75   void addAbstractTypeUser(AbstractTypeUser *U) const {
76     assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
77     AbstractTypeUsers.push_back(U);
78   }
79
80   /// removeAbstractTypeUser - Notify an abstract type that a user of the class
81   /// no longer has a handle to the type.  This function is called primarily by
82   /// the PATypeHandle class.  When there are no users of the abstract type, it
83   /// is annihilated, because there is no way to get a reference to it ever
84   /// again.
85   ///
86   void removeAbstractTypeUser(AbstractTypeUser *U) const;
87
88   /// refineAbstractTypeTo - This function is used to when it is discovered that
89   /// the 'this' abstract type is actually equivalent to the NewType specified.
90   /// This causes all users of 'this' to switch to reference the more concrete
91   /// type NewType and for 'this' to be deleted.
92   ///
93   void refineAbstractTypeTo(const Type *NewType);
94
95   void dump() const { Type::dump(); }
96
97   // Methods for support type inquiry through isa, cast, and dyn_cast:
98   static inline bool classof(const DerivedType *T) { return true; }
99   static inline bool classof(const Type *T) {
100     return T->isDerivedType();
101   }
102 };
103
104
105 /// FunctionType - Class to represent function types
106 ///
107 class FunctionType : public DerivedType {
108   friend class TypeMap<FunctionValType, FunctionType>;
109   bool isVarArgs;
110
111   FunctionType(const FunctionType &);                   // Do not implement
112   const FunctionType &operator=(const FunctionType &);  // Do not implement
113 protected:
114   /// This should really be private, but it squelches a bogus warning
115   /// from GCC to make them protected:  warning: `class FunctionType' only 
116   /// defines private constructors and has no friends
117   ///
118   /// Private ctor - Only can be created by a static member...
119   ///
120   FunctionType(const Type *Result, const std::vector<const Type*> &Params, 
121                bool IsVarArgs);
122
123 public:
124   /// FunctionType::get - This static method is the primary way of constructing
125   /// a FunctionType
126   ///
127   static FunctionType *get(const Type *Result,
128                            const std::vector<const Type*> &Params,
129                            bool isVarArg);
130
131   inline bool isVarArg() const { return isVarArgs; }
132   inline const Type *getReturnType() const { return ContainedTys[0]; }
133
134   typedef std::vector<PATypeHandle>::const_iterator param_iterator;
135   param_iterator param_begin() const { return ContainedTys.begin()+1; }
136   param_iterator param_end() const { return ContainedTys.end(); }
137
138   // Parameter type accessors...
139   const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
140
141   /// getNumParams - Return the number of fixed parameters this function type
142   /// requires.  This does not consider varargs.
143   ///
144   unsigned getNumParams() const { return (unsigned)ContainedTys.size()-1; }
145
146   // Implement the AbstractTypeUser interface.
147   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
148   virtual void typeBecameConcrete(const DerivedType *AbsTy);
149   
150   // Methods for support type inquiry through isa, cast, and dyn_cast:
151   static inline bool classof(const FunctionType *T) { return true; }
152   static inline bool classof(const Type *T) {
153     return T->getTypeID() == FunctionTyID;
154   }
155 };
156
157
158 /// CompositeType - Common super class of ArrayType, StructType, PointerType
159 /// and PackedType
160 class CompositeType : public DerivedType {
161 protected:
162   inline CompositeType(TypeID id) : DerivedType(id) { }
163 public:
164
165   /// getTypeAtIndex - Given an index value into the type, return the type of
166   /// the element.
167   ///
168   virtual const Type *getTypeAtIndex(const Value *V) const = 0;
169   virtual bool indexValid(const Value *V) const = 0;
170
171   // Methods for support type inquiry through isa, cast, and dyn_cast:
172   static inline bool classof(const CompositeType *T) { return true; }
173   static inline bool classof(const Type *T) {
174     return T->getTypeID() == ArrayTyID || 
175            T->getTypeID() == StructTyID ||
176            T->getTypeID() == PointerTyID ||
177            T->getTypeID() == PackedTyID;
178   }
179 };
180
181
182 /// StructType - Class to represent struct types
183 ///
184 class StructType : public CompositeType {
185   friend class TypeMap<StructValType, StructType>;
186   StructType(const StructType &);                   // Do not implement
187   const StructType &operator=(const StructType &);  // Do not implement
188
189 protected:
190   /// This should really be private, but it squelches a bogus warning
191   /// from GCC to make them protected:  warning: `class StructType' only 
192   /// defines private constructors and has no friends
193   ///
194   /// Private ctor - Only can be created by a static member...
195   ///
196   StructType(const std::vector<const Type*> &Types);
197
198 public:
199   /// StructType::get - This static method is the primary way to create a
200   /// StructType.
201   ///
202   static StructType *get(const std::vector<const Type*> &Params);
203
204   // Iterator access to the elements
205   typedef std::vector<PATypeHandle>::const_iterator element_iterator;
206   element_iterator element_begin() const { return ContainedTys.begin(); }
207   element_iterator element_end() const { return ContainedTys.end(); }
208
209   // Random access to the elements
210   unsigned getNumElements() const { return (unsigned)ContainedTys.size(); }
211   const Type *getElementType(unsigned N) const {
212     assert(N < ContainedTys.size() && "Element number out of range!");
213     return ContainedTys[N];
214   }
215
216   /// getTypeAtIndex - Given an index value into the type, return the type of
217   /// the element.  For a structure type, this must be a constant value...
218   ///
219   virtual const Type *getTypeAtIndex(const Value *V) const ;
220   virtual bool indexValid(const Value *V) const;
221
222   // Implement the AbstractTypeUser interface.
223   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
224   virtual void typeBecameConcrete(const DerivedType *AbsTy);
225
226   // Methods for support type inquiry through isa, cast, and dyn_cast:
227   static inline bool classof(const StructType *T) { return true; }
228   static inline bool classof(const Type *T) {
229     return T->getTypeID() == StructTyID;
230   }
231 };
232
233
234 /// SequentialType - This is the superclass of the array, pointer and packed 
235 /// type classes.  All of these represent "arrays" in memory.  The array type
236 /// represents a specifically sized array, pointer types are unsized/unknown
237 /// size arrays, packed types represent specifically sized arrays that 
238 /// allow for use of SIMD instructions.  SequentialType holds the common 
239 /// features of all, which stem from the fact that all three lay their 
240 /// components out in memory identically.
241 ///
242 class SequentialType : public CompositeType {
243   SequentialType(const SequentialType &);                  // Do not implement!
244   const SequentialType &operator=(const SequentialType &); // Do not implement!
245 protected:
246   SequentialType(TypeID TID, const Type *ElType) : CompositeType(TID) {
247     ContainedTys.reserve(1);
248     ContainedTys.push_back(PATypeHandle(ElType, this));
249   }
250
251 public:
252   inline const Type *getElementType() const { return ContainedTys[0]; }
253
254   virtual bool indexValid(const Value *V) const;
255
256   /// getTypeAtIndex - Given an index value into the type, return the type of
257   /// the element.  For sequential types, there is only one subtype...
258   ///
259   virtual const Type *getTypeAtIndex(const Value *V) const {
260     return ContainedTys[0];
261   }
262
263   // Methods for support type inquiry through isa, cast, and dyn_cast:
264   static inline bool classof(const SequentialType *T) { return true; }
265   static inline bool classof(const Type *T) {
266     return T->getTypeID() == ArrayTyID ||
267            T->getTypeID() == PointerTyID ||
268            T->getTypeID() == PackedTyID;
269   }
270 };
271
272
273 /// ArrayType - Class to represent array types
274 ///
275 class ArrayType : public SequentialType {
276   friend class TypeMap<ArrayValType, ArrayType>;
277   uint64_t NumElements;
278
279   ArrayType(const ArrayType &);                   // Do not implement
280   const ArrayType &operator=(const ArrayType &);  // Do not implement
281 protected:
282   /// This should really be private, but it squelches a bogus warning
283   /// from GCC to make them protected:  warning: `class ArrayType' only 
284   /// defines private constructors and has no friends
285   ///
286   /// Private ctor - Only can be created by a static member...
287   ///
288   ArrayType(const Type *ElType, uint64_t NumEl);
289
290 public:
291   /// ArrayType::get - This static method is the primary way to construct an
292   /// ArrayType
293   ///
294   static ArrayType *get(const Type *ElementType, uint64_t NumElements);
295
296   inline uint64_t getNumElements() const { return NumElements; }
297
298   // Implement the AbstractTypeUser interface.
299   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
300   virtual void typeBecameConcrete(const DerivedType *AbsTy);
301
302   // Methods for support type inquiry through isa, cast, and dyn_cast:
303   static inline bool classof(const ArrayType *T) { return true; }
304   static inline bool classof(const Type *T) {
305     return T->getTypeID() == ArrayTyID;
306   }
307 };
308
309 /// PackedType - Class to represent packed types
310 ///
311 class PackedType : public SequentialType {
312   friend class TypeMap<PackedValType, PackedType>;
313   unsigned NumElements;
314
315   PackedType(const PackedType &);                   // Do not implement
316   const PackedType &operator=(const PackedType &);  // Do not implement
317 protected:
318   /// This should really be private, but it squelches a bogus warning
319   /// from GCC to make them protected:  warning: `class PackedType' only 
320   /// defines private constructors and has no friends
321   ///
322   /// Private ctor - Only can be created by a static member...
323   ///
324   PackedType(const Type *ElType, unsigned NumEl);
325
326 public:
327   /// PackedType::get - This static method is the primary way to construct an
328   /// PackedType
329   ///
330   static PackedType *get(const Type *ElementType, unsigned NumElements);
331
332   inline unsigned getNumElements() const { return NumElements; }
333
334   // Implement the AbstractTypeUser interface.
335   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
336   virtual void typeBecameConcrete(const DerivedType *AbsTy);
337
338   // Methods for support type inquiry through isa, cast, and dyn_cast:
339   static inline bool classof(const PackedType *T) { return true; }
340   static inline bool classof(const Type *T) {
341     return T->getTypeID() == PackedTyID;
342   }
343 };
344
345
346 /// PointerType - Class to represent pointers
347 ///
348 class PointerType : public SequentialType {
349   friend class TypeMap<PointerValType, PointerType>;
350   PointerType(const PointerType &);                   // Do not implement
351   const PointerType &operator=(const PointerType &);  // Do not implement
352 protected:
353   // This should really be private, but it squelches a bogus warning
354   // from GCC to make them protected:  warning: `class PointerType' only 
355   // defines private constructors and has no friends
356
357   // Private ctor - Only can be created by a static member...
358   PointerType(const Type *ElType);
359
360 public:
361   /// PointerType::get - This is the only way to construct a new pointer type.
362   static PointerType *get(const Type *ElementType);
363
364   // Implement the AbstractTypeUser interface.
365   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
366   virtual void typeBecameConcrete(const DerivedType *AbsTy);
367
368   // Implement support type inquiry through isa, cast, and dyn_cast:
369   static inline bool classof(const PointerType *T) { return true; }
370   static inline bool classof(const Type *T) {
371     return T->getTypeID() == PointerTyID;
372   }
373 };
374
375
376 /// OpaqueType - Class to represent abstract types
377 ///
378 class OpaqueType : public DerivedType {
379   OpaqueType(const OpaqueType &);                   // DO NOT IMPLEMENT
380   const OpaqueType &operator=(const OpaqueType &);  // DO NOT IMPLEMENT
381 protected:
382   /// This should really be private, but it squelches a bogus warning
383   /// from GCC to make them protected:  warning: `class OpaqueType' only 
384   /// defines private constructors and has no friends
385   ///
386   /// Private ctor - Only can be created by a static member...
387   OpaqueType();
388
389 public:
390   /// OpaqueType::get - Static factory method for the OpaqueType class...
391   ///
392   static OpaqueType *get() {
393     return new OpaqueType();           // All opaque types are distinct
394   }
395
396   // Implement the AbstractTypeUser interface.
397   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
398     abort();   // FIXME: this is not really an AbstractTypeUser!
399   }
400   virtual void typeBecameConcrete(const DerivedType *AbsTy) {
401     abort();   // FIXME: this is not really an AbstractTypeUser!
402   }
403
404   // Implement support for type inquiry through isa, cast, and dyn_cast:
405   static inline bool classof(const OpaqueType *T) { return true; }
406   static inline bool classof(const Type *T) {
407     return T->getTypeID() == OpaqueTyID;
408   }
409 };
410
411 } // End llvm namespace
412
413 #endif