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:
576 llvm_unreachable(
"Unhandled directive->assoc stmt");
581 case OpenACCDirectiveKind::Parallel:
582 case OpenACCDirectiveKind::Serial:
583 case OpenACCDirectiveKind::Kernels:
588 case OpenACCDirectiveKind::Invalid:
589 llvm_unreachable(
"Shouldn't be creating a scope for an invalid construct");
598Parser::OpenACCClauseParseResult Parser::OpenACCCanContinue() {
599 return {
nullptr, OpenACCParseCanContinue::Can};
602Parser::OpenACCClauseParseResult Parser::OpenACCCannotContinue() {
603 return {
nullptr, OpenACCParseCanContinue::Cannot};
606Parser::OpenACCClauseParseResult Parser::OpenACCSuccess(
OpenACCClause *Clause) {
607 return {Clause, OpenACCParseCanContinue::Can};
610ExprResult Parser::ParseOpenACCConditionExpr() {
635 bool FirstClause =
true;
636 while (
getCurToken().isNot(tok::annot_pragma_openacc_end)) {
642 OpenACCClauseParseResult
Result = ParseOpenACCClause(Clauses, DirKind);
644 Clauses.push_back(Clause);
645 }
else if (
Result.getInt() == OpenACCParseCanContinue::Cannot) {
648 SkipUntilEndOfDirective(*
this);
655Parser::OpenACCIntExprParseResult
663 return {ER, OpenACCParseCanContinue::Cannot};
669 return {ER, OpenACCParseCanContinue::Can};
672 OpenACCParseCanContinue::Can};
678 OpenACCIntExprParseResult CurResult = ParseOpenACCIntExpr(DK, CK,
Loc);
680 if (!CurResult.first.isUsable() &&
681 CurResult.second == OpenACCParseCanContinue::Cannot) {
682 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
687 IntExprs.push_back(CurResult.first.get());
690 ExpectAndConsume(tok::comma);
692 CurResult = ParseOpenACCIntExpr(DK, CK,
Loc);
694 if (!CurResult.first.isUsable() &&
695 CurResult.second == OpenACCParseCanContinue::Cannot) {
696 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
700 IntExprs.push_back(CurResult.first.get());
714bool Parser::ParseOpenACCDeviceTypeList(
717 if (expectIdentifierOrKeyword(*
this)) {
718 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
726 ExpectAndConsume(tok::comma);
728 if (expectIdentifierOrKeyword(*
this)) {
729 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
745bool Parser::ParseOpenACCSizeExpr() {
752 tok::annot_pragma_openacc_end)) {
762bool Parser::ParseOpenACCSizeExprList() {
763 if (ParseOpenACCSizeExpr()) {
764 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
770 ExpectAndConsume(tok::comma);
772 if (ParseOpenACCSizeExpr()) {
773 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
789 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Static,
getCurToken()) &&
794 return ParseOpenACCSizeExpr();
797 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Dim,
getCurToken()) &&
806 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Num,
getCurToken()) &&
819 if (ParseOpenACCGangArg(GangLoc)) {
820 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
826 ExpectAndConsume(tok::comma);
828 if (ParseOpenACCGangArg(GangLoc)) {
829 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
842Parser::OpenACCClauseParseResult
847 if (expectIdentifierOrKeyword(*
this))
848 return OpenACCCannotContinue();
855 return OpenACCCannotContinue();
861 return ParseOpenACCClauseParams(ExistingClauses, DirKind, Kind, ClauseLoc);
864Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
869 tok::annot_pragma_openacc_end);
872 if (ClauseHasRequiredParens(DirKind, ClauseKind)) {
873 if (
Parens.expectAndConsume()) {
877 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openacc_end,
879 return OpenACCCanContinue();
883 switch (ClauseKind) {
887 if (expectIdentifierOrKeyword(*
this)) {
889 return OpenACCCanContinue();
895 getOpenACCDefaultClauseKind(DefKindTok);
898 Diag(DefKindTok, diag::err_acc_invalid_default_clause_kind);
900 return OpenACCCanContinue();
907 ExprResult CondExpr = ParseOpenACCConditionExpr();
913 return OpenACCCanContinue();
921 bool IsReadOnly = tryParseAndConsumeSpecialTokenKind(
922 *
this, OpenACCSpecialTokenKind::ReadOnly, ClauseKind);
933 bool IsZero = tryParseAndConsumeSpecialTokenKind(
934 *
this, OpenACCSpecialTokenKind::Zero, ClauseKind);
942 ParseReductionOperator(*
this);
943 ParseOpenACCVarList();
958 ParseOpenACCVarList();
976 tryParseAndConsumeSpecialTokenKind(*
this, OpenACCSpecialTokenKind::Force,
982 return OpenACCCanContinue();
987 ExprResult BindArg = ParseOpenACCBindClauseArgument();
990 return OpenACCCanContinue();
1001 return OpenACCCanContinue();
1011 ClauseKind, ClauseLoc)
1015 return OpenACCCanContinue();
1033 }
else if (!ParseOpenACCDeviceTypeList(Archs)) {
1037 return OpenACCCanContinue();
1042 if (ParseOpenACCSizeExprList()) {
1044 return OpenACCCanContinue();
1048 llvm_unreachable(
"Not a required parens type?");
1053 if (
Parens.consumeClose())
1054 return OpenACCCannotContinue();
1056 }
else if (ClauseHasOptionalParens(DirKind, ClauseKind)) {
1057 if (!
Parens.consumeOpen()) {
1059 switch (ClauseKind) {
1062 ExprResult CondExpr = ParseOpenACCConditionExpr();
1068 return OpenACCCanContinue();
1074 tryParseAndConsumeSpecialTokenKind(*
this,
1077 ? OpenACCSpecialTokenKind::Length
1078 : OpenACCSpecialTokenKind::Num,
1081 ClauseKind, ClauseLoc)
1085 return OpenACCCanContinue();
1098 return OpenACCCanContinue();
1103 if (ParseOpenACCGangArgList(ClauseLoc)) {
1105 return OpenACCCanContinue();
1109 OpenACCWaitParseInfo Info =
1110 ParseOpenACCWaitArgument(ClauseLoc,
1114 return OpenACCCanContinue();
1118 std::move(Info.QueueIdExprs));
1122 llvm_unreachable(
"Not an optional parens type?");
1125 if (
Parens.consumeClose())
1126 return OpenACCCannotContinue();
1133 return OpenACCSuccess(
1144Parser::OpenACCIntExprParseResult
1147 return ParseOpenACCIntExpr(DK, CK,
Loc);
1154Parser::OpenACCWaitParseInfo
1156 OpenACCWaitParseInfo
Result;
1158 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::DevNum, Tok) &&
1165 OpenACCIntExprParseResult Res = ParseOpenACCIntExpr(
1170 if (Res.first.isInvalid() &&
1171 Res.second == OpenACCParseCanContinue::Cannot) {
1176 if (ExpectAndConsume(tok::colon)) {
1181 Result.DevNumExpr = Res.first.get();
1185 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Queues, Tok) &&
1197 bool FirstArg =
true;
1200 if (ExpectAndConsume(tok::comma)) {
1207 OpenACCIntExprParseResult Res = ParseOpenACCAsyncArgument(
1213 if (Res.first.isInvalid() &&
1214 Res.second == OpenACCParseCanContinue::Cannot) {
1219 Result.QueueIdExprs.push_back(Res.first.get());
1225ExprResult Parser::ParseOpenACCIDExpression() {
1228 Res = ParseCXXIdExpression(
true);
1233 if (Tok.
isNot(tok::identifier)) {
1234 Diag(Tok, diag::err_expected) << tok::identifier;
1255ExprResult Parser::ParseOpenACCBindClauseArgument() {
1271 return ParseOpenACCIDExpression();
1281Parser::OpenACCVarParseResult Parser::ParseOpenACCVar() {
1282 OpenACCArraySectionRAII ArraySections(*
this);
1286 return {Res, OpenACCParseCanContinue::Cannot};
1290 return {Res, OpenACCParseCanContinue::Can};
1294 return {Res, OpenACCParseCanContinue::Can};
1300 auto [Res, CanContinue] = ParseOpenACCVar();
1302 Vars.push_back(Res.
get());
1303 }
else if (CanContinue == OpenACCParseCanContinue::Cannot) {
1309 ExpectAndConsume(tok::comma);
1311 auto [Res, CanContinue] = ParseOpenACCVar();
1314 Vars.push_back(Res.
get());
1315 }
else if (CanContinue == OpenACCParseCanContinue::Cannot) {
1327void Parser::ParseOpenACCCacheVarList() {
1336 if (tryParseAndConsumeSpecialTokenKind(*
this,
1337 OpenACCSpecialTokenKind::ReadOnly,
1345 ParseOpenACCVarList();
1348Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() {
1358 ParseOpenACCAtomicKind(*
this);
1363 tok::annot_pragma_openacc_end);
1365 if (!
T.consumeOpen()) {
1368 Diag(
T.getOpenLocation(), diag::err_acc_invalid_open_paren);
1374 ExprResult RoutineName = ParseOpenACCIDExpression();
1384 ParseOpenACCCacheVarList();
1391 if (ParseOpenACCWaitArgument(StartLoc,
true).Failed)
1401 Diag(Tok, diag::err_expected) << tok::l_paren;
1405 OpenACCDirectiveParseInfo ParseInfo{DirKind, StartLoc,
SourceLocation{},
1406 ParseOpenACCClauseList(DirKind)};
1408 assert(Tok.
is(tok::annot_pragma_openacc_end) &&
1409 "Didn't parse all OpenACC Clauses");
1410 ParseInfo.EndLoc = ConsumeAnnotationToken();
1411 assert(ParseInfo.EndLoc.isValid() &&
1412 "Terminating annotation token not present");
1419 assert(Tok.
is(tok::annot_pragma_openacc) &&
"expected OpenACC Start Token");
1422 ConsumeAnnotationToken();
1424 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
1426 if (
getActions().OpenACC().ActOnStartDeclDirective(DirInfo.DirKind,
1436 assert(Tok.
is(tok::annot_pragma_openacc) &&
"expected OpenACC Start Token");
1439 ConsumeAnnotationToken();
1441 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
1442 if (
getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind,
1448 if (doesDirectiveHaveAssociatedStmt(DirInfo.DirKind)) {
1450 ParseScope ACCScope(
this, getOpenACCScopeFlags(DirInfo.DirKind));
1457 DirInfo.DirKind, DirInfo.StartLoc, DirInfo.EndLoc, DirInfo.Clauses,
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.
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 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(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'.
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
OpenACCClause * ActOnClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCParsedClause &Clause)
Called after parsing an OpenACC Clause so that it can be checked.
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
StmtResult ActOnAssociatedStmt(OpenACCDirectiveKind K, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
@ 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.