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