clang  19.0.0git
Job.h
Go to the documentation of this file.
1 //===- Job.h - Commands to Execute ------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_CLANG_DRIVER_JOB_H
10 #define LLVM_CLANG_DRIVER_JOB_H
11 
12 #include "clang/Basic/LLVM.h"
13 #include "clang/Driver/InputInfo.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/iterator.h"
19 #include "llvm/Option/Option.h"
20 #include "llvm/Support/Program.h"
21 #include <memory>
22 #include <optional>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 
27 namespace clang {
28 namespace driver {
29 
30 class Action;
31 class InputInfo;
32 class Tool;
33 
35  StringRef Filename;
36  StringRef VFSPath;
37 
38  CrashReportInfo(StringRef Filename, StringRef VFSPath)
40 };
41 
42 // Encodes the kind of response file supported for a command invocation.
43 // Response files are necessary if the command line gets too large, requiring
44 // the arguments to be transferred to a file.
47  // Provides full support for response files, which means we can transfer
48  // all tool input arguments to a file.
50  // Input file names can live in a file, but flags can't. This is a special
51  // case for old versions of Apple's ld64.
53  // Does not support response files: all arguments must be passed via
54  // command line.
55  RF_None
56  };
57  /// The level of support for response files.
59 
60  /// The encoding to use when writing response files on Windows. Ignored on
61  /// other host OSes.
62  ///
63  /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response
64  /// files encoded with the system current code page.
65  /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows.
66  /// - Clang accepts both UTF8 and UTF16.
67  ///
68  /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should
69  /// always use UTF16 for Windows, which is the Windows official encoding for
70  /// international characters.
71  llvm::sys::WindowsEncodingMethod ResponseEncoding;
72 
73  /// What prefix to use for the command-line argument when passing a response
74  /// file.
75  const char *ResponseFlag;
76 
77  /// Returns a ResponseFileSupport indicating that response files are not
78  /// supported.
79  static constexpr ResponseFileSupport None() {
80  return {RF_None, llvm::sys::WEM_UTF8, nullptr};
81  }
82 
83  /// Returns a ResponseFileSupport indicating that response files are
84  /// supported, using the @file syntax. On windows, the file is written in the
85  /// UTF8 encoding. On other OSes, no re-encoding occurs.
86  static constexpr ResponseFileSupport AtFileUTF8() {
87  return {RF_Full, llvm::sys::WEM_UTF8, "@"};
88  }
89 
90  /// Returns a ResponseFileSupport indicating that response files are
91  /// supported, using the @file syntax. On windows, the file is written in the
92  /// current ANSI code-page encoding. On other OSes, no re-encoding occurs.
93  static constexpr ResponseFileSupport AtFileCurCP() {
94  return {RF_Full, llvm::sys::WEM_CurrentCodePage, "@"};
95  }
96 
97  /// Returns a ResponseFileSupport indicating that response files are
98  /// supported, using the @file syntax. On windows, the file is written in the
99  /// UTF-16 encoding. On other OSes, no re-encoding occurs.
100  static constexpr ResponseFileSupport AtFileUTF16() {
101  return {RF_Full, llvm::sys::WEM_UTF16, "@"};
102  }
103 };
104 
105 /// Command - An executable path/name and argument vector to
106 /// execute.
107 class Command {
108 public:
109  using ErrorCodeDiagMapTy = llvm::DenseMap<int, std::string>;
110  using ErrorCodeExitMapTy = llvm::DenseMap<int, bool>;
111 
112 private:
113  /// Source - The action which caused the creation of this job.
114  const Action &Source;
115 
116  /// Tool - The tool which caused the creation of this job.
117  const Tool &Creator;
118 
119  /// Whether and how to generate response files if the arguments are too long.
120  ResponseFileSupport ResponseSupport;
121 
122  /// The executable to run.
123  const char *Executable;
124 
125  /// The container for custom driver-set diagnostic messages that are
126  /// produced upon particular error codes returned by the command.
127  /// In order to add such a diagnostic for an external tool, consider the
128  /// following criteria:
129  /// 1) Does the command's executable return different codes upon different
130  /// types of errors?
131  /// 2) If the executable provides a single error code for various error types,
132  /// is only a certain type of failure expected to occur within the driver
133  /// flow? E.g. the driver guarantees a valid input to the tool, so any
134  /// "invalid input" error can be ruled out
135  ErrorCodeDiagMapTy ErrorCodeDiagMap;
136 
137  /// Similar to the container for the diagnostic messages, this container
138  /// is used to signify if the toolchain should error and exit right away
139  /// or if we should continue compilation.
140  ErrorCodeExitMapTy ErrorCodeExitMap;
141 
142  /// Optional argument to prepend.
143  const char *PrependArg;
144 
145  /// The list of program arguments (not including the implicit first
146  /// argument, which will be the executable).
147  llvm::opt::ArgStringList Arguments;
148 
149  /// The list of program inputs.
150  std::vector<InputInfo> InputInfoList;
151 
152  /// The list of program arguments which are outputs. May be empty.
153  std::vector<std::string> OutputFilenames;
154 
155  /// Response file name, if this command is set to use one, or nullptr
156  /// otherwise
157  const char *ResponseFile = nullptr;
158 
159  /// The input file list in case we need to emit a file list instead of a
160  /// proper response file
161  llvm::opt::ArgStringList InputFileList;
162 
163  /// String storage if we need to create a new argument to specify a response
164  /// file
165  std::string ResponseFileFlag;
166 
167  /// See Command::setEnvironment
168  std::vector<const char *> Environment;
169 
170  /// Optional redirection for stdin, stdout, stderr.
171  std::vector<std::optional<std::string>> RedirectFiles;
172 
173  /// Information on executable run provided by OS.
174  mutable std::optional<llvm::sys::ProcessStatistics> ProcStat;
175 
176  /// When a response file is needed, we try to put most arguments in an
177  /// exclusive file, while others remains as regular command line arguments.
178  /// This functions fills a vector with the regular command line arguments,
179  /// argv, excluding the ones passed in a response file.
180  void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const;
181 
182  /// Encodes an array of C strings into a single string separated by whitespace.
183  /// This function will also put in quotes arguments that have whitespaces and
184  /// will escape the regular backslashes (used in Windows paths) and quotes.
185  /// The results are the contents of a response file, written into a raw_ostream.
186  void writeResponseFile(raw_ostream &OS) const;
187 
188 public:
189  /// Whether to print the input filenames when executing.
190  bool PrintInputFilenames = false;
191 
192  /// Whether the command will be executed in this process or not.
193  bool InProcess = false;
194 
195  Command(const Action &Source, const Tool &Creator,
196  ResponseFileSupport ResponseSupport, const char *Executable,
197  const llvm::opt::ArgStringList &Arguments, ArrayRef<InputInfo> Inputs,
198  ArrayRef<InputInfo> Outputs = std::nullopt,
199  const char *PrependArg = nullptr);
200  // FIXME: This really shouldn't be copyable, but is currently copied in some
201  // error handling in Driver::generateCompilationDiagnostics.
202  Command(const Command &) = default;
203  virtual ~Command() = default;
204 
205  virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
206  CrashReportInfo *CrashInfo = nullptr) const;
207 
208  virtual int Execute(ArrayRef<std::optional<StringRef>> Redirects,
209  std::string *ErrMsg, bool *ExecutionFailed) const;
210 
211  /// Store a custom driver diagnostic message upon a particular error code
212  /// returned by the command
213  void addDiagForErrorCode(int ErrorCode, StringRef CustomDiag);
214 
215  /// Store if the compilation should exit upon a particular error code
216  /// returned by the command
217  void addExitForErrorCode(int ErrorCode, bool Exit);
218 
219  /// Get the custom driver diagnostic message for a particular error code
220  /// if such was stored. Returns an empty string if no diagnostic message
221  /// was found for the given error code.
222  StringRef getDiagForErrorCode(int ErrorCode) const;
223 
224  /// Will the tool exit when a particular error code is encountered. Returns
225  /// true if not set (always exit)
226  bool getWillExitForErrorCode(int ErrorCode) const;
227 
228  /// getSource - Return the Action which caused the creation of this job.
229  const Action &getSource() const { return Source; }
230 
231  /// getCreator - Return the Tool which caused the creation of this job.
232  const Tool &getCreator() const { return Creator; }
233 
234  /// Returns the kind of response file supported by the current invocation.
236  return ResponseSupport;
237  }
238 
239  /// Set to pass arguments via a response file when launching the command
240  void setResponseFile(const char *FileName);
241 
242  /// Set an input file list, necessary if you specified an RF_FileList response
243  /// file support.
244  void setInputFileList(llvm::opt::ArgStringList List) {
245  InputFileList = std::move(List);
246  }
247 
248  /// Sets the environment to be used by the new process.
249  /// \param NewEnvironment An array of environment variables.
250  /// \remark If the environment remains unset, then the environment
251  /// from the parent process will be used.
252  virtual void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment);
253 
254  void
255  setRedirectFiles(const std::vector<std::optional<std::string>> &Redirects);
256 
257  void replaceArguments(llvm::opt::ArgStringList List) {
258  Arguments = std::move(List);
259  }
260 
261  void replaceExecutable(const char *Exe) { Executable = Exe; }
262 
263  const char *getExecutable() const { return Executable; }
264 
265  const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
266 
267  const std::vector<InputInfo> &getInputInfos() const { return InputInfoList; }
268 
269  const std::vector<std::string> &getOutputFilenames() const {
270  return OutputFilenames;
271  }
272 
273  std::optional<llvm::sys::ProcessStatistics> getProcessStatistics() const {
274  return ProcStat;
275  }
276 
277 protected:
278  /// Optionally print the filenames to be compiled
279  void PrintFileNames() const;
280 };
281 
282 /// Use the CC1 tool callback when available, to avoid creating a new process
283 class CC1Command : public Command {
284 public:
285  CC1Command(const Action &Source, const Tool &Creator,
286  ResponseFileSupport ResponseSupport, const char *Executable,
287  const llvm::opt::ArgStringList &Arguments,
288  ArrayRef<InputInfo> Inputs,
289  ArrayRef<InputInfo> Outputs = std::nullopt,
290  const char *PrependArg = nullptr);
291 
292  void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
293  CrashReportInfo *CrashInfo = nullptr) const override;
294 
295  int Execute(ArrayRef<std::optional<StringRef>> Redirects, std::string *ErrMsg,
296  bool *ExecutionFailed) const override;
297 
298  void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment) override;
299 };
300 
301 /// JobList - A sequence of jobs to perform.
302 class JobList {
303 public:
305  using size_type = list_type::size_type;
306  using iterator = llvm::pointee_iterator<list_type::iterator>;
307  using const_iterator = llvm::pointee_iterator<list_type::const_iterator>;
308 
309 private:
310  list_type Jobs;
311 
312 public:
313  void Print(llvm::raw_ostream &OS, const char *Terminator,
314  bool Quote, CrashReportInfo *CrashInfo = nullptr) const;
315 
316  /// Add a job to the list (taking ownership).
317  void addJob(std::unique_ptr<Command> J) { Jobs.push_back(std::move(J)); }
318 
319  /// Clear the job list.
320  void clear();
321 
322  /// Return a mutable list of Jobs for llvm-foreach wrapping.
323  list_type &getJobsForOverride() { return Jobs; }
324  const list_type &getJobs() const { return Jobs; }
325 
326  bool empty() const { return Jobs.empty(); }
327  size_type size() const { return Jobs.size(); }
328  iterator begin() { return Jobs.begin(); }
329  const_iterator begin() const { return Jobs.begin(); }
330  iterator end() { return Jobs.end(); }
331  const_iterator end() const { return Jobs.end(); }
332 };
333 
334 } // namespace driver
335 } // namespace clang
336 
337 #endif // LLVM_CLANG_DRIVER_JOB_H
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Action - Represent an abstract compilation step to perform.
Definition: Action.h:49
Use the CC1 tool callback when available, to avoid creating a new process.
Definition: Job.h:283
void setEnvironment(llvm::ArrayRef< const char * > NewEnvironment) override
Sets the environment to be used by the new process.
Definition: Job.cpp:469
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const override
Definition: Job.cpp:425
int Execute(ArrayRef< std::optional< StringRef >> Redirects, std::string *ErrMsg, bool *ExecutionFailed) const override
Definition: Job.cpp:432
CC1Command(const Action &Source, const Tool &Creator, ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef< InputInfo > Inputs, ArrayRef< InputInfo > Outputs=std::nullopt, const char *PrependArg=nullptr)
Definition: Job.cpp:414
Command - An executable path/name and argument vector to execute.
Definition: Job.h:107
llvm::DenseMap< int, std::string > ErrorCodeDiagMapTy
Definition: Job.h:109
const char * getExecutable() const
Definition: Job.h:263
const ResponseFileSupport & getResponseFileSupport()
Returns the kind of response file supported by the current invocation.
Definition: Job.h:235
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
Definition: Job.h:232
void addDiagForErrorCode(int ErrorCode, StringRef CustomDiag)
Store a custom driver diagnostic message upon a particular error code returned by the command.
Definition: Job.cpp:167
virtual ~Command()=default
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
Definition: Job.cpp:323
Command(const Command &)=default
StringRef getDiagForErrorCode(int ErrorCode) const
Get the custom driver diagnostic message for a particular error code if such was stored.
Definition: Job.cpp:175
void replaceExecutable(const char *Exe)
Definition: Job.h:261
void setInputFileList(llvm::opt::ArgStringList List)
Set an input file list, necessary if you specified an RF_FileList response file support.
Definition: Job.h:244
void addExitForErrorCode(int ErrorCode, bool Exit)
Store if the compilation should exit upon a particular error code returned by the command.
Definition: Job.cpp:171
bool PrintInputFilenames
Whether to print the input filenames when executing.
Definition: Job.h:190
const std::vector< std::string > & getOutputFilenames() const
Definition: Job.h:269
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
Definition: Job.cpp:229
bool getWillExitForErrorCode(int ErrorCode) const
Will the tool exit when a particular error code is encountered.
Definition: Job.cpp:182
bool InProcess
Whether the command will be executed in this process or not.
Definition: Job.h:193
virtual int Execute(ArrayRef< std::optional< StringRef >> Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Definition: Job.cpp:348
std::optional< llvm::sys::ProcessStatistics > getProcessStatistics() const
Definition: Job.h:273
virtual void setEnvironment(llvm::ArrayRef< const char * > NewEnvironment)
Sets the environment to be used by the new process.
Definition: Job.cpp:329
Command(const Action &Source, const Tool &Creator, ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef< InputInfo > Inputs, ArrayRef< InputInfo > Outputs=std::nullopt, const char *PrependArg=nullptr)
Definition: Job.cpp:39
const std::vector< InputInfo > & getInputInfos() const
Definition: Job.h:267
const llvm::opt::ArgStringList & getArguments() const
Definition: Job.h:265
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
Definition: Job.h:229
llvm::DenseMap< int, bool > ErrorCodeExitMapTy
Definition: Job.h:110
void setRedirectFiles(const std::vector< std::optional< std::string >> &Redirects)
Definition: Job.cpp:335
void replaceArguments(llvm::opt::ArgStringList List)
Definition: Job.h:257
void PrintFileNames() const
Optionally print the filenames to be compiled.
Definition: Job.cpp:340
JobList - A sequence of jobs to perform.
Definition: Job.h:302
size_type size() const
Definition: Job.h:327
list_type & getJobsForOverride()
Return a mutable list of Jobs for llvm-foreach wrapping.
Definition: Job.h:323
bool empty() const
Definition: Job.h:326
list_type::size_type size_type
Definition: Job.h:305
void clear()
Clear the job list.
Definition: Job.cpp:481
const_iterator begin() const
Definition: Job.h:329
const list_type & getJobs() const
Definition: Job.h:324
void addJob(std::unique_ptr< Command > J)
Add a job to the list (taking ownership).
Definition: Job.h:317
const_iterator end() const
Definition: Job.h:331
iterator end()
Definition: Job.h:330
llvm::pointee_iterator< list_type::iterator > iterator
Definition: Job.h:306
llvm::pointee_iterator< list_type::const_iterator > const_iterator
Definition: Job.h:307
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
Definition: Job.cpp:475
iterator begin()
Definition: Job.h:328
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
The JSON file list parser is used to communicate input to InstallAPI.
CrashReportInfo(StringRef Filename, StringRef VFSPath)
Definition: Job.h:38
ResponseFileKind ResponseKind
The level of support for response files.
Definition: Job.h:58
llvm::sys::WindowsEncodingMethod ResponseEncoding
The encoding to use when writing response files on Windows.
Definition: Job.h:71
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.
Definition: Job.h:79
static constexpr ResponseFileSupport AtFileUTF8()
Definition: Job.h:86
const char * ResponseFlag
What prefix to use for the command-line argument when passing a response file.
Definition: Job.h:75
static constexpr ResponseFileSupport AtFileCurCP()
Definition: Job.h:93
static constexpr ResponseFileSupport AtFileUTF16()
Definition: Job.h:100