//===-- 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/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>

#ifdef USING_SPLIT_STACK
constexpr bool using_splitstack = true;
#else
constexpr bool using_splitstack = false;
#endif

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;
  }

  // Check if '-fsplit-stack' is supported by this compiler configuration.
#ifndef USING_SPLIT_STACK
  if (args_.hasArg(gollvm::options::OPT_fsplit_stack)) {
    errs() << progname
           << ": '-fsplit-stack' is not supported by this compiler "
              "configuration\n";
    return false;
  }
#endif

  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], using_splitstack);

  // 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;
}
