//===- subzero/src/IceGlobalInits.h - Global declarations -------*- C++ -*-===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Declares the representation of function declarations, global variable
/// declarations, and the corresponding variable initializers in Subzero.
///
/// Global variable initializers are represented as a sequence of simple
/// initializers.
///
//===----------------------------------------------------------------------===//

#ifndef SUBZERO_SRC_ICEGLOBALINITS_H
#define SUBZERO_SRC_ICEGLOBALINITS_H

#include "IceDefs.h"
#include "IceFixups.h"
#include "IceGlobalContext.h"
#include "IceIntrinsics.h"
#include "IceMangling.h"
#include "IceOperand.h"
#include "IceTypes.h"

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#endif // __clang__

#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" // for NaClBitcodeRecord.
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/GlobalValue.h" // for GlobalValue::LinkageTypes.

#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__

#include <memory>
#include <utility>

// TODO(kschimpf): Remove ourselves from using LLVM representation for calling
// conventions and linkage types.

namespace Ice {

/// Base class for global variable and function declarations.
class GlobalDeclaration {
  GlobalDeclaration() = delete;
  GlobalDeclaration(const GlobalDeclaration &) = delete;
  GlobalDeclaration &operator=(const GlobalDeclaration &) = delete;

public:
  /// Discriminator for LLVM-style RTTI.
  enum GlobalDeclarationKind {
    FunctionDeclarationKind,
    VariableDeclarationKind
  };
  GlobalDeclarationKind getKind() const { return Kind; }
  GlobalString getName() const { return Name; }
  void setName(GlobalContext *Ctx, const std::string &NewName) {
    Name = Ctx->getGlobalString(getSuppressMangling() ? NewName
                                                      : mangleName(NewName));
  }
  void setName(GlobalString NewName) { Name = NewName; }
  void setName(GlobalContext *Ctx) {
    Name = GlobalString::createWithoutString(Ctx);
  }
  bool hasName() const { return Name.hasStdString(); }
  bool isInternal() const {
    return Linkage == llvm::GlobalValue::InternalLinkage;
  }
  llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; }
  void setLinkage(llvm::GlobalValue::LinkageTypes L) {
    assert(!hasName());
    Linkage = L;
  }
  bool isExternal() const {
    return Linkage == llvm::GlobalValue::ExternalLinkage;
  }
  virtual ~GlobalDeclaration() = default;

  /// Prints out type of the global declaration.
  virtual void dumpType(Ostream &Stream) const = 0;

  /// Prints out the global declaration.
  virtual void dump(Ostream &Stream) const = 0;

  /// Returns true if when emitting names, we should suppress mangling.
  virtual bool getSuppressMangling() const = 0;

  /// Returns textual name of linkage.
  const char *getLinkageName() const {
    return isInternal() ? "internal" : "external";
  }

  /// Returns true if the name of this GlobalDeclaration indicates that it
  /// should have ExternalLinkage (as a special case).
  virtual bool isPNaClABIExternalName(const std::string &Name) const = 0;

protected:
  GlobalDeclaration(GlobalDeclarationKind Kind,
                    llvm::GlobalValue::LinkageTypes Linkage)
      : Kind(Kind), Linkage(Linkage) {}

  /// Returns true if linkage is defined correctly for the global declaration,
  /// based on default rules.
  bool verifyLinkageDefault() const {
    switch (Linkage) {
    default:
      return false;
    case llvm::GlobalValue::InternalLinkage:
      return true;
    case llvm::GlobalValue::ExternalLinkage:
      return getFlags().getAllowExternDefinedSymbols();
    }
  }

  const GlobalDeclarationKind Kind;
  llvm::GlobalValue::LinkageTypes Linkage;
  GlobalString Name;
};

/// Models a function declaration. This includes the type signature of the
/// function, its calling conventions, and its linkage.
class FunctionDeclaration : public GlobalDeclaration {
  FunctionDeclaration() = delete;
  FunctionDeclaration(const FunctionDeclaration &) = delete;
  FunctionDeclaration &operator=(const FunctionDeclaration &) = delete;

public:
  static FunctionDeclaration *create(GlobalContext *Context,
                                     const FuncSigType &Signature,
                                     llvm::CallingConv::ID CallingConv,
                                     llvm::GlobalValue::LinkageTypes Linkage,
                                     bool IsProto) {
    return new (Context->allocate<FunctionDeclaration>())
        FunctionDeclaration(Signature, CallingConv, Linkage, IsProto);
  }
  const FuncSigType &getSignature() const { return Signature; }
  llvm::CallingConv::ID getCallingConv() const { return CallingConv; }
  /// isProto implies that there isn't a (local) definition for the function.
  bool isProto() const { return IsProto; }
  static bool classof(const GlobalDeclaration *Addr) {
    return Addr->getKind() == FunctionDeclarationKind;
  }
  void dumpType(Ostream &Stream) const final;
  void dump(Ostream &Stream) const final;
  bool getSuppressMangling() const final { return isExternal() && IsProto; }

