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