diff options
Diffstat (limited to 'clang-r353983e/include/clang/Driver/Compilation.h')
| -rw-r--r-- | clang-r353983e/include/clang/Driver/Compilation.h | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/clang-r353983e/include/clang/Driver/Compilation.h b/clang-r353983e/include/clang/Driver/Compilation.h new file mode 100644 index 00000000..33ae133e --- /dev/null +++ b/clang-r353983e/include/clang/Driver/Compilation.h @@ -0,0 +1,311 @@ +//===- 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; + + /// 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; + } + + /// 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); +}; + +} // namespace driver +} // namespace clang + +#endif // LLVM_CLANG_DRIVER_COMPILATION_H |
