Viewing file: Compilation.h (12.32 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
//===- 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/StringRef.h" #include "llvm/Option/Option.h" #include <cassert> #include <iterator> #include <map> #include <memory> #include <optional> #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;
/// -ftime-trace result files. ArgStringMap TimeTraceFiles;
/// Optional redirection for stdin, stdout, stderr. std::vector<std::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; }
unsigned getActiveOffloadKinds() const { return ActiveOffloadMask; }
/// 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); }
const_offload_toolchains_range getOffloadToolChains(Action::OffloadKind Kind) 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)); }
llvm::opt::ArgStringList &getTempFiles() { return TempFiles; } 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; }
const char *getTimeTraceFile(const JobAction *JA) const { return TimeTraceFiles.lookup(JA); } void addTimeTraceFile(const char *Name, const JobAction *JA) { assert(!TimeTraceFiles.contains(JA)); TimeTraceFiles[JA] = 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. /// \param LogOnly - When true, only tries to log the command, not actually /// execute it. /// \return The result code of the subprocess. int ExecuteCommand(const Command &C, const Command *&FailingCommand, bool LogOnly = false) 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. /// \param LogOnly - When true, only tries to log the command, not actually /// execute it. void ExecuteJobs(const JobList &Jobs, SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands, bool LogOnly = false) 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 std::nullopt). void Redirect(ArrayRef<std::optional<StringRef>> Redirects); };
} // namespace driver } // namespace clang
#endif // LLVM_CLANG_DRIVER_COMPILATION_H
|