Type.h revision ec55b08fd0dbe3191507ad81b93ab446254ee611
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(const std::string &Name, 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 unsigned getRefCount() const { return RefCount; } 113 114 /// ForwardType - This field is used to implement the union find scheme for 115 /// abstract types. When types are refined to other types, this field is set 116 /// to the more refined type. Only abstract types can be forwarded. 117 mutable const Type *ForwardType; 118 119 /// ContainedTys - The list of types contained by this one. For example, this 120 /// includes the arguments of a function type, the elements of the structure, 121 /// the pointee of a pointer, etc. Note that keeping this vector in the Type 122 /// class wastes some space for types that do not contain anything (such as 123 /// primitive types). However, keeping it here allows the subtype_* members 124 /// to be implemented MUCH more efficiently, and dynamically very few types do 125 /// not contain any elements (most are derived). 126 std::vector<PATypeHandle> ContainedTys; 127 128public: 129 virtual void print(std::ostream &O) const; 130 131 /// @brief Debugging support: print to stderr 132 virtual void dump() const; 133 134 //===--------------------------------------------------------------------===// 135 // Property accessors for dealing with types... Some of these virtual methods 136 // are defined in private classes defined in Type.cpp for primitive types. 137 // 138 139 /// getPrimitiveID - Return the base type of the type. This will return one 140 /// of the PrimitiveID enum elements defined above. 141 /// 142 inline PrimitiveID getPrimitiveID() const { return ID; } 143 144 /// getUniqueID - Returns the UID of the type. This can be thought of as a 145 /// small integer version of the pointer to the type class. Two types that 146 /// are structurally different have different UIDs. This can be used for 147 /// indexing types into an array. 148 /// 149 inline unsigned getUniqueID() const { return UID; } 150 151 /// getDescription - Return the string representation of the type... 152 const std::string &getDescription() const; 153 154 /// isSigned - Return whether an integral numeric type is signed. This is 155 /// true for SByteTy, ShortTy, IntTy, LongTy. Note that this is not true for 156 /// Float and Double. 157 /// 158 virtual bool isSigned() const { return 0; } 159 160 /// isUnsigned - Return whether a numeric type is unsigned. This is not quite 161 /// the complement of isSigned... nonnumeric types return false as they do 162 /// with isSigned. This returns true for UByteTy, UShortTy, UIntTy, and 163 /// ULongTy 164 /// 165 virtual bool isUnsigned() const { return 0; } 166 167 /// isInteger - Equilivent to isSigned() || isUnsigned(), but with only a 168 /// single virtual function invocation. 169 /// 170 virtual bool isInteger() const { return 0; } 171 172 /// isIntegral - Returns true if this is an integral type, which is either 173 /// BoolTy or one of the Integer types. 174 /// 175 bool isIntegral() const { return isInteger() || this == BoolTy; } 176 177 /// isFloatingPoint - Return true if this is one of the two floating point 178 /// types 179 bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID; } 180 181 /// isAbstract - True if the type is either an Opaque type, or is a derived 182 /// type that includes an opaque type somewhere in it. 183 /// 184 inline bool isAbstract() const { return Abstract; } 185 186 /// isLosslesslyConvertibleTo - Return true if this type can be converted to 187 /// 'Ty' without any reinterpretation of bits. For example, uint to int. 188 /// 189 bool isLosslesslyConvertibleTo(const Type *Ty) const; 190 191 192 /// Here are some useful little methods to query what type derived types are 193 /// Note that all other types can just compare to see if this == Type::xxxTy; 194 /// 195 inline bool isPrimitiveType() const { return ID < FirstDerivedTyID; } 196 inline bool isDerivedType() const { return ID >= FirstDerivedTyID; } 197 198 /// isFirstClassType - Return true if the value is holdable in a register. 199 inline bool isFirstClassType() const { 200 return (ID != VoidTyID && ID < TypeTyID) || ID == PointerTyID; 201 } 202 203 /// isSized - Return true if it makes sense to take the size of this type. To 204 /// get the actual size for a particular target, it is reasonable to use the 205 /// TargetData subsystem to do this. 206 /// 207 bool isSized() const { 208 return ID != VoidTyID && ID != TypeTyID && 209 ID != FunctionTyID && ID != LabelTyID && ID != OpaqueTyID; 210 } 211 212 /// getPrimitiveSize - Return the basic size of this type if it is a primative 213 /// type. These are fixed by LLVM and are not target dependent. This will 214 /// return zero if the type does not have a size or is not a primitive type. 215 /// 216 unsigned getPrimitiveSize() const; 217 218 /// getUnsignedVersion - If this is an integer type, return the unsigned 219 /// variant of this type. For example int -> uint. 220 const Type *getUnsignedVersion() const; 221 222 /// getSignedVersion - If this is an integer type, return the signed variant 223 /// of this type. For example uint -> int. 224 const Type *getSignedVersion() const; 225 226 /// getForwaredType - Return the type that this type has been resolved to if 227 /// it has been resolved to anything. This is used to implement the 228 /// union-find algorithm for type resolution, and shouldn't be used by general 229 /// purpose clients. 230 const Type *getForwardedType() const { 231 if (!ForwardType) return 0; 232 return getForwardedTypeInternal(); 233 } 234 235 //===--------------------------------------------------------------------===// 236 // Type Iteration support 237 // 238 typedef std::vector<PATypeHandle>::const_iterator subtype_iterator; 239 subtype_iterator subtype_begin() const { return ContainedTys.begin(); } 240 subtype_iterator subtype_end() const { return ContainedTys.end(); } 241 242 /// getContainedType - This method is used to implement the type iterator 243 /// (defined a the end of the file). For derived types, this returns the 244 /// types 'contained' in the derived type. 245 /// 246 const Type *getContainedType(unsigned i) const { 247 assert(i < ContainedTys.size() && "Index out of range!"); 248 return ContainedTys[i]; 249 } 250 251 /// getNumContainedTypes - Return the number of types in the derived type. 252 /// 253 unsigned getNumContainedTypes() const { return ContainedTys.size(); } 254 255 //===--------------------------------------------------------------------===// 256 // Static members exported by the Type class itself. Useful for getting 257 // instances of Type. 258 // 259 260 /// getPrimitiveType/getUniqueIDType - Return a type based on an identifier. 261 static const Type *getPrimitiveType(PrimitiveID IDNumber); 262 static const Type *getUniqueIDType(unsigned UID); 263 264 //===--------------------------------------------------------------------===// 265 // These are the builtin types that are always available... 266 // 267 static Type *VoidTy , *BoolTy; 268 static Type *SByteTy, *UByteTy, 269 *ShortTy, *UShortTy, 270 *IntTy , *UIntTy, 271 *LongTy , *ULongTy; 272 static Type *FloatTy, *DoubleTy; 273 274 static Type *TypeTy , *LabelTy; 275 276 /// Methods for support type inquiry through isa, cast, and dyn_cast: 277 static inline bool classof(const Type *T) { return true; } 278 static inline bool classof(const Value *V) { 279 return V->getValueType() == Value::TypeVal; 280 } 281 282#include "llvm/Type.def" 283 284 // Virtual methods used by callbacks below. These should only be implemented 285 // in the DerivedType class. 286 virtual void addAbstractTypeUser(AbstractTypeUser *U) const { 287 abort(); // Only on derived types! 288 } 289 virtual void removeAbstractTypeUser(AbstractTypeUser *U) const { 290 abort(); // Only on derived types! 291 } 292 293 void addRef() const { 294 assert(isAbstract() && "Cannot add a reference to a non-abstract type!"); 295 ++RefCount; 296 } 297 298 void dropRef() const { 299 assert(isAbstract() && "Cannot drop a refernce to a non-abstract type!"); 300 assert(RefCount && "No objects are currently referencing this object!"); 301 302 // If this is the last PATypeHolder using this object, and there are no 303 // PATypeHandles using it, the type is dead, delete it now. 304 if (--RefCount == 0) 305 RefCountIsZero(); 306 } 307private: 308 virtual void RefCountIsZero() const { 309 abort(); // only on derived types! 310 } 311 312}; 313 314//===----------------------------------------------------------------------===// 315// Define some inline methods for the AbstractTypeUser.h:PATypeHandle class. 316// These are defined here because they MUST be inlined, yet are dependent on 317// the definition of the Type class. Of course Type derives from Value, which 318// contains an AbstractTypeUser instance, so there is no good way to factor out 319// the code. Hence this bit of uglyness. 320// 321// In the long term, Type should not derive from Value, allowing 322// AbstractTypeUser.h to #include Type.h, allowing us to eliminate this 323// nastyness entirely. 324// 325inline void PATypeHandle::addUser() { 326 assert(Ty && "Type Handle has a null type!"); 327 if (Ty->isAbstract()) 328 Ty->addAbstractTypeUser(User); 329} 330inline void PATypeHandle::removeUser() { 331 if (Ty->isAbstract()) 332 Ty->removeAbstractTypeUser(User); 333} 334 335inline void PATypeHandle::removeUserFromConcrete() { 336 if (!Ty->isAbstract()) 337 Ty->removeAbstractTypeUser(User); 338} 339 340// Define inline methods for PATypeHolder... 341 342inline void PATypeHolder::addRef() { 343 if (Ty->isAbstract()) 344 Ty->addRef(); 345} 346 347inline void PATypeHolder::dropRef() { 348 if (Ty->isAbstract()) 349 Ty->dropRef(); 350} 351 352/// get - This implements the forwarding part of the union-find algorithm for 353/// abstract types. Before every access to the Type*, we check to see if the 354/// type we are pointing to is forwarding to a new type. If so, we drop our 355/// reference to the type. 356/// 357inline const Type* PATypeHolder::get() const { 358 const Type *NewTy = Ty->getForwardedType(); 359 if (!NewTy) return Ty; 360 return *const_cast<PATypeHolder*>(this) = NewTy; 361} 362 363 364 365//===----------------------------------------------------------------------===// 366// Provide specializations of GraphTraits to be able to treat a type as a 367// graph of sub types... 368 369template <> struct GraphTraits<Type*> { 370 typedef Type NodeType; 371 typedef Type::subtype_iterator ChildIteratorType; 372 373 static inline NodeType *getEntryNode(Type *T) { return T; } 374 static inline ChildIteratorType child_begin(NodeType *N) { 375 return N->subtype_begin(); 376 } 377 static inline ChildIteratorType child_end(NodeType *N) { 378 return N->subtype_end(); 379 } 380}; 381 382template <> struct GraphTraits<const Type*> { 383 typedef const Type NodeType; 384 typedef Type::subtype_iterator ChildIteratorType; 385 386 static inline NodeType *getEntryNode(const Type *T) { return T; } 387 static inline ChildIteratorType child_begin(NodeType *N) { 388 return N->subtype_begin(); 389 } 390 static inline ChildIteratorType child_end(NodeType *N) { 391 return N->subtype_end(); 392 } 393}; 394 395template <> inline bool isa_impl<PointerType, Type>(const Type &Ty) { 396 return Ty.getPrimitiveID() == Type::PointerTyID; 397} 398 399} // End llvm namespace 400 401#endif 402