  /// Returns true if linkage is correct for the function declaration.
  bool verifyLinkageCorrect(const GlobalContext *Ctx) const {
    if (getName().hasStdString()) {
      if (isPNaClABIExternalName(getName().toString()) ||
          isIntrinsicName(Ctx)) {
        return Linkage == llvm::GlobalValue::ExternalLinkage;
      }
    }
    return verifyLinkageDefault();
  }

  /// Validates that the type signature of the function is correct. Returns true
  /// if valid.
  bool validateTypeSignature(const GlobalContext *Ctx) const {
    bool IsIntrinsic;
    if (const Intrinsics::FullIntrinsicInfo *Info =
            getIntrinsicInfo(Ctx, &IsIntrinsic))
      return validateIntrinsicTypeSignature(Info);
    return !IsIntrinsic && validateRegularTypeSignature();
  }

  /// Generates an error message describing why validateTypeSignature returns
  /// false.
  std::string getTypeSignatureError(const GlobalContext *Ctx);

  /// Returns corresponding PNaCl intrisic information.
  const Intrinsics::FullIntrinsicInfo *
  getIntrinsicInfo(const GlobalContext *Ctx) const {
    bool BadIntrinsic;
    return getIntrinsicInfo(Ctx, &BadIntrinsic);
  }

  /// Same as above, except IsIntrinsic is true if the function is intrinsic
  /// (even if not a PNaCl intrinsic).
  const Intrinsics::FullIntrinsicInfo *
  getIntrinsicInfo(const GlobalContext *Ctx, bool *IsIntrinsic) const;

private:
  const Ice::FuncSigType Signature;
  llvm::CallingConv::ID CallingConv;
  const bool IsProto;

  FunctionDeclaration(const FuncSigType &Signature,
                      llvm::CallingConv::ID CallingConv,
                      llvm::GlobalValue::LinkageTypes Linkage, bool IsProto)
      : GlobalDeclaration(FunctionDeclarationKind, Linkage),
        Signature(Signature), CallingConv(CallingConv), IsProto(IsProto) {}

  bool isPNaClABIExternalName(const std::string &Name) const override {
    return Name == "_start";
  }

  bool isIntrinsicName(const GlobalContext *Ctx) const {
    bool IsIntrinsic;
    getIntrinsicInfo(Ctx, &IsIntrinsic);
    return IsIntrinsic;
  }

  bool validateRegularTypeSignature() const;

  bool validateIntrinsicTypeSignature(
      const Intrinsics::FullIntrinsicInfo *Info) const;
};

/// Models a global variable declaration, and its initializers.
class VariableDeclaration : public GlobalDeclaration {
  VariableDeclaration(const VariableDeclaration &) = delete;
  VariableDeclaration &operator=(const VariableDeclaration &) = delete;

public:
  /// Base class for a global variable initializer.
  class Initializer {
    Initializer(const Initializer &) = delete;
    Initializer &operator=(const Initializer &) = delete;

  public:
    /// Discriminator for LLVM-style RTTI.
    enum InitializerKind {
      DataInitializerKind,
      ZeroInitializerKind,
      RelocInitializerKind
    };
    InitializerKind getKind() const { return Kind; }
    virtual SizeT getNumBytes() const = 0;
    virtual void dump(Ostream &Stream) const = 0;
    virtual void dumpType(Ostream &Stream) const;

  protected:
    explicit Initializer(InitializerKind Kind) : Kind(Kind) {}

  private:
    const InitializerKind Kind;
  };
  static_assert(std::is_trivially_destructible<Initializer>::value,
                "Initializer must be trivially destructible.");

  /// Models the data in a data initializer.
  using DataVecType = char *;

  /// Defines a sequence of byte values as a data initializer.
  class DataInitializer : public Initializer {
    DataInitializer(const DataInitializer &) = delete;
    DataInitializer &operator=(const DataInitializer &) = delete;

  public:
    template <class... Args>
    static DataInitializer *create(VariableDeclarationList *VDL,
                                   Args &&... TheArgs) {
      return new (VDL->allocate_initializer<DataInitializer>())
          DataInitializer(VDL, std::forward<Args>(TheArgs)...);
    }

    const llvm::StringRef getContents() const {
      return llvm::StringRef(Contents, ContentsSize);
    }
    SizeT getNumBytes() const final { return ContentsSize; }
    void dump(Ostream &Stream) const final;
    static bool classof(const Initializer *D) {
      return D->getKind() == DataInitializerKind;
    }

  private:
    DataInitializer(VariableDeclarationList *VDL,
                    const llvm::NaClBitcodeRecord::RecordVector &Values)
        : Initializer(DataInitializerKind), ContentsSize(Values.size()),
          // ugh, we should actually do new char[], but this may involve
          // implementation-specific details. Given that Contents is arena
          // allocated, and never delete[]d, just use char --
          // AllocOwner->allocate_array will allocate a buffer with the right
          // size.
          Contents(new (VDL->allocate_initializer<char>(ContentsSize)) char) {
      for (SizeT I = 0; I < Values.size(); ++I)
        Contents[I] = static_cast<int8_t>(Values[I]);
    }

    DataInitializer(VariableDeclarationList *VDL, const char *Str,
                    size_t StrLen)
        : Initializer(DataInitializerKind), ContentsSize(StrLen),
          Contents(new (VDL->allocate_initializer<char>(ContentsSize)) char) {
      for (size_t i = 0; i < StrLen; ++i)
        Contents[i] = Str[i];
    }

    /// The byte contents of the data initializer.
    const SizeT ContentsSize;
    DataVecType Contents;
  };
  static_assert(std::is_trivially_destructible<DataInitializer>::value,
                "DataInitializer must be trivially destructible.");

  /// Defines a sequence of bytes initialized to zero.
  class ZeroInitializer : public Initializer {
    ZeroInitializer(const ZeroInitializer &) = delete;
    ZeroInitializer &operator=(const ZeroInitializer &) = delete;

  public:
    static ZeroInitializer *create(VariableDeclarationList *VDL, SizeT Size) {
      return new (VDL->allocate_initializer<ZeroInitializer>())
          ZeroInitializer(Size);
    }
    SizeT getNumBytes() const final { return Size; }
    void dump(Ostream &Stream) const final;
    static bool classof(const Initializer *Z) {
      return Z->getKind() == ZeroInitializerKind;
    }

  private:
    explicit ZeroInitializer(SizeT Size)
        : Initializer(ZeroInitializerKind), Size(Size) {}

    /// The number of bytes to be zero initialized.
    SizeT Size;
  };
  static_assert(std::is_trivially_destructible<ZeroInitializer>::value,
                "ZeroInitializer must be trivially destructible.");

  /// Defines the relocation value of another global declaration.
  class RelocInitializer : public Initializer {
    RelocInitializer(const RelocInitializer &) = delete;
    RelocInitializer &operator=(const RelocInitializer &) = delete;

  public:
    static RelocInitializer *create(VariableDeclarationList *VDL,
                                    const GlobalDeclaration *Declaration,
                                    const RelocOffsetArray &OffsetExpr) {
      constexpr bool NoFixup = false;
      return new (VDL->allocate_initializer<RelocInitializer>())
          RelocInitializer(VDL, Declaration, OffsetExpr, NoFixup);
    }

    static RelocInitializer *create(VariableDeclarationList *VDL,
                                    const GlobalDeclaration *Declaration,
                                    const RelocOffsetArray &OffsetExpr,
                                    FixupKind Fixup) {
      constexpr bool HasFixup = true;
      return new (VDL->allocate_initializer<RelocInitializer>())
          RelocInitializer(VDL, Declaration, OffsetExpr, HasFixup, Fixup);
    }

    RelocOffsetT getOffset() const {
      RelocOffsetT Offset = 0;
      for (SizeT i = 0; i < OffsetExprSize; ++i) {
        Offset += OffsetExpr[i]->getOffset();
      }
      return Offset;
    }

    bool hasFixup() const { return HasFixup; }
    FixupKind getFixup() const {
      assert(HasFixup);
      return Fixup;
    }

    const GlobalDeclaration *getDeclaration() const { return Declaration; }
    SizeT getNumBytes() const final { return RelocAddrSize; }
    void dump(Ostream &Stream) const final;
    void dumpType(Ostream &Stream) const final;
    static bool classof(const Initializer *R) {
      return R->getKind() == RelocInitializerKind;
    }

  private:
    RelocInitializer(VariableDeclarationList *VDL,
                     const GlobalDeclaration *Declaration,
                     const RelocOffsetArray &OffsetExpr, bool HasFixup,
                     FixupKind Fixup = 0)
        : Initializer(RelocInitializerKind),
          Declaration(Declaration), // The global declaration used in the reloc.
          OffsetExprSize(OffsetExpr.size()),
          OffsetExpr(new (VDL->allocate_initializer<RelocOffset *>(
              OffsetExprSize)) RelocOffset *),
          HasFixup(HasFixup), Fixup(Fixup) {
      for (SizeT i = 0; i < OffsetExprSize; ++i) {
        this->OffsetExpr[i] = OffsetExpr[i];
      }
    }

    const GlobalDeclaration *Declaration;
    /// The offset to add to the relocation.
    const SizeT OffsetExprSize;
    RelocOffset **OffsetExpr;
    const bool HasFixup = false;
    const FixupKind Fixup = 0;
  };
  static_assert(std::is_trivially_destructible<RelocInitializer>::value,
                "RelocInitializer must be trivially destructible.");

  /// Models the list of initializers.
  // TODO(jpp): missing allocator.
  using InitializerListType = std::vector<Initializer *>;

  static VariableDeclaration *create(VariableDeclarationList *VDL,
                                     bool SuppressMangling = false,
                                     llvm::GlobalValue::LinkageTypes Linkage =
                                         llvm::GlobalValue::InternalLinkage) {
    return new (VDL->allocate_variable_declaration<VariableDeclaration>())
        VariableDeclaration(Linkage, SuppressMangling);
  }

  static VariableDeclaration *createExternal(VariableDeclarationList *VDL) {
    constexpr bool SuppressMangling = true;
    constexpr llvm::GlobalValue::LinkageTypes Linkage =
        llvm::GlobalValue::ExternalLinkage;
    return create(VDL, SuppressMangling, Linkage);
  }

  const InitializerListType &getInitializers() const { return Initializers; }
  bool getIsConstant() const { return IsConstant; }
  void setIsConstant(bool NewValue) { IsConstant = NewValue; }
  uint32_t getAlignment() const { return Alignment; }
  void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; }
  bool hasInitializer() const { return HasInitializer; }
  bool hasNonzeroInitializer() const {
    return !(Initializers.size() == 1 &&
             llvm::isa<ZeroInitializer>(Initializers[0]));
  }

  /// Returns the number of bytes for the initializer of the global address.
  SizeT getNumBytes() const {
    SizeT Count = 0;
    for (const auto *Init : Initializers) {
      Count += Init->getNumBytes();
    }
    return Count;
  }

  /// Adds Initializer to the list of initializers. Takes ownership of the
  /// initializer.
  void addInitializer(Initializer *Initializer) {
    const bool OldSuppressMangling = getSuppressMangling();
    Initializers.emplace_back(Initializer);
    HasInitializer = true;
    // The getSuppressMangling() logic depends on whether the global variable
    // has initializers.  If its value changed as a result of adding an
    // initializer, then make sure we haven't previously set the name based on
    // faulty SuppressMangling logic.
    const bool SameMangling = (OldSuppressMangling == getSuppressMangling());
    (void)SameMangling;
    assert(Name.hasStdString() || SameMangling);
  }

  /// Prints out type for initializer associated with the declaration to Stream.
  void dumpType(Ostream &Stream) const final;

  /// Prints out the definition of the global variable declaration (including
  /// initialization).
  virtual void dump(Ostream &Stream) const override;

  /// Returns true if linkage is correct for the variable declaration.
  bool verifyLinkageCorrect() const {
    if (getName().hasStdString()) {
      if (isPNaClABIExternalName(getName().toString())) {
        return Linkage == llvm::GlobalValue::ExternalLinkage;
      }
    }
    return verifyLinkageDefault();
  }

  static bool classof(const GlobalDeclaration *Addr) {
    return Addr->getKind() == VariableDeclarationKind;
  }

  bool getSuppressMangling() const final {
    if (ForceSuppressMangling)
      return true;
    return isExternal() && !hasInitializer();
  }

  void discardInitializers() { Initializers.clear(); }

  bool isPNaClABIExternalName(const std::string &Name) const override {
    return Name == "__pnacl_pso_root";
  }

private:
  /// List of initializers for the declared variable.
  InitializerListType Initializers;
  bool HasInitializer = false;
  /// The alignment of the declared variable.
  uint32_t Alignment = 0;
  /// True if a declared (global) constant.
  bool IsConstant = false;
  /// If set to true, force getSuppressMangling() to return true.
  const bool ForceSuppressMangling;

  VariableDeclaration(llvm::GlobalValue::LinkageTypes Linkage,
                      bool SuppressMangling)
      : GlobalDeclaration(VariableDeclarationKind, Linkage),
        ForceSuppressMangling(SuppressMangling) {}
};

template <class StreamType>
inline StreamType &operator<<(StreamType &Stream,
                              const VariableDeclaration::Initializer &Init) {
  Init.dump(Stream);
  return Stream;
}

template <class StreamType>
inline StreamType &operator<<(StreamType &Stream,
                              const GlobalDeclaration &Addr) {
  Addr.dump(Stream);
  return Stream;
}

} // end of namespace Ice

#endif // SUBZERO_SRC_ICEGLOBALINITS_H
