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