//===-- llvm/Type.h - Classes for handling data types -----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the Type class.  For more "Type"
// stuff, look in DerivedTypes.h.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_IR_TYPE_H
#define LLVM_IR_TYPE_H

#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"

namespace llvm {

class PointerType;
class IntegerType;
class raw_ostream;
class Module;
class LLVMContext;
class LLVMContextImpl;
class StringRef;
template<class GraphType> struct GraphTraits;

/// The instances of the Type class are immutable: once they are created,
/// they are never changed.  Also note that only one instance of a particular
/// type is ever created.  Thus seeing if two types are equal is a matter of
/// doing a trivial pointer comparison. To enforce that no two equal instances
/// are created, Type instances can only be created via static factory methods
/// in class Type and in derived classes.  Once allocated, Types are never
/// free'd.
///
class Type {
public:
  //===--------------------------------------------------------------------===//
  /// Definitions of all of the base types for the Type system.  Based on this
  /// value, you can cast to a class defined in DerivedTypes.h.
  /// Note: If you add an element to this, you need to add an element to the
  /// Type::getPrimitiveType function, or else things will break!
  /// Also update LLVMTypeKind and LLVMGetTypeKind () in the C binding.
  ///
  enum TypeID {
    // PrimitiveTypes - make sure LastPrimitiveTyID stays up to date.
    VoidTyID = 0,    ///<  0: type with no size
    HalfTyID,        ///<  1: 16-bit floating point type
    FloatTyID,       ///<  2: 32-bit floating point type
    DoubleTyID,      ///<  3: 64-bit floating point type
    X86_FP80TyID,    ///<  4: 80-bit floating point type (X87)
    FP128TyID,       ///<  5: 128-bit floating point type (112-bit mantissa)
    PPC_FP128TyID,   ///<  6: 128-bit floating point type (two 64-bits, PowerPC)
    LabelTyID,       ///<  7: Labels
    MetadataTyID,    ///<  8: Metadata
    X86_MMXTyID,     ///<  9: MMX vectors (64 bits, X86 specific)
    TokenTyID,       ///< 10: Tokens

    // Derived types... see DerivedTypes.h file.
    // Make sure FirstDerivedTyID stays up to date!
    IntegerTyID,     ///< 11: Arbitrary bit width integers
    FunctionTyID,    ///< 12: Functions
    StructTyID,      ///< 13: Structures
    ArrayTyID,       ///< 14: Arrays
    PointerTyID,     ///< 15: Pointers
    VectorTyID       ///< 16: SIMD 'packed' format, or other vector type
  };

private:
  /// This refers to the LLVMContext in which this type was uniqued.
  LLVMContext &Context;

  TypeID   ID : 8;            // The current base type of this type.
  unsigned SubclassData : 24; // Space for subclasses to store data.
                              // Note that this should be synchronized with
                              // MAX_INT_BITS value in IntegerType class.

protected:
  friend class LLVMContextImpl;
  explicit Type(LLVMContext &C, TypeID tid)
    : Context(C), ID(tid), SubclassData(0),
      NumContainedTys(0), ContainedTys(nullptr) {}
  ~Type() = default;

  unsigned getSubclassData() const { return SubclassData; }

  void setSubclassData(unsigned val) {
    SubclassData = val;
    // Ensure we don't have any accidental truncation.
    assert(getSubclassData() == val && "Subclass data too large for field");
  }

  /// Keeps track of how many Type*'s there are in the ContainedTys list.
  unsigned NumContainedTys;

  /// A pointer to the array of Types contained by this Type. For example, this
  /// includes the arguments of a function type, the elements of a structure,
  /// the pointee of a pointer, the element type of an array, etc. This pointer
  /// may be 0 for types that don't contain other types (Integer, Double,
  /// Float).
  Type * const *ContainedTys;

  static bool isSequentialType(TypeID TyID) {
    return TyID == ArrayTyID || TyID == VectorTyID;
  }

public:
  /// Print the current type.
  /// Omit the type details if \p NoDetails == true.
  /// E.g., let %st = type { i32, i16 }
  /// When \p NoDetails is true, we only print %st.
  /// Put differently, \p NoDetails prints the type as if
  /// inlined with the operands when printing an instruction.
  void print(raw_ostream &O, bool IsForDebug = false,
             bool NoDetails = false) const;
  void dump() const;

