1789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar//===--- Job.h - Commands to Execute ----------------------------*- C++ -*-===//
2789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar//
3789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar//                     The LLVM Compiler Infrastructure
4789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar//
5789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar// This file is distributed under the University of Illinois Open Source
6789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar// License. See LICENSE.TXT for details.
7789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar//
8789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar//===----------------------------------------------------------------------===//
9789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
10176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_DRIVER_JOB_H
11176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_DRIVER_JOB_H
12789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
1330a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/Basic/LLVM.h"
14789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar#include "llvm/ADT/SmallVector.h"
15176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#include "llvm/ADT/iterator.h"
160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#include "llvm/Option/Option.h"
17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <memory>
18a1ead48a4e9961c7eb22592310c7e9c30cb56794Daniel Dunbar
19fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborgnamespace llvm {
20fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg  class raw_ostream;
21fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg}
22fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg
23789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarnamespace clang {
24789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarnamespace driver {
25b1e25a1bc03292dc538d336573e0be1490223171Reid Klecknerclass Action;
26daab7b1016f0a82fefa4f7be6e63c57c06b19ffcDaniel Dunbarclass Command;
27daab7b1016f0a82fefa4f7be6e63c57c06b19ffcDaniel Dunbarclass Tool;
28789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
2964228b6c0696f3579d40bab0ef40691ef4f41242Hans Wennborg// Re-export this as clang::driver::ArgStringList.
305c6ecf5a07317edc4a01f967a43eb3f76142d387Hans Wennborgusing llvm::opt::ArgStringList;
314832ee31e6ab96b77ad429ef9347fbf09c099f47Hans Wennborg
32176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct CrashReportInfo {
33176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StringRef Filename;
34176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StringRef VFSPath;
35176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
36176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CrashReportInfo(StringRef Filename, StringRef VFSPath)
37176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      : Filename(Filename), VFSPath(VFSPath) {}
38176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
39176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
40789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarclass Job {
41789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarpublic:
42789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  enum JobClass {
43789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar    CommandClass,
44c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg    FallbackCommandClass,
45789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar    JobListClass
46789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  };
47789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
48789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarprivate:
49789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  JobClass Kind;
50789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
51789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarprotected:
52789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  Job(JobClass _Kind) : Kind(_Kind) {}
53789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarpublic:
54789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  virtual ~Job();
55789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
56789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  JobClass getKind() const { return Kind; }
57fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg
58fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg  /// Print - Print this Job in -### format.
59fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg  ///
60fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg  /// \param OS - The stream to print on.
61fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg  /// \param Terminator - A string to print at the end of the line.
62fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg  /// \param Quote - Should separate arguments be quoted.
63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \param CrashInfo - Details for inclusion in a crash report.
64176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                     CrashReportInfo *CrashInfo = nullptr) const = 0;
66789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar};
67789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
68c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg/// Command - An executable path/name and argument vector to
69c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg/// execute.
70789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarclass Command : public Job {
71cae087e164e94e4286c11bf694dd0ff88f295302Daniel Dunbar  /// Source - The action which caused the creation of this job.
72cae087e164e94e4286c11bf694dd0ff88f295302Daniel Dunbar  const Action &Source;
73cae087e164e94e4286c11bf694dd0ff88f295302Daniel Dunbar
74daab7b1016f0a82fefa4f7be6e63c57c06b19ffcDaniel Dunbar  /// Tool - The tool which caused the creation of this job.
75daab7b1016f0a82fefa4f7be6e63c57c06b19ffcDaniel Dunbar  const Tool &Creator;
76daab7b1016f0a82fefa4f7be6e63c57c06b19ffcDaniel Dunbar
77d57ac5990d22592665a67a28fc5d39f1155424d3Daniel Dunbar  /// The executable to run.
78789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  const char *Executable;
79d57ac5990d22592665a67a28fc5d39f1155424d3Daniel Dunbar
80d57ac5990d22592665a67a28fc5d39f1155424d3Daniel Dunbar  /// The list of program arguments (not including the implicit first
81d57ac5990d22592665a67a28fc5d39f1155424d3Daniel Dunbar  /// argument, which will be the executable).
825c6ecf5a07317edc4a01f967a43eb3f76142d387Hans Wennborg  llvm::opt::ArgStringList Arguments;
83789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
84176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// Response file name, if this command is set to use one, or nullptr
85176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// otherwise
86176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const char *ResponseFile;
87176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
88176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// The input file list in case we need to emit a file list instead of a
89176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// proper response file
90176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  llvm::opt::ArgStringList InputFileList;
91176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
92176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// String storage if we need to create a new argument to specify a response
93176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// file
94176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  std::string ResponseFileFlag;
95176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
96176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// When a response file is needed, we try to put most arguments in an
97176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// exclusive file, while others remains as regular command line arguments.
98176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// This functions fills a vector with the regular command line arguments,
99176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// argv, excluding the ones passed in a response file.
100176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const;
101176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
102176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// Encodes an array of C strings into a single string separated by whitespace.
103176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// This function will also put in quotes arguments that have whitespaces and
104176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// will escape the regular backslashes (used in Windows paths) and quotes.
105176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// The results are the contents of a response file, written into a raw_ostream.
106176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void writeResponseFile(raw_ostream &OS) const;
107176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
108789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarpublic:
109daab7b1016f0a82fefa4f7be6e63c57c06b19ffcDaniel Dunbar  Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
1105c6ecf5a07317edc4a01f967a43eb3f76142d387Hans Wennborg          const llvm::opt::ArgStringList &_Arguments);
111cae087e164e94e4286c11bf694dd0ff88f295302Daniel Dunbar
112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
113176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines             CrashReportInfo *CrashInfo = nullptr) const override;
114fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg
115c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg  virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
116c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg                      bool *ExecutionFailed) const;
117aaaa2a1889fe882e7e41048e3b298ca594454eb1Hans Wennborg
118cae087e164e94e4286c11bf694dd0ff88f295302Daniel Dunbar  /// getSource - Return the Action which caused the creation of this job.
119cae087e164e94e4286c11bf694dd0ff88f295302Daniel Dunbar  const Action &getSource() const { return Source; }
120789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
121daab7b1016f0a82fefa4f7be6e63c57c06b19ffcDaniel Dunbar  /// getCreator - Return the Tool which caused the creation of this job.
122daab7b1016f0a82fefa4f7be6e63c57c06b19ffcDaniel Dunbar  const Tool &getCreator() const { return Creator; }
123daab7b1016f0a82fefa4f7be6e63c57c06b19ffcDaniel Dunbar
124176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// Set to pass arguments via a response file when launching the command
125176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void setResponseFile(const char *FileName);
126176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
127176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// Set an input file list, necessary if we need to use a response file but
128176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// the tool being called only supports input files lists.
129176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void setInputFileList(llvm::opt::ArgStringList List) {
130176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    InputFileList = std::move(List);
131176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
132176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const char *getExecutable() const { return Executable; }
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1355c6ecf5a07317edc4a01f967a43eb3f76142d387Hans Wennborg  const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
136789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
1371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Job *J) {
138c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg    return J->getKind() == CommandClass ||
139c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg           J->getKind() == FallbackCommandClass;
140789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  }
141789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar};
142789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
143c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg/// Like Command, but with a fallback which is executed in case
144c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg/// the primary command crashes.
145c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborgclass FallbackCommand : public Command {
146c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborgpublic:
147c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg  FallbackCommand(const Action &Source_, const Tool &Creator_,
148c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg                  const char *Executable_, const ArgStringList &Arguments_,
149176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                  std::unique_ptr<Command> Fallback_);
150c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
152176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines             CrashReportInfo *CrashInfo = nullptr) const override;
153c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int Execute(const StringRef **Redirects, std::string *ErrMsg,
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              bool *ExecutionFailed) const override;
156c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg
157c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg  static bool classof(const Job *J) {
158c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg    return J->getKind() == FallbackCommandClass;
159c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg  }
160c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg
161c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborgprivate:
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<Command> Fallback;
163c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg};
164c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg
165c8ba0a0acd30f0b56d08a3a0947f68ac01a40730Hans Wennborg/// JobList - A sequence of jobs to perform.
166789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarclass JobList : public Job {
167789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarpublic:
168176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  typedef SmallVector<std::unique_ptr<Job>, 4> list_type;
169cfcb96f610d6354234e8c33f3a25e340f6cd3a80Daniel Dunbar  typedef list_type::size_type size_type;
170176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  typedef llvm::pointee_iterator<list_type::iterator> iterator;
171176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  typedef llvm::pointee_iterator<list_type::const_iterator> const_iterator;
172789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
173789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarprivate:
174789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  list_type Jobs;
175789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
176789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbarpublic:
177789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  JobList();
17833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  ~JobList() override {}
179789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void Print(llvm::raw_ostream &OS, const char *Terminator,
181176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines             bool Quote, CrashReportInfo *CrashInfo = nullptr) const override;
182fc3389701ead32709ba84825e4c06651065da2c0Hans Wennborg
1839d44023453094832ada2770941e9e4c96ce0e75eDaniel Dunbar  /// Add a job to the list (taking ownership).
184176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void addJob(std::unique_ptr<Job> J) { Jobs.push_back(std::move(J)); }
185789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
1862b81910618f63e4ce2373c926a26e76b4b91373fChad Rosier  /// Clear the job list.
1872b81910618f63e4ce2373c926a26e76b4b91373fChad Rosier  void clear();
1882b81910618f63e4ce2373c926a26e76b4b91373fChad Rosier
189789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  const list_type &getJobs() const { return Jobs; }
190789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
191cfcb96f610d6354234e8c33f3a25e340f6cd3a80Daniel Dunbar  size_type size() const { return Jobs.size(); }
192cfcb96f610d6354234e8c33f3a25e340f6cd3a80Daniel Dunbar  iterator begin() { return Jobs.begin(); }
193cfcb96f610d6354234e8c33f3a25e340f6cd3a80Daniel Dunbar  const_iterator begin() const { return Jobs.begin(); }
194cfcb96f610d6354234e8c33f3a25e340f6cd3a80Daniel Dunbar  iterator end() { return Jobs.end(); }
195cfcb96f610d6354234e8c33f3a25e340f6cd3a80Daniel Dunbar  const_iterator end() const { return Jobs.end(); }
1961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Job *J) {
1981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return J->getKind() == JobListClass;
199789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar  }
200789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar};
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
202789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar} // end namespace driver
203789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar} // end namespace clang
204789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar
205789e220d481371d52bd6265b5c414c5fe277f76bDaniel Dunbar#endif
206