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 20namespace llvm { 21 class raw_ostream; 22} 23 24namespace clang { 25namespace driver { 26class Action; 27class Command; 28class Tool; 29class InputInfo; 30 31// Re-export this as clang::driver::ArgStringList. 32using llvm::opt::ArgStringList; 33 34struct 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. 44class 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 88public: 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. 134class FallbackCommand : public Command { 135public: 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 147private: 148 std::unique_ptr<Command> Fallback; 149}; 150 151/// Like Command, but always pretends that the wrapped command succeeded. 152class ForceSuccessCommand : public Command { 153public: 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. 166class JobList { 167public: 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 173private: 174 list_type Jobs; 175 176public: 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