19 #include "llvm/ADT/PointerIntPair.h" 21 using namespace clang;
41 OMPD_distribute_parallel,
42 OMPD_teams_distribute_parallel,
43 OMPD_target_teams_distribute_parallel,
47 class DeclDirectiveListParserHelper final {
59 Identifiers.push_back(Res.
get());
72 return llvm::StringSwitch<unsigned>(S)
73 .Case(
"cancellation", OMPD_cancellation)
74 .Case(
"data", OMPD_data)
75 .Case(
"declare", OMPD_declare)
76 .Case(
"end", OMPD_end)
77 .Case(
"enter", OMPD_enter)
78 .Case(
"exit", OMPD_exit)
79 .Case(
"point", OMPD_point)
80 .Case(
"reduction", OMPD_reduction)
81 .Case(
"update", OMPD_update)
82 .Case(
"mapper", OMPD_mapper)
90 static const unsigned F[][3] = {
91 {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
92 {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
93 {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
94 {OMPD_declare, OMPD_simd, OMPD_declare_simd},
95 {OMPD_declare, OMPD_target, OMPD_declare_target},
96 {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
97 {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
98 {OMPD_distribute_parallel_for, OMPD_simd,
99 OMPD_distribute_parallel_for_simd},
100 {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
101 {OMPD_end, OMPD_declare, OMPD_end_declare},
102 {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
103 {OMPD_target, OMPD_data, OMPD_target_data},
104 {OMPD_target, OMPD_enter, OMPD_target_enter},
105 {OMPD_target, OMPD_exit, OMPD_target_exit},
106 {OMPD_target, OMPD_update, OMPD_target_update},
107 {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
108 {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
109 {OMPD_for, OMPD_simd, OMPD_for_simd},
110 {OMPD_parallel, OMPD_for, OMPD_parallel_for},
111 {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
112 {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
113 {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
114 {OMPD_target, OMPD_parallel, OMPD_target_parallel},
115 {OMPD_target, OMPD_simd, OMPD_target_simd},
116 {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
117 {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
118 {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
119 {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
120 {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
121 {OMPD_teams_distribute_parallel, OMPD_for,
122 OMPD_teams_distribute_parallel_for},
123 {OMPD_teams_distribute_parallel_for, OMPD_simd,
124 OMPD_teams_distribute_parallel_for_simd},
125 {OMPD_target, OMPD_teams, OMPD_target_teams},
126 {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
127 {OMPD_target_teams_distribute, OMPD_parallel,
128 OMPD_target_teams_distribute_parallel},
129 {OMPD_target_teams_distribute, OMPD_simd,
130 OMPD_target_teams_distribute_simd},
131 {OMPD_target_teams_distribute_parallel, OMPD_for,
132 OMPD_target_teams_distribute_parallel_for},
133 {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
134 OMPD_target_teams_distribute_parallel_for_simd}};
135 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
144 for (
unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
145 if (DKind != F[I][0])
156 if (SDKind == F[I][1]) {
161 return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
170 bool WithOperator =
false;
171 if (Tok.
is(tok::kw_operator)) {
201 case tok::identifier:
206 P.
Diag(Tok.
getLocation(), diag::err_omp_expected_reduction_identifier);
207 P.
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
214 : DeclNames.getCXXOperatorName(OOK);
233 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
234 return DeclGroupPtrTy();
238 if (Name.
isEmpty() &&
Tok.
is(tok::annot_pragma_openmp_end))
239 return DeclGroupPtrTy();
242 bool IsCorrect = !ExpectAndConsume(tok::colon);
244 if (!IsCorrect &&
Tok.
is(tok::annot_pragma_openmp_end))
245 return DeclGroupPtrTy();
247 IsCorrect = IsCorrect && !Name.
isEmpty();
249 if (
Tok.
is(tok::colon) ||
Tok.
is(tok::annot_pragma_openmp_end)) {
250 Diag(
Tok.getLocation(), diag::err_expected_type);
254 if (!IsCorrect &&
Tok.
is(tok::annot_pragma_openmp_end))
255 return DeclGroupPtrTy();
266 Actions.ActOnOpenMPDeclareReductionType(Range.
getBegin(), TR);
267 if (!ReductionType.
isNull()) {
268 ReductionTypes.push_back(
269 std::make_pair(ReductionType, Range.
getBegin()));
272 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
276 if (
Tok.
is(tok::colon) ||
Tok.
is(tok::annot_pragma_openmp_end))
280 if (ExpectAndConsume(tok::comma)) {
282 if (
Tok.
is(tok::annot_pragma_openmp_end)) {
283 Diag(
Tok.getLocation(), diag::err_expected_type);
284 return DeclGroupPtrTy();
287 }
while (
Tok.
isNot(tok::annot_pragma_openmp_end));
289 if (ReductionTypes.empty()) {
290 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
291 return DeclGroupPtrTy();
294 if (!IsCorrect &&
Tok.
is(tok::annot_pragma_openmp_end))
295 return DeclGroupPtrTy();
298 if (ExpectAndConsume(tok::colon))
301 if (
Tok.
is(tok::annot_pragma_openmp_end)) {
302 Diag(
Tok.getLocation(), diag::err_expected_expression);
303 return DeclGroupPtrTy();
306 DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
307 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
311 unsigned I = 0, E = ReductionTypes.size();
312 for (
Decl *D : DRD.get()) {
313 TentativeParsingAction TPA(*
this);
318 Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
320 Actions.ActOnFinishFullExpr(ParseAssignmentExpression().
get(),
321 D->getLocation(),
false);
322 Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.
get());
325 Tok.
isNot(tok::annot_pragma_openmp_end)) {
332 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
334 if (
Tok.
is(tok::identifier) &&
335 Tok.getIdentifierInfo()->isStr(
"initializer")) {
338 Diag(
Tok.getLocation(), diag::err_expected) <<
"'initializer'";
345 tok::annot_pragma_openmp_end);
349 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
355 Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
358 if (
Tok.
is(tok::identifier) &&
359 Tok.getIdentifierInfo()->isStr(
"omp_priv")) {
360 if (Actions.getLangOpts().CPlusPlus) {
361 InitializerResult = Actions.ActOnFinishFullExpr(
362 ParseAssignmentExpression().
get(), D->getLocation(),
366 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
369 InitializerResult = Actions.ActOnFinishFullExpr(
370 ParseAssignmentExpression().
get(), D->getLocation(),
373 Actions.ActOnOpenMPDeclareReductionInitializerEnd(
374 D, InitializerResult.
get(), OmpPrivParm);
376 Tok.
isNot(tok::annot_pragma_openmp_end)) {
394 return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
398 void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
401 if (isTokenEqualOrEqualTypo()) {
404 if (
Tok.
is(tok::code_completion)) {
405 Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
406 Actions.FinalizeDeclaration(OmpPrivParm);
414 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
415 Actions.ActOnInitializerError(OmpPrivParm);
417 Actions.AddInitializerToDecl(OmpPrivParm, Init.
get(),
420 }
else if (
Tok.
is(tok::l_paren)) {
426 CommaLocsTy CommaLocs;
429 auto RunSignatureHelp = [
this, OmpPrivParm, LParLoc, &Exprs]() {
430 QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
433 CalledSignatureHelp =
true;
434 return PreferredType;
436 if (ParseExpressionList(Exprs, CommaLocs, [&] {
437 PreferredType.enterFunctionArgument(
Tok.getLocation(),
440 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
442 Actions.ActOnInitializerError(OmpPrivParm);
443 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
450 assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
451 "Unexpected number of commas!");
455 Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
458 }
else if (getLangOpts().CPlusPlus11 &&
Tok.
is(tok::l_brace)) {
460 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
465 Actions.ActOnInitializerError(OmpPrivParm);
467 Actions.AddInitializerToDecl(OmpPrivParm, Init.
get(),
471 Actions.ActOnUninitializedDecl(OmpPrivParm);
485 bool IsCorrect =
true;
490 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
491 return DeclGroupPtrTy();
495 auto &DeclNames = Actions.getASTContext().DeclarationNames;
497 if (PP.LookAhead(0).is(tok::colon)) {
499 Diag(
Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
502 MapperId = DeclNames.getIdentifier(
Tok.getIdentifierInfo());
506 ExpectAndConsume(tok::colon);
510 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get(
"default"));
513 if (!IsCorrect &&
Tok.
is(tok::annot_pragma_openmp_end))
514 return DeclGroupPtrTy();
528 return DeclGroupPtrTy();
535 return DeclGroupPtrTy();
540 getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
546 ParseScope OMPDirectiveScope(
this, ScopeFlags);
547 Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
550 Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
551 DMD, getCurScope(), MapperType, Range.
getBegin(), VName);
555 while (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
559 Actions.StartOpenMPClause(CKind);
561 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);
563 Clauses.push_back(Clause);
567 if (
Tok.
is(tok::comma))
569 Actions.EndOpenMPClause();
571 if (Clauses.empty()) {
572 Diag(
Tok, diag::err_omp_expected_clause)
578 Actions.EndOpenMPDSABlock(
nullptr);
579 OMPDirectiveScope.Exit();
582 Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
584 return DeclGroupPtrTy();
592 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
594 ParseSpecifierQualifierList(DS, AS, DSC);
599 ParseDeclarator(DeclaratorInfo);
602 Diag(
Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
605 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
607 return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
616 class FNContextRAII final {
621 bool HasTemplateScope =
false;
622 bool HasFunScope =
false;
623 FNContextRAII() =
delete;
624 FNContextRAII(
const FNContextRAII &) =
delete;
625 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
642 if (HasTemplateScope)
643 Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
651 Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
658 if (HasTemplateScope)
681 bool IsError =
false;
682 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
683 if (Tok.
isNot(tok::identifier))
685 OMPDeclareSimdDeclAttr::BranchStateTy Out;
687 StringRef ClauseName = II->
getName();
689 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
690 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
691 P.
Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
693 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
699 }
else if (ClauseName.equals(
"simdlen")) {
701 P.
Diag(Tok, diag::err_omp_more_one_clause)
713 CKind == OMPC_linear) {
716 if (CKind == OMPC_aligned)
718 else if (CKind == OMPC_linear)
725 if (CKind == OMPC_aligned) {
726 Alignments.append(Aligneds.size() - Alignments.size(), Data.
TailExpr);
727 }
else if (CKind == OMPC_linear) {
730 Data.
LinKind = OMPC_LINEAR_val;
731 LinModifiers.append(Linears.size() - LinModifiers.size(),
733 Steps.append(Linears.size() - Steps.size(), Data.
TailExpr);
740 if (Tok.
is(tok::comma))
750 PP.EnterToken(
Tok,
true);
751 PP.EnterTokenStream(Toks,
true,
754 ConsumeAnyToken(
true);
756 FNContextRAII FnContext(*
this, Ptr);
757 OMPDeclareSimdDeclAttr::BranchStateTy BS =
758 OMPDeclareSimdDeclAttr::BS_Undefined;
768 Alignments, Linears, LinModifiers, Steps);
770 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
771 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
773 while (
Tok.
isNot(tok::annot_pragma_openmp_end))
780 return Actions.ActOnOpenMPDeclareSimdDirective(
781 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
788 while (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
789 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
790 if (
Tok.
is(tok::identifier)) {
792 StringRef ClauseName = II->
getName();
794 if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT)) {
795 Diag(
Tok, diag::err_omp_declare_target_unexpected_clause) << ClauseName;
800 auto &&Callback = [
this, MT, &SameDirectiveDecls](
802 Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
805 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
810 if (
Tok.
is(tok::comma))
813 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
816 SameDirectiveDecls.end());
818 return DeclGroupPtrTy();
819 return Actions.BuildDeclaratorGroup(Decls);
824 if (DKind != OMPD_end_declare_target) {
825 Diag(
Tok, diag::err_expected_end_declare_target);
826 Diag(DTLoc, diag::note_matching) <<
"'#pragma omp declare target'";
830 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
831 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
833 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
870 assert(
Tok.
is(tok::annot_pragma_openmp) &&
"Not an OpenMP directive!");
877 case OMPD_threadprivate: {
879 DeclDirectiveListParserHelper Helper(
this, DKind);
880 if (!ParseOpenMPSimpleVarList(DKind, Helper,
884 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
885 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
887 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
890 ConsumeAnnotationToken();
891 return Actions.ActOnOpenMPThreadprivateDirective(Loc,
892 Helper.getIdentifiers());
896 case OMPD_allocate: {
898 DeclDirectiveListParserHelper Helper(
this, DKind);
899 if (!ParseOpenMPSimpleVarList(DKind, Helper,
902 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
906 while (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
910 Actions.StartOpenMPClause(CKind);
911 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
912 !FirstClauses[CKind].getInt());
913 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
915 FirstClauses[CKind].setInt(
true);
916 if (Clause !=
nullptr)
917 Clauses.push_back(Clause);
918 if (
Tok.
is(tok::annot_pragma_openmp_end)) {
919 Actions.EndOpenMPClause();
923 if (
Tok.
is(tok::comma))
925 Actions.EndOpenMPClause();
929 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
930 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
932 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
936 ConsumeAnnotationToken();
937 return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
942 case OMPD_requires: {
947 if (
Tok.
is(tok::annot_pragma_openmp_end)) {
948 Diag(
Tok, diag::err_omp_expected_clause)
952 while (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
956 Actions.StartOpenMPClause(CKind);
957 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
958 !FirstClauses[CKind].getInt());
959 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
961 FirstClauses[CKind].setInt(
true);
962 if (Clause !=
nullptr)
963 Clauses.push_back(Clause);
964 if (
Tok.
is(tok::annot_pragma_openmp_end)) {
965 Actions.EndOpenMPClause();
969 if (
Tok.
is(tok::comma))
971 Actions.EndOpenMPClause();
974 if (Clauses.size() == 0) {
975 Diag(
Tok, diag::err_omp_expected_clause)
977 ConsumeAnnotationToken();
980 ConsumeAnnotationToken();
981 return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
983 case OMPD_declare_reduction:
985 if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
988 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
989 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
991 while (
Tok.
isNot(tok::annot_pragma_openmp_end))
995 ConsumeAnnotationToken();
999 case OMPD_declare_mapper: {
1001 if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1003 ConsumeAnnotationToken();
1008 case OMPD_declare_simd: {
1015 while(
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1016 Toks.push_back(
Tok);
1019 Toks.push_back(
Tok);
1023 if (
Tok.
is(tok::annot_pragma_openmp)) {
1024 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs,
TagType, Tag);
1025 }
else if (
Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
1029 MaybeParseCXX11Attributes(Attrs);
1031 Ptr = ParseExternalDeclaration(Attrs, &PDS);
1034 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs,
TagType, Tag);
1038 Diag(Loc, diag::err_omp_decl_in_declare_simd);
1039 return DeclGroupPtrTy();
1041 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1043 case OMPD_declare_target: {
1045 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1046 return ParseOMPDeclareTargetClauses();
1052 if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1053 return DeclGroupPtrTy();
1063 MaybeParseCXX11Attributes(Attrs);
1065 Ptr = ParseExternalDeclaration(Attrs, &PDS);
1068 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs,
TagType, Tag);
1072 Decls.append(Ref.
begin(), Ref.
end());
1074 if (
Tok.isAnnotation() &&
Tok.
is(tok::annot_pragma_openmp)) {
1075 TentativeParsingAction TPA(*
this);
1076 ConsumeAnnotationToken();
1078 if (DKind != OMPD_end_declare_target)
1085 ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
1086 Actions.ActOnFinishOpenMPDeclareTargetDirective();
1087 return Actions.BuildDeclaratorGroup(Decls);
1090 Diag(
Tok, diag::err_omp_unknown_directive);
1095 case OMPD_taskyield:
1098 case OMPD_taskgroup:
1108 case OMPD_parallel_for:
1109 case OMPD_parallel_for_simd:
1110 case OMPD_parallel_sections:
1114 case OMPD_cancellation_point:
1116 case OMPD_target_data:
1117 case OMPD_target_enter_data:
1118 case OMPD_target_exit_data:
1119 case OMPD_target_parallel:
1120 case OMPD_target_parallel_for:
1122 case OMPD_taskloop_simd:
1123 case OMPD_distribute:
1124 case OMPD_end_declare_target:
1125 case OMPD_target_update:
1126 case OMPD_distribute_parallel_for:
1127 case OMPD_distribute_parallel_for_simd:
1128 case OMPD_distribute_simd:
1129 case OMPD_target_parallel_for_simd:
1130 case OMPD_target_simd:
1131 case OMPD_teams_distribute:
1132 case OMPD_teams_distribute_simd:
1133 case OMPD_teams_distribute_parallel_for_simd:
1134 case OMPD_teams_distribute_parallel_for:
1135 case OMPD_target_teams:
1136 case OMPD_target_teams_distribute:
1137 case OMPD_target_teams_distribute_parallel_for:
1138 case OMPD_target_teams_distribute_parallel_for_simd:
1139 case OMPD_target_teams_distribute_simd:
1140 Diag(
Tok, diag::err_omp_unexpected_directive)
1144 while (
Tok.
isNot(tok::annot_pragma_openmp_end))
1193 Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
1194 assert(
Tok.
is(tok::annot_pragma_openmp) &&
"Not an OpenMP directive!");
1207 bool HasAssociatedStatement =
true;
1208 bool FlushHasClause =
false;
1211 case OMPD_threadprivate: {
1213 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1214 ParsedStmtContext()) {
1215 Diag(
Tok, diag::err_omp_immediate_directive)
1219 DeclDirectiveListParserHelper Helper(
this, DKind);
1220 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1224 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1225 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
1227 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1229 DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
1230 Loc, Helper.getIdentifiers());
1231 Directive = Actions.ActOnDeclStmt(Res, Loc,
Tok.getLocation());
1233 SkipUntil(tok::annot_pragma_openmp_end);
1236 case OMPD_allocate: {
1238 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1239 ParsedStmtContext()) {
1240 Diag(
Tok, diag::err_omp_immediate_directive)
1244 DeclDirectiveListParserHelper Helper(
this, DKind);
1245 if (!ParseOpenMPSimpleVarList(DKind, Helper,
1248 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1252 while (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1256 Actions.StartOpenMPClause(CKind);
1257 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
1258 !FirstClauses[CKind].getInt());
1259 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1261 FirstClauses[CKind].setInt(
true);
1262 if (Clause !=
nullptr)
1263 Clauses.push_back(Clause);
1264 if (
Tok.
is(tok::annot_pragma_openmp_end)) {
1265 Actions.EndOpenMPClause();
1269 if (
Tok.
is(tok::comma))
1271 Actions.EndOpenMPClause();
1275 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1276 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
1278 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1281 DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
1282 Loc, Helper.getIdentifiers(), Clauses);
1283 Directive = Actions.ActOnDeclStmt(Res, Loc,
Tok.getLocation());
1285 SkipUntil(tok::annot_pragma_openmp_end);
1288 case OMPD_declare_reduction:
1290 if (DeclGroupPtrTy Res =
1291 ParseOpenMPDeclareReductionDirective(
AS_none)) {
1294 if (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1295 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
1297 while (
Tok.
isNot(tok::annot_pragma_openmp_end))
1301 Directive = Actions.ActOnDeclStmt(Res, Loc,
Tok.getLocation());
1303 SkipUntil(tok::annot_pragma_openmp_end);
1306 case OMPD_declare_mapper: {
1308 if (DeclGroupPtrTy Res =
1309 ParseOpenMPDeclareMapperDirective(
AS_none)) {
1311 ConsumeAnnotationToken();
1312 Directive = Actions.ActOnDeclStmt(Res, Loc,
Tok.getLocation());
1314 SkipUntil(tok::annot_pragma_openmp_end);
1319 if (PP.LookAhead(0).is(tok::l_paren)) {
1320 FlushHasClause =
true;
1323 PP.EnterToken(
Tok,
true);
1326 case OMPD_taskyield:
1329 case OMPD_cancellation_point:
1331 case OMPD_target_enter_data:
1332 case OMPD_target_exit_data:
1333 case OMPD_target_update:
1334 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1335 ParsedStmtContext()) {
1336 Diag(
Tok, diag::err_omp_immediate_directive)
1339 HasAssociatedStatement =
false;
1351 case OMPD_parallel_for:
1352 case OMPD_parallel_for_simd:
1353 case OMPD_parallel_sections:
1359 case OMPD_taskgroup:
1360 case OMPD_target_data:
1361 case OMPD_target_parallel:
1362 case OMPD_target_parallel_for:
1364 case OMPD_taskloop_simd:
1365 case OMPD_distribute:
1366 case OMPD_distribute_parallel_for:
1367 case OMPD_distribute_parallel_for_simd:
1368 case OMPD_distribute_simd:
1369 case OMPD_target_parallel_for_simd:
1370 case OMPD_target_simd:
1371 case OMPD_teams_distribute:
1372 case OMPD_teams_distribute_simd:
1373 case OMPD_teams_distribute_parallel_for_simd:
1374 case OMPD_teams_distribute_parallel_for:
1375 case OMPD_target_teams:
1376 case OMPD_target_teams_distribute:
1377 case OMPD_target_teams_distribute_parallel_for:
1378 case OMPD_target_teams_distribute_parallel_for_simd:
1379 case OMPD_target_teams_distribute_simd: {
1382 if (DKind == OMPD_critical) {
1384 tok::annot_pragma_openmp_end);
1386 if (
Tok.isAnyIdentifier()) {
1391 Diag(
Tok, diag::err_omp_expected_identifier_for_critical);
1395 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
1397 if (
Tok.
isNot(tok::annot_pragma_openmp_end))
1405 ParseScope OMPDirectiveScope(
this, ScopeFlags);
1406 Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
1408 while (
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1412 : FlushHasClause ? OMPC_flush
1414 Actions.StartOpenMPClause(CKind);
1415 FlushHasClause =
false;
1417 ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
1418 FirstClauses[CKind].setInt(
true);
1420 FirstClauses[CKind].setPointer(Clause);
1421 Clauses.push_back(Clause);
1425 if (
Tok.
is(tok::comma))
1427 Actions.EndOpenMPClause();
1430 EndLoc =
Tok.getLocation();
1432 ConsumeAnnotationToken();
1437 if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
1438 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1439 ParsedStmtContext()) {
1440 Diag(Loc, diag::err_omp_immediate_directive)
1444 HasAssociatedStatement =
false;
1448 if (HasAssociatedStatement) {
1450 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1455 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1456 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
1457 DKind == OMPD_target_exit_data) {
1458 Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1460 Actions.ActOnCompoundStmt(Loc, Loc,
llvm::None,
1462 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1464 Directive = Actions.ActOnOpenMPExecutableDirective(
1465 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
1469 Actions.EndOpenMPDSABlock(Directive.get());
1470 OMPDirectiveScope.Exit();
1473 case OMPD_declare_simd:
1474 case OMPD_declare_target:
1475 case OMPD_end_declare_target:
1477 Diag(
Tok, diag::err_omp_unexpected_directive)
1479 SkipUntil(tok::annot_pragma_openmp_end);
1482 Diag(
Tok, diag::err_omp_unknown_directive);
1483 SkipUntil(tok::annot_pragma_openmp_end);
1493 bool Parser::ParseOpenMPSimpleVarList(
1497 bool AllowScopeSpecifier) {
1503 bool IsCorrect =
true;
1504 bool NoIdentIsFound =
true;
1507 while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end)) {
1512 NoIdentIsFound =
false;
1514 if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
1515 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
false)) {
1517 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1519 }
else if (ParseUnqualifiedId(SS,
false,
false,
false,
false,
nullptr,
1522 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1525 Tok.
isNot(tok::annot_pragma_openmp_end)) {
1527 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1533 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
1536 if (
Tok.
is(tok::comma)) {
1541 if (NoIdentIsFound) {
1542 Diag(
Tok, diag::err_expected) << tok::identifier;
1571 bool ErrorFound =
false;
1572 bool WrongDirective =
false;
1578 WrongDirective =
true;
1583 case OMPC_num_threads:
1589 case OMPC_num_teams:
1590 case OMPC_thread_limit:
1592 case OMPC_grainsize:
1593 case OMPC_num_tasks:
1595 case OMPC_allocator:
1619 Diag(
Tok, diag::err_omp_more_one_clause)
1624 if (CKind == OMPC_ordered && PP.LookAhead(0).isNot(tok::l_paren))
1625 Clause = ParseOpenMPClause(CKind, WrongDirective);
1627 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
1630 case OMPC_proc_bind:
1631 case OMPC_atomic_default_mem_order:
1641 Diag(
Tok, diag::err_omp_more_one_clause)
1646 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
1649 case OMPC_dist_schedule:
1650 case OMPC_defaultmap:
1656 Diag(
Tok, diag::err_omp_more_one_clause)
1663 Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
1667 case OMPC_mergeable:
1676 case OMPC_unified_address:
1677 case OMPC_unified_shared_memory:
1678 case OMPC_reverse_offload:
1679 case OMPC_dynamic_allocators:
1687 Diag(
Tok, diag::err_omp_more_one_clause)
1692 Clause = ParseOpenMPClause(CKind, WrongDirective);
1695 case OMPC_firstprivate:
1696 case OMPC_lastprivate:
1698 case OMPC_reduction:
1699 case OMPC_task_reduction:
1700 case OMPC_in_reduction:
1704 case OMPC_copyprivate:
1710 case OMPC_use_device_ptr:
1711 case OMPC_is_device_ptr:
1713 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
1716 Diag(
Tok, diag::warn_omp_extra_tokens_at_eol)
1718 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1722 if (!WrongDirective)
1723 Diag(
Tok, diag::err_omp_unexpected_clause)
1725 SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
1728 return ErrorFound ? nullptr : Clause;
1737 if (T.
expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
1742 false,
false, NotTypeCast));
1744 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
1747 RLoc =
Tok.getLocation();
1801 return Actions.ActOnOpenMPSingleExprClause(
Kind, Val.
get(), Loc, LLoc, RLoc);
1823 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok));
1826 Tok.
isNot(tok::annot_pragma_openmp_end))
1836 return Actions.ActOnOpenMPSimpleClause(
Kind, Type, TypeLoc, LOpen, Loc, RLoc);
1871 return Actions.ActOnOpenMPClause(
Kind, Loc,
Tok.getLocation());
1901 if (
Kind == OMPC_schedule) {
1902 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
1903 Arg.resize(NumberOfElements);
1904 KLoc.resize(NumberOfElements);
1909 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok));
1912 Arg[Modifier1] = KindModifier;
1913 KLoc[Modifier1] =
Tok.getLocation();
1915 Tok.
isNot(tok::annot_pragma_openmp_end))
1917 if (
Tok.
is(tok::comma)) {
1921 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok));
1925 KLoc[Modifier2] =
Tok.getLocation();
1927 Tok.
isNot(tok::annot_pragma_openmp_end))
1931 if (
Tok.
is(tok::colon))
1934 Diag(
Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
1936 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok));
1938 Arg[ScheduleKind] = KindModifier;
1939 KLoc[ScheduleKind] =
Tok.getLocation();
1941 Tok.
isNot(tok::annot_pragma_openmp_end))
1943 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1944 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1945 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
1947 DelimLoc = ConsumeAnyToken();
1948 }
else if (
Kind == OMPC_dist_schedule) {
1950 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok)));
1951 KLoc.push_back(
Tok.getLocation());
1953 Tok.
isNot(tok::annot_pragma_openmp_end))
1955 if (Arg.back() == OMPC_DIST_SCHEDULE_static &&
Tok.
is(tok::comma))
1956 DelimLoc = ConsumeAnyToken();
1957 }
else if (
Kind == OMPC_defaultmap) {
1960 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok)));
1961 KLoc.push_back(
Tok.getLocation());
1963 Tok.
isNot(tok::annot_pragma_openmp_end))
1966 if (
Tok.
is(tok::colon))
1969 Diag(
Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
1972 Kind,
Tok.isAnnotation() ?
"" : PP.getSpelling(
Tok)));
1973 KLoc.push_back(
Tok.getLocation());
1975 Tok.
isNot(tok::annot_pragma_openmp_end))
1978 assert(
Kind == OMPC_if);
1979 KLoc.push_back(
Tok.getLocation());
1980 TentativeParsingAction TPA(*
this);
1984 if (
Tok.
is(tok::colon) && getLangOpts().OpenMP > 40) {
1986 DelimLoc = ConsumeToken();
1996 bool NeedAnExpression = (
Kind == OMPC_schedule && DelimLoc.
isValid()) ||
1997 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
1999 if (NeedAnExpression) {
2001 ExprResult LHS(ParseCastExpression(
false,
false, NotTypeCast));
2004 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
2012 if (NeedAnExpression && Val.
isInvalid())
2017 return Actions.ActOnOpenMPSingleExprWithArgClause(
2023 if (ReductionIdScopeSpec.
isEmpty()) {
2064 nullptr,
nullptr, ReductionId);
2070 if (!Tok.
is(tok::identifier))
2076 return TypeModifier;
2084 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2094 Diag(
Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
2095 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2099 auto &DeclNames = Actions.getASTContext().DeclarationNames;
2101 DeclNames.getIdentifier(
Tok.getIdentifierInfo()),
Tok.getLocation());
2111 while (getCurToken().isNot(tok::colon)) {
2113 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
2114 TypeModifier == OMPC_MAP_MODIFIER_close) {
2118 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
2122 if (parseMapperModifier(Data))
2128 if (
Tok.
is(tok::comma)) {
2129 Diag(
Tok, diag::err_omp_map_type_modifier_missing);
2134 if (PP.LookAhead(0).is(tok::colon))
2136 Diag(
Tok, diag::err_omp_unknown_map_type_modifier);
2139 if (getCurToken().is(tok::comma))
2149 if (!Tok.
isOneOf(tok::identifier, tok::kw_delete))
2162 if (Tok.
is(tok::colon)) {
2163 P.
Diag(Tok, diag::err_omp_map_type_missing);
2168 P.
Diag(Tok, diag::err_omp_unknown_map_type);
2178 bool InvalidReductionId =
false;
2179 bool IsInvalidMapperModifier =
false;
2187 bool NeedRParenForLinear =
false;
2189 tok::annot_pragma_openmp_end);
2191 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
2192 Kind == OMPC_in_reduction) {
2200 if (InvalidReductionId) {
2201 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2204 if (
Tok.
is(tok::colon))
2207 Diag(
Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
2208 if (!InvalidReductionId)
2210 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
2211 }
else if (Kind == OMPC_depend) {
2216 Kind,
Tok.
is(tok::identifier) ? PP.getSpelling(
Tok) :
""));
2220 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2225 if (DKind == OMPD_ordered && Data.
DepKind == OMPC_DEPEND_source) {
2231 if (
Tok.
is(tok::colon)) {
2234 Diag(
Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
2235 : diag::warn_pragma_expected_colon)
2236 <<
"dependency type";
2238 }
else if (Kind == OMPC_linear) {
2240 if (
Tok.
is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
2245 NeedRParenForLinear =
true;
2247 }
else if (Kind == OMPC_map) {
2257 TentativeParsingAction TPA(*
this);
2258 bool ColonPresent =
false;
2259 if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2261 if (
Tok.
is(tok::colon))
2262 ColonPresent =
true;
2268 IsInvalidMapperModifier = parseMapTypeModifiers(Data);
2269 if (!IsInvalidMapperModifier)
2272 SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
2275 Data.
MapType = OMPC_MAP_tofrom;
2279 if (
Tok.
is(tok::colon))
2281 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
2282 if (
Tok.
is(tok::identifier)) {
2283 bool IsMapperModifier =
false;
2284 if (Kind == OMPC_to) {
2287 if (
Modifier == OMPC_TO_MODIFIER_mapper)
2288 IsMapperModifier =
true;
2292 if (
Modifier == OMPC_FROM_MODIFIER_mapper)
2293 IsMapperModifier =
true;
2295 if (IsMapperModifier) {
2298 IsInvalidMapperModifier = parseMapperModifier(Data);
2300 if (!IsInvalidMapperModifier)
2301 Diag(
Tok, diag::warn_pragma_expected_colon) <<
")";
2302 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2306 if (
Tok.
is(tok::colon))
2310 }
else if (Kind == OMPC_allocate) {
2313 TentativeParsingAction TPA(*
this);
2315 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2319 if (
Tok.
is(tok::colon)) {
2332 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2338 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
2339 Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
2340 (Kind == OMPC_reduction && !InvalidReductionId) ||
2343 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
2345 Tok.
isNot(tok::annot_pragma_openmp_end))) {
2349 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2351 Vars.push_back(VarExpr.
get());
2353 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2357 IsComma =
Tok.
is(tok::comma);
2360 else if (
Tok.
isNot(tok::r_paren) &&
2361 Tok.
isNot(tok::annot_pragma_openmp_end) &&
2362 (!MayHaveTail ||
Tok.
isNot(tok::colon)))
2363 Diag(
Tok, diag::err_omp_expected_punc)
2366 << (Kind == OMPC_flush);
2370 if (NeedRParenForLinear)
2374 const bool MustHaveTail = MayHaveTail &&
Tok.
is(tok::colon);
2378 ExprResult Tail = ParseAssignmentExpression();
2380 Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
false);
2384 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2389 Data.
RLoc =
Tok.getLocation();
2394 (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
2395 (MustHaveTail && !Data.
TailExpr) || InvalidReductionId ||
2396 IsInvalidMapperModifier;
2454 if (ParseOpenMPVarList(DKind,
Kind, Vars, Data))
2460 return Actions.ActOnOpenMPVarListClause(
OpenMPDependClauseKind DepKind
OpenMPFromModifierKind
OpenMP modifier kind for 'from' clause.
Defines the clang::ASTContext interface.
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.
A (possibly-)qualified type.
static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P)
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)) {...
DeclarationNameInfo ReductionOrMapperId
bool isEmpty() const
No scope specifier.
Decl - This represents one declaration (or definition), e.g.
SmallVector< OpenMPMapModifierKind, OMPMapClause::NumberOfModifiers > MapTypeModifiers
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 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
Represents a variable declaration or definition.
ActionResult< Stmt * > StmtResult
Information about one declarator, including the parsed type information and the identifier.
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...
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
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
The collection of all-type qualifiers we support.
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
Base wrapper for a particular "section" of type source info.
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.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
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.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OpenMPDirectiveKind Kind)
Called on correct id-expression from the '#pragma omp threadprivate'.
Represents a C++ nested-name-specifier or a global scope specifier.
IdentifierInfo * getIdentifier() const
Sema - This implements semantic analysis and AST building for C.
A RAII object to enter scope of a compound statement.
DeclarationNameTable DeclarationNames
This is the scope of OpenMP executable directive.
Sema & getActions() const
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.
const Token & getCurToken() const
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.
static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data)
Parse map-type in map clause.
Preprocessor & getPreprocessor() const
SmallVector< SourceLocation, OMPMapClause::NumberOfModifiers > MapTypeModifiersLoc
SourceLocation getOpenLocation() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
static OpenMPMapModifierKind isMapModifier(Parser &P)
Checks if the token is a valid map-type-modifier.
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.
OpenMPLinearClauseKind Modifier
Modifier of 'linear' clause.
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.
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
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.
static OpenMPMapClauseKind isMapType(Parser &P)
Checks if the token is a valid map-type.
This is a scope that corresponds to the template parameters of a C++ template.
The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
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
OpenMPToModifierKind
OpenMP modifier kind for 'to' clause.
CXXScopeSpec ReductionOrMapperIdScopeSpec
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.
OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str)
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
This is a scope that can contain a declaration.
Captures information about "declaration specifiers".
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 represents '#pragma omp declare mapper ...' directive.
This is the scope of some OpenMP loop directive.
bool parseMapTypeModifiers(OpenMPVarListDataTy &Data)
Parses map-type-modifiers in map clause.
bool parseMapperModifier(OpenMPVarListDataTy &Data)
Parses the mapper modifier in map, to, and from clauses.
This structure contains most locations needed for by an OMPVarListClause.
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.
This represents a decl that may have a name.
Directive - Abstract class representing a parsed verify directive.
SourceLocation getBegin() const
VerifyDiagnosticConsumer::Directive Directive
SourceLocation getLocation() const
OpenMPMapClauseKind MapType
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
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