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