19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
22 using namespace clang;
29 enum class OpenACCDirectiveKindEx {
41 OpenACCDirectiveKindEx getOpenACCDirectiveKind(
Token Tok) {
42 if (!Tok.
is(tok::identifier))
43 return OpenACCDirectiveKindEx::Invalid;
45 llvm::StringSwitch<OpenACCDirectiveKind>(
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))
82 if (Tok.
is(tok::kw_default))
86 if (Tok.
is(tok::kw_if))
90 if (Tok.
is(tok::kw_private))
93 if (!Tok.
is(tok::identifier))
96 return llvm::StringSwitch<OpenACCClauseKind>(
154 if (!Tok.
is(tok::identifier))
156 return llvm::StringSwitch<OpenACCAtomicKind>(
166 if (!Tok.
is(tok::identifier))
169 return llvm::StringSwitch<OpenACCDefaultClauseKind>(
176 enum class OpenACCSpecialTokenKind {
188 bool 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:
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))
237 template <
typename DirOrClauseTy>
238 bool 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))
306 llvm_unreachable(
"Unknown 'Kind' Passed");
313 if (
P.NextToken().isNot(tok::colon)) {
314 P.Diag(
P.getCurToken(), diag::err_acc_expected_reduction_operator);
317 Token ReductionKindTok =
P.getCurToken();
322 switch (ReductionKindTok.
getKind()) {
337 case tok::identifier:
344 P.Diag(ReductionKindTok, diag::err_acc_invalid_reduction_operator);
347 llvm_unreachable(
"Reduction op token kind not caught by 'default'?");
352 bool expectIdentifierOrKeyword(
Parser &
P) {
353 Token Tok =
P.getCurToken();
355 if (isTokenIdentifierOrKeyword(
P, Tok))
358 P.Diag(
P.getCurToken(), diag::err_expected) << tok::identifier;
363 ParseOpenACCEnterExitDataDirective(
Parser &
P,
Token FirstTok,
364 OpenACCDirectiveKindEx ExtDirKind) {
365 Token SecondTok =
P.getCurToken();
368 P.Diag(FirstTok, diag::err_acc_invalid_directive)
378 if (!SecondTok.
is(tok::identifier))
379 P.Diag(SecondTok, diag::err_expected) << tok::identifier;
381 P.Diag(FirstTok, diag::err_acc_invalid_directive)
387 return ExtDirKind == OpenACCDirectiveKindEx::Enter
393 Token AtomicClauseToken =
P.getCurToken();
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))
428 OpenACCDirectiveKindEx ExDirKind = getOpenACCDirectiveKind(FirstTok);
436 if (ExDirKind >= OpenACCDirectiveKindEx::Invalid) {
438 case OpenACCDirectiveKindEx::Invalid: {
439 P.Diag(FirstTok, diag::err_acc_invalid_directive)
443 case OpenACCDirectiveKindEx::Enter:
444 case OpenACCDirectiveKindEx::Exit:
445 return ParseOpenACCEnterExitDataDirective(
P, FirstTok, ExDirKind);
454 Token SecondTok =
P.getCurToken();
477 enum ClauseParensKind {
488 : ClauseParensKind::Optional;
494 return ClauseParensKind::Optional;
534 return ClauseParensKind::Required;
545 llvm_unreachable(
"Unhandled clause kind");
550 return getClauseParensKind(DirKind,
Kind) == ClauseParensKind::Optional;
555 return getClauseParensKind(DirKind,
Kind) == ClauseParensKind::Required;
562 void SkipUntilEndOfDirective(
Parser &
P) {
563 while (
P.getCurToken().isNot(tok::annot_pragma_openacc_end))
576 llvm_unreachable(
"Unhandled directive->assoc stmt");
589 llvm_unreachable(
"Shouldn't be creating a scope for an invalid construct");
598 Parser::OpenACCClauseParseResult Parser::OpenACCCanContinue() {
599 return {
nullptr, OpenACCParseCanContinue::Can};
602 Parser::OpenACCClauseParseResult Parser::OpenACCCannotContinue() {
603 return {
nullptr, OpenACCParseCanContinue::Cannot};
606 Parser::OpenACCClauseParseResult Parser::OpenACCSuccess(
OpenACCClause *Clause) {
607 return {Clause, OpenACCParseCanContinue::Can};
610 ExprResult Parser::ParseOpenACCConditionExpr() {
615 ExprResult ER = getActions().CorrectDelayedTyposInExpr(ParseExpression());
621 getActions().ActOnCondition(getCurScope(), ER.
get()->
getExprLoc(),
635 bool FirstClause =
true;
636 while (getCurToken().isNot(tok::annot_pragma_openacc_end)) {
638 if (!FirstClause && getCurToken().is(tok::comma))
642 OpenACCClauseParseResult Result = ParseOpenACCClause(Clauses, DirKind);
644 Clauses.push_back(Clause);
645 }
else if (Result.getInt() == OpenACCParseCanContinue::Cannot) {
648 SkipUntilEndOfDirective(*
this);
655 Parser::OpenACCIntExprParseResult
663 return {ER, OpenACCParseCanContinue::Cannot};
667 ER = getActions().CorrectDelayedTyposInExpr(ER);
669 return {ER, OpenACCParseCanContinue::Can};
671 return {getActions().OpenACC().ActOnIntExpr(DK, CK,
Loc, ER.
get()),
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());
689 while (!getCurToken().
isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
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());
714 bool Parser::ParseOpenACCDeviceTypeList(
717 if (expectIdentifierOrKeyword(*
this)) {
718 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
723 Archs.emplace_back(Ident, ConsumeToken());
725 while (!getCurToken().
isOneOf(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,
733 Ident = getCurToken().getIdentifierInfo();
734 Archs.emplace_back(Ident, ConsumeToken());
745 bool Parser::ParseOpenACCSizeExpr() {
750 if (getCurToken().is(tok::star) &&
751 NextToken().
isOneOf(tok::comma, tok::r_paren,
752 tok::annot_pragma_openacc_end)) {
758 .CorrectDelayedTyposInExpr(ParseAssignmentExpression())
762 bool Parser::ParseOpenACCSizeExprList() {
763 if (ParseOpenACCSizeExpr()) {
764 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
769 while (!getCurToken().
isOneOf(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()) &&
790 NextToken().is(tok::colon)) {
794 return ParseOpenACCSizeExpr();
797 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Dim, getCurToken()) &&
798 NextToken().is(tok::colon)) {
806 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Num, getCurToken()) &&
807 NextToken().is(tok::colon)) {
819 if (ParseOpenACCGangArg(GangLoc)) {
820 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
825 while (!getCurToken().
isOneOf(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,
842 Parser::OpenACCClauseParseResult
847 if (expectIdentifierOrKeyword(*
this))
848 return OpenACCCannotContinue();
853 Diag(getCurToken(), diag::err_acc_invalid_clause)
854 << getCurToken().getIdentifierInfo();
855 return OpenACCCannotContinue();
861 return ParseOpenACCClauseParams(ExistingClauses, DirKind,
Kind, ClauseLoc);
864 Parser::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) {
885 Token DefKindTok = getCurToken();
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);
934 bool IsZero = tryParseAndConsumeSpecialTokenKind(
960 ParseOpenACCVarList(ClauseKind);
978 tryParseAndConsumeSpecialTokenKind(*
this, OpenACCSpecialTokenKind::Force,
981 getActions().CorrectDelayedTyposInExpr(ParseConstantExpression());
984 return OpenACCCanContinue();
989 ExprResult BindArg = ParseOpenACCBindClauseArgument();
992 return OpenACCCanContinue();
1003 return OpenACCCanContinue();
1013 ClauseKind, ClauseLoc)
1017 return OpenACCCanContinue();
1031 if (getCurToken().is(tok::star)) {
1035 }
else if (!ParseOpenACCDeviceTypeList(Archs)) {
1039 return OpenACCCanContinue();
1044 if (ParseOpenACCSizeExprList()) {
1046 return OpenACCCanContinue();
1050 llvm_unreachable(
"Not a required parens type?");
1053 ParsedClause.
setEndLoc(getCurToken().getLocation());
1055 if (
Parens.consumeClose())
1056 return OpenACCCannotContinue();
1058 }
else if (ClauseHasOptionalParens(DirKind, ClauseKind)) {
1059 if (!
Parens.consumeOpen()) {
1061 switch (ClauseKind) {
1064 ExprResult CondExpr = ParseOpenACCConditionExpr();
1070 return OpenACCCanContinue();
1076 tryParseAndConsumeSpecialTokenKind(*
this,
1079 ? OpenACCSpecialTokenKind::Length
1080 : OpenACCSpecialTokenKind::Num,
1083 ClauseKind, ClauseLoc)
1087 return OpenACCCanContinue();
1100 return OpenACCCanContinue();
1105 if (ParseOpenACCGangArgList(ClauseLoc)) {
1107 return OpenACCCanContinue();
1111 OpenACCWaitParseInfo Info =
1112 ParseOpenACCWaitArgument(ClauseLoc,
1116 return OpenACCCanContinue();
1120 std::move(Info.QueueIdExprs));
1124 llvm_unreachable(
"Not an optional parens type?");
1126 ParsedClause.
setEndLoc(getCurToken().getLocation());
1127 if (
Parens.consumeClose())
1128 return OpenACCCannotContinue();
1135 return OpenACCSuccess(
1136 Actions.OpenACC().ActOnClause(ExistingClauses, ParsedClause));
1146 Parser::OpenACCIntExprParseResult
1149 return ParseOpenACCIntExpr(DK, CK,
Loc);
1156 Parser::OpenACCWaitParseInfo
1158 OpenACCWaitParseInfo Result;
1160 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::DevNum, Tok) &&
1161 NextToken().is(tok::colon)) {
1167 OpenACCIntExprParseResult Res = ParseOpenACCIntExpr(
1172 if (Res.first.isInvalid() &&
1173 Res.second == OpenACCParseCanContinue::Cannot) {
1174 Result.Failed =
true;
1178 if (ExpectAndConsume(tok::colon)) {
1179 Result.Failed =
true;
1183 Result.DevNumExpr = Res.first.get();
1187 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Queues, Tok) &&
1188 NextToken().is(tok::colon)) {
1190 Result.QueuesLoc = ConsumeToken();
1199 bool FirstArg =
true;
1200 while (!getCurToken().
isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
1202 if (ExpectAndConsume(tok::comma)) {
1203 Result.Failed =
true;
1209 OpenACCIntExprParseResult Res = ParseOpenACCAsyncArgument(
1215 if (Res.first.isInvalid() &&
1216 Res.second == OpenACCParseCanContinue::Cannot) {
1217 Result.Failed =
true;
1221 Result.QueueIdExprs.push_back(Res.first.get());
1227 ExprResult Parser::ParseOpenACCIDExpression() {
1230 Res = ParseCXXIdExpression(
true);
1235 if (Tok.
isNot(tok::identifier)) {
1236 Diag(Tok, diag::err_expected) << tok::identifier;
1240 Token FuncName = getCurToken();
1249 Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc,
1254 return getActions().CorrectDelayedTyposInExpr(Res);
1257 ExprResult Parser::ParseOpenACCBindClauseArgument() {
1264 if (getCurToken().is(tok::r_paren)) {
1265 Diag(getCurToken(), diag::err_acc_incorrect_bind_arg);
1270 return getActions().CorrectDelayedTyposInExpr(ParseStringLiteralExpression(
1273 return ParseOpenACCIDExpression();
1284 OpenACCArraySectionRAII ArraySections(*
this);
1286 ExprResult Res = ParseAssignmentExpression();
1288 return {Res, OpenACCParseCanContinue::Cannot};
1290 Res = getActions().CorrectDelayedTyposInExpr(Res.
get());
1292 return {Res, OpenACCParseCanContinue::Can};
1294 Res = getActions().OpenACC().ActOnVar(CK, Res.
get());
1296 return {Res, OpenACCParseCanContinue::Can};
1302 auto [Res, CanContinue] = ParseOpenACCVar(CK);
1304 Vars.push_back(Res.
get());
1305 }
else if (CanContinue == OpenACCParseCanContinue::Cannot) {
1306 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, StopBeforeMatch);
1310 while (!getCurToken().
isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
1311 ExpectAndConsume(tok::comma);
1313 auto [Res, CanContinue] = ParseOpenACCVar(CK);
1316 Vars.push_back(Res.
get());
1317 }
else if (CanContinue == OpenACCParseCanContinue::Cannot) {
1318 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, StopBeforeMatch);
1329 void Parser::ParseOpenACCCacheVarList() {
1338 if (tryParseAndConsumeSpecialTokenKind(*
this,
1339 OpenACCSpecialTokenKind::ReadOnly,
1350 Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() {
1354 getActions().OpenACC().ActOnConstruct(DirKind, StartLoc);
1360 ParseOpenACCAtomicKind(*
this);
1365 tok::annot_pragma_openacc_end);
1367 if (!
T.consumeOpen()) {
1370 Diag(
T.getOpenLocation(), diag::err_acc_invalid_open_paren);
1376 ExprResult RoutineName = ParseOpenACCIDExpression();
1386 ParseOpenACCCacheVarList();
1393 if (ParseOpenACCWaitArgument(StartLoc,
true).Failed)
1403 Diag(Tok, diag::err_expected) << tok::l_paren;
1407 OpenACCDirectiveParseInfo ParseInfo{DirKind, StartLoc,
SourceLocation{},
1408 ParseOpenACCClauseList(DirKind)};
1410 assert(Tok.
is(tok::annot_pragma_openacc_end) &&
1411 "Didn't parse all OpenACC Clauses");
1412 ParseInfo.EndLoc = ConsumeAnnotationToken();
1413 assert(ParseInfo.EndLoc.isValid() &&
1414 "Terminating annotation token not present");
1421 assert(Tok.
is(tok::annot_pragma_openacc) &&
"expected OpenACC Start Token");
1424 ConsumeAnnotationToken();
1426 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
1428 if (getActions().OpenACC().ActOnStartDeclDirective(DirInfo.DirKind,
1433 return DeclGroupPtrTy::make(getActions().OpenACC().ActOnEndDeclDirective());
1438 assert(Tok.
is(tok::annot_pragma_openacc) &&
"expected OpenACC Start Token");
1441 ConsumeAnnotationToken();
1443 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
1444 if (getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind,
1450 if (doesDirectiveHaveAssociatedStmt(DirInfo.DirKind)) {
1452 ParseScope ACCScope(
this, getOpenACCScopeFlags(DirInfo.DirKind));
1454 AssocStmt = getActions().OpenACC().ActOnAssociatedStmt(DirInfo.DirKind,
1458 return getActions().OpenACC().ActOnEndStmtDirective(
1459 DirInfo.DirKind, DirInfo.StartLoc, DirInfo.EndLoc, DirInfo.Clauses,
static Decl::Kind getKind(const Decl *D)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines some OpenACC-specific enums and functions.
constexpr static 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.
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.
DeclGroupPtrTy ParseOpenACCDirectiveDecl()
Placeholder for now, should just ignore the directives after emitting a diagnostic.
StmtResult ParseOpenACCDirectiveStmt()
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
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 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)
@ Boolean
A boolean condition, from 'if', 'while', 'for', or 'do'.
Encodes a location in the source.
Token - This structure provides full information about a lexed token.
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
IdentifierInfo * getIdentifierInfo() 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.
constexpr XRayInstrMask None
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.
@ Auto
'auto' clause, allowed on 'loop' directives.
@ 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.
@ NoHost
'nohost' clause, allowed on 'routine' directives.
@ 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',...
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
@ 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.
@ Independent
'independent' clause, allowed on 'loop' directives.
@ NumWorkers
'num_workers' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs...
@ IfPresent
'if_present' clause, allowed on 'host_data' and 'update' directives.
@ 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'.
@ Finalize
'finalize' clause, allowed on 'exit data' directive.
@ Invalid
Not a valid option.
@ Present
'present' option.
const FunctionProtoType * T
@ Invalid
Invalid Reduction Clause Kind.
@ Parens
New-expression has a C++98 paren-delimited initializer.
Diagnostic wrappers for TextAPI types for error reporting.