1193326Sed//===--- Job.h - Commands to Execute ----------------------------*- C++ -*-===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed
10193326Sed#ifndef CLANG_DRIVER_JOB_H_
11193326Sed#define CLANG_DRIVER_JOB_H_
12193326Sed
13249423Sdim#include "clang/Basic/LLVM.h"
14263508Sdim#include "llvm/ADT/OwningPtr.h"
15193326Sed#include "llvm/ADT/SmallVector.h"
16263508Sdim#include "llvm/Option/Option.h"
17193326Sed
18263508Sdimnamespace llvm {
19263508Sdim  class raw_ostream;
20263508Sdim}
21263508Sdim
22193326Sednamespace clang {
23193326Sednamespace driver {
24263508Sdimclass Action;
25200583Srdivackyclass Command;
26200583Srdivackyclass Tool;
27193326Sed
28263508Sdim// Re-export this as clang::driver::ArgStringList.
29263508Sdimusing llvm::opt::ArgStringList;
30263508Sdim
31193326Sedclass Job {
32193326Sedpublic:
33193326Sed  enum JobClass {
34193326Sed    CommandClass,
35263508Sdim    FallbackCommandClass,
36193326Sed    JobListClass
37193326Sed  };
38193326Sed
39193326Sedprivate:
40193326Sed  JobClass Kind;
41193326Sed
42193326Sedprotected:
43193326Sed  Job(JobClass _Kind) : Kind(_Kind) {}
44193326Sedpublic:
45193326Sed  virtual ~Job();
46193326Sed
47193326Sed  JobClass getKind() const { return Kind; }
48193326Sed
49263508Sdim  /// Print - Print this Job in -### format.
50263508Sdim  ///
51263508Sdim  /// \param OS - The stream to print on.
52263508Sdim  /// \param Terminator - A string to print at the end of the line.
53263508Sdim  /// \param Quote - Should separate arguments be quoted.
54263508Sdim  /// \param CrashReport - Whether to print for inclusion in a crash report.
55263508Sdim  virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
56263508Sdim                     bool Quote, bool CrashReport = false) const = 0;
57193326Sed};
58193326Sed
59263508Sdim/// Command - An executable path/name and argument vector to
60263508Sdim/// execute.
61193326Sedclass Command : public Job {
62195341Sed  /// Source - The action which caused the creation of this job.
63195341Sed  const Action &Source;
64195341Sed
65200583Srdivacky  /// Tool - The tool which caused the creation of this job.
66200583Srdivacky  const Tool &Creator;
67200583Srdivacky
68193326Sed  /// The executable to run.
69193326Sed  const char *Executable;
70193326Sed
71193326Sed  /// The list of program arguments (not including the implicit first
72193326Sed  /// argument, which will be the executable).
73263508Sdim  llvm::opt::ArgStringList Arguments;
74193326Sed
75193326Sedpublic:
76200583Srdivacky  Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
77263508Sdim          const llvm::opt::ArgStringList &_Arguments);
78193326Sed
79263508Sdim  virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
80263508Sdim                     bool Quote, bool CrashReport = false) const;
81263508Sdim
82263508Sdim  virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
83263508Sdim                      bool *ExecutionFailed) const;
84263508Sdim
85195341Sed  /// getSource - Return the Action which caused the creation of this job.
86195341Sed  const Action &getSource() const { return Source; }
87195341Sed
88200583Srdivacky  /// getCreator - Return the Tool which caused the creation of this job.
89200583Srdivacky  const Tool &getCreator() const { return Creator; }
90200583Srdivacky
91263508Sdim  const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
92195341Sed
93263508Sdim  static bool classof(const Job *J) {
94263508Sdim    return J->getKind() == CommandClass ||
95263508Sdim           J->getKind() == FallbackCommandClass;
96263508Sdim  }
97263508Sdim};
98193326Sed
99263508Sdim/// Like Command, but with a fallback which is executed in case
100263508Sdim/// the primary command crashes.
101263508Sdimclass FallbackCommand : public Command {
102263508Sdimpublic:
103263508Sdim  FallbackCommand(const Action &Source_, const Tool &Creator_,
104263508Sdim                  const char *Executable_, const ArgStringList &Arguments_,
105263508Sdim                  Command *Fallback_);
106263508Sdim
107263508Sdim  virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
108263508Sdim                     bool Quote, bool CrashReport = false) const;
109263508Sdim
110263508Sdim  virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
111263508Sdim                      bool *ExecutionFailed) const;
112263508Sdim
113198092Srdivacky  static bool classof(const Job *J) {
114263508Sdim    return J->getKind() == FallbackCommandClass;
115193326Sed  }
116263508Sdim
117263508Sdimprivate:
118263508Sdim  OwningPtr<Command> Fallback;
119193326Sed};
120193326Sed
121263508Sdim/// JobList - A sequence of jobs to perform.
122193326Sedclass JobList : public Job {
123193326Sedpublic:
124226633Sdim  typedef SmallVector<Job*, 4> list_type;
125193326Sed  typedef list_type::size_type size_type;
126193326Sed  typedef list_type::iterator iterator;
127193326Sed  typedef list_type::const_iterator const_iterator;
128193326Sed
129193326Sedprivate:
130193326Sed  list_type Jobs;
131193326Sed
132193326Sedpublic:
133193326Sed  JobList();
134205219Srdivacky  virtual ~JobList();
135193326Sed
136263508Sdim  virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
137263508Sdim                     bool Quote, bool CrashReport = false) const;
138263508Sdim
139205219Srdivacky  /// Add a job to the list (taking ownership).
140193326Sed  void addJob(Job *J) { Jobs.push_back(J); }
141193326Sed
142226633Sdim  /// Clear the job list.
143226633Sdim  void clear();
144226633Sdim
145193326Sed  const list_type &getJobs() const { return Jobs; }
146193326Sed
147193326Sed  size_type size() const { return Jobs.size(); }
148193326Sed  iterator begin() { return Jobs.begin(); }
149193326Sed  const_iterator begin() const { return Jobs.begin(); }
150193326Sed  iterator end() { return Jobs.end(); }
151193326Sed  const_iterator end() const { return Jobs.end(); }
152198092Srdivacky
153198092Srdivacky  static bool classof(const Job *J) {
154198092Srdivacky    return J->getKind() == JobListClass;
155193326Sed  }
156193326Sed};
157198092Srdivacky
158193326Sed} // end namespace driver
159193326Sed} // end namespace clang
160193326Sed
161193326Sed#endif
162