//===--- CreateInvocationFromArgs.h - CompilerInvocation from Args --------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Construct a compiler invocation object for command line driver arguments
//
//===----------------------------------------------------------------------===//

#include "clang/Driver/CreateInvocationFromArgs.h"
#include "clang/Basic/DiagnosticFrontend.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/Utils.h"
#include "clang/Options/Options.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/Host.h"

using namespace llvm::opt;

namespace clang {

std::unique_ptr<CompilerInvocation>
createInvocation(ArrayRef<const char *> ArgList, CreateInvocationOptions Opts) {
  assert(!ArgList.empty());
  std::optional<DiagnosticOptions> LocalDiagOpts;
  IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
  if (Opts.Diags) {
    Diags = std::move(Opts.Diags);
  } else {
    LocalDiagOpts.emplace();
    Diags = CompilerInstance::createDiagnostics(
        Opts.VFS ? *Opts.VFS : *llvm::vfs::getRealFileSystem(), *LocalDiagOpts);
  }

  SmallVector<const char *, 16> Args(ArgList);

  // FIXME: Find a cleaner way to force the driver into restricted modes.
  Args.insert(
      llvm::find_if(
          Args, [](const char *Elem) { return llvm::StringRef(Elem) == "--"; }),
      "-fsyntax-only");

  // FIXME: We shouldn't have to pass in the path info.
  driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(), *Diags,
                           "clang LLVM compiler", Opts.VFS);

  // Don't check that inputs exist, they may have been remapped.
  TheDriver.setCheckInputsExist(false);
  TheDriver.setProbePrecompiled(Opts.ProbePrecompiled);

  std::unique_ptr<driver::Compilation> C(TheDriver.BuildCompilation(Args));
  if (!C)
    return nullptr;

  if (C->getArgs().hasArg(options::OPT_fdriver_only))
    return nullptr;

  // Just print the cc1 options if -### was present.
  if (C->getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
    C->getJobs().Print(llvm::errs(), "\n", true);
    return nullptr;
  }

  // We expect to get back exactly one command job, if we didn't something
  // failed. Offload compilation is an exception as it creates multiple jobs. If
  // that's the case, we proceed with the first job. If caller needs a
  // particular job, it should be controlled via options (e.g.
  // --cuda-{host|device}-only for CUDA) passed to the driver.
  const driver::JobList &Jobs = C->getJobs();
  bool OffloadCompilation = false;
  if (Jobs.size() > 1) {
    for (auto &A : C->getActions()) {
      // On MacOSX real actions may end up being wrapped in BindArchAction
      if (isa<driver::BindArchAction>(A))
        A = *A->input_begin();
      if (isa<driver::OffloadAction>(A)) {
        OffloadCompilation = true;
        break;
      }
    }
  }

  bool PickFirstOfMany = OffloadCompilation || Opts.RecoverOnError;
  if (Jobs.size() == 0 || (Jobs.size() > 1 && !PickFirstOfMany)) {
    SmallString<256> Msg;
    llvm::raw_svector_ostream OS(Msg);
    Jobs.Print(OS, "; ", true);
    Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
    return nullptr;
  }
  auto Cmd = llvm::find_if(Jobs, [](const driver::Command &Cmd) {
    return StringRef(Cmd.getCreator().getName()) == "clang";
  });
  if (Cmd == Jobs.end()) {
    Diags->Report(diag::err_fe_expected_clang_command);
    return nullptr;
  }

  const ArgStringList &CCArgs = Cmd->getArguments();
  if (Opts.CC1Args)
    *Opts.CC1Args = {CCArgs.begin(), CCArgs.end()};
  auto CI = std::make_unique<CompilerInvocation>();
  if (!CompilerInvocation::CreateFromArgs(*CI, CCArgs, *Diags, Args[0]) &&
      !Opts.RecoverOnError)
    return nullptr;
  return CI;
}

} // namespace clang
