//===-- llvm-goc.cpp - compiler driver for gollvm  ------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
//
// Compiler driver for gollvm. Invokes frontend / backend to compile
// Go code into assembly and/or object files, and orchestrates process
// of assembling and linking if needed.
//
//===----------------------------------------------------------------------===//

#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 "Compilation.h"
#include "Driver.h"
#include "ToolChain.h"
#include "Tool.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Verifier.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

#include <algorithm>
#include <cstring>
#include <string>
#include <system_error>
#include <sys/types.h>
#include <unistd.h>

using namespace llvm;
using namespace gollvm::driver;

class CommandLineParser {
 public:
  CommandLineParser(opt::OptTable *opts)
      : opts_(opts)
  { }

  bool parseCommandLine(int argc, char **argv);

  opt::InputArgList &args() { return args_; }

 private:
  opt::OptTable *opts_;
  opt::InputArgList args_;
};

bool CommandLineParser::parseCommandLine(int argc, char **argv)
{
  const char *progname = argv[0];

  unsigned missingArgIndex, missingArgCount;
  ArrayRef<const char *> argvv = makeArrayRef(argv, argc);
  args_ = opts_->ParseArgs(argvv.slice(1), missingArgIndex, missingArgCount);

  // Honor --help first
  if (args_.hasArg(gollvm::options::OPT_help)) {
    opts_->PrintHelp(errs(), progname, "Gollvm (LLVM-based Go compiler)",
                     0, 0, false);
    exit(0);
  }

  // Honor -dumpversion
  if (args_.hasArg(gollvm::options::OPT_dumpversion)) {
    llvm::outs() << GOLLVM_COMPILERVERSION << "\n";
    exit(0);
  }

  // Honor -version
  if (args_.hasArg(gollvm::options::OPT_version)) {
    Driver::emitVersion();
    exit(0);
  }

  // Honor --print-multi-lib. FIXME: add real multilib support.
  if (args_.hasArg(gollvm::options::OPT_print_multi_lib)) {
    llvm::outs() << ".;@m64\n";
    exit(0);
  }

  // Complain about missing arguments.
  if (missingArgIndex != 0) {
    errs() << progname << ": error: argument to '"
           << args_.getArgString(missingArgIndex)
           << "' option missing, espected "
           << missingArgCount << " value(s)\n";
    return false;
  }

  // Check for unsupported options.
  for (const opt::Arg *arg : args_) {
    if (arg->getOption().hasFlag(gollvm::options::Unsupported)) {
      errs() << progname << ": error: unsupported command line option '"
             << arg->getAsString(args_) << "'\n";
      return false;
    }
  }

  // Check for unknown options.
  bool foundUnknown = false;
  for (const opt::Arg *arg : args_.filtered(gollvm::options::OPT_UNKNOWN)) {
    errs() << progname << ": error: unrecognized command line option '"
             << arg->getAsString(args_) << "'\n";
    foundUnknown = true;
  }
  if (foundUnknown)
    return false;

  // Honor -mllvm
  auto llvmargs = args_.getAllArgValues(gollvm::options::OPT_mllvm);
  if (! llvmargs.empty()) {
    unsigned nargs = llvmargs.size();
    auto args = std::make_unique<const char*[]>(nargs + 2);
    args[0] = "gollvm (LLVM option parsing)";
    for (unsigned i = 0; i != nargs; ++i)
      args[i + 1] = llvmargs[i].c_str();
    args[nargs + 1] = nullptr;
    llvm::cl::ParseCommandLineOptions(nargs + 1, args.get());
  }

  // HACK: the go tool likes to invoke the C and Go compiler drivers
  // at various points to detect whether a given command line flag is
  // supported (ex: "gcc -x c - -someflag < /dev/null"), and tends to
  // pass "-x c" even when the driver is gccgo. Gccgo is (mirabile
  // dictu) a functional C compiler, but gollvm is not. For the time
  // being we will "fake it" by allowing "-x ... -" but then requiring
  // that standard input be empty (so as to support the Go tool, but
  // not act as a general-purposes C compiler).
  opt::Arg *xarg = args_.getLastArg(gollvm::options::OPT_x);
  if (xarg != nullptr &&
      ! llvm::StringRef(xarg->getValue()).equals("c") &&
      ! llvm::StringRef(xarg->getValue()).equals("go")) {
    errs() << progname << ": invalid argument '"
           << xarg->getValue() << "' to '"
           << xarg->getAsString(args_) << "' option\n";
    return false;
  }

  return true;
}

int main(int argc, char **argv)
{
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal(argv[0]);
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Parse command line.
  std::unique_ptr<opt::OptTable> opts =
      gollvm::options::createGollvmDriverOptTable();
  CommandLineParser clp(opts.get());
  if (!clp.parseCommandLine(argc, argv))
    return 1;

  // Create driver.
  Driver driver(clp.args(), opts.get(), argv[0]);

  // Set up driver, select target and toolchain.
  ToolChain *toolchain = driver.setup();
  if (toolchain == nullptr)
    return 1;

  // Build compilation; construct actions for this compile.
  std::unique_ptr<Compilation> compilation =
      driver.buildCompilation(*toolchain);
  if (!driver.buildActions(*compilation))
    return 2;

  // Process the action list. This will carry out actions that don't
  // require use of an external tool, and will generate a list of
  // commands for invoking external tools.
  if (!driver.processActions(*compilation))
    return 3;

  // Execute the external-tool command list created above.
  if (! compilation->executeCommands())
    return 4;

  // We're done.
  return 0;
}