  /// Return the LLVMContext in which this type was uniqued.
  LLVMContext &getContext() const { return Context; }

  //===--------------------------------------------------------------------===//
  // Accessors for working with types.
  //

  /// Return the type id for the type. This will return one of the TypeID enum
  /// elements defined above.
  TypeID getTypeID() const { return ID; }

  /// Return true if this is 'void'.
  bool isVoidTy() const { return getTypeID() == VoidTyID; }

  /// Return true if this is 'half', a 16-bit IEEE fp type.
  bool isHalfTy() const { return getTypeID() == HalfTyID; }

  /// Return true if this is 'float', a 32-bit IEEE fp type.
  bool isFloatTy() const { return getTypeID() == FloatTyID; }

  /// Return true if this is 'double', a 64-bit IEEE fp type.
  bool isDoubleTy() const { return getTypeID() == DoubleTyID; }

  /// Return true if this is x86 long double.
  bool isX86_FP80Ty() const { return getTypeID() == X86_FP80TyID; }

  /// Return true if this is 'fp128'.
  bool isFP128Ty() const { return getTypeID() == FP128TyID; }

  /// Return true if this is powerpc long double.
  bool isPPC_FP128Ty() const { return getTypeID() == PPC_FP128TyID; }

  /// Return true if this is one of the six floating-point types
  bool isFloatingPointTy() const {
    return getTypeID() == HalfTyID || getTypeID() == FloatTyID ||
           getTypeID() == DoubleTyID ||
           getTypeID() == X86_FP80TyID || getTypeID() == FP128TyID ||
           getTypeID() == PPC_FP128TyID;
  }

  const fltSemantics &getFltSemantics() const {
    switch (getTypeID()) {
    case HalfTyID: return APFloat::IEEEhalf();
    case FloatTyID: return APFloat::IEEEsingle();
    case DoubleTyID: return APFloat::IEEEdouble();
    case X86_FP80TyID: return APFloat::x87DoubleExtended();
    case FP128TyID: return APFloat::IEEEquad();
    case PPC_FP128TyID: return APFloat::PPCDoubleDouble();
    default: llvm_unreachable("Invalid floating type");
    }
  }

  /// Return true if this is X86 MMX.
  bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; }

