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