Home | History | Annotate | Download | only in Driver
      1 //===--- Compilation.h - Compilation Task Data Structure --------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_CLANG_DRIVER_COMPILATION_H
     11 #define LLVM_CLANG_DRIVER_COMPILATION_H
     12 
     13 #include "clang/Driver/Action.h"
     14 #include "clang/Driver/Job.h"
     15 #include "clang/Driver/Util.h"
     16 #include "llvm/ADT/DenseMap.h"
     17 #include <map>
     18 
     19 namespace llvm {
     20 namespace opt {
     21   class DerivedArgList;
     22   class InputArgList;
     23 }
     24 }
     25 
     26 namespace clang {
     27 namespace driver {
     28   class Driver;
     29   class JobList;
     30   class ToolChain;
     31 
     32 /// Compilation - A set of tasks to perform for a single driver
     33 /// invocation.
     34 class Compilation {
     35   /// The driver we were created by.
     36   const Driver &TheDriver;
     37 
     38   /// The default tool chain.
     39   const ToolChain &DefaultToolChain;
     40 
     41   /// A mask of all the programming models the host has to support in the
     42   /// current compilation.
     43   unsigned ActiveOffloadMask;
     44 
     45   /// Array with the toolchains of offloading host and devices in the order they
     46   /// were requested by the user. We are preserving that order in case the code
     47   /// generation needs to derive a programming-model-specific semantic out of
     48   /// it.
     49   std::multimap<Action::OffloadKind, const ToolChain *>
     50       OrderedOffloadingToolchains;
     51 
     52   /// The original (untranslated) input argument list.
     53   llvm::opt::InputArgList *Args;
     54 
     55   /// The driver translated arguments. Note that toolchains may perform their
     56   /// own argument translation.
     57   llvm::opt::DerivedArgList *TranslatedArgs;
     58 
     59   /// The list of actions we've created via MakeAction.  This is not accessible
     60   /// to consumers; it's here just to manage ownership.
     61   std::vector<std::unique_ptr<Action>> AllActions;
     62 
     63   /// The list of actions.  This is maintained and modified by consumers, via
     64   /// getActions().
     65   ActionList Actions;
     66 
     67   /// The root list of jobs.
     68   JobList Jobs;
     69 
     70   /// Cache of translated arguments for a particular tool chain, bound
     71   /// architecture, and device offload kind.
     72   struct TCArgsKey final {
     73     const ToolChain *TC = nullptr;
     74     StringRef BoundArch;
     75     Action::OffloadKind DeviceOffloadKind = Action::OFK_None;
     76     bool operator<(const TCArgsKey &K) const {
     77       if (TC < K.TC)
     78         return true;
     79       else if (TC == K.TC && BoundArch < K.BoundArch)
     80         return true;
     81       else if (TC == K.TC && BoundArch == K.BoundArch &&
     82                DeviceOffloadKind < K.DeviceOffloadKind)
     83         return true;
     84       return false;
     85     }
     86     TCArgsKey(const ToolChain *TC, StringRef BoundArch,
     87               Action::OffloadKind DeviceOffloadKind)
     88         : TC(TC), BoundArch(BoundArch), DeviceOffloadKind(DeviceOffloadKind) {}
     89   };
     90   std::map<TCArgsKey, llvm::opt::DerivedArgList *> TCArgs;
     91 
     92   /// Temporary files which should be removed on exit.
     93   llvm::opt::ArgStringList TempFiles;
     94 
     95   /// Result files which should be removed on failure.
     96   ArgStringMap ResultFiles;
     97 
     98   /// Result files which are generated correctly on failure, and which should
     99   /// only be removed if we crash.
    100   ArgStringMap FailureResultFiles;
    101 
    102   /// Optional redirection for stdin, stdout, stderr.
    103   std::vector<Optional<StringRef>> Redirects;
    104 
    105   /// Whether we're compiling for diagnostic purposes.
    106   bool ForDiagnostics;
    107 
    108   /// Whether an error during the parsing of the input args.
    109   bool ContainsError;
    110 
    111 public:
    112   Compilation(const Driver &D, const ToolChain &DefaultToolChain,
    113               llvm::opt::InputArgList *Args,
    114               llvm::opt::DerivedArgList *TranslatedArgs, bool ContainsError);
    115   ~Compilation();
    116 
    117   const Driver &getDriver() const { return TheDriver; }
    118 
    119   const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
    120 
    121   unsigned isOffloadingHostKind(Action::OffloadKind Kind) const {
    122     return ActiveOffloadMask & Kind;
    123   }
    124 
    125   /// Iterator that visits device toolchains of a given kind.
    126   typedef const std::multimap<Action::OffloadKind,
    127                               const ToolChain *>::const_iterator
    128       const_offload_toolchains_iterator;
    129   typedef std::pair<const_offload_toolchains_iterator,
    130                     const_offload_toolchains_iterator>
    131       const_offload_toolchains_range;
    132 
    133   template <Action::OffloadKind Kind>
    134   const_offload_toolchains_range getOffloadToolChains() const {
    135     return OrderedOffloadingToolchains.equal_range(Kind);
    136   }
    137 
    138   /// Return true if an offloading tool chain of a given kind exists.
    139   template <Action::OffloadKind Kind> bool hasOffloadToolChain() const {
    140     return OrderedOffloadingToolchains.find(Kind) !=
    141            OrderedOffloadingToolchains.end();
    142   }
    143 
    144   /// Return an offload toolchain of the provided kind. Only one is expected to
    145   /// exist.
    146   template <Action::OffloadKind Kind>
    147   const ToolChain *getSingleOffloadToolChain() const {
    148     auto TCs = getOffloadToolChains<Kind>();
    149 
    150     assert(TCs.first != TCs.second &&
    151            "No tool chains of the selected kind exist!");
    152     assert(std::next(TCs.first) == TCs.second &&
    153            "More than one tool chain of the this kind exist.");
    154     return TCs.first->second;
    155   }
    156 
    157   void addOffloadDeviceToolChain(const ToolChain *DeviceToolChain,
    158                                  Action::OffloadKind OffloadKind) {
    159     assert(OffloadKind != Action::OFK_Host && OffloadKind != Action::OFK_None &&
    160            "This is not a device tool chain!");
    161 
    162     // Update the host offload kind to also contain this kind.
    163     ActiveOffloadMask |= OffloadKind;
    164     OrderedOffloadingToolchains.insert(
    165         std::make_pair(OffloadKind, DeviceToolChain));
    166   }
    167 
    168   const llvm::opt::InputArgList &getInputArgs() const { return *Args; }
    169 
    170   const llvm::opt::DerivedArgList &getArgs() const { return *TranslatedArgs; }
    171 
    172   llvm::opt::DerivedArgList &getArgs() { return *TranslatedArgs; }
    173 
    174   ActionList &getActions() { return Actions; }
    175   const ActionList &getActions() const { return Actions; }
    176 
    177   /// Creates a new Action owned by this Compilation.
    178   ///
    179   /// The new Action is *not* added to the list returned by getActions().
    180   template <typename T, typename... Args> T *MakeAction(Args &&... Arg) {
    181     T *RawPtr = new T(std::forward<Args>(Arg)...);
    182     AllActions.push_back(std::unique_ptr<Action>(RawPtr));
    183     return RawPtr;
    184   }
    185 
    186   JobList &getJobs() { return Jobs; }
    187   const JobList &getJobs() const { return Jobs; }
    188 
    189   void addCommand(std::unique_ptr<Command> C) { Jobs.addJob(std::move(C)); }
    190 
    191   const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; }
    192 
    193   const ArgStringMap &getResultFiles() const { return ResultFiles; }
    194 
    195   const ArgStringMap &getFailureResultFiles() const {
    196     return FailureResultFiles;
    197   }
    198 
    199   /// Returns the sysroot path.
    200   StringRef getSysRoot() const;
    201 
    202   /// getArgsForToolChain - Return the derived argument list for the
    203   /// tool chain \p TC (or the default tool chain, if TC is not specified).
    204   /// If a device offloading kind is specified, a translation specific for that
    205   /// kind is performed, if any.
    206   ///
    207   /// \param BoundArch - The bound architecture name, or 0.
    208   /// \param DeviceOffloadKind - The offload device kind that should be used in
    209   /// the translation, if any.
    210   const llvm::opt::DerivedArgList &
    211   getArgsForToolChain(const ToolChain *TC, StringRef BoundArch,
    212                       Action::OffloadKind DeviceOffloadKind);
    213 
    214   /// addTempFile - Add a file to remove on exit, and returns its
    215   /// argument.
    216   const char *addTempFile(const char *Name) {
    217     TempFiles.push_back(Name);
    218     return Name;
    219   }
    220 
    221   /// addResultFile - Add a file to remove on failure, and returns its
    222   /// argument.
    223   const char *addResultFile(const char *Name, const JobAction *JA) {
    224     ResultFiles[JA] = Name;
    225     return Name;
    226   }
    227 
    228   /// addFailureResultFile - Add a file to remove if we crash, and returns its
    229   /// argument.
    230   const char *addFailureResultFile(const char *Name, const JobAction *JA) {
    231     FailureResultFiles[JA] = Name;
    232     return Name;
    233   }
    234 
    235   /// CleanupFile - Delete a given file.
    236   ///
    237   /// \param IssueErrors - Report failures as errors.
    238   /// \return Whether the file was removed successfully.
    239   bool CleanupFile(const char *File, bool IssueErrors = false) const;
    240 
    241   /// CleanupFileList - Remove the files in the given list.
    242   ///
    243   /// \param IssueErrors - Report failures as errors.
    244   /// \return Whether all files were removed successfully.
    245   bool CleanupFileList(const llvm::opt::ArgStringList &Files,
    246                        bool IssueErrors = false) const;
    247 
    248   /// CleanupFileMap - Remove the files in the given map.
    249   ///
    250   /// \param JA - If specified, only delete the files associated with this
    251   /// JobAction.  Otherwise, delete all files in the map.
    252   /// \param IssueErrors - Report failures as errors.
    253   /// \return Whether all files were removed successfully.
    254   bool CleanupFileMap(const ArgStringMap &Files,
    255                       const JobAction *JA,
    256                       bool IssueErrors = false) const;
    257 
    258   /// ExecuteCommand - Execute an actual command.
    259   ///
    260   /// \param FailingCommand - For non-zero results, this will be set to the
    261   /// Command which failed, if any.
    262   /// \return The result code of the subprocess.
    263   int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;
    264 
    265   /// ExecuteJob - Execute a single job.
    266   ///
    267   /// \param FailingCommands - For non-zero results, this will be a vector of
    268   /// failing commands and their associated result code.
    269   void ExecuteJobs(
    270       const JobList &Jobs,
    271       SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const;
    272 
    273   /// initCompilationForDiagnostics - Remove stale state and suppress output
    274   /// so compilation can be reexecuted to generate additional diagnostic
    275   /// information (e.g., preprocessed source(s)).
    276   void initCompilationForDiagnostics();
    277 
    278   /// Return true if we're compiling for diagnostics.
    279   bool isForDiagnostics() const { return ForDiagnostics; }
    280 
    281   /// Return whether an error during the parsing of the input args.
    282   bool containsError() const { return ContainsError; }
    283 
    284   /// Redirect - Redirect output of this compilation. Can only be done once.
    285   ///
    286   /// \param Redirects - array of optional paths. The array should have a size
    287   /// of three. The inferior process's stdin(0), stdout(1), and stderr(2) will
    288   /// be redirected to the corresponding paths, if provided (not llvm::None).
    289   void Redirect(ArrayRef<Optional<StringRef>> Redirects);
    290 };
    291 
    292 } // end namespace driver
    293 } // end namespace clang
    294 
    295 #endif
    296