Job.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Job.h - Commands to Execute ------------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_CLANG_DRIVER_JOB_H
  14. #define LLVM_CLANG_DRIVER_JOB_H
  15. #include "clang/Basic/LLVM.h"
  16. #include "clang/Driver/InputInfo.h"
  17. #include "llvm/ADT/ArrayRef.h"
  18. #include "llvm/ADT/Optional.h"
  19. #include "llvm/ADT/SmallVector.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/ADT/iterator.h"
  22. #include "llvm/Option/Option.h"
  23. #include "llvm/Support/Program.h"
  24. #include <memory>
  25. #include <string>
  26. #include <utility>
  27. #include <vector>
  28. namespace clang {
  29. namespace driver {
  30. class Action;
  31. class InputInfo;
  32. class Tool;
  33. struct CrashReportInfo {
  34. StringRef Filename;
  35. StringRef VFSPath;
  36. CrashReportInfo(StringRef Filename, StringRef VFSPath)
  37. : Filename(Filename), VFSPath(VFSPath) {}
  38. };
  39. // Encodes the kind of response file supported for a command invocation.
  40. // Response files are necessary if the command line gets too large, requiring
  41. // the arguments to be transferred to a file.
  42. struct ResponseFileSupport {
  43. enum ResponseFileKind {
  44. // Provides full support for response files, which means we can transfer
  45. // all tool input arguments to a file.
  46. RF_Full,
  47. // Input file names can live in a file, but flags can't. This is a special
  48. // case for old versions of Apple's ld64.
  49. RF_FileList,
  50. // Does not support response files: all arguments must be passed via
  51. // command line.
  52. RF_None
  53. };
  54. /// The level of support for response files.
  55. ResponseFileKind ResponseKind;
  56. /// The encoding to use when writing response files on Windows. Ignored on
  57. /// other host OSes.
  58. ///
  59. /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response
  60. /// files encoded with the system current code page.
  61. /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows.
  62. /// - Clang accepts both UTF8 and UTF16.
  63. ///
  64. /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should
  65. /// always use UTF16 for Windows, which is the Windows official encoding for
  66. /// international characters.
  67. llvm::sys::WindowsEncodingMethod ResponseEncoding;
  68. /// What prefix to use for the command-line argument when passing a response
  69. /// file.
  70. const char *ResponseFlag;
  71. /// Returns a ResponseFileSupport indicating that response files are not
  72. /// supported.
  73. static constexpr ResponseFileSupport None() {
  74. return {RF_None, llvm::sys::WEM_UTF8, nullptr};
  75. }
  76. /// Returns a ResponseFileSupport indicating that response files are
  77. /// supported, using the @file syntax. On windows, the file is written in the
  78. /// UTF8 encoding. On other OSes, no re-encoding occurs.
  79. static constexpr ResponseFileSupport AtFileUTF8() {
  80. return {RF_Full, llvm::sys::WEM_UTF8, "@"};
  81. }
  82. /// Returns a ResponseFileSupport indicating that response files are
  83. /// supported, using the @file syntax. On windows, the file is written in the
  84. /// current ANSI code-page encoding. On other OSes, no re-encoding occurs.
  85. static constexpr ResponseFileSupport AtFileCurCP() {
  86. return {RF_Full, llvm::sys::WEM_CurrentCodePage, "@"};
  87. }
  88. /// Returns a ResponseFileSupport indicating that response files are
  89. /// supported, using the @file syntax. On windows, the file is written in the
  90. /// UTF-16 encoding. On other OSes, no re-encoding occurs.
  91. static constexpr ResponseFileSupport AtFileUTF16() {
  92. return {RF_Full, llvm::sys::WEM_UTF16, "@"};
  93. }
  94. };
  95. /// Command - An executable path/name and argument vector to
  96. /// execute.
  97. class Command {
  98. /// Source - The action which caused the creation of this job.
  99. const Action &Source;
  100. /// Tool - The tool which caused the creation of this job.
  101. const Tool &Creator;
  102. /// Whether and how to generate response files if the arguments are too long.
  103. ResponseFileSupport ResponseSupport;
  104. /// The executable to run.
  105. const char *Executable;
  106. /// The list of program arguments (not including the implicit first
  107. /// argument, which will be the executable).
  108. llvm::opt::ArgStringList Arguments;
  109. /// The list of program inputs.
  110. std::vector<InputInfo> InputInfoList;
  111. /// The list of program arguments which are outputs. May be empty.
  112. std::vector<std::string> OutputFilenames;
  113. /// Response file name, if this command is set to use one, or nullptr
  114. /// otherwise
  115. const char *ResponseFile = nullptr;
  116. /// The input file list in case we need to emit a file list instead of a
  117. /// proper response file
  118. llvm::opt::ArgStringList InputFileList;
  119. /// String storage if we need to create a new argument to specify a response
  120. /// file
  121. std::string ResponseFileFlag;
  122. /// See Command::setEnvironment
  123. std::vector<const char *> Environment;
  124. /// Information on executable run provided by OS.
  125. mutable Optional<llvm::sys::ProcessStatistics> ProcStat;
  126. /// When a response file is needed, we try to put most arguments in an
  127. /// exclusive file, while others remains as regular command line arguments.
  128. /// This functions fills a vector with the regular command line arguments,
  129. /// argv, excluding the ones passed in a response file.
  130. void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const;
  131. /// Encodes an array of C strings into a single string separated by whitespace.
  132. /// This function will also put in quotes arguments that have whitespaces and
  133. /// will escape the regular backslashes (used in Windows paths) and quotes.
  134. /// The results are the contents of a response file, written into a raw_ostream.
  135. void writeResponseFile(raw_ostream &OS) const;
  136. public:
  137. /// Whether to print the input filenames when executing.
  138. bool PrintInputFilenames = false;
  139. /// Whether the command will be executed in this process or not.
  140. bool InProcess = false;
  141. Command(const Action &Source, const Tool &Creator,
  142. ResponseFileSupport ResponseSupport, const char *Executable,
  143. const llvm::opt::ArgStringList &Arguments, ArrayRef<InputInfo> Inputs,
  144. ArrayRef<InputInfo> Outputs = None);
  145. // FIXME: This really shouldn't be copyable, but is currently copied in some
  146. // error handling in Driver::generateCompilationDiagnostics.
  147. Command(const Command &) = default;
  148. virtual ~Command() = default;
  149. virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
  150. CrashReportInfo *CrashInfo = nullptr) const;
  151. virtual int Execute(ArrayRef<Optional<StringRef>> Redirects,
  152. std::string *ErrMsg, bool *ExecutionFailed) const;
  153. /// getSource - Return the Action which caused the creation of this job.
  154. const Action &getSource() const { return Source; }
  155. /// getCreator - Return the Tool which caused the creation of this job.
  156. const Tool &getCreator() const { return Creator; }
  157. /// Returns the kind of response file supported by the current invocation.
  158. const ResponseFileSupport &getResponseFileSupport() {
  159. return ResponseSupport;
  160. }
  161. /// Set to pass arguments via a response file when launching the command
  162. void setResponseFile(const char *FileName);
  163. /// Set an input file list, necessary if you specified an RF_FileList response
  164. /// file support.
  165. void setInputFileList(llvm::opt::ArgStringList List) {
  166. InputFileList = std::move(List);
  167. }
  168. /// Sets the environment to be used by the new process.
  169. /// \param NewEnvironment An array of environment variables.
  170. /// \remark If the environment remains unset, then the environment
  171. /// from the parent process will be used.
  172. virtual void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment);
  173. void replaceArguments(llvm::opt::ArgStringList List) {
  174. Arguments = std::move(List);
  175. }
  176. void replaceExecutable(const char *Exe) { Executable = Exe; }
  177. const char *getExecutable() const { return Executable; }
  178. const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
  179. const std::vector<InputInfo> &getInputInfos() const { return InputInfoList; }
  180. const std::vector<std::string> &getOutputFilenames() const {
  181. return OutputFilenames;
  182. }
  183. Optional<llvm::sys::ProcessStatistics> getProcessStatistics() const {
  184. return ProcStat;
  185. }
  186. protected:
  187. /// Optionally print the filenames to be compiled
  188. void PrintFileNames() const;
  189. };
  190. /// Use the CC1 tool callback when available, to avoid creating a new process
  191. class CC1Command : public Command {
  192. public:
  193. CC1Command(const Action &Source, const Tool &Creator,
  194. ResponseFileSupport ResponseSupport, const char *Executable,
  195. const llvm::opt::ArgStringList &Arguments,
  196. ArrayRef<InputInfo> Inputs, ArrayRef<InputInfo> Outputs = None);
  197. void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
  198. CrashReportInfo *CrashInfo = nullptr) const override;
  199. int Execute(ArrayRef<Optional<StringRef>> Redirects, std::string *ErrMsg,
  200. bool *ExecutionFailed) const override;
  201. void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment) override;
  202. };
  203. /// Like Command, but always pretends that the wrapped command succeeded.
  204. class ForceSuccessCommand : public Command {
  205. public:
  206. ForceSuccessCommand(const Action &Source_, const Tool &Creator_,
  207. ResponseFileSupport ResponseSupport,
  208. const char *Executable_,
  209. const llvm::opt::ArgStringList &Arguments_,
  210. ArrayRef<InputInfo> Inputs,
  211. ArrayRef<InputInfo> Outputs = None);
  212. void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
  213. CrashReportInfo *CrashInfo = nullptr) const override;
  214. int Execute(ArrayRef<Optional<StringRef>> Redirects, std::string *ErrMsg,
  215. bool *ExecutionFailed) const override;
  216. };
  217. /// JobList - A sequence of jobs to perform.
  218. class JobList {
  219. public:
  220. using list_type = SmallVector<std::unique_ptr<Command>, 4>;
  221. using size_type = list_type::size_type;
  222. using iterator = llvm::pointee_iterator<list_type::iterator>;
  223. using const_iterator = llvm::pointee_iterator<list_type::const_iterator>;
  224. private:
  225. list_type Jobs;
  226. public:
  227. void Print(llvm::raw_ostream &OS, const char *Terminator,
  228. bool Quote, CrashReportInfo *CrashInfo = nullptr) const;
  229. /// Add a job to the list (taking ownership).
  230. void addJob(std::unique_ptr<Command> J) { Jobs.push_back(std::move(J)); }
  231. /// Clear the job list.
  232. void clear();
  233. const list_type &getJobs() const { return Jobs; }
  234. bool empty() const { return Jobs.empty(); }
  235. size_type size() const { return Jobs.size(); }
  236. iterator begin() { return Jobs.begin(); }
  237. const_iterator begin() const { return Jobs.begin(); }
  238. iterator end() { return Jobs.end(); }
  239. const_iterator end() const { return Jobs.end(); }
  240. };
  241. } // namespace driver
  242. } // namespace clang
  243. #endif // LLVM_CLANG_DRIVER_JOB_H
  244. #ifdef __GNUC__
  245. #pragma GCC diagnostic pop
  246. #endif