Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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/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 <optional>
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
      : 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
  static constexpr ResponseFileSupport None() {
79
    return {RF_None, llvm::sys::WEM_UTF8, nullptr};
80
  }
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
  static constexpr ResponseFileSupport AtFileUTF8() {
86
    return {RF_Full, llvm::sys::WEM_UTF8, "@"};
87
  }
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
  static constexpr ResponseFileSupport AtFileCurCP() {
93
    return {RF_Full, llvm::sys::WEM_CurrentCodePage, "@"};
94
  }
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
  static constexpr ResponseFileSupport AtFileUTF16() {
100
    return {RF_Full, llvm::sys::WEM_UTF16, "@"};
101
  }
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
  /// Optional redirection for stdin, stdout, stderr.
145
  std::vector<std::optional<std::string>> RedirectFiles;
146
 
147
  /// Information on executable run provided by OS.
148
  mutable std::optional<llvm::sys::ProcessStatistics> ProcStat;
149
 
150
  /// When a response file is needed, we try to put most arguments in an
151
  /// exclusive file, while others remains as regular command line arguments.
152
  /// This functions fills a vector with the regular command line arguments,
153
  /// argv, excluding the ones passed in a response file.
154
  void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const;
155
 
156
  /// Encodes an array of C strings into a single string separated by whitespace.
157
  /// This function will also put in quotes arguments that have whitespaces and
158
  /// will escape the regular backslashes (used in Windows paths) and quotes.
159
  /// The results are the contents of a response file, written into a raw_ostream.
160
  void writeResponseFile(raw_ostream &OS) const;
161
 
162
public:
163
  /// Whether to print the input filenames when executing.
164
  bool PrintInputFilenames = false;
165
 
166
  /// Whether the command will be executed in this process or not.
167
  bool InProcess = false;
168
 
169
  Command(const Action &Source, const Tool &Creator,
170
          ResponseFileSupport ResponseSupport, const char *Executable,
171
          const llvm::opt::ArgStringList &Arguments, ArrayRef<InputInfo> Inputs,
172
          ArrayRef<InputInfo> Outputs = std::nullopt);
173
  // FIXME: This really shouldn't be copyable, but is currently copied in some
174
  // error handling in Driver::generateCompilationDiagnostics.
175
  Command(const Command &) = default;
176
  virtual ~Command() = default;
177
 
178
  virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
179
                     CrashReportInfo *CrashInfo = nullptr) const;
180
 
181
  virtual int Execute(ArrayRef<std::optional<StringRef>> Redirects,
182
                      std::string *ErrMsg, bool *ExecutionFailed) const;
183
 
184
  /// getSource - Return the Action which caused the creation of this job.
185
  const Action &getSource() const { return Source; }
186
 
187
  /// getCreator - Return the Tool which caused the creation of this job.
188
  const Tool &getCreator() const { return Creator; }
189
 
190
  /// Returns the kind of response file supported by the current invocation.
191
  const ResponseFileSupport &getResponseFileSupport() {
192
    return ResponseSupport;
193
  }
194
 
195
  /// Set to pass arguments via a response file when launching the command
196
  void setResponseFile(const char *FileName);
197
 
198
  /// Set an input file list, necessary if you specified an RF_FileList response
199
  /// file support.
200
  void setInputFileList(llvm::opt::ArgStringList List) {
201
    InputFileList = std::move(List);
202
  }
203
 
204
  /// Sets the environment to be used by the new process.
205
  /// \param NewEnvironment An array of environment variables.
206
  /// \remark If the environment remains unset, then the environment
207
  ///         from the parent process will be used.
208
  virtual void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment);
209
 
210
  void
211
  setRedirectFiles(const std::vector<std::optional<std::string>> &Redirects);
212
 
213
  void replaceArguments(llvm::opt::ArgStringList List) {
214
    Arguments = std::move(List);
215
  }
216
 
217
  void replaceExecutable(const char *Exe) { Executable = Exe; }
218
 
219
  const char *getExecutable() const { return Executable; }
220
 
221
  const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
222
 
223
  const std::vector<InputInfo> &getInputInfos() const { return InputInfoList; }
224
 
225
  const std::vector<std::string> &getOutputFilenames() const {
226
    return OutputFilenames;
227
  }
228
 
229
  std::optional<llvm::sys::ProcessStatistics> getProcessStatistics() const {
230
    return ProcStat;
231
  }
232
 
233
protected:
234
  /// Optionally print the filenames to be compiled
235
  void PrintFileNames() const;
236
};
237
 
238
/// Use the CC1 tool callback when available, to avoid creating a new process
239
class CC1Command : public Command {
240
public:
241
  CC1Command(const Action &Source, const Tool &Creator,
242
             ResponseFileSupport ResponseSupport, const char *Executable,
243
             const llvm::opt::ArgStringList &Arguments,
244
             ArrayRef<InputInfo> Inputs,
245
             ArrayRef<InputInfo> Outputs = std::nullopt);
246
 
247
  void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
248
             CrashReportInfo *CrashInfo = nullptr) const override;
249
 
250
  int Execute(ArrayRef<std::optional<StringRef>> Redirects, std::string *ErrMsg,
251
              bool *ExecutionFailed) const override;
252
 
253
  void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment) override;
254
};
255
 
256
/// Like Command, but always pretends that the wrapped command succeeded.
257
class ForceSuccessCommand : public Command {
258
public:
259
  ForceSuccessCommand(const Action &Source_, const Tool &Creator_,
260
                      ResponseFileSupport ResponseSupport,
261
                      const char *Executable_,
262
                      const llvm::opt::ArgStringList &Arguments_,
263
                      ArrayRef<InputInfo> Inputs,
264
                      ArrayRef<InputInfo> Outputs = std::nullopt);
265
 
266
  void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
267
             CrashReportInfo *CrashInfo = nullptr) const override;
268
 
269
  int Execute(ArrayRef<std::optional<StringRef>> Redirects, std::string *ErrMsg,
270
              bool *ExecutionFailed) const override;
271
};
272
 
273
/// JobList - A sequence of jobs to perform.
274
class JobList {
275
public:
276
  using list_type = SmallVector<std::unique_ptr<Command>, 4>;
277
  using size_type = list_type::size_type;
278
  using iterator = llvm::pointee_iterator<list_type::iterator>;
279
  using const_iterator = llvm::pointee_iterator<list_type::const_iterator>;
280
 
281
private:
282
  list_type Jobs;
283
 
284
public:
285
  void Print(llvm::raw_ostream &OS, const char *Terminator,
286
             bool Quote, CrashReportInfo *CrashInfo = nullptr) const;
287
 
288
  /// Add a job to the list (taking ownership).
289
  void addJob(std::unique_ptr<Command> J) { Jobs.push_back(std::move(J)); }
290
 
291
  /// Clear the job list.
292
  void clear();
293
 
294
  const list_type &getJobs() const { return Jobs; }
295
 
296
  bool empty() const { return Jobs.empty(); }
297
  size_type size() const { return Jobs.size(); }
298
  iterator begin() { return Jobs.begin(); }
299
  const_iterator begin() const { return Jobs.begin(); }
300
  iterator end() { return Jobs.end(); }
301
  const_iterator end() const { return Jobs.end(); }
302
};
303
 
304
} // namespace driver
305
} // namespace clang
306
 
307
#endif // LLVM_CLANG_DRIVER_JOB_H