//===- Compilation.h - Compilation Task Data Structure ----------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_DRIVER_COMPILATION_H
#define LLVM_CLANG_DRIVER_COMPILATION_H

#include "clang/Basic/LLVM.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Job.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Option.h"
#include <cassert>
#include <iterator>
#include <map>
#include <memory>
#include <utility>
#include <vector>

namespace llvm {
namespace opt {

class DerivedArgList;
class InputArgList;

} // namespace opt
} // namespace llvm

namespace clang {
namespace driver {

class Driver;
class ToolChain;

/// Compilation - A set of tasks to perform for a single driver
/// invocation.
class Compilation {
  /// The driver we were created by.
  const Driver &TheDriver;

  /// The default tool chain.
  const ToolChain &DefaultToolChain;

  /// A mask of all the programming models the host has to support in the
  /// current compilation.
  unsigned ActiveOffloadMask = 0;

  /// Array with the toolchains of offloading host and devices in the order they
  /// were requested by the user. We are preserving that order in case the code
  /// generation needs to derive a programming-model-specific semantic out of
  /// it.
  std::multimap<Action::OffloadKind, const ToolChain *>
      OrderedOffloadingToolchains;

  /// The original (untranslated) input argument list.
  llvm::opt::InputArgList *Args;

  /// The driver translated arguments. Note that toolchains may perform their
  /// own argument translation.
  llvm::opt::DerivedArgList *TranslatedArgs;

  /// The list of actions we've created via MakeAction.  This is not accessible
  /// to consumers; it's here just to manage ownership.
  std::vector<std::unique_ptr<Action>> AllActions;

  /// The list of actions.  This is maintained and modified by consumers, via
  /// getActions().
  ActionList Actions;

  /// The root list of jobs.
  JobList Jobs;

  /// Cache of translated arguments for a particular tool chain, bound
  /// architecture, and device offload kind.
  struct TCArgsKey final {
    const ToolChain *TC = nullptr;
    StringRef BoundArch;
    Action::OffloadKind DeviceOffloadKind = Action::OFK_None;

    TCArgsKey(const ToolChain *TC, StringRef BoundArch,
              Action::OffloadKind DeviceOffloadKind)
        : TC(TC), BoundArch(BoundArch), DeviceOffloadKind(DeviceOffloadKind) {}

    bool operator<(const TCArgsKey &K) const {
      if (TC < K.TC)
        return true;
      else if (TC == K.TC && BoundArch < K.BoundArch)
        return true;
      else if (TC == K.TC && BoundArch == K.BoundArch &&
               DeviceOffloadKind < K.DeviceOffloadKind)
        return true;
      return false;
    }
  };
  std::map<TCArgsKey, llvm::opt::DerivedArgList *> TCArgs;

  /// Temporary files which should be removed on exit.
  llvm::opt::ArgStringList TempFiles;

  /// Result files which should be removed on failure.
  ArgStringMap ResultFiles;

  /// Result files which are generated correctly on failure, and which should
  /// only be removed if we crash.
  ArgStringMap FailureResultFiles;

  /// Optional redirection for stdin, stdout, stderr.
  std::vector<Optional<StringRef>> Redirects;

  /// Callback called after compilation job has been finished.
  /// Arguments of the callback are the compilation job as an instance of
  /// class Command and the exit status of the corresponding child process.
  std::function<void(const Command &, int)> PostCallback;

  /// Whether we're compiling for diagnostic purposes.
  bool ForDiagnostics = false;

  /// Whether an error during the parsing of the input args.
  bool ContainsError;

  /// Whether to keep temporary files regardless of -save-temps.
  bool ForceKeepTempFiles = false;

public:
  Compilation(const Driver &D, const ToolChain &DefaultToolChain,
              llvm::opt::InputArgList *Args,
              llvm::opt::DerivedArgList *TranslatedArgs, bool ContainsError);
  ~Compilation();

  const Driver &getDriver() const { return TheDriver; }

  const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }

  unsigned isOffloadingHostKind(Action::OffloadKind Kind) const {
    return ActiveOffloadMask & Kind;
  }

  /// Iterator that visits device toolchains of a given kind.
  using const_offload_toolchains_iterator =
      const std::multimap<Action::OffloadKind,
                          const ToolChain *>::const_iterator;
  using const_offload_toolchains_range =
      std::pair<const_offload_toolchains_iterator,
                const_offload_toolchains_iterator>;

  template <Action::OffloadKind Kind>
  const_offload_toolchains_range getOffloadToolChains() const {
    return OrderedOffloadingToolchains.equal_range(Kind);
  }

  /// Return true if an offloading tool chain of a given kind exists.
  template <Action::OffloadKind Kind> bool hasOffloadToolChain() const {
    return OrderedOffloadingToolchains.find(Kind) !=
           OrderedOffloadingToolchains.end();
  }

  /// Return an offload toolchain of the provided kind. Only one is expected to
  /// exist.
  template <Action::OffloadKind Kind>
  const ToolChain *getSingleOffloadToolChain() const {
    auto TCs = getOffloadToolChains<Kind>();

    assert(TCs.first != TCs.second &&
           "No tool chains of the selected kind exist!");
    assert(std::next(TCs.first) == TCs.second &&
           "More than one tool chain of the this kind exist.");
    return TCs.first->second;
  }

