//===-- llvm/DerivedTypes.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 declarations of classes that represent "derived
// types".  These are things like "arrays of x" or "structure of x, y, z" or
// "function returning x taking (y,z) as parameters", etc...
//
// The implementations of these classes live in the Type.cpp file.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_IR_DERIVEDTYPES_H
#define LLVM_IR_DERIVEDTYPES_H

#include "llvm/IR/Type.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"

namespace llvm {

class Value;
class APInt;
class LLVMContext;
template<typename T> class ArrayRef;
class StringRef;

/// Class to represent integer types. Note that this class is also used to
/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
/// Int64Ty.
/// @brief Integer representation type
class IntegerType : public Type {
  friend class LLVMContextImpl;
  
protected:
  explicit IntegerType(LLVMContext &C, unsigned NumBits) : Type(C, IntegerTyID){
    setSubclassData(NumBits);
  }
public:
  /// This enum is just used to hold constants we need for IntegerType.
  enum {
    MIN_INT_BITS = 1,        ///< Minimum number of bits that can be specified
    MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified
      ///< Note that bit width is stored in the Type classes SubclassData field
      ///< which has 23 bits. This yields a maximum bit width of 8,388,607 bits.
  };

  /// This static method is the primary way of constructing an IntegerType.
  /// If an IntegerType with the same NumBits value was previously instantiated,
  /// that instance will be returned. Otherwise a new one will be created. Only
  /// one instance with a given NumBits value is ever created.
  /// @brief Get or create an IntegerType instance.
  static IntegerType *get(LLVMContext &C, unsigned NumBits);

  /// @brief Get the number of bits in this IntegerType
  unsigned getBitWidth() const { return getSubclassData(); }

  /// getBitMask - Return a bitmask with ones set for all of the bits
  /// that can be set by an unsigned version of this type.  This is 0xFF for
  /// i8, 0xFFFF for i16, etc.
  uint64_t getBitMask() const {
    return ~uint64_t(0UL) >> (64-getBitWidth());
  }

  /// getSignBit - Return a uint64_t with just the most significant bit set (the
  /// sign bit, if the value is treated as a signed number).
  uint64_t getSignBit() const {
    return 1ULL << (getBitWidth()-1);
  }

  /// For example, this is 0xFF for an 8 bit integer, 0xFFFF for i16, etc.
  /// @returns a bit mask with ones set for all the bits of this type.
  /// @brief Get a bit mask for this type.
  APInt getMask() const;

  /// This method determines if the width of this IntegerType is a power-of-2
  /// in terms of 8 bit bytes.
  /// @returns true if this is a power-of-2 byte width.
  /// @brief Is this a power-of-2 byte-width IntegerType ?
  bool isPowerOf2ByteWidth() const;

  /// Methods for support type inquiry through isa, cast, and dyn_cast.
  static inline bool classof(const Type *T) {
    return T->getTypeID() == IntegerTyID;
  }
};


/// FunctionType - Class to represent function types
///
class FunctionType : public Type {
  FunctionType(const FunctionType &) LLVM_DELETED_FUNCTION;
  const FunctionType &operator=(const FunctionType &) LLVM_DELETED_FUNCTION;
  FunctionType(Type *Result, ArrayRef<Type*> Params, bool IsVarArgs);

public:
  /// FunctionType::get - This static method is the primary way of constructing
  /// a FunctionType.
  ///
  static FunctionType *get(Type *Result,
                           ArrayRef<Type*> Params, bool isVarArg);

  /// FunctionType::get - Create a FunctionType taking no parameters.
  ///
  static FunctionType *get(Type *Result, bool isVarArg);
  
  /// isValidReturnType - Return true if the specified type is valid as a return
  /// type.
  static bool isValidReturnType(Type *RetTy);

  /// isValidArgumentType - Return true if the specified type is valid as an
  /// argument type.
  static bool isValidArgumentType(Type *ArgTy);

  bool isVarArg() const { return getSubclassData()!=0; }
  Type *getReturnType() const { return ContainedTys[0]; }

  typedef Type::subtype_iterator param_iterator;
  param_iterator param_begin() const { return ContainedTys + 1; }
  param_iterator param_end() const { return &ContainedTys[NumContainedTys]; }

  /// Parameter type accessors.
  Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }

