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