//===-- IntegAssembler.cpp ------------------------------------------------===//
//
// Copyright 2020 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.
//
//===----------------------------------------------------------------------===//
//
// Gollvm driver helper class "IntegAssembler" methods.
//
//===----------------------------------------------------------------------===//

#include "IntegAssembler.h"

#include "go-llvm-linemap.h"
#include "go-llvm-diagnostics.h"
#include "go-llvm.h"
#include "go-c.h"
#include "mpfr.h"
#include "GollvmOptions.h"
#include "GollvmConfig.h"
#include "GollvmPasses.h"

#include "Action.h"
#include "Artifact.h"
#include "Driver.h"
#include "ToolChain.h"

#include "llvm/ADT/Triple.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"

#include <sstream>

using namespace llvm;

namespace gollvm {
namespace driver {

class IntegAssemblerImpl {
 public:
  IntegAssemblerImpl(IntegAssembler &ia, ToolChain &tc, const std::string &executablePath);

  // Perform compilation.
  bool performAction(Compilation &compilation,
                     const Action &jobAction,
                     const ArtifactList &inputArtifacts,
                     const Artifact &output);

 private:
  IntegAssembler &ia_;
  Triple triple_;
  const ToolChain &toolchain_;
  Driver &driver_;
  LLVMContext context_;
  const char *progname_;
  std::string executablePath_;
  opt::InputArgList &args_;
  std::string inputFileName_;
  std::string objOutFileName_;
  std::unique_ptr<raw_fd_ostream> objout_;

  bool resolveInputOutput(const Action &jobAction,
                          const ArtifactList &inputArtifacts,
                          const Artifact &output);
  bool invokeAssembler();
};

IntegAssemblerImpl::IntegAssemblerImpl(IntegAssembler &ia, ToolChain &tc, const std::string &executablePath)
    : ia_(ia),
      triple_(tc.driver().triple()),
      toolchain_(tc),
      driver_(tc.driver()),
      progname_(tc.driver().progname()),
      executablePath_(executablePath),
      args_(tc.driver().args())
{
  InitializeAllTargets();
  InitializeAllTargetMCs();
  InitializeAllAsmPrinters();
  InitializeAllAsmParsers();
}

bool IntegAssemblerImpl::resolveInputOutput(const Action &jobAction,
                                            const ArtifactList &inputArtifacts,
                                            const Artifact &output)
{
  // Collect input file. Should be only one.
  if (inputArtifacts.size() != 1) {
    errs() << progname_ << ": expected exactly one input file, "
           << inputArtifacts.size() << " provided.\n";
    return false;
  }
  inputFileName_ = inputArtifacts[0]->file();
  objOutFileName_ = output.file();

  // Remove output on signal.
  if (objOutFileName_ != "-")
    sys::RemoveFileOnSignal(objOutFileName_);

  // Open output file.
  std::error_code EC;
  sys::fs::OpenFlags OpenFlags = sys::fs::OF_None;
  objout_ = std::make_unique<raw_fd_ostream>(
      objOutFileName_, EC, OpenFlags);
  if (EC) {
    errs() << progname_ << ": error opening " << objOutFileName_ << ": "
           << EC.message() << '\n';
    return false;
  }
  return true;
}

bool IntegAssemblerImpl::invokeAssembler()
{
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget("", triple_, Error);
  if (!TheTarget) {
    errs() << progname_ << ": unknown/unsupported target "
           << triple_.str() << "\n";
    return false;
  }

  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
      MemoryBuffer::getFileOrSTDIN(inputFileName_);
  if (std::error_code EC = Buffer.getError()) {
    Error = EC.message();
    errs() << progname_ << ": opening/reading " << inputFileName_ << ": "
           << EC.message() << "\n";
    return false;
  }

  auto Trip = triple_.str();
  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(driver_.args().getAllArgValues(gollvm::options::OPT_I));

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Trip));
  assert(MRI && "Unable to create target register info!");

  MCTargetOptions MCOptions;
  std::unique_ptr<MCAsmInfo> MAI(
      TheTarget->createMCAsmInfo(*MRI, Trip, MCOptions));
  assert(MAI && "Unable to create target asm info!");

  // Note: -Xassembler and -Wa, options should already have been
  // examined at this point.

  // FIXME: no support yet for -march (bring over from CompileGo.cpp)
  opt::Arg *cpuarg = args_.getLastArg(gollvm::options::OPT_march_EQ);
  if (cpuarg != nullptr) {
    errs() << progname_ << ": internal error: option '"
           <<  cpuarg->getAsString(args_)
           << "' not yet implemented in integrated assembler\n";
    assert(false);
    return false;
  }

