Use the Support/iterator file to abstract out compiler differences
[oota-llvm.git] / include / llvm / Type.h
index d5f57cba04bdd6fc1edfb0d7179efc109a6752ef..8cb4b581fcfb322a1d95a32af495ba3328796548 100644 (file)
@@ -1,7 +1,7 @@
 //===-- llvm/Type.h - Classes for handling data types ------------*- C++ -*--=//
 //
 // This file contains the declaration of the Type class.  For more "Type" type
-// stuff, look in DerivedTypes.h and Opt/ConstantHandling.h
+// stuff, look in DerivedTypes.h.
 //
 // Note that instances of the Type class are immutable: once they are created,
 // they are never changed.  Also note that only one instance of a particular 
 #define LLVM_TYPE_H
 
 #include "llvm/Value.h"
+#include "Support/GraphTraits.h"
+#include "Support/iterator"
 
 class DerivedType;
-class MethodType;
+class FunctionType;
 class ArrayType;
 class PointerType;
 class StructType;
@@ -54,40 +56,39 @@ public:
 
     TypeTyID,                           // 12   : Type definitions
     LabelTyID     ,                     // 13   : Labels... 
-    /*LockTyID , */                     // 14   : mutex - TODO
 
     // Derived types... see DerivedTypes.h file...
     // Make sure FirstDerivedTyID stays up to date!!!
-    MethodTyID    , ModuleTyID,         // Methods... Modules...
+    FunctionTyID  , StructTyID,         // Functions... Structs...
     ArrayTyID     , PointerTyID,        // Array... pointer...
-    StructTyID    , OpaqueTyID,         // Structure... Opaque type instances...
+    OpaqueTyID,                         // Opaque type instances...
     //PackedTyID  ,                     // SIMD 'packed' format... TODO
     //...
 
     NumPrimitiveIDs,                    // Must remain as last defined ID
-    FirstDerivedTyID = MethodTyID,
+    FirstDerivedTyID = FunctionTyID,
   };
 
 private:
   PrimitiveID ID;        // The current base type of this type...
   unsigned    UID;       // The unique ID number for this class
-  string      Desc;      // The printed name of the string...
+  std::string Desc;      // The printed name of the string...
   bool        Abstract;  // True if type contains an OpaqueType
   bool        Recursive; // True if the type is recursive
 
 protected:
   // ctor is protected, so only subclasses can create Type objects...
-  Type(const string &Name, PrimitiveID id);
+  Type(const std::string &Name, PrimitiveID id);
   virtual ~Type() {}
 
   // When types are refined, they update their description to be more concrete.
   //
-  inline void setDescription(const string &D) { Desc = D; }
+  inline void setDescription(const std::string &D) { Desc = D; }
   
   // setName - Associate the name with this type in the symbol table, but don't
   // set the local name to be equal specified name.
   //
-  virtual void setName(const string &Name, SymbolTable *ST = 0);
+  virtual void setName(const std::string &Name, SymbolTable *ST = 0);
 
   // Types can become nonabstract later, if they are refined.
   //
@@ -98,6 +99,7 @@ protected:
   inline void setRecursive(bool Val) { Recursive = Val; }
 
 public:
+  virtual void print(std::ostream &O) const;
 
   //===--------------------------------------------------------------------===//
   // Property accessors for dealing with types...
@@ -116,7 +118,7 @@ public:
   inline unsigned getUniqueID() const { return UID; }
 
   // getDescription - Return the string representation of the type...
-  inline const string &getDescription() const { return Desc; }
+  inline const std::string &getDescription() const { return Desc; }
 
   // isSigned - Return whether a numeric type is signed.
   virtual bool isSigned() const { return 0; }
@@ -132,6 +134,10 @@ public:
   //
   virtual bool isIntegral() const { return 0; }
 
+  // isFloatingPoint - Return true if this is one of the two floating point
+  // types
+  bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID; }
+
   // isAbstract - True if the type is either an Opaque type, or is a derived
   // type that includes an opaque type somewhere in it.  
   //
@@ -141,13 +147,46 @@ public:
   //
   inline bool isRecursive() const { return Recursive; }
 
+  // isLosslesslyConvertableTo - Return true if this type can be converted to
+  // 'Ty' without any reinterpretation of bits.  For example, uint to int.
+  //
+  bool isLosslesslyConvertableTo(const Type *Ty) const;
+
+
+  // Here are some useful little methods to query what type derived types are
+  // Note that all other types can just compare to see if this == Type::xxxTy;
+  //
+  inline bool isPrimitiveType() const { return ID < FirstDerivedTyID;  }
+  inline bool isDerivedType()   const { return ID >= FirstDerivedTyID; }
+
+  // isFirstClassType - Return true if the value is holdable in a register.
+  inline bool isFirstClassType() const {
+    return isPrimitiveType() || ID == PointerTyID;
+  }
+
+  // isSized - Return true if it makes sense to take the size of this type.  To
+  // get the actual size for a particular target, it is reasonable to use the
+  // TargetData subsystem to do this.
+  //
+  bool isSized() const {
+    return ID != VoidTyID && ID != TypeTyID &&
+           ID != FunctionTyID && ID != LabelTyID && ID != OpaqueTyID;
+  }
+
+  // getPrimitiveSize - Return the basic size of this type if it is a primative
+  // type.  These are fixed by LLVM and are not target dependant.  This will
+  // return zero if the type does not have a size or is not a primitive type.
+  //
+  unsigned getPrimitiveSize() const;
+
+
   //===--------------------------------------------------------------------===//
   // Type Iteration support
   //
   class TypeIterator;
