Type.h revision 38ecbf18eb9c8ca7ae08dfed4dc6fb4e3e5deb1e
183e3c4f9d796a5da223a3ebd5d4ba985c7ecc39dDan Gohman//===-- llvm/Type.h - Classes for handling data types -----------*- C++ -*-===//
2bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell//
3bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell//                     The LLVM Compiler Infrastructure
4bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file was developed by the LLVM research group and is distributed under
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// the University of Illinois Open Source License. See LICENSE.TXT for details.
7bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell//
8bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell//===----------------------------------------------------------------------===//
9bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell
1083e3c4f9d796a5da223a3ebd5d4ba985c7ecc39dDan Gohman
1183e3c4f9d796a5da223a3ebd5d4ba985c7ecc39dDan Gohman#ifndef LLVM_TYPE_H
1283e3c4f9d796a5da223a3ebd5d4ba985c7ecc39dDan Gohman#define LLVM_TYPE_H
1383e3c4f9d796a5da223a3ebd5d4ba985c7ecc39dDan Gohman
1483e3c4f9d796a5da223a3ebd5d4ba985c7ecc39dDan Gohman#include "llvm/AbstractTypeUser.h"
1583e3c4f9d796a5da223a3ebd5d4ba985c7ecc39dDan Gohman#include "llvm/Support/Casting.h"
16bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/Support/DataTypes.h"
17bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/Support/Streams.h"
18bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/ADT/GraphTraits.h"
19bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/ADT/iterator"
20bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include <string>
21bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include <vector>
225520732b24a5a321140dd79af70d321c7ff3dec9Chris Lattner
239a38e3e3991ea443e555d8060f91202a786acdd4Dan Gohmannamespace llvm {
24bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell
25bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswellclass ArrayType;
26562b84b3aea359d1f918184e355da82bf05eb290Jay Foadclass DerivedType;
2762d327e241f59735eed836e98c8f11ffaa6cf6f8Chris Lattnerclass FunctionType;
2862d327e241f59735eed836e98c8f11ffaa6cf6f8Chris Lattnerclass OpaqueType;
29618c1dbd293d15ee19f61b1156ab8086ad28311aChad Rosierclass PointerType;
305520732b24a5a321140dd79af70d321c7ff3dec9Chris Lattnerclass StructType;
31c5f6a1f9d61d74017d90e149728cb3d283e0a0e0Chris Lattnerclass PackedType;
32c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwinclass TypeMapBase;
33bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell
34bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell/// This file contains the declaration of the Type class.  For more "Type" type
3583471853b1d5a9efe6b9e7565c457fc901f84926Rafael Espindola/// stuff, look in DerivedTypes.h.
36bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell///
3797af751deb9b26fd42fbcee082da9ccc4ded5b45Jeff Cohen/// The instances of the Type class are immutable: once they are created,
38bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell/// they are never changed.  Also note that only one instance of a particular
39bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell/// type is ever created.  Thus seeing if two types are equal is a matter of
4003dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner/// doing a trivial pointer comparison. To enforce that no two equal instances
4103dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner/// are created, Type instances can only be created via static factory methods
4203dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner/// in class Type and in derived classes.
4303dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner///
446333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner/// Once allocated, Types are never free'd, unless they are an abstract type
456333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner/// that is resolved to a more concrete type.
466333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner///
47db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner/// Types themself don't have a name, and can be named either by:
486333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner/// - using SymbolTable instance, typically from some Module,
494c7c0f23533565c7e2ddf71e01bf50f2aede5f1bNadav Rotem/// - using convenience methods in the Module class (which uses module's
504c7c0f23533565c7e2ddf71e01bf50f2aede5f1bNadav Rotem///    SymbolTable too).
514c7c0f23533565c7e2ddf71e01bf50f2aede5f1bNadav Rotem///
524c7c0f23533565c7e2ddf71e01bf50f2aede5f1bNadav Rotem/// Opaque types are simple derived types with no state.  There may be many
534c7c0f23533565c7e2ddf71e01bf50f2aede5f1bNadav Rotem/// different Opaque type objects floating around, but two are only considered
544c7c0f23533565c7e2ddf71e01bf50f2aede5f1bNadav Rotem/// identical if they are pointer equals of each other.  This allows us to have
5504594aeffa3360882eb09a888a0970321b987b16Rafael Espindola/// two opaque types that end up resolving to different concrete types later.
5604594aeffa3360882eb09a888a0970321b987b16Rafael Espindola///
577302d80490feabfc8a01bee0fa698aab55169544Chris Lattner/// Opaque types are also kinda weird and scary and different because they have
587302d80490feabfc8a01bee0fa698aab55169544Chris Lattner/// to keep a list of uses of the type.  When, through linking, parsing, or
5904594aeffa3360882eb09a888a0970321b987b16Rafael Espindola/// bytecode reading, they become resolved, they need to find and update all
6004594aeffa3360882eb09a888a0970321b987b16Rafael Espindola/// users of the unknown type, causing them to reference a new, more concrete
617302d80490feabfc8a01bee0fa698aab55169544Chris Lattner/// type.  Opaque types are deleted when their use list dwindles to zero users.
627302d80490feabfc8a01bee0fa698aab55169544Chris Lattner///
637302d80490feabfc8a01bee0fa698aab55169544Chris Lattner/// @brief Root of type hierarchy
6404594aeffa3360882eb09a888a0970321b987b16Rafael Espindolaclass Type : public AbstractTypeUser {
6504594aeffa3360882eb09a888a0970321b987b16Rafael Espindolapublic:
6604594aeffa3360882eb09a888a0970321b987b16Rafael Espindola  ///===-------------------------------------------------------------------===//
677302d80490feabfc8a01bee0fa698aab55169544Chris Lattner  /// Definitions of all of the base types for the Type system.  Based on this
687302d80490feabfc8a01bee0fa698aab55169544Chris Lattner  /// value, you can cast to a "DerivedType" subclass (see DerivedTypes.h)
6904594aeffa3360882eb09a888a0970321b987b16Rafael Espindola  /// Note: If you add an element to this, you need to add an element to the
7004594aeffa3360882eb09a888a0970321b987b16Rafael Espindola  /// Type::getPrimitiveType function, or else things will break!
7104594aeffa3360882eb09a888a0970321b987b16Rafael Espindola  ///
7204594aeffa3360882eb09a888a0970321b987b16Rafael Espindola  enum TypeID {
737302d80490feabfc8a01bee0fa698aab55169544Chris Lattner    // PrimitiveTypes .. make sure LastPrimitiveTyID stays up to date
7404594aeffa3360882eb09a888a0970321b987b16Rafael Espindola    VoidTyID = 0  , BoolTyID,           //  0, 1: Basics...
7504594aeffa3360882eb09a888a0970321b987b16Rafael Espindola    UByteTyID     , SByteTyID,          //  2, 3: 8 bit types...
7604594aeffa3360882eb09a888a0970321b987b16Rafael Espindola    UShortTyID    , ShortTyID,          //  4, 5: 16 bit types...
7704594aeffa3360882eb09a888a0970321b987b16Rafael Espindola    UIntTyID      , IntTyID,            //  6, 7: 32 bit types...
787302d80490feabfc8a01bee0fa698aab55169544Chris Lattner    ULongTyID     , LongTyID,           //  8, 9: 64 bit types...
7904594aeffa3360882eb09a888a0970321b987b16Rafael Espindola    FloatTyID     , DoubleTyID,         // 10,11: Floating point types...
8004594aeffa3360882eb09a888a0970321b987b16Rafael Espindola    LabelTyID     ,                     // 12   : Labels...
817302d80490feabfc8a01bee0fa698aab55169544Chris Lattner
827302d80490feabfc8a01bee0fa698aab55169544Chris Lattner    // Derived types... see DerivedTypes.h file...
837302d80490feabfc8a01bee0fa698aab55169544Chris Lattner    // Make sure FirstDerivedTyID stays up to date!!!
847302d80490feabfc8a01bee0fa698aab55169544Chris Lattner    FunctionTyID  , StructTyID,         // Functions... Structs...
857302d80490feabfc8a01bee0fa698aab55169544Chris Lattner    ArrayTyID     , PointerTyID,        // Array... pointer...
8604594aeffa3360882eb09a888a0970321b987b16Rafael Espindola    OpaqueTyID,                         // Opaque type instances...
8704594aeffa3360882eb09a888a0970321b987b16Rafael Espindola    PackedTyID,                         // SIMD 'packed' format...
8804594aeffa3360882eb09a888a0970321b987b16Rafael Espindola    BC_ONLY_PackedStructTyID,           // packed struct, for BC rep only
8904594aeffa3360882eb09a888a0970321b987b16Rafael Espindola    //...
9004594aeffa3360882eb09a888a0970321b987b16Rafael Espindola
911c9fe0361b3f9f5c814ce761b97ecd11637a1d7dNadav Rotem    NumTypeIDs,                         // Must remain as last defined ID
92db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    LastPrimitiveTyID = LabelTyID,
936333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner    FirstDerivedTyID = FunctionTyID
946333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  };
956333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
9693798daa3ecbfb29624052d3e54d2404ab65897aChris Lattnerprivate:
9793798daa3ecbfb29624052d3e54d2404ab65897aChris Lattner  TypeID   ID : 8;    // The current base type of this type.
9893798daa3ecbfb29624052d3e54d2404ab65897aChris Lattner  bool     Abstract : 1;  // True if type contains an OpaqueType
9993798daa3ecbfb29624052d3e54d2404ab65897aChris Lattner  bool     SubclassData : 1; //Space for subclasses to store a flag
1002ca5c8644e6c35b3a7910a576ed89cddb7b82c3bChris Lattner
10193798daa3ecbfb29624052d3e54d2404ab65897aChris Lattner  /// RefCount - This counts the number of PATypeHolders that are pointing to
10293798daa3ecbfb29624052d3e54d2404ab65897aChris Lattner  /// this type.  When this number falls to zero, if the type is abstract and
10393798daa3ecbfb29624052d3e54d2404ab65897aChris Lattner  /// has no AbstractTypeUsers, the type is deleted.  This is only sensical for
1046b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// derived types.
10593798daa3ecbfb29624052d3e54d2404ab65897aChris Lattner  ///
10693798daa3ecbfb29624052d3e54d2404ab65897aChris Lattner  mutable unsigned RefCount;
1076333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1086333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  const Type *getForwardedTypeInternal() const;
1096b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattnerprotected:
1106333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  Type(const char *Name, TypeID id);
1116333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  Type(TypeID id) : ID(id), Abstract(false), RefCount(0), ForwardType(0) {}
1126333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  virtual ~Type() {
1136b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner    assert(AbstractTypeUsers.empty());
114db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  }
1156333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1166333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// Types can become nonabstract later, if they are refined.
1176333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  ///
1186333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  inline void setAbstract(bool Val) { Abstract = Val; }
1196333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1206333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  unsigned getRefCount() const { return RefCount; }
1216333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1226333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  bool getSubclassData() const { return SubclassData; }
1236333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  void setSubclassData(bool b) { SubclassData = b; }
1246333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1256333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// ForwardType - This field is used to implement the union find scheme for
126b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  /// abstract types.  When types are refined to other types, this field is set
1276333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// to the more refined type.  Only abstract types can be forwarded.
1286333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  mutable const Type *ForwardType;
129db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner
1306333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// ContainedTys - The list of types contained by this one.  For example, this
1316333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// includes the arguments of a function type, the elements of the structure,
1326333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// the pointee of a pointer, etc.  Note that keeping this vector in the Type
1336333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// class wastes some space for types that do not contain anything (such as
1346333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// primitive types).  However, keeping it here allows the subtype_* members
1356333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// to be implemented MUCH more efficiently, and dynamically very few types do
1366333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// not contain any elements (most are derived).
1376333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  std::vector<PATypeHandle> ContainedTys;
1386333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1396333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// AbstractTypeUsers - Implement a list of the users that need to be notified
140b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  /// if I am a type, and I get resolved into a more concrete type.
1416333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  ///
142db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  mutable std::vector<AbstractTypeUser *> AbstractTypeUsers;
1436333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattnerpublic:
1446333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  void print(OStream &O) const {
1456333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner    if (O.stream()) print(*O.stream());
1466b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  }
1476b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  void print(std::ostream &O) const;
1486b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner
1496333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// @brief Debugging support: print to stderr
1506333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  void dump() const;
1516333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1526333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  //===--------------------------------------------------------------------===//
1536333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  // Property accessors for dealing with types... Some of these virtual methods
1546333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  // are defined in private classes defined in Type.cpp for primitive types.
1556333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  //
1566333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1576333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// getTypeID - Return the type id for the type.  This will return one
1586333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// of the TypeID enum elements defined above.
1596333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  ///
1606333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  inline TypeID getTypeID() const { return ID; }
1616333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1626333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// getDescription - Return the string representation of the type...
1636333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  const std::string &getDescription() const;
1646333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1656333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// isSigned - Return whether an integral numeric type is signed.  This is
1666333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// true for SByteTy, ShortTy, IntTy, LongTy.  Note that this is not true for
1676333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// Float and Double.
1686333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  ///
1696333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  bool isSigned() const {
1706b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner    return ID == SByteTyID || ID == ShortTyID ||
1716333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner           ID == IntTyID || ID == LongTyID;
1726333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  }
1736333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1746333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// isUnsigned - Return whether a numeric type is unsigned.  This is not quite
1756333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// the complement of isSigned... nonnumeric types return false as they do
1766333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// with isSigned.  This returns true for UByteTy, UShortTy, UIntTy, and
1776333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// ULongTy
1786333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  ///
1796333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  bool isUnsigned() const {
1806333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner    return ID == UByteTyID || ID == UShortTyID ||
1816333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner           ID == UIntTyID || ID == ULongTyID;
1826333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  }
1836333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
1846333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// isInteger - Equivalent to isSigned() || isUnsigned()
1856333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  ///
1866333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  bool isInteger() const { return ID >= UByteTyID && ID <= LongTyID; }
1876b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner
1886b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// isIntegral - Returns true if this is an integral type, which is either
1896b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// BoolTy or one of the Integer types.
1906b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  ///
1916b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  bool isIntegral() const { return isInteger() || this == BoolTy; }
1926b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner
1936b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// isFloatingPoint - Return true if this is one of the two floating point
1946b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// types
1956b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID; }
1966b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner
1976b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// isFPOrFPVector - Return true if this is a FP type or a vector of FP types.
1986b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  ///
1996333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  bool isFPOrFPVector() const;
2006b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner
2016b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// isAbstract - True if the type is either an Opaque type, or is a derived
2026b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// type that includes an opaque type somewhere in it.
2036b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  ///
2046b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  inline bool isAbstract() const { return Abstract; }
2056b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner
2066b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// canLosslesslyBitCastTo - Return true if this type could be converted
2076333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// with a lossless BitCast to type 'Ty'. For example, uint to int. BitCasts
2086b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// are valid for types of the same size only where no re-interpretation of
2096b0dc92043ab1f63d78b8796098575e1d777b701Chris Lattner  /// the bits is done.
2106333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// @brief Determine if this type could be losslessly bitcast to Ty
2116333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  bool canLosslesslyBitCastTo(const Type *Ty) const;
2126333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner
2132ca5c8644e6c35b3a7910a576ed89cddb7b82c3bChris Lattner
2146333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// Here are some useful little methods to query what type derived types are
2156333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  /// Note that all other types can just compare to see if this == Type::xxxTy;
2166333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  ///
21703dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  inline bool isPrimitiveType() const { return ID <= LastPrimitiveTyID; }
21803dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  inline bool isDerivedType()   const { return ID >= FirstDerivedTyID; }
21903dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner
22003dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// isFirstClassType - Return true if the value is holdable in a register.
22103dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  ///
22203dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  inline bool isFirstClassType() const {
22303dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner    return (ID != VoidTyID && ID <= LastPrimitiveTyID) ||
22403dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner            ID == PointerTyID || ID == PackedTyID;
22503dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  }
22603dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner
22703dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// isSized - Return true if it makes sense to take the size of this type.  To
22803dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// get the actual size for a particular target, it is reasonable to use the
22903dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// TargetData subsystem to do this.
23003dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  ///
23103dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  bool isSized() const {
23203dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner    // If it's a primitive, it is always sized.
23303dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner    if (ID >= BoolTyID && ID <= DoubleTyID || ID == PointerTyID)
23403dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner      return true;
23503dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner    // If it is not something that can have a size (e.g. a function or label),
23603dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner    // it doesn't have a size.
23703dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner    if (ID != StructTyID && ID != ArrayTyID && ID != PackedTyID)
23803dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner      return false;
23903dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner    // If it is something that can have a size and it's concrete, it definitely
24003dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner    // has a size, otherwise we have to try harder to decide.
241f286f6fd93d569befe6e77c94a947e6e04e95685Chris Lattner    return !isAbstract() || isSizedDerivedType();
242f286f6fd93d569befe6e77c94a947e6e04e95685Chris Lattner  }
24303dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner
24403dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// getPrimitiveSize - Return the basic size of this type if it is a primitive
24503dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// type.  These are fixed by LLVM and are not target dependent.  This will
24603dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// return zero if the type does not have a size or is not a primitive type.
24703dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  ///
24803dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  unsigned getPrimitiveSize() const;
24903dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  unsigned getPrimitiveSizeInBits() const;
25003dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner
251de2d74b213844b17eb5327fba27f21e699d3af66Gabor Greif  /// getUnsignedVersion - If this is an integer type, return the unsigned
252785c6af9797fcf551feef70f2ecb5cd075b6e3c4Gabor Greif  /// variant of this type.  For example int -> uint.
253de2d74b213844b17eb5327fba27f21e699d3af66Gabor Greif  const Type *getUnsignedVersion() const;
25403dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner
255e368b460a206fafa0d31d5d059b1779b94f7df8cDan Gohman  /// getSignedVersion - If this is an integer type, return the signed variant
25603dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// of this type.  For example uint -> int.
257db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  const Type *getSignedVersion() const;
25803dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner
259b1919e2f08ecb37140af676fd2916f8d5ed7df3dChris Lattner  /// getIntegralTypeMask - Return a bitmask with ones set for all of the bits
26003dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// that can be set by an unsigned version of this type.  This is 0xFF for
261db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  /// sbyte/ubyte, 0xFFFF for shorts, etc.
262777d2306b36816a53bc1ae1244c0dc7d998ae691Duncan Sands  uint64_t getIntegralTypeMask() const {
26303dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner    assert(isIntegral() && "This only works for integral types!");
26403dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner    return ~uint64_t(0UL) >> (64-getPrimitiveSizeInBits());
26503dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  }
26603dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner
26703dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// getForwaredType - Return the type that this type has been resolved to if
26803dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// it has been resolved to anything.  This is used to implement the
26903dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// union-find algorithm for type resolution, and shouldn't be used by general
27003dd25ca964813c8b9fe14479443b9c21fb92c55Chris Lattner  /// purpose clients.
271fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  const Type *getForwardedType() const {
272fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    if (!ForwardType) return 0;
273fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    return getForwardedTypeInternal();
274fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  }
275fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
276fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  /// getVAArgsPromotedType - Return the type an argument of this type
277fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  /// will be promoted to if passed through a variable argument
278fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  /// function.
279fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  const Type *getVAArgsPromotedType() const {
280fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    if (ID == BoolTyID || ID == UByteTyID || ID == UShortTyID)
281c7b1382e351249774be63bd73839e8a0671635e1Chris Lattner      return Type::UIntTy;
282c7b1382e351249774be63bd73839e8a0671635e1Chris Lattner    else if (ID == SByteTyID || ID == ShortTyID)
283fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner      return Type::IntTy;
284fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    else if (ID == FloatTyID)
285fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner      return Type::DoubleTy;
286fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    else
287fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner      return this;
288fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  }
289fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
290fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  //===--------------------------------------------------------------------===//
291fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  // Type Iteration support
292fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  //
293fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  typedef std::vector<PATypeHandle>::const_iterator subtype_iterator;
294fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  subtype_iterator subtype_begin() const { return ContainedTys.begin(); }
295c7b1382e351249774be63bd73839e8a0671635e1Chris Lattner  subtype_iterator subtype_end() const { return ContainedTys.end(); }
296fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
297fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  /// getContainedType - This method is used to implement the type iterator
298fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  /// (defined a the end of the file).  For derived types, this returns the
299fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  /// types 'contained' in the derived type.
300fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  ///
301fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  const Type *getContainedType(unsigned i) const {
302fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    assert(i < ContainedTys.size() && "Index out of range!");
3036333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner    return ContainedTys[i];
304fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  }
305fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
306fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  /// getNumContainedTypes - Return the number of types in the derived type.
3076333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  ///
308fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  typedef std::vector<PATypeHandle>::size_type size_type;
309fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  size_type getNumContainedTypes() const { return ContainedTys.size(); }
310c7b1382e351249774be63bd73839e8a0671635e1Chris Lattner
311fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  //===--------------------------------------------------------------------===//
312a97ddd0cffb9a9eb1313343fd49097c9057a5850Chris Lattner  // Static members exported by the Type class itself.  Useful for getting
313fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  // instances of Type.
314fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  //
315fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
316fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  /// getPrimitiveType - Return a type based on an identifier.
317fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static const Type *getPrimitiveType(TypeID IDNumber);
318fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
319fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  //===--------------------------------------------------------------------===//
320fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  // These are the builtin types that are always available...
321fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  //
322fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static Type *VoidTy , *BoolTy;
323fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static Type *SByteTy, *UByteTy,
324fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner              *ShortTy, *UShortTy,
325fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner              *IntTy  , *UIntTy,
326fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner              *LongTy , *ULongTy;
327fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static Type *FloatTy, *DoubleTy;
328fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
329fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static Type* LabelTy;
330fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
331fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  /// Methods for support type inquiry through isa, cast, and dyn_cast:
332fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static inline bool classof(const Type *T) { return true; }
333fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
334fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  void addRef() const {
335fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    assert(isAbstract() && "Cannot add a reference to a non-abstract type!");
336fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    ++RefCount;
337fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  }
338fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
339fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  void dropRef() const {
340fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    assert(isAbstract() && "Cannot drop a reference to a non-abstract type!");
341fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    assert(RefCount && "No objects are currently referencing this object!");
342c5af649758ac8c6ffb896d7d5c570640a9fa1deeChris Lattner
343fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    // If this is the last PATypeHolder using this object, and there are no
344fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    // PATypeHandles using it, the type is dead, delete it now.
345fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    if (--RefCount == 0 && AbstractTypeUsers.empty())
346fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner      delete this;
347fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  }
348fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
349fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  /// addAbstractTypeUser - Notify an abstract type that there is a new user of
350a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner  /// it.  This function is called primarily by the PATypeHandle class.
351a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner  ///
352a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner  void addAbstractTypeUser(AbstractTypeUser *U) const {
353a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner    assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
354fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    AbstractTypeUsers.push_back(U);
355fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  }
356a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner
357a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner  /// removeAbstractTypeUser - Notify an abstract type that a user of the class
358a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner  /// no longer has a handle to the type.  This function is called primarily by
359a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner  /// the PATypeHandle class.  When there are no users of the abstract type, it
360a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner  /// is annihilated, because there is no way to get a reference to it ever
361f2124cc6c1d4e675526e87bcc9fccd3ef4664dcbDuncan Sands  /// again.
362a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner  ///
363a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner  void removeAbstractTypeUser(AbstractTypeUser *U) const;
364fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
365fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattnerprivate:
366f2124cc6c1d4e675526e87bcc9fccd3ef4664dcbDuncan Sands  /// isSizedDerivedType - Derived types like structures and arrays are sized
367f2124cc6c1d4e675526e87bcc9fccd3ef4664dcbDuncan Sands  /// iff all of the members of the type are sized as well.  Since asking for
368f2124cc6c1d4e675526e87bcc9fccd3ef4664dcbDuncan Sands  /// their size is relatively uncommon, move this operation out of line.
369f2124cc6c1d4e675526e87bcc9fccd3ef4664dcbDuncan Sands  bool isSizedDerivedType() const;
370fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
371f2124cc6c1d4e675526e87bcc9fccd3ef4664dcbDuncan Sands  virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
372fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  virtual void typeBecameConcrete(const DerivedType *AbsTy);
373f2124cc6c1d4e675526e87bcc9fccd3ef4664dcbDuncan Sands
374f2124cc6c1d4e675526e87bcc9fccd3ef4664dcbDuncan Sandsprotected:
375fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  // PromoteAbstractToConcrete - This is an internal method used to calculate
376fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  // change "Abstract" from true to false when types are refined.
377fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  void PromoteAbstractToConcrete();
378a97ddd0cffb9a9eb1313343fd49097c9057a5850Chris Lattner  friend class TypeMapBase;
3796475d9434ff3e981160f85d3f1aa07c9e0ace6f2Anders Carlsson};
3805d43ff4e7ea30eaf5a1c417f0ec528900f5c83f2Anders Carlsson
3815d43ff4e7ea30eaf5a1c417f0ec528900f5c83f2Anders Carlsson//===----------------------------------------------------------------------===//
382a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner// Define some inline methods for the AbstractTypeUser.h:PATypeHandle class.
383a1f00f4d488eb5daff52faaf99c62ee652fd3b85Chris Lattner// These are defined here because they MUST be inlined, yet are dependent on
3846475d9434ff3e981160f85d3f1aa07c9e0ace6f2Anders Carlsson// the definition of the Type class.
3856475d9434ff3e981160f85d3f1aa07c9e0ace6f2Anders Carlsson//
386fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattnerinline void PATypeHandle::addUser() {
387fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  assert(Ty && "Type Handle has a null type!");
388fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  if (Ty->isAbstract())
389fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    Ty->addAbstractTypeUser(User);
390fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner}
391fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattnerinline void PATypeHandle::removeUser() {
392db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  if (Ty->isAbstract())
393db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    Ty->removeAbstractTypeUser(User);
394fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner}
395fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
396fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner// Define inline methods for PATypeHolder...
397fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
39817f0cd3cc1432231f2bc5601e7e463986a59d817Chris Lattnerinline void PATypeHolder::addRef() {
39917f0cd3cc1432231f2bc5601e7e463986a59d817Chris Lattner  if (Ty->isAbstract())
40017f0cd3cc1432231f2bc5601e7e463986a59d817Chris Lattner    Ty->addRef();
401db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner}
40217f0cd3cc1432231f2bc5601e7e463986a59d817Chris Lattner
403fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattnerinline void PATypeHolder::dropRef() {
40417f0cd3cc1432231f2bc5601e7e463986a59d817Chris Lattner  if (Ty->isAbstract())
405fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    Ty->dropRef();
4061df9859c40492511b8aa4321eb76496005d3b75bDuncan Sands}
40717f0cd3cc1432231f2bc5601e7e463986a59d817Chris Lattner
40817f0cd3cc1432231f2bc5601e7e463986a59d817Chris Lattner
40917f0cd3cc1432231f2bc5601e7e463986a59d817Chris Lattner//===----------------------------------------------------------------------===//
41017f0cd3cc1432231f2bc5601e7e463986a59d817Chris Lattner// Provide specializations of GraphTraits to be able to treat a type as a
411fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner// graph of sub types...
412fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
4136333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattnertemplate <> struct GraphTraits<Type*> {
414fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  typedef Type NodeType;
4156333c3959b7e3e43930ab523f0657791e9eb5d48Chris Lattner  typedef Type::subtype_iterator ChildIteratorType;
416fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
417fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static inline NodeType *getEntryNode(Type *T) { return T; }
418fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static inline ChildIteratorType child_begin(NodeType *N) {
419fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    return N->subtype_begin();
420739208a790398cf1f9da05149c768371e48781e8Chris Lattner  }
421fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static inline ChildIteratorType child_end(NodeType *N) {
422fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    return N->subtype_end();
423fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  }
424fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner};
425fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
426fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattnertemplate <> struct GraphTraits<const Type*> {
427fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  typedef const Type NodeType;
428c7b1382e351249774be63bd73839e8a0671635e1Chris Lattner  typedef Type::subtype_iterator ChildIteratorType;
429fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
430fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static inline NodeType *getEntryNode(const Type *T) { return T; }
431fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static inline ChildIteratorType child_begin(NodeType *N) {
432fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    return N->subtype_begin();
433fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  }
434fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  static inline ChildIteratorType child_end(NodeType *N) {
435fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner    return N->subtype_end();
436fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner  }
437fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner};
438fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
439fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattnertemplate <> inline bool isa_impl<PointerType, Type>(const Type &Ty) {
440739208a790398cf1f9da05149c768371e48781e8Chris Lattner  return Ty.getTypeID() == Type::PointerTyID;
441fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner}
442fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
443fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattnerstd::ostream &operator<<(std::ostream &OS, const Type &T);
444fe8c7c807c6f815561bc2bdddfd330b05dbdfc93Chris Lattner
445b31189f26297fe30214da3e8d14a4575d5fdd262Chris Lattner} // End llvm namespace
446b31189f26297fe30214da3e8d14a4575d5fdd262Chris Lattner
447739208a790398cf1f9da05149c768371e48781e8Chris Lattner#endif
448ce800511701135ed86845b451693a248c83a7973Dan Gohman