  // Support for compressed debug.
  llvm::DebugCompressionType CompressDebugSections =
      llvm::DebugCompressionType::None;
  if (!driver_.determineDebugCompressionType(&CompressDebugSections))
    return false;

  // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
  // may be created with a combination of default and explicit settings.
  MAI->setCompressDebugSections(CompressDebugSections);

  // Build up the feature string from the target feature list.
  std::string FS;
  std::string CPU;
  std::unique_ptr<MCStreamer> Str;
  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(Trip, CPU, FS));

  MCContext Ctx(triple_, MAI.get(), MRI.get(), STI.get(), &SrcMgr, &MCOptions);

  bool PIC = (driver_.getPicLevel() != PICLevel::NotPIC);
  Ctx.setGenDwarfForAssembly(true);

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  std::unique_ptr<MCObjectFileInfo> MOFI(
      TheTarget->createMCObjectFileInfo(Ctx, PIC));
  Ctx.setObjectFileInfo(MOFI.get());

  // Use current dir (llvm-goc does not yet support -fdebug-compilation-dir)
  SmallString<128> CWD;
  if (!sys::fs::current_path(CWD))
    Ctx.setCompilationDir(CWD);

  // Honor -fdebug-prefix=... option.
  for (const auto &arg : driver_.args().getAllArgValues(gollvm::options::OPT_fdebug_prefix_map_EQ)) {
    std::pair<StringRef, StringRef> p = StringRef(arg).split('=');
    Ctx.addDebugPrefixMapEntry(std::string(p.first), std::string(p.second));
  }


  StringRef BaseName = llvm::sys::path::filename(inputFileName_);
  Ctx.setMainFileName(BaseName);
  // FIXME: incorporate version here?
  Ctx.setDwarfDebugProducer("llvm-goc");

  raw_pwrite_stream *Out = objout_.get();
  std::unique_ptr<buffer_ostream> BOS;

  if (!objout_->supportsSeeking()) {
    BOS = std::make_unique<buffer_ostream>(*objout_);
    Out = BOS.get();
  }

  std::unique_ptr<MCCodeEmitter> CE(
      TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
  std::unique_ptr<MCAsmBackend> MAB(
      TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
  std::unique_ptr<MCObjectWriter> OW = MAB->createObjectWriter(*Out);

  Triple T(driver_.triple());
  unsigned RelaxAll = 0;
  unsigned IncrementalLinkerCompatible = 0;
  Str.reset(TheTarget->createMCObjectStreamer(
      T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI,
      RelaxAll, IncrementalLinkerCompatible,
        /*DWARFMustBeAtTheEnd*/ true));

  bool NoExecStack = true;
  Str.get()->initSections(NoExecStack, *STI);

  // Assembly to object compilation should leverage assembly info.
  Str->setUseAssemblerInfoForParsing(true);

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));

  std::unique_ptr<MCTargetAsmParser> TAP(
      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
  if (!TAP) {
    errs() << progname_ << ": error: unknown triple"
           << triple_.str() << "\n";
    return false;
  }

  // FIXME: add support for -Wa,-defsym here?

  Parser->setTargetParser(*TAP.get());
  bool NoInitialTextSection = false;
  auto Failed = Parser->Run(NoInitialTextSection);

  // Close Streamer first.
  // It might have a reference to the output stream.
  Str.reset();
  // Close the output stream early.
  BOS.reset();
  objout_.reset();

  // Delete output file if there were errors.
  if (Failed) {
    if (objOutFileName_ != "-")
      sys::fs::remove(objOutFileName_);
  }

  return !Failed;
}

bool IntegAssemblerImpl::performAction(Compilation &compilation,
                                  const Action &jobAction,
                                  const ArtifactList &inputArtifacts,
                                  const Artifact &output)
{
  if (ia_.emitMinusVOrHashHashHash(triple_, output, jobAction))
    return true;

  // Resolve input/output files.
  if (!resolveInputOutput(jobAction, inputArtifacts, output))
    return false;

  // Invoke back end
  if (!invokeAssembler())
    return false;

  return true;
}

//........................................................................

IntegAssembler::IntegAssembler(ToolChain &tc, const std::string &executablePath)
    : InternalTool("integassembler", tc, executablePath),
      impl_(new IntegAssemblerImpl(*this, tc, executablePath))
{
}

IntegAssembler::~IntegAssembler()
{
}

bool IntegAssembler::performAction(Compilation &compilation,
                              const Action &jobAction,
                              const ArtifactList &inputArtifacts,
                              const Artifact &output)
{
  return impl_->performAction(compilation, jobAction, inputArtifacts, output);
}


} // end namespace driver
} // end namespace gollvm
