23 #include "llvm/ADT/PointerIntPair.h"
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/ADT/UniqueVector.h"
26 #include "llvm/Frontend/OpenMP/OMPAssume.h"
27 #include "llvm/Frontend/OpenMP/OMPContext.h"
29 using namespace clang;
30 using namespace llvm::omp;
37 enum OpenMPDirectiveKindEx {
38 OMPD_cancellation = llvm::omp::Directive_enumSize + 1,
50 OMPD_distribute_parallel,
51 OMPD_teams_distribute_parallel,
52 OMPD_target_teams_distribute_parallel,
62 struct OpenMPDirectiveKindExWrapper {
65 bool operator==(OpenMPDirectiveKindExWrapper
V)
const {
68 bool operator!=(OpenMPDirectiveKindExWrapper
V)
const {
79 class DeclDirectiveListParserHelper final {
88 ExprResult Res =
P->getActions().ActOnOpenMPIdExpression(
89 P->getCurScope(), SS, NameInfo,
Kind);
91 Identifiers.push_back(Res.
get());
100 OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);
101 if (DKind != OMPD_unknown)
104 return llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)
105 .Case(
"cancellation", OMPD_cancellation)
106 .Case(
"data", OMPD_data)
107 .Case(
"declare", OMPD_declare)
108 .Case(
"end", OMPD_end)
109 .Case(
"enter", OMPD_enter)
110 .Case(
"exit", OMPD_exit)
111 .Case(
"point", OMPD_point)
112 .Case(
"reduction", OMPD_reduction)
113 .Case(
"update", OMPD_update)
114 .Case(
"mapper", OMPD_mapper)
115 .Case(
"variant", OMPD_variant)
116 .Case(
"begin", OMPD_begin)
117 .Default(OMPD_unknown);
124 static const OpenMPDirectiveKindExWrapper F[][3] = {
125 {OMPD_begin, OMPD_declare, OMPD_begin_declare},
126 {OMPD_begin, OMPD_assumes, OMPD_begin_assumes},
127 {OMPD_end, OMPD_declare, OMPD_end_declare},
128 {OMPD_end, OMPD_assumes, OMPD_end_assumes},
129 {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
130 {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
131 {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
132 {OMPD_declare, OMPD_simd, OMPD_declare_simd},
133 {OMPD_declare, OMPD_target, OMPD_declare_target},
134 {OMPD_declare, OMPD_variant, OMPD_declare_variant},
135 {OMPD_begin_declare, OMPD_target, OMPD_begin_declare_target},
136 {OMPD_begin_declare, OMPD_variant, OMPD_begin_declare_variant},
137 {OMPD_end_declare, OMPD_variant, OMPD_end_declare_variant},
138 {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
139 {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
140 {OMPD_distribute_parallel_for, OMPD_simd,
141 OMPD_distribute_parallel_for_simd},
142 {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
143 {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
144 {OMPD_target, OMPD_data, OMPD_target_data},
145 {OMPD_target, OMPD_enter, OMPD_target_enter},
146 {OMPD_target, OMPD_exit, OMPD_target_exit},
147 {OMPD_target, OMPD_update, OMPD_target_update},
148 {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
149 {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
150 {OMPD_for, OMPD_simd, OMPD_for_simd},
151 {OMPD_parallel, OMPD_for, OMPD_parallel_for},
152 {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
153 {OMPD_parallel, OMPD_loop, OMPD_parallel_loop},
154 {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
155 {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
156 {OMPD_target, OMPD_parallel, OMPD_target_parallel},
157 {OMPD_target, OMPD_simd, OMPD_target_simd},
158 {OMPD_target_parallel, OMPD_loop, OMPD_target_parallel_loop},
159 {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
160 {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
161 {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
162 {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
163 {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
164 {OMPD_teams_distribute_parallel, OMPD_for,
165 OMPD_teams_distribute_parallel_for},
166 {OMPD_teams_distribute_parallel_for, OMPD_simd,
167 OMPD_teams_distribute_parallel_for_simd},
168 {OMPD_teams, OMPD_loop, OMPD_teams_loop},
169 {OMPD_target, OMPD_teams, OMPD_target_teams},
170 {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
171 {OMPD_target_teams, OMPD_loop, OMPD_target_teams_loop},
172 {OMPD_target_teams_distribute, OMPD_parallel,
173 OMPD_target_teams_distribute_parallel},
174 {OMPD_target_teams_distribute, OMPD_simd,
175 OMPD_target_teams_distribute_simd},
176 {OMPD_target_teams_distribute_parallel, OMPD_for,
177 OMPD_target_teams_distribute_parallel_for},
178 {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
179 OMPD_target_teams_distribute_parallel_for_simd},
180 {OMPD_master, OMPD_taskloop, OMPD_master_taskloop},
181 {OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},
182 {OMPD_parallel, OMPD_master, OMPD_parallel_master},
183 {OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},
184 {OMPD_parallel_master_taskloop, OMPD_simd,
185 OMPD_parallel_master_taskloop_simd}};
186 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
187 Token Tok =
P.getCurToken();
188 OpenMPDirectiveKindExWrapper DKind =
190 ?
static_cast<unsigned>(OMPD_unknown)
192 if (DKind == OMPD_unknown)
195 for (
unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
196 if (DKind != F[I][0])
199 Tok =
P.getPreprocessor().LookAhead(0);
200 OpenMPDirectiveKindExWrapper SDKind =
202 ?
static_cast<unsigned>(OMPD_unknown)
204 if (SDKind == OMPD_unknown)
207 if (SDKind == F[I][1]) {
212 return unsigned(DKind) < llvm::omp::Directive_enumSize
218 Token Tok =
P.getCurToken();
219 Sema &Actions =
P.getActions();
222 bool WithOperator =
false;
223 if (Tok.
is(tok::kw_operator)) {
225 Tok =
P.getCurToken();
253 case tok::identifier:
258 P.Diag(Tok.
getLocation(), diag::err_omp_expected_reduction_identifier);
259 P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
266 : DeclNames.getCXXOperatorName(OOK);
283 if (T.expectAndConsume(
284 diag::err_expected_lparen_after,
285 getOpenMPDirectiveName(OMPD_declare_reduction).data())) {
286 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
287 return DeclGroupPtrTy();
291 if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
292 return DeclGroupPtrTy();
295 bool IsCorrect = !ExpectAndConsume(tok::colon);
297 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
298 return DeclGroupPtrTy();
300 IsCorrect = IsCorrect && !Name.isEmpty();
302 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
303 Diag(Tok.getLocation(), diag::err_expected_type);
307 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
308 return DeclGroupPtrTy();
318 Actions.ActOnOpenMPDeclareReductionType(
Range.getBegin(), TR);
319 if (!ReductionType.
isNull()) {
320 ReductionTypes.push_back(
321 std::make_pair(ReductionType,
Range.getBegin()));
324 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
328 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
332 if (ExpectAndConsume(tok::comma)) {
334 if (Tok.is(tok::annot_pragma_openmp_end)) {
335 Diag(Tok.getLocation(), diag::err_expected_type);
336 return DeclGroupPtrTy();
339 }
while (Tok.isNot(tok::annot_pragma_openmp_end));
341 if (ReductionTypes.empty()) {
342 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
343 return DeclGroupPtrTy();
346 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
347 return DeclGroupPtrTy();
350 if (ExpectAndConsume(tok::colon))
353 if (Tok.is(tok::annot_pragma_openmp_end)) {
354 Diag(Tok.getLocation(), diag::err_expected_expression);
355 return DeclGroupPtrTy();
358 DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
359 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
363 unsigned I = 0, E = ReductionTypes.size();
364 for (
Decl *D : DRD.get()) {
365 TentativeParsingAction TPA(*
this);
370 Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
371 ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
372 ParseExpression().get(), D->getLocation(),
false);
373 Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.
get());
375 if (CombinerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
376 Tok.isNot(tok::annot_pragma_openmp_end)) {
381 IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.
isUsable();
383 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
385 if (Tok.is(tok::identifier) &&
386 Tok.getIdentifierInfo()->isStr(
"initializer")) {
389 Diag(Tok.getLocation(), diag::err_expected) <<
"'initializer'";
396 tok::annot_pragma_openmp_end);
398 !T.expectAndConsume(diag::err_expected_lparen_after,
"initializer") &&
400 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
406 Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
409 if (Tok.is(tok::identifier) &&
410 Tok.getIdentifierInfo()->isStr(
"omp_priv")) {
412 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
414 InitializerResult = Actions.ActOnFinishFullExpr(
415 ParseAssignmentExpression().get(), D->getLocation(),
418 Actions.ActOnOpenMPDeclareReductionInitializerEnd(
419 D, InitializerResult.
get(), OmpPrivParm);
420 if (InitializerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
421 Tok.isNot(tok::annot_pragma_openmp_end)) {
427 !T.consumeClose() && IsCorrect && !InitializerResult.
isInvalid();
439 return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
443 void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
446 if (isTokenEqualOrEqualTypo()) {
449 if (Tok.is(tok::code_completion)) {
451 Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
452 Actions.FinalizeDeclaration(OmpPrivParm);
456 PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
459 if (Init.isInvalid()) {
460 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
461 Actions.ActOnInitializerError(OmpPrivParm);
463 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
466 }
else if (Tok.is(tok::l_paren)) {
472 CommaLocsTy CommaLocs;
475 auto RunSignatureHelp = [
this, OmpPrivParm, LParLoc, &Exprs]() {
476 QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
478 OmpPrivParm->
getLocation(), Exprs, LParLoc,
false);
479 CalledSignatureHelp =
true;
480 return PreferredType;
482 if (ParseExpressionList(Exprs, CommaLocs, [&] {
483 PreferredType.enterFunctionArgument(Tok.getLocation(),
486 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
488 Actions.ActOnInitializerError(OmpPrivParm);
489 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
493 if (!T.consumeClose())
494 RLoc = T.getCloseLocation();
496 assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
497 "Unexpected number of commas!");
500 Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
501 Actions.AddInitializerToDecl(OmpPrivParm,
Initializer.get(),
504 }
else if (getLangOpts().
CPlusPlus11 && Tok.is(tok::l_brace)) {
506 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
510 if (Init.isInvalid()) {
511 Actions.ActOnInitializerError(OmpPrivParm);
513 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
517 Actions.ActOnUninitializedDecl(OmpPrivParm);
531 bool IsCorrect =
true;
534 if (T.expectAndConsume(diag::err_expected_lparen_after,
535 getOpenMPDirectiveName(OMPD_declare_mapper).data())) {
536 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
537 return DeclGroupPtrTy();
541 auto &DeclNames = Actions.getASTContext().DeclarationNames;
543 if (PP.LookAhead(0).is(tok::colon)) {
544 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
545 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
548 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
552 ExpectAndConsume(tok::colon);
556 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get(
"default"));
559 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
560 return DeclGroupPtrTy();
574 return DeclGroupPtrTy();
578 IsCorrect &= !T.consumeClose();
581 return DeclGroupPtrTy();
589 ParseScope OMPDirectiveScope(
this, ScopeFlags);
590 Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
593 ExprResult MapperVarRef = Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
594 getCurScope(), MapperType,
Range.getBegin(), VName);
598 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
601 : getOpenMPClauseKind(PP.getSpelling(Tok));
602 Actions.StartOpenMPClause(CKind);
604 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
606 Clauses.push_back(Clause);
610 if (Tok.is(tok::comma))
612 Actions.EndOpenMPClause();
614 if (Clauses.empty()) {
615 Diag(Tok, diag::err_omp_expected_clause)
616 << getOpenMPDirectiveName(OMPD_declare_mapper);
621 Actions.EndOpenMPDSABlock(
nullptr);
622 OMPDirectiveScope.Exit();
623 DeclGroupPtrTy DG = Actions.ActOnOpenMPDeclareMapperDirective(
624 getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
625 Range.getBegin(), VName, AS, MapperVarRef.
get(), Clauses);
627 return DeclGroupPtrTy();
636 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
638 ParseSpecifierQualifierList(DS, AS, DSC);
643 ParseDeclarator(DeclaratorInfo);
644 Range = DeclaratorInfo.getSourceRange();
645 if (DeclaratorInfo.getIdentifier() ==
nullptr) {
646 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
649 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
651 return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
660 class FNContextRAII final {
664 bool HasFunScope =
false;
665 FNContextRAII() =
delete;
666 FNContextRAII(
const FNContextRAII &) =
delete;
667 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
674 Sema &Actions =
P.getActions();
682 P.ReenterTemplateScopes(Scopes, D);
694 P.getActions().ActOnExitFunctionContext();
713 const Token &Tok =
P.getCurToken();
714 bool IsError =
false;
715 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
716 if (Tok.
isNot(tok::identifier))
718 OMPDeclareSimdDeclAttr::BranchStateTy Out;
720 StringRef ClauseName = II->
getName();
722 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
723 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
724 P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
726 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
732 }
else if (ClauseName.equals(
"simdlen")) {
734 P.Diag(Tok, diag::err_omp_more_one_clause)
735 << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
740 SimdLen =
P.ParseOpenMPParensExpr(ClauseName, RLoc);
745 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
746 CKind == OMPC_linear) {
749 if (CKind == OMPC_aligned) {
751 }
else if (CKind == OMPC_linear) {
757 if (
P.ParseOpenMPVarList(OMPD_declare_simd,
758 getOpenMPClauseKind(ClauseName), *Vars, Data))
760 if (CKind == OMPC_aligned) {
761 Alignments.append(Aligneds.size() - Alignments.size(),
763 }
else if (CKind == OMPC_linear) {
766 "Unexpected linear modifier.");
767 if (
P.getActions().CheckOpenMPLinearModifier(
771 LinModifiers.append(Linears.size() - LinModifiers.size(),
780 if (Tok.
is(tok::comma))
790 PP.EnterToken(Tok,
true);
791 PP.EnterTokenStream(Toks,
true,
794 ConsumeAnyToken(
true);
795 ConsumeAnyToken(
true);
797 FNContextRAII FnContext(*
this, Ptr);
798 OMPDeclareSimdDeclAttr::BranchStateTy BS =
799 OMPDeclareSimdDeclAttr::BS_Undefined;
809 Alignments, Linears, LinModifiers, Steps);
810 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
816 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
824 CONTEXT_SELECTOR_SET_LVL = 0,
825 CONTEXT_SELECTOR_LVL = 1,
826 CONTEXT_TRAIT_LVL = 2,
829 static StringRef stringLiteralParser(
Parser &
P) {
830 ExprResult Res =
P.ParseStringLiteralExpression(
true);
834 static StringRef getNameFromIdOrString(
Parser &
P,
Token &Tok,
836 if (Tok.
is(tok::identifier) || Tok.
is(tok::kw_for)) {
838 StringRef Name =
P.getPreprocessor().getSpelling(Tok, Buffer);
839 (void)
P.ConsumeToken();
844 return stringLiteralParser(
P);
847 diag::warn_omp_declare_variant_string_literal_or_identifier)
852 static bool checkForDuplicates(
Parser &
P, StringRef Name,
854 llvm::StringMap<SourceLocation> &Seen,
856 auto Res = Seen.try_emplace(Name, NameLoc);
862 P.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
864 P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
871 llvm::omp::TraitSet Set,
873 llvm::StringMap<SourceLocation> &Seen) {
874 TIProperty.
Kind = TraitProperty::invalid;
877 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_TRAIT_LVL);
880 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set,
Selector);
885 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(Set,
Selector, Name);
886 if (TIProperty.
Kind != TraitProperty::invalid) {
887 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
888 TIProperty.
Kind = TraitProperty::invalid;
894 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
895 << Name << getOpenMPContextTraitSelectorName(
Selector)
896 << getOpenMPContextTraitSetName(Set);
898 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
899 if (SetForName != TraitSet::invalid) {
900 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
901 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
902 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
903 << Name <<
"<selector-name>"
904 <<
"(<property-name>)";
907 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
908 if (SelectorForName != TraitSelector::invalid) {
909 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
910 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
911 bool AllowsTraitScore =
false;
912 bool RequiresProperty =
false;
913 isValidTraitSelectorForTraitSet(
914 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
915 AllowsTraitScore, RequiresProperty);
916 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
917 << getOpenMPContextTraitSetName(
918 getOpenMPContextTraitSetForSelector(SelectorForName))
919 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
922 for (
const auto &PotentialSet :
923 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
925 TraitProperty PropertyForName =
926 getOpenMPContextTraitPropertyKind(PotentialSet,
Selector, Name);
927 if (PropertyForName == TraitProperty::invalid)
929 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
930 << getOpenMPContextTraitSetName(
931 getOpenMPContextTraitSetForProperty(PropertyForName))
932 << getOpenMPContextTraitSelectorName(
933 getOpenMPContextTraitSelectorForProperty(PropertyForName))
934 << (
"(" + Name +
")").str();
937 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
938 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set,
Selector);
944 llvm::StringMap<SourceLocation> &Seen) {
945 assert(TISelector.
Kind ==
946 llvm::omp::TraitSelector::implementation_extension &&
947 "Only for extension properties, e.g., "
948 "`implementation={extension(PROPERTY)}`");
949 if (TIProperty.
Kind == TraitProperty::invalid)
952 if (TIProperty.
Kind ==
953 TraitProperty::implementation_extension_disable_implicit_base)
956 if (TIProperty.
Kind ==
957 TraitProperty::implementation_extension_allow_templates)
962 llvm::omp::TraitProperty::implementation_extension_match_all ||
964 llvm::omp::TraitProperty::implementation_extension_match_any ||
966 llvm::omp::TraitProperty::implementation_extension_match_none);
969 if (IsMatchExtension(TIProperty)) {
971 if (IsMatchExtension(SeenProp)) {
972 P.Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
973 StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
976 P.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
977 << CONTEXT_TRAIT_LVL << SeenName;
983 llvm_unreachable(
"Unknown extension property!");
987 llvm::omp::TraitSet Set,
988 llvm::StringMap<SourceLocation> &Seen) {
989 assert(TISelector.
Kind != TraitSelector::user_condition &&
990 "User conditions are special properties not handled here!");
994 parseOMPTraitPropertyKind(TIProperty, Set, TISelector.
Kind, Seen);
996 if (TISelector.
Kind == llvm::omp::TraitSelector::implementation_extension)
999 TIProperty.
Kind = TraitProperty::invalid;
1002 if (TIProperty.
Kind == TraitProperty::invalid) {
1004 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1005 << CONTEXT_TRAIT_LVL;
1009 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.
Kind,
1010 TISelector.
Kind, Set)) {
1018 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
1019 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
1021 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1022 << getOpenMPContextTraitSetName(Set);
1023 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
1024 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
1026 << getOpenMPContextTraitSelectorName(
1027 getOpenMPContextTraitSelectorForProperty(TIProperty.
Kind))
1028 << getOpenMPContextTraitSetName(
1029 getOpenMPContextTraitSetForProperty(TIProperty.
Kind));
1030 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1031 << CONTEXT_TRAIT_LVL;
1035 llvm::omp::TraitSet Set,
1036 llvm::StringMap<SourceLocation> &Seen) {
1037 TISelector.
Kind = TraitSelector::invalid;
1040 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_LVL);
1043 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1047 TISelector.
Kind = getOpenMPContextTraitSelectorKind(Name);
1048 if (TISelector.
Kind != TraitSelector::invalid) {
1049 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1050 TISelector.
Kind = TraitSelector::invalid;
1055 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1056 << Name << getOpenMPContextTraitSetName(Set);
1058 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1059 if (SetForName != TraitSet::invalid) {
1060 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1061 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1062 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1063 << Name <<
"<selector-name>"
1064 <<
"<property-name>";
1067 for (
const auto &PotentialSet :
1068 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1069 TraitSet::device}) {
1070 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1071 PotentialSet, TraitSelector::invalid, Name);
1072 if (PropertyForName == TraitProperty::invalid)
1074 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1075 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1076 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1077 << getOpenMPContextTraitSetName(
1078 getOpenMPContextTraitSetForProperty(PropertyForName))
1079 << getOpenMPContextTraitSelectorName(
1080 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1081 << (
"(" + Name +
")").str();
1084 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1085 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1092 StringRef SelectorName =
1093 P.getPreprocessor().getSpelling(
P.getCurToken(), Buffer);
1094 if (!SelectorName.equals(
"score"))
1096 (void)
P.ConsumeToken();
1098 ScoreExpr =
P.ParseOpenMPParensExpr(SelectorName, RLoc);
1100 if (
P.getCurToken().is(tok::colon))
1101 (
void)
P.ConsumeAnyToken();
1103 P.Diag(
P.getCurToken(), diag::warn_omp_declare_variant_expected)
1105 <<
"score expression";
1112 void Parser::parseOMPContextSelector(
1114 llvm::StringMap<SourceLocation> &SeenSelectors) {
1115 unsigned short OuterPC = ParenCount;
1120 auto FinishSelector = [OuterPC,
this]() ->
void {
1123 while (!SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1124 tok::annot_pragma_openmp_end},
1127 if (Tok.
is(tok::r_paren) && OuterPC > ParenCount)
1128 (
void)ConsumeParen();
1129 if (OuterPC <= ParenCount) {
1133 if (!Tok.
is(tok::comma) && !Tok.
is(tok::r_paren)) {
1137 (void)ConsumeAnyToken();
1139 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1140 << CONTEXT_SELECTOR_LVL;
1144 parseOMPTraitSelectorKind(TISelector, Set, SeenSelectors);
1145 if (TISelector.
Kind == TraitSelector::invalid)
1146 return FinishSelector();
1148 bool AllowsTraitScore =
false;
1149 bool RequiresProperty =
false;
1150 if (!isValidTraitSelectorForTraitSet(TISelector.
Kind, Set, AllowsTraitScore,
1151 RequiresProperty)) {
1152 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1153 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1154 << getOpenMPContextTraitSetName(Set);
1155 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1156 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1157 << getOpenMPContextTraitSetName(
1158 getOpenMPContextTraitSetForSelector(TISelector.
Kind))
1159 << RequiresProperty;
1160 return FinishSelector();
1163 if (!RequiresProperty) {
1165 {getOpenMPContextTraitPropertyForSelector(TISelector.
Kind),
1166 getOpenMPContextTraitSelectorName(TISelector.
Kind)});
1170 if (!Tok.
is(tok::l_paren)) {
1171 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1172 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1173 << getOpenMPContextTraitSetName(Set);
1174 return FinishSelector();
1177 if (TISelector.
Kind == TraitSelector::user_condition) {
1181 return FinishSelector();
1184 {TraitProperty::user_condition_unknown,
"<condition>"});
1189 tok::annot_pragma_openmp_end);
1191 (void)BDT.consumeOpen();
1196 if (!AllowsTraitScore && !Score.
isUnset()) {
1198 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1199 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1200 << getOpenMPContextTraitSetName(Set) << Score.
get();
1202 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1203 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1204 << getOpenMPContextTraitSetName(Set) <<
"<invalid>";
1212 llvm::StringMap<SourceLocation> SeenProperties;
1214 parseOMPContextProperty(TISelector, Set, SeenProperties);
1215 }
while (TryConsumeToken(tok::comma));
1221 void Parser::parseOMPTraitSetKind(
OMPTraitSet &TISet,
1222 llvm::StringMap<SourceLocation> &Seen) {
1223 TISet.
Kind = TraitSet::invalid;
1226 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_SET_LVL);
1229 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1233 TISet.
Kind = getOpenMPContextTraitSetKind(Name);
1234 if (TISet.
Kind != TraitSet::invalid) {
1235 if (checkForDuplicates(*
this, Name, NameLoc, Seen,
1236 CONTEXT_SELECTOR_SET_LVL))
1237 TISet.
Kind = TraitSet::invalid;
1242 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1244 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1245 if (SelectorForName != TraitSelector::invalid) {
1246 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1247 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1248 bool AllowsTraitScore =
false;
1249 bool RequiresProperty =
false;
1250 isValidTraitSelectorForTraitSet(
1251 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1252 AllowsTraitScore, RequiresProperty);
1253 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1254 << getOpenMPContextTraitSetName(
1255 getOpenMPContextTraitSetForSelector(SelectorForName))
1256 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
1259 for (
const auto &PotentialSet :
1260 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1261 TraitSet::device}) {
1262 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1263 PotentialSet, TraitSelector::invalid, Name);
1264 if (PropertyForName == TraitProperty::invalid)
1266 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1267 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1268 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1269 << getOpenMPContextTraitSetName(
1270 getOpenMPContextTraitSetForProperty(PropertyForName))
1271 << getOpenMPContextTraitSelectorName(
1272 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1273 << (
"(" + Name +
")").str();
1276 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1277 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1283 void Parser::parseOMPContextSelectorSet(
1284 OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1285 auto OuterBC = BraceCount;
1290 auto FinishSelectorSet = [
this, OuterBC]() ->
void {
1293 while (!SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1294 tok::annot_pragma_openmp_end},
1297 if (Tok.
is(tok::r_brace) && OuterBC > BraceCount)
1298 (
void)ConsumeBrace();
1299 if (OuterBC <= BraceCount) {
1303 if (!Tok.
is(tok::comma) && !Tok.
is(tok::r_brace)) {
1307 (void)ConsumeAnyToken();
1309 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1310 << CONTEXT_SELECTOR_SET_LVL;
1313 parseOMPTraitSetKind(TISet, SeenSets);
1314 if (TISet.
Kind == TraitSet::invalid)
1315 return FinishSelectorSet();
1318 if (!TryConsumeToken(tok::equal))
1321 << (
"context set name \"" + getOpenMPContextTraitSetName(TISet.
Kind) +
1326 if (Tok.
is(tok::l_brace)) {
1327 (void)ConsumeBrace();
1331 << (
"'=' that follows the context set name \"" +
1332 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1336 llvm::StringMap<SourceLocation> SeenSelectors;
1339 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1340 if (TISelector.
Kind != TraitSelector::invalid &&
1343 }
while (TryConsumeToken(tok::comma));
1346 if (Tok.
is(tok::r_brace)) {
1347 (void)ConsumeBrace();
1351 << (
"context selectors for the context set \"" +
1352 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1361 llvm::StringMap<SourceLocation> SeenSets;
1364 parseOMPContextSelectorSet(TISet, SeenSets);
1365 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1366 TI.
Sets.push_back(TISet);
1367 }
while (TryConsumeToken(tok::comma));
1376 PP.EnterToken(Tok,
true);
1377 PP.EnterTokenStream(Toks,
true,
1380 ConsumeAnyToken(
true);
1381 ConsumeAnyToken(
true);
1383 FNContextRAII FnContext(*
this, Ptr);
1394 AssociatedFunction = ParseOpenMPParensExpr(
1395 getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1398 if (!AssociatedFunction.
isUsable()) {
1399 if (!Tok.
is(tok::annot_pragma_openmp_end))
1400 while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1403 (void)ConsumeAnnotationToken();
1407 OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
1416 if (Tok.
is(tok::annot_pragma_openmp_end)) {
1418 << (getLangOpts().OpenMP < 51 ? 0 : 1);
1421 bool IsError =
false;
1422 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1425 : getOpenMPClauseKind(PP.getSpelling(Tok));
1426 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1427 getLangOpts().OpenMP)) {
1429 << (getLangOpts().OpenMP < 51 ? 0 : 1);
1435 IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1437 case OMPC_adjust_args: {
1442 IsError = ParseOpenMPVarList(OMPD_declare_variant, OMPC_adjust_args,
1445 llvm::append_range(Data.
ExtraModifier == OMPC_ADJUST_ARGS_nothing
1447 : AdjustNeedDevicePtr,
1451 case OMPC_append_args:
1452 if (!AppendArgs.empty()) {
1453 Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1454 << getOpenMPDirectiveName(OMPD_declare_variant)
1455 << getOpenMPClauseName(CKind) << 0;
1461 IsError = parseOpenMPAppendArgs(AppendArgs);
1465 llvm_unreachable(
"Unexpected clause for declare variant.");
1469 while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1472 (void)ConsumeAnnotationToken();
1476 if (Tok.
is(tok::comma))
1482 Ptr, AssociatedFunction.
get(), TI, AppendArgs.size(),
1485 if (DeclVarData && !TI.
Sets.empty())
1487 DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1488 AdjustNeedDevicePtr, AppendArgs, AdjustArgsLoc, AppendArgsLoc,
1492 (void)ConsumeAnnotationToken();
1499 const Token &Tok =
P.getCurToken();
1500 bool HasError =
false;
1501 bool IsTarget =
false;
1502 bool IsTargetSync =
false;
1504 while (Tok.
is(tok::identifier)) {
1510 P.Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
1514 P.Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
1515 IsTargetSync =
true;
1518 P.Diag(Tok, diag::err_omp_expected_interop_type);
1522 if (!Tok.
is(tok::comma))
1529 if (!IsTarget && !IsTargetSync) {
1530 P.Diag(Tok, diag::err_omp_expected_interop_type);
1536 if (IsTarget && IsTargetSync)
1537 return OMPDeclareVariantAttr::Target_TargetSync;
1539 return OMPDeclareVariantAttr::Target;
1540 return OMPDeclareVariantAttr::TargetSync;
1543 bool Parser::parseOpenMPAppendArgs(
1545 bool HasError =
false;
1548 if (T.expectAndConsume(diag::err_expected_lparen_after,
1549 getOpenMPClauseName(OMPC_append_args).data()))
1557 tok::annot_pragma_openmp_end);
1558 if (IT.expectAndConsume(diag::err_expected_lparen_after,
"interop"))
1564 InterOpTypes.push_back(IType.getValue());
1569 if (Tok.
is(tok::comma))
1572 if (!HasError && InterOpTypes.empty()) {
1575 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1578 HasError = T.consumeClose() || HasError;
1582 bool Parser::parseOMPDeclareVariantMatchClause(
SourceLocation Loc,
1588 : getOpenMPClauseKind(PP.getSpelling(Tok));
1589 if (CKind != OMPC_match) {
1591 << (getLangOpts().OpenMP < 51 ? 0 : 1);
1594 (void)ConsumeToken();
1597 if (T.expectAndConsume(diag::err_expected_lparen_after,
1598 getOpenMPClauseName(OMPC_match).data()))
1602 parseOMPContextSelectors(Loc, TI);
1605 (void)T.consumeClose();
1616 bool MergedSet =
false;
1622 bool MergedSelector =
false;
1626 MergedSelector =
true;
1629 bool MergedProperty =
false;
1643 if (
Selector.Kind == llvm::omp::TraitSelector::user_condition) {
1644 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1645 }
else if (
Selector.ScoreOrCondition !=
1647 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1648 << getOpenMPContextTraitPropertyName(
1650 << getOpenMPContextTraitSelectorName(ParentSelector.
Kind)
1651 << getOpenMPContextTraitSetName(ParentSet.
Kind);
1654 if (!MergedProperty)
1655 Selector.Properties.push_back(ParentProperty);
1658 if (!MergedSelector)
1659 Set.
Selectors.push_back(ParentSelector);
1663 TI.
Sets.push_back(ParentSet);
1684 bool SkippedClauses =
false;
1686 auto SkipBraces = [&](llvm::StringRef Spelling,
bool IssueNote) {
1688 tok::annot_pragma_openmp_end);
1689 if (T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1692 if (IssueNote && T.getCloseLocation().isValid())
1693 Diag(T.getCloseLocation(),
1694 diag::note_omp_assumption_clause_continue_here);
1700 auto MatchACMClause = [&](StringRef RawString) {
1701 llvm::StringSwitch<int> SS(RawString);
1702 unsigned ACMIdx = 0;
1703 for (
const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1704 if (ACMI.StartsWith)
1705 SS.StartsWith(ACMI.Identifier, ACMIdx++);
1707 SS.Case(ACMI.Identifier, ACMIdx++);
1709 return SS.Default(-1);
1712 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1718 Idx = MatchACMClause(II->
getName());
1722 bool NextIsLPar = Tok.
is(tok::l_paren);
1725 Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1726 << llvm::omp::getOpenMPDirectiveName(DKind)
1727 << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1729 SkipBraces(II ? II->
getName() :
"",
true);
1730 SkippedClauses =
true;
1733 const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1734 if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1737 SkippedClauses =
true;
1738 SkipBraces(II->
getName(),
false);
1744 diag::warn_omp_unknown_assumption_clause_without_args)
1746 SkipBraces(II->
getName(),
true);
1749 assert(II &&
"Expected an identifier clause!");
1751 if (ACMI.StartsWith)
1752 Assumption =
"ompx_" + Assumption.substr(ACMI.Identifier.size());
1754 Assumption =
"omp_" + Assumption;
1755 Assumptions.push_back(Assumption);
1761 void Parser::ParseOpenMPEndAssumesDirective(
SourceLocation Loc) {
1765 Diag(Loc, diag::err_expected_begin_assumes);
1779 struct SimpleClauseData {
1793 const Token &Tok =
P.getCurToken();
1799 getOpenMPClauseName(
Kind).data()))
1806 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
1807 Tok.
isNot(tok::annot_pragma_openmp_end))
1808 P.ConsumeAnyToken();
1815 return SimpleClauseData(
Type, Loc, LOpen,
TypeLoc, RLoc);
1818 void Parser::ParseOMPDeclareTargetClauses(
1819 Sema::DeclareTargetContextInfo &DTCI) {
1821 bool RequiresToOrLinkOrIndirectClause =
false;
1822 bool HasToOrLinkOrIndirectClause =
false;
1823 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1824 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1825 bool HasIdentifier = Tok.
is(tok::identifier);
1826 if (HasIdentifier) {
1828 RequiresToOrLinkOrIndirectClause =
true;
1830 StringRef ClauseName = II->
getName();
1831 bool IsDeviceTypeClause =
1832 getLangOpts().OpenMP >= 50 &&
1833 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1835 bool IsIndirectClause = getLangOpts().OpenMP >= 51 &&
1836 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1837 if (DTCI.Indirect.hasValue() && IsIndirectClause) {
1838 Diag(Tok, diag::err_omp_more_one_clause)
1839 << getOpenMPDirectiveName(OMPD_declare_target)
1840 << getOpenMPClauseName(OMPC_indirect) << 0;
1843 bool IsToOrLinkClause =
1844 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1845 assert((!IsDeviceTypeClause || !IsToOrLinkClause) &&
"Cannot be both!");
1847 if (!IsDeviceTypeClause && !IsIndirectClause &&
1848 DTCI.Kind == OMPD_begin_declare_target) {
1849 Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1850 << ClauseName << (getLangOpts().OpenMP >= 51 ? 3 : 0);
1853 if (!IsDeviceTypeClause && !IsToOrLinkClause && !IsIndirectClause) {
1854 Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1856 << (getLangOpts().OpenMP >= 51 ? 4
1857 : getLangOpts().OpenMP >= 50 ? 2
1862 if (IsToOrLinkClause || IsIndirectClause)
1863 HasToOrLinkOrIndirectClause =
true;
1865 if (IsIndirectClause) {
1866 if (!ParseOpenMPIndirectClause(DTCI,
false))
1871 if (IsDeviceTypeClause) {
1874 if (DevTypeData.hasValue()) {
1875 if (DeviceTypeLoc.
isValid()) {
1877 Diag(DevTypeData.getValue().Loc,
1878 diag::warn_omp_more_one_device_type_clause);
1882 case OMPC_DEVICE_TYPE_any:
1883 DTCI.DT = OMPDeclareTargetDeclAttr::DT_Any;
1885 case OMPC_DEVICE_TYPE_host:
1886 DTCI.DT = OMPDeclareTargetDeclAttr::DT_Host;
1888 case OMPC_DEVICE_TYPE_nohost:
1889 DTCI.DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1892 llvm_unreachable(
"Unexpected device_type");
1894 DeviceTypeLoc = DevTypeData.getValue().Loc;
1901 if (DTCI.Kind == OMPD_declare_target || HasIdentifier) {
1909 bool FirstMapping = DTCI.ExplicitlyMapped.try_emplace(ND, MI).second;
1911 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1914 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1919 if (Tok.
is(tok::l_paren)) {
1921 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1924 if (!HasIdentifier && Tok.
isNot(tok::annot_pragma_openmp_end)) {
1926 diag::err_omp_declare_target_unexpected_clause_after_implicit_to);
1931 if (Tok.
is(tok::comma))
1935 if (DTCI.Indirect.hasValue() && DTCI.DT != OMPDeclareTargetDeclAttr::DT_Any)
1936 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1939 if (DTCI.Kind == OMPD_declare_target && RequiresToOrLinkOrIndirectClause &&
1940 !HasToOrLinkOrIndirectClause)
1941 Diag(DTCI.Loc, diag::err_omp_declare_target_missing_to_or_link_clause)
1942 << (getLangOpts().OpenMP >= 51 ? 1 : 0);
1944 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1950 if (Tok.
is(tok::annot_pragma_openmp_end))
1953 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1954 << getOpenMPDirectiveName(DKind);
1955 while (Tok.
isNot(tok::annot_pragma_openmp_end))
1964 bool SkipUntilOpenMPEnd) {
1965 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1967 if (FoundKind == ExpectedKind) {
1969 skipUntilPragmaOpenMPEnd(ExpectedKind);
1973 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1975 Diag(BeginLoc, diag::note_matching)
1976 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind) +
"'").str();
1977 if (SkipUntilOpenMPEnd)
1978 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1984 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1988 if (Tok.
is(tok::annot_pragma_openmp_end))
1989 ConsumeAnnotationToken();
2031 assert(Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2032 "Not an OpenMP directive!");
2039 TentativeParsingAction TPA(*
this);
2040 Loc = ConsumeAnnotationToken();
2042 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
2047 Toks.push_back(Tok);
2049 (void)ConsumeAnyToken();
2050 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
2052 else if (Tok.
is(tok::annot_pragma_openmp_end))
2054 Toks.push_back(Tok);
2058 (void)ConsumeAnyToken();
2059 auto *LP =
new LateParsedPragma(
this, AS);
2061 getCurrentClass().LateParsedDeclarations.push_back(LP);
2066 Loc = ConsumeAnnotationToken();
2071 case OMPD_threadprivate: {
2073 DeclDirectiveListParserHelper Helper(
this, DKind);
2074 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2076 skipUntilPragmaOpenMPEnd(DKind);
2078 ConsumeAnnotationToken();
2080 Helper.getIdentifiers());
2084 case OMPD_allocate: {
2086 DeclDirectiveListParserHelper Helper(
this, DKind);
2087 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2090 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2092 llvm::omp::Clause_enumSize + 1>
2093 FirstClauses(llvm::omp::Clause_enumSize + 1);
2094 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2097 : getOpenMPClauseKind(PP.getSpelling(Tok));
2100 OMPD_allocate, CKind, !FirstClauses[
unsigned(CKind)].getInt());
2101 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2103 FirstClauses[
unsigned(CKind)].setInt(
true);
2104 if (Clause !=
nullptr)
2105 Clauses.push_back(Clause);
2106 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2111 if (Tok.
is(tok::comma))
2115 skipUntilPragmaOpenMPEnd(DKind);
2118 ConsumeAnnotationToken();
2124 case OMPD_requires: {
2128 llvm::omp::Clause_enumSize + 1>
2129 FirstClauses(llvm::omp::Clause_enumSize + 1);
2130 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2131 Diag(Tok, diag::err_omp_expected_clause)
2132 << getOpenMPDirectiveName(OMPD_requires);
2135 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2138 : getOpenMPClauseKind(PP.getSpelling(Tok));
2141 OMPD_requires, CKind, !FirstClauses[
unsigned(CKind)].getInt());
2142 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2144 FirstClauses[
unsigned(CKind)].setInt(
true);
2145 if (Clause !=
nullptr)
2146 Clauses.push_back(Clause);
2147 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2152 if (Tok.
is(tok::comma))
2157 if (Clauses.empty()) {
2158 Diag(Tok, diag::err_omp_expected_clause)
2159 << getOpenMPDirectiveName(OMPD_requires);
2160 ConsumeAnnotationToken();
2163 ConsumeAnnotationToken();
2167 case OMPD_begin_assumes:
2168 ParseOpenMPAssumesDirective(DKind, ConsumeToken());
2170 case OMPD_end_assumes:
2171 ParseOpenMPEndAssumesDirective(ConsumeToken());
2173 case OMPD_declare_reduction:
2175 if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2176 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2178 ConsumeAnnotationToken();
2182 case OMPD_declare_mapper: {
2184 if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2186 ConsumeAnnotationToken();
2191 case OMPD_begin_declare_variant: {
2198 OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
2201 if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
2205 (void)ConsumeAnnotationToken();
2210 skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
2214 VariantMatchInfo VMI;
2217 std::function<void(StringRef)> DiagUnknownTrait =
2218 [
this, Loc](StringRef ISATrait) {
2221 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2224 ASTCtx, std::move(DiagUnknownTrait),
2228 if (isVariantApplicableInContext(VMI, OMPCtx,
true)) {
2234 unsigned Nesting = 1;
2240 if (DK == OMPD_end_declare_variant)
2242 else if (DK == OMPD_begin_declare_variant)
2244 if (!Nesting || isEofOrEom())
2249 parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
2250 DK, Loc, DKLoc,
true);
2255 case OMPD_end_declare_variant: {
2259 Diag(Loc, diag::err_expected_begin_declare_variant);
2263 case OMPD_declare_variant:
2264 case OMPD_declare_simd: {
2270 Toks.push_back(Tok);
2272 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2273 Toks.push_back(Tok);
2276 Toks.push_back(Tok);
2280 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2281 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2283 }
else if (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
2287 MaybeParseCXX11Attributes(Attrs);
2289 Ptr = ParseExternalDeclaration(Attrs, &PDS);
2292 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs,
TagType, Tag);
2296 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2297 << (DKind == OMPD_declare_simd ? 0 : 1);
2298 return DeclGroupPtrTy();
2300 if (DKind == OMPD_declare_simd)
2301 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2302 assert(DKind == OMPD_declare_variant &&
2303 "Expected declare variant directive only");
2304 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2307 case OMPD_begin_declare_target:
2308 case OMPD_declare_target: {
2310 bool HasClauses = Tok.
isNot(tok::annot_pragma_openmp_end);
2311 Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2313 ParseOMPDeclareTargetClauses(DTCI);
2314 bool HasImplicitMappings =
2315 DKind == OMPD_begin_declare_target || !HasClauses ||
2316 (DTCI.ExplicitlyMapped.empty() && DTCI.Indirect.hasValue());
2321 if (HasImplicitMappings) {
2328 for (
auto &It : DTCI.ExplicitlyMapped)
2329 Decls.push_back(It.first);
2332 case OMPD_end_declare_target: {
2334 Diag(Tok, diag::err_omp_unexpected_directive)
2335 << 1 << getOpenMPDirectiveName(DKind);
2338 const Sema::DeclareTargetContextInfo &DTCI =
2340 ParseOMPEndDeclareTargetDirective(DTCI.Kind, DKind, DTCI.Loc);
2344 Diag(Tok, diag::err_omp_unknown_directive);
2351 case OMPD_taskyield:
2354 case OMPD_taskgroup:
2366 case OMPD_parallel_for:
2367 case OMPD_parallel_for_simd:
2368 case OMPD_parallel_sections:
2369 case OMPD_parallel_master:
2373 case OMPD_cancellation_point:
2375 case OMPD_target_data:
2376 case OMPD_target_enter_data:
2377 case OMPD_target_exit_data:
2378 case OMPD_target_parallel:
2379 case OMPD_target_parallel_for:
2381 case OMPD_taskloop_simd:
2382 case OMPD_master_taskloop:
2383 case OMPD_master_taskloop_simd:
2384 case OMPD_parallel_master_taskloop:
2385 case OMPD_parallel_master_taskloop_simd:
2386 case OMPD_distribute:
2387 case OMPD_target_update:
2388 case OMPD_distribute_parallel_for:
2389 case OMPD_distribute_parallel_for_simd:
2390 case OMPD_distribute_simd:
2391 case OMPD_target_parallel_for_simd:
2392 case OMPD_target_simd:
2393 case OMPD_teams_distribute:
2394 case OMPD_teams_distribute_simd:
2395 case OMPD_teams_distribute_parallel_for_simd:
2396 case OMPD_teams_distribute_parallel_for:
2397 case OMPD_target_teams:
2398 case OMPD_target_teams_distribute:
2399 case OMPD_target_teams_distribute_parallel_for:
2400 case OMPD_target_teams_distribute_parallel_for_simd:
2401 case OMPD_target_teams_distribute_simd:
2404 case OMPD_metadirective:
2406 case OMPD_teams_loop:
2407 case OMPD_target_teams_loop:
2408 case OMPD_parallel_loop:
2409 case OMPD_target_parallel_loop:
2410 Diag(Tok, diag::err_omp_unexpected_directive)
2411 << 1 << getOpenMPDirectiveName(DKind);
2416 while (Tok.
isNot(tok::annot_pragma_openmp_end))
2462 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2463 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2464 if (!ReadDirectiveWithinMetadirective)
2465 assert(Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2466 "Not an OpenMP directive!");
2471 llvm::omp::Clause_enumSize + 1>
2472 FirstClauses(llvm::omp::Clause_enumSize + 1);
2477 : ConsumeAnnotationToken(),
2480 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2481 Diag(Tok, diag::err_omp_unknown_directive);
2488 bool HasAssociatedStatement =
true;
2491 case OMPD_metadirective: {
2498 TentativeParsingAction TPA(*
this);
2502 tok::annot_pragma_openmp_end);
2503 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2506 : getOpenMPClauseKind(PP.getSpelling(Tok));
2510 if (T.expectAndConsume(diag::err_expected_lparen_after,
2511 getOpenMPClauseName(CKind).data()))
2515 if (CKind == OMPC_when) {
2517 parseOMPContextSelectors(Loc, TI);
2518 if (TI.
Sets.size() == 0) {
2519 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2525 if (Tok.
is(tok::colon))
2528 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2535 while (Tok.
isNot(tok::r_paren) || paren != 0) {
2536 if (Tok.
is(tok::l_paren))
2538 if (Tok.
is(tok::r_paren))
2540 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2541 Diag(Tok, diag::err_omp_expected_punc)
2542 << getOpenMPClauseName(CKind) << 0;
2549 if (Tok.
is(tok::r_paren))
2552 VariantMatchInfo VMI;
2555 VMIs.push_back(VMI);
2561 std::function<void(StringRef)> DiagUnknownTrait =
2562 [
this, Loc](StringRef ISATrait) {
2565 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2572 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2579 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2581 if (Idx++ != BestIdx) {
2586 while (Tok.
isNot(tok::r_paren) || paren != 0) {
2587 if (Tok.
is(tok::l_paren))
2589 if (Tok.
is(tok::r_paren))
2594 if (Tok.
is(tok::r_paren))
2601 : getOpenMPClauseKind(PP.getSpelling(Tok));
2608 if (CKind == OMPC_when) {
2611 parseOMPContextSelectors(Loc, TI);
2619 if (Tok.
is(tok::r_paren)) {
2620 SkipUntil(tok::annot_pragma_openmp_end);
2625 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2632 case OMPD_threadprivate: {
2634 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2635 ParsedStmtContext()) {
2636 Diag(Tok, diag::err_omp_immediate_directive)
2637 << getOpenMPDirectiveName(DKind) << 0;
2640 DeclDirectiveListParserHelper Helper(
this, DKind);
2641 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2643 skipUntilPragmaOpenMPEnd(DKind);
2645 Loc, Helper.getIdentifiers());
2648 SkipUntil(tok::annot_pragma_openmp_end);
2651 case OMPD_allocate: {
2653 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2654 ParsedStmtContext()) {
2655 Diag(Tok, diag::err_omp_immediate_directive)
2656 << getOpenMPDirectiveName(DKind) << 0;
2659 DeclDirectiveListParserHelper Helper(
this, DKind);
2660 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2663 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2665 llvm::omp::Clause_enumSize + 1>
2666 FirstClauses(llvm::omp::Clause_enumSize + 1);
2667 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2670 : getOpenMPClauseKind(PP.getSpelling(Tok));
2673 OMPD_allocate, CKind, !FirstClauses[
unsigned(CKind)].getInt());
2674 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2676 FirstClauses[
unsigned(CKind)].setInt(
true);
2677 if (Clause !=
nullptr)
2678 Clauses.push_back(Clause);
2679 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2684 if (Tok.
is(tok::comma))
2688 skipUntilPragmaOpenMPEnd(DKind);
2691 Loc, Helper.getIdentifiers(), Clauses);
2694 SkipUntil(tok::annot_pragma_openmp_end);
2697 case OMPD_declare_reduction:
2699 if (DeclGroupPtrTy Res =
2700 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2701 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2705 SkipUntil(tok::annot_pragma_openmp_end);
2708 case OMPD_declare_mapper: {
2710 if (DeclGroupPtrTy Res =
2711 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2713 ConsumeAnnotationToken();
2716 SkipUntil(tok::annot_pragma_openmp_end);
2723 case OMPD_taskyield:
2726 case OMPD_cancellation_point:
2728 case OMPD_target_enter_data:
2729 case OMPD_target_exit_data:
2730 case OMPD_target_update:
2732 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2733 ParsedStmtContext()) {
2734 Diag(Tok, diag::err_omp_immediate_directive)
2735 << getOpenMPDirectiveName(DKind) << 0;
2737 HasAssociatedStatement =
false;
2751 case OMPD_parallel_for:
2752 case OMPD_parallel_for_simd:
2753 case OMPD_parallel_sections:
2754 case OMPD_parallel_master:
2760 case OMPD_taskgroup:
2761 case OMPD_target_data:
2762 case OMPD_target_parallel:
2763 case OMPD_target_parallel_for:
2765 case OMPD_teams_loop:
2766 case OMPD_target_teams_loop:
2767 case OMPD_parallel_loop:
2768 case OMPD_target_parallel_loop:
2770 case OMPD_taskloop_simd:
2771 case OMPD_master_taskloop:
2772 case OMPD_master_taskloop_simd:
2773 case OMPD_parallel_master_taskloop:
2774 case OMPD_parallel_master_taskloop_simd:
2775 case OMPD_distribute:
2776 case OMPD_distribute_parallel_for:
2777 case OMPD_distribute_parallel_for_simd:
2778 case OMPD_distribute_simd:
2779 case OMPD_target_parallel_for_simd:
2780 case OMPD_target_simd:
2781 case OMPD_teams_distribute:
2782 case OMPD_teams_distribute_simd:
2783 case OMPD_teams_distribute_parallel_for_simd:
2784 case OMPD_teams_distribute_parallel_for:
2785 case OMPD_target_teams:
2786 case OMPD_target_teams_distribute:
2787 case OMPD_target_teams_distribute_parallel_for:
2788 case OMPD_target_teams_distribute_parallel_for_simd:
2789 case OMPD_target_teams_distribute_simd:
2794 bool ImplicitClauseAllowed =
false;
2795 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2797 ImplicitClauseAllowed =
true;
2801 if (DKind == OMPD_critical) {
2803 tok::annot_pragma_openmp_end);
2804 if (!T.consumeOpen()) {
2810 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2814 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2816 if (Tok.
isNot(tok::annot_pragma_openmp_end))
2824 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2827 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2830 if (ReadDirectiveWithinMetadirective && Tok.
is(tok::r_paren)) {
2831 while (Tok.
isNot(tok::annot_pragma_openmp_end))
2835 bool HasImplicitClause =
false;
2836 if (ImplicitClauseAllowed && Tok.
is(tok::l_paren)) {
2837 HasImplicitClause =
true;
2840 PP.EnterToken(Tok,
true);
2841 PP.EnterToken(ImplicitTok,
true);
2846 : getOpenMPClauseKind(PP.getSpelling(Tok));
2847 if (HasImplicitClause) {
2848 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2849 if (DKind == OMPD_flush) {
2852 assert(DKind == OMPD_depobj &&
2853 "Expected flush or depobj directives.");
2854 CKind = OMPC_depobj;
2858 ImplicitClauseAllowed =
false;
2860 HasImplicitClause =
false;
2862 DKind, CKind, !FirstClauses[
unsigned(CKind)].getInt());
2863 FirstClauses[
unsigned(CKind)].setInt(
true);
2865 FirstClauses[
unsigned(CKind)].setPointer(Clause);
2866 Clauses.push_back(Clause);
2870 if (Tok.
is(tok::comma))
2877 ConsumeAnnotationToken();
2882 if (DKind == OMPD_ordered && FirstClauses[
unsigned(OMPC_depend)].getInt()) {
2883 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2884 ParsedStmtContext()) {
2885 Diag(Loc, diag::err_omp_immediate_directive)
2886 << getOpenMPDirectiveName(DKind) << 1
2887 << getOpenMPClauseName(OMPC_depend);
2889 HasAssociatedStatement =
false;
2892 if (DKind == OMPD_tile && !FirstClauses[
unsigned(OMPC_sizes)].getInt()) {
2893 Diag(Loc, diag::err_omp_required_clause)
2894 << getOpenMPDirectiveName(OMPD_tile) <<
"sizes";
2898 if (HasAssociatedStatement) {
2907 AssociatedStmt = ParseStatement();
2910 getLangOpts().OpenMPIRBuilder)
2914 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2915 DKind == OMPD_target_exit_data) {
2923 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2928 OMPDirectiveScope.Exit();
2931 case OMPD_declare_simd:
2932 case OMPD_declare_target:
2933 case OMPD_begin_declare_target:
2934 case OMPD_end_declare_target:
2936 case OMPD_begin_declare_variant:
2937 case OMPD_end_declare_variant:
2938 case OMPD_declare_variant:
2939 Diag(Tok, diag::err_omp_unexpected_directive)
2940 << 1 << getOpenMPDirectiveName(DKind);
2941 SkipUntil(tok::annot_pragma_openmp_end);
2945 Diag(Tok, diag::err_omp_unknown_directive);
2946 SkipUntil(tok::annot_pragma_openmp_end);
2956 bool Parser::ParseOpenMPSimpleVarList(
2960 bool AllowScopeSpecifier) {
2963 if (T.expectAndConsume(diag::err_expected_lparen_after,
2964 getOpenMPDirectiveName(
Kind).data()))
2966 bool IsCorrect =
true;
2967 bool NoIdentIsFound =
true;
2970 while (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::annot_pragma_openmp_end)) {
2974 Token PrevTok = Tok;
2975 NoIdentIsFound =
false;
2977 if (AllowScopeSpecifier && getLangOpts().
CPlusPlus &&
2978 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2981 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2983 }
else if (ParseUnqualifiedId(SS,
nullptr,
2984 false,
false,
false,
2985 false,
false,
nullptr, Name)) {
2987 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2989 }
else if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::r_paren) &&
2990 Tok.
isNot(tok::annot_pragma_openmp_end)) {
2992 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3001 if (Tok.
is(tok::comma)) {
3006 if (NoIdentIsFound) {
3007 Diag(Tok, diag::err_expected) << tok::identifier;
3012 IsCorrect = !T.consumeClose() && IsCorrect;
3017 OMPClause *Parser::ParseOpenMPSizesClause() {
3022 if (T.consumeOpen()) {
3023 Diag(Tok, diag::err_expected) << tok::l_paren;
3034 ValExprs.push_back(Val.
get());
3036 if (Tok.
is(tok::r_paren) || Tok.
is(tok::annot_pragma_openmp_end))
3039 ExpectAndConsume(tok::comma);
3045 ValExprs, ClauseNameLoc, T.getOpenLocation(), T.getCloseLocation());
3054 if (T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3059 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3060 if (Allocator.isInvalid()) {
3061 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3067 if (Tok.
is(tok::l_paren)) {
3069 tok::annot_pragma_openmp_end);
3072 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3075 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3083 if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::r_paren))
3084 Diag(Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3086 if (Tok.
is(tok::comma))
3088 }
while (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::annot_pragma_openmp_end));
3091 T.getCloseLocation(), Data);
3116 OMPClauseKind = CKind;
3118 bool ErrorFound =
false;
3119 bool WrongDirective =
false;
3121 if (CKind != OMPC_unknown &&
3122 !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
3123 Diag(Tok, diag::err_omp_unexpected_clause)
3124 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3126 WrongDirective =
true;
3131 case OMPC_num_threads:
3136 case OMPC_num_teams:
3137 case OMPC_thread_limit:
3139 case OMPC_grainsize:
3140 case OMPC_num_tasks:
3142 case OMPC_allocator:
3145 case OMPC_novariants:
3146 case OMPC_nocontext:
3176 Diag(Tok, diag::err_omp_more_one_clause)
3177 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3181 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3182 PP.LookAhead(0).isNot(tok::l_paren))
3183 Clause = ParseOpenMPClause(CKind, WrongDirective);
3185 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3188 case OMPC_proc_bind:
3189 case OMPC_atomic_default_mem_order:
3202 if (!FirstClause && CKind != OMPC_order) {
3203 Diag(Tok, diag::err_omp_more_one_clause)
3204 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3208 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3212 case OMPC_dist_schedule:
3213 case OMPC_defaultmap:
3220 if ((getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3222 Diag(Tok, diag::err_omp_more_one_clause)
3223 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3228 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3232 case OMPC_mergeable:
3245 case OMPC_unified_address:
3246 case OMPC_unified_shared_memory:
3247 case OMPC_reverse_offload:
3248 case OMPC_dynamic_allocators:
3257 Diag(Tok, diag::err_omp_more_one_clause)
3258 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3262 Clause = ParseOpenMPClause(CKind, WrongDirective);
3266 Diag(Tok, diag::err_omp_more_one_clause)
3267 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3271 Clause = (DKind == OMPD_depobj)
3272 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3273 : ParseOpenMPClause(CKind, WrongDirective);
3276 case OMPC_firstprivate:
3277 case OMPC_lastprivate:
3279 case OMPC_reduction:
3280 case OMPC_task_reduction:
3281 case OMPC_in_reduction:
3285 case OMPC_copyprivate:
3291 case OMPC_use_device_ptr:
3292 case OMPC_use_device_addr:
3293 case OMPC_is_device_ptr:
3294 case OMPC_has_device_addr:
3296 case OMPC_nontemporal:
3297 case OMPC_inclusive:
3298 case OMPC_exclusive:
3300 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3304 Diag(Tok, diag::err_omp_more_one_clause)
3305 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3309 Clause = ParseOpenMPSizesClause();
3311 case OMPC_uses_allocators:
3312 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3315 if (DKind != OMPD_interop) {
3317 Diag(Tok, diag::err_omp_more_one_clause)
3318 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3321 Clause = ParseOpenMPClause(CKind, WrongDirective);
3327 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3329 case OMPC_device_type:
3331 skipUntilPragmaOpenMPEnd(DKind);
3333 case OMPC_threadprivate:
3336 if (!WrongDirective)
3337 Diag(Tok, diag::err_omp_unexpected_clause)
3338 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3339 SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
3344 return ErrorFound ? nullptr : Clause;
3352 bool IsAddressOfOperand) {
3354 if (T.
expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3359 ParseCastExpression(AnyCastExpr, IsAddressOfOperand, NotTypeCast));
3418 ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(
Kind), RLoc);
3432 bool Parser::ParseOpenMPIndirectClause(Sema::DeclareTargetContextInfo &DTCI,
3437 if (Tok.
isNot(tok::l_paren)) {
3440 DTCI.Indirect =
nullptr;
3445 ParseOpenMPParensExpr(getOpenMPClauseName(OMPC_indirect), RLoc);
3456 if (
Ret.isInvalid())
3461 if (
Ret.isInvalid())
3463 DTCI.Indirect = Val.
get();
3497 if (T.expectAndConsume(diag::err_expected_lparen_after,
3498 getOpenMPClauseName(
Kind).data()))
3501 bool IsTarget =
false;
3502 bool IsTargetSync =
false;
3505 if (
Kind == OMPC_init) {
3508 if (Tok.
is(tok::identifier) && PP.getSpelling(Tok) ==
"prefer_type") {
3511 tok::annot_pragma_openmp_end);
3512 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3515 while (Tok.
isNot(tok::r_paren)) {
3517 ExprResult LHS = ParseCastExpression(AnyCastExpr);
3523 Prefs.push_back(PTExpr.
get());
3525 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3528 if (Tok.
is(tok::comma))
3534 if (!Prefs.empty()) {
3535 if (Tok.
is(tok::comma))
3538 Diag(Tok, diag::err_omp_expected_punc_after_interop_mod);
3544 IsTarget = IType != OMPDeclareVariantAttr::TargetSync;
3545 IsTargetSync = IType != OMPDeclareVariantAttr::Target;
3546 if (Tok.
isNot(tok::colon))
3547 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3549 if (Tok.
is(tok::colon))
3558 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3564 if (!T.consumeClose())
3565 RLoc = T.getCloseLocation();
3567 if (ParseOnly || !InteropVarExpr.
isUsable() ||
3568 (
Kind == OMPC_init && !IsTarget && !IsTargetSync))
3571 if (
Kind == OMPC_init)
3573 IsTargetSync, Loc, T.getOpenLocation(),
3575 if (
Kind == OMPC_use)
3577 T.getOpenLocation(), VarLoc, RLoc);
3579 if (
Kind == OMPC_destroy)
3581 T.getOpenLocation(), VarLoc, RLoc);
3583 llvm_unreachable(
"Unexpected interop variable clause.");
3604 if (!Val || ParseOnly)
3606 if (getLangOpts().OpenMP < 51 &&
Kind == OMPC_default &&
3607 (
static_cast<DefaultKind
>(Val.getValue().Type) == OMP_DEFAULT_private ||
3608 static_cast<DefaultKind
>(Val.getValue().Type) ==
3609 OMP_DEFAULT_firstprivate)) {
3610 Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa)
3611 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val.getValue().Type) ==
3614 : OMPC_firstprivate)
3615 << getOpenMPClauseName(OMPC_default) <<
"5.1";
3619 Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen,
3620 Val.getValue().Loc, Val.getValue().RLoc);
3681 if (T.expectAndConsume(diag::err_expected_lparen_after,
3682 getOpenMPClauseName(
Kind).data()))
3688 if (
Kind == OMPC_schedule) {
3689 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3690 Arg.resize(NumberOfElements);
3691 KLoc.resize(NumberOfElements);
3699 Arg[Modifier1] = KindModifier;
3701 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3702 Tok.
isNot(tok::annot_pragma_openmp_end))
3704 if (Tok.
is(tok::comma)) {
3713 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3714 Tok.
isNot(tok::annot_pragma_openmp_end))
3718 if (Tok.
is(tok::colon))
3721 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
3725 Arg[ScheduleKind] = KindModifier;
3727 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3728 Tok.
isNot(tok::annot_pragma_openmp_end))
3730 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3731 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3732 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3734 DelimLoc = ConsumeAnyToken();
3735 }
else if (
Kind == OMPC_dist_schedule) {
3739 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3740 Tok.
isNot(tok::annot_pragma_openmp_end))
3742 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.
is(tok::comma))
3743 DelimLoc = ConsumeAnyToken();
3744 }
else if (
Kind == OMPC_defaultmap) {
3752 Arg.push_back(Modifier);
3754 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3755 Tok.
isNot(tok::annot_pragma_openmp_end))
3758 if (Tok.
is(tok::colon) || getLangOpts().OpenMP < 50) {
3759 if (Tok.
is(tok::colon))
3762 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
3767 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3768 Tok.
isNot(tok::annot_pragma_openmp_end))
3774 }
else if (
Kind == OMPC_device) {
3777 NextToken().is(tok::colon)) {
3787 KLoc.emplace_back();
3790 assert(
Kind == OMPC_if);
3792 TentativeParsingAction TPA(*
this);
3795 if (DK != OMPD_unknown) {
3797 if (Tok.
is(tok::colon) && getLangOpts().OpenMP > 40) {
3799 DelimLoc = ConsumeToken();
3802 Arg.back() =
unsigned(OMPD_unknown);
3809 bool NeedAnExpression = (
Kind == OMPC_schedule && DelimLoc.
isValid()) ||
3810 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
3811 Kind == OMPC_if ||
Kind == OMPC_device;
3812 if (NeedAnExpression) {
3814 ExprResult LHS(ParseCastExpression(AnyCastExpr,
false, NotTypeCast));
3822 if (!T.consumeClose())
3823 RLoc = T.getCloseLocation();
3825 if (NeedAnExpression && Val.
isInvalid())
3831 Kind, Arg, Val.
get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
3836 if (ReductionIdScopeSpec.
isEmpty()) {
3838 switch (
P.getCurToken().getKind()) {
3873 return P.ParseUnqualifiedId(
3874 ReductionIdScopeSpec,
nullptr,
3878 false,
nullptr, ReductionId);
3884 Token Tok =
P.getCurToken();
3885 if (!Tok.
is(tok::identifier))
3900 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3910 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::kw_default)) {
3912 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3929 while (getCurToken().isNot(tok::colon)) {
3942 if (parseMapperModifier(Data))
3948 if (Tok.
is(tok::comma)) {
3949 Diag(Tok, diag::err_omp_map_type_modifier_missing);
3954 if (PP.LookAhead(0).is(tok::colon))
3956 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
3957 << (getLangOpts().OpenMP >= 51 ? 1 : 0)
3958 << getLangOpts().OpenMPExtensions;
3961 if (getCurToken().is(tok::comma))
3970 Token Tok =
P.getCurToken();
3972 if (!Tok.
isOneOf(tok::identifier, tok::kw_delete))
3985 Token Tok =
P.getCurToken();
3986 if (Tok.
is(tok::colon)) {
3987 P.Diag(Tok, diag::err_omp_map_type_missing);
3992 P.Diag(Tok, diag::err_omp_unknown_map_type);
3998 ExprResult Parser::ParseOpenMPIteratorsExpr() {
3999 assert(Tok.
is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4000 "Expected 'iterator' token.");
4004 if (T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4009 while (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::annot_pragma_openmp_end)) {
4012 if (Tok.
isNot(tok::identifier) || NextToken().isNot(tok::equal)) {
4019 IteratorType = TR.
get();
4025 if (Tok.
is(tok::identifier)) {
4027 IdLoc = ConsumeToken();
4029 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4034 if (Tok.
is(tok::equal))
4035 AssignLoc = ConsumeToken();
4037 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4043 ExprResult LHS = ParseCastExpression(AnyCastExpr);
4050 if (Tok.
is(tok::colon))
4051 ColonLoc = ConsumeToken();
4055 LHS = ParseCastExpression(AnyCastExpr);
4064 if (Tok.
is(tok::colon)) {
4066 SecColonLoc = ConsumeToken();
4069 LHS = ParseCastExpression(AnyCastExpr);
4077 if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::r_paren))
4078 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4079 if (Tok.
is(tok::comma))
4085 D.
Type = IteratorType;
4096 if (!T.consumeClose())
4097 RLoc = T.getCloseLocation();
4109 bool InvalidReductionId =
false;
4110 bool IsInvalidMapperModifier =
false;
4115 getOpenMPClauseName(
Kind).data()))
4118 bool HasIterator =
false;
4119 bool NeedRParenForLinear =
false;
4121 tok::annot_pragma_openmp_end);
4123 if (
Kind == OMPC_reduction ||
Kind == OMPC_task_reduction ||
4124 Kind == OMPC_in_reduction) {
4126 if (
Kind == OMPC_reduction && getLangOpts().OpenMP >= 50 &&
4127 (Tok.
is(tok::identifier) || Tok.
is(tok::kw_default)) &&
4128 NextToken().is(tok::comma)) {
4134 assert(Tok.
is(tok::comma) &&
"Expected comma.");
4135 (void)ConsumeToken();
4145 if (InvalidReductionId) {
4146 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4149 if (Tok.
is(tok::colon))
4152 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4153 if (!InvalidReductionId)
4156 }
else if (
Kind == OMPC_depend) {
4157 if (getLangOpts().OpenMP >= 50) {
4158 if (Tok.
is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4167 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4170 ExpectAndConsume(tok::comma);
4176 Kind, Tok.
is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4180 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4185 if (DKind == OMPD_ordered && Data.
ExtraModifier == OMPC_DEPEND_source) {
4191 if (Tok.
is(tok::colon)) {
4194 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4195 : diag::warn_pragma_expected_colon)
4196 <<
"dependency type";
4198 }
else if (
Kind == OMPC_linear) {
4201 if (Tok.
is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
4206 NeedRParenForLinear =
true;
4208 }
else if (
Kind == OMPC_lastprivate) {
4215 Tok.
is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
4220 assert(Tok.
is(tok::colon) &&
"Expected colon.");
4223 }
else if (
Kind == OMPC_map) {
4234 TentativeParsingAction TPA(*
this);
4235 bool ColonPresent =
false;
4236 if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4238 if (Tok.
is(tok::colon))
4239 ColonPresent =
true;
4245 IsInvalidMapperModifier = parseMapTypeModifiers(Data);
4246 if (!IsInvalidMapperModifier)
4249 SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
4256 if (Tok.
is(tok::colon))
4258 }
else if (
Kind == OMPC_to ||
Kind == OMPC_from) {
4259 while (Tok.
is(tok::identifier)) {
4267 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
4268 IsInvalidMapperModifier = parseMapperModifier(Data);
4269 if (IsInvalidMapperModifier)
4273 if (getLangOpts().OpenMP < 51)
4277 if (Tok.
is(tok::comma))
4281 if (!IsInvalidMapperModifier) {
4282 if (getLangOpts().OpenMP < 51)
4283 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
4285 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
4287 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4295 }
else if (
Kind == OMPC_allocate ||
4296 (
Kind == OMPC_affinity && Tok.
is(tok::identifier) &&
4297 PP.getSpelling(Tok) ==
"iterator")) {
4300 TentativeParsingAction TPA(*
this);
4305 if (
Kind == OMPC_allocate) {
4306 Tail = ParseAssignmentExpression();
4310 Tail = ParseOpenMPIteratorsExpr();
4316 if (Tok.
is(tok::colon)) {
4328 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4331 }
else if (
Kind == OMPC_adjust_args) {
4335 Kind, Tok.
is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4339 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4343 if (Tok.
is(tok::colon))
4345 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
4351 (
Kind != OMPC_reduction &&
Kind != OMPC_task_reduction &&
4352 Kind != OMPC_in_reduction &&
Kind != OMPC_depend &&
Kind != OMPC_map) ||
4353 (
Kind == OMPC_reduction && !InvalidReductionId) ||
4356 (
Kind == OMPC_adjust_args &&
4358 const bool MayHaveTail = (
Kind == OMPC_linear ||
Kind == OMPC_aligned);
4359 while (IsComma || (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::colon) &&
4360 Tok.
isNot(tok::annot_pragma_openmp_end))) {
4367 Vars.push_back(VarExpr.
get());
4369 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4373 IsComma = Tok.
is(tok::comma);
4376 else if (Tok.
isNot(tok::r_paren) &&
4377 Tok.
isNot(tok::annot_pragma_openmp_end) &&
4378 (!MayHaveTail || Tok.
isNot(tok::colon)))
4379 Diag(Tok, diag::err_omp_expected_punc)
4380 << ((
Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
4381 : getOpenMPClauseName(
Kind))
4382 << (
Kind == OMPC_flush);
4386 if (NeedRParenForLinear)
4390 const bool MustHaveTail = MayHaveTail && Tok.
is(tok::colon);
4394 ExprResult Tail = ParseAssignmentExpression();
4400 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4411 return (
Kind != OMPC_depend &&
Kind != OMPC_map && Vars.empty()) ||
4413 IsInvalidMapperModifier;
4479 OpenMPVarListDataTy Data;
4481 if (ParseOpenMPVarList(DKind,
Kind, Vars, Data))
4488 Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc,
4489 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
4490 Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
4491 Data.IsMapTypeImplicit, Data.ExtraModifierLoc, Data.MotionModifiers,
4492 Data.MotionModifiersLoc);