Home | History | Annotate | Download | only in Driver
      1 //===--- Job.h - Commands to Execute ----------------------------*- 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_JOB_H
     11 #define LLVM_CLANG_DRIVER_JOB_H
     12 
     13 #include "clang/Basic/LLVM.h"
     14 #include "llvm/ADT/ArrayRef.h"
     15 #include "llvm/ADT/SmallVector.h"
     16 #include "llvm/ADT/iterator.h"
     17 #include "llvm/Option/Option.h"
     18 #include <memory>
     19 
     20 namespace llvm {
     21   class raw_ostream;
     22 }
     23 
     24 namespace clang {
     25 namespace driver {
     26 class Action;
     27 class Command;
     28 class Tool;
     29 class InputInfo;
     30 
     31 // Re-export this as clang::driver::ArgStringList.
     32 using llvm::opt::ArgStringList;
     33 
     34 struct CrashReportInfo {
     35   StringRef Filename;
     36   StringRef VFSPath;
     37 
     38   CrashReportInfo(StringRef Filename, StringRef VFSPath)
     39       : Filename(Filename), VFSPath(VFSPath) {}
     40 };
     41 
     42 /// Command - An executable path/name and argument vector to
     43 /// execute.
     44 class Command {
     45   /// Source - The action which caused the creation of this job.
     46   const Action &Source;
     47 
     48   /// Tool - The tool which caused the creation of this job.
     49   const Tool &Creator;
     50 
     51   /// The executable to run.
     52   const char *Executable;
     53 
     54   /// The list of program arguments (not including the implicit first
     55   /// argument, which will be the executable).
     56   llvm::opt::ArgStringList Arguments;
     57 
     58   /// The list of program arguments which are inputs.
     59   llvm::opt::ArgStringList InputFilenames;
     60 
     61   /// Response file name, if this command is set to use one, or nullptr
     62   /// otherwise
     63   const char *ResponseFile;
     64 
     65   /// The input file list in case we need to emit a file list instead of a
     66   /// proper response file
     67   llvm::opt::ArgStringList InputFileList;
     68 
     69   /// String storage if we need to create a new argument to specify a response
     70   /// file
     71   std::string ResponseFileFlag;
     72 
     73   /// See Command::setEnvironment
     74   std::vector<const char *> Environment;
     75 
     76   /// When a response file is needed, we try to put most arguments in an
     77   /// exclusive file, while others remains as regular command line arguments.
     78   /// This functions fills a vector with the regular command line arguments,
     79   /// argv, excluding the ones passed in a response file.
     80   void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const;
     81 
     82   /// Encodes an array of C strings into a single string separated by whitespace.
     83   /// This function will also put in quotes arguments that have whitespaces and
     84   /// will escape the regular backslashes (used in Windows paths) and quotes.
     85   /// The results are the contents of a response file, written into a raw_ostream.
     86   void writeResponseFile(raw_ostream &OS) const;
     87 
     88 public:
     89   Command(const Action &Source, const Tool &Creator, const char *Executable,
     90           const llvm::opt::ArgStringList &Arguments,
     91           ArrayRef<InputInfo> Inputs);
     92   // FIXME: This really shouldn't be copyable, but is currently copied in some
     93   // error handling in Driver::generateCompilationDiagnostics.
     94   Command(const Command &) = default;
     95   virtual ~Command() {}
     96 
     97   virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
     98                      CrashReportInfo *CrashInfo = nullptr) const;
     99 
    100   virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
    101                       bool *ExecutionFailed) const;
    102 
    103   /// getSource - Return the Action which caused the creation of this job.
    104   const Action &getSource() const { return Source; }
    105 
    106   /// getCreator - Return the Tool which caused the creation of this job.
    107   const Tool &getCreator() const { return Creator; }
    108 
    109   /// Set to pass arguments via a response file when launching the command
    110   void setResponseFile(const char *FileName);
    111 
    112   /// Set an input file list, necessary if we need to use a response file but
    113   /// the tool being called only supports input files lists.
    114   void setInputFileList(llvm::opt::ArgStringList List) {
    115     InputFileList = std::move(List);
    116   }
    117 
    118   /// \brief Sets the environment to be used by the new process.
    119   /// \param NewEnvironment An array of environment variables.
    120   /// \remark If the environment remains unset, then the environment
    121   ///         from the parent process will be used.
    122   void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment);
    123 
    124   const char *getExecutable() const { return Executable; }
    125 
    126   const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
    127 
    128   /// Print a command argument, and optionally quote it.
    129   static void printArg(llvm::raw_ostream &OS, StringRef Arg, bool Quote);
    130 };
    131 
    132 /// Like Command, but with a fallback which is executed in case
    133 /// the primary command crashes.
    134 class FallbackCommand : public Command {
    135 public:
    136   FallbackCommand(const Action &Source_, const Tool &Creator_,
    137                   const char *Executable_, const ArgStringList &Arguments_,
    138                   ArrayRef<InputInfo> Inputs,
    139                   std::unique_ptr<Command> Fallback_);
    140 
    141   void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
    142              CrashReportInfo *CrashInfo = nullptr) const override;
    143 
    144   int Execute(const StringRef **Redirects, std::string *ErrMsg,
    145               bool *ExecutionFailed) const override;
    146 
    147 private:
    148   std::unique_ptr<Command> Fallback;
    149 };
    150 
    151 /// Like Command, but always pretends that the wrapped command succeeded.
    152 class ForceSuccessCommand : public Command {
    153 public:
    154   ForceSuccessCommand(const Action &Source_, const Tool &Creator_,
    155                       const char *Executable_, const ArgStringList &Arguments_,
    156                       ArrayRef<InputInfo> Inputs);
    157 
    158   void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
    159              CrashReportInfo *CrashInfo = nullptr) const override;
    160 
    161   int Execute(const StringRef **Redirects, std::string *ErrMsg,
    162               bool *ExecutionFailed) const override;
    163 };
    164 
    165 /// JobList - A sequence of jobs to perform.
    166 class JobList {
    167 public:
    168   typedef SmallVector<std::unique_ptr<Command>, 4> list_type;
    169   typedef list_type::size_type size_type;
    170   typedef llvm::pointee_iterator<list_type::iterator> iterator;
    171   typedef llvm::pointee_iterator<list_type::const_iterator> const_iterator;
    172 
    173 private:
    174   list_type Jobs;
    175 
    176 public:
    177   void Print(llvm::raw_ostream &OS, const char *Terminator,
    178              bool Quote, CrashReportInfo *CrashInfo = nullptr) const;
    179 
    180   /// Add a job to the list (taking ownership).
    181   void addJob(std::unique_ptr<Command> J) { Jobs.push_back(std::move(J)); }
    182 
    183   /// Clear the job list.
    184   void clear();
    185 
    186   const list_type &getJobs() const { return Jobs; }
    187 
    188   bool empty() const { return Jobs.empty(); }
    189   size_type size() const { return Jobs.size(); }
    190   iterator begin() { return Jobs.begin(); }
    191   const_iterator begin() const { return Jobs.begin(); }
    192   iterator end() { return Jobs.end(); }
    193   const_iterator end() const { return Jobs.end(); }
    194 };
    195 
    196 } // end namespace driver
    197 } // end namespace clang
    198 
    199 #endif
    200