1//===--- Action.h - Abstract compilation steps ------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef CLANG_DRIVER_ACTION_H_
11#define CLANG_DRIVER_ACTION_H_
12
13#include "clang/Driver/Types.h"
14#include "clang/Driver/Util.h"
15#include "llvm/ADT/SmallVector.h"
16
17namespace llvm {
18namespace opt {
19  class Arg;
20}
21}
22
23namespace clang {
24namespace driver {
25
26/// Action - Represent an abstract compilation step to perform.
27///
28/// An action represents an edge in the compilation graph; typically
29/// it is a job to transform an input using some tool.
30///
31/// The current driver is hard wired to expect actions which produce a
32/// single primary output, at least in terms of controlling the
33/// compilation. Actions can produce auxiliary files, but can only
34/// produce a single output to feed into subsequent actions.
35class Action {
36public:
37  typedef ActionList::size_type size_type;
38  typedef ActionList::iterator iterator;
39  typedef ActionList::const_iterator const_iterator;
40
41  enum ActionClass {
42    InputClass = 0,
43    BindArchClass,
44    PreprocessJobClass,
45    PrecompileJobClass,
46    AnalyzeJobClass,
47    MigrateJobClass,
48    CompileJobClass,
49    AssembleJobClass,
50    LinkJobClass,
51    LipoJobClass,
52    DsymutilJobClass,
53    VerifyDebugInfoJobClass,
54    VerifyPCHJobClass,
55
56    JobClassFirst=PreprocessJobClass,
57    JobClassLast=VerifyPCHJobClass
58  };
59
60  static const char *getClassName(ActionClass AC);
61
62private:
63  ActionClass Kind;
64
65  /// The output type of this action.
66  types::ID Type;
67
68  ActionList Inputs;
69
70  unsigned OwnsInputs : 1;
71
72protected:
73  Action(ActionClass _Kind, types::ID _Type)
74    : Kind(_Kind), Type(_Type), OwnsInputs(true)  {}
75  Action(ActionClass _Kind, Action *Input, types::ID _Type)
76    : Kind(_Kind), Type(_Type), Inputs(&Input, &Input + 1), OwnsInputs(true) {}
77  Action(ActionClass _Kind, const ActionList &_Inputs, types::ID _Type)
78    : Kind(_Kind), Type(_Type), Inputs(_Inputs), OwnsInputs(true) {}
79public:
80  virtual ~Action();
81
82  const char *getClassName() const { return Action::getClassName(getKind()); }
83
84  bool getOwnsInputs() { return OwnsInputs; }
85  void setOwnsInputs(bool Value) { OwnsInputs = Value; }
86
87  ActionClass getKind() const { return Kind; }
88  types::ID getType() const { return Type; }
89
90  ActionList &getInputs() { return Inputs; }
91  const ActionList &getInputs() const { return Inputs; }
92
93  size_type size() const { return Inputs.size(); }
94
95  iterator begin() { return Inputs.begin(); }
96  iterator end() { return Inputs.end(); }
97  const_iterator begin() const { return Inputs.begin(); }
98  const_iterator end() const { return Inputs.end(); }
99};
100
101class InputAction : public Action {
102  virtual void anchor();
103  const llvm::opt::Arg &Input;
104
105public:
106  InputAction(const llvm::opt::Arg &_Input, types::ID _Type);
107
108  const llvm::opt::Arg &getInputArg() const { return Input; }
109
110  static bool classof(const Action *A) {
111    return A->getKind() == InputClass;
112  }
113};
114
115class BindArchAction : public Action {
116  virtual void anchor();
117  /// The architecture to bind, or 0 if the default architecture
118  /// should be bound.
119  const char *ArchName;
120
121public:
122  BindArchAction(Action *Input, const char *_ArchName);
123
124  const char *getArchName() const { return ArchName; }
125
126  static bool classof(const Action *A) {
127    return A->getKind() == BindArchClass;
128  }
129};
130
131class JobAction : public Action {
132  virtual void anchor();
133protected:
134  JobAction(ActionClass Kind, Action *Input, types::ID Type);
135  JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
136
137public:
138  static bool classof(const Action *A) {
139    return (A->getKind() >= JobClassFirst &&
140            A->getKind() <= JobClassLast);
141  }
142};
143
144class PreprocessJobAction : public JobAction {
145  void anchor() override;
146public:
147  PreprocessJobAction(Action *Input, types::ID OutputType);
148
149  static bool classof(const Action *A) {
150    return A->getKind() == PreprocessJobClass;
151  }
152};
153
154class PrecompileJobAction : public JobAction {
155  void anchor() override;
156public:
157  PrecompileJobAction(Action *Input, types::ID OutputType);
158
159  static bool classof(const Action *A) {
160    return A->getKind() == PrecompileJobClass;
161  }
162};
163
164class AnalyzeJobAction : public JobAction {
165  void anchor() override;
166public:
167  AnalyzeJobAction(Action *Input, types::ID OutputType);
168
169  static bool classof(const Action *A) {
170    return A->getKind() == AnalyzeJobClass;
171  }
172};
173
174class MigrateJobAction : public JobAction {
175  void anchor() override;
176public:
177  MigrateJobAction(Action *Input, types::ID OutputType);
178
179  static bool classof(const Action *A) {
180    return A->getKind() == MigrateJobClass;
181  }
182};
183
184class CompileJobAction : public JobAction {
185  void anchor() override;
186public:
187  CompileJobAction(Action *Input, types::ID OutputType);
188
189  static bool classof(const Action *A) {
190    return A->getKind() == CompileJobClass;
191  }
192};
193
194class AssembleJobAction : public JobAction {
195  void anchor() override;
196public:
197  AssembleJobAction(Action *Input, types::ID OutputType);
198
199  static bool classof(const Action *A) {
200    return A->getKind() == AssembleJobClass;
201  }
202};
203
204class LinkJobAction : public JobAction {
205  void anchor() override;
206public:
207  LinkJobAction(ActionList &Inputs, types::ID Type);
208
209  static bool classof(const Action *A) {
210    return A->getKind() == LinkJobClass;
211  }
212};
213
214class LipoJobAction : public JobAction {
215  void anchor() override;
216public:
217  LipoJobAction(ActionList &Inputs, types::ID Type);
218
219  static bool classof(const Action *A) {
220    return A->getKind() == LipoJobClass;
221  }
222};
223
224class DsymutilJobAction : public JobAction {
225  void anchor() override;
226public:
227  DsymutilJobAction(ActionList &Inputs, types::ID Type);
228
229  static bool classof(const Action *A) {
230    return A->getKind() == DsymutilJobClass;
231  }
232};
233
234class VerifyJobAction : public JobAction {
235  void anchor() override;
236public:
237  VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type);
238  VerifyJobAction(ActionClass Kind, ActionList &Inputs, types::ID Type);
239  static bool classof(const Action *A) {
240    return A->getKind() == VerifyDebugInfoJobClass ||
241           A->getKind() == VerifyPCHJobClass;
242  }
243};
244
245class VerifyDebugInfoJobAction : public VerifyJobAction {
246  void anchor() override;
247public:
248  VerifyDebugInfoJobAction(Action *Input, types::ID Type);
249  static bool classof(const Action *A) {
250    return A->getKind() == VerifyDebugInfoJobClass;
251  }
252};
253
254class VerifyPCHJobAction : public VerifyJobAction {
255  void anchor() override;
256public:
257  VerifyPCHJobAction(Action *Input, types::ID Type);
258  static bool classof(const Action *A) {
259    return A->getKind() == VerifyPCHJobClass;
260  }
261};
262
263} // end namespace driver
264} // end namespace clang
265
266#endif
267