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