• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 LLVM_CLANG_DRIVER_ACTION_H
11 #define LLVM_CLANG_DRIVER_ACTION_H
12 
13 #include "clang/Basic/Cuda.h"
14 #include "clang/Driver/Types.h"
15 #include "clang/Driver/Util.h"
16 #include "llvm/ADT/SmallVector.h"
17 
18 namespace llvm {
19 
20 class StringRef;
21 
22 namespace opt {
23   class Arg;
24 }
25 }
26 
27 namespace clang {
28 namespace driver {
29 
30 /// Action - Represent an abstract compilation step to perform.
31 ///
32 /// An action represents an edge in the compilation graph; typically
33 /// it is a job to transform an input using some tool.
34 ///
35 /// The current driver is hard wired to expect actions which produce a
36 /// single primary output, at least in terms of controlling the
37 /// compilation. Actions can produce auxiliary files, but can only
38 /// produce a single output to feed into subsequent actions.
39 ///
40 /// Actions are usually owned by a Compilation, which creates new
41 /// actions via MakeAction().
42 class Action {
43 public:
44   typedef ActionList::size_type size_type;
45   typedef ActionList::iterator input_iterator;
46   typedef ActionList::const_iterator input_const_iterator;
47   typedef llvm::iterator_range<input_iterator> input_range;
48   typedef llvm::iterator_range<input_const_iterator> input_const_range;
49 
50   enum ActionClass {
51     InputClass = 0,
52     BindArchClass,
53     CudaDeviceClass,
54     CudaHostClass,
55     PreprocessJobClass,
56     PrecompileJobClass,
57     AnalyzeJobClass,
58     MigrateJobClass,
59     CompileJobClass,
60     BackendJobClass,
61     AssembleJobClass,
62     LinkJobClass,
63     LipoJobClass,
64     DsymutilJobClass,
65     VerifyDebugInfoJobClass,
66     VerifyPCHJobClass,
67 
68     JobClassFirst=PreprocessJobClass,
69     JobClassLast=VerifyPCHJobClass
70   };
71 
72   // The offloading kind determines if this action is binded to a particular
73   // programming model. Each entry reserves one bit. We also have a special kind
74   // to designate the host offloading tool chain.
75   //
76   // FIXME: This is currently used to indicate that tool chains are used in a
77   // given programming, but will be used here as well once a generic offloading
78   // action is implemented.
79   enum OffloadKind {
80     OFK_None = 0x00,
81     // The host offloading tool chain.
82     OFK_Host = 0x01,
83     // The device offloading tool chains - one bit for each programming model.
84     OFK_Cuda = 0x02,
85   };
86 
87   static const char *getClassName(ActionClass AC);
88 
89 private:
90   ActionClass Kind;
91 
92   /// The output type of this action.
93   types::ID Type;
94 
95   ActionList Inputs;
96 
97 protected:
Action(ActionClass Kind,types::ID Type)98   Action(ActionClass Kind, types::ID Type) : Action(Kind, ActionList(), Type) {}
Action(ActionClass Kind,Action * Input,types::ID Type)99   Action(ActionClass Kind, Action *Input, types::ID Type)
100       : Action(Kind, ActionList({Input}), Type) {}
Action(ActionClass Kind,Action * Input)101   Action(ActionClass Kind, Action *Input)
102       : Action(Kind, ActionList({Input}), Input->getType()) {}
Action(ActionClass Kind,const ActionList & Inputs,types::ID Type)103   Action(ActionClass Kind, const ActionList &Inputs, types::ID Type)
104       : Kind(Kind), Type(Type), Inputs(Inputs) {}
105 
106 public:
107   virtual ~Action();
108 
getClassName()109   const char *getClassName() const { return Action::getClassName(getKind()); }
110 
getKind()111   ActionClass getKind() const { return Kind; }
getType()112   types::ID getType() const { return Type; }
113 
getInputs()114   ActionList &getInputs() { return Inputs; }
getInputs()115   const ActionList &getInputs() const { return Inputs; }
116 
size()117   size_type size() const { return Inputs.size(); }
118 
input_begin()119   input_iterator input_begin() { return Inputs.begin(); }
input_end()120   input_iterator input_end() { return Inputs.end(); }
inputs()121   input_range inputs() { return input_range(input_begin(), input_end()); }
input_begin()122   input_const_iterator input_begin() const { return Inputs.begin(); }
input_end()123   input_const_iterator input_end() const { return Inputs.end(); }
inputs()124   input_const_range inputs() const {
125     return input_const_range(input_begin(), input_end());
126   }
127 };
128 
129 class InputAction : public Action {
130   virtual void anchor();
131   const llvm::opt::Arg &Input;
132 
133 public:
134   InputAction(const llvm::opt::Arg &Input, types::ID Type);
135 
getInputArg()136   const llvm::opt::Arg &getInputArg() const { return Input; }
137 
classof(const Action * A)138   static bool classof(const Action *A) {
139     return A->getKind() == InputClass;
140   }
141 };
142 
143 class BindArchAction : public Action {
144   virtual void anchor();
145   /// The architecture to bind, or 0 if the default architecture
146   /// should be bound.
147   const char *ArchName;
148 
149 public:
150   BindArchAction(Action *Input, const char *ArchName);
151 
getArchName()152   const char *getArchName() const { return ArchName; }
153 
classof(const Action * A)154   static bool classof(const Action *A) {
155     return A->getKind() == BindArchClass;
156   }
157 };
158 
159 class CudaDeviceAction : public Action {
160   virtual void anchor();
161 
162   const CudaArch GpuArch;
163 
164   /// True when action results are not consumed by the host action (e.g when
165   /// -fsyntax-only or --cuda-device-only options are used).
166   bool AtTopLevel;
167 
168 public:
169   CudaDeviceAction(Action *Input, CudaArch Arch, bool AtTopLevel);
170 
171   /// Get the CUDA GPU architecture to which this Action corresponds.  Returns
172   /// UNKNOWN if this Action corresponds to multiple architectures.
getGpuArch()173   CudaArch getGpuArch() const { return GpuArch; }
174 
isAtTopLevel()175   bool isAtTopLevel() const { return AtTopLevel; }
176 
classof(const Action * A)177   static bool classof(const Action *A) {
178     return A->getKind() == CudaDeviceClass;
179   }
180 };
181 
182 class CudaHostAction : public Action {
183   virtual void anchor();
184   ActionList DeviceActions;
185 
186 public:
187   CudaHostAction(Action *Input, const ActionList &DeviceActions);
188 
getDeviceActions()189   const ActionList &getDeviceActions() const { return DeviceActions; }
190 
classof(const Action * A)191   static bool classof(const Action *A) { return A->getKind() == CudaHostClass; }
192 };
193 
194 class JobAction : public Action {
195   virtual void anchor();
196 protected:
197   JobAction(ActionClass Kind, Action *Input, types::ID Type);
198   JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
199 
200 public:
classof(const Action * A)201   static bool classof(const Action *A) {
202     return (A->getKind() >= JobClassFirst &&
203             A->getKind() <= JobClassLast);
204   }
205 };
206 
207 class PreprocessJobAction : public JobAction {
208   void anchor() override;
209 public:
210   PreprocessJobAction(Action *Input, types::ID OutputType);
211 
classof(const Action * A)212   static bool classof(const Action *A) {
213     return A->getKind() == PreprocessJobClass;
214   }
215 };
216 
217 class PrecompileJobAction : public JobAction {
218   void anchor() override;
219 public:
220   PrecompileJobAction(Action *Input, types::ID OutputType);
221 
classof(const Action * A)222   static bool classof(const Action *A) {
223     return A->getKind() == PrecompileJobClass;
224   }
225 };
226 
227 class AnalyzeJobAction : public JobAction {
228   void anchor() override;
229 public:
230   AnalyzeJobAction(Action *Input, types::ID OutputType);
231 
classof(const Action * A)232   static bool classof(const Action *A) {
233     return A->getKind() == AnalyzeJobClass;
234   }
235 };
236 
237 class MigrateJobAction : public JobAction {
238   void anchor() override;
239 public:
240   MigrateJobAction(Action *Input, types::ID OutputType);
241 
classof(const Action * A)242   static bool classof(const Action *A) {
243     return A->getKind() == MigrateJobClass;
244   }
245 };
246 
247 class CompileJobAction : public JobAction {
248   void anchor() override;
249 public:
250   CompileJobAction(Action *Input, types::ID OutputType);
251 
classof(const Action * A)252   static bool classof(const Action *A) {
253     return A->getKind() == CompileJobClass;
254   }
255 };
256 
257 class BackendJobAction : public JobAction {
258   void anchor() override;
259 public:
260   BackendJobAction(Action *Input, types::ID OutputType);
261 
classof(const Action * A)262   static bool classof(const Action *A) {
263     return A->getKind() == BackendJobClass;
264   }
265 };
266 
267 class AssembleJobAction : public JobAction {
268   void anchor() override;
269 public:
270   AssembleJobAction(Action *Input, types::ID OutputType);
271 
classof(const Action * A)272   static bool classof(const Action *A) {
273     return A->getKind() == AssembleJobClass;
274   }
275 };
276 
277 class LinkJobAction : public JobAction {
278   void anchor() override;
279 public:
280   LinkJobAction(ActionList &Inputs, types::ID Type);
281 
classof(const Action * A)282   static bool classof(const Action *A) {
283     return A->getKind() == LinkJobClass;
284   }
285 };
286 
287 class LipoJobAction : public JobAction {
288   void anchor() override;
289 public:
290   LipoJobAction(ActionList &Inputs, types::ID Type);
291 
classof(const Action * A)292   static bool classof(const Action *A) {
293     return A->getKind() == LipoJobClass;
294   }
295 };
296 
297 class DsymutilJobAction : public JobAction {
298   void anchor() override;
299 public:
300   DsymutilJobAction(ActionList &Inputs, types::ID Type);
301 
classof(const Action * A)302   static bool classof(const Action *A) {
303     return A->getKind() == DsymutilJobClass;
304   }
305 };
306 
307 class VerifyJobAction : public JobAction {
308   void anchor() override;
309 public:
310   VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type);
classof(const Action * A)311   static bool classof(const Action *A) {
312     return A->getKind() == VerifyDebugInfoJobClass ||
313            A->getKind() == VerifyPCHJobClass;
314   }
315 };
316 
317 class VerifyDebugInfoJobAction : public VerifyJobAction {
318   void anchor() override;
319 public:
320   VerifyDebugInfoJobAction(Action *Input, types::ID Type);
classof(const Action * A)321   static bool classof(const Action *A) {
322     return A->getKind() == VerifyDebugInfoJobClass;
323   }
324 };
325 
326 class VerifyPCHJobAction : public VerifyJobAction {
327   void anchor() override;
328 public:
329   VerifyPCHJobAction(Action *Input, types::ID Type);
classof(const Action * A)330   static bool classof(const Action *A) {
331     return A->getKind() == VerifyPCHJobClass;
332   }
333 };
334 
335 } // end namespace driver
336 } // end namespace clang
337 
338 #endif
339