19#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/StringSwitch.h"
29enum class OpenACCDirectiveKindEx {
30 Invalid =
static_cast<int>(OpenACCDirectiveKind::Invalid),
41OpenACCDirectiveKindEx getOpenACCDirectiveKind(
Token Tok) {
42 if (!Tok.
is(tok::identifier))
43 return OpenACCDirectiveKindEx::Invalid;
45 llvm::StringSwitch<OpenACCDirectiveKind>(
47 .Case(
"parallel", OpenACCDirectiveKind::Parallel)
48 .Case(
"serial", OpenACCDirectiveKind::Serial)
49 .Case(
"kernels", OpenACCDirectiveKind::Kernels)
50 .Case(
"data", OpenACCDirectiveKind::Data)
51 .Case(
"host_data", OpenACCDirectiveKind::HostData)
52 .Case(
"loop", OpenACCDirectiveKind::Loop)
53 .Case(
"cache", OpenACCDirectiveKind::Cache)
54 .Case(
"atomic", OpenACCDirectiveKind::Atomic)
55 .Case(
"routine", OpenACCDirectiveKind::Routine)
56 .Case(
"declare", OpenACCDirectiveKind::Declare)
57 .Case(
"init", OpenACCDirectiveKind::Init)
58 .Case(
"shutdown", OpenACCDirectiveKind::Shutdown)
59 .Case(
"set", OpenACCDirectiveKind::Set)
60 .Case(
"update", OpenACCDirectiveKind::Update)
61 .Case(
"wait", OpenACCDirectiveKind::Wait)
62 .Default(OpenACCDirectiveKind::Invalid);
64 if (DirKind != OpenACCDirectiveKind::Invalid)
65 return static_cast<OpenACCDirectiveKindEx
>(DirKind);
67 return llvm::StringSwitch<OpenACCDirectiveKindEx>(
69 .Case(
"enter", OpenACCDirectiveKindEx::Enter)
70 .Case(
"exit", OpenACCDirectiveKindEx::Exit)
71 .Default(OpenACCDirectiveKindEx::Invalid);
78 if (Tok.
is(tok::kw_auto))
79 return OpenACCClauseKind::Auto;
82 if (Tok.
is(tok::kw_default))
83 return OpenACCClauseKind::Default;
86 if (Tok.
is(tok::kw_if))
87 return OpenACCClauseKind::If;
90 if (Tok.
is(tok::kw_private))
91 return OpenACCClauseKind::Private;
93 if (!Tok.
is(tok::identifier))
94 return OpenACCClauseKind::Invalid;
96 return llvm::StringSwitch<OpenACCClauseKind>(
98 .Case(
"async", OpenACCClauseKind::Async)
99 .Case(
"attach", OpenACCClauseKind::Attach)
100 .Case(
"auto", OpenACCClauseKind::Auto)
101 .Case(
"bind", OpenACCClauseKind::Bind)
102 .Case(
"create", OpenACCClauseKind::Create)
103 .Case(
"pcreate", OpenACCClauseKind::PCreate)
104 .Case(
"present_or_create", OpenACCClauseKind::PresentOrCreate)
105 .Case(
"collapse", OpenACCClauseKind::Collapse)
106 .Case(
"copy", OpenACCClauseKind::Copy)
107 .Case(
"pcopy", OpenACCClauseKind::PCopy)
108 .Case(
"present_or_copy", OpenACCClauseKind::PresentOrCopy)
109 .Case(
"copyin", OpenACCClauseKind::CopyIn)
110 .Case(
"pcopyin", OpenACCClauseKind::PCopyIn)
111 .Case(
"present_or_copyin", OpenACCClauseKind::PresentOrCopyIn)
112 .Case(
"copyout", OpenACCClauseKind::CopyOut)
113 .Case(
"pcopyout", OpenACCClauseKind::PCopyOut)
114 .Case(
"present_or_copyout", OpenACCClauseKind::PresentOrCopyOut)
115 .Case(
"default", OpenACCClauseKind::Default)
116 .Case(
"default_async", OpenACCClauseKind::DefaultAsync)
117 .Case(
"delete", OpenACCClauseKind::Delete)
118 .Case(
"detach", OpenACCClauseKind::Detach)
119 .Case(
"device", OpenACCClauseKind::Device)
120 .Case(
"device_num", OpenACCClauseKind::DeviceNum)
121 .Case(
"device_resident", OpenACCClauseKind::DeviceResident)
122 .Case(
"device_type", OpenACCClauseKind::DeviceType)
123 .Case(
"deviceptr", OpenACCClauseKind::DevicePtr)
124 .Case(
"dtype", OpenACCClauseKind::DType)
125 .Case(
"finalize", OpenACCClauseKind::Finalize)
126 .Case(
"firstprivate", OpenACCClauseKind::FirstPrivate)
127 .Case(
"gang", OpenACCClauseKind::Gang)
128 .Case(
"host", OpenACCClauseKind::Host)
129 .Case(
"if", OpenACCClauseKind::If)
130 .Case(
"if_present", OpenACCClauseKind::IfPresent)
131 .Case(
"independent", OpenACCClauseKind::Independent)
132 .Case(
"link", OpenACCClauseKind::Link)
133 .Case(
"no_create", OpenACCClauseKind::NoCreate)
134 .Case(
"num_gangs", OpenACCClauseKind::NumGangs)
135 .Case(
"num_workers", OpenACCClauseKind::NumWorkers)
136 .Case(
"nohost", OpenACCClauseKind::NoHost)
137 .Case(
"present", OpenACCClauseKind::Present)
138 .Case(
"private", OpenACCClauseKind::Private)
139 .Case(
"reduction", OpenACCClauseKind::Reduction)
140 .Case(
"self", OpenACCClauseKind::Self)
141 .Case(
"seq", OpenACCClauseKind::Seq)
142 .Case(
"tile", OpenACCClauseKind::Tile)
143 .Case(
"use_device", OpenACCClauseKind::UseDevice)
144 .Case(
"vector", OpenACCClauseKind::Vector)
145 .Case(
"vector_length", OpenACCClauseKind::VectorLength)
146 .Case(
"wait", OpenACCClauseKind::Wait)
147 .Case(
"worker", OpenACCClauseKind::Worker)
148 .Default(OpenACCClauseKind::Invalid);
154 if (!Tok.
is(tok::identifier))
155 return OpenACCAtomicKind::Invalid;
156 return llvm::StringSwitch<OpenACCAtomicKind>(
158 .Case(
"read", OpenACCAtomicKind::Read)
159 .Case(
"write", OpenACCAtomicKind::Write)
160 .Case(
"update", OpenACCAtomicKind::Update)
161 .Case(
"capture", OpenACCAtomicKind::Capture)
162 .Default(OpenACCAtomicKind::Invalid);
166 if (!Tok.
is(tok::identifier))
167 return OpenACCDefaultClauseKind::Invalid;
169 return llvm::StringSwitch<OpenACCDefaultClauseKind>(
171 .Case(
"none", OpenACCDefaultClauseKind::None)
172 .Case(
"present", OpenACCDefaultClauseKind::Present)
173 .Default(OpenACCDefaultClauseKind::Invalid);
176enum class OpenACCSpecialTokenKind {
188bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind,
Token Tok) {
189 if (Tok.
is(tok::kw_static) && Kind == OpenACCSpecialTokenKind::Static)
192 if (!Tok.
is(tok::identifier))
196 case OpenACCSpecialTokenKind::ReadOnly:
198 case OpenACCSpecialTokenKind::DevNum:
200 case OpenACCSpecialTokenKind::Queues:
202 case OpenACCSpecialTokenKind::Zero:
204 case OpenACCSpecialTokenKind::Force:
206 case OpenACCSpecialTokenKind::Num:
208 case OpenACCSpecialTokenKind::Length:
210 case OpenACCSpecialTokenKind::Dim:
212 case OpenACCSpecialTokenKind::Static:
215 llvm_unreachable(
"Unknown 'Kind' Passed");
222 if (Tok.
is(tok::identifier))
237template <
typename DirOrClauseTy>
238bool tryParseAndConsumeSpecialTokenKind(
Parser &
P, OpenACCSpecialTokenKind Kind,
239 DirOrClauseTy DirOrClause) {
240 Token IdentTok =
P.getCurToken();
243 if (isTokenIdentifierOrKeyword(
P, IdentTok) &&
P.NextToken().is(tok::colon)) {
247 if (!isOpenACCSpecialToken(Kind, IdentTok)) {
248 P.Diag(IdentTok, diag::err_acc_invalid_tag_kind)
250 << std::is_same_v<DirOrClauseTy, OpenACCClauseKind>;
261 if (!Tok.
is(tok::identifier))
265 case OpenACCDirectiveKind::Parallel:
267 case OpenACCDirectiveKind::Serial:
269 case OpenACCDirectiveKind::Kernels:
271 case OpenACCDirectiveKind::Data:
273 case OpenACCDirectiveKind::HostData:
275 case OpenACCDirectiveKind::Loop:
277 case OpenACCDirectiveKind::Cache:
280 case OpenACCDirectiveKind::ParallelLoop:
281 case OpenACCDirectiveKind::SerialLoop:
282 case OpenACCDirectiveKind::KernelsLoop:
283 case OpenACCDirectiveKind::EnterData:
284 case OpenACCDirectiveKind::ExitData:
287 case OpenACCDirectiveKind::Atomic:
289 case OpenACCDirectiveKind::Routine:
291 case OpenACCDirectiveKind::Declare:
293 case OpenACCDirectiveKind::Init:
295 case OpenACCDirectiveKind::Shutdown:
297 case OpenACCDirectiveKind::Set:
299 case OpenACCDirectiveKind::Update:
301 case OpenACCDirectiveKind::Wait:
303 case OpenACCDirectiveKind::Invalid:
306 llvm_unreachable(
"Unknown 'Kind' Passed");
313 if (
P.NextToken().isNot(tok::colon)) {
314 P.Diag(
P.getCurToken(), diag::err_acc_expected_reduction_operator);
315 return OpenACCReductionOperator::Invalid;
317 Token ReductionKindTok =
P.getCurToken();
322 switch (ReductionKindTok.
getKind()) {
324 return OpenACCReductionOperator::Addition;
326 return OpenACCReductionOperator::Multiplication;
328 return OpenACCReductionOperator::BitwiseAnd;
330 return OpenACCReductionOperator::BitwiseOr;
332 return OpenACCReductionOperator::BitwiseXOr;
334 return OpenACCReductionOperator::And;
336 return OpenACCReductionOperator::Or;
337 case tok::identifier:
339 return OpenACCReductionOperator::Max;
341 return OpenACCReductionOperator::Min;
344 P.Diag(ReductionKindTok, diag::err_acc_invalid_reduction_operator);
345 return OpenACCReductionOperator::Invalid;
347 llvm_unreachable(
"Reduction op token kind not caught by 'default'?");
352bool expectIdentifierOrKeyword(
Parser &
P) {
353 Token Tok =
P.getCurToken();
355 if (isTokenIdentifierOrKeyword(
P, Tok))
358 P.Diag(
P.getCurToken(), diag::err_expected) << tok::identifier;
363ParseOpenACCEnterExitDataDirective(
Parser &
P,
Token FirstTok,
364 OpenACCDirectiveKindEx ExtDirKind) {
365 Token SecondTok =
P.getCurToken();
368 P.Diag(FirstTok, diag::err_acc_invalid_directive)
370 return OpenACCDirectiveKind::Invalid;
377 if (!isOpenACCDirectiveKind(OpenACCDirectiveKind::Data, SecondTok)) {
378 if (!SecondTok.
is(tok::identifier))
379 P.Diag(SecondTok, diag::err_expected) << tok::identifier;
381 P.Diag(FirstTok, diag::err_acc_invalid_directive)
384 return OpenACCDirectiveKind::Invalid;
387 return ExtDirKind == OpenACCDirectiveKindEx::Enter
388 ? OpenACCDirectiveKind::EnterData
389 : OpenACCDirectiveKind::ExitData;
393 Token AtomicClauseToken =
P.getCurToken();
397 return OpenACCAtomicKind::Update;
404 if (AtomicKind == OpenACCAtomicKind::Invalid)
405 return OpenACCAtomicKind::Update;
413 Token FirstTok =
P.getCurToken();
417 if (FirstTok.
isNot(tok::identifier)) {
418 P.Diag(FirstTok, diag::err_acc_missing_directive);
420 if (
P.getCurToken().isNot(tok::annot_pragma_openacc_end))
423 return OpenACCDirectiveKind::Invalid;
428 OpenACCDirectiveKindEx ExDirKind = getOpenACCDirectiveKind(FirstTok);
436 if (ExDirKind >= OpenACCDirectiveKindEx::Invalid) {
438 case OpenACCDirectiveKindEx::Invalid: {
439 P.Diag(FirstTok, diag::err_acc_invalid_directive)
441 return OpenACCDirectiveKind::Invalid;
443 case OpenACCDirectiveKindEx::Enter:
444 case OpenACCDirectiveKindEx::Exit:
445 return ParseOpenACCEnterExitDataDirective(
P, FirstTok, ExDirKind);
454 Token SecondTok =
P.getCurToken();
456 isOpenACCDirectiveKind(OpenACCDirectiveKind::Loop, SecondTok)) {
462 case OpenACCDirectiveKind::Parallel:
464 return OpenACCDirectiveKind::ParallelLoop;
465 case OpenACCDirectiveKind::Serial:
467 return OpenACCDirectiveKind::SerialLoop;
468 case OpenACCDirectiveKind::Kernels:
470 return OpenACCDirectiveKind::KernelsLoop;
477enum ClauseParensKind {
486 case OpenACCClauseKind::Self:
487 return DirKind == OpenACCDirectiveKind::Update ? ClauseParensKind::Required
488 : ClauseParensKind::Optional;
489 case OpenACCClauseKind::Async:
490 case OpenACCClauseKind::Worker:
491 case OpenACCClauseKind::Vector:
492 case OpenACCClauseKind::Gang:
493 case OpenACCClauseKind::Wait:
494 return ClauseParensKind::Optional;
496 case OpenACCClauseKind::Default:
497 case OpenACCClauseKind::If:
498 case OpenACCClauseKind::Create:
499 case OpenACCClauseKind::PCreate:
500 case OpenACCClauseKind::PresentOrCreate:
501 case OpenACCClauseKind::Copy:
502 case OpenACCClauseKind::PCopy:
503 case OpenACCClauseKind::PresentOrCopy:
504 case OpenACCClauseKind::CopyIn:
505 case OpenACCClauseKind::PCopyIn:
506 case OpenACCClauseKind::PresentOrCopyIn:
507 case OpenACCClauseKind::CopyOut:
508 case OpenACCClauseKind::PCopyOut:
509 case OpenACCClauseKind::PresentOrCopyOut:
510 case OpenACCClauseKind::UseDevice:
511 case OpenACCClauseKind::NoCreate:
512 case OpenACCClauseKind::Present:
513 case OpenACCClauseKind::DevicePtr:
514 case OpenACCClauseKind::Attach:
515 case OpenACCClauseKind::Detach:
516 case OpenACCClauseKind::Private:
517 case OpenACCClauseKind::FirstPrivate:
518 case OpenACCClauseKind::Delete:
519 case OpenACCClauseKind::DeviceResident:
520 case OpenACCClauseKind::Device:
521 case OpenACCClauseKind::Link:
522 case OpenACCClauseKind::Host:
523 case OpenACCClauseKind::Reduction:
524 case OpenACCClauseKind::Collapse:
525 case OpenACCClauseKind::Bind:
526 case OpenACCClauseKind::VectorLength:
527 case OpenACCClauseKind::NumGangs:
528 case OpenACCClauseKind::NumWorkers:
529 case OpenACCClauseKind::DeviceNum:
530 case OpenACCClauseKind::DefaultAsync:
531 case OpenACCClauseKind::DeviceType:
532 case OpenACCClauseKind::DType:
533 case OpenACCClauseKind::Tile:
534 return ClauseParensKind::Required;
536 case OpenACCClauseKind::Auto:
537 case OpenACCClauseKind::Finalize:
538 case OpenACCClauseKind::IfPresent:
539 case OpenACCClauseKind::Independent:
540 case OpenACCClauseKind::Invalid:
541 case OpenACCClauseKind::NoHost:
542 case OpenACCClauseKind::Seq:
543 return ClauseParensKind::None;
545 llvm_unreachable(
"Unhandled clause kind");
550 return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Optional;
555 return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Required;
562void SkipUntilEndOfDirective(
Parser &
P) {
563 while (
P.getCurToken().isNot(tok::annot_pragma_openacc_end))
571 case OpenACCDirectiveKind::Parallel:
572 case OpenACCDirectiveKind::Serial:
573 case OpenACCDirectiveKind::Kernels:
574 case OpenACCDirectiveKind::Loop:
577 llvm_unreachable(
"Unhandled directive->assoc stmt");
582 case OpenACCDirectiveKind::Parallel:
583 case OpenACCDirectiveKind::Serial:
584 case OpenACCDirectiveKind::Kernels:
589 case OpenACCDirectiveKind::Invalid:
590 llvm_unreachable(
"Shouldn't be creating a scope for an invalid construct");
599Parser::OpenACCClauseParseResult Parser::OpenACCCanContinue() {
600 return {
nullptr, OpenACCParseCanContinue::Can};
603Parser::OpenACCClauseParseResult Parser::OpenACCCannotContinue() {
604 return {
nullptr, OpenACCParseCanContinue::Cannot};
607Parser::OpenACCClauseParseResult Parser::OpenACCSuccess(
OpenACCClause *Clause) {
608 return {Clause, OpenACCParseCanContinue::Can};
611ExprResult Parser::ParseOpenACCConditionExpr() {
636 bool FirstClause =
true;
637 while (
getCurToken().isNot(tok::annot_pragma_openacc_end)) {
643 OpenACCClauseParseResult
Result = ParseOpenACCClause(Clauses, DirKind);
645 Clauses.push_back(Clause);
646 }
else if (
Result.getInt() == OpenACCParseCanContinue::Cannot) {
649 SkipUntilEndOfDirective(*
this);
656Parser::OpenACCIntExprParseResult
664 return {ER, OpenACCParseCanContinue::Cannot};
670 return {ER, OpenACCParseCanContinue::Can};
673 OpenACCParseCanContinue::Can};
679 OpenACCIntExprParseResult CurResult = ParseOpenACCIntExpr(DK, CK,
Loc);
681 if (!CurResult.first.isUsable() &&
682 CurResult.second == OpenACCParseCanContinue::Cannot) {
683 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
688 IntExprs.push_back(CurResult.first.get());
691 ExpectAndConsume(tok::comma);
693 CurResult = ParseOpenACCIntExpr(DK, CK,
Loc);
695 if (!CurResult.first.isUsable() &&
696 CurResult.second == OpenACCParseCanContinue::Cannot) {
697 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
701 IntExprs.push_back(CurResult.first.get());
715bool Parser::ParseOpenACCDeviceTypeList(
718 if (expectIdentifierOrKeyword(*
this)) {
719 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
727 ExpectAndConsume(tok::comma);
729 if (expectIdentifierOrKeyword(*
this)) {
730 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
746bool Parser::ParseOpenACCSizeExpr() {
753 tok::annot_pragma_openacc_end)) {
763bool Parser::ParseOpenACCSizeExprList() {
764 if (ParseOpenACCSizeExpr()) {
765 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
771 ExpectAndConsume(tok::comma);
773 if (ParseOpenACCSizeExpr()) {
774 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
790 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Static,
getCurToken()) &&
795 return ParseOpenACCSizeExpr();
798 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Dim,
getCurToken()) &&
807 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Num,
getCurToken()) &&
820 if (ParseOpenACCGangArg(GangLoc)) {
821 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
827 ExpectAndConsume(tok::comma);
829 if (ParseOpenACCGangArg(GangLoc)) {
830 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
843Parser::OpenACCClauseParseResult
848 if (expectIdentifierOrKeyword(*
this))
849 return OpenACCCannotContinue();
856 return OpenACCCannotContinue();
862 return ParseOpenACCClauseParams(ExistingClauses, DirKind, Kind, ClauseLoc);
865Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
870 tok::annot_pragma_openacc_end);
873 if (ClauseHasRequiredParens(DirKind, ClauseKind)) {
874 if (
Parens.expectAndConsume()) {
878 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openacc_end,
880 return OpenACCCanContinue();
884 switch (ClauseKind) {
888 if (expectIdentifierOrKeyword(*
this)) {
890 return OpenACCCanContinue();
896 getOpenACCDefaultClauseKind(DefKindTok);
899 Diag(DefKindTok, diag::err_acc_invalid_default_clause_kind);
901 return OpenACCCanContinue();
908 ExprResult CondExpr = ParseOpenACCConditionExpr();
914 return OpenACCCanContinue();
922 bool IsReadOnly = tryParseAndConsumeSpecialTokenKind(
923 *
this, OpenACCSpecialTokenKind::ReadOnly, ClauseKind);
935 bool IsZero = tryParseAndConsumeSpecialTokenKind(
936 *
this, OpenACCSpecialTokenKind::Zero, ClauseKind);
961 ParseOpenACCVarList(ClauseKind);
979 tryParseAndConsumeSpecialTokenKind(*
this, OpenACCSpecialTokenKind::Force,
985 return OpenACCCanContinue();
990 ExprResult BindArg = ParseOpenACCBindClauseArgument();
993 return OpenACCCanContinue();
1004 return OpenACCCanContinue();
1014 ClauseKind, ClauseLoc)
1018 return OpenACCCanContinue();
1036 }
else if (!ParseOpenACCDeviceTypeList(Archs)) {
1040 return OpenACCCanContinue();
1045 if (ParseOpenACCSizeExprList()) {
1047 return OpenACCCanContinue();
1051 llvm_unreachable(
"Not a required parens type?");
1056 if (
Parens.consumeClose())
1057 return OpenACCCannotContinue();
1059 }
else if (ClauseHasOptionalParens(DirKind, ClauseKind)) {
1060 if (!
Parens.consumeOpen()) {
1062 switch (ClauseKind) {
1065 ExprResult CondExpr = ParseOpenACCConditionExpr();
1071 return OpenACCCanContinue();
1077 tryParseAndConsumeSpecialTokenKind(*
this,
1080 ? OpenACCSpecialTokenKind::Length
1081 : OpenACCSpecialTokenKind::Num,
1084 ClauseKind, ClauseLoc)
1088 return OpenACCCanContinue();
1101 return OpenACCCanContinue();
1106 if (ParseOpenACCGangArgList(ClauseLoc)) {
1108 return OpenACCCanContinue();
1112 OpenACCWaitParseInfo Info =
1113 ParseOpenACCWaitArgument(ClauseLoc,
1117 return OpenACCCanContinue();
1121 std::move(Info.QueueIdExprs));
1125 llvm_unreachable(
"Not an optional parens type?");
1128 if (
Parens.consumeClose())
1129 return OpenACCCannotContinue();
1138 return OpenACCSuccess(
1149Parser::OpenACCIntExprParseResult
1152 return ParseOpenACCIntExpr(DK, CK,
Loc);
1159Parser::OpenACCWaitParseInfo
1161 OpenACCWaitParseInfo
Result;
1163 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::DevNum, Tok) &&
1170 OpenACCIntExprParseResult Res = ParseOpenACCIntExpr(
1175 if (Res.first.isInvalid() &&
1176 Res.second == OpenACCParseCanContinue::Cannot) {
1181 if (ExpectAndConsume(tok::colon)) {
1186 Result.DevNumExpr = Res.first.get();
1190 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Queues, Tok) &&
1202 bool FirstArg =
true;
1205 if (ExpectAndConsume(tok::comma)) {
1212 OpenACCIntExprParseResult Res = ParseOpenACCAsyncArgument(
1218 if (Res.first.isInvalid() &&
1219 Res.second == OpenACCParseCanContinue::Cannot) {
1224 Result.QueueIdExprs.push_back(Res.first.get());
1230ExprResult Parser::ParseOpenACCIDExpression() {
1233 Res = ParseCXXIdExpression(
true);
1238 if (Tok.
isNot(tok::identifier)) {
1239 Diag(Tok, diag::err_expected) << tok::identifier;
1260ExprResult Parser::ParseOpenACCBindClauseArgument() {
1276 return ParseOpenACCIDExpression();
1287 OpenACCArraySectionRAII ArraySections(*
this);
1291 return {Res, OpenACCParseCanContinue::Cannot};
1295 return {Res, OpenACCParseCanContinue::Can};
1299 return {Res, OpenACCParseCanContinue::Can};
1305 auto [Res, CanContinue] = ParseOpenACCVar(CK);
1307 Vars.push_back(Res.
get());
1308 }
else if (CanContinue == OpenACCParseCanContinue::Cannot) {
1314 ExpectAndConsume(tok::comma);
1316 auto [Res, CanContinue] = ParseOpenACCVar(CK);
1319 Vars.push_back(Res.
get());
1320 }
else if (CanContinue == OpenACCParseCanContinue::Cannot) {
1332void Parser::ParseOpenACCCacheVarList() {
1341 if (tryParseAndConsumeSpecialTokenKind(*
this,
1342 OpenACCSpecialTokenKind::ReadOnly,
1353Parser::OpenACCDirectiveParseInfo
1354Parser::ParseOpenACCDirective() {
1365 ParseOpenACCAtomicKind(*
this);
1370 tok::annot_pragma_openacc_end);
1372 if (!
T.consumeOpen()) {
1375 Diag(
T.getOpenLocation(), diag::err_acc_invalid_open_paren);
1381 ExprResult RoutineName = ParseOpenACCIDExpression();
1391 ParseOpenACCCacheVarList();
1398 if (ParseOpenACCWaitArgument(DirLoc,
true).Failed)
1408 Diag(Tok, diag::err_expected) << tok::l_paren;
1412 OpenACCDirectiveParseInfo ParseInfo{DirKind, StartLoc, DirLoc,
1414 ParseOpenACCClauseList(DirKind)};
1416 assert(Tok.
is(tok::annot_pragma_openacc_end) &&
1417 "Didn't parse all OpenACC Clauses");
1418 ParseInfo.EndLoc = ConsumeAnnotationToken();
1419 assert(ParseInfo.EndLoc.isValid() &&
1420 "Terminating annotation token not present");
1427 assert(Tok.
is(tok::annot_pragma_openacc) &&
"expected OpenACC Start Token");
1431 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
1433 if (
getActions().OpenACC().ActOnStartDeclDirective(DirInfo.DirKind,
1443 assert(Tok.
is(tok::annot_pragma_openacc) &&
"expected OpenACC Start Token");
1447 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
1448 if (
getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind,
1455 if (doesDirectiveHaveAssociatedStmt(DirInfo.DirKind)) {
1457 ParseScope ACCScope(
this, getOpenACCScopeFlags(DirInfo.DirKind));
1460 DirInfo.StartLoc, DirInfo.DirKind, ParseStatement());
1464 DirInfo.DirKind, DirInfo.StartLoc, DirInfo.DirLoc, DirInfo.EndLoc,
1465 DirInfo.Clauses, AssocStmt);
static Decl::Kind getKind(const Decl *D)
Defines some OpenACC-specific enums and functions.
static constexpr bool isOneOf()
This file declares semantic analysis for OpenACC constructs and clauses.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
Represents a C++ nested-name-specifier or a global scope specifier.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
One of these records is kept for each identifier that is lexed.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
Wrapper for void* pointer.
static OpaquePtr make(PtrTy P)
This is the base type for all OpenACC Clauses.
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
DeclGroupPtrTy ParseOpenACCDirectiveDecl()
Placeholder for now, should just ignore the directives after emitting a diagnostic.
Sema & getActions() const
ExprResult ParseConstantExpression()
StmtResult ParseOpenACCDirectiveStmt()
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
const Token & getCurToken() const
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
Activates OpenACC parsing mode to preseve OpenACC specific annotation tokens.
@ ContinueScope
This is a while, do, for, which can have continue statements embedded into it.
@ OpenACCComputeConstructScope
This is the scope of an OpenACC Compute Construct, which restricts jumping into/out of it.
@ BreakScope
This is a while, do, switch, for, etc that can have break statements embedded into it.
Helper type for the registration/assignment of constructs that need to 'know' about their parent cons...
A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...
void setLParenLoc(SourceLocation EndLoc)
void setConditionDetails(Expr *ConditionExpr)
void setReductionDetails(OpenACCReductionOperator Op, llvm::SmallVector< Expr * > &&VarList)
void setDefaultDetails(OpenACCDefaultClauseKind DefKind)
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc, llvm::SmallVector< Expr * > &&IntExprs)
void setEndLoc(SourceLocation EndLoc)
void setIntExprDetails(ArrayRef< Expr * > IntExprs)
void setDeviceTypeDetails(llvm::SmallVector< DeviceTypeArgument > &&Archs)
ExprResult ActOnVar(OpenACCClauseKind CK, Expr *VarExpr)
Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...
ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation Loc, Expr *IntExpr)
Called when encountering an 'int-expr' for OpenACC, and manages conversions and diagnostics to 'int'.
OpenACCClause * ActOnClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCParsedClause &Clause)
Called after parsing an OpenACC Clause so that it can be checked.
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
@ Boolean
A boolean condition, from 'if', 'while', 'for', or 'do'.
ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, CorrectionCandidateCallback *CCC=nullptr, bool IsInlineAsmIdentifier=false, Token *KeywordReplacement=nullptr)
ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, Expr *SubExpr, ConditionKind CK, bool MissingOK=false)
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
Encodes a location in the source.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
Represents a C++ unqualified-id that has been parsed.
bool Zero(InterpState &S, CodePtr OpPC)
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.
bool isAnnotation(TokenKind K)
Return true if this is any of tok::annot_* kinds.
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ Bind
'bind' clause, allowed on routine constructs.
@ Gang
'gang' clause, allowed on 'loop' and Combined constructs.
@ Wait
'wait' clause, allowed on Compute, Data, 'update', and Combined constructs.
@ DevicePtr
'deviceptr' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ PCopyOut
'copyout' clause alias 'pcopyout'. Preserved for diagnostic purposes.
@ VectorLength
'vector_length' clause, allowed on 'parallel', 'kernels', 'parallel loop', and 'kernels loop' constru...
@ Async
'async' clause, allowed on Compute, Data, 'update', 'wait', and Combined constructs.
@ PresentOrCreate
'create' clause alias 'present_or_create'.
@ Collapse
'collapse' clause, allowed on 'loop' and Combined constructs.
@ PresentOrCopy
'copy' clause alias 'present_or_copy'. Preserved for diagnostic purposes.
@ DeviceNum
'device_num' clause, allowed on 'init', 'shutdown', and 'set' constructs.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ Vector
'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
@ Copy
'copy' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ Worker
'worker' clause, allowed on 'loop', Combined, and 'routine' directives.
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ DeviceType
'device_type' clause, allowed on Compute, 'data', 'init', 'shutdown', 'set', update',...
@ DefaultAsync
'default_async' clause, allowed on 'set' construct.
@ Attach
'attach' clause, allowed on Compute and Combined constructs, plus 'data' and 'enter data'.
@ NumGangs
'num_gangs' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs.
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
@ Default
'default' clause, allowed on parallel, serial, kernel (and compound) constructs.
@ UseDevice
'use_device' clause, allowed on 'host_data' construct.
@ NoCreate
'no_create' clause, allowed on allowed on Compute and Combined constructs, plus 'data'.
@ PresentOrCopyOut
'copyout' clause alias 'present_or_copyout'.
@ Link
'link' clause, allowed on 'declare' construct.
@ Reduction
'reduction' clause, allowed on Parallel, Serial, Loop, and the combined constructs.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ CopyOut
'copyout' clause, allowed on Compute and Combined constructs, plus 'data', 'exit data',...
@ FirstPrivate
'firstprivate' clause, allowed on 'parallel', 'serial', 'parallel loop', and 'serial loop' constructs...
@ Host
'host' clause, allowed on 'update' construct.
@ PCopy
'copy' clause alias 'pcopy'. Preserved for diagnostic purposes.
@ Tile
'tile' clause, allowed on 'loop' and Combined constructs.
@ PCopyIn
'copyin' clause alias 'pcopyin'. Preserved for diagnostic purposes.
@ DeviceResident
'device_resident' clause, allowed on the 'declare' construct.
@ PCreate
'create' clause alias 'pcreate'. Preserved for diagnostic purposes.
@ Present
'present' clause, allowed on Compute and Combined constructs, plus 'data' and 'declare'.
@ DType
'dtype' clause, an alias for 'device_type', stored separately for diagnostic purposes.
@ CopyIn
'copyin' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ Device
'device' clause, allowed on the 'update' construct.
@ NumWorkers
'num_workers' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs...
@ Detach
'detach' clause, allowed on the 'exit data' construct.
@ Delete
'delete' clause, allowed on the 'exit data' construct.
@ PresentOrCopyIn
'copyin' clause alias 'present_or_copyin'.
@ Result
The result type of a method or function.
@ Invalid
Not a valid option.
const FunctionProtoType * T
@ None
The alignment was not explicit in code.
@ Parens
New-expression has a C++98 paren-delimited initializer.
Diagnostic wrappers for TextAPI types for error reporting.