  /// Return true if this is a FP type or a vector of FP.
  bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy(); }

  /// Return true if this is 'label'.
  bool isLabelTy() const { return getTypeID() == LabelTyID; }

  /// Return true if this is 'metadata'.
  bool isMetadataTy() const { return getTypeID() == MetadataTyID; }

  /// Return true if this is 'token'.
  bool isTokenTy() const { return getTypeID() == TokenTyID; }

  /// True if this is an instance of IntegerType.
  bool isIntegerTy() const { return getTypeID() == IntegerTyID; }

  /// Return true if this is an IntegerType of the given width.
  bool isIntegerTy(unsigned Bitwidth) const;

  /// Return true if this is an integer type or a vector of integer types.
  bool isIntOrIntVectorTy() const { return getScalarType()->isIntegerTy(); }

  /// True if this is an instance of FunctionType.
  bool isFunctionTy() const { return getTypeID() == FunctionTyID; }

  /// True if this is an instance of StructType.
  bool isStructTy() const { return getTypeID() == StructTyID; }

  /// True if this is an instance of ArrayType.
  bool isArrayTy() const { return getTypeID() == ArrayTyID; }

  /// True if this is an instance of PointerType.
  bool isPointerTy() const { return getTypeID() == PointerTyID; }

  /// Return true if this is a pointer type or a vector of pointer types.
  bool isPtrOrPtrVectorTy() const { return getScalarType()->isPointerTy(); }

  /// True if this is an instance of VectorType.
  bool isVectorTy() const { return getTypeID() == VectorTyID; }

  /// Return true if this type could be converted with a lossless BitCast to
  /// type 'Ty'. For example, i8* to i32*. BitCasts are valid for types of the
  /// same size only where no re-interpretation of the bits is done.
  /// @brief Determine if this type could be losslessly bitcast to Ty
  bool canLosslesslyBitCastTo(Type *Ty) const;

  /// Return true if this type is empty, that is, it has no elements or all of
  /// its elements are empty.
  bool isEmptyTy() const;

  /// Return true if the type is "first class", meaning it is a valid type for a
  /// Value.
  bool isFirstClassType() const {
    return getTypeID() != FunctionTyID && getTypeID() != VoidTyID;
  }

  /// Return true if the type is a valid type for a register in codegen. This
  /// includes all first-class types except struct and array types.
  bool isSingleValueType() const {
    return isFloatingPointTy() || isX86_MMXTy() || isIntegerTy() ||
           isPointerTy() || isVectorTy();
  }

  /// Return true if the type is an aggregate type. This means it is valid as
  /// the first operand of an insertvalue or extractvalue instruction. This
  /// includes struct and array types, but does not include vector types.
  bool isAggregateType() const {
    return getTypeID() == StructTyID || getTypeID() == ArrayTyID;
  }

  /// 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
  /// DataLayout subsystem to do this.
  bool isSized(SmallPtrSetImpl<Type*> *Visited = nullptr) const {
    // If it's a primitive, it is always sized.
    if (getTypeID() == IntegerTyID || isFloatingPointTy() ||
        getTypeID() == PointerTyID ||
        getTypeID() == X86_MMXTyID)
      return true;
    // If it is not something that can have a size (e.g. a function or label),
    // it doesn't have a size.
    if (getTypeID() != StructTyID && getTypeID() != ArrayTyID &&
        getTypeID() != VectorTyID)
      return false;
    // Otherwise we have to try harder to decide.
    return isSizedDerivedType(Visited);
  }

  /// Return the basic size of this type if it is a primitive type. These are
  /// fixed by LLVM and are not target-dependent.
  /// This will return zero if the type does not have a size or is not a
  /// primitive type.
  ///
  /// Note that this may not reflect the size of memory allocated for an
  /// instance of the type or the number of bytes that are written when an
  /// instance of the type is stored to memory. The DataLayout class provides
  /// additional query functions to provide this information.
  ///
  unsigned getPrimitiveSizeInBits() const LLVM_READONLY;

  /// If this is a vector type, return the getPrimitiveSizeInBits value for the
  /// element type. Otherwise return the getPrimitiveSizeInBits value for this
  /// type.
  unsigned getScalarSizeInBits() const LLVM_READONLY;

  /// Return the width of the mantissa of this type. This is only valid on
  /// floating-point types. If the FP type does not have a stable mantissa (e.g.
  /// ppc long double), this method returns -1.
  int getFPMantissaWidth() const;

  /// If this is a vector type, return the element type, otherwise return
  /// 'this'.
  Type *getScalarType() const {
    if (isVectorTy())
      return getVectorElementType();
    return const_cast<Type*>(this);
  }

  //===--------------------------------------------------------------------===//
  // Type Iteration support.
  //
  typedef Type * const *subtype_iterator;
  subtype_iterator subtype_begin() const { return ContainedTys; }
  subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];}
  ArrayRef<Type*> subtypes() const {
    return makeArrayRef(subtype_begin(), subtype_end());
  }

  typedef std::reverse_iterator<subtype_iterator> subtype_reverse_iterator;
  subtype_reverse_iterator subtype_rbegin() const {
    return subtype_reverse_iterator(subtype_end());
  }
  subtype_reverse_iterator subtype_rend() const {
    return subtype_reverse_iterator(subtype_begin());
  }

  /// This method is used to implement the type iterator (defined at the end of
  /// the file). For derived types, this returns the types 'contained' in the
  /// derived type.
  Type *getContainedType(unsigned i) const {
    assert(i < NumContainedTys && "Index out of range!");
    return ContainedTys[i];
  }

  /// Return the number of types in the derived type.
  unsigned getNumContainedTypes() const { return NumContainedTys; }

  //===--------------------------------------------------------------------===//
  // Helper methods corresponding to subclass methods.  This forces a cast to
  // the specified subclass and calls its accessor.  "getVectorNumElements" (for
  // example) is shorthand for cast<VectorType>(Ty)->getNumElements().  This is
  // only intended to cover the core methods that are frequently used, helper
  // methods should not be added here.

  inline unsigned getIntegerBitWidth() const;

  inline Type *getFunctionParamType(unsigned i) const;
  inline unsigned getFunctionNumParams() const;
  inline bool isFunctionVarArg() const;

  inline StringRef getStructName() const;
  inline unsigned getStructNumElements() const;
  inline Type *getStructElementType(unsigned N) const;

  inline Type *getSequentialElementType() const {
    assert(isSequentialType(getTypeID()) && "Not a sequential type!");
    return ContainedTys[0];
  }

  inline uint64_t getArrayNumElements() const;
  Type *getArrayElementType() const {
    assert(getTypeID() == ArrayTyID);
    return ContainedTys[0];
  }

  inline unsigned getVectorNumElements() const;
  Type *getVectorElementType() const {
    assert(getTypeID() == VectorTyID);
    return ContainedTys[0];
  }

  Type *getPointerElementType() const {
    assert(getTypeID() == PointerTyID);
    return ContainedTys[0];
  }

  /// Get the address space of this pointer or pointer vector type.
  inline unsigned getPointerAddressSpace() const;

  //===--------------------------------------------------------------------===//
  // Static members exported by the Type class itself.  Useful for getting
  // instances of Type.
  //

  /// Return a type based on an identifier.
  static Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber);

  //===--------------------------------------------------------------------===//
  // These are the builtin types that are always available.
  //
  static Type *getVoidTy(LLVMContext &C);
  static Type *getLabelTy(LLVMContext &C);
  static Type *getHalfTy(LLVMContext &C);
  static Type *getFloatTy(LLVMContext &C);
  static Type *getDoubleTy(LLVMContext &C);
  static Type *getMetadataTy(LLVMContext &C);
  static Type *getX86_FP80Ty(LLVMContext &C);
  static Type *getFP128Ty(LLVMContext &C);
  static Type *getPPC_FP128Ty(LLVMContext &C);
  static Type *getX86_MMXTy(LLVMContext &C);
  static Type *getTokenTy(LLVMContext &C);
  static IntegerType *getIntNTy(LLVMContext &C, unsigned N);
  static IntegerType *getInt1Ty(LLVMContext &C);
  static IntegerType *getInt8Ty(LLVMContext &C);
  static IntegerType *getInt16Ty(LLVMContext &C);
  static IntegerType *getInt32Ty(LLVMContext &C);
  static IntegerType *getInt64Ty(LLVMContext &C);
  static IntegerType *getInt128Ty(LLVMContext &C);

  //===--------------------------------------------------------------------===//
  // Convenience methods for getting pointer types with one of the above builtin
  // types as pointee.
  //
  static PointerType *getHalfPtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getFloatPtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getDoublePtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getX86_MMXPtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS = 0);
  static PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0);
  static PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0);

  /// Return a pointer to the current type. This is equivalent to
  /// PointerType::get(Foo, AddrSpace).
  PointerType *getPointerTo(unsigned AddrSpace = 0) const;

private:
  /// Derived types like structures and arrays are sized iff all of the members
  /// of the type are sized as well. Since asking for their size is relatively
  /// uncommon, move this operation out-of-line.
  bool isSizedDerivedType(SmallPtrSetImpl<Type*> *Visited = nullptr) const;
};

// Printing of types.
static inline raw_ostream &operator<<(raw_ostream &OS, const Type &T) {
  T.print(OS);
  return OS;
}

// allow isa<PointerType>(x) to work without DerivedTypes.h included.
template <> struct isa_impl<PointerType, Type> {
  static inline bool doit(const Type &Ty) {
    return Ty.getTypeID() == Type::PointerTyID;
  }
};

//===----------------------------------------------------------------------===//
// Provide specializations of GraphTraits to be able to treat a type as a
// graph of sub types.

template <> struct GraphTraits<Type *> {
  typedef Type *NodeRef;
  typedef Type::subtype_iterator ChildIteratorType;

  static NodeRef getEntryNode(Type *T) { return T; }
  static ChildIteratorType child_begin(NodeRef N) { return N->subtype_begin(); }
  static ChildIteratorType child_end(NodeRef N) { return N->subtype_end(); }
};

template <> struct GraphTraits<const Type*> {
  typedef const Type *NodeRef;
  typedef Type::subtype_iterator ChildIteratorType;

  static NodeRef getEntryNode(NodeRef T) { return T; }
  static ChildIteratorType child_begin(NodeRef N) { return N->subtype_begin(); }
  static ChildIteratorType child_end(NodeRef N) { return N->subtype_end(); }
};

// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_ISA_CONVERSION_FUNCTIONS(Type, LLVMTypeRef)

/* Specialized opaque type conversions.
 */
inline Type **unwrap(LLVMTypeRef* Tys) {
  return reinterpret_cast<Type**>(Tys);
}

inline LLVMTypeRef *wrap(Type **Tys) {
  return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
}

} // End llvm namespace

#endif
