1 //===-- llvm/DerivedTypes.h - Classes for handling data types ----*- C++ -*--=//
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...
7 // The implementations of these classes live in the Type.cpp file.
9 //===----------------------------------------------------------------------===//
11 #ifndef LLVM_DERIVED_TYPES_H
12 #define LLVM_DERIVED_TYPES_H
14 #include "llvm/Type.h"
16 template<class ValType, class TypeClass> class TypeMap;
17 class FunctionValType;
22 class DerivedType : public Type {
23 char isRefining; // Used for recursive types
25 // AbstractTypeUsers - Implement a list of the users that need to be notified
26 // if I am a type, and I get resolved into a more concrete type.
28 ///// FIXME: kill mutable nonsense when Type's are not const
29 mutable std::vector<AbstractTypeUser *> AbstractTypeUsers;
32 inline DerivedType(PrimitiveID id) : Type("", id) {
36 assert(AbstractTypeUsers.empty());
39 // typeIsRefined - Notify AbstractTypeUsers of this type that the current type
40 // has been refined a bit. The pointer is still valid and still should be
41 // used, but the subtypes have changed.
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. This also removes the
48 // type from the internal tables of available types.
49 virtual void dropAllTypeUses(bool inMap) = 0;
52 void refineAbstractTypeToInternal(const Type *NewType, bool inMap);
56 //===--------------------------------------------------------------------===//
57 // Abstract Type handling methods - These types have special lifetimes, which
58 // are managed by (add|remove)AbstractTypeUser. See comments in
59 // AbstractTypeUser.h for more information.
61 // addAbstractTypeUser - Notify an abstract type that there is a new user of
62 // it. This function is called primarily by the PATypeHandle class.
64 void addAbstractTypeUser(AbstractTypeUser *U) const;
66 // removeAbstractTypeUser - Notify an abstract type that a user of the class
67 // no longer has a handle to the type. This function is called primarily by
68 // the PATypeHandle class. When there are no users of the abstract type, it
69 // is annihilated, because there is no way to get a reference to it ever
72 void removeAbstractTypeUser(AbstractTypeUser *U) const;
74 // refineAbstractTypeTo - This function is used to when it is discovered that
75 // the 'this' abstract type is actually equivalent to the NewType specified.
76 // This causes all users of 'this' to switch to reference the more concrete
77 // type NewType and for 'this' to be deleted.
79 void refineAbstractTypeTo(const Type *NewType) {
80 refineAbstractTypeToInternal(NewType, true);
83 // Methods for support type inquiry through isa, cast, and dyn_cast:
84 static inline bool classof(const DerivedType *T) { return true; }
85 static inline bool classof(const Type *T) {
86 return T->isDerivedType();
88 static inline bool classof(const Value *V) {
89 return isa<Type>(V) && classof(cast<Type>(V));
96 struct FunctionType : public DerivedType {
97 typedef std::vector<PATypeHandle> ParamTypes;
98 friend class TypeMap<FunctionValType, FunctionType>;
100 PATypeHandle ResultType;
104 FunctionType(const FunctionType &); // Do not implement
105 const FunctionType &operator=(const FunctionType &); // Do not implement
107 // This should really be private, but it squelches a bogus warning
108 // from GCC to make them protected: warning: `class FunctionType' only
109 // defines private constructors and has no friends
111 // Private ctor - Only can be created by a static member...
112 FunctionType(const Type *Result, const std::vector<const Type*> &Params,
115 // dropAllTypeUses - When this (abstract) type is resolved to be equal to
116 // another (more concrete) type, we must eliminate all references to other
117 // types, to avoid some circular reference problems. This also removes the
118 // type from the internal tables of available types.
119 virtual void dropAllTypeUses(bool inMap);
123 inline bool isVarArg() const { return isVarArgs; }
124 inline const Type *getReturnType() const { return ResultType; }
125 inline const ParamTypes &getParamTypes() const { return ParamTys; }
127 // Parameter type accessors...
128 const Type *getParamType(unsigned i) const { return ParamTys[i]; }
130 // getNumParams - Return the number of fixed parameters this function type
131 // requires. This does not consider varargs.
133 unsigned getNumParams() const { return ParamTys.size(); }
136 virtual const Type *getContainedType(unsigned i) const {
137 return i == 0 ? ResultType :
138 (i <= ParamTys.size() ? ParamTys[i-1].get() : 0);
140 virtual unsigned getNumContainedTypes() const { return ParamTys.size()+1; }
142 // refineAbstractType - Called when a contained type is found to be more
143 // concrete - this could potentially change us from an abstract type to a
146 virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
148 static FunctionType *get(const Type *Result,
149 const std::vector<const Type*> &Params,
153 // Methods for support type inquiry through isa, cast, and dyn_cast:
154 static inline bool classof(const FunctionType *T) { return true; }
155 static inline bool classof(const Type *T) {
156 return T->getPrimitiveID() == FunctionTyID;
158 static inline bool classof(const Value *V) {
159 return isa<Type>(V) && classof(cast<Type>(V));
164 // CompositeType - Common super class of ArrayType, StructType, and PointerType
166 class CompositeType : public DerivedType {
168 inline CompositeType(PrimitiveID id) : DerivedType(id) { }
171 // getTypeAtIndex - Given an index value into the type, return the type of the
174 virtual const Type *getTypeAtIndex(const Value *V) const = 0;
175 virtual bool indexValid(const Value *V) const = 0;
177 // getIndexType - Return the type required of indices for this composite.
178 // For structures, this is ubyte, for arrays, this is uint
180 virtual const Type *getIndexType() const = 0;
183 // Methods for support type inquiry through isa, cast, and dyn_cast:
184 static inline bool classof(const CompositeType *T) { return true; }
185 static inline bool classof(const Type *T) {
186 return T->getPrimitiveID() == ArrayTyID ||
187 T->getPrimitiveID() == StructTyID ||
188 T->getPrimitiveID() == PointerTyID;
190 static inline bool classof(const Value *V) {
191 return isa<Type>(V) && classof(cast<Type>(V));
196 struct StructType : public CompositeType {
197 friend class TypeMap<StructValType, StructType>;
198 typedef std::vector<PATypeHandle> ElementTypes;
201 ElementTypes ETypes; // Element types of struct
203 StructType(const StructType &); // Do not implement
204 const StructType &operator=(const StructType &); // Do not implement
207 // This should really be private, but it squelches a bogus warning
208 // from GCC to make them protected: warning: `class StructType' only
209 // defines private constructors and has no friends
211 // Private ctor - Only can be created by a static member...
212 StructType(const std::vector<const Type*> &Types);
214 // dropAllTypeUses - When this (abstract) type is resolved to be equal to
215 // another (more concrete) type, we must eliminate all references to other
216 // types, to avoid some circular reference problems. This also removes the
217 // type from the internal tables of available types.
218 virtual void dropAllTypeUses(bool inMap);
221 inline const ElementTypes &getElementTypes() const { return ETypes; }
223 virtual const Type *getContainedType(unsigned i) const {
224 return i < ETypes.size() ? ETypes[i].get() : 0;
226 virtual unsigned getNumContainedTypes() const { return ETypes.size(); }
228 // getTypeAtIndex - Given an index value into the type, return the type of the
229 // element. For a structure type, this must be a constant value...
231 virtual const Type *getTypeAtIndex(const Value *V) const ;
232 virtual bool indexValid(const Value *V) const;
234 // getIndexType - Return the type required of indices for this composite.
235 // For structures, this is ubyte, for arrays, this is uint
237 virtual const Type *getIndexType() const { return Type::UByteTy; }
239 // refineAbstractType - Called when a contained type is found to be more
240 // concrete - this could potentially change us from an abstract type to a
243 virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
245 static StructType *get(const std::vector<const Type*> &Params);
247 // Methods for support type inquiry through isa, cast, and dyn_cast:
248 static inline bool classof(const StructType *T) { return true; }
249 static inline bool classof(const Type *T) {
250 return T->getPrimitiveID() == StructTyID;
252 static inline bool classof(const Value *V) {
253 return isa<Type>(V) && classof(cast<Type>(V));
258 // SequentialType - This is the superclass of the array and pointer type
259 // classes. Both of these represent "arrays" in memory. The array type
260 // represents a specifically sized array, pointer types are unsized/unknown size
261 // arrays. SequentialType holds the common features of both, which stem from
262 // the fact that both lay their components out in memory identically.
264 class SequentialType : public CompositeType {
265 SequentialType(const SequentialType &); // Do not implement!
266 const SequentialType &operator=(const SequentialType &); // Do not implement!
268 PATypeHandle ElementType;
270 SequentialType(PrimitiveID TID, const Type *ElType)
271 : CompositeType(TID), ElementType(PATypeHandle(ElType, this)) {
275 inline const Type *getElementType() const { return ElementType; }
277 virtual const Type *getContainedType(unsigned i) const {
278 return i == 0 ? ElementType.get() : 0;
280 virtual unsigned getNumContainedTypes() const { return 1; }
282 // getTypeAtIndex - Given an index value into the type, return the type of the
283 // element. For sequential types, there is only one subtype...
285 virtual const Type *getTypeAtIndex(const Value *V) const {
286 return ElementType.get();
288 virtual bool indexValid(const Value *V) const {
289 return V->getType() == Type::LongTy; // Must be a 'long' index
292 // getIndexType() - Return the type required of indices for this composite.
293 // For structures, this is ubyte, for arrays, this is uint
295 virtual const Type *getIndexType() const { return Type::LongTy; }
297 // Methods for support type inquiry through isa, cast, and dyn_cast:
298 static inline bool classof(const SequentialType *T) { return true; }
299 static inline bool classof(const Type *T) {
300 return T->getPrimitiveID() == ArrayTyID ||
301 T->getPrimitiveID() == PointerTyID;
303 static inline bool classof(const Value *V) {
304 return isa<Type>(V) && classof(cast<Type>(V));
309 class ArrayType : public SequentialType {
310 friend class TypeMap<ArrayValType, ArrayType>;
311 unsigned NumElements;
313 ArrayType(const ArrayType &); // Do not implement
314 const ArrayType &operator=(const ArrayType &); // Do not implement
316 // This should really be private, but it squelches a bogus warning
317 // from GCC to make them protected: warning: `class ArrayType' only
318 // defines private constructors and has no friends
320 // Private ctor - Only can be created by a static member...
321 ArrayType(const Type *ElType, unsigned NumEl);
323 // dropAllTypeUses - When this (abstract) type is resolved to be equal to
324 // another (more concrete) type, we must eliminate all references to other
325 // types, to avoid some circular reference problems. This also removes the
326 // type from the internal tables of available types.
327 virtual void dropAllTypeUses(bool inMap);
330 inline unsigned getNumElements() const { return NumElements; }
332 // refineAbstractType - Called when a contained type is found to be more
333 // concrete - this could potentially change us from an abstract type to a
336 virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
338 static ArrayType *get(const Type *ElementType, unsigned NumElements);
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->getPrimitiveID() == ArrayTyID;
345 static inline bool classof(const Value *V) {
346 return isa<Type>(V) && classof(cast<Type>(V));
352 class PointerType : public SequentialType {
353 friend class TypeMap<PointerValType, PointerType>;
354 PointerType(const PointerType &); // Do not implement
355 const PointerType &operator=(const PointerType &); // Do not implement
357 // This should really be private, but it squelches a bogus warning
358 // from GCC to make them protected: warning: `class PointerType' only
359 // defines private constructors and has no friends
361 // Private ctor - Only can be created by a static member...
362 PointerType(const Type *ElType);
364 // dropAllTypeUses - When this (abstract) type is resolved to be equal to
365 // another (more concrete) type, we must eliminate all references to other
366 // types, to avoid some circular reference problems. This also removes the
367 // type from the internal tables of available types.
368 virtual void dropAllTypeUses(bool inMap);
370 // PointerType::get - Named constructor for pointer types...
371 static PointerType *get(const Type *ElementType);
373 // refineAbstractType - Called when a contained type is found to be more
374 // concrete - this could potentially change us from an abstract type to a
377 virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
379 // Methods for support type inquiry through isa, cast, and dyn_cast:
380 static inline bool classof(const PointerType *T) { return true; }
381 static inline bool classof(const Type *T) {
382 return T->getPrimitiveID() == PointerTyID;
384 static inline bool classof(const Value *V) {
385 return isa<Type>(V) && classof(cast<Type>(V));
390 class OpaqueType : public DerivedType {
391 OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT
392 const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT
394 // This should really be private, but it squelches a bogus warning
395 // from GCC to make them protected: warning: `class OpaqueType' only
396 // defines private constructors and has no friends
398 // Private ctor - Only can be created by a static member...
401 // dropAllTypeUses - When this (abstract) type is resolved to be equal to
402 // another (more concrete) type, we must eliminate all references to other
403 // types, to avoid some circular reference problems.
404 virtual void dropAllTypeUses(bool inMap) {} // No type uses
408 // get - Static factory method for the OpaqueType class...
409 static OpaqueType *get() {
410 return new OpaqueType(); // All opaque types are distinct
413 // Methods for support type inquiry through isa, cast, and dyn_cast:
414 static inline bool classof(const OpaqueType *T) { return true; }
415 static inline bool classof(const Type *T) {
416 return T->getPrimitiveID() == OpaqueTyID;
418 static inline bool classof(const Value *V) {
419 return isa<Type>(V) && classof(cast<Type>(V));
424 // Define some inline methods for the AbstractTypeUser.h:PATypeHandle class.
425 // These are defined here because they MUST be inlined, yet are dependent on
426 // the definition of the Type class. Of course Type derives from Value, which
427 // contains an AbstractTypeUser instance, so there is no good way to factor out
428 // the code. Hence this bit of uglyness.
430 inline void PATypeHandle::addUser() {
431 assert(Ty && "Type Handle has a null type!");
432 if (Ty->isAbstract())
433 cast<DerivedType>(Ty)->addAbstractTypeUser(User);
435 inline void PATypeHandle::removeUser() {
436 if (Ty->isAbstract())
437 cast<DerivedType>(Ty)->removeAbstractTypeUser(User);
440 inline void PATypeHandle::removeUserFromConcrete() {
441 if (!Ty->isAbstract())
442 cast<DerivedType>(Ty)->removeAbstractTypeUser(User);