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