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;
89 if (!Tok.
is(tok::identifier))
90 return OpenACCClauseKind::Invalid;
92 return llvm::StringSwitch<OpenACCClauseKind>(
94 .Case(
"async", OpenACCClauseKind::Async)
95 .Case(
"attach", OpenACCClauseKind::Attach)
96 .Case(
"auto", OpenACCClauseKind::Auto)
97 .Case(
"bind", OpenACCClauseKind::Bind)
98 .Case(
"create", OpenACCClauseKind::Create)
99 .Case(
"collapse", OpenACCClauseKind::Collapse)
100 .Case(
"copy", OpenACCClauseKind::Copy)
101 .Case(
"copyin", OpenACCClauseKind::CopyIn)
102 .Case(
"copyout", OpenACCClauseKind::CopyOut)
103 .Case(
"default", OpenACCClauseKind::Default)
104 .Case(
"default_async", OpenACCClauseKind::DefaultAsync)
105 .Case(
"delete", OpenACCClauseKind::Delete)
106 .Case(
"detach", OpenACCClauseKind::Detach)
107 .Case(
"device", OpenACCClauseKind::Device)
108 .Case(
"device_num", OpenACCClauseKind::DeviceNum)
109 .Case(
"device_resident", OpenACCClauseKind::DeviceResident)
110 .Case(
"device_type", OpenACCClauseKind::DeviceType)
111 .Case(
"deviceptr", OpenACCClauseKind::DevicePtr)
112 .Case(
"dtype", OpenACCClauseKind::DType)
113 .Case(
"finalize", OpenACCClauseKind::Finalize)
114 .Case(
"firstprivate", OpenACCClauseKind::FirstPrivate)
115 .Case(
"gang", OpenACCClauseKind::Gang)
116 .Case(
"host", OpenACCClauseKind::Host)
117 .Case(
"if", OpenACCClauseKind::If)
118 .Case(
"if_present", OpenACCClauseKind::IfPresent)
119 .Case(
"independent", OpenACCClauseKind::Independent)
120 .Case(
"link", OpenACCClauseKind::Link)
121 .Case(
"no_create", OpenACCClauseKind::NoCreate)
122 .Case(
"num_gangs", OpenACCClauseKind::NumGangs)
123 .Case(
"num_workers", OpenACCClauseKind::NumWorkers)
124 .Case(
"nohost", OpenACCClauseKind::NoHost)
125 .Case(
"present", OpenACCClauseKind::Present)
126 .Case(
"private", OpenACCClauseKind::Private)
127 .Case(
"reduction", OpenACCClauseKind::Reduction)
128 .Case(
"self", OpenACCClauseKind::Self)
129 .Case(
"seq", OpenACCClauseKind::Seq)
130 .Case(
"tile", OpenACCClauseKind::Tile)
131 .Case(
"use_device", OpenACCClauseKind::UseDevice)
132 .Case(
"vector", OpenACCClauseKind::Vector)
133 .Case(
"vector_length", OpenACCClauseKind::VectorLength)
134 .Case(
"wait", OpenACCClauseKind::Wait)
135 .Case(
"worker", OpenACCClauseKind::Worker)
136 .Default(OpenACCClauseKind::Invalid);
142 if (!Tok.
is(tok::identifier))
143 return OpenACCAtomicKind::Invalid;
144 return llvm::StringSwitch<OpenACCAtomicKind>(
146 .Case(
"read", OpenACCAtomicKind::Read)
147 .Case(
"write", OpenACCAtomicKind::Write)
148 .Case(
"update", OpenACCAtomicKind::Update)
149 .Case(
"capture", OpenACCAtomicKind::Capture)
150 .Default(OpenACCAtomicKind::Invalid);
154 if (!Tok.
is(tok::identifier))
155 return OpenACCDefaultClauseKind::Invalid;
157 return llvm::StringSwitch<OpenACCDefaultClauseKind>(
159 .Case(
"none", OpenACCDefaultClauseKind::None)
160 .Case(
"present", OpenACCDefaultClauseKind::Present)
161 .Default(OpenACCDefaultClauseKind::Invalid);
164enum class OpenACCSpecialTokenKind {
176bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind,
Token Tok) {
177 if (Tok.
is(tok::kw_static) && Kind == OpenACCSpecialTokenKind::Static)
180 if (!Tok.
is(tok::identifier))
184 case OpenACCSpecialTokenKind::ReadOnly:
186 case OpenACCSpecialTokenKind::DevNum:
188 case OpenACCSpecialTokenKind::Queues:
190 case OpenACCSpecialTokenKind::Zero:
192 case OpenACCSpecialTokenKind::Force:
194 case OpenACCSpecialTokenKind::Num:
196 case OpenACCSpecialTokenKind::Length:
198 case OpenACCSpecialTokenKind::Dim:
200 case OpenACCSpecialTokenKind::Static:
203 llvm_unreachable(
"Unknown 'Kind' Passed");
210 if (Tok.
is(tok::identifier))
225template <
typename DirOrClauseTy>
226bool tryParseAndConsumeSpecialTokenKind(
Parser &
P, OpenACCSpecialTokenKind Kind,
227 DirOrClauseTy DirOrClause) {
228 Token IdentTok =
P.getCurToken();
231 if (isTokenIdentifierOrKeyword(
P, IdentTok) &&
P.NextToken().is(tok::colon)) {
235 if (!isOpenACCSpecialToken(Kind, IdentTok)) {
236 P.Diag(IdentTok, diag::err_acc_invalid_tag_kind)
238 << std::is_same_v<DirOrClauseTy, OpenACCClauseKind>;
249 if (!Tok.
is(tok::identifier))
253 case OpenACCDirectiveKind::Parallel:
255 case OpenACCDirectiveKind::Serial:
257 case OpenACCDirectiveKind::Kernels:
259 case OpenACCDirectiveKind::Data:
261 case OpenACCDirectiveKind::HostData:
263 case OpenACCDirectiveKind::Loop:
265 case OpenACCDirectiveKind::Cache:
268 case OpenACCDirectiveKind::ParallelLoop:
269 case OpenACCDirectiveKind::SerialLoop:
270 case OpenACCDirectiveKind::KernelsLoop:
271 case OpenACCDirectiveKind::EnterData:
272 case OpenACCDirectiveKind::ExitData:
275 case OpenACCDirectiveKind::Atomic:
277 case OpenACCDirectiveKind::Routine:
279 case OpenACCDirectiveKind::Declare:
281 case OpenACCDirectiveKind::Init:
283 case OpenACCDirectiveKind::Shutdown:
285 case OpenACCDirectiveKind::Set:
287 case OpenACCDirectiveKind::Update:
289 case OpenACCDirectiveKind::Wait:
291 case OpenACCDirectiveKind::Invalid:
294 llvm_unreachable(
"Unknown 'Kind' Passed");
301 if (
P.NextToken().isNot(tok::colon)) {
302 P.Diag(
P.getCurToken(), diag::err_acc_expected_reduction_operator);
303 return OpenACCReductionOperator::Invalid;
305 Token ReductionKindTok =
P.getCurToken();
310 switch (ReductionKindTok.
getKind()) {
312 return OpenACCReductionOperator::Addition;
314 return OpenACCReductionOperator::Multiplication;
316 return OpenACCReductionOperator::BitwiseAnd;
318 return OpenACCReductionOperator::BitwiseOr;
320 return OpenACCReductionOperator::BitwiseXOr;
322 return OpenACCReductionOperator::And;
324 return OpenACCReductionOperator::Or;
325 case tok::identifier:
327 return OpenACCReductionOperator::Max;
329 return OpenACCReductionOperator::Min;
332 P.Diag(ReductionKindTok, diag::err_acc_invalid_reduction_operator);
333 return OpenACCReductionOperator::Invalid;
335 llvm_unreachable(
"Reduction op token kind not caught by 'default'?");
340bool expectIdentifierOrKeyword(
Parser &
P) {
341 Token Tok =
P.getCurToken();
343 if (isTokenIdentifierOrKeyword(
P, Tok))
346 P.Diag(
P.getCurToken(), diag::err_expected) << tok::identifier;
351ParseOpenACCEnterExitDataDirective(
Parser &
P,
Token FirstTok,
352 OpenACCDirectiveKindEx ExtDirKind) {
353 Token SecondTok =
P.getCurToken();
356 P.Diag(FirstTok, diag::err_acc_invalid_directive)
358 return OpenACCDirectiveKind::Invalid;
365 if (!isOpenACCDirectiveKind(OpenACCDirectiveKind::Data, SecondTok)) {
366 if (!SecondTok.
is(tok::identifier))
367 P.Diag(SecondTok, diag::err_expected) << tok::identifier;
369 P.Diag(FirstTok, diag::err_acc_invalid_directive)
372 return OpenACCDirectiveKind::Invalid;
375 return ExtDirKind == OpenACCDirectiveKindEx::Enter
376 ? OpenACCDirectiveKind::EnterData
377 : OpenACCDirectiveKind::ExitData;
381 Token AtomicClauseToken =
P.getCurToken();
385 return OpenACCAtomicKind::Update;
392 if (AtomicKind == OpenACCAtomicKind::Invalid)
393 return OpenACCAtomicKind::Update;
401 Token FirstTok =
P.getCurToken();
405 if (FirstTok.
isNot(tok::identifier)) {
406 P.Diag(FirstTok, diag::err_acc_missing_directive);
408 if (
P.getCurToken().isNot(tok::annot_pragma_openacc_end))
411 return OpenACCDirectiveKind::Invalid;
416 OpenACCDirectiveKindEx ExDirKind = getOpenACCDirectiveKind(FirstTok);
424 if (ExDirKind >= OpenACCDirectiveKindEx::Invalid) {
426 case OpenACCDirectiveKindEx::Invalid: {
427 P.Diag(FirstTok, diag::err_acc_invalid_directive)
429 return OpenACCDirectiveKind::Invalid;
431 case OpenACCDirectiveKindEx::Enter:
432 case OpenACCDirectiveKindEx::Exit:
433 return ParseOpenACCEnterExitDataDirective(
P, FirstTok, ExDirKind);
442 Token SecondTok =
P.getCurToken();
444 isOpenACCDirectiveKind(OpenACCDirectiveKind::Loop, SecondTok)) {
450 case OpenACCDirectiveKind::Parallel:
452 return OpenACCDirectiveKind::ParallelLoop;
453 case OpenACCDirectiveKind::Serial:
455 return OpenACCDirectiveKind::SerialLoop;
456 case OpenACCDirectiveKind::Kernels:
458 return OpenACCDirectiveKind::KernelsLoop;
465enum ClauseParensKind {
474 case OpenACCClauseKind::Self:
475 return DirKind == OpenACCDirectiveKind::Update ? ClauseParensKind::Required
476 : ClauseParensKind::Optional;
477 case OpenACCClauseKind::Async:
478 case OpenACCClauseKind::Worker:
479 case OpenACCClauseKind::Vector:
480 case OpenACCClauseKind::Gang:
481 case OpenACCClauseKind::Wait:
482 return ClauseParensKind::Optional;
484 case OpenACCClauseKind::Default:
485 case OpenACCClauseKind::If:
486 case OpenACCClauseKind::Create:
487 case OpenACCClauseKind::Copy:
488 case OpenACCClauseKind::CopyIn:
489 case OpenACCClauseKind::CopyOut:
490 case OpenACCClauseKind::UseDevice:
491 case OpenACCClauseKind::NoCreate:
492 case OpenACCClauseKind::Present:
493 case OpenACCClauseKind::DevicePtr:
494 case OpenACCClauseKind::Attach:
495 case OpenACCClauseKind::Detach:
496 case OpenACCClauseKind::Private:
497 case OpenACCClauseKind::FirstPrivate:
498 case OpenACCClauseKind::Delete:
499 case OpenACCClauseKind::DeviceResident:
500 case OpenACCClauseKind::Device:
501 case OpenACCClauseKind::Link:
502 case OpenACCClauseKind::Host:
503 case OpenACCClauseKind::Reduction:
504 case OpenACCClauseKind::Collapse:
505 case OpenACCClauseKind::Bind:
506 case OpenACCClauseKind::VectorLength:
507 case OpenACCClauseKind::NumGangs:
508 case OpenACCClauseKind::NumWorkers:
509 case OpenACCClauseKind::DeviceNum:
510 case OpenACCClauseKind::DefaultAsync:
511 case OpenACCClauseKind::DeviceType:
512 case OpenACCClauseKind::DType:
513 case OpenACCClauseKind::Tile:
514 return ClauseParensKind::Required;
516 case OpenACCClauseKind::Auto:
517 case OpenACCClauseKind::Finalize:
518 case OpenACCClauseKind::IfPresent:
519 case OpenACCClauseKind::Independent:
520 case OpenACCClauseKind::Invalid:
521 case OpenACCClauseKind::NoHost:
522 case OpenACCClauseKind::Seq:
523 return ClauseParensKind::None;
525 llvm_unreachable(
"Unhandled clause kind");
530 return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Optional;
535 return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Required;
542void SkipUntilEndOfDirective(
Parser &
P) {
543 while (
P.getCurToken().isNot(tok::annot_pragma_openacc_end))
551 case OpenACCDirectiveKind::Parallel:
552 case OpenACCDirectiveKind::Serial:
553 case OpenACCDirectiveKind::Kernels:
556 llvm_unreachable(
"Unhandled directive->assoc stmt");
561 case OpenACCDirectiveKind::Parallel:
562 case OpenACCDirectiveKind::Serial:
563 case OpenACCDirectiveKind::Kernels:
568 case OpenACCDirectiveKind::Invalid:
569 llvm_unreachable(
"Shouldn't be creating a scope for an invalid construct");
578Parser::OpenACCClauseParseResult Parser::OpenACCCanContinue() {
579 return {
nullptr, OpenACCParseCanContinue::Can};
582Parser::OpenACCClauseParseResult Parser::OpenACCCannotContinue() {
583 return {
nullptr, OpenACCParseCanContinue::Cannot};
586Parser::OpenACCClauseParseResult Parser::OpenACCSuccess(
OpenACCClause *Clause) {
587 return {Clause, OpenACCParseCanContinue::Can};
590ExprResult Parser::ParseOpenACCConditionExpr() {
615 bool FirstClause =
true;
616 while (
getCurToken().isNot(tok::annot_pragma_openacc_end)) {
622 OpenACCClauseParseResult
Result = ParseOpenACCClause(Clauses, DirKind);
624 Clauses.push_back(Clause);
625 }
else if (
Result.getInt() == OpenACCParseCanContinue::Cannot) {
628 SkipUntilEndOfDirective(*
this);
635Parser::OpenACCIntExprParseResult
643 return {ER, OpenACCParseCanContinue::Cannot};
649 return {ER, OpenACCParseCanContinue::Can};
652 OpenACCParseCanContinue::Can};
658 OpenACCIntExprParseResult CurResult = ParseOpenACCIntExpr(DK, CK, Loc);
660 if (!CurResult.first.isUsable() &&
661 CurResult.second == OpenACCParseCanContinue::Cannot) {
662 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
667 IntExprs.push_back(CurResult.first.get());
670 ExpectAndConsume(tok::comma);
672 CurResult = ParseOpenACCIntExpr(DK, CK, Loc);
674 if (!CurResult.first.isUsable() &&
675 CurResult.second == OpenACCParseCanContinue::Cannot) {
676 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
680 IntExprs.push_back(CurResult.first.get());
693 if (ParseOpenACCVar())
697 ExpectAndConsume(tok::comma);
701 if (ParseOpenACCVar())
716bool Parser::ParseOpenACCDeviceTypeList() {
718 if (expectIdentifierOrKeyword(*
this)) {
719 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,
744bool Parser::ParseOpenACCSizeExpr() {
751 tok::annot_pragma_openacc_end)) {
761bool Parser::ParseOpenACCSizeExprList() {
762 if (ParseOpenACCSizeExpr()) {
763 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
769 ExpectAndConsume(tok::comma);
771 if (ParseOpenACCSizeExpr()) {
772 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
788 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Static,
getCurToken()) &&
793 return ParseOpenACCSizeExpr();
796 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Dim,
getCurToken()) &&
805 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Num,
getCurToken()) &&
818 if (ParseOpenACCGangArg(GangLoc)) {
819 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
825 ExpectAndConsume(tok::comma);
827 if (ParseOpenACCGangArg(GangLoc)) {
828 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
841Parser::OpenACCClauseParseResult
846 if (expectIdentifierOrKeyword(*
this))
847 return OpenACCCannotContinue();
854 return OpenACCCannotContinue();
860 return ParseOpenACCClauseParams(ExistingClauses, DirKind, Kind, ClauseLoc);
863Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
868 tok::annot_pragma_openacc_end);
871 if (ClauseHasRequiredParens(DirKind, ClauseKind)) {
873 if (
Parens.expectAndConsume()) {
877 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openacc_end,
879 return OpenACCCanContinue();
882 switch (ClauseKind) {
886 if (expectIdentifierOrKeyword(*
this)) {
888 return OpenACCCanContinue();
894 getOpenACCDefaultClauseKind(DefKindTok);
897 Diag(DefKindTok, diag::err_acc_invalid_default_clause_kind);
899 return OpenACCCanContinue();
906 ExprResult CondExpr = ParseOpenACCConditionExpr();
912 return OpenACCCanContinue();
918 tryParseAndConsumeSpecialTokenKind(
919 *
this, OpenACCSpecialTokenKind::ReadOnly, ClauseKind);
920 if (ParseOpenACCClauseVarList(ClauseKind)) {
922 return OpenACCCanContinue();
927 tryParseAndConsumeSpecialTokenKind(*
this, OpenACCSpecialTokenKind::Zero,
929 if (ParseOpenACCClauseVarList(ClauseKind)) {
931 return OpenACCCanContinue();
937 ParseReductionOperator(*
this);
938 if (ParseOpenACCClauseVarList(ClauseKind)) {
940 return OpenACCCanContinue();
963 if (ParseOpenACCClauseVarList(ClauseKind)) {
965 return OpenACCCanContinue();
969 tryParseAndConsumeSpecialTokenKind(*
this, OpenACCSpecialTokenKind::Force,
975 return OpenACCCanContinue();
980 ExprResult BindArg = ParseOpenACCBindClauseArgument();
983 return OpenACCCanContinue();
994 return OpenACCCanContinue();
1004 ClauseKind, ClauseLoc)
1008 return OpenACCCanContinue();
1025 }
else if (ParseOpenACCDeviceTypeList()) {
1027 return OpenACCCanContinue();
1031 if (ParseOpenACCSizeExprList()) {
1033 return OpenACCCanContinue();
1037 llvm_unreachable(
"Not a required parens type?");
1042 if (
Parens.consumeClose())
1043 return OpenACCCannotContinue();
1045 }
else if (ClauseHasOptionalParens(DirKind, ClauseKind)) {
1047 if (!
Parens.consumeOpen()) {
1048 switch (ClauseKind) {
1051 ExprResult CondExpr = ParseOpenACCConditionExpr();
1057 return OpenACCCanContinue();
1063 tryParseAndConsumeSpecialTokenKind(*
this,
1066 ? OpenACCSpecialTokenKind::Length
1067 : OpenACCSpecialTokenKind::Num,
1070 ClauseKind, ClauseLoc)
1074 return OpenACCCanContinue();
1079 ExprResult AsyncArg = ParseOpenACCAsyncArgument();
1082 return OpenACCCanContinue();
1087 if (ParseOpenACCGangArgList(ClauseLoc)) {
1089 return OpenACCCanContinue();
1093 if (ParseOpenACCWaitArgument(ClauseLoc,
1096 return OpenACCCanContinue();
1100 llvm_unreachable(
"Not an optional parens type?");
1103 if (
Parens.consumeClose())
1104 return OpenACCCannotContinue();
1107 return OpenACCSuccess(
1118ExprResult Parser::ParseOpenACCAsyncArgument() {
1126bool Parser::ParseOpenACCWaitArgument(
SourceLocation Loc,
bool IsDirective) {
1128 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::DevNum, Tok) &&
1145 if (ExpectAndConsume(tok::colon))
1150 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Queues, Tok) &&
1162 bool FirstArg =
true;
1165 if (ExpectAndConsume(tok::comma))
1170 ExprResult CurArg = ParseOpenACCAsyncArgument();
1179ExprResult Parser::ParseOpenACCIDExpression() {
1182 Res = ParseCXXIdExpression(
true);
1187 if (Tok.
isNot(tok::identifier)) {
1188 Diag(Tok, diag::err_expected) << tok::identifier;
1209ExprResult Parser::ParseOpenACCBindClauseArgument() {
1225 return ParseOpenACCIDExpression();
1235bool Parser::ParseOpenACCVar() {
1236 OpenACCArraySectionRAII ArraySections(*
this);
1246void Parser::ParseOpenACCCacheVarList() {
1255 if (tryParseAndConsumeSpecialTokenKind(*
this,
1256 OpenACCSpecialTokenKind::ReadOnly,
1262 bool FirstArray =
true;
1265 ExpectAndConsume(tok::comma);
1276 if (ParseOpenACCVar())
1277 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, tok::comma,
1282Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() {
1292 ParseOpenACCAtomicKind(*
this);
1297 tok::annot_pragma_openacc_end);
1299 if (!
T.consumeOpen()) {
1302 Diag(
T.getOpenLocation(), diag::err_acc_invalid_open_paren);
1308 ExprResult RoutineName = ParseOpenACCIDExpression();
1318 ParseOpenACCCacheVarList();
1325 if (ParseOpenACCWaitArgument(StartLoc,
true))
1335 Diag(Tok, diag::err_expected) << tok::l_paren;
1339 OpenACCDirectiveParseInfo ParseInfo{DirKind, StartLoc,
SourceLocation{},
1340 ParseOpenACCClauseList(DirKind)};
1342 assert(Tok.
is(tok::annot_pragma_openacc_end) &&
1343 "Didn't parse all OpenACC Clauses");
1344 ParseInfo.EndLoc = ConsumeAnnotationToken();
1345 assert(ParseInfo.EndLoc.isValid() &&
1346 "Terminating annotation token not present");
1353 assert(Tok.
is(tok::annot_pragma_openacc) &&
"expected OpenACC Start Token");
1356 ConsumeAnnotationToken();
1358 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
1360 if (
getActions().OpenACC().ActOnStartDeclDirective(DirInfo.DirKind,
1370 assert(Tok.
is(tok::annot_pragma_openacc) &&
"expected OpenACC Start Token");
1373 ConsumeAnnotationToken();
1375 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
1376 if (
getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind,
1382 if (doesDirectiveHaveAssociatedStmt(DirInfo.DirKind)) {
1384 ParseScope ACCScope(
this, getOpenACCScopeFlags(DirInfo.DirKind));
1391 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 setDefaultDetails(OpenACCDefaultClauseKind DefKind)
void setEndLoc(SourceLocation EndLoc)
void setIntExprDetails(ArrayRef< Expr * > IntExprs)
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 isOneOf(tok::TokenKind K1, tok::TokenKind K2) 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.