Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:52

0001 //===- Action.h - Abstract compilation steps --------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_DRIVER_ACTION_H
0010 #define LLVM_CLANG_DRIVER_ACTION_H
0011 
0012 #include "clang/Basic/LLVM.h"
0013 #include "clang/Driver/Types.h"
0014 #include "clang/Driver/Util.h"
0015 #include "llvm/ADT/ArrayRef.h"
0016 #include "llvm/ADT/STLExtras.h"
0017 #include "llvm/ADT/SmallVector.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/ADT/iterator_range.h"
0020 #include <string>
0021 
0022 namespace llvm {
0023 namespace opt {
0024 
0025 class Arg;
0026 
0027 } // namespace opt
0028 } // namespace llvm
0029 
0030 namespace clang {
0031 namespace driver {
0032 
0033 class ToolChain;
0034 
0035 /// Action - Represent an abstract compilation step to perform.
0036 ///
0037 /// An action represents an edge in the compilation graph; typically
0038 /// it is a job to transform an input using some tool.
0039 ///
0040 /// The current driver is hard wired to expect actions which produce a
0041 /// single primary output, at least in terms of controlling the
0042 /// compilation. Actions can produce auxiliary files, but can only
0043 /// produce a single output to feed into subsequent actions.
0044 ///
0045 /// Actions are usually owned by a Compilation, which creates new
0046 /// actions via MakeAction().
0047 class Action {
0048 public:
0049   using size_type = ActionList::size_type;
0050   using input_iterator = ActionList::iterator;
0051   using input_const_iterator = ActionList::const_iterator;
0052   using input_range = llvm::iterator_range<input_iterator>;
0053   using input_const_range = llvm::iterator_range<input_const_iterator>;
0054 
0055   enum ActionClass {
0056     InputClass = 0,
0057     BindArchClass,
0058     OffloadClass,
0059     PreprocessJobClass,
0060     PrecompileJobClass,
0061     ExtractAPIJobClass,
0062     AnalyzeJobClass,
0063     MigrateJobClass,
0064     CompileJobClass,
0065     BackendJobClass,
0066     AssembleJobClass,
0067     LinkJobClass,
0068     IfsMergeJobClass,
0069     LipoJobClass,
0070     DsymutilJobClass,
0071     VerifyDebugInfoJobClass,
0072     VerifyPCHJobClass,
0073     OffloadBundlingJobClass,
0074     OffloadUnbundlingJobClass,
0075     OffloadPackagerJobClass,
0076     LinkerWrapperJobClass,
0077     StaticLibJobClass,
0078     BinaryAnalyzeJobClass,
0079 
0080     JobClassFirst = PreprocessJobClass,
0081     JobClassLast = BinaryAnalyzeJobClass
0082   };
0083 
0084   // The offloading kind determines if this action is binded to a particular
0085   // programming model. Each entry reserves one bit. We also have a special kind
0086   // to designate the host offloading tool chain.
0087   enum OffloadKind {
0088     OFK_None = 0x00,
0089 
0090     // The host offloading tool chain.
0091     OFK_Host = 0x01,
0092 
0093     // The device offloading tool chains - one bit for each programming model.
0094     OFK_Cuda = 0x02,
0095     OFK_OpenMP = 0x04,
0096     OFK_HIP = 0x08,
0097     OFK_SYCL = 0x10,
0098   };
0099 
0100   static const char *getClassName(ActionClass AC);
0101 
0102 private:
0103   ActionClass Kind;
0104 
0105   /// The output type of this action.
0106   types::ID Type;
0107 
0108   ActionList Inputs;
0109 
0110   /// Flag that is set to true if this action can be collapsed with others
0111   /// actions that depend on it. This is true by default and set to false when
0112   /// the action is used by two different tool chains, which is enabled by the
0113   /// offloading support implementation.
0114   bool CanBeCollapsedWithNextDependentAction = true;
0115 
0116 protected:
0117   ///
0118   /// Offload information.
0119   ///
0120 
0121   /// The host offloading kind - a combination of kinds encoded in a mask.
0122   /// Multiple programming models may be supported simultaneously by the same
0123   /// host.
0124   unsigned ActiveOffloadKindMask = 0u;
0125 
0126   /// Offloading kind of the device.
0127   OffloadKind OffloadingDeviceKind = OFK_None;
0128 
0129   /// The Offloading architecture associated with this action.
0130   const char *OffloadingArch = nullptr;
0131 
0132   /// The Offloading toolchain associated with this device action.
0133   const ToolChain *OffloadingToolChain = nullptr;
0134 
0135   Action(ActionClass Kind, types::ID Type) : Action(Kind, ActionList(), Type) {}
0136   Action(ActionClass Kind, Action *Input, types::ID Type)
0137       : Action(Kind, ActionList({Input}), Type) {}
0138   Action(ActionClass Kind, Action *Input)
0139       : Action(Kind, ActionList({Input}), Input->getType()) {}
0140   Action(ActionClass Kind, const ActionList &Inputs, types::ID Type)
0141       : Kind(Kind), Type(Type), Inputs(Inputs) {}
0142 
0143 public:
0144   virtual ~Action();
0145 
0146   const char *getClassName() const { return Action::getClassName(getKind()); }
0147 
0148   ActionClass getKind() const { return Kind; }
0149   types::ID getType() const { return Type; }
0150 
0151   ActionList &getInputs() { return Inputs; }
0152   const ActionList &getInputs() const { return Inputs; }
0153 
0154   size_type size() const { return Inputs.size(); }
0155 
0156   input_iterator input_begin() { return Inputs.begin(); }
0157   input_iterator input_end() { return Inputs.end(); }
0158   input_range inputs() { return input_range(input_begin(), input_end()); }
0159   input_const_iterator input_begin() const { return Inputs.begin(); }
0160   input_const_iterator input_end() const { return Inputs.end(); }
0161   input_const_range inputs() const {
0162     return input_const_range(input_begin(), input_end());
0163   }
0164 
0165   /// Mark this action as not legal to collapse.
0166   void setCannotBeCollapsedWithNextDependentAction() {
0167     CanBeCollapsedWithNextDependentAction = false;
0168   }
0169 
0170   /// Return true if this function can be collapsed with others.
0171   bool isCollapsingWithNextDependentActionLegal() const {
0172     return CanBeCollapsedWithNextDependentAction;
0173   }
0174 
0175   /// Return a string containing the offload kind of the action.
0176   std::string getOffloadingKindPrefix() const;
0177 
0178   /// Return a string that can be used as prefix in order to generate unique
0179   /// files for each offloading kind. By default, no prefix is used for
0180   /// non-device kinds, except if \a CreatePrefixForHost is set.
0181   static std::string
0182   GetOffloadingFileNamePrefix(OffloadKind Kind,
0183                               StringRef NormalizedTriple,
0184                               bool CreatePrefixForHost = false);
0185 
0186   /// Return a string containing a offload kind name.
0187   static StringRef GetOffloadKindName(OffloadKind Kind);
0188 
0189   /// Set the device offload info of this action and propagate it to its
0190   /// dependences.
0191   void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch,
0192                                   const ToolChain *OToolChain);
0193 
0194   /// Append the host offload info of this action and propagate it to its
0195   /// dependences.
0196   void propagateHostOffloadInfo(unsigned OKinds, const char *OArch);
0197 
0198   void setHostOffloadInfo(unsigned OKinds, const char *OArch) {
0199     ActiveOffloadKindMask |= OKinds;
0200     OffloadingArch = OArch;
0201   }
0202 
0203   /// Set the offload info of this action to be the same as the provided action,
0204   /// and propagate it to its dependences.
0205   void propagateOffloadInfo(const Action *A);
0206 
0207   unsigned getOffloadingHostActiveKinds() const {
0208     return ActiveOffloadKindMask;
0209   }
0210 
0211   OffloadKind getOffloadingDeviceKind() const { return OffloadingDeviceKind; }
0212   const char *getOffloadingArch() const { return OffloadingArch; }
0213   const ToolChain *getOffloadingToolChain() const {
0214     return OffloadingToolChain;
0215   }
0216 
0217   /// Check if this action have any offload kinds. Note that host offload kinds
0218   /// are only set if the action is a dependence to a host offload action.
0219   bool isHostOffloading(unsigned int OKind) const {
0220     return ActiveOffloadKindMask & OKind;
0221   }
0222   bool isDeviceOffloading(OffloadKind OKind) const {
0223     return OffloadingDeviceKind == OKind;
0224   }
0225   bool isOffloading(OffloadKind OKind) const {
0226     return isHostOffloading(OKind) || isDeviceOffloading(OKind);
0227   }
0228 };
0229 
0230 class InputAction : public Action {
0231   const llvm::opt::Arg &Input;
0232   std::string Id;
0233   virtual void anchor();
0234 
0235 public:
0236   InputAction(const llvm::opt::Arg &Input, types::ID Type,
0237               StringRef Id = StringRef());
0238 
0239   const llvm::opt::Arg &getInputArg() const { return Input; }
0240 
0241   void setId(StringRef _Id) { Id = _Id.str(); }
0242   StringRef getId() const { return Id; }
0243 
0244   static bool classof(const Action *A) {
0245     return A->getKind() == InputClass;
0246   }
0247 };
0248 
0249 class BindArchAction : public Action {
0250   virtual void anchor();
0251 
0252   /// The architecture to bind, or 0 if the default architecture
0253   /// should be bound.
0254   StringRef ArchName;
0255 
0256 public:
0257   BindArchAction(Action *Input, StringRef ArchName);
0258 
0259   StringRef getArchName() const { return ArchName; }
0260 
0261   static bool classof(const Action *A) {
0262     return A->getKind() == BindArchClass;
0263   }
0264 };
0265 
0266 /// An offload action combines host or/and device actions according to the
0267 /// programming model implementation needs and propagates the offloading kind to
0268 /// its dependences.
0269 class OffloadAction final : public Action {
0270   virtual void anchor();
0271 
0272 public:
0273   /// Type used to communicate device actions. It associates bound architecture,
0274   /// toolchain, and offload kind to each action.
0275   class DeviceDependences final {
0276   public:
0277     using ToolChainList = SmallVector<const ToolChain *, 3>;
0278     using BoundArchList = SmallVector<const char *, 3>;
0279     using OffloadKindList = SmallVector<OffloadKind, 3>;
0280 
0281   private:
0282     // Lists that keep the information for each dependency. All the lists are
0283     // meant to be updated in sync. We are adopting separate lists instead of a
0284     // list of structs, because that simplifies forwarding the actions list to
0285     // initialize the inputs of the base Action class.
0286 
0287     /// The dependence actions.
0288     ActionList DeviceActions;
0289 
0290     /// The offloading toolchains that should be used with the action.
0291     ToolChainList DeviceToolChains;
0292 
0293     /// The architectures that should be used with this action.
0294     BoundArchList DeviceBoundArchs;
0295 
0296     /// The offload kind of each dependence.
0297     OffloadKindList DeviceOffloadKinds;
0298 
0299   public:
0300     /// Add an action along with the associated toolchain, bound arch, and
0301     /// offload kind.
0302     void add(Action &A, const ToolChain &TC, const char *BoundArch,
0303              OffloadKind OKind);
0304 
0305     /// Add an action along with the associated toolchain, bound arch, and
0306     /// offload kinds.
0307     void add(Action &A, const ToolChain &TC, const char *BoundArch,
0308              unsigned OffloadKindMask);
0309 
0310     /// Get each of the individual arrays.
0311     const ActionList &getActions() const { return DeviceActions; }
0312     const ToolChainList &getToolChains() const { return DeviceToolChains; }
0313     const BoundArchList &getBoundArchs() const { return DeviceBoundArchs; }
0314     const OffloadKindList &getOffloadKinds() const {
0315       return DeviceOffloadKinds;
0316     }
0317   };
0318 
0319   /// Type used to communicate host actions. It associates bound architecture,
0320   /// toolchain, and offload kinds to the host action.
0321   class HostDependence final {
0322     /// The dependence action.
0323     Action &HostAction;
0324 
0325     /// The offloading toolchain that should be used with the action.
0326     const ToolChain &HostToolChain;
0327 
0328     /// The architectures that should be used with this action.
0329     const char *HostBoundArch = nullptr;
0330 
0331     /// The offload kind of each dependence.
0332     unsigned HostOffloadKinds = 0u;
0333 
0334   public:
0335     HostDependence(Action &A, const ToolChain &TC, const char *BoundArch,
0336                    const unsigned OffloadKinds)
0337         : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch),
0338           HostOffloadKinds(OffloadKinds) {}
0339 
0340     /// Constructor version that obtains the offload kinds from the device
0341     /// dependencies.
0342     HostDependence(Action &A, const ToolChain &TC, const char *BoundArch,
0343                    const DeviceDependences &DDeps);
0344     Action *getAction() const { return &HostAction; }
0345     const ToolChain *getToolChain() const { return &HostToolChain; }
0346     const char *getBoundArch() const { return HostBoundArch; }
0347     unsigned getOffloadKinds() const { return HostOffloadKinds; }
0348   };
0349 
0350   using OffloadActionWorkTy =
0351       llvm::function_ref<void(Action *, const ToolChain *, const char *)>;
0352 
0353 private:
0354   /// The host offloading toolchain that should be used with the action.
0355   const ToolChain *HostTC = nullptr;
0356 
0357   /// The tool chains associated with the list of actions.
0358   DeviceDependences::ToolChainList DevToolChains;
0359 
0360 public:
0361   OffloadAction(const HostDependence &HDep);
0362   OffloadAction(const DeviceDependences &DDeps, types::ID Ty);
0363   OffloadAction(const HostDependence &HDep, const DeviceDependences &DDeps);
0364 
0365   /// Execute the work specified in \a Work on the host dependence.
0366   void doOnHostDependence(const OffloadActionWorkTy &Work) const;
0367 
0368   /// Execute the work specified in \a Work on each device dependence.
0369   void doOnEachDeviceDependence(const OffloadActionWorkTy &Work) const;
0370 
0371   /// Execute the work specified in \a Work on each dependence.
0372   void doOnEachDependence(const OffloadActionWorkTy &Work) const;
0373 
0374   /// Execute the work specified in \a Work on each host or device dependence if
0375   /// \a IsHostDependenceto is true or false, respectively.
0376   void doOnEachDependence(bool IsHostDependence,
0377                           const OffloadActionWorkTy &Work) const;
0378 
0379   /// Return true if the action has a host dependence.
0380   bool hasHostDependence() const;
0381 
0382   /// Return the host dependence of this action. This function is only expected
0383   /// to be called if the host dependence exists.
0384   Action *getHostDependence() const;
0385 
0386   /// Return true if the action has a single device dependence. If \a
0387   /// DoNotConsiderHostActions is set, ignore the host dependence, if any, while
0388   /// accounting for the number of dependences.
0389   bool hasSingleDeviceDependence(bool DoNotConsiderHostActions = false) const;
0390 
0391   /// Return the single device dependence of this action. This function is only
0392   /// expected to be called if a single device dependence exists. If \a
0393   /// DoNotConsiderHostActions is set, a host dependence is allowed.
0394   Action *
0395   getSingleDeviceDependence(bool DoNotConsiderHostActions = false) const;
0396 
0397   static bool classof(const Action *A) { return A->getKind() == OffloadClass; }
0398 };
0399 
0400 class JobAction : public Action {
0401   virtual void anchor();
0402 
0403 protected:
0404   JobAction(ActionClass Kind, Action *Input, types::ID Type);
0405   JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
0406 
0407 public:
0408   static bool classof(const Action *A) {
0409     return (A->getKind() >= JobClassFirst &&
0410             A->getKind() <= JobClassLast);
0411   }
0412 };
0413 
0414 class PreprocessJobAction : public JobAction {
0415   void anchor() override;
0416 
0417 public:
0418   PreprocessJobAction(Action *Input, types::ID OutputType);
0419 
0420   static bool classof(const Action *A) {
0421     return A->getKind() == PreprocessJobClass;
0422   }
0423 };
0424 
0425 class PrecompileJobAction : public JobAction {
0426   void anchor() override;
0427 
0428 protected:
0429   PrecompileJobAction(ActionClass Kind, Action *Input, types::ID OutputType);
0430 
0431 public:
0432   PrecompileJobAction(Action *Input, types::ID OutputType);
0433 
0434   static bool classof(const Action *A) {
0435     return A->getKind() == PrecompileJobClass;
0436   }
0437 };
0438 
0439 class ExtractAPIJobAction : public JobAction {
0440   void anchor() override;
0441 
0442 public:
0443   ExtractAPIJobAction(Action *Input, types::ID OutputType);
0444 
0445   static bool classof(const Action *A) {
0446     return A->getKind() == ExtractAPIJobClass;
0447   }
0448 
0449   void addHeaderInput(Action *Input) { getInputs().push_back(Input); }
0450 };
0451 
0452 class AnalyzeJobAction : public JobAction {
0453   void anchor() override;
0454 
0455 public:
0456   AnalyzeJobAction(Action *Input, types::ID OutputType);
0457 
0458   static bool classof(const Action *A) {
0459     return A->getKind() == AnalyzeJobClass;
0460   }
0461 };
0462 
0463 class MigrateJobAction : public JobAction {
0464   void anchor() override;
0465 
0466 public:
0467   MigrateJobAction(Action *Input, types::ID OutputType);
0468 
0469   static bool classof(const Action *A) {
0470     return A->getKind() == MigrateJobClass;
0471   }
0472 };
0473 
0474 class CompileJobAction : public JobAction {
0475   void anchor() override;
0476 
0477 public:
0478   CompileJobAction(Action *Input, types::ID OutputType);
0479 
0480   static bool classof(const Action *A) {
0481     return A->getKind() == CompileJobClass;
0482   }
0483 };
0484 
0485 class BackendJobAction : public JobAction {
0486   void anchor() override;
0487 
0488 public:
0489   BackendJobAction(Action *Input, types::ID OutputType);
0490 
0491   static bool classof(const Action *A) {
0492     return A->getKind() == BackendJobClass;
0493   }
0494 };
0495 
0496 class AssembleJobAction : public JobAction {
0497   void anchor() override;
0498 
0499 public:
0500   AssembleJobAction(Action *Input, types::ID OutputType);
0501 
0502   static bool classof(const Action *A) {
0503     return A->getKind() == AssembleJobClass;
0504   }
0505 };
0506 
0507 class IfsMergeJobAction : public JobAction {
0508   void anchor() override;
0509 
0510 public:
0511   IfsMergeJobAction(ActionList &Inputs, types::ID Type);
0512 
0513   static bool classof(const Action *A) {
0514     return A->getKind() == IfsMergeJobClass;
0515   }
0516 };
0517 
0518 class LinkJobAction : public JobAction {
0519   void anchor() override;
0520 
0521 public:
0522   LinkJobAction(ActionList &Inputs, types::ID Type);
0523 
0524   static bool classof(const Action *A) {
0525     return A->getKind() == LinkJobClass;
0526   }
0527 };
0528 
0529 class LipoJobAction : public JobAction {
0530   void anchor() override;
0531 
0532 public:
0533   LipoJobAction(ActionList &Inputs, types::ID Type);
0534 
0535   static bool classof(const Action *A) {
0536     return A->getKind() == LipoJobClass;
0537   }
0538 };
0539 
0540 class DsymutilJobAction : public JobAction {
0541   void anchor() override;
0542 
0543 public:
0544   DsymutilJobAction(ActionList &Inputs, types::ID Type);
0545 
0546   static bool classof(const Action *A) {
0547     return A->getKind() == DsymutilJobClass;
0548   }
0549 };
0550 
0551 class VerifyJobAction : public JobAction {
0552   void anchor() override;
0553 
0554 public:
0555   VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type);
0556 
0557   static bool classof(const Action *A) {
0558     return A->getKind() == VerifyDebugInfoJobClass ||
0559            A->getKind() == VerifyPCHJobClass;
0560   }
0561 };
0562 
0563 class VerifyDebugInfoJobAction : public VerifyJobAction {
0564   void anchor() override;
0565 
0566 public:
0567   VerifyDebugInfoJobAction(Action *Input, types::ID Type);
0568 
0569   static bool classof(const Action *A) {
0570     return A->getKind() == VerifyDebugInfoJobClass;
0571   }
0572 };
0573 
0574 class VerifyPCHJobAction : public VerifyJobAction {
0575   void anchor() override;
0576 
0577 public:
0578   VerifyPCHJobAction(Action *Input, types::ID Type);
0579 
0580   static bool classof(const Action *A) {
0581     return A->getKind() == VerifyPCHJobClass;
0582   }
0583 };
0584 
0585 class OffloadBundlingJobAction : public JobAction {
0586   void anchor() override;
0587 
0588 public:
0589   // Offloading bundling doesn't change the type of output.
0590   OffloadBundlingJobAction(ActionList &Inputs);
0591 
0592   static bool classof(const Action *A) {
0593     return A->getKind() == OffloadBundlingJobClass;
0594   }
0595 };
0596 
0597 class OffloadUnbundlingJobAction final : public JobAction {
0598   void anchor() override;
0599 
0600 public:
0601   /// Type that provides information about the actions that depend on this
0602   /// unbundling action.
0603   struct DependentActionInfo final {
0604     /// The tool chain of the dependent action.
0605     const ToolChain *DependentToolChain = nullptr;
0606 
0607     /// The bound architecture of the dependent action.
0608     StringRef DependentBoundArch;
0609 
0610     /// The offload kind of the dependent action.
0611     const OffloadKind DependentOffloadKind = OFK_None;
0612 
0613     DependentActionInfo(const ToolChain *DependentToolChain,
0614                         StringRef DependentBoundArch,
0615                         const OffloadKind DependentOffloadKind)
0616         : DependentToolChain(DependentToolChain),
0617           DependentBoundArch(DependentBoundArch),
0618           DependentOffloadKind(DependentOffloadKind) {}
0619   };
0620 
0621 private:
0622   /// Container that keeps information about each dependence of this unbundling
0623   /// action.
0624   SmallVector<DependentActionInfo, 6> DependentActionInfoArray;
0625 
0626 public:
0627   // Offloading unbundling doesn't change the type of output.
0628   OffloadUnbundlingJobAction(Action *Input);
0629 
0630   /// Register information about a dependent action.
0631   void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch,
0632                                    OffloadKind Kind) {
0633     DependentActionInfoArray.push_back({TC, BoundArch, Kind});
0634   }
0635 
0636   /// Return the information about all depending actions.
0637   ArrayRef<DependentActionInfo> getDependentActionsInfo() const {
0638     return DependentActionInfoArray;
0639   }
0640 
0641   static bool classof(const Action *A) {
0642     return A->getKind() == OffloadUnbundlingJobClass;
0643   }
0644 };
0645 
0646 class OffloadPackagerJobAction : public JobAction {
0647   void anchor() override;
0648 
0649 public:
0650   OffloadPackagerJobAction(ActionList &Inputs, types::ID Type);
0651 
0652   static bool classof(const Action *A) {
0653     return A->getKind() == OffloadPackagerJobClass;
0654   }
0655 };
0656 
0657 class LinkerWrapperJobAction : public JobAction {
0658   void anchor() override;
0659 
0660 public:
0661   LinkerWrapperJobAction(ActionList &Inputs, types::ID Type);
0662 
0663   static bool classof(const Action *A) {
0664     return A->getKind() == LinkerWrapperJobClass;
0665   }
0666 };
0667 
0668 class StaticLibJobAction : public JobAction {
0669   void anchor() override;
0670 
0671 public:
0672   StaticLibJobAction(ActionList &Inputs, types::ID Type);
0673 
0674   static bool classof(const Action *A) {
0675     return A->getKind() == StaticLibJobClass;
0676   }
0677 };
0678 
0679 class BinaryAnalyzeJobAction : public JobAction {
0680   void anchor() override;
0681 
0682 public:
0683   BinaryAnalyzeJobAction(Action *Input, types::ID Type);
0684 
0685   static bool classof(const Action *A) {
0686     return A->getKind() == BinaryAnalyzeJobClass;
0687   }
0688 };
0689 
0690 } // namespace driver
0691 } // namespace clang
0692 
0693 #endif // LLVM_CLANG_DRIVER_ACTION_H