clang API Documentation

Job.h
Go to the documentation of this file.
00001 //===--- Job.h - Commands to Execute ----------------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #ifndef LLVM_CLANG_DRIVER_JOB_H
00011 #define LLVM_CLANG_DRIVER_JOB_H
00012 
00013 #include "clang/Basic/LLVM.h"
00014 #include "llvm/ADT/SmallVector.h"
00015 #include "llvm/Option/Option.h"
00016 #include "llvm/ADT/iterator.h"
00017 #include <memory>
00018 
00019 namespace llvm {
00020   class raw_ostream;
00021 }
00022 
00023 namespace clang {
00024 namespace driver {
00025 class Action;
00026 class Command;
00027 class Tool;
00028 
00029 // Re-export this as clang::driver::ArgStringList.
00030 using llvm::opt::ArgStringList;
00031 
00032 struct CrashReportInfo {
00033   StringRef Filename;
00034   StringRef VFSPath;
00035 
00036   CrashReportInfo(StringRef Filename, StringRef VFSPath)
00037       : Filename(Filename), VFSPath(VFSPath) {}
00038 };
00039 
00040 class Job {
00041 public:
00042   enum JobClass {
00043     CommandClass,
00044     FallbackCommandClass,
00045     JobListClass
00046   };
00047 
00048 private:
00049   JobClass Kind;
00050 
00051 protected:
00052   Job(JobClass _Kind) : Kind(_Kind) {}
00053 public:
00054   virtual ~Job();
00055 
00056   JobClass getKind() const { return Kind; }
00057 
00058   /// Print - Print this Job in -### format.
00059   ///
00060   /// \param OS - The stream to print on.
00061   /// \param Terminator - A string to print at the end of the line.
00062   /// \param Quote - Should separate arguments be quoted.
00063   /// \param CrashInfo - Details for inclusion in a crash report.
00064   virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
00065                      CrashReportInfo *CrashInfo = nullptr) const = 0;
00066 };
00067 
00068 /// Command - An executable path/name and argument vector to
00069 /// execute.
00070 class Command : public Job {
00071   /// Source - The action which caused the creation of this job.
00072   const Action &Source;
00073 
00074   /// Tool - The tool which caused the creation of this job.
00075   const Tool &Creator;
00076 
00077   /// The executable to run.
00078   const char *Executable;
00079 
00080   /// The list of program arguments (not including the implicit first
00081   /// argument, which will be the executable).
00082   llvm::opt::ArgStringList Arguments;
00083 
00084   /// Response file name, if this command is set to use one, or nullptr
00085   /// otherwise
00086   const char *ResponseFile;
00087 
00088   /// The input file list in case we need to emit a file list instead of a
00089   /// proper response file
00090   llvm::opt::ArgStringList InputFileList;
00091 
00092   /// String storage if we need to create a new argument to specify a response
00093   /// file
00094   std::string ResponseFileFlag;
00095 
00096   /// When a response file is needed, we try to put most arguments in an
00097   /// exclusive file, while others remains as regular command line arguments.
00098   /// This functions fills a vector with the regular command line arguments,
00099   /// argv, excluding the ones passed in a response file.
00100   void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const;
00101 
00102   /// Encodes an array of C strings into a single string separated by whitespace.
00103   /// This function will also put in quotes arguments that have whitespaces and
00104   /// will escape the regular backslashes (used in Windows paths) and quotes.
00105   /// The results are the contents of a response file, written into a raw_ostream.
00106   void writeResponseFile(raw_ostream &OS) const;
00107 
00108 public:
00109   Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
00110           const llvm::opt::ArgStringList &_Arguments);
00111 
00112   void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
00113              CrashReportInfo *CrashInfo = nullptr) const override;
00114 
00115   virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
00116                       bool *ExecutionFailed) const;
00117 
00118   /// getSource - Return the Action which caused the creation of this job.
00119   const Action &getSource() const { return Source; }
00120 
00121   /// getCreator - Return the Tool which caused the creation of this job.
00122   const Tool &getCreator() const { return Creator; }
00123 
00124   /// Set to pass arguments via a response file when launching the command
00125   void setResponseFile(const char *FileName);
00126 
00127   /// Set an input file list, necessary if we need to use a response file but
00128   /// the tool being called only supports input files lists.
00129   void setInputFileList(llvm::opt::ArgStringList List) {
00130     InputFileList = std::move(List);
00131   }
00132 
00133   const char *getExecutable() const { return Executable; }
00134 
00135   const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
00136 
00137   static bool classof(const Job *J) {
00138     return J->getKind() == CommandClass ||
00139            J->getKind() == FallbackCommandClass;
00140   }
00141 };
00142 
00143 /// Like Command, but with a fallback which is executed in case
00144 /// the primary command crashes.
00145 class FallbackCommand : public Command {
00146 public:
00147   FallbackCommand(const Action &Source_, const Tool &Creator_,
00148                   const char *Executable_, const ArgStringList &Arguments_,
00149                   std::unique_ptr<Command> Fallback_);
00150 
00151   void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
00152              CrashReportInfo *CrashInfo = nullptr) const override;
00153 
00154   int Execute(const StringRef **Redirects, std::string *ErrMsg,
00155               bool *ExecutionFailed) const override;
00156 
00157   static bool classof(const Job *J) {
00158     return J->getKind() == FallbackCommandClass;
00159   }
00160 
00161 private:
00162   std::unique_ptr<Command> Fallback;
00163 };
00164 
00165 /// JobList - A sequence of jobs to perform.
00166 class JobList : public Job {
00167 public:
00168   typedef SmallVector<std::unique_ptr<Job>, 4> list_type;
00169   typedef list_type::size_type size_type;
00170   typedef llvm::pointee_iterator<list_type::iterator> iterator;
00171   typedef llvm::pointee_iterator<list_type::const_iterator> const_iterator;
00172 
00173 private:
00174   list_type Jobs;
00175 
00176 public:
00177   JobList();
00178   virtual ~JobList() {}
00179 
00180   void Print(llvm::raw_ostream &OS, const char *Terminator,
00181              bool Quote, CrashReportInfo *CrashInfo = nullptr) const override;
00182 
00183   /// Add a job to the list (taking ownership).
00184   void addJob(std::unique_ptr<Job> J) { Jobs.push_back(std::move(J)); }
00185 
00186   /// Clear the job list.
00187   void clear();
00188 
00189   const list_type &getJobs() const { return Jobs; }
00190 
00191   size_type size() const { return Jobs.size(); }
00192   iterator begin() { return Jobs.begin(); }
00193   const_iterator begin() const { return Jobs.begin(); }
00194   iterator end() { return Jobs.end(); }
00195   const_iterator end() const { return Jobs.end(); }
00196 
00197   static bool classof(const Job *J) {
00198     return J->getKind() == JobListClass;
00199   }
00200 };
00201 
00202 } // end namespace driver
00203 } // end namespace clang
00204 
00205 #endif