20 #include "llvm/ADT/PointerIntPair.h" 22 using namespace clang;
42 OMPD_distribute_parallel,
43 OMPD_teams_distribute_parallel,
44 OMPD_target_teams_distribute_parallel
47 class ThreadprivateListParserHelper final {
52 ThreadprivateListParserHelper(
Parser *P) :
P(P) {}
57 Identifiers.push_back(Res.
get());
70 return llvm::StringSwitch<unsigned>(S)
71 .Case(
"cancellation", OMPD_cancellation)
72 .Case(
"data", OMPD_data)
73 .Case(
"declare", OMPD_declare)
74 .Case(
"end", OMPD_end)
75 .Case(
"enter", OMPD_enter)
76 .Case(
"exit", OMPD_exit)
77 .Case(
"point", OMPD_point)
78 .Case(
"reduction", OMPD_reduction)
79 .Case(
"update", OMPD_update)
87 static const unsigned F[][3] = {
88 { OMPD_cancellation, OMPD_point, OMPD_cancellation_point },
89 { OMPD_declare, OMPD_reduction, OMPD_declare_reduction },
90 { OMPD_declare, OMPD_simd, OMPD_declare_simd },
91 { OMPD_declare, OMPD_target, OMPD_declare_target },
92 { OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel },
93 { OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for },
94 { OMPD_distribute_parallel_for, OMPD_simd,
95 OMPD_distribute_parallel_for_simd },
96 { OMPD_distribute, OMPD_simd, OMPD_distribute_simd },
97 { OMPD_end, OMPD_declare, OMPD_end_declare },
98 { OMPD_end_declare, OMPD_target, OMPD_end_declare_target },
99 { OMPD_target, OMPD_data, OMPD_target_data },
100 { OMPD_target, OMPD_enter, OMPD_target_enter },
101 { OMPD_target, OMPD_exit, OMPD_target_exit },
102 { OMPD_target, OMPD_update, OMPD_target_update },
103 { OMPD_target_enter, OMPD_data, OMPD_target_enter_data },
104 { OMPD_target_exit, OMPD_data, OMPD_target_exit_data },
105 { OMPD_for, OMPD_simd, OMPD_for_simd },
106 { OMPD_parallel, OMPD_for, OMPD_parallel_for },
107 { OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd },
108 { OMPD_parallel, OMPD_sections, OMPD_parallel_sections },
109 { OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd },
110 { OMPD_target, OMPD_parallel, OMPD_target_parallel },
111 { OMPD_target, OMPD_simd, OMPD_target_simd },
112 { OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for },
113 { OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd },
114 { OMPD_teams, OMPD_distribute, OMPD_teams_distribute },
115 { OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd },
116 { OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel },
117 { OMPD_teams_distribute_parallel, OMPD_for, OMPD_teams_distribute_parallel_for },
118 { OMPD_teams_distribute_parallel_for, OMPD_simd, OMPD_teams_distribute_parallel_for_simd },
119 { OMPD_target, OMPD_teams, OMPD_target_teams },
120 { OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute },
121 { OMPD_target_teams_distribute, OMPD_parallel, OMPD_target_teams_distribute_parallel },
122 { OMPD_target_teams_distribute, OMPD_simd, OMPD_target_teams_distribute_simd },
123 { OMPD_target_teams_distribute_parallel, OMPD_for, OMPD_target_teams_distribute_parallel_for },
124 { OMPD_target_teams_distribute_parallel_for, OMPD_simd, OMPD_target_teams_distribute_parallel_for_simd }
126 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
135 for (
unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
136 if (DKind != F[i][0])
147 if (SDKind == F[i][1]) {
152 return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
161 bool WithOperator =
false;
162 if (Tok.
is(tok::kw_operator)) {
192 case tok::identifier:
197 P.
Diag(Tok.
getLocation(), diag::err_omp_expected_reduction_identifier);
198 P.
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
205 : DeclNames.getCXXOperatorName(OOK);
224 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
225 return DeclGroupPtrTy();
229 if (Name.
isEmpty() &&
Tok.
is(tok::annot_pragma_openmp_end))
230 return DeclGroupPtrTy();
233 bool IsCorrect = !ExpectAndConsume(tok::colon);
235 if (!IsCorrect &&
Tok.
is(tok::annot_pragma_openmp_end))
236 return DeclGroupPtrTy();
238 IsCorrect = IsCorrect && !Name.
isEmpty();
240 if (
Tok.
is(tok::colon) ||
Tok.
is(tok::annot_pragma_openmp_end)) {
241 Diag(
Tok.getLocation(), diag::err_expected_type);
245 if (!IsCorrect &&
Tok.
is(tok::annot_pragma_openmp_end))
246 return DeclGroupPtrTy();
257 Actions.ActOnOpenMPDeclareReductionType(Range.
getBegin(), TR);
258 if (!ReductionType.isNull()) {
259 ReductionTypes.push_back(
260 std::make_pair(ReductionType, Range.
getBegin()));
263 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
267 if (
Tok.
is(tok::colon) ||
Tok.
is(tok::annot_pragma_openmp_end))
271 if (ExpectAndConsume(tok::comma)) {
273 if (
Tok.
is(tok::annot_pragma_openmp_end)) {
274 Diag(
Tok.getLocation(), diag::err_expected_type);
275 return DeclGroupPtrTy();
278 }
while (
Tok.
isNot(tok::annot_pragma_openmp_end));
280 if (ReductionTypes.empty()) {
281 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
282 return DeclGroupPtrTy();
285 if (!IsCorrect &&
Tok.
is(tok::annot_pragma_openmp_end))
286 return DeclGroupPtrTy();
289 if (ExpectAndConsume(tok::colon))
292 if (
Tok.
is(tok::annot_pragma_openmp_end)) {
293 Diag(
Tok.getLocation(), diag::err_expected_expression);
294 return DeclGroupPtrTy();
297 DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
298 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
302 unsigned I = 0, E = ReductionTypes.size();
303 for (
auto *D : DRD.get()) {
304 TentativeParsingAction TPA(*
this);
309 Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
311 Actions.ActOnFinishFullExpr(ParseAssignmentExpression().
get(),
312 D->getLocation(),
true);
313 Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.
get());
316 Tok.
isNot(tok::annot_pragma_openmp_end)) {
323 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
325 if (
Tok.
is(tok::identifier) &&
326 Tok.getIdentifierInfo()->isStr(
"initializer"))
329 Diag(
Tok.getLocation(), diag::err_expected) <<
"'initializer'";
336 tok::annot_pragma_openmp_end);
340 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
346 Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
349 if (
Tok.
is(tok::identifier) &&
350 Tok.getIdentifierInfo()->isStr(
"omp_priv")) {
352 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
354 InitializerResult = Actions.ActOnFinishFullExpr(
355 ParseAssignmentExpression().
get(), D->getLocation(),
358 Actions.ActOnOpenMPDeclareReductionInitializerEnd(
359 D, InitializerResult.
get(), OmpPrivParm);
361 Tok.
isNot(tok::annot_pragma_openmp_end)) {
379 return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
383 void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
386 if (isTokenEqualOrEqualTypo()) {
389 if (
Tok.
is(tok::code_completion)) {
390 Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
391 Actions.FinalizeDeclaration(OmpPrivParm);
399 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
400 Actions.ActOnInitializerError(OmpPrivParm);
402 Actions.AddInitializerToDecl(OmpPrivParm, Init.
get(),
405 }
else if (
Tok.
is(tok::l_paren)) {
411 CommaLocsTy CommaLocs;
413 if (ParseExpressionList(Exprs, CommaLocs, [
this, OmpPrivParm, &Exprs] {
414 Actions.CodeCompleteConstructor(
418 Actions.ActOnInitializerError(OmpPrivParm);
419 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
424 assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
425 "Unexpected number of commas!");
427 ExprResult Initializer = Actions.ActOnParenListExpr(
429 Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
432 }
else if (getLangOpts().CPlusPlus11 &&
Tok.
is(tok::l_brace)) {
434 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
439 Actions.ActOnInitializerError(OmpPrivParm);
441 Actions.AddInitializerToDecl(OmpPrivParm, Init.
get(),
445 Actions.ActOnUninitializedDecl(OmpPrivParm);
455 class FNContextRAII final {
460 bool HasTemplateScope =
false;
461 bool HasFunScope =
false;
462 FNContextRAII() =
delete;
463 FNContextRAII(
const FNContextRAII &) =
delete;
464 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
481 if (HasTemplateScope)
482 Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
490 Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
497 if (HasTemplateScope)
520 bool IsError =
false;
521 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
522 if (Tok.
isNot(tok::identifier))
524 OMPDeclareSimdDeclAttr::BranchStateTy Out;
526 StringRef ClauseName = II->
getName();
528 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
529 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
530 P.
Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
532 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
538 }
else if (ClauseName.equals(
"simdlen")) {
540 P.
Diag(Tok, diag::err_omp_more_one_clause)
552 CKind == OMPC_linear) {
554 auto *Vars = &Uniforms;
555 if (CKind == OMPC_aligned)
557 else if (CKind == OMPC_linear)
564 if (CKind == OMPC_aligned)
565 Alignments.append(Aligneds.size() - Alignments.size(), Data.
TailExpr);
566 else if (CKind == OMPC_linear) {
569 Data.
LinKind = OMPC_LINEAR_val;
570 LinModifiers.append(Linears.size() - LinModifiers.size(),
572 Steps.append(Linears.size() - Steps.size(), Data.
TailExpr);
579 if (Tok.
is(tok::comma))
590 PP.EnterTokenStream(Toks,
true);
592 ConsumeAnyToken(
true);
594 FNContextRAII FnContext(*
this, Ptr);
595 OMPDeclareSimdDeclAttr::BranchStateTy BS =
596 OMPDeclareSimdDeclAttr::BS_Undefined;
606 Alignments, Linears, LinModifiers, Steps);
608 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
609 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
611 while (
Tok.
isNot(tok::annot_pragma_openmp_end))
617 return Actions.ActOnOpenMPDeclareSimdDirective(
618 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
642 assert(
Tok.
is(tok::annot_pragma_openmp) &&
"Not an OpenMP directive!");
649 case OMPD_threadprivate: {
651 ThreadprivateListParserHelper Helper(
this);
652 if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper,
true)) {
655 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
656 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
658 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
661 ConsumeAnnotationToken();
662 return Actions.ActOnOpenMPThreadprivateDirective(Loc,
663 Helper.getIdentifiers());
667 case OMPD_declare_reduction:
669 if (
auto Res = ParseOpenMPDeclareReductionDirective(AS)) {
672 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
673 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
675 while (
Tok.
isNot(tok::annot_pragma_openmp_end))
679 ConsumeAnnotationToken();
683 case OMPD_declare_simd: {
690 while(
Tok.
isNot(tok::annot_pragma_openmp_end)) {
698 if (
Tok.
is(tok::annot_pragma_openmp))
699 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs,
TagType, Tag);
700 else if (
Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
704 MaybeParseCXX11Attributes(Attrs);
706 Ptr = ParseExternalDeclaration(Attrs, &PDS);
709 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs,
TagType, Tag);
713 Diag(Loc, diag::err_omp_decl_in_declare_simd);
714 return DeclGroupPtrTy();
716 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
718 case OMPD_declare_target: {
720 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
723 while (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
724 OMPDeclareTargetDeclAttr::MapTypeTy MT =
725 OMPDeclareTargetDeclAttr::MT_To;
726 if (
Tok.
is(tok::identifier)) {
728 StringRef ClauseName = II->
getName();
730 if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName,
732 Diag(
Tok, diag::err_omp_declare_target_unexpected_clause)
738 auto Callback = [
this, MT, &SameDirectiveDecls](
740 Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
743 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
true))
747 if (
Tok.
is(tok::comma))
750 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
752 return DeclGroupPtrTy();
758 if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
759 return DeclGroupPtrTy();
762 while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target &&
768 MaybeParseCXX11Attributes(Attrs);
770 Ptr = ParseExternalDeclaration(Attrs, &PDS);
773 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs,
TagType, Tag);
775 if (
Tok.isAnnotation() &&
Tok.
is(tok::annot_pragma_openmp)) {
776 TentativeParsingAction TPA(*
this);
777 ConsumeAnnotationToken();
779 if (DKind != OMPD_end_declare_target)
786 if (DKind == OMPD_end_declare_target) {
788 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
789 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
791 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
796 Diag(
Tok, diag::err_expected_end_declare_target);
797 Diag(DTLoc, diag::note_matching) <<
"'#pragma omp declare target'";
799 Actions.ActOnFinishOpenMPDeclareTargetDirective();
800 return DeclGroupPtrTy();
803 Diag(
Tok, diag::err_omp_unknown_directive);
821 case OMPD_parallel_for:
822 case OMPD_parallel_for_simd:
823 case OMPD_parallel_sections:
827 case OMPD_cancellation_point:
829 case OMPD_target_data:
830 case OMPD_target_enter_data:
831 case OMPD_target_exit_data:
832 case OMPD_target_parallel:
833 case OMPD_target_parallel_for:
835 case OMPD_taskloop_simd:
836 case OMPD_distribute:
837 case OMPD_end_declare_target:
838 case OMPD_target_update:
839 case OMPD_distribute_parallel_for:
840 case OMPD_distribute_parallel_for_simd:
841 case OMPD_distribute_simd:
842 case OMPD_target_parallel_for_simd:
843 case OMPD_target_simd:
844 case OMPD_teams_distribute:
845 case OMPD_teams_distribute_simd:
846 case OMPD_teams_distribute_parallel_for_simd:
847 case OMPD_teams_distribute_parallel_for:
848 case OMPD_target_teams:
849 case OMPD_target_teams_distribute:
850 case OMPD_target_teams_distribute_parallel_for:
851 case OMPD_target_teams_distribute_parallel_for_simd:
852 case OMPD_target_teams_distribute_simd:
853 Diag(
Tok, diag::err_omp_unexpected_directive)
857 while (
Tok.
isNot(tok::annot_pragma_openmp_end))
896 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
897 AllowedConstructsKind Allowed) {
898 assert(
Tok.
is(tok::annot_pragma_openmp) &&
"Not an OpenMP directive!");
911 bool HasAssociatedStatement =
true;
912 bool FlushHasClause =
false;
915 case OMPD_threadprivate: {
916 if (Allowed != ACK_Any) {
917 Diag(
Tok, diag::err_omp_immediate_directive)
921 ThreadprivateListParserHelper Helper(
this);
922 if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper,
false)) {
925 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
926 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
928 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
930 DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
931 Loc, Helper.getIdentifiers());
932 Directive = Actions.ActOnDeclStmt(Res, Loc,
Tok.getLocation());
934 SkipUntil(tok::annot_pragma_openmp_end);
937 case OMPD_declare_reduction:
939 if (
auto Res = ParseOpenMPDeclareReductionDirective(
AS_none)) {
942 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
943 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
945 while (
Tok.
isNot(tok::annot_pragma_openmp_end))
949 Directive = Actions.ActOnDeclStmt(Res, Loc,
Tok.getLocation());
951 SkipUntil(tok::annot_pragma_openmp_end);
954 if (PP.LookAhead(0).is(tok::l_paren)) {
955 FlushHasClause =
true;
964 case OMPD_cancellation_point:
966 case OMPD_target_enter_data:
967 case OMPD_target_exit_data:
968 case OMPD_target_update:
969 if (Allowed == ACK_StatementsOpenMPNonStandalone) {
970 Diag(
Tok, diag::err_omp_immediate_directive)
973 HasAssociatedStatement =
false;
985 case OMPD_parallel_for:
986 case OMPD_parallel_for_simd:
987 case OMPD_parallel_sections:
994 case OMPD_target_data:
995 case OMPD_target_parallel:
996 case OMPD_target_parallel_for:
998 case OMPD_taskloop_simd:
999 case OMPD_distribute:
1000 case OMPD_distribute_parallel_for:
1001 case OMPD_distribute_parallel_for_simd:
1002 case OMPD_distribute_simd:
1003 case OMPD_target_parallel_for_simd:
1004 case OMPD_target_simd:
1005 case OMPD_teams_distribute:
1006 case OMPD_teams_distribute_simd:
1007 case OMPD_teams_distribute_parallel_for_simd:
1008 case OMPD_teams_distribute_parallel_for:
1009 case OMPD_target_teams:
1010 case OMPD_target_teams_distribute:
1011 case OMPD_target_teams_distribute_parallel_for:
1012 case OMPD_target_teams_distribute_parallel_for_simd:
1013 case OMPD_target_teams_distribute_simd: {
1016 if (DKind == OMPD_critical) {
1018 tok::annot_pragma_openmp_end);
1020 if (
Tok.isAnyIdentifier()) {
1025 Diag(
Tok, diag::err_omp_expected_identifier_for_critical);
1029 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
1031 if (
Tok.
isNot(tok::annot_pragma_openmp_end))
1039 ParseScope OMPDirectiveScope(
this, ScopeFlags);
1040 Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
1042 while (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1046 : FlushHasClause ? OMPC_flush
1048 Actions.StartOpenMPClause(CKind);
1049 FlushHasClause =
false;
1051 ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
1052 FirstClauses[CKind].setInt(
true);
1054 FirstClauses[CKind].setPointer(Clause);
1055 Clauses.push_back(Clause);
1059 if (
Tok.
is(tok::comma))
1061 Actions.EndOpenMPClause();
1064 EndLoc =
Tok.getLocation();
1066 ConsumeAnnotationToken();
1071 if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
1072 if (Allowed == ACK_StatementsOpenMPNonStandalone) {
1073 Diag(Loc, diag::err_omp_immediate_directive)
1077 HasAssociatedStatement =
false;
1081 if (HasAssociatedStatement) {
1084 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1085 Actions.ActOnStartOfCompoundStmt();
1087 AssociatedStmt = ParseStatement();
1088 Actions.ActOnFinishOfCompoundStmt();
1089 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1090 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
1091 DKind == OMPD_target_exit_data) {
1093 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1094 Actions.ActOnStartOfCompoundStmt();
1096 Actions.ActOnCompoundStmt(Loc, Loc,
llvm::None,
false);
1097 Actions.ActOnFinishOfCompoundStmt();
1098 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1100 Directive = Actions.ActOnOpenMPExecutableDirective(
1101 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
1105 Actions.EndOpenMPDSABlock(Directive.get());
1106 OMPDirectiveScope.Exit();
1109 case OMPD_declare_simd:
1110 case OMPD_declare_target:
1111 case OMPD_end_declare_target:
1112 Diag(
Tok, diag::err_omp_unexpected_directive)
1114 SkipUntil(tok::annot_pragma_openmp_end);
1117 Diag(
Tok, diag::err_omp_unknown_directive);
1118 SkipUntil(tok::annot_pragma_openmp_end);
1128 bool Parser::ParseOpenMPSimpleVarList(
1132 bool AllowScopeSpecifier) {
1138 bool IsCorrect =
true;
1139 bool NoIdentIsFound =
true;
1142 while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1148 NoIdentIsFound =
false;
1150 if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
1151 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
false)) {
1153 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1155 }
else if (ParseUnqualifiedId(SS,
false,
false,
false,
false,
nullptr,
1156 TemplateKWLoc, Name)) {
1158 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1161 Tok.
isNot(tok::annot_pragma_openmp_end)) {
1163 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1169 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
1172 if (
Tok.
is(tok::comma)) {
1177 if (NoIdentIsFound) {
1178 Diag(
Tok, diag::err_expected) << tok::identifier;
1207 bool ErrorFound =
false;
1217 case OMPC_num_threads:
1223 case OMPC_num_teams:
1224 case OMPC_thread_limit:
1226 case OMPC_grainsize:
1227 case OMPC_num_tasks:
1250 Diag(
Tok, diag::err_omp_more_one_clause)
1255 if (CKind == OMPC_ordered && PP.LookAhead(0).isNot(tok::l_paren))
1256 Clause = ParseOpenMPClause(CKind);
1258 Clause = ParseOpenMPSingleExprClause(CKind);
1261 case OMPC_proc_bind:
1268 Diag(
Tok, diag::err_omp_more_one_clause)
1273 Clause = ParseOpenMPSimpleClause(CKind);
1276 case OMPC_dist_schedule:
1277 case OMPC_defaultmap:
1283 Diag(
Tok, diag::err_omp_more_one_clause)
1290 Clause = ParseOpenMPSingleExprWithArgClause(CKind);
1294 case OMPC_mergeable:
1308 Diag(
Tok, diag::err_omp_more_one_clause)
1313 Clause = ParseOpenMPClause(CKind);
1316 case OMPC_firstprivate:
1317 case OMPC_lastprivate:
1319 case OMPC_reduction:
1320 case OMPC_task_reduction:
1321 case OMPC_in_reduction:
1325 case OMPC_copyprivate:
1331 case OMPC_use_device_ptr:
1332 case OMPC_is_device_ptr:
1333 Clause = ParseOpenMPVarListClause(DKind, CKind);
1336 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
1338 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1344 SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
1347 return ErrorFound ? nullptr : Clause;
1356 if (T.
expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
1361 false,
false, NotTypeCast));
1363 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc);
1413 return Actions.ActOnOpenMPSingleExprClause(Kind, Val.
get(), Loc, LLoc, RLoc);
1434 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok));
1437 Tok.
isNot(tok::annot_pragma_openmp_end))
1443 return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
1477 return Actions.ActOnOpenMPClause(Kind, Loc,
Tok.getLocation());
1506 if (Kind == OMPC_schedule) {
1507 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
1508 Arg.resize(NumberOfElements);
1509 KLoc.resize(NumberOfElements);
1514 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok));
1517 Arg[Modifier1] = KindModifier;
1518 KLoc[Modifier1] =
Tok.getLocation();
1520 Tok.
isNot(tok::annot_pragma_openmp_end))
1522 if (
Tok.
is(tok::comma)) {
1526 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok));
1530 KLoc[Modifier2] =
Tok.getLocation();
1532 Tok.
isNot(tok::annot_pragma_openmp_end))
1536 if (
Tok.
is(tok::colon))
1539 Diag(
Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
1541 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok));
1543 Arg[ScheduleKind] = KindModifier;
1544 KLoc[ScheduleKind] =
Tok.getLocation();
1546 Tok.
isNot(tok::annot_pragma_openmp_end))
1548 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1549 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1550 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
1552 DelimLoc = ConsumeAnyToken();
1553 }
else if (Kind == OMPC_dist_schedule) {
1555 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok)));
1556 KLoc.push_back(
Tok.getLocation());
1558 Tok.
isNot(tok::annot_pragma_openmp_end))
1560 if (Arg.back() == OMPC_DIST_SCHEDULE_static &&
Tok.
is(tok::comma))
1561 DelimLoc = ConsumeAnyToken();
1562 }
else if (Kind == OMPC_defaultmap) {
1565 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok)));
1566 KLoc.push_back(
Tok.getLocation());
1568 Tok.
isNot(tok::annot_pragma_openmp_end))
1571 if (
Tok.
is(tok::colon))
1574 Diag(
Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
1577 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok)));
1578 KLoc.push_back(
Tok.getLocation());
1580 Tok.
isNot(tok::annot_pragma_openmp_end))
1583 assert(Kind == OMPC_if);
1584 KLoc.push_back(
Tok.getLocation());
1585 TentativeParsingAction TPA(*
this);
1589 if (
Tok.
is(tok::colon) && getLangOpts().OpenMP > 40) {
1591 DelimLoc = ConsumeToken();
1600 bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.
isValid()) ||
1601 (Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
1603 if (NeedAnExpression) {
1605 ExprResult LHS(ParseCastExpression(
false,
false, NotTypeCast));
1607 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc);
1613 if (NeedAnExpression && Val.
isInvalid())
1616 return Actions.ActOnOpenMPSingleExprWithArgClause(
1624 if (ReductionIdScopeSpec.
isEmpty()) {
1665 nullptr, TemplateKWLoc, ReductionId);
1674 bool InvalidReductionId =
false;
1675 bool MapTypeModifierSpecified =
false;
1683 bool NeedRParenForLinear =
false;
1685 tok::annot_pragma_openmp_end);
1687 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
1688 Kind == OMPC_in_reduction) {
1695 UnqualifiedReductionId);
1696 if (InvalidReductionId) {
1697 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
1700 if (
Tok.
is(tok::colon))
1703 Diag(
Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
1704 if (!InvalidReductionId)
1706 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
1707 }
else if (Kind == OMPC_depend) {
1712 Kind,
Tok.
is(tok::identifier) ? PP.getSpelling(
Tok) :
""));
1716 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
1721 if (DKind == OMPD_ordered && Data.
DepKind == OMPC_DEPEND_source) {
1727 if (
Tok.
is(tok::colon))
1730 Diag(
Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
1731 : diag::warn_pragma_expected_colon)
1732 <<
"dependency type";
1734 }
else if (Kind == OMPC_linear) {
1736 if (
Tok.
is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
1741 NeedRParenForLinear =
true;
1743 }
else if (Kind == OMPC_map) {
1749 auto &&IsMapClauseModifierToken = [](
const Token &
Tok) ->
bool {
1750 return Tok.
isOneOf(tok::identifier, tok::kw_delete);
1757 IsMapClauseModifierToken(
Tok)
1762 bool ColonExpected =
false;
1764 if (IsMapClauseModifierToken(
Tok)) {
1765 if (PP.LookAhead(0).is(tok::colon)) {
1767 Diag(
Tok, diag::err_omp_unknown_map_type);
1768 else if (Data.
MapType == OMPC_MAP_always)
1769 Diag(
Tok, diag::err_omp_map_type_missing);
1771 }
else if (PP.LookAhead(0).is(tok::comma)) {
1772 if (IsMapClauseModifierToken(PP.LookAhead(1)) &&
1773 PP.LookAhead(2).is(tok::colon)) {
1776 Diag(
Tok, diag::err_omp_unknown_map_type_modifier);
1779 MapTypeModifierSpecified =
true;
1785 IsMapClauseModifierToken(
Tok)
1790 Data.
MapType == OMPC_MAP_always)
1791 Diag(
Tok, diag::err_omp_unknown_map_type);
1794 Data.
MapType = OMPC_MAP_tofrom;
1797 }
else if (IsMapClauseModifierToken(PP.LookAhead(0))) {
1798 if (PP.LookAhead(1).is(tok::colon)) {
1801 Diag(
Tok, diag::err_omp_unknown_map_type_modifier);
1804 MapTypeModifierSpecified =
true;
1809 IsMapClauseModifierToken(
Tok)
1814 Data.
MapType == OMPC_MAP_always)
1815 Diag(
Tok, diag::err_omp_unknown_map_type);
1818 Data.
MapType = OMPC_MAP_tofrom;
1822 Data.
MapType = OMPC_MAP_tofrom;
1826 Data.
MapType = OMPC_MAP_tofrom;
1830 if (
Tok.
is(tok::colon))
1832 else if (ColonExpected)
1833 Diag(
Tok, diag::warn_pragma_expected_colon) <<
"map type";
1837 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
1838 Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
1839 (Kind == OMPC_reduction && !InvalidReductionId) ||
1841 (!MapTypeModifierSpecified ||
1844 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
1846 Tok.
isNot(tok::annot_pragma_openmp_end))) {
1850 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
1852 Vars.push_back(VarExpr.
get());
1854 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1858 IsComma =
Tok.
is(tok::comma);
1861 else if (
Tok.
isNot(tok::r_paren) &&
1862 Tok.
isNot(tok::annot_pragma_openmp_end) &&
1863 (!MayHaveTail ||
Tok.
isNot(tok::colon)))
1864 Diag(
Tok, diag::err_omp_expected_punc)
1867 << (Kind == OMPC_flush);
1871 if (NeedRParenForLinear)
1875 const bool MustHaveTail = MayHaveTail &&
Tok.
is(tok::colon);
1879 ExprResult Tail = ParseAssignmentExpression();
1880 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc);
1884 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1892 (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
1893 (MustHaveTail && !Data.
TailExpr) || InvalidReductionId)
1949 if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
1952 return Actions.ActOnOpenMPVarListClause(
OpenMPDependClauseKind DepKind
Defines the clang::ASTContext interface.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
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.
ParseScope - Introduces a new scope for parsing.
DeclarationNameInfo ReductionId
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
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)) {...
bool isEmpty() const
No scope specifier.
Decl - This represents one declaration (or definition), e.g.
The base class of the type hierarchy.
SourceLocation getCloseLocation() const
This indicates that the scope corresponds to a function, which means that labels are set here...
bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind)
static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P)
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, UnqualifiedId &ReductionId)
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
void ActOnExitFunctionContext()
Wrapper for void* pointer.
Parser - This implements a parser for the C family of languages.
bool isEmpty() const
Evaluates true when this declaration name is empty.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
SourceLocation DepLinMapLoc
VarDecl - An instance of this class is created to represent a variable declaration or definition...
TypeSpecifierType
Specifies the kind of type.
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing...
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed...
tok::TokenKind getKind() 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 ...
OpenMPLinearClauseKind LinKind
Base wrapper for a particular "section" of type source info.
RecordDecl - Represents a struct/union/class.
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
One of these records is kept for each identifier that is lexed.
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Token - This structure provides full information about a lexed token.
bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, ParsedType ObjectType, SourceLocation &TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
VerifyDiagnosticConsumer::Directive Directive
Represents a C++ unqualified-id that has been parsed.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str)
static bool parseDeclareSimdClauses(Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen, SmallVectorImpl< Expr *> &Uniforms, SmallVectorImpl< Expr *> &Aligneds, SmallVectorImpl< Expr *> &Alignments, SmallVectorImpl< Expr *> &Linears, SmallVectorImpl< unsigned > &LinModifiers, SmallVectorImpl< Expr *> &Steps)
Parses clauses for 'declare simd' directive.
Represents a C++ nested-name-specifier or a global scope specifier.
Sema - This implements semantic analysis and AST building for C.
A RAII object to enter scope of a compound statement.
DeclarationNameTable DeclarationNames
OpenMPMapClauseKind MapTypeModifier
const FunctionProtoType * T
This is the scope of OpenMP executable directive.
Sema & getActions() const
const Token & getCurToken() const
CXXScopeSpec ReductionIdScopeSpec
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
OpenMPClauseKind
OpenMP clauses.
DeclContext * getDeclContext()
This is a compound statement scope.
Preprocessor & getPreprocessor() const
SourceLocation getOpenLocation() const
A class for parsing a DeclSpec.
bool isTemplateDecl() const
returns true if this declaration is a template
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
ASTContext & getASTContext() const
Encodes a location in the source.
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, SmallVectorImpl< Expr *> &Vars, OpenMPVarListDataTy &Data)
Parses clauses with list.
static unsigned getOpenMPDirectiveKindEx(StringRef S)
IdentifierInfo * getIdentifierInfo() const
OpenMPDirectiveKind
OpenMP directives.
This is a basic class for representing single OpenMP clause.
Scope * getCurScope() const
ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc)
Parses simple expression in parens for single-expression clauses of OpenMP constructs.
StringRef getName() const
Return the actual identifier string.
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool expectAndConsume(unsigned DiagID=diag::err_expected, const char *Msg="", tok::TokenKind SkipToTok=tok::unknown)
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
This is the scope of some OpenMP simd directive.
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
This is a scope that corresponds to the template parameters of a C++ template.
DeclarationName - The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
Data used for parsing list of variables in OpenMP clauses.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
static const TST TST_unspecified
Not an overloaded operator.
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str)
QualType getCanonicalTypeInternal() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
This file defines OpenMP AST classes for executable directives and clauses.
void setOperatorFunctionId(SourceLocation OperatorLoc, OverloadedOperatorKind Op, SourceLocation SymbolLocations[3])
Specify that this unqualified-id was parsed as an operator-function-id.
ActionResult< Stmt * > StmtResult
OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str)
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
This is a scope that can contain a declaration.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
static DeclarationName parseOpenMPReductionId(Parser &P)
This is the scope of some OpenMP loop directive.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
A trivial tuple used to represent a source range.
NamedDecl - This represents a decl with a name.
Directive - Abstract class representing a parsed verify directive.
SourceLocation getBegin() const
SourceLocation getLocation() const
OpenMPMapClauseKind MapType
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
Stop skipping at specified token, but don't skip the token itself.
SourceLocation getEndLoc() const