  /// getNumParams - Return the number of fixed parameters this function type
  /// requires.  This does not consider varargs.
  ///
  unsigned getNumParams() const { return NumContainedTys - 1; }

  /// Methods for support type inquiry through isa, cast, and dyn_cast.
  static inline bool classof(const Type *T) {
    return T->getTypeID() == FunctionTyID;
  }
};


/// CompositeType - Common super class of ArrayType, StructType, PointerType
/// and VectorType.
class CompositeType : public Type {
protected:
  explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) { }
public:

  /// getTypeAtIndex - Given an index value into the type, return the type of
  /// the element.
  ///
  Type *getTypeAtIndex(const Value *V);
  Type *getTypeAtIndex(unsigned Idx);
  bool indexValid(const Value *V) const;
  bool indexValid(unsigned Idx) const;

  /// Methods for support type inquiry through isa, cast, and dyn_cast.
  static inline bool classof(const Type *T) {
    return T->getTypeID() == ArrayTyID ||
           T->getTypeID() == StructTyID ||
           T->getTypeID() == PointerTyID ||
           T->getTypeID() == VectorTyID;
  }
};


/// StructType - Class to represent struct types.  There are two different kinds
/// of struct types: Literal structs and Identified structs.
///
/// Literal struct types (e.g. { i32, i32 }) are uniqued structurally, and must
/// always have a body when created.  You can get one of these by using one of
/// the StructType::get() forms.
///  
/// Identified structs (e.g. %foo or %42) may optionally have a name and are not
/// uniqued.  The names for identified structs are managed at the LLVMContext
/// level, so there can only be a single identified struct with a given name in
/// a particular LLVMContext.  Identified structs may also optionally be opaque
/// (have no body specified).  You get one of these by using one of the
/// StructType::create() forms.
///
/// Independent of what kind of struct you have, the body of a struct type are
/// laid out in memory consequtively with the elements directly one after the
/// other (if the struct is packed) or (if not packed) with padding between the
/// elements as defined by DataLayout (which is required to match what the code
/// generator for a target expects).
///
class StructType : public CompositeType {
  StructType(const StructType &) LLVM_DELETED_FUNCTION;
  const StructType &operator=(const StructType &) LLVM_DELETED_FUNCTION;
  StructType(LLVMContext &C)
    : CompositeType(C, StructTyID), SymbolTableEntry(nullptr) {}
  enum {
    /// This is the contents of the SubClassData field.
    SCDB_HasBody = 1,
    SCDB_Packed = 2,
    SCDB_IsLiteral = 4,
    SCDB_IsSized = 8
  };

  /// SymbolTableEntry - For a named struct that actually has a name, this is a
  /// pointer to the symbol table entry (maintained by LLVMContext) for the
  /// struct.  This is null if the type is an literal struct or if it is
  /// a identified type that has an empty name.
  /// 
  void *SymbolTableEntry;
public:
  ~StructType() {
    delete [] ContainedTys; // Delete the body.
  }

  /// StructType::create - This creates an identified struct.
  static StructType *create(LLVMContext &Context, StringRef Name);
  static StructType *create(LLVMContext &Context);
  
  static StructType *create(ArrayRef<Type*> Elements,
                            StringRef Name,
                            bool isPacked = false);
  static StructType *create(ArrayRef<Type*> Elements);
  static StructType *create(LLVMContext &Context,
                            ArrayRef<Type*> Elements,
                            StringRef Name,
                            bool isPacked = false);
  static StructType *create(LLVMContext &Context, ArrayRef<Type*> Elements);
  static StructType *create(StringRef Name, Type *elt1, ...) END_WITH_NULL;