  void addOffloadDeviceToolChain(const ToolChain *DeviceToolChain,
                                 Action::OffloadKind OffloadKind) {
    assert(OffloadKind != Action::OFK_Host && OffloadKind != Action::OFK_None &&
           "This is not a device tool chain!");

    // Update the host offload kind to also contain this kind.
    ActiveOffloadMask |= OffloadKind;
    OrderedOffloadingToolchains.insert(
        std::make_pair(OffloadKind, DeviceToolChain));
  }

  const llvm::opt::InputArgList &getInputArgs() const { return *Args; }

  const llvm::opt::DerivedArgList &getArgs() const { return *TranslatedArgs; }

  llvm::opt::DerivedArgList &getArgs() { return *TranslatedArgs; }

  ActionList &getActions() { return Actions; }
  const ActionList &getActions() const { return Actions; }

  /// Creates a new Action owned by this Compilation.
  ///
  /// The new Action is *not* added to the list returned by getActions().
  template <typename T, typename... Args> T *MakeAction(Args &&... Arg) {
    T *RawPtr = new T(std::forward<Args>(Arg)...);
    AllActions.push_back(std::unique_ptr<Action>(RawPtr));
    return RawPtr;
  }

  JobList &getJobs() { return Jobs; }
  const JobList &getJobs() const { return Jobs; }

  void addCommand(std::unique_ptr<Command> C) { Jobs.addJob(std::move(C)); }

  const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; }

  const ArgStringMap &getResultFiles() const { return ResultFiles; }

  const ArgStringMap &getFailureResultFiles() const {
    return FailureResultFiles;
  }

  /// Installs a handler that is executed when a compilation job is finished.
  /// The arguments of the callback specify the compilation job as an instance
  /// of class Command and the exit status of the child process executed that
  /// job.
  void setPostCallback(const std::function<void(const Command &, int)> &CB) {
    PostCallback = CB;
  }

  /// Returns the sysroot path.
  StringRef getSysRoot() const;

  /// getArgsForToolChain - Return the derived argument list for the
  /// tool chain \p TC (or the default tool chain, if TC is not specified).
  /// If a device offloading kind is specified, a translation specific for that
  /// kind is performed, if any.
  ///
  /// \param BoundArch - The bound architecture name, or 0.
  /// \param DeviceOffloadKind - The offload device kind that should be used in
  /// the translation, if any.
  const llvm::opt::DerivedArgList &
  getArgsForToolChain(const ToolChain *TC, StringRef BoundArch,
                      Action::OffloadKind DeviceOffloadKind);

  /// addTempFile - Add a file to remove on exit, and returns its
  /// argument.
  const char *addTempFile(const char *Name) {
    TempFiles.push_back(Name);
    return Name;
  }

  /// addResultFile - Add a file to remove on failure, and returns its
  /// argument.
  const char *addResultFile(const char *Name, const JobAction *JA) {
    ResultFiles[JA] = Name;
    return Name;
  }

  /// addFailureResultFile - Add a file to remove if we crash, and returns its
  /// argument.
  const char *addFailureResultFile(const char *Name, const JobAction *JA) {
    FailureResultFiles[JA] = Name;
    return Name;
  }

  /// CleanupFile - Delete a given file.
  ///
  /// \param IssueErrors - Report failures as errors.
  /// \return Whether the file was removed successfully.
  bool CleanupFile(const char *File, bool IssueErrors = false) const;

  /// CleanupFileList - Remove the files in the given list.
  ///
  /// \param IssueErrors - Report failures as errors.
  /// \return Whether all files were removed successfully.
  bool CleanupFileList(const llvm::opt::ArgStringList &Files,
                       bool IssueErrors = false) const;

  /// CleanupFileMap - Remove the files in the given map.
  ///
  /// \param JA - If specified, only delete the files associated with this
  /// JobAction.  Otherwise, delete all files in the map.
  /// \param IssueErrors - Report failures as errors.
  /// \return Whether all files were removed successfully.
  bool CleanupFileMap(const ArgStringMap &Files,
                      const JobAction *JA,
                      bool IssueErrors = false) const;

  /// ExecuteCommand - Execute an actual command.
  ///
  /// \param FailingCommand - For non-zero results, this will be set to the
  /// Command which failed, if any.
  /// \return The result code of the subprocess.
  int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;

  /// ExecuteJob - Execute a single job.
  ///
  /// \param FailingCommands - For non-zero results, this will be a vector of
  /// failing commands and their associated result code.
  void ExecuteJobs(
      const JobList &Jobs,
      SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const;

  /// initCompilationForDiagnostics - Remove stale state and suppress output
  /// so compilation can be reexecuted to generate additional diagnostic
  /// information (e.g., preprocessed source(s)).
  void initCompilationForDiagnostics();

  /// Return true if we're compiling for diagnostics.
  bool isForDiagnostics() const { return ForDiagnostics; }

  /// Return whether an error during the parsing of the input args.
  bool containsError() const { return ContainsError; }

  /// Force driver to fail before toolchain is created. This is necessary when
  /// error happens in action builder.
  void setContainsError() { ContainsError = true; }

  /// Redirect - Redirect output of this compilation. Can only be done once.
  ///
  /// \param Redirects - array of optional paths. The array should have a size
  /// of three. The inferior process's stdin(0), stdout(1), and stderr(2) will
  /// be redirected to the corresponding paths, if provided (not llvm::None).
  void Redirect(ArrayRef<Optional<StringRef>> Redirects);
};

} // namespace driver
} // namespace clang

#endif // LLVM_CLANG_DRIVER_COMPILATION_H
