1 //===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
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...
14 // The implementations of these classes live in the Type.cpp file.
16 //===----------------------------------------------------------------------===//
18 #ifndef LLVM_DERIVED_TYPES_H
19 #define LLVM_DERIVED_TYPES_H
21 #include "llvm/Type.h"
25 template<class ValType, class TypeClass> class TypeMap;
26 class FunctionValType;
31 class DerivedType : public Type, public AbstractTypeUser {
32 // AbstractTypeUsers - Implement a list of the users that need to be notified
33 // if I am a type, and I get resolved into a more concrete type.
35 mutable std::vector<AbstractTypeUser *> AbstractTypeUsers;
38 DerivedType(TypeID id) : Type("", id) {}
40 assert(AbstractTypeUsers.empty());
43 /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type
44 /// that the current type has transitioned from being abstract to being
47 void notifyUsesThatTypeBecameConcrete();
49 /// dropAllTypeUses - When this (abstract) type is resolved to be equal to
50 /// another (more concrete) type, we must eliminate all references to other
51 /// types, to avoid some circular reference problems.
53 void dropAllTypeUses();
55 void RefCountIsZero() const {
56 if (AbstractTypeUsers.empty())
63 //===--------------------------------------------------------------------===//
64 // Abstract Type handling methods - These types have special lifetimes, which
65 // are managed by (add|remove)AbstractTypeUser. See comments in
66 // AbstractTypeUser.h for more information.
68 /// addAbstractTypeUser - Notify an abstract type that there is a new user of
69 /// it. This function is called primarily by the PATypeHandle class.
71 void addAbstractTypeUser(AbstractTypeUser *U) const {
72 assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
73 AbstractTypeUsers.push_back(U);
76 /// removeAbstractTypeUser - Notify an abstract type that a user of the class
77 /// no longer has a handle to the type. This function is called primarily by
78 /// the PATypeHandle class. When there are no users of the abstract type, it
79 /// is annihilated, because there is no way to get a reference to it ever
82 void removeAbstractTypeUser(AbstractTypeUser *U) const;
84 /// refineAbstractTypeTo - This function is used to when it is discovered that
85 /// the 'this' abstract type is actually equivalent to the NewType specified.
86 /// This causes all users of 'this' to switch to reference the more concrete
87 /// type NewType and for 'this' to be deleted.
89 void refineAbstractTypeTo(const Type *NewType);
91 void dump() const { Type::dump(); }
93 // Methods for support type inquiry through isa, cast, and dyn_cast:
94 static inline bool classof(const DerivedType *T) { return true; }
95 static inline bool classof(const Type *T) {
96 return T->isDerivedType();
101 /// FunctionType - Class to represent function types
103 class FunctionType : public DerivedType {
104 friend class TypeMap<FunctionValType, FunctionType>;
107 FunctionType(const FunctionType &); // Do not implement
108 const FunctionType &operator=(const FunctionType &); // Do not implement
110 /// This should really be private, but it squelches a bogus warning
111 /// from GCC to make them protected: warning: `class FunctionType' only
112 /// defines private constructors and has no friends
114 /// Private ctor - Only can be created by a static member...
116 FunctionType(const Type *Result, const std::vector<const Type*> &Params,
120 /// FunctionType::get - This static method is the primary way of constructing
123 static FunctionType *get(const Type *Result,
124 const std::vector<const Type*> &Params,
127 inline bool isVarArg() const { return isVarArgs; }
128 inline const Type *getReturnType() const { return ContainedTys[0]; }
130 typedef std::vector<PATypeHandle>::const_iterator param_iterator;
131 param_iterator param_begin() const { return ContainedTys.begin()+1; }
132 param_iterator param_end() const { return ContainedTys.end(); }
134 // Parameter type accessors...
135 const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
137 /// getNumParams - Return the number of fixed parameters this function type
138 /// requires. This does not consider varargs.
140 unsigned getNumParams() const { return ContainedTys.size()-1; }
142 // Implement the AbstractTypeUser interface.
143 virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
144 virtual void typeBecameConcrete(const DerivedType *AbsTy);
146 // Methods for support type inquiry through isa, cast, and dyn_cast:
147 static inline bool classof(const FunctionType *T) { return true; }
148 static inline bool classof(const Type *T) {
149 return T->getTypeID() == FunctionTyID;
154 /// CompositeType - Common super class of ArrayType, StructType, and PointerType
156 class CompositeType : public DerivedType {
158 inline CompositeType(TypeID id) : DerivedType(id) { }
161 /// getTypeAtIndex - Given an index value into the type, return the type of
164 virtual const Type *getTypeAtIndex(const Value *V) const = 0;
165 virtual bool indexValid(const Value *V) const = 0;
167 // Methods for support type inquiry through isa, cast, and dyn_cast:
168 static inline bool classof(const CompositeType *T) { return true; }
169 static inline bool classof(const Type *T) {
170 return T->getTypeID() == ArrayTyID ||
171 T->getTypeID() == StructTyID ||
172 T->getTypeID() == PointerTyID;
177 /// StructType - Class to represent struct types
179 class StructType : public CompositeType {
180 friend class TypeMap<StructValType, StructType>;
181 StructType(const StructType &); // Do not implement
182 const StructType &operator=(const StructType &); // Do not implement
185 /// This should really be private, but it squelches a bogus warning
186 /// from GCC to make them protected: warning: `class StructType' only
187 /// defines private constructors and has no friends
189 /// Private ctor - Only can be created by a static member...
191 StructType(const std::vector<const Type*> &Types);
194 /// StructType::get - This static method is the primary way to create a
197 static StructType *get(const std::vector<const Type*> &Params);
199 // Iterator access to the elements
200 typedef std::vector<PATypeHandle>::const_iterator element_iterator;
201 element_iterator element_begin() const { return ContainedTys.begin(); }
202 element_iterator element_end() const { return ContainedTys.end(); }
204 // Random access to the elements
205 unsigned getNumElements() const { return ContainedTys.size(); }
206 const Type *getElementType(unsigned N) const {
207 assert(N < ContainedTys.size() && "Element number out of range!");
208 return ContainedTys[N];
211 /// getTypeAtIndex - Given an index value into the type, return the type of
212 /// the element. For a structure type, this must be a constant value...
214 virtual const Type *getTypeAtIndex(const Value *V) const ;
215 virtual bool indexValid(const Value *V) const;
217 // Implement the AbstractTypeUser interface.
218 virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
219 virtual void typeBecameConcrete(const DerivedType *AbsTy);
221 // Methods for support type inquiry through isa, cast, and dyn_cast:
222 static inline bool classof(const StructType *T) { return true; }
223 static inline bool classof(const Type *T) {
224 return T->getTypeID() == StructTyID;
229 /// SequentialType - This is the superclass of the array and pointer type
230 /// classes. Both of these represent "arrays" in memory. The array type
231 /// represents a specifically sized array, pointer types are unsized/unknown
232 /// size arrays. SequentialType holds the common features of both, which stem
233 /// from the fact that both lay their components out in memory identically.
235 class SequentialType : public CompositeType {
236 SequentialType(const SequentialType &); // Do not implement!
237 const SequentialType &operator=(const SequentialType &); // Do not implement!
239 SequentialType(TypeID TID, const Type *ElType) : CompositeType(TID) {
240 ContainedTys.reserve(1);
241 ContainedTys.push_back(PATypeHandle(ElType, this));
245 inline const Type *getElementType() const { return ContainedTys[0]; }
247 virtual bool indexValid(const Value *V) const;
249 /// getTypeAtIndex - Given an index value into the type, return the type of
250 /// the element. For sequential types, there is only one subtype...
252 virtual const Type *getTypeAtIndex(const Value *V) const {
253 return ContainedTys[0];
256 // Methods for support type inquiry through isa, cast, and dyn_cast:
257 static inline bool classof(const SequentialType *T) { return true; }
258 static inline bool classof(const Type *T) {
259 return T->getTypeID() == ArrayTyID ||
260 T->getTypeID() == PointerTyID;
265 /// ArrayType - Class to represent array types
267 class ArrayType : public SequentialType {
268 friend class TypeMap<ArrayValType, ArrayType>;
269 unsigned NumElements;
271 ArrayType(const ArrayType &); // Do not implement
272 const ArrayType &operator=(const ArrayType &); // Do not implement
274 /// This should really be private, but it squelches a bogus warning
275 /// from GCC to make them protected: warning: `class ArrayType' only
276 /// defines private constructors and has no friends
278 /// Private ctor - Only can be created by a static member...
280 ArrayType(const Type *ElType, unsigned NumEl);
283 /// ArrayType::get - This static method is the primary way to construct an
286 static ArrayType *get(const Type *ElementType, unsigned NumElements);
288 inline unsigned getNumElements() const { return NumElements; }
290 // Implement the AbstractTypeUser interface.
291 virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
292 virtual void typeBecameConcrete(const DerivedType *AbsTy);
294 // Methods for support type inquiry through isa, cast, and dyn_cast:
295 static inline bool classof(const ArrayType *T) { return true; }
296 static inline bool classof(const Type *T) {
297 return T->getTypeID() == ArrayTyID;
302 /// PointerType - Class to represent pointers
304 class PointerType : public SequentialType {
305 friend class TypeMap<PointerValType, PointerType>;
306 PointerType(const PointerType &); // Do not implement
307 const PointerType &operator=(const PointerType &); // Do not implement
309 // This should really be private, but it squelches a bogus warning
310 // from GCC to make them protected: warning: `class PointerType' only
311 // defines private constructors and has no friends
313 // Private ctor - Only can be created by a static member...
314 PointerType(const Type *ElType);
317 /// PointerType::get - This is the only way to construct a new pointer type.
318 static PointerType *get(const Type *ElementType);
320 // Implement the AbstractTypeUser interface.
321 virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
322 virtual void typeBecameConcrete(const DerivedType *AbsTy);
324 // Implement support type inquiry through isa, cast, and dyn_cast:
325 static inline bool classof(const PointerType *T) { return true; }
326 static inline bool classof(const Type *T) {
327 return T->getTypeID() == PointerTyID;
332 /// OpaqueType - Class to represent abstract types
334 class OpaqueType : public DerivedType {
335 OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT
336 const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT
338 /// This should really be private, but it squelches a bogus warning
339 /// from GCC to make them protected: warning: `class OpaqueType' only
340 /// defines private constructors and has no friends
342 /// Private ctor - Only can be created by a static member...
346 /// OpaqueType::get - Static factory method for the OpaqueType class...
348 static OpaqueType *get() {
349 return new OpaqueType(); // All opaque types are distinct
352 // Implement the AbstractTypeUser interface.
353 virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
354 abort(); // FIXME: this is not really an AbstractTypeUser!
356 virtual void typeBecameConcrete(const DerivedType *AbsTy) {
357 abort(); // FIXME: this is not really an AbstractTypeUser!
360 // Implement support for type inquiry through isa, cast, and dyn_cast:
361 static inline bool classof(const OpaqueType *T) { return true; }
362 static inline bool classof(const Type *T) {
363 return T->getTypeID() == OpaqueTyID;
367 } // End llvm namespace