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