Commit more code over to new cast style
[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 class DerivedType : public Type {
17   // AbstractTypeUsers - Implement a list of the users that need to be notified
18   // if I am a type, and I get resolved into a more concrete type.
19   //
20   ///// FIXME: kill mutable nonsense when Type's are not const
21   mutable vector<AbstractTypeUser *> AbstractTypeUsers;
22
23   char isRefining;                                   // Used for recursive types
24
25 protected:
26   inline DerivedType(const string &Name, PrimitiveID id) : Type(Name, id) {
27     isRefining = false;
28   }
29
30   // typeIsRefined - Notify AbstractTypeUsers of this type that the current type
31   // has been refined a bit.  The pointer is still valid and still should be
32   // used, but the subtypes have changed.
33   //
34   void typeIsRefined();
35   
36   // setDerivedTypeProperties - Based on the subtypes, set the name of this
37   // type so that it is printed nicely by the type printer.  Also calculate
38   // whether this type is abstract or not.  Used by the constructor and when
39   // the type is refined.
40   //
41   void setDerivedTypeProperties();
42
43 public:
44
45   //===--------------------------------------------------------------------===//
46   // Abstract Type handling methods - These types have special lifetimes, which
47   // are managed by (add|remove)AbstractTypeUser. See comments in
48   // AbstractTypeUser.h for more information.
49
50   // addAbstractTypeUser - Notify an abstract type that there is a new user of
51   // it.  This function is called primarily by the PATypeHandle class.
52   //
53   void addAbstractTypeUser(AbstractTypeUser *U) const {
54     assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
55 #if 0
56     cerr << "  addAbstractTypeUser[" << (void*)this << ", " << getDescription() 
57          << "][" << AbstractTypeUsers.size() << "] User = " << U << endl;
58 #endif
59     AbstractTypeUsers.push_back(U);
60   }
61
62   // removeAbstractTypeUser - Notify an abstract type that a user of the class
63   // no longer has a handle to the type.  This function is called primarily by
64   // the PATypeHandle class.  When there are no users of the abstract type, it
65   // is anihilated, because there is no way to get a reference to it ever again.
66   //
67   void removeAbstractTypeUser(AbstractTypeUser *U) const;
68
69   // getNumAbstractTypeUsers - Return the number of users registered to the type
70   inline unsigned getNumAbstractTypeUsers() const {
71     assert(isAbstract() && "getNumAbstractTypeUsers: Type not abstract!");
72     return AbstractTypeUsers.size(); 
73   }
74
75   // refineAbstractTypeTo - This function is used to when it is discovered that
76   // the 'this' abstract type is actually equivalent to the NewType specified.
77   // This causes all users of 'this' to switch to reference the more concrete
78   // type NewType and for 'this' to be deleted.
79   //
80   void refineAbstractTypeTo(const Type *NewType);
81
82   // Methods for support type inquiry through isa, cast, and dyn_cast:
83   static inline bool classof(const DerivedType *T) { return true; }
84   static inline bool classof(const Type *T) {
85     return T->isDerivedType();
86   }
87   static inline bool classof(const Value *V) {
88     return isa<Type>(V) && classof(cast<const Type>(V));
89   }
90 };
91
92
93
94
95 class MethodType : public DerivedType {
96 public:
97   typedef vector<PATypeHandle<Type> > ParamTypes;
98 private:
99   PATypeHandle<Type> ResultType;
100   ParamTypes ParamTys;
101   bool isVarArgs;
102
103   MethodType(const MethodType &);                   // Do not implement
104   const MethodType &operator=(const MethodType &);  // Do not implement
105 protected:
106   // This should really be private, but it squelches a bogus warning
107   // from GCC to make them protected:  warning: `class MethodType' only 
108   // defines private constructors and has no friends
109
110   // Private ctor - Only can be created by a static member...
111   MethodType(const Type *Result, const vector<const Type*> &Params, 
112              bool IsVarArgs);
113
114 public:
115
116   inline bool isVarArg() const { return isVarArgs; }
117   inline const Type *getReturnType() const { return ResultType; }
118   inline const ParamTypes &getParamTypes() const { return ParamTys; }
119
120
121   virtual const Type *getContainedType(unsigned i) const {
122     return i == 0 ? ResultType : (i <= ParamTys.size() ? ParamTys[i-1] : 0);
123   }
124   virtual unsigned getNumContainedTypes() const { return ParamTys.size()+1; }
125
126   // refineAbstractType - Called when a contained type is found to be more
127   // concrete - this could potentially change us from an abstract type to a
128   // concrete type.
129   //
130   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
131
132   static MethodType *get(const Type *Result, const vector<const Type*> &Params);
133
134
135   // Methods for support type inquiry through isa, cast, and dyn_cast:
136   static inline bool classof(const MethodType *T) { return true; }
137   static inline bool classof(const Type *T) {
138     return T->getPrimitiveID() == MethodTyID;
139   }
140   static inline bool classof(const Value *V) {
141     return isa<Type>(V) && classof(cast<const Type>(V));
142   }
143 };
144
145
146 class ArrayType : public DerivedType {
147 private:
148   PATypeHandle<Type> ElementType;
149   int NumElements;       // >= 0 for sized array, -1 for unbounded/unknown array
150
151   ArrayType(const ArrayType &);                   // Do not implement
152   const ArrayType &operator=(const ArrayType &);  // Do not implement
153 protected:
154   // This should really be private, but it squelches a bogus warning
155   // from GCC to make them protected:  warning: `class ArrayType' only 
156   // defines private constructors and has no friends
157
158
159   // Private ctor - Only can be created by a static member...
160   ArrayType(const Type *ElType, int NumEl);
161
162 public:
163
164   inline const Type *getElementType() const { return ElementType; }
165   inline int         getNumElements() const { return NumElements; }
166
167   inline bool isSized()   const { return NumElements >= 0; }
168   inline bool isUnsized() const { return NumElements == -1; }
169
170   virtual const Type *getContainedType(unsigned i) const { 
171     return i == 0 ? ElementType : 0;
172   }
173   virtual unsigned getNumContainedTypes() const { return 1; }
174
175   // refineAbstractType - Called when a contained type is found to be more
176   // concrete - this could potentially change us from an abstract type to a
177   // concrete type.
178   //
179   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
180
181   static ArrayType *get(const Type *ElementType, int NumElements = -1);
182
183   // Methods for support type inquiry through isa, cast, and dyn_cast:
184   static inline bool classof(const ArrayType *T) { return true; }
185   static inline bool classof(const Type *T) {
186     return T->getPrimitiveID() == ArrayTyID;
187   }
188   static inline bool classof(const Value *V) {
189     return isa<Type>(V) && classof(cast<const Type>(V));
190   }
191 };
192
193
194 class StructType : public DerivedType {
195 public:
196   typedef vector<PATypeHandle<Type> > ElementTypes;
197
198 private:
199   ElementTypes ETypes;                              // Element types of struct
200
201   StructType(const StructType &);                   // Do not implement
202   const StructType &operator=(const StructType &);  // Do not implement
203
204 protected:
205   // This should really be private, but it squelches a bogus warning
206   // from GCC to make them protected:  warning: `class StructType' only 
207   // defines private constructors and has no friends
208
209   // Private ctor - Only can be created by a static member...
210   StructType(const vector<const Type*> &Types);
211   
212 public:
213   inline const ElementTypes &getElementTypes() const { return ETypes; }
214
215   virtual const Type *getContainedType(unsigned i) const { 
216     return i < ETypes.size() ? ETypes[i] : 0;
217   }
218   virtual unsigned getNumContainedTypes() const { return ETypes.size(); }
219
220   // refineAbstractType - Called when a contained type is found to be more
221   // concrete - this could potentially change us from an abstract type to a
222   // concrete type.
223   //
224   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
225
226   static StructType *get(const vector<const Type*> &Params);
227
228   // Methods for support type inquiry through isa, cast, and dyn_cast:
229   static inline bool classof(const StructType *T) { return true; }
230   static inline bool classof(const Type *T) {
231     return T->getPrimitiveID() == StructTyID;
232   }
233   static inline bool classof(const Value *V) {
234     return isa<Type>(V) && classof(cast<const Type>(V));
235   }
236 };
237
238
239 class PointerType : public DerivedType {
240 private:
241   PATypeHandle<Type> ValueType;
242
243   PointerType(const PointerType &);                   // Do not implement
244   const PointerType &operator=(const PointerType &);  // Do not implement
245 protected:
246   // This should really be private, but it squelches a bogus warning
247   // from GCC to make them protected:  warning: `class PointerType' only 
248   // defines private constructors and has no friends
249
250
251   // Private ctor - Only can be created by a static member...
252   PointerType(const Type *ElType);
253
254 public:
255
256   inline const Type *getValueType() const { return ValueType; }
257
258   virtual const Type *getContainedType(unsigned i) const { 
259     return i == 0 ? ValueType : 0;
260   }
261   virtual unsigned getNumContainedTypes() const { return 1; }
262
263   static PointerType *get(const Type *ElementType);
264
265   // refineAbstractType - Called when a contained type is found to be more
266   // concrete - this could potentially change us from an abstract type to a
267   // concrete type.
268   //
269   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
270
271   // Methods for support type inquiry through isa, cast, and dyn_cast:
272   static inline bool classof(const PointerType *T) { return true; }
273   static inline bool classof(const Type *T) {
274     return T->getPrimitiveID() == PointerTyID;
275   }
276   static inline bool classof(const Value *V) {
277     return isa<Type>(V) && classof(cast<const Type>(V));
278   }
279 };
280
281
282 class OpaqueType : public DerivedType {
283 private:
284   OpaqueType(const OpaqueType &);                   // Do not implement
285   const OpaqueType &operator=(const OpaqueType &);  // Do not implement
286 protected:
287   // This should really be private, but it squelches a bogus warning
288   // from GCC to make them protected:  warning: `class OpaqueType' only 
289   // defines private constructors and has no friends
290
291   // Private ctor - Only can be created by a static member...
292   OpaqueType();
293
294 public:
295
296   // get - Static factory method for the OpaqueType class...
297   static OpaqueType *get() {
298     return new OpaqueType();           // All opaque types are distinct
299   }
300
301   // Methods for support type inquiry through isa, cast, and dyn_cast:
302   static inline bool classof(const OpaqueType *T) { return true; }
303   static inline bool classof(const Type *T) {
304     return T->getPrimitiveID() == OpaqueTyID;
305   }
306   static inline bool classof(const Value *V) {
307     return isa<Type>(V) && classof(cast<const Type>(V));
308   }
309 };
310
311
312 // Define some inline methods for the AbstractTypeUser.h:PATypeHandle class.
313 // These are defined here because they MUST be inlined, yet are dependant on 
314 // the definition of the Type class.  Of course Type derives from Value, which
315 // contains an AbstractTypeUser instance, so there is no good way to factor out
316 // the code.  Hence this bit of uglyness.
317 //
318 template <class TypeSubClass> void PATypeHandle<TypeSubClass>::addUser() {
319   if (Ty->isAbstract())
320     cast<DerivedType>(Ty)->addAbstractTypeUser(User);
321 }
322 template <class TypeSubClass> void PATypeHandle<TypeSubClass>::removeUser() {
323   if (Ty->isAbstract())
324     cast<DerivedType>(Ty)->removeAbstractTypeUser(User);
325 }
326
327 #endif