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 /// 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 /// Response file name, if this command is set to use one, or nullptr 57 /// otherwise 58 const char *ResponseFile; 59 60 /// The input file list in case we need to emit a file list instead of a 61 /// proper response file 62 llvm::opt::ArgStringList InputFileList; 63 64 /// String storage if we need to create a new argument to specify a response 65 /// file 66 std::string ResponseFileFlag; 67 68 /// When a response file is needed, we try to put most arguments in an 69 /// exclusive file, while others remains as regular command line arguments. 70 /// This functions fills a vector with the regular command line arguments, 71 /// argv, excluding the ones passed in a response file. 72 void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const; 73 74 /// Encodes an array of C strings into a single string separated by whitespace. 75 /// This function will also put in quotes arguments that have whitespaces and 76 /// will escape the regular backslashes (used in Windows paths) and quotes. 77 /// The results are the contents of a response file, written into a raw_ostream. 78 void writeResponseFile(raw_ostream &OS) const; 79 80 public: 81 Command(const Action &Source, const Tool &Creator, const char *Executable, 82 const llvm::opt::ArgStringList &Arguments); ~Command()83 virtual ~Command() {} 84 85 virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, 86 CrashReportInfo *CrashInfo = nullptr) const; 87 88 virtual int Execute(const StringRef **Redirects, std::string *ErrMsg, 89 bool *ExecutionFailed) const; 90 91 /// getSource - Return the Action which caused the creation of this job. getSource()92 const Action &getSource() const { return Source; } 93 94 /// getCreator - Return the Tool which caused the creation of this job. getCreator()95 const Tool &getCreator() const { return Creator; } 96 97 /// Set to pass arguments via a response file when launching the command 98 void setResponseFile(const char *FileName); 99 100 /// Set an input file list, necessary if we need to use a response file but 101 /// the tool being called only supports input files lists. setInputFileList(llvm::opt::ArgStringList List)102 void setInputFileList(llvm::opt::ArgStringList List) { 103 InputFileList = std::move(List); 104 } 105 getExecutable()106 const char *getExecutable() const { return Executable; } 107 getArguments()108 const llvm::opt::ArgStringList &getArguments() const { return Arguments; } 109 110 /// Print a command argument, and optionally quote it. 111 static void printArg(llvm::raw_ostream &OS, const char *Arg, bool Quote); 112 }; 113 114 /// Like Command, but with a fallback which is executed in case 115 /// the primary command crashes. 116 class FallbackCommand : public Command { 117 public: 118 FallbackCommand(const Action &Source_, const Tool &Creator_, 119 const char *Executable_, const ArgStringList &Arguments_, 120 std::unique_ptr<Command> Fallback_); 121 122 void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, 123 CrashReportInfo *CrashInfo = nullptr) const override; 124 125 int Execute(const StringRef **Redirects, std::string *ErrMsg, 126 bool *ExecutionFailed) const override; 127 128 private: 129 std::unique_ptr<Command> Fallback; 130 }; 131 132 /// JobList - A sequence of jobs to perform. 133 class JobList { 134 public: 135 typedef SmallVector<std::unique_ptr<Command>, 4> list_type; 136 typedef list_type::size_type size_type; 137 typedef llvm::pointee_iterator<list_type::iterator> iterator; 138 typedef llvm::pointee_iterator<list_type::const_iterator> const_iterator; 139 140 private: 141 list_type Jobs; 142 143 public: 144 void Print(llvm::raw_ostream &OS, const char *Terminator, 145 bool Quote, CrashReportInfo *CrashInfo = nullptr) const; 146 147 /// Add a job to the list (taking ownership). addJob(std::unique_ptr<Command> J)148 void addJob(std::unique_ptr<Command> J) { Jobs.push_back(std::move(J)); } 149 150 /// Clear the job list. 151 void clear(); 152 getJobs()153 const list_type &getJobs() const { return Jobs; } 154 size()155 size_type size() const { return Jobs.size(); } begin()156 iterator begin() { return Jobs.begin(); } begin()157 const_iterator begin() const { return Jobs.begin(); } end()158 iterator end() { return Jobs.end(); } end()159 const_iterator end() const { return Jobs.end(); } 160 }; 161 162 } // end namespace driver 163 } // end namespace clang 164 165 #endif 166