For PR1043:
[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 class IntegerValType;
33
34 class DerivedType : public Type {
35   friend class Type;
36
37 protected:
38   DerivedType(TypeID id) : Type(id) {}
39
40   /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type
41   /// that the current type has transitioned from being abstract to being
42   /// concrete.
43   ///
44   void notifyUsesThatTypeBecameConcrete();
45
46   /// dropAllTypeUses - When this (abstract) type is resolved to be equal to
47   /// another (more concrete) type, we must eliminate all references to other
48   /// types, to avoid some circular reference problems.
49   ///
50   void dropAllTypeUses();
51
52 public:
53
54   //===--------------------------------------------------------------------===//
55   // Abstract Type handling methods - These types have special lifetimes, which
56   // are managed by (add|remove)AbstractTypeUser. See comments in
57   // AbstractTypeUser.h for more information.
58
59   /// refineAbstractTypeTo - This function is used to when it is discovered that
60   /// the 'this' abstract type is actually equivalent to the NewType specified.
61   /// This causes all users of 'this' to switch to reference the more concrete
62   /// type NewType and for 'this' to be deleted.
63   ///
64   void refineAbstractTypeTo(const Type *NewType);
65
66   void dump() const { Type::dump(); }
67
68   // Methods for support type inquiry through isa, cast, and dyn_cast:
69   static inline bool classof(const DerivedType *T) { return true; }
70   static inline bool classof(const Type *T) {
71     return T->isDerivedType();
72   }
73 };
74
75 /// Class to represent integer types. Note that this class is also used to
76 /// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
77 /// Int64Ty. 
78 /// @brief Integer representation type
79 class IntegerType : public DerivedType {
80 protected:
81   IntegerType(unsigned NumBits) : DerivedType(IntegerTyID) {
82     setSubclassData(NumBits);
83   }
84   friend class TypeMap<IntegerValType, IntegerType>;
85 public:
86   /// This enum is just used to hold constants we need for IntegerType.
87   enum {
88     MIN_INT_BITS = 1,        ///< Minimum number of bits that can be specified
89     MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified
90       ///< Note that bit width is stored in the Type classes SubclassData field
91       ///< which has 23 bits. This yields a maximum bit width of 8,388,607 bits.
92   };
93
94   /// This static method is the primary way of constructing an IntegerType. 
95   /// If an IntegerType with the same NumBits value was previously instantiated,
96   /// that instance will be returned. Otherwise a new one will be created. Only
97   /// one instance with a given NumBits value is ever created.
98   /// @brief Get or create an IntegerType instance.
99   static const IntegerType* get(unsigned NumBits);
100
101   /// @brief Get the number of bits in this IntegerType
102   unsigned getBitWidth() const { return getSubclassData(); }
103
104   /// getBitMask - Return a bitmask with ones set for all of the bits
105   /// that can be set by an unsigned version of this type.  This is 0xFF for
106   /// sbyte/ubyte, 0xFFFF for shorts, etc.
107   uint64_t getBitMask() const {
108     return ~uint64_t(0UL) >> (64-getPrimitiveSizeInBits());
109   }
110
111   /// This method determines if the width of this IntegerType is a power-of-2
112   /// in terms of 8 bit bytes. 
113   /// @returns true if this is a power-of-2 byte width.
114   /// @brief Is this a power-of-2 byte-width IntegerType ?
115   bool isPowerOf2ByteWidth() const;
116
117   // Methods for support type inquiry through isa, cast, and dyn_cast:
118   static inline bool classof(const IntegerType *T) { return true; }
119   static inline bool classof(const Type *T) {
120     return T->getTypeID() == IntegerTyID;
121   }
122 };
123
124
125 /// FunctionType - Class to represent function types
126 ///
127 class FunctionType : public DerivedType {
128 public:
129   /// Function parameters can have attributes to indicate how they should be
130   /// treated by optimizations and code generation. This enumeration lists the
131   /// set of possible attributes.
132   /// @brief Function parameter attributes enumeration.
133   enum ParameterAttributes {
134     NoAttributeSet    = 0,      ///< No attribute value has been set 
135     ZExtAttribute     = 1,      ///< zero extended before/after call
136     SExtAttribute     = 1 << 1, ///< sign extended before/after call
137     NoReturnAttribute = 1 << 2  ///< mark the function as not returning
138   };
139   typedef std::vector<ParameterAttributes> ParamAttrsList;
140 private:
141   friend class TypeMap<FunctionValType, FunctionType>;
142   bool isVarArgs;
143   ParamAttrsList *ParamAttrs;
144
145   FunctionType(const FunctionType &);                   // Do not implement
146   const FunctionType &operator=(const FunctionType &);  // Do not implement
147   FunctionType(const Type *Result, const std::vector<const Type*> &Params,
148                bool IsVarArgs, const ParamAttrsList &Attrs);
149
150 public:
151   /// FunctionType::get - This static method is the primary way of constructing
152   /// a FunctionType. 
153   ///
154   static FunctionType *get(
155     const Type *Result, ///< The result type
156     const std::vector<const Type*> &Params, ///< The types of the parameters
157     bool isVarArg, ///< Whether this is a variable argument length function
158     const ParamAttrsList & Attrs = ParamAttrsList()
159       ///< Indicates the parameter attributes to use, if any. The 0th entry
160       ///< in the list refers to the return type. Parameters are numbered
161       ///< starting at 1. 
162   );
163
164   inline bool isVarArg() const { return isVarArgs; }
165   inline const Type *getReturnType() const { return ContainedTys[0]; }
166
167   typedef std::vector<PATypeHandle>::const_iterator param_iterator;
168   param_iterator param_begin() const { return ContainedTys.begin()+1; }
169   param_iterator param_end() const { return ContainedTys.end(); }
170
171   // Parameter type accessors...
172   const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
173
174   /// getNumParams - Return the number of fixed parameters this function type
175   /// requires.  This does not consider varargs.
176   ///
177   unsigned getNumParams() const { return unsigned(ContainedTys.size()-1); }
178
179   /// The parameter attributes for the \p ith parameter are returned. The 0th
180   /// parameter refers to the return type of the function.
181   /// @returns The ParameterAttributes for the \p ith parameter.
182   /// @brief Get the attributes for a parameter
183   ParameterAttributes getParamAttrs(unsigned i) const;
184
185   /// @brief Determine if a parameter attribute is set
186   bool paramHasAttr(unsigned i, ParameterAttributes attr) const {
187     return getParamAttrs(i) & attr;
188   }
189
190   /// @brief Return the number of parameter attributes this type has.
191   unsigned getNumAttrs() const { 
192     return (ParamAttrs ?  unsigned(ParamAttrs->size()) : 0);
193   }
194
195   /// @brief Convert a ParameterAttribute into its assembly text
196   static std::string getParamAttrsText(ParameterAttributes Attr);
197
198   // Implement the AbstractTypeUser interface.
199   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
200   virtual void typeBecameConcrete(const DerivedType *AbsTy);
201
202   // Methods for support type inquiry through isa, cast, and dyn_cast:
203   static inline bool classof(const FunctionType *T) { return true; }
204   static inline bool classof(const Type *T) {
205     return T->getTypeID() == FunctionTyID;
206   }
207 };
208
209
210 /// CompositeType - Common super class of ArrayType, StructType, PointerType
211 /// and PackedType
212 class CompositeType : public DerivedType {
213 protected:
214   inline CompositeType(TypeID id) : DerivedType(id) { }
215 public:
216
217   /// getTypeAtIndex - Given an index value into the type, return the type of
218   /// the element.
219   ///
220   virtual const Type *getTypeAtIndex(const Value *V) const = 0;
221   virtual bool indexValid(const Value *V) const = 0;
222
223   // Methods for support type inquiry through isa, cast, and dyn_cast:
224   static inline bool classof(const CompositeType *T) { return true; }
225   static inline bool classof(const Type *T) {
226     return T->getTypeID() == ArrayTyID ||
227            T->getTypeID() == StructTyID ||
228            T->getTypeID() == PointerTyID ||
229            T->getTypeID() == PackedTyID;
230   }
231 };
232
233
234 /// StructType - Class to represent struct types
235 ///
236 class StructType : public CompositeType {
237   friend class TypeMap<StructValType, StructType>;
238   StructType(const StructType &);                   // Do not implement
239   const StructType &operator=(const StructType &);  // Do not implement
240   StructType(const std::vector<const Type*> &Types, bool isPacked);
241 public:
242   /// StructType::get - This static method is the primary way to create a
243   /// StructType.
244   ///
245   static StructType *get(const std::vector<const Type*> &Params, 
246                          bool isPacked=false);
247
248   // Iterator access to the elements
249   typedef std::vector<PATypeHandle>::const_iterator element_iterator;
250   element_iterator element_begin() const { return ContainedTys.begin(); }
251   element_iterator element_end() const { return ContainedTys.end(); }
252
253   // Random access to the elements
254   unsigned getNumElements() const { return unsigned(ContainedTys.size()); }
255   const Type *getElementType(unsigned N) const {
256     assert(N < ContainedTys.size() && "Element number out of range!");
257     return ContainedTys[N];
258   }
259
260   /// getTypeAtIndex - Given an index value into the type, return the type of
261   /// the element.  For a structure type, this must be a constant value...
262   ///
263   virtual const Type *getTypeAtIndex(const Value *V) const ;
264   virtual bool indexValid(const Value *V) const;
265
266   // Implement the AbstractTypeUser interface.
267   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
268   virtual void typeBecameConcrete(const DerivedType *AbsTy);
269
270   // Methods for support type inquiry through isa, cast, and dyn_cast:
271   static inline bool classof(const StructType *T) { return true; }
272   static inline bool classof(const Type *T) {
273     return T->getTypeID() == StructTyID;
274   }
275
276   bool isPacked() const { return getSubclassData(); }
277 };
278
279
280 /// SequentialType - This is the superclass of the array, pointer and packed
281 /// type classes.  All of these represent "arrays" in memory.  The array type
282 /// represents a specifically sized array, pointer types are unsized/unknown
283 /// size arrays, packed types represent specifically sized arrays that
284 /// allow for use of SIMD instructions.  SequentialType holds the common
285 /// features of all, which stem from the fact that all three lay their
286 /// components out in memory identically.
287 ///
288 class SequentialType : public CompositeType {
289   SequentialType(const SequentialType &);                  // Do not implement!
290   const SequentialType &operator=(const SequentialType &); // Do not implement!
291 protected:
292   SequentialType(TypeID TID, const Type *ElType) : CompositeType(TID) {
293     ContainedTys.reserve(1);
294     ContainedTys.push_back(PATypeHandle(ElType, this));
295   }
296
297 public:
298   inline const Type *getElementType() const { return ContainedTys[0]; }
299
300   virtual bool indexValid(const Value *V) const;
301
302   /// getTypeAtIndex - Given an index value into the type, return the type of
303   /// the element.  For sequential types, there is only one subtype...
304   ///
305   virtual const Type *getTypeAtIndex(const Value *V) const {
306     return ContainedTys[0];
307   }
308
309   // Methods for support type inquiry through isa, cast, and dyn_cast:
310   static inline bool classof(const SequentialType *T) { return true; }
311   static inline bool classof(const Type *T) {
312     return T->getTypeID() == ArrayTyID ||
313            T->getTypeID() == PointerTyID ||
314            T->getTypeID() == PackedTyID;
315   }
316 };
317
318
319 /// ArrayType - Class to represent array types
320 ///
321 class ArrayType : public SequentialType {
322   friend class TypeMap<ArrayValType, ArrayType>;
323   uint64_t NumElements;
324
325   ArrayType(const ArrayType &);                   // Do not implement
326   const ArrayType &operator=(const ArrayType &);  // Do not implement
327   ArrayType(const Type *ElType, uint64_t NumEl);
328 public:
329   /// ArrayType::get - This static method is the primary way to construct an
330   /// ArrayType
331   ///
332   static ArrayType *get(const Type *ElementType, uint64_t NumElements);
333
334   inline uint64_t getNumElements() const { return NumElements; }
335
336   // Implement the AbstractTypeUser interface.
337   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
338   virtual void typeBecameConcrete(const DerivedType *AbsTy);
339
340   // Methods for support type inquiry through isa, cast, and dyn_cast:
341   static inline bool classof(const ArrayType *T) { return true; }
342   static inline bool classof(const Type *T) {
343     return T->getTypeID() == ArrayTyID;
344   }
345 };
346
347 /// PackedType - Class to represent packed types
348 ///
349 class PackedType : public SequentialType {
350   friend class TypeMap<PackedValType, PackedType>;
351   unsigned NumElements;
352
353   PackedType(const PackedType &);                   // Do not implement
354   const PackedType &operator=(const PackedType &);  // Do not implement
355   PackedType(const Type *ElType, unsigned NumEl);
356 public:
357   /// PackedType::get - This static method is the primary way to construct an
358   /// PackedType
359   ///
360   static PackedType *get(const Type *ElementType, unsigned NumElements);
361
362   /// @brief Return the number of elements in the Packed type.
363   inline unsigned getNumElements() const { return NumElements; }
364
365   /// @brief Return the number of bits in the Packed type.
366   inline unsigned getBitWidth() const { 
367     return NumElements *getElementType()->getPrimitiveSizeInBits();
368   }
369
370   // Implement the AbstractTypeUser interface.
371   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
372   virtual void typeBecameConcrete(const DerivedType *AbsTy);
373
374   // Methods for support type inquiry through isa, cast, and dyn_cast:
375   static inline bool classof(const PackedType *T) { return true; }
376   static inline bool classof(const Type *T) {
377     return T->getTypeID() == PackedTyID;
378   }
379 };
380
381
382 /// PointerType - Class to represent pointers
383 ///
384 class PointerType : public SequentialType {
385   friend class TypeMap<PointerValType, PointerType>;
386   PointerType(const PointerType &);                   // Do not implement
387   const PointerType &operator=(const PointerType &);  // Do not implement
388   PointerType(const Type *ElType);
389 public:
390   /// PointerType::get - This is the only way to construct a new pointer type.
391   static PointerType *get(const Type *ElementType);
392
393   // Implement the AbstractTypeUser interface.
394   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
395   virtual void typeBecameConcrete(const DerivedType *AbsTy);
396
397   // Implement support type inquiry through isa, cast, and dyn_cast:
398   static inline bool classof(const PointerType *T) { return true; }
399   static inline bool classof(const Type *T) {
400     return T->getTypeID() == PointerTyID;
401   }
402 };
403
404
405 /// OpaqueType - Class to represent abstract types
406 ///
407 class OpaqueType : public DerivedType {
408   OpaqueType(const OpaqueType &);                   // DO NOT IMPLEMENT
409   const OpaqueType &operator=(const OpaqueType &);  // DO NOT IMPLEMENT
410   OpaqueType();
411 public:
412   /// OpaqueType::get - Static factory method for the OpaqueType class...
413   ///
414   static OpaqueType *get() {
415     return new OpaqueType();           // All opaque types are distinct
416   }
417
418   // Implement the AbstractTypeUser interface.
419   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
420     abort();   // FIXME: this is not really an AbstractTypeUser!
421   }
422   virtual void typeBecameConcrete(const DerivedType *AbsTy) {
423     abort();   // FIXME: this is not really an AbstractTypeUser!
424   }
425
426   // Implement support for type inquiry through isa, cast, and dyn_cast:
427   static inline bool classof(const OpaqueType *T) { return true; }
428   static inline bool classof(const Type *T) {
429     return T->getTypeID() == OpaqueTyID;
430   }
431 };
432
433 } // End llvm namespace
434
435 #endif