  /// StructType::get - This static method is the primary way to create a
  /// literal StructType.
  static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements,
                         bool isPacked = false);

  /// StructType::get - Create an empty structure type.
  ///
  static StructType *get(LLVMContext &Context, bool isPacked = false);
  
  /// StructType::get - This static method is a convenience method for creating
  /// structure types by specifying the elements as arguments.  Note that this
  /// method always returns a non-packed struct, and requires at least one
  /// element type.
  static StructType *get(Type *elt1, ...) END_WITH_NULL;

  bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
  
  /// isLiteral - Return true if this type is uniqued by structural
  /// equivalence, false if it is a struct definition.
  bool isLiteral() const { return (getSubclassData() & SCDB_IsLiteral) != 0; }
  
  /// isOpaque - Return true if this is a type with an identity that has no body
  /// specified yet.  These prints as 'opaque' in .ll files.
  bool isOpaque() const { return (getSubclassData() & SCDB_HasBody) == 0; }

  /// isSized - Return true if this is a sized type.
  bool isSized(SmallPtrSet<const Type*, 4> *Visited = nullptr) const;
  
  /// hasName - Return true if this is a named struct that has a non-empty name.
  bool hasName() const { return SymbolTableEntry != nullptr; }
  
  /// getName - Return the name for this struct type if it has an identity.
  /// This may return an empty string for an unnamed struct type.  Do not call
  /// this on an literal type.
  StringRef getName() const;
  
  /// setName - Change the name of this type to the specified name, or to a name
  /// with a suffix if there is a collision.  Do not call this on an literal
  /// type.
  void setName(StringRef Name);

  /// setBody - Specify a body for an opaque identified type.
  void setBody(ArrayRef<Type*> Elements, bool isPacked = false);
  void setBody(Type *elt1, ...) END_WITH_NULL;
  
  /// isValidElementType - Return true if the specified type is valid as a
  /// element type.
  static bool isValidElementType(Type *ElemTy);
  

  // Iterator access to the elements.
  typedef Type::subtype_iterator element_iterator;
  element_iterator element_begin() const { return ContainedTys; }
  element_iterator element_end() const { return &ContainedTys[NumContainedTys];}

  /// isLayoutIdentical - Return true if this is layout identical to the
  /// specified struct.
  bool isLayoutIdentical(StructType *Other) const;  
  
  /// Random access to the elements
  unsigned getNumElements() const { return NumContainedTys; }
  Type *getElementType(unsigned N) const {
    assert(N < NumContainedTys && "Element number out of range!");
    return ContainedTys[N];
  }

  /// Methods for support type inquiry through isa, cast, and dyn_cast.
  static inline bool classof(const Type *T) {
    return T->getTypeID() == StructTyID;
  }
};

/// SequentialType - This is the superclass of the array, pointer and vector
/// type classes.  All of these represent "arrays" in memory.  The array type
/// represents a specifically sized array, pointer types are unsized/unknown
/// size arrays, vector types represent specifically sized arrays that
/// allow for use of SIMD instructions.  SequentialType holds the common
/// features of all, which stem from the fact that all three lay their
/// components out in memory identically.
///
class SequentialType : public CompositeType {
  Type *ContainedType;               ///< Storage for the single contained type.
  SequentialType(const SequentialType &) LLVM_DELETED_FUNCTION;
  const SequentialType &operator=(const SequentialType &) LLVM_DELETED_FUNCTION;

protected:
  SequentialType(TypeID TID, Type *ElType)
    : CompositeType(ElType->getContext(), TID), ContainedType(ElType) {
    ContainedTys = &ContainedType;
    NumContainedTys = 1;
  }

public:
  Type *getElementType() const { return ContainedTys[0]; }

  /// Methods for support type inquiry through isa, cast, and dyn_cast.
  static inline bool classof(const Type *T) {
    return T->getTypeID() == ArrayTyID ||
           T->getTypeID() == PointerTyID ||
           T->getTypeID() == VectorTyID;
  }
};


/// ArrayType - Class to represent array types.
///
class ArrayType : public SequentialType {
  uint64_t NumElements;

  ArrayType(const ArrayType &) LLVM_DELETED_FUNCTION;
  const ArrayType &operator=(const ArrayType &) LLVM_DELETED_FUNCTION;
  ArrayType(Type *ElType, uint64_t NumEl);
public:
  /// ArrayType::get - This static method is the primary way to construct an
  /// ArrayType
  ///
  static ArrayType *get(Type *ElementType, uint64_t NumElements);

  /// isValidElementType - Return true if the specified type is valid as a
  /// element type.
  static bool isValidElementType(Type *ElemTy);

  uint64_t getNumElements() const { return NumElements; }

  /// Methods for support type inquiry through isa, cast, and dyn_cast.
  static inline bool classof(const Type *T) {
    return T->getTypeID() == ArrayTyID;
  }
};

/// VectorType - Class to represent vector types.
///
class VectorType : public SequentialType {
  unsigned NumElements;

