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/SmallVector.h" 15 #include "llvm/ADT/iterator.h" 16 #include "llvm/Option/Option.h" 17 #include <memory> 18 19 namespace llvm { 20 class raw_ostream; 21 } 22 23 namespace clang { 24 namespace driver { 25 class Action; 26 class Command; 27 class Tool; 28 29 // Re-export this as clang::driver::ArgStringList. 30 using llvm::opt::ArgStringList; 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 class Job { 41 public: 42 enum JobClass { 43 CommandClass, 44 FallbackCommandClass, 45 JobListClass 46 }; 47 48 private: 49 JobClass Kind; 50 51 protected: Job(JobClass _Kind)52 Job(JobClass _Kind) : Kind(_Kind) {} 53 public: 54 virtual ~Job(); 55 getKind()56 JobClass getKind() const { return Kind; } 57 58 /// Print - Print this Job in -### format. 59 /// 60 /// \param OS - The stream to print on. 61 /// \param Terminator - A string to print at the end of the line. 62 /// \param Quote - Should separate arguments be quoted. 63 /// \param CrashInfo - Details for inclusion in a crash report. 64 virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, 65 CrashReportInfo *CrashInfo = nullptr) const = 0; 66 }; 67 68 /// Command - An executable path/name and argument vector to 69 /// execute. 70 class Command : public Job { 71 /// Source - The action which caused the creation of this job. 72 const Action &Source; 73 74 /// Tool - The tool which caused the creation of this job. 75 const Tool &Creator; 76 77 /// The executable to run. 78 const char *Executable; 79 80 /// The list of program arguments (not including the implicit first 81 /// argument, which will be the executable). 82 llvm::opt::ArgStringList Arguments; 83 84 /// Response file name, if this command is set to use one, or nullptr 85 /// otherwise 86 const char *ResponseFile; 87 88 /// The input file list in case we need to emit a file list instead of a 89 /// proper response file 90 llvm::opt::ArgStringList InputFileList; 91 92 /// String storage if we need to create a new argument to specify a response 93 /// file 94 std::string ResponseFileFlag; 95 96 /// When a response file is needed, we try to put most arguments in an 97 /// exclusive file, while others remains as regular command line arguments. 98 /// This functions fills a vector with the regular command line arguments, 99 /// argv, excluding the ones passed in a response file. 100 void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const; 101 102 /// Encodes an array of C strings into a single string separated by whitespace. 103 /// This function will also put in quotes arguments that have whitespaces and 104 /// will escape the regular backslashes (used in Windows paths) and quotes. 105 /// The results are the contents of a response file, written into a raw_ostream. 106 void writeResponseFile(raw_ostream &OS) const; 107 108 public: 109 Command(const Action &_Source, const Tool &_Creator, const char *_Executable, 110 const llvm::opt::ArgStringList &_Arguments); 111 112 void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, 113 CrashReportInfo *CrashInfo = nullptr) const override; 114 115 virtual int Execute(const StringRef **Redirects, std::string *ErrMsg, 116 bool *ExecutionFailed) const; 117 118 /// getSource - Return the Action which caused the creation of this job. getSource()119 const Action &getSource() const { return Source; } 120 121 /// getCreator - Return the Tool which caused the creation of this job. getCreator()122 const Tool &getCreator() const { return Creator; } 123 124 /// Set to pass arguments via a response file when launching the command 125 void setResponseFile(const char *FileName); 126 127 /// Set an input file list, necessary if we need to use a response file but 128 /// the tool being called only supports input files lists. setInputFileList(llvm::opt::ArgStringList List)129 void setInputFileList(llvm::opt::ArgStringList List) { 130 InputFileList = std::move(List); 131 } 132 getExecutable()133 const char *getExecutable() const { return Executable; } 134 getArguments()135 const llvm::opt::ArgStringList &getArguments() const { return Arguments; } 136 classof(const Job * J)137 static bool classof(const Job *J) { 138 return J->getKind() == CommandClass || 139 J->getKind() == FallbackCommandClass; 140 } 141 }; 142 143 /// Like Command, but with a fallback which is executed in case 144 /// the primary command crashes. 145 class FallbackCommand : public Command { 146 public: 147 FallbackCommand(const Action &Source_, const Tool &Creator_, 148 const char *Executable_, const ArgStringList &Arguments_, 149 std::unique_ptr<Command> Fallback_); 150 151 void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, 152 CrashReportInfo *CrashInfo = nullptr) const override; 153 154 int Execute(const StringRef **Redirects, std::string *ErrMsg, 155 bool *ExecutionFailed) const override; 156 classof(const Job * J)157 static bool classof(const Job *J) { 158 return J->getKind() == FallbackCommandClass; 159 } 160 161 private: 162 std::unique_ptr<Command> Fallback; 163 }; 164 165 /// JobList - A sequence of jobs to perform. 166 class JobList : public Job { 167 public: 168 typedef SmallVector<std::unique_ptr<Job>, 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 JobList(); ~JobList()178 ~JobList() override {} 179 180 void Print(llvm::raw_ostream &OS, const char *Terminator, 181 bool Quote, CrashReportInfo *CrashInfo = nullptr) const override; 182 183 /// Add a job to the list (taking ownership). addJob(std::unique_ptr<Job> J)184 void addJob(std::unique_ptr<Job> J) { Jobs.push_back(std::move(J)); } 185 186 /// Clear the job list. 187 void clear(); 188 getJobs()189 const list_type &getJobs() const { return Jobs; } 190 size()191 size_type size() const { return Jobs.size(); } begin()192 iterator begin() { return Jobs.begin(); } begin()193 const_iterator begin() const { return Jobs.begin(); } end()194 iterator end() { return Jobs.end(); } end()195 const_iterator end() const { return Jobs.end(); } 196 classof(const Job * J)197 static bool classof(const Job *J) { 198 return J->getKind() == JobListClass; 199 } 200 }; 201 202 } // end namespace driver 203 } // end namespace clang 204 205 #endif 206