//===-- go-llvm.h - LLVM implementation of gofrontend 'Btype' class -------===//
//
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//===----------------------------------------------------------------------===//
//
// Defines Llvm_backend and related classes
//
//===----------------------------------------------------------------------===//

#ifndef LLVMGOFRONTEND_GO_LLVM_BTYPE_H
#define LLVMGOFRONTEND_GO_LLVM_BTYPE_H

// Currently these need to be included before backend.h
#include "go-linemap.h"
#include "go-location.h"
#include "go-llvm-btype.h"

#include "backend.h"

namespace llvm {
class Type;
class Value;
class raw_ostream;
class DISubroutineType;
}

class BStructType;
class BArrayType;
class BPointerType;
class BIntegerType;
class BComplexType;
class BFloatType;
class BFunctionType;

// Btype wraps llvm::Type

class Btype {
 public:
  enum TyFlavor {
    ArrayT, ComplexT, FloatT, FunctionT, IntegerT, PointerT, StructT, AuxT
  };
  Btype(TyFlavor flavor, llvm::Type *type, Location location)
      : type_(type), location_(location), flavor_(flavor),
        isPlaceholder_(false) { }
  virtual ~Btype() { }

  TyFlavor flavor() const { return flavor_; }
  Location location() const { return location_; }
  void setLocation(Location loc) { location_ = loc; }

  // Underlying LLVM type.
  llvm::Type *type() const { return type_; }
  void setType(llvm::Type *t) { assert(t); type_ = t; }

  // Name of type if named.
  const std::string &name() const { return name_; }
  void setName(const std::string &name) { name_ = name; }

  // Whether this type is a placeholder. This can be set for type
  // explicitly created as placeholders (for example, something
  // returned from ::placeholder_pointer_type()) or it can be set in
  // cases where a primary type creation call is made by some sub-type
  // is a placeholder (for example, invoking ::pointer_type() with an
  // element type that is still a placeholder).
  bool isPlaceholder() const { return isPlaceholder_; }
  void setPlaceholder(bool v) { isPlaceholder_ = v; }

  // Similar to the above, but returns true for placeholder
  // struct types.
  bool isUnresolvedPlaceholder() const;

  // Create a shallow copy of this type
  Btype *clone() const;

  // debugging
  void dump() const;

  // dump to raw ostream buffer
  void osdump(llvm::raw_ostream &os, unsigned ilevel) const;

  // test for exact equality (including type names)
  bool equal(const Btype &other) const;

  // test for structural equality (ignores type names)
  bool equivalent(const Btype &other) const;

  // hash
  unsigned hash() const;

  // Cast to derived class (these return NULL if the type
  // does not have the appropriate flavor).
  inline BStructType *castToBStructType();
  inline BArrayType *castToBArrayType();
  inline BPointerType *castToBPointerType();
  inline BIntegerType *castToBIntegerType();
  inline BComplexType *castToBComplexType();
  inline BFloatType *castToBFloatType();
  inline BFunctionType *castToBFunctionType();
  inline const BStructType *castToBStructType() const;
  inline const BArrayType *castToBArrayType() const;
  inline const BPointerType *castToBPointerType() const;
  inline const BIntegerType *castToBIntegerType() const;
  inline const BComplexType *castToBComplexType() const;
  inline const BFloatType *castToBFloatType() const;
  inline const BFunctionType *castToBFunctionType() const;

 private:
  enum  CompareCtl { Default=0, IgnoreNames=1 };
  bool equalImpl(const Btype &other, CompareCtl ctl) const;
  Btype() : type_(NULL) {}
  std::string name_;
  llvm::Type *type_;
  Location location_;
  TyFlavor flavor_;
  bool isPlaceholder_;
};

class BIntegerType : public Btype {
 public:
  BIntegerType(bool isUnsigned, unsigned bits,
               llvm::Type *type, Location location)
      : Btype(IntegerT, type, location),
        bits_(bits), isUnsigned_(isUnsigned) { }

  bool isUnsigned() const { return isUnsigned_; }
  unsigned bits() const { return bits_; }

  // Create a shallow copy of this type
  Btype *clone() const {
    return new BIntegerType(isUnsigned_, bits_, type(), location());
  }

 private:
  unsigned bits_;
  bool isUnsigned_;
};

inline BIntegerType *Btype::castToBIntegerType() {
  return (flavor_ == IntegerT ? static_cast<BIntegerType *>(this)
          : nullptr);
}

inline const BIntegerType *Btype::castToBIntegerType() const {
  return (flavor_ == IntegerT ? static_cast<const BIntegerType *>(this)
          : nullptr);
}

class BComplexType : public Btype {
 public:
  BComplexType(unsigned bits, llvm::Type *type, Location location)
      : Btype(ComplexT, type, location), bits_(bits) { }

  // Here 'bits' is for the entire object, not for each sub-part
  unsigned bits() const { return bits_; }

  // Create a shallow copy of this type
  Btype *clone() const {
    return new BComplexType(bits_, type(), location());
  }

 private:
  unsigned bits_;
};

inline BComplexType *Btype::castToBComplexType() {
  return (flavor_ == ComplexT ? static_cast<BComplexType *>(this)
          : nullptr);
}

inline const BComplexType *Btype::castToBComplexType() const {
  return (flavor_ == ComplexT ? static_cast<const BComplexType *>(this)
          : nullptr);
}

class BFloatType : public Btype {
 public:
  BFloatType(unsigned bits, llvm::Type *type, Location location)
      : Btype(FloatT, type, location), bits_(bits) { }

  unsigned bits() const { return bits_; }

  // Create a shallow copy of this type
  Btype *clone() const {
    return new BFloatType(bits_, type(), location());
  }

 private:
  unsigned bits_;
};

inline BFloatType *Btype::castToBFloatType() {
  return (flavor_ == FloatT ? static_cast<BFloatType *>(this)
          : nullptr);
}

inline const BFloatType *Btype::castToBFloatType() const {
  return (flavor_ == FloatT ? static_cast<const BFloatType *>(this)
          : nullptr);
}

class BStructType : public Btype {
 public:

  // For concrete struct types
  BStructType(const std::vector<Backend::Btyped_identifier> &fields,
              llvm::Type *type, Location location)
      : Btype(StructT, type, location), fields_(fields) { }

  // For placeholder struct types
  BStructType(const std::string &name, Location location)
      : Btype(StructT, nullptr, location)
  {
    setPlaceholder(true);
    setName(name);
  }

  Btype *fieldType(unsigned idx) const {
    return fields_[idx].btype;
  }
  void setFieldType(unsigned idx, Btype *t) {
    assert(t);
    fields_[idx].btype = t;
  }
  const std::string &fieldName(unsigned idx) const {
    return fields_[idx].name;
  }
  const std::vector<Backend::Btyped_identifier> &fields() const {
    return fields_;
  }
  void setFields(const std::vector<Backend::Btyped_identifier> &fields) {
    fields_ = fields;
  }

  // Create a shallow copy of this type
  Btype *clone() const {
    return new BStructType(fields_, type(), location());
  }

 private:
  std::vector<Backend::Btyped_identifier> fields_;
};

inline BStructType *Btype::castToBStructType() {
  return (flavor_ == StructT ? static_cast<BStructType *>(this)
          : nullptr);
}

inline const BStructType *Btype::castToBStructType() const {
  return (flavor_ == StructT ? static_cast<const BStructType *>(this)
          : nullptr);
}

class BArrayType : public Btype {
 public:
  // For concrete array types
  BArrayType(Btype *elemType, Bexpression *nelements,
             llvm::Type *type, Location location)
      : Btype(ArrayT, type, location),
        elemType_(elemType), nelements_(nelements)
  {
    if (elemType_->isPlaceholder())
      setPlaceholder(true);
  }

  // For placeholder array types
  BArrayType(const std::string &name, Location location)
      : Btype(ArrayT, nullptr, location),
        elemType_(nullptr), nelements_(nullptr)
  {
    setPlaceholder(true);
    setName(name);
  }

  Btype *elemType() const {
    return elemType_;
  }
  void setElemType(Btype *t) {
    assert(t);
    elemType_ = t;
    if (elemType_->isPlaceholder())
      setPlaceholder(true);
  }
  Bexpression *nelements() const {
    return nelements_;
  }
  void setNelements(Bexpression *nel) { nelements_ = nel; }
  uint64_t nelSize() const;

  // Create a shallow copy of this type
  Btype *clone() const {
    return new BArrayType(elemType_, nelements_, type(), location());
  }

 private:
  Btype *elemType_;
  Bexpression *nelements_;
};

inline BArrayType *Btype::castToBArrayType() {
  return (flavor_ == ArrayT ? static_cast<BArrayType *>(this)
          : nullptr);
}

inline const BArrayType *Btype::castToBArrayType() const {
  return (flavor_ == ArrayT ? static_cast<const BArrayType *>(this)
          : nullptr);
}

class BPointerType : public Btype {
 public:
  // For concrete pointer types
  BPointerType(Btype *toType, llvm::Type *type, Location location)
      : Btype(PointerT, type, location), toType_(toType) {
    if (toType_->isPlaceholder())
      setPlaceholder(true);
  }

  // For placeholder pointers
  BPointerType(const std::string &name, Location location)
      : Btype(PointerT, nullptr, location), toType_(nullptr) {
    setPlaceholder(true);
    setName(name);
  }

  Btype *toType() const {
    return toType_;
  }
  void setToType(Btype *to) {
    toType_ = to;
  }

  // Create a shallow copy of this type
  Btype *clone() const {
    return new BPointerType(toType_, type(), location());
  }

 private:
  Btype *toType_;
};

inline BPointerType *Btype::castToBPointerType() {
  return (flavor_ == PointerT ? static_cast<BPointerType *>(this)
          : nullptr);
}

inline const BPointerType *Btype::castToBPointerType() const {
  return (flavor_ == PointerT ? static_cast<const BPointerType *>(this)
          : nullptr);
}

class BFunctionType : public Btype {
 public:
  BFunctionType(Btype *receiverType,
                const std::vector<Btype *> &paramTypes,
                const std::vector<Btype *> &resultTypes,
                Btype *rtype,
                llvm::Type *type,
                bool followsCabi,
                Location location)
      : Btype(FunctionT, type, location), receiverType_(receiverType),
        paramTypes_(paramTypes), resultTypes_(resultTypes),
        rtype_(rtype), followsCabi_(followsCabi) {
    assert(!receiverType || paramTypes[0] == receiverType);
  }

  Btype *resultType() const { return rtype_; }
  Btype *receiverType() const { return receiverType_; }

  // Does this function type follow ABI rules?
  bool followsCabi() const { return followsCabi_; }

  // Note that if the receiver type is non-null, it will
  // occupy the first slot in paramTypes.
  const std::vector<Btype *> &paramTypes() const { return paramTypes_; }

  // Create a shallow copy of this type
  Btype *clone() const {
    return new BFunctionType(receiverType_, paramTypes_, resultTypes_, rtype_,
                             type(), followsCabi(), location());
  }

 private:
  Btype *receiverType_;
  std::vector<Btype *> paramTypes_;
  std::vector<Btype *> resultTypes_;
  Btype *rtype_;
  bool followsCabi_;
};

inline BFunctionType *Btype::castToBFunctionType() {
  return (flavor_ == FunctionT ? static_cast<BFunctionType *>(this)
          : nullptr);
}
inline const BFunctionType *Btype::castToBFunctionType() const {
  return (flavor_ == FunctionT ? static_cast<const BFunctionType *>(this)
          : nullptr);
}

#endif // LLVMGOFRONTEND_GO_LLVM_BTYPE_H