  VectorType(const VectorType &) LLVM_DELETED_FUNCTION;
  const VectorType &operator=(const VectorType &) LLVM_DELETED_FUNCTION;
  VectorType(Type *ElType, unsigned NumEl);
public:
  /// VectorType::get - This static method is the primary way to construct an
  /// VectorType.
  ///
  static VectorType *get(Type *ElementType, unsigned NumElements);

  /// VectorType::getInteger - This static method gets a VectorType with the
  /// same number of elements as the input type, and the element type is an
  /// integer type of the same width as the input element type.
  ///
  static VectorType *getInteger(VectorType *VTy) {
    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
    assert(EltBits && "Element size must be of a non-zero size");
    Type *EltTy = IntegerType::get(VTy->getContext(), EltBits);
    return VectorType::get(EltTy, VTy->getNumElements());
  }

  /// VectorType::getExtendedElementVectorType - This static method is like
  /// getInteger except that the element types are twice as wide as the
  /// elements in the input type.
  ///
  static VectorType *getExtendedElementVectorType(VectorType *VTy) {
    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
    Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2);
    return VectorType::get(EltTy, VTy->getNumElements());
  }

  /// VectorType::getTruncatedElementVectorType - This static method is like
  /// getInteger except that the element types are half as wide as the
  /// elements in the input type.
  ///
  static VectorType *getTruncatedElementVectorType(VectorType *VTy) {
    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
    assert((EltBits & 1) == 0 &&
           "Cannot truncate vector element with odd bit-width");
    Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2);
    return VectorType::get(EltTy, VTy->getNumElements());
  }

  /// VectorType::getHalfElementsVectorType - This static method returns
  /// a VectorType with half as many elements as the input type and the
  /// same element type.
  ///
  static VectorType *getHalfElementsVectorType(VectorType *VTy) {
    unsigned NumElts = VTy->getNumElements();
    assert ((NumElts & 1) == 0 &&
            "Cannot halve vector with odd number of elements.");
    return VectorType::get(VTy->getElementType(), NumElts/2);
  }

  /// VectorType::getDoubleElementsVectorType - This static method returns
  /// a VectorType with twice  as many elements as the input type and the
  /// same element type.
  ///
  static VectorType *getDoubleElementsVectorType(VectorType *VTy) {
    unsigned NumElts = VTy->getNumElements();
    return VectorType::get(VTy->getElementType(), NumElts*2);
  }

  /// isValidElementType - Return true if the specified type is valid as a
  /// element type.
  static bool isValidElementType(Type *ElemTy);

  /// @brief Return the number of elements in the Vector type.
  unsigned getNumElements() const { return NumElements; }

  /// @brief Return the number of bits in the Vector type.
  /// Returns zero when the vector is a vector of pointers.
  unsigned getBitWidth() const {
    return NumElements * getElementType()->getPrimitiveSizeInBits();
  }

  /// Methods for support type inquiry through isa, cast, and dyn_cast.
  static inline bool classof(const Type *T) {
    return T->getTypeID() == VectorTyID;
  }
};


/// PointerType - Class to represent pointers.
///
class PointerType : public SequentialType {
  PointerType(const PointerType &) LLVM_DELETED_FUNCTION;
  const PointerType &operator=(const PointerType &) LLVM_DELETED_FUNCTION;
  explicit PointerType(Type *ElType, unsigned AddrSpace);
public:
  /// PointerType::get - This constructs a pointer to an object of the specified
  /// type in a numbered address space.
  static PointerType *get(Type *ElementType, unsigned AddressSpace);

  /// PointerType::getUnqual - This constructs a pointer to an object of the
  /// specified type in the generic address space (address space zero).
  static PointerType *getUnqual(Type *ElementType) {
    return PointerType::get(ElementType, 0);
  }

  /// isValidElementType - Return true if the specified type is valid as a
  /// element type.
  static bool isValidElementType(Type *ElemTy);

  /// @brief Return the address space of the Pointer type.
  inline unsigned getAddressSpace() const { return getSubclassData(); }

  /// Implement support type inquiry through isa, cast, and dyn_cast.
  static inline bool classof(const Type *T) {
    return T->getTypeID() == PointerTyID;
  }
};

} // End llvm namespace

#endif
