Type.h revision f5d9fa7e78a2c5d57171a141020491d48222de22
1//===-- llvm/Type.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 declaration of the Type class.  For more "Type" type
11// stuff, look in DerivedTypes.h.
12//
13// Note that instances of the Type class are immutable: once they are created,
14// they are never changed.  Also note that only one instance of a particular
15// type is ever created.  Thus seeing if two types are equal is a matter of
16// doing a trivial pointer comparison.
17//
18// Types, once allocated, are never free'd, unless they are an abstract type
19// that is resolved to a more concrete type.
20//
21// Opaque types are simple derived types with no state.  There may be many
22// different Opaque type objects floating around, but two are only considered
23// identical if they are pointer equals of each other.  This allows us to have
24// two opaque types that end up resolving to different concrete types later.
25//
26// Opaque types are also kinda wierd and scary and different because they have
27// to keep a list of uses of the type.  When, through linking, parsing, or
28// bytecode reading, they become resolved, they need to find and update all
29// users of the unknown type, causing them to reference a new, more concrete
30// type.  Opaque types are deleted when their use list dwindles to zero users.
31//
32//===----------------------------------------------------------------------===//
33
34#ifndef LLVM_TYPE_H
35#define LLVM_TYPE_H
36
37#include "AbstractTypeUser.h"
38#include "llvm/Support/Casting.h"
39#include "llvm/ADT/GraphTraits.h"
40#include "llvm/ADT/iterator"
41#include <vector>
42
43namespace llvm {
44
45class ArrayType;
46class DerivedType;
47class FunctionType;
48class OpaqueType;
49class PointerType;
50class StructType;
51class PackedType;
52
53class Type {
54public:
55  ///===-------------------------------------------------------------------===//
56  /// Definitions of all of the base types for the Type system.  Based on this
57  /// value, you can cast to a "DerivedType" subclass (see DerivedTypes.h)
58  /// Note: If you add an element to this, you need to add an element to the
59  /// Type::getPrimitiveType function, or else things will break!
60  ///
61  enum TypeID {
62    // PrimitiveTypes .. make sure LastPrimitiveTyID stays up to date
63    VoidTyID = 0  , BoolTyID,           //  0, 1: Basics...
64    UByteTyID     , SByteTyID,          //  2, 3: 8 bit types...
65    UShortTyID    , ShortTyID,          //  4, 5: 16 bit types...
66    UIntTyID      , IntTyID,            //  6, 7: 32 bit types...
67    ULongTyID     , LongTyID,           //  8, 9: 64 bit types...
68    FloatTyID     , DoubleTyID,         // 10,11: Floating point types...
69    LabelTyID     ,                     // 12   : Labels...
70
71    // Derived types... see DerivedTypes.h file...
72    // Make sure FirstDerivedTyID stays up to date!!!
73    FunctionTyID  , StructTyID,         // Functions... Structs...
74    ArrayTyID     , PointerTyID,        // Array... pointer...
75    OpaqueTyID,                         // Opaque type instances...
76    PackedTyID,                         // SIMD 'packed' format...
77    //...
78
79    NumTypeIDs,                         // Must remain as last defined ID
80    LastPrimitiveTyID = LabelTyID,
81    FirstDerivedTyID = FunctionTyID,
82  };
83
84private:
85  TypeID   ID : 8;    // The current base type of this type.
86  bool     Abstract;  // True if type contains an OpaqueType
87
88  /// RefCount - This counts the number of PATypeHolders that are pointing to
89  /// this type.  When this number falls to zero, if the type is abstract and
90  /// has no AbstractTypeUsers, the type is deleted.  This is only sensical for
91  /// derived types.
92  ///
93  mutable unsigned RefCount;
94
95  const Type *getForwardedTypeInternal() const;
96protected:
97  Type(const std::string& Name, TypeID id);
98  virtual ~Type() {}
99
100  /// Types can become nonabstract later, if they are refined.
101  ///
102  inline void setAbstract(bool Val) { Abstract = Val; }
103
104  // PromoteAbstractToConcrete - This is an internal method used to calculate
105  // change "Abstract" from true to false when types are refined.
106  bool PromoteAbstractToConcrete(void *);
107
108  unsigned getRefCount() const { return RefCount; }
109
110  /// ForwardType - This field is used to implement the union find scheme for
111  /// abstract types.  When types are refined to other types, this field is set
112  /// to the more refined type.  Only abstract types can be forwarded.
113  mutable const Type *ForwardType;
114
115  /// ContainedTys - The list of types contained by this one.  For example, this
116  /// includes the arguments of a function type, the elements of the structure,
117  /// the pointee of a pointer, etc.  Note that keeping this vector in the Type
118  /// class wastes some space for types that do not contain anything (such as
119  /// primitive types).  However, keeping it here allows the subtype_* members
120  /// to be implemented MUCH more efficiently, and dynamically very few types do
121  /// not contain any elements (most are derived).
122  std::vector<PATypeHandle> ContainedTys;
123
124public:
125  virtual void print(std::ostream &O) const;
126
127  /// @brief Debugging support: print to stderr
128  virtual void dump() const;
129
130  //===--------------------------------------------------------------------===//
131  // Property accessors for dealing with types... Some of these virtual methods
132  // are defined in private classes defined in Type.cpp for primitive types.
133  //
134
135  /// getTypeID - Return the type id for the type.  This will return one
136  /// of the TypeID enum elements defined above.
137  ///
138  inline TypeID getTypeID() const { return ID; }
139
140  /// getDescription - Return the string representation of the type...
141  const std::string &getDescription() const;
142
143  /// isSigned - Return whether an integral numeric type is signed.  This is
144  /// true for SByteTy, ShortTy, IntTy, LongTy.  Note that this is not true for
145  /// Float and Double.
146  ///
147  bool isSigned() const {
148    return ID == SByteTyID || ID == ShortTyID ||
149           ID == IntTyID || ID == LongTyID;
150  }
151
152  /// isUnsigned - Return whether a numeric type is unsigned.  This is not quite
153  /// the complement of isSigned... nonnumeric types return false as they do
154  /// with isSigned.  This returns true for UByteTy, UShortTy, UIntTy, and
155  /// ULongTy
156  ///
157  bool isUnsigned() const {
158    return ID == UByteTyID || ID == UShortTyID ||
159           ID == UIntTyID || ID == ULongTyID;
160  }
161
162  /// isInteger - Equivalent to isSigned() || isUnsigned()
163  ///
164  bool isInteger() const { return ID >= UByteTyID && ID <= LongTyID; }
165
166  /// isIntegral - Returns true if this is an integral type, which is either
167  /// BoolTy or one of the Integer types.
168  ///
169  bool isIntegral() const { return isInteger() || this == BoolTy; }
170
171  /// isFloatingPoint - Return true if this is one of the two floating point
172  /// types
173  bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID; }
174
175  /// isAbstract - True if the type is either an Opaque type, or is a derived
176  /// type that includes an opaque type somewhere in it.
177  ///
178  inline bool isAbstract() const { return Abstract; }
179
180  /// isLosslesslyConvertibleTo - Return true if this type can be converted to
181  /// 'Ty' without any reinterpretation of bits.  For example, uint to int.
182  ///
183  bool isLosslesslyConvertibleTo(const Type *Ty) const;
184
185
186  /// Here are some useful little methods to query what type derived types are
187  /// Note that all other types can just compare to see if this == Type::xxxTy;
188  ///
189  inline bool isPrimitiveType() const { return ID <= LastPrimitiveTyID; }
190  inline bool isDerivedType()   const { return ID >= FirstDerivedTyID; }
191
192  /// isFirstClassType - Return true if the value is holdable in a register.
193  inline bool isFirstClassType() const {
194    return (ID != VoidTyID && ID <= LastPrimitiveTyID) ||
195            ID == PointerTyID || ID == PackedTyID;
196  }
197
198  /// isSized - Return true if it makes sense to take the size of this type.  To
199  /// get the actual size for a particular target, it is reasonable to use the
200  /// TargetData subsystem to do this.
201  ///
202  bool isSized() const {
203    return (ID >= BoolTyID && ID <= DoubleTyID) || ID == PointerTyID ||
204           isSizedDerivedType();
205  }
206
207  /// getPrimitiveSize - Return the basic size of this type if it is a primitive
208  /// type.  These are fixed by LLVM and are not target dependent.  This will
209  /// return zero if the type does not have a size or is not a primitive type.
210  ///
211  unsigned getPrimitiveSize() const;
212
213  /// getUnsignedVersion - If this is an integer type, return the unsigned
214  /// variant of this type.  For example int -> uint.
215  const Type *getUnsignedVersion() const;
216
217  /// getSignedVersion - If this is an integer type, return the signed variant
218  /// of this type.  For example uint -> int.
219  const Type *getSignedVersion() const;
220
221  /// getForwaredType - Return the type that this type has been resolved to if
222  /// it has been resolved to anything.  This is used to implement the
223  /// union-find algorithm for type resolution, and shouldn't be used by general
224  /// purpose clients.
225  const Type *getForwardedType() const {
226    if (!ForwardType) return 0;
227    return getForwardedTypeInternal();
228  }
229
230  //===--------------------------------------------------------------------===//
231  // Type Iteration support
232  //
233  typedef std::vector<PATypeHandle>::const_iterator subtype_iterator;
234  subtype_iterator subtype_begin() const { return ContainedTys.begin(); }
235  subtype_iterator subtype_end() const { return ContainedTys.end(); }
236
237  /// getContainedType - This method is used to implement the type iterator
238  /// (defined a the end of the file).  For derived types, this returns the
239  /// types 'contained' in the derived type.
240  ///
241  const Type *getContainedType(unsigned i) const {
242    assert(i < ContainedTys.size() && "Index out of range!");
243    return ContainedTys[i];
244  }
245
246  /// getNumContainedTypes - Return the number of types in the derived type.
247  ///
248  unsigned getNumContainedTypes() const { return ContainedTys.size(); }
249
250  //===--------------------------------------------------------------------===//
251  // Static members exported by the Type class itself.  Useful for getting
252  // instances of Type.
253  //
254
255  /// getPrimitiveType - Return a type based on an identifier.
256  static const Type *getPrimitiveType(TypeID IDNumber);
257
258  //===--------------------------------------------------------------------===//
259  // These are the builtin types that are always available...
260  //
261  static Type *VoidTy , *BoolTy;
262  static Type *SByteTy, *UByteTy,
263              *ShortTy, *UShortTy,
264              *IntTy  , *UIntTy,
265              *LongTy , *ULongTy;
266  static Type *FloatTy, *DoubleTy;
267
268  static Type* LabelTy;
269
270  /// Methods for support type inquiry through isa, cast, and dyn_cast:
271  static inline bool classof(const Type *T) { return true; }
272
273#include "llvm/Type.def"
274
275  // Virtual methods used by callbacks below.  These should only be implemented
276  // in the DerivedType class.
277  virtual void addAbstractTypeUser(AbstractTypeUser *U) const {
278    abort(); // Only on derived types!
279  }
280  virtual void removeAbstractTypeUser(AbstractTypeUser *U) const {
281    abort(); // Only on derived types!
282  }
283
284  void addRef() const {
285    assert(isAbstract() && "Cannot add a reference to a non-abstract type!");
286    ++RefCount;
287  }
288
289  void dropRef() const {
290    assert(isAbstract() && "Cannot drop a refernce to a non-abstract type!");
291    assert(RefCount && "No objects are currently referencing this object!");
292
293    // If this is the last PATypeHolder using this object, and there are no
294    // PATypeHandles using it, the type is dead, delete it now.
295    if (--RefCount == 0)
296      RefCountIsZero();
297  }
298private:
299  /// isSizedDerivedType - Derived types like structures and arrays are sized
300  /// iff all of the members of the type are sized as well.  Since asking for
301  /// their size is relatively uncommon, move this operation out of line.
302  bool isSizedDerivedType() const;
303
304  virtual void RefCountIsZero() const {
305    abort(); // only on derived types!
306  }
307
308};
309
310//===----------------------------------------------------------------------===//
311// Define some inline methods for the AbstractTypeUser.h:PATypeHandle class.
312// These are defined here because they MUST be inlined, yet are dependent on
313// the definition of the Type class.  Of course Type derives from Value, which
314// contains an AbstractTypeUser instance, so there is no good way to factor out
315// the code.  Hence this bit of uglyness.
316//
317// In the long term, Type should not derive from Value, allowing
318// AbstractTypeUser.h to #include Type.h, allowing us to eliminate this
319// nastyness entirely.
320//
321inline void PATypeHandle::addUser() {
322  assert(Ty && "Type Handle has a null type!");
323  if (Ty->isAbstract())
324    Ty->addAbstractTypeUser(User);
325}
326inline void PATypeHandle::removeUser() {
327  if (Ty->isAbstract())
328    Ty->removeAbstractTypeUser(User);
329}
330
331inline void PATypeHandle::removeUserFromConcrete() {
332  if (!Ty->isAbstract())
333    Ty->removeAbstractTypeUser(User);
334}
335
336// Define inline methods for PATypeHolder...
337
338inline void PATypeHolder::addRef() {
339  if (Ty->isAbstract())
340    Ty->addRef();
341}
342
343inline void PATypeHolder::dropRef() {
344  if (Ty->isAbstract())
345    Ty->dropRef();
346}
347
348/// get - This implements the forwarding part of the union-find algorithm for
349/// abstract types.  Before every access to the Type*, we check to see if the
350/// type we are pointing to is forwarding to a new type.  If so, we drop our
351/// reference to the type.
352///
353inline Type* PATypeHolder::get() const {
354  const Type *NewTy = Ty->getForwardedType();
355  if (!NewTy) return const_cast<Type*>(Ty);
356  return *const_cast<PATypeHolder*>(this) = NewTy;
357}
358
359
360
361//===----------------------------------------------------------------------===//
362// Provide specializations of GraphTraits to be able to treat a type as a
363// graph of sub types...
364
365template <> struct GraphTraits<Type*> {
366  typedef Type NodeType;
367  typedef Type::subtype_iterator ChildIteratorType;
368
369  static inline NodeType *getEntryNode(Type *T) { return T; }
370  static inline ChildIteratorType child_begin(NodeType *N) {
371    return N->subtype_begin();
372  }
373  static inline ChildIteratorType child_end(NodeType *N) {
374    return N->subtype_end();
375  }
376};
377
378template <> struct GraphTraits<const Type*> {
379  typedef const Type NodeType;
380  typedef Type::subtype_iterator ChildIteratorType;
381
382  static inline NodeType *getEntryNode(const Type *T) { return T; }
383  static inline ChildIteratorType child_begin(NodeType *N) {
384    return N->subtype_begin();
385  }
386  static inline ChildIteratorType child_end(NodeType *N) {
387    return N->subtype_end();
388  }
389};
390
391template <> inline bool isa_impl<PointerType, Type>(const Type &Ty) {
392  return Ty.getTypeID() == Type::PointerTyID;
393}
394
395std::ostream &operator<<(std::ostream &OS, const Type &T);
396
397} // End llvm namespace
398
399#endif
400