//===--- Compilation.h - Compilation Task Data Structure --------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_DRIVER_COMPILATION_H
#define LLVM_CLANG_DRIVER_COMPILATION_H

#include "clang/Driver/Action.h"
#include "clang/Driver/Job.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/DenseMap.h"
#include <map>

namespace llvm {
namespace opt {
  class DerivedArgList;
  class InputArgList;
}
}

namespace clang {
namespace driver {
  class Driver;
  class JobList;
  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;

  /// 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;
    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;
    }
    TCArgsKey(const ToolChain *TC, StringRef BoundArch,
              Action::OffloadKind DeviceOffloadKind)
        : TC(TC), BoundArch(BoundArch), DeviceOffloadKind(DeviceOffloadKind) {}
  };
  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;

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

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

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.
  typedef const std::multimap<Action::OffloadKind,
                              const ToolChain *>::const_iterator
      const_offload_toolchains_iterator;
  typedef std::pair<const_offload_toolchains_iterator,
                    const_offload_toolchains_iterator>
      const_offload_toolchains_range;

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

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

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

} // end namespace driver
} // end namespace clang

#endif