-  typedef TypeIterator contype_iterator;
-  inline contype_iterator contype_begin() const;   // DEFINED BELOW
-  inline contype_iterator contype_end() const;     // DEFINED BELOW
+  typedef TypeIterator subtype_iterator;
+  inline subtype_iterator subtype_begin() const;   // DEFINED BELOW
+  inline subtype_iterator subtype_end() const;     // DEFINED BELOW
 
   // getContainedType - This method is used to implement the type iterator
   // (defined a the end of the file).  For derived types, this returns the types
@@ -172,51 +211,25 @@ public:
   //===--------------------------------------------------------------------===//
   // These are the builtin types that are always available...
   //
-  static const Type *VoidTy , *BoolTy;
-  static const Type *SByteTy, *UByteTy,
-                    *ShortTy, *UShortTy,
-                    *IntTy  , *UIntTy, 
-                    *LongTy , *ULongTy;
-  static const Type *FloatTy, *DoubleTy;
-
-  static const Type *TypeTy , *LabelTy; //, *LockTy;
-
-  // Here are some useful little methods to query what type derived types are
-  // Note that all other types can just compare to see if this == Type::xxxTy;
-  //
-  inline bool isDerivedType()   const { return ID >= FirstDerivedTyID; }
-  inline bool isPrimitiveType() const { return ID < FirstDerivedTyID;  }
-
-  inline bool isLabelType()     const { return this == LabelTy; }
-
-  inline const DerivedType *castDerivedType() const {
-    return isDerivedType() ? (const DerivedType*)this : 0;
-  }
-  inline const DerivedType *castDerivedTypeAsserting() const {
-    assert(isDerivedType());
-    return (const DerivedType*)this;
+  static Type *VoidTy , *BoolTy;
+  static Type *SByteTy, *UByteTy,
+              *ShortTy, *UShortTy,
+              *IntTy  , *UIntTy, 
+              *LongTy , *ULongTy;
+  static Type *FloatTy, *DoubleTy;
+
+  static Type *TypeTy , *LabelTy;
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Type *T) { return true; }
+  static inline bool classof(const Value *V) {
+    return V->getValueType() == Value::TypeVal;
   }
 
-  inline const MethodType *isMethodType() const {
-    return ID == MethodTyID ? (const MethodType*)this : 0;
-  }
-  inline bool isModuleType()    const { return ID == ModuleTyID;     }
-  inline const ArrayType *isArrayType() const { 
-    return ID == ArrayTyID ? (const ArrayType*)this : 0;
-  }
-  inline const PointerType *isPointerType() const { 
-    return ID == PointerTyID ? (const PointerType*)this : 0;
-  }
-  inline const StructType *isStructType() const {
-    return ID == StructTyID ? (const StructType*)this : 0;
-  }
-  inline const OpaqueType *isOpaqueType() const {
-    return ID == OpaqueTyID ? (const OpaqueType*)this : 0;
-  }
+#include "llvm/Type.def"
 
 private:
-  class TypeIterator : public std::bidirectional_iterator<const Type,
-                                                         ptrdiff_t> {
+  class TypeIterator : public bidirectional_iterator<const Type, ptrdiff_t> {
     const Type * const Ty;
     unsigned Idx;
 
@@ -243,12 +256,46 @@ private:
   };
 };
 
-inline Type::TypeIterator Type::contype_begin() const {
+inline Type::TypeIterator Type::subtype_begin() const {
   return TypeIterator(this, 0);
 }
 
-inline Type::TypeIterator Type::contype_end() const {
+inline Type::TypeIterator Type::subtype_end() const {
   return TypeIterator(this, getNumContainedTypes());
 }
 
+
+// Provide specializations of GraphTraits to be able to treat a type as a 
+// graph of sub types...
+
+template <> struct GraphTraits<Type*> {
+  typedef Type NodeType;
+  typedef Type::subtype_iterator ChildIteratorType;
+
+  static inline NodeType *getEntryNode(Type *T) { return T; }
+  static inline ChildIteratorType child_begin(NodeType *N) { 
+    return N->subtype_begin(); 
+  }
+  static inline ChildIteratorType child_end(NodeType *N) { 
+    return N->subtype_end();
+  }
+};
+
+template <> struct GraphTraits<const Type*> {
+  typedef const Type NodeType;
+  typedef Type::subtype_iterator ChildIteratorType;
+
+  static inline NodeType *getEntryNode(const Type *T) { return T; }
+  static inline ChildIteratorType child_begin(NodeType *N) { 
+    return N->subtype_begin(); 
+  }
+  static inline ChildIteratorType child_end(NodeType *N) { 
+    return N->subtype_end();
+  }
+};
+
+template <> inline bool isa_impl<PointerType, Type>(const Type &Ty) { 
+  return Ty.getPrimitiveID() == Type::PointerTyID;
+}
+
 #endif