File indexing completed on 2026-05-10 08:37:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_SEMA_SEMAOPENACC_H
0015 #define LLVM_CLANG_SEMA_SEMAOPENACC_H
0016
0017 #include "clang/AST/DeclGroup.h"
0018 #include "clang/AST/StmtOpenACC.h"
0019 #include "clang/Basic/LLVM.h"
0020 #include "clang/Basic/OpenACCKinds.h"
0021 #include "clang/Basic/SourceLocation.h"
0022 #include "clang/Sema/Ownership.h"
0023 #include "clang/Sema/SemaBase.h"
0024 #include "llvm/ADT/SmallVector.h"
0025 #include "llvm/Support/Compiler.h"
0026 #include <cassert>
0027 #include <optional>
0028 #include <utility>
0029 #include <variant>
0030
0031 namespace clang {
0032 class IdentifierInfo;
0033 class OpenACCClause;
0034
0035 class SemaOpenACC : public SemaBase {
0036 private:
0037 struct ComputeConstructInfo {
0038
0039
0040
0041 OpenACCDirectiveKind Kind = OpenACCDirectiveKind::Invalid;
0042
0043
0044 ArrayRef<OpenACCClause *> Clauses;
0045 } ActiveComputeConstructInfo;
0046
0047 bool isInComputeConstruct() const {
0048 return ActiveComputeConstructInfo.Kind != OpenACCDirectiveKind::Invalid;
0049 }
0050
0051
0052
0053
0054
0055 struct LoopCheckingInfo {
0056
0057
0058
0059 LLVM_PREFERRED_TYPE(bool)
0060 unsigned TopLevelLoopSeen : 1;
0061
0062
0063
0064 LLVM_PREFERRED_TYPE(bool)
0065 unsigned CurLevelHasLoopAlready : 1;
0066
0067 } LoopInfo{false, false};
0068
0069
0070
0071
0072
0073
0074
0075
0076 struct CollapseCheckingInfo {
0077 OpenACCCollapseClause *ActiveCollapse = nullptr;
0078
0079
0080
0081
0082
0083
0084 std::optional<llvm::APSInt> CurCollapseCount;
0085
0086
0087
0088
0089 bool CollapseDepthSatisfied = true;
0090
0091
0092
0093 OpenACCDirectiveKind DirectiveKind = OpenACCDirectiveKind::Invalid;
0094 } CollapseInfo;
0095
0096
0097
0098 struct TileCheckingInfo {
0099 OpenACCTileClause *ActiveTile = nullptr;
0100
0101
0102
0103
0104 std::optional<unsigned> CurTileCount;
0105
0106
0107
0108
0109 bool TileDepthSatisfied = true;
0110
0111
0112
0113 OpenACCDirectiveKind DirectiveKind = OpenACCDirectiveKind::Invalid;
0114 } TileInfo;
0115
0116
0117
0118
0119
0120
0121
0122 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
0123
0124
0125 struct ForStmtBeginChecker {
0126 SemaOpenACC &SemaRef;
0127 SourceLocation ForLoc;
0128 bool IsRangeFor = false;
0129 std::optional<const CXXForRangeStmt *> RangeFor = nullptr;
0130 const Stmt *Init = nullptr;
0131 bool InitChanged = false;
0132 std::optional<const Stmt *> Cond = nullptr;
0133 std::optional<const Stmt *> Inc = nullptr;
0134
0135 bool AlreadyChecked = false;
0136
0137 ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
0138 std::optional<const CXXForRangeStmt *> S)
0139 : SemaRef(SemaRef), ForLoc(ForLoc), IsRangeFor(true), RangeFor(S) {}
0140
0141 ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
0142 const Stmt *I, bool InitChanged,
0143 std::optional<const Stmt *> C,
0144 std::optional<const Stmt *> Inc)
0145 : SemaRef(SemaRef), ForLoc(ForLoc), IsRangeFor(false), Init(I),
0146 InitChanged(InitChanged), Cond(C), Inc(Inc) {}
0147
0148
0149
0150
0151 void check();
0152
0153 const ValueDecl *checkInit();
0154 void checkCond();
0155 void checkInc(const ValueDecl *Init);
0156 };
0157
0158
0159 void ForStmtBeginHelper(SourceLocation ForLoc, ForStmtBeginChecker &C);
0160
0161 public:
0162 ComputeConstructInfo &getActiveComputeConstructInfo() {
0163 return ActiveComputeConstructInfo;
0164 }
0165
0166
0167
0168
0169
0170 struct LoopGangOnKernelTy {
0171 SourceLocation Loc;
0172 OpenACCDirectiveKind DirKind = OpenACCDirectiveKind::Invalid;
0173 } LoopGangClauseOnKernel;
0174
0175
0176
0177
0178
0179 SourceLocation LoopWorkerClauseLoc;
0180
0181
0182
0183
0184 SourceLocation LoopVectorClauseLoc;
0185
0186
0187
0188
0189
0190 struct LoopWithoutSeqCheckingInfo {
0191 OpenACCDirectiveKind Kind = OpenACCDirectiveKind::Invalid;
0192 SourceLocation Loc;
0193 } LoopWithoutSeqInfo;
0194
0195
0196 using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
0197
0198
0199
0200
0201
0202 class OpenACCParsedClause {
0203 OpenACCDirectiveKind DirKind;
0204 OpenACCClauseKind ClauseKind;
0205 SourceRange ClauseRange;
0206 SourceLocation LParenLoc;
0207
0208 struct DefaultDetails {
0209 OpenACCDefaultClauseKind DefaultClauseKind;
0210 };
0211
0212 struct ConditionDetails {
0213 Expr *ConditionExpr;
0214 };
0215
0216 struct IntExprDetails {
0217 SmallVector<Expr *> IntExprs;
0218 };
0219
0220 struct VarListDetails {
0221 SmallVector<Expr *> VarList;
0222 bool IsReadOnly;
0223 bool IsZero;
0224 };
0225
0226 struct WaitDetails {
0227 Expr *DevNumExpr;
0228 SourceLocation QueuesLoc;
0229 SmallVector<Expr *> QueueIdExprs;
0230 };
0231
0232 struct DeviceTypeDetails {
0233 SmallVector<DeviceTypeArgument> Archs;
0234 };
0235 struct ReductionDetails {
0236 OpenACCReductionOperator Op;
0237 SmallVector<Expr *> VarList;
0238 };
0239
0240 struct CollapseDetails {
0241 bool IsForce;
0242 Expr *LoopCount;
0243 };
0244
0245 struct GangDetails {
0246 SmallVector<OpenACCGangKind> GangKinds;
0247 SmallVector<Expr *> IntExprs;
0248 };
0249
0250 std::variant<std::monostate, DefaultDetails, ConditionDetails,
0251 IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails,
0252 ReductionDetails, CollapseDetails, GangDetails>
0253 Details = std::monostate{};
0254
0255 public:
0256 OpenACCParsedClause(OpenACCDirectiveKind DirKind,
0257 OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
0258 : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}
0259
0260 OpenACCDirectiveKind getDirectiveKind() const { return DirKind; }
0261
0262 OpenACCClauseKind getClauseKind() const { return ClauseKind; }
0263
0264 SourceLocation getBeginLoc() const { return ClauseRange.getBegin(); }
0265
0266 SourceLocation getLParenLoc() const { return LParenLoc; }
0267
0268 SourceLocation getEndLoc() const { return ClauseRange.getEnd(); }
0269
0270 OpenACCDefaultClauseKind getDefaultClauseKind() const {
0271 assert(ClauseKind == OpenACCClauseKind::Default &&
0272 "Parsed clause is not a default clause");
0273 return std::get<DefaultDetails>(Details).DefaultClauseKind;
0274 }
0275
0276 const Expr *getConditionExpr() const {
0277 return const_cast<OpenACCParsedClause *>(this)->getConditionExpr();
0278 }
0279
0280 Expr *getConditionExpr() {
0281 assert((ClauseKind == OpenACCClauseKind::If ||
0282 (ClauseKind == OpenACCClauseKind::Self &&
0283 DirKind != OpenACCDirectiveKind::Update)) &&
0284 "Parsed clause kind does not have a condition expr");
0285
0286
0287
0288 if (ClauseKind == OpenACCClauseKind::Self &&
0289 std::holds_alternative<std::monostate>(Details))
0290 return nullptr;
0291
0292 return std::get<ConditionDetails>(Details).ConditionExpr;
0293 }
0294
0295 unsigned getNumIntExprs() const {
0296 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
0297 ClauseKind == OpenACCClauseKind::NumWorkers ||
0298 ClauseKind == OpenACCClauseKind::Async ||
0299 ClauseKind == OpenACCClauseKind::DeviceNum ||
0300 ClauseKind == OpenACCClauseKind::DefaultAsync ||
0301 ClauseKind == OpenACCClauseKind::Tile ||
0302 ClauseKind == OpenACCClauseKind::Worker ||
0303 ClauseKind == OpenACCClauseKind::Vector ||
0304 ClauseKind == OpenACCClauseKind::VectorLength) &&
0305 "Parsed clause kind does not have a int exprs");
0306
0307
0308
0309 if ((ClauseKind == OpenACCClauseKind::Async ||
0310 ClauseKind == OpenACCClauseKind::Worker ||
0311 ClauseKind == OpenACCClauseKind::Vector ||
0312 ClauseKind == OpenACCClauseKind::Wait) &&
0313 std::holds_alternative<std::monostate>(Details))
0314 return 0;
0315 return std::get<IntExprDetails>(Details).IntExprs.size();
0316 }
0317
0318 SourceLocation getQueuesLoc() const {
0319 assert(ClauseKind == OpenACCClauseKind::Wait &&
0320 "Parsed clause kind does not have a queues location");
0321
0322 if (std::holds_alternative<std::monostate>(Details))
0323 return SourceLocation{};
0324
0325 return std::get<WaitDetails>(Details).QueuesLoc;
0326 }
0327
0328 Expr *getDevNumExpr() const {
0329 assert(ClauseKind == OpenACCClauseKind::Wait &&
0330 "Parsed clause kind does not have a device number expr");
0331
0332 if (std::holds_alternative<std::monostate>(Details))
0333 return nullptr;
0334
0335 return std::get<WaitDetails>(Details).DevNumExpr;
0336 }
0337
0338 ArrayRef<Expr *> getQueueIdExprs() const {
0339 assert(ClauseKind == OpenACCClauseKind::Wait &&
0340 "Parsed clause kind does not have a queue id expr list");
0341
0342 if (std::holds_alternative<std::monostate>(Details))
0343 return ArrayRef<Expr *>();
0344
0345 return std::get<WaitDetails>(Details).QueueIdExprs;
0346 }
0347
0348 ArrayRef<Expr *> getIntExprs() {
0349 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
0350 ClauseKind == OpenACCClauseKind::NumWorkers ||
0351 ClauseKind == OpenACCClauseKind::Async ||
0352 ClauseKind == OpenACCClauseKind::DeviceNum ||
0353 ClauseKind == OpenACCClauseKind::DefaultAsync ||
0354 ClauseKind == OpenACCClauseKind::Tile ||
0355 ClauseKind == OpenACCClauseKind::Gang ||
0356 ClauseKind == OpenACCClauseKind::Worker ||
0357 ClauseKind == OpenACCClauseKind::Vector ||
0358 ClauseKind == OpenACCClauseKind::VectorLength) &&
0359 "Parsed clause kind does not have a int exprs");
0360
0361 if (ClauseKind == OpenACCClauseKind::Gang) {
0362
0363
0364 if (std::holds_alternative<std::monostate>(Details))
0365 return {};
0366 return std::get<GangDetails>(Details).IntExprs;
0367 }
0368
0369 return std::get<IntExprDetails>(Details).IntExprs;
0370 }
0371
0372 ArrayRef<Expr *> getIntExprs() const {
0373 return const_cast<OpenACCParsedClause *>(this)->getIntExprs();
0374 }
0375
0376 OpenACCReductionOperator getReductionOp() const {
0377 return std::get<ReductionDetails>(Details).Op;
0378 }
0379
0380 ArrayRef<OpenACCGangKind> getGangKinds() const {
0381 assert(ClauseKind == OpenACCClauseKind::Gang &&
0382 "Parsed clause kind does not have gang kind");
0383
0384
0385 if (std::holds_alternative<std::monostate>(Details))
0386 return {};
0387 return std::get<GangDetails>(Details).GangKinds;
0388 }
0389
0390 ArrayRef<Expr *> getVarList() {
0391 assert((ClauseKind == OpenACCClauseKind::Private ||
0392 ClauseKind == OpenACCClauseKind::NoCreate ||
0393 ClauseKind == OpenACCClauseKind::Present ||
0394 ClauseKind == OpenACCClauseKind::Copy ||
0395 ClauseKind == OpenACCClauseKind::PCopy ||
0396 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
0397 ClauseKind == OpenACCClauseKind::CopyIn ||
0398 ClauseKind == OpenACCClauseKind::PCopyIn ||
0399 ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
0400 ClauseKind == OpenACCClauseKind::CopyOut ||
0401 ClauseKind == OpenACCClauseKind::PCopyOut ||
0402 ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
0403 ClauseKind == OpenACCClauseKind::Create ||
0404 ClauseKind == OpenACCClauseKind::PCreate ||
0405 ClauseKind == OpenACCClauseKind::PresentOrCreate ||
0406 ClauseKind == OpenACCClauseKind::Attach ||
0407 ClauseKind == OpenACCClauseKind::Delete ||
0408 ClauseKind == OpenACCClauseKind::UseDevice ||
0409 ClauseKind == OpenACCClauseKind::Detach ||
0410 ClauseKind == OpenACCClauseKind::DevicePtr ||
0411 ClauseKind == OpenACCClauseKind::Reduction ||
0412 ClauseKind == OpenACCClauseKind::Host ||
0413 ClauseKind == OpenACCClauseKind::Device ||
0414 (ClauseKind == OpenACCClauseKind::Self &&
0415 DirKind == OpenACCDirectiveKind::Update) ||
0416 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
0417 "Parsed clause kind does not have a var-list");
0418
0419 if (ClauseKind == OpenACCClauseKind::Reduction)
0420 return std::get<ReductionDetails>(Details).VarList;
0421
0422 return std::get<VarListDetails>(Details).VarList;
0423 }
0424
0425 ArrayRef<Expr *> getVarList() const {
0426 return const_cast<OpenACCParsedClause *>(this)->getVarList();
0427 }
0428
0429 bool isReadOnly() const {
0430 assert((ClauseKind == OpenACCClauseKind::CopyIn ||
0431 ClauseKind == OpenACCClauseKind::PCopyIn ||
0432 ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
0433 "Only copyin accepts 'readonly:' tag");
0434 return std::get<VarListDetails>(Details).IsReadOnly;
0435 }
0436
0437 bool isZero() const {
0438 assert((ClauseKind == OpenACCClauseKind::CopyOut ||
0439 ClauseKind == OpenACCClauseKind::PCopyOut ||
0440 ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
0441 ClauseKind == OpenACCClauseKind::Create ||
0442 ClauseKind == OpenACCClauseKind::PCreate ||
0443 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
0444 "Only copyout/create accepts 'zero' tag");
0445 return std::get<VarListDetails>(Details).IsZero;
0446 }
0447
0448 bool isForce() const {
0449 assert(ClauseKind == OpenACCClauseKind::Collapse &&
0450 "Only 'collapse' has a force tag");
0451 return std::get<CollapseDetails>(Details).IsForce;
0452 }
0453
0454 Expr *getLoopCount() const {
0455 assert(ClauseKind == OpenACCClauseKind::Collapse &&
0456 "Only 'collapse' has a loop count");
0457 return std::get<CollapseDetails>(Details).LoopCount;
0458 }
0459
0460 ArrayRef<DeviceTypeArgument> getDeviceTypeArchitectures() const {
0461 assert((ClauseKind == OpenACCClauseKind::DeviceType ||
0462 ClauseKind == OpenACCClauseKind::DType) &&
0463 "Only 'device_type'/'dtype' has a device-type-arg list");
0464 return std::get<DeviceTypeDetails>(Details).Archs;
0465 }
0466
0467 void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
0468 void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }
0469
0470 void setDefaultDetails(OpenACCDefaultClauseKind DefKind) {
0471 assert(ClauseKind == OpenACCClauseKind::Default &&
0472 "Parsed clause is not a default clause");
0473 Details = DefaultDetails{DefKind};
0474 }
0475
0476 void setConditionDetails(Expr *ConditionExpr) {
0477 assert((ClauseKind == OpenACCClauseKind::If ||
0478 (ClauseKind == OpenACCClauseKind::Self &&
0479 DirKind != OpenACCDirectiveKind::Update)) &&
0480 "Parsed clause kind does not have a condition expr");
0481
0482
0483 assert((!ConditionExpr || ConditionExpr->isInstantiationDependent() ||
0484 ConditionExpr->getType()->isScalarType()) &&
0485 "Condition expression type not scalar/dependent");
0486
0487 Details = ConditionDetails{ConditionExpr};
0488 }
0489
0490 void setIntExprDetails(ArrayRef<Expr *> IntExprs) {
0491 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
0492 ClauseKind == OpenACCClauseKind::NumWorkers ||
0493 ClauseKind == OpenACCClauseKind::Async ||
0494 ClauseKind == OpenACCClauseKind::DeviceNum ||
0495 ClauseKind == OpenACCClauseKind::DefaultAsync ||
0496 ClauseKind == OpenACCClauseKind::Tile ||
0497 ClauseKind == OpenACCClauseKind::Worker ||
0498 ClauseKind == OpenACCClauseKind::Vector ||
0499 ClauseKind == OpenACCClauseKind::VectorLength) &&
0500 "Parsed clause kind does not have a int exprs");
0501 Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
0502 }
0503 void setIntExprDetails(llvm::SmallVector<Expr *> &&IntExprs) {
0504 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
0505 ClauseKind == OpenACCClauseKind::NumWorkers ||
0506 ClauseKind == OpenACCClauseKind::Async ||
0507 ClauseKind == OpenACCClauseKind::DeviceNum ||
0508 ClauseKind == OpenACCClauseKind::DefaultAsync ||
0509 ClauseKind == OpenACCClauseKind::Tile ||
0510 ClauseKind == OpenACCClauseKind::Worker ||
0511 ClauseKind == OpenACCClauseKind::Vector ||
0512 ClauseKind == OpenACCClauseKind::VectorLength) &&
0513 "Parsed clause kind does not have a int exprs");
0514 Details = IntExprDetails{std::move(IntExprs)};
0515 }
0516
0517 void setGangDetails(ArrayRef<OpenACCGangKind> GKs,
0518 ArrayRef<Expr *> IntExprs) {
0519 assert(ClauseKind == OpenACCClauseKind::Gang &&
0520 "Parsed Clause kind does not have gang details");
0521 assert(GKs.size() == IntExprs.size() && "Mismatched kind/size?");
0522
0523 Details = GangDetails{{GKs.begin(), GKs.end()},
0524 {IntExprs.begin(), IntExprs.end()}};
0525 }
0526
0527 void setGangDetails(llvm::SmallVector<OpenACCGangKind> &&GKs,
0528 llvm::SmallVector<Expr *> &&IntExprs) {
0529 assert(ClauseKind == OpenACCClauseKind::Gang &&
0530 "Parsed Clause kind does not have gang details");
0531 assert(GKs.size() == IntExprs.size() && "Mismatched kind/size?");
0532
0533 Details = GangDetails{std::move(GKs), std::move(IntExprs)};
0534 }
0535
0536 void setVarListDetails(ArrayRef<Expr *> VarList, bool IsReadOnly,
0537 bool IsZero) {
0538 assert((ClauseKind == OpenACCClauseKind::Private ||
0539 ClauseKind == OpenACCClauseKind::NoCreate ||
0540 ClauseKind == OpenACCClauseKind::Present ||
0541 ClauseKind == OpenACCClauseKind::Copy ||
0542 ClauseKind == OpenACCClauseKind::PCopy ||
0543 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
0544 ClauseKind == OpenACCClauseKind::CopyIn ||
0545 ClauseKind == OpenACCClauseKind::PCopyIn ||
0546 ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
0547 ClauseKind == OpenACCClauseKind::CopyOut ||
0548 ClauseKind == OpenACCClauseKind::PCopyOut ||
0549 ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
0550 ClauseKind == OpenACCClauseKind::Create ||
0551 ClauseKind == OpenACCClauseKind::PCreate ||
0552 ClauseKind == OpenACCClauseKind::PresentOrCreate ||
0553 ClauseKind == OpenACCClauseKind::Attach ||
0554 ClauseKind == OpenACCClauseKind::Delete ||
0555 ClauseKind == OpenACCClauseKind::UseDevice ||
0556 ClauseKind == OpenACCClauseKind::Detach ||
0557 ClauseKind == OpenACCClauseKind::DevicePtr ||
0558 ClauseKind == OpenACCClauseKind::Host ||
0559 ClauseKind == OpenACCClauseKind::Device ||
0560 (ClauseKind == OpenACCClauseKind::Self &&
0561 DirKind == OpenACCDirectiveKind::Update) ||
0562 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
0563 "Parsed clause kind does not have a var-list");
0564 assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
0565 ClauseKind == OpenACCClauseKind::PCopyIn ||
0566 ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
0567 "readonly: tag only valid on copyin");
0568 assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
0569 ClauseKind == OpenACCClauseKind::PCopyOut ||
0570 ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
0571 ClauseKind == OpenACCClauseKind::Create ||
0572 ClauseKind == OpenACCClauseKind::PCreate ||
0573 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
0574 "zero: tag only valid on copyout/create");
0575 Details =
0576 VarListDetails{{VarList.begin(), VarList.end()}, IsReadOnly, IsZero};
0577 }
0578
0579 void setVarListDetails(llvm::SmallVector<Expr *> &&VarList, bool IsReadOnly,
0580 bool IsZero) {
0581 assert((ClauseKind == OpenACCClauseKind::Private ||
0582 ClauseKind == OpenACCClauseKind::NoCreate ||
0583 ClauseKind == OpenACCClauseKind::Present ||
0584 ClauseKind == OpenACCClauseKind::Copy ||
0585 ClauseKind == OpenACCClauseKind::PCopy ||
0586 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
0587 ClauseKind == OpenACCClauseKind::CopyIn ||
0588 ClauseKind == OpenACCClauseKind::PCopyIn ||
0589 ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
0590 ClauseKind == OpenACCClauseKind::CopyOut ||
0591 ClauseKind == OpenACCClauseKind::PCopyOut ||
0592 ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
0593 ClauseKind == OpenACCClauseKind::Create ||
0594 ClauseKind == OpenACCClauseKind::PCreate ||
0595 ClauseKind == OpenACCClauseKind::PresentOrCreate ||
0596 ClauseKind == OpenACCClauseKind::Attach ||
0597 ClauseKind == OpenACCClauseKind::Delete ||
0598 ClauseKind == OpenACCClauseKind::UseDevice ||
0599 ClauseKind == OpenACCClauseKind::Detach ||
0600 ClauseKind == OpenACCClauseKind::DevicePtr ||
0601 ClauseKind == OpenACCClauseKind::Host ||
0602 ClauseKind == OpenACCClauseKind::Device ||
0603 (ClauseKind == OpenACCClauseKind::Self &&
0604 DirKind == OpenACCDirectiveKind::Update) ||
0605 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
0606 "Parsed clause kind does not have a var-list");
0607 assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
0608 ClauseKind == OpenACCClauseKind::PCopyIn ||
0609 ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
0610 "readonly: tag only valid on copyin");
0611 assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
0612 ClauseKind == OpenACCClauseKind::PCopyOut ||
0613 ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
0614 ClauseKind == OpenACCClauseKind::Create ||
0615 ClauseKind == OpenACCClauseKind::PCreate ||
0616 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
0617 "zero: tag only valid on copyout/create");
0618 Details = VarListDetails{std::move(VarList), IsReadOnly, IsZero};
0619 }
0620
0621 void setReductionDetails(OpenACCReductionOperator Op,
0622 llvm::SmallVector<Expr *> &&VarList) {
0623 assert(ClauseKind == OpenACCClauseKind::Reduction &&
0624 "reduction details only valid on reduction");
0625 Details = ReductionDetails{Op, std::move(VarList)};
0626 }
0627
0628 void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc,
0629 llvm::SmallVector<Expr *> &&IntExprs) {
0630 assert(ClauseKind == OpenACCClauseKind::Wait &&
0631 "Parsed clause kind does not have a wait-details");
0632 Details = WaitDetails{DevNum, QueuesLoc, std::move(IntExprs)};
0633 }
0634
0635 void setDeviceTypeDetails(llvm::SmallVector<DeviceTypeArgument> &&Archs) {
0636 assert((ClauseKind == OpenACCClauseKind::DeviceType ||
0637 ClauseKind == OpenACCClauseKind::DType) &&
0638 "Only 'device_type'/'dtype' has a device-type-arg list");
0639 Details = DeviceTypeDetails{std::move(Archs)};
0640 }
0641
0642 void setCollapseDetails(bool IsForce, Expr *LoopCount) {
0643 assert(ClauseKind == OpenACCClauseKind::Collapse &&
0644 "Only 'collapse' has collapse details");
0645 Details = CollapseDetails{IsForce, LoopCount};
0646 }
0647 };
0648
0649 SemaOpenACC(Sema &S);
0650
0651
0652 void ActOnWhileStmt(SourceLocation WhileLoc);
0653
0654 void ActOnDoStmt(SourceLocation DoLoc);
0655
0656
0657 void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor,
0658 const Stmt *RangeFor);
0659 void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *RangeFor);
0660
0661
0662 void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First,
0663 const Stmt *Second, const Stmt *Third);
0664 void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *OldFirst,
0665 const Stmt *First, const Stmt *OldSecond,
0666 const Stmt *Second, const Stmt *OldThird,
0667 const Stmt *Third);
0668
0669
0670
0671 void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body);
0672
0673
0674 OpenACCClause *ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
0675 OpenACCParsedClause &Clause);
0676
0677
0678
0679
0680 void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc);
0681
0682
0683
0684
0685
0686 bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
0687 ArrayRef<const OpenACCClause *> Clauses);
0688
0689
0690
0691
0692
0693 bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc);
0694
0695
0696 StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc,
0697 OpenACCDirectiveKind K,
0698 ArrayRef<const OpenACCClause *> Clauses,
0699 StmtResult AssocStmt);
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710 StmtResult ActOnEndStmtDirective(
0711 OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc,
0712 SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs,
0713 SourceLocation RParenLoc, SourceLocation EndLoc,
0714 ArrayRef<OpenACCClause *> Clauses, StmtResult AssocStmt);
0715
0716
0717
0718 DeclGroupRef ActOnEndDeclDirective();
0719
0720
0721
0722 ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
0723 SourceLocation Loc, Expr *IntExpr);
0724
0725
0726
0727 ExprResult ActOnVar(OpenACCClauseKind CK, Expr *VarExpr);
0728
0729
0730
0731 ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind,
0732 OpenACCReductionOperator ReductionOp,
0733 Expr *VarExpr);
0734
0735
0736
0737 bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr);
0738
0739
0740 ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
0741 Expr *LowerBound,
0742 SourceLocation ColonLocFirst, Expr *Length,
0743 SourceLocation RBLoc);
0744
0745 ExprResult CheckCollapseLoopCount(Expr *LoopCount);
0746
0747 ExprResult CheckTileSizeExpr(Expr *SizeExpr);
0748
0749
0750 ExprResult CheckGangExpr(ArrayRef<const OpenACCClause *> ExistingClauses,
0751 OpenACCDirectiveKind DK, OpenACCGangKind GK,
0752 Expr *E);
0753
0754
0755
0756 OpenACCClause *
0757 CheckGangClause(OpenACCDirectiveKind DirKind,
0758 ArrayRef<const OpenACCClause *> ExistingClauses,
0759 SourceLocation BeginLoc, SourceLocation LParenLoc,
0760 ArrayRef<OpenACCGangKind> GangKinds,
0761 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
0762
0763
0764 OpenACCClause *
0765 CheckReductionClause(ArrayRef<const OpenACCClause *> ExistingClauses,
0766 OpenACCDirectiveKind DirectiveKind,
0767 SourceLocation BeginLoc, SourceLocation LParenLoc,
0768 OpenACCReductionOperator ReductionOp,
0769 ArrayRef<Expr *> Vars, SourceLocation EndLoc);
0770
0771 ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc);
0772 ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc);
0773
0774
0775
0776 class LoopInConstructRAII {
0777 SemaOpenACC &SemaRef;
0778 LoopCheckingInfo OldLoopInfo;
0779 CollapseCheckingInfo OldCollapseInfo;
0780 TileCheckingInfo OldTileInfo;
0781 bool PreserveDepth;
0782
0783 public:
0784 LoopInConstructRAII(SemaOpenACC &SemaRef, bool PreserveDepth = true)
0785 : SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo),
0786 OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo),
0787 PreserveDepth(PreserveDepth) {}
0788 ~LoopInConstructRAII() {
0789
0790
0791
0792 bool CollapseDepthSatisified =
0793 PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied
0794 : OldCollapseInfo.CollapseDepthSatisfied;
0795 bool TileDepthSatisfied = PreserveDepth
0796 ? SemaRef.TileInfo.TileDepthSatisfied
0797 : OldTileInfo.TileDepthSatisfied;
0798 bool CurLevelHasLoopAlready =
0799 PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready
0800 : OldLoopInfo.CurLevelHasLoopAlready;
0801
0802 SemaRef.LoopInfo = OldLoopInfo;
0803 SemaRef.CollapseInfo = OldCollapseInfo;
0804 SemaRef.TileInfo = OldTileInfo;
0805
0806 SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified;
0807 SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied;
0808 SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
0809 }
0810 };
0811
0812
0813
0814
0815 class AssociatedStmtRAII {
0816 SemaOpenACC &SemaRef;
0817 ComputeConstructInfo OldActiveComputeConstructInfo;
0818 OpenACCDirectiveKind DirKind;
0819 LoopGangOnKernelTy OldLoopGangClauseOnKernel;
0820 SourceLocation OldLoopWorkerClauseLoc;
0821 SourceLocation OldLoopVectorClauseLoc;
0822 LoopWithoutSeqCheckingInfo OldLoopWithoutSeqInfo;
0823 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
0824 LoopInConstructRAII LoopRAII;
0825
0826 public:
0827 AssociatedStmtRAII(SemaOpenACC &, OpenACCDirectiveKind, SourceLocation,
0828 ArrayRef<const OpenACCClause *>,
0829 ArrayRef<OpenACCClause *>);
0830 void SetCollapseInfoBeforeAssociatedStmt(
0831 ArrayRef<const OpenACCClause *> UnInstClauses,
0832 ArrayRef<OpenACCClause *> Clauses);
0833 void SetTileInfoBeforeAssociatedStmt(
0834 ArrayRef<const OpenACCClause *> UnInstClauses,
0835 ArrayRef<OpenACCClause *> Clauses);
0836 ~AssociatedStmtRAII();
0837 };
0838 };
0839
0840 }
0841
0842 #endif