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(
"collapse", OpenACCClauseKind::Collapse)
104 .Case(
"copy", OpenACCClauseKind::Copy)
105 .Case(
"copyin", OpenACCClauseKind::CopyIn)
106 .Case(
"copyout", OpenACCClauseKind::CopyOut)
107 .Case(
"default", OpenACCClauseKind::Default)
108 .Case(
"default_async", OpenACCClauseKind::DefaultAsync)
109 .Case(
"delete", OpenACCClauseKind::Delete)
110 .Case(
"detach", OpenACCClauseKind::Detach)
111 .Case(
"device", OpenACCClauseKind::Device)
112 .Case(
"device_num", OpenACCClauseKind::DeviceNum)
113 .Case(
"device_resident", OpenACCClauseKind::DeviceResident)
114 .Case(
"device_type", OpenACCClauseKind::DeviceType)
115 .Case(
"deviceptr", OpenACCClauseKind::DevicePtr)
116 .Case(
"dtype", OpenACCClauseKind::DType)
117 .Case(
"finalize", OpenACCClauseKind::Finalize)
118 .Case(
"firstprivate", OpenACCClauseKind::FirstPrivate)
119 .Case(
"gang", OpenACCClauseKind::Gang)
120 .Case(
"host", OpenACCClauseKind::Host)
121 .Case(
"if", OpenACCClauseKind::If)
122 .Case(
"if_present", OpenACCClauseKind::IfPresent)
123 .Case(
"independent", OpenACCClauseKind::Independent)
124 .Case(
"link", OpenACCClauseKind::Link)
125 .Case(
"no_create", OpenACCClauseKind::NoCreate)
126 .Case(
"num_gangs", OpenACCClauseKind::NumGangs)
127 .Case(
"num_workers", OpenACCClauseKind::NumWorkers)
128 .Case(
"nohost", OpenACCClauseKind::NoHost)
129 .Case(
"present", OpenACCClauseKind::Present)
130 .Case(
"private", OpenACCClauseKind::Private)
131 .Case(
"reduction", OpenACCClauseKind::Reduction)
132 .Case(
"self", OpenACCClauseKind::Self)
133 .Case(
"seq", OpenACCClauseKind::Seq)
134 .Case(
"tile", OpenACCClauseKind::Tile)
135 .Case(
"use_device", OpenACCClauseKind::UseDevice)
136 .Case(
"vector", OpenACCClauseKind::Vector)
137 .Case(
"vector_length", OpenACCClauseKind::VectorLength)
138 .Case(
"wait", OpenACCClauseKind::Wait)
139 .Case(
"worker", OpenACCClauseKind::Worker)
140 .Default(OpenACCClauseKind::Invalid);
146 if (!Tok.
is(tok::identifier))
147 return OpenACCAtomicKind::Invalid;
148 return llvm::StringSwitch<OpenACCAtomicKind>(
150 .Case(
"read", OpenACCAtomicKind::Read)
151 .Case(
"write", OpenACCAtomicKind::Write)
152 .Case(
"update", OpenACCAtomicKind::Update)
153 .Case(
"capture", OpenACCAtomicKind::Capture)
154 .Default(OpenACCAtomicKind::Invalid);
158 if (!Tok.
is(tok::identifier))
159 return OpenACCDefaultClauseKind::Invalid;
161 return llvm::StringSwitch<OpenACCDefaultClauseKind>(
163 .Case(
"none", OpenACCDefaultClauseKind::None)
164 .Case(
"present", OpenACCDefaultClauseKind::Present)
165 .Default(OpenACCDefaultClauseKind::Invalid);
168enum class OpenACCSpecialTokenKind {
180bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind,
Token Tok) {
181 if (Tok.
is(tok::kw_static) && Kind == OpenACCSpecialTokenKind::Static)
184 if (!Tok.
is(tok::identifier))
188 case OpenACCSpecialTokenKind::ReadOnly:
190 case OpenACCSpecialTokenKind::DevNum:
192 case OpenACCSpecialTokenKind::Queues:
194 case OpenACCSpecialTokenKind::Zero:
196 case OpenACCSpecialTokenKind::Force:
198 case OpenACCSpecialTokenKind::Num:
200 case OpenACCSpecialTokenKind::Length:
202 case OpenACCSpecialTokenKind::Dim:
204 case OpenACCSpecialTokenKind::Static:
207 llvm_unreachable(
"Unknown 'Kind' Passed");
214 if (Tok.
is(tok::identifier))
229template <
typename DirOrClauseTy>
230bool tryParseAndConsumeSpecialTokenKind(
Parser &
P, OpenACCSpecialTokenKind Kind,
231 DirOrClauseTy DirOrClause) {
232 Token IdentTok =
P.getCurToken();
235 if (isTokenIdentifierOrKeyword(
P, IdentTok) &&
P.NextToken().is(tok::colon)) {
239 if (!isOpenACCSpecialToken(Kind, IdentTok)) {
240 P.Diag(IdentTok, diag::err_acc_invalid_tag_kind)
242 << std::is_same_v<DirOrClauseTy, OpenACCClauseKind>;
253 if (!Tok.
is(tok::identifier))
257 case OpenACCDirectiveKind::Parallel:
259 case OpenACCDirectiveKind::Serial:
261 case OpenACCDirectiveKind::Kernels:
263 case OpenACCDirectiveKind::Data:
265 case OpenACCDirectiveKind::HostData:
267 case OpenACCDirectiveKind::Loop:
269 case OpenACCDirectiveKind::Cache:
272 case OpenACCDirectiveKind::ParallelLoop:
273 case OpenACCDirectiveKind::SerialLoop:
274 case OpenACCDirectiveKind::KernelsLoop:
275 case OpenACCDirectiveKind::EnterData:
276 case OpenACCDirectiveKind::ExitData:
279 case OpenACCDirectiveKind::Atomic:
281 case OpenACCDirectiveKind::Routine:
283 case OpenACCDirectiveKind::Declare:
285 case OpenACCDirectiveKind::Init:
287 case OpenACCDirectiveKind::Shutdown:
289 case OpenACCDirectiveKind::Set:
291 case OpenACCDirectiveKind::Update:
293 case OpenACCDirectiveKind::Wait:
295 case OpenACCDirectiveKind::Invalid:
298 llvm_unreachable(
"Unknown 'Kind' Passed");
305 if (
P.NextToken().isNot(tok::colon)) {
306 P.Diag(
P.getCurToken(), diag::err_acc_expected_reduction_operator);
307 return OpenACCReductionOperator::Invalid;
309 Token ReductionKindTok =
P.getCurToken();
314 switch (ReductionKindTok.
getKind()) {
316 return OpenACCReductionOperator::Addition;
318 return OpenACCReductionOperator::Multiplication;
320 return OpenACCReductionOperator::BitwiseAnd;
322 return OpenACCReductionOperator::BitwiseOr;
324 return OpenACCReductionOperator::BitwiseXOr;
326 return OpenACCReductionOperator::And;
328 return OpenACCReductionOperator::Or;
329 case tok::identifier:
331 return OpenACCReductionOperator::Max;
333 return OpenACCReductionOperator::Min;
336 P.Diag(ReductionKindTok, diag::err_acc_invalid_reduction_operator);
337 return OpenACCReductionOperator::Invalid;
339 llvm_unreachable(
"Reduction op token kind not caught by 'default'?");
344bool expectIdentifierOrKeyword(
Parser &
P) {
345 Token Tok =
P.getCurToken();
347 if (isTokenIdentifierOrKeyword(
P, Tok))
350 P.Diag(
P.getCurToken(), diag::err_expected) << tok::identifier;
355ParseOpenACCEnterExitDataDirective(
Parser &
P,
Token FirstTok,
356 OpenACCDirectiveKindEx ExtDirKind) {
357 Token SecondTok =
P.getCurToken();
360 P.Diag(FirstTok, diag::err_acc_invalid_directive)
362 return OpenACCDirectiveKind::Invalid;
369 if (!isOpenACCDirectiveKind(OpenACCDirectiveKind::Data, SecondTok)) {
370 if (!SecondTok.
is(tok::identifier))
371 P.Diag(SecondTok, diag::err_expected) << tok::identifier;
373 P.Diag(FirstTok, diag::err_acc_invalid_directive)
376 return OpenACCDirectiveKind::Invalid;
379 return ExtDirKind == OpenACCDirectiveKindEx::Enter
380 ? OpenACCDirectiveKind::EnterData
381 : OpenACCDirectiveKind::ExitData;
385 Token AtomicClauseToken =
P.getCurToken();
389 return OpenACCAtomicKind::Update;
396 if (AtomicKind == OpenACCAtomicKind::Invalid)
397 return OpenACCAtomicKind::Update;
405 Token FirstTok =
P.getCurToken();
409 if (FirstTok.
isNot(tok::identifier)) {
410 P.Diag(FirstTok, diag::err_acc_missing_directive);
412 if (
P.getCurToken().isNot(tok::annot_pragma_openacc_end))
415 return OpenACCDirectiveKind::Invalid;
420 OpenACCDirectiveKindEx ExDirKind = getOpenACCDirectiveKind(FirstTok);
428 if (ExDirKind >= OpenACCDirectiveKindEx::Invalid) {
430 case OpenACCDirectiveKindEx::Invalid: {
431 P.Diag(FirstTok, diag::err_acc_invalid_directive)
433 return OpenACCDirectiveKind::Invalid;
435 case OpenACCDirectiveKindEx::Enter:
436 case OpenACCDirectiveKindEx::Exit:
437 return ParseOpenACCEnterExitDataDirective(
P, FirstTok, ExDirKind);
446 Token SecondTok =
P.getCurToken();
448 isOpenACCDirectiveKind(OpenACCDirectiveKind::Loop, SecondTok)) {
454 case OpenACCDirectiveKind::Parallel:
456 return OpenACCDirectiveKind::ParallelLoop;
457 case OpenACCDirectiveKind::Serial:
459 return OpenACCDirectiveKind::SerialLoop;
460 case OpenACCDirectiveKind::Kernels:
462 return OpenACCDirectiveKind::KernelsLoop;
469enum ClauseParensKind {
478 case OpenACCClauseKind::Self:
479 return DirKind == OpenACCDirectiveKind::Update ? ClauseParensKind::Required
480 : ClauseParensKind::Optional;
481 case OpenACCClauseKind::Async:
482 case OpenACCClauseKind::Worker:
483 case OpenACCClauseKind::Vector:
484 case OpenACCClauseKind::Gang:
485 case OpenACCClauseKind::Wait:
486 return ClauseParensKind::Optional;
488 case OpenACCClauseKind::Default:
489 case OpenACCClauseKind::If:
490 case OpenACCClauseKind::Create:
491 case OpenACCClauseKind::Copy:
492 case OpenACCClauseKind::CopyIn:
493 case OpenACCClauseKind::CopyOut:
494 case OpenACCClauseKind::UseDevice:
495 case OpenACCClauseKind::NoCreate:
496 case OpenACCClauseKind::Present:
497 case OpenACCClauseKind::DevicePtr:
498 case OpenACCClauseKind::Attach:
499 case OpenACCClauseKind::Detach:
500 case OpenACCClauseKind::Private:
501 case OpenACCClauseKind::FirstPrivate:
502 case OpenACCClauseKind::Delete:
503 case OpenACCClauseKind::DeviceResident:
504 case OpenACCClauseKind::Device:
505 case OpenACCClauseKind::Link:
506 case OpenACCClauseKind::Host:
507 case OpenACCClauseKind::Reduction:
508 case OpenACCClauseKind::Collapse:
509 case OpenACCClauseKind::Bind:
510 case OpenACCClauseKind::VectorLength:
511 case OpenACCClauseKind::NumGangs:
512 case OpenACCClauseKind::NumWorkers:
513 case OpenACCClauseKind::DeviceNum:
514 case OpenACCClauseKind::DefaultAsync:
515 case OpenACCClauseKind::DeviceType:
516 case OpenACCClauseKind::DType:
517 case OpenACCClauseKind::Tile:
518 return ClauseParensKind::Required;
520 case OpenACCClauseKind::Auto:
521 case OpenACCClauseKind::Finalize:
522 case OpenACCClauseKind::IfPresent:
523 case OpenACCClauseKind::Independent:
524 case OpenACCClauseKind::Invalid:
525 case OpenACCClauseKind::NoHost:
526 case OpenACCClauseKind::Seq:
527 return ClauseParensKind::None;
529 llvm_unreachable(
"Unhandled clause kind");
534 return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Optional;
539 return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Required;
546void SkipUntilEndOfDirective(
Parser &
P) {
547 while (
P.getCurToken().isNot(tok::annot_pragma_openacc_end))
555 case OpenACCDirectiveKind::Parallel:
556 case OpenACCDirectiveKind::Serial:
557 case OpenACCDirectiveKind::Kernels:
560 llvm_unreachable(
"Unhandled directive->assoc stmt");
565 case OpenACCDirectiveKind::Parallel:
566 case OpenACCDirectiveKind::Serial:
567 case OpenACCDirectiveKind::Kernels:
572 case OpenACCDirectiveKind::Invalid:
573 llvm_unreachable(
"Shouldn't be creating a scope for an invalid construct");
582Parser::OpenACCClauseParseResult Parser::OpenACCCanContinue() {
583 return {
nullptr, OpenACCParseCanContinue::Can};
586Parser::OpenACCClauseParseResult Parser::OpenACCCannotContinue() {
587 return {
nullptr, OpenACCParseCanContinue::Cannot};
590Parser::OpenACCClauseParseResult Parser::OpenACCSuccess(
OpenACCClause *Clause) {
591 return {Clause, OpenACCParseCanContinue::Can};
594ExprResult Parser::ParseOpenACCConditionExpr() {
619 bool FirstClause =
true;
620 while (
getCurToken().isNot(tok::annot_pragma_openacc_end)) {
626 OpenACCClauseParseResult
Result = ParseOpenACCClause(Clauses, DirKind);
628 Clauses.push_back(Clause);
629 }
else if (
Result.getInt() == OpenACCParseCanContinue::Cannot) {
632 SkipUntilEndOfDirective(*
this);
639Parser::OpenACCIntExprParseResult
647 return {ER, OpenACCParseCanContinue::Cannot};
653 return {ER, OpenACCParseCanContinue::Can};
656 OpenACCParseCanContinue::Can};
662 OpenACCIntExprParseResult CurResult = ParseOpenACCIntExpr(DK, CK, Loc);
664 if (!CurResult.first.isUsable() &&
665 CurResult.second == OpenACCParseCanContinue::Cannot) {
666 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
671 IntExprs.push_back(CurResult.first.get());
674 ExpectAndConsume(tok::comma);
676 CurResult = ParseOpenACCIntExpr(DK, CK, Loc);
678 if (!CurResult.first.isUsable() &&
679 CurResult.second == OpenACCParseCanContinue::Cannot) {
680 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
684 IntExprs.push_back(CurResult.first.get());
698bool Parser::ParseOpenACCDeviceTypeList() {
700 if (expectIdentifierOrKeyword(*
this)) {
701 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
708 ExpectAndConsume(tok::comma);
710 if (expectIdentifierOrKeyword(*
this)) {
711 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
726bool Parser::ParseOpenACCSizeExpr() {
733 tok::annot_pragma_openacc_end)) {
743bool Parser::ParseOpenACCSizeExprList() {
744 if (ParseOpenACCSizeExpr()) {
745 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
751 ExpectAndConsume(tok::comma);
753 if (ParseOpenACCSizeExpr()) {
754 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
770 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Static,
getCurToken()) &&
775 return ParseOpenACCSizeExpr();
778 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Dim,
getCurToken()) &&
787 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Num,
getCurToken()) &&
800 if (ParseOpenACCGangArg(GangLoc)) {
801 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
807 ExpectAndConsume(tok::comma);
809 if (ParseOpenACCGangArg(GangLoc)) {
810 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
823Parser::OpenACCClauseParseResult
828 if (expectIdentifierOrKeyword(*
this))
829 return OpenACCCannotContinue();
836 return OpenACCCannotContinue();
842 return ParseOpenACCClauseParams(ExistingClauses, DirKind, Kind, ClauseLoc);
845Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
850 tok::annot_pragma_openacc_end);
853 if (ClauseHasRequiredParens(DirKind, ClauseKind)) {
855 if (
Parens.expectAndConsume()) {
859 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openacc_end,
861 return OpenACCCanContinue();
864 switch (ClauseKind) {
868 if (expectIdentifierOrKeyword(*
this)) {
870 return OpenACCCanContinue();
876 getOpenACCDefaultClauseKind(DefKindTok);
879 Diag(DefKindTok, diag::err_acc_invalid_default_clause_kind);
881 return OpenACCCanContinue();
888 ExprResult CondExpr = ParseOpenACCConditionExpr();
894 return OpenACCCanContinue();
900 tryParseAndConsumeSpecialTokenKind(
901 *
this, OpenACCSpecialTokenKind::ReadOnly, ClauseKind);
902 ParseOpenACCVarList();
906 tryParseAndConsumeSpecialTokenKind(*
this, OpenACCSpecialTokenKind::Zero,
908 ParseOpenACCVarList();
913 ParseReductionOperator(*
this);
914 ParseOpenACCVarList();
935 ParseOpenACCVarList();
941 tryParseAndConsumeSpecialTokenKind(*
this, OpenACCSpecialTokenKind::Force,
947 return OpenACCCanContinue();
952 ExprResult BindArg = ParseOpenACCBindClauseArgument();
955 return OpenACCCanContinue();
966 return OpenACCCanContinue();
976 ClauseKind, ClauseLoc)
980 return OpenACCCanContinue();
997 }
else if (ParseOpenACCDeviceTypeList()) {
999 return OpenACCCanContinue();
1003 if (ParseOpenACCSizeExprList()) {
1005 return OpenACCCanContinue();
1009 llvm_unreachable(
"Not a required parens type?");
1014 if (
Parens.consumeClose())
1015 return OpenACCCannotContinue();
1017 }
else if (ClauseHasOptionalParens(DirKind, ClauseKind)) {
1019 if (!
Parens.consumeOpen()) {
1020 switch (ClauseKind) {
1023 ExprResult CondExpr = ParseOpenACCConditionExpr();
1029 return OpenACCCanContinue();
1035 tryParseAndConsumeSpecialTokenKind(*
this,
1038 ? OpenACCSpecialTokenKind::Length
1039 : OpenACCSpecialTokenKind::Num,
1042 ClauseKind, ClauseLoc)
1046 return OpenACCCanContinue();
1051 ExprResult AsyncArg = ParseOpenACCAsyncArgument();
1054 return OpenACCCanContinue();
1059 if (ParseOpenACCGangArgList(ClauseLoc)) {
1061 return OpenACCCanContinue();
1065 if (ParseOpenACCWaitArgument(ClauseLoc,
1068 return OpenACCCanContinue();
1072 llvm_unreachable(
"Not an optional parens type?");
1075 if (
Parens.consumeClose())
1076 return OpenACCCannotContinue();
1079 return OpenACCSuccess(
1090ExprResult Parser::ParseOpenACCAsyncArgument() {
1098bool Parser::ParseOpenACCWaitArgument(
SourceLocation Loc,
bool IsDirective) {
1100 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::DevNum, Tok) &&
1117 if (ExpectAndConsume(tok::colon))
1122 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Queues, Tok) &&
1134 bool FirstArg =
true;
1137 if (ExpectAndConsume(tok::comma))
1142 ExprResult CurArg = ParseOpenACCAsyncArgument();
1151ExprResult Parser::ParseOpenACCIDExpression() {
1154 Res = ParseCXXIdExpression(
true);
1159 if (Tok.
isNot(tok::identifier)) {
1160 Diag(Tok, diag::err_expected) << tok::identifier;
1181ExprResult Parser::ParseOpenACCBindClauseArgument() {
1197 return ParseOpenACCIDExpression();
1207Parser::OpenACCVarParseResult Parser::ParseOpenACCVar() {
1208 OpenACCArraySectionRAII ArraySections(*
this);
1212 return {Res, OpenACCParseCanContinue::Cannot};
1216 return {Res, OpenACCParseCanContinue::Can};
1220 return {Res, OpenACCParseCanContinue::Can};
1226 auto [Res, CanContinue] = ParseOpenACCVar();
1228 Vars.push_back(Res.
get());
1229 }
else if (CanContinue == OpenACCParseCanContinue::Cannot) {
1235 ExpectAndConsume(tok::comma);
1237 auto [Res, CanContinue] = ParseOpenACCVar();
1240 Vars.push_back(Res.
get());
1241 }
else if (CanContinue == OpenACCParseCanContinue::Cannot) {
1253void Parser::ParseOpenACCCacheVarList() {
1262 if (tryParseAndConsumeSpecialTokenKind(*
this,
1263 OpenACCSpecialTokenKind::ReadOnly,
1271 ParseOpenACCVarList();
1274Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() {
1284 ParseOpenACCAtomicKind(*
this);
1289 tok::annot_pragma_openacc_end);
1291 if (!
T.consumeOpen()) {
1294 Diag(
T.getOpenLocation(), diag::err_acc_invalid_open_paren);
1300 ExprResult RoutineName = ParseOpenACCIDExpression();
1310 ParseOpenACCCacheVarList();
1317 if (ParseOpenACCWaitArgument(StartLoc,
true))
1327 Diag(Tok, diag::err_expected) << tok::l_paren;
1331 OpenACCDirectiveParseInfo ParseInfo{DirKind, StartLoc,
SourceLocation{},
1332 ParseOpenACCClauseList(DirKind)};
1334 assert(Tok.
is(tok::annot_pragma_openacc_end) &&
1335 "Didn't parse all OpenACC Clauses");
1336 ParseInfo.EndLoc = ConsumeAnnotationToken();
1337 assert(ParseInfo.EndLoc.isValid() &&
1338 "Terminating annotation token not present");
1345 assert(Tok.
is(tok::annot_pragma_openacc) &&
"expected OpenACC Start Token");
1348 ConsumeAnnotationToken();
1350 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
1352 if (
getActions().OpenACC().ActOnStartDeclDirective(DirInfo.DirKind,
1362 assert(Tok.
is(tok::annot_pragma_openacc) &&
"expected OpenACC Start Token");
1365 ConsumeAnnotationToken();
1367 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
1368 if (
getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind,
1374 if (doesDirectiveHaveAssociatedStmt(DirInfo.DirKind)) {
1376 ParseScope ACCScope(
this, getOpenACCScopeFlags(DirInfo.DirKind));
1383 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...
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 setVarListDetails(ArrayRef< Expr * > VarList)
void setDefaultDetails(OpenACCDefaultClauseKind DefKind)
void setEndLoc(SourceLocation EndLoc)
void setIntExprDetails(ArrayRef< Expr * > IntExprs)
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'.
@ 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.
@ Collapse
'collapse' clause, allowed on 'loop' and Combined constructs.
@ 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
'copyin' 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'.
@ 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.
@ Tile
'tile' clause, allowed on 'loop' and Combined constructs.
@ DeviceResident
'device_resident' clause, allowed on the 'declare' construct.
@ 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.
@ 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.