Coverage Report

Created: 2021-08-24 07:12

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