File indexing completed on 2026-05-10 08:36:52
0001
0002
0003
0004
0005
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 }
0028 }
0029
0030 namespace clang {
0031 namespace driver {
0032
0033 class ToolChain;
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
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
0085
0086
0087 enum OffloadKind {
0088 OFK_None = 0x00,
0089
0090
0091 OFK_Host = 0x01,
0092
0093
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
0106 types::ID Type;
0107
0108 ActionList Inputs;
0109
0110
0111
0112
0113
0114 bool CanBeCollapsedWithNextDependentAction = true;
0115
0116 protected:
0117
0118
0119
0120
0121
0122
0123
0124 unsigned ActiveOffloadKindMask = 0u;
0125
0126
0127 OffloadKind OffloadingDeviceKind = OFK_None;
0128
0129
0130 const char *OffloadingArch = nullptr;
0131
0132
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
0166 void setCannotBeCollapsedWithNextDependentAction() {
0167 CanBeCollapsedWithNextDependentAction = false;
0168 }
0169
0170
0171 bool isCollapsingWithNextDependentActionLegal() const {
0172 return CanBeCollapsedWithNextDependentAction;
0173 }
0174
0175
0176 std::string getOffloadingKindPrefix() const;
0177
0178
0179
0180
0181 static std::string
0182 GetOffloadingFileNamePrefix(OffloadKind Kind,
0183 StringRef NormalizedTriple,
0184 bool CreatePrefixForHost = false);
0185
0186
0187 static StringRef GetOffloadKindName(OffloadKind Kind);
0188
0189
0190
0191 void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch,
0192 const ToolChain *OToolChain);
0193
0194
0195
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
0204
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
0218
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
0253
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
0267
0268
0269 class OffloadAction final : public Action {
0270 virtual void anchor();
0271
0272 public:
0273
0274
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
0283
0284
0285
0286
0287
0288 ActionList DeviceActions;
0289
0290
0291 ToolChainList DeviceToolChains;
0292
0293
0294 BoundArchList DeviceBoundArchs;
0295
0296
0297 OffloadKindList DeviceOffloadKinds;
0298
0299 public:
0300
0301
0302 void add(Action &A, const ToolChain &TC, const char *BoundArch,
0303 OffloadKind OKind);
0304
0305
0306
0307 void add(Action &A, const ToolChain &TC, const char *BoundArch,
0308 unsigned OffloadKindMask);
0309
0310
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
0320
0321 class HostDependence final {
0322
0323 Action &HostAction;
0324
0325
0326 const ToolChain &HostToolChain;
0327
0328
0329 const char *HostBoundArch = nullptr;
0330
0331
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
0341
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
0355 const ToolChain *HostTC = nullptr;
0356
0357
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
0366 void doOnHostDependence(const OffloadActionWorkTy &Work) const;
0367
0368
0369 void doOnEachDeviceDependence(const OffloadActionWorkTy &Work) const;
0370
0371
0372 void doOnEachDependence(const OffloadActionWorkTy &Work) const;
0373
0374
0375
0376 void doOnEachDependence(bool IsHostDependence,
0377 const OffloadActionWorkTy &Work) const;
0378
0379
0380 bool hasHostDependence() const;
0381
0382
0383
0384 Action *getHostDependence() const;
0385
0386
0387
0388
0389 bool hasSingleDeviceDependence(bool DoNotConsiderHostActions = false) const;
0390
0391
0392
0393
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
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
0602
0603 struct DependentActionInfo final {
0604
0605 const ToolChain *DependentToolChain = nullptr;
0606
0607
0608 StringRef DependentBoundArch;
0609
0610
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
0623
0624 SmallVector<DependentActionInfo, 6> DependentActionInfoArray;
0625
0626 public:
0627
0628 OffloadUnbundlingJobAction(Action *Input);
0629
0630
0631 void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch,
0632 OffloadKind Kind) {
0633 DependentActionInfoArray.push_back({TC, BoundArch, Kind});
0634 }
0635
0636
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 }
0691 }
0692
0693 #endif