26#include "llvm/ADT/SmallBitVector.h"
27#include "llvm/ADT/StringSwitch.h"
28#include "llvm/Frontend/OpenMP/DirectiveNameParser.h"
29#include "llvm/Frontend/OpenMP/OMPAssume.h"
30#include "llvm/Frontend/OpenMP/OMPContext.h"
35using namespace llvm::omp;
42class DeclDirectiveListParserHelper final {
43 SmallVector<Expr *, 4> Identifiers;
50 void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
51 ExprResult Res = P->getActions().OpenMP().ActOnOpenMPIdExpression(
52 P->getCurScope(), SS, NameInfo, Kind);
54 Identifiers.push_back(Res.
get());
56 llvm::ArrayRef<Expr *> getIdentifiers()
const {
return Identifiers; }
65 auto [D, VR] = getOpenMPDirectiveKindAndVersions(Name);
67 if (D == Directive::OMPD_ordered_blockassoc)
68 D = Directive::OMPD_ordered_standalone;
69 assert(D == Kind &&
"Directive kind mismatch");
72 if (
static_cast<int>(Version) < VR.Min)
73 P.
Diag(Loc, diag::warn_omp_future_directive_spelling) << Name;
79 static const DirectiveNameParser DirParser;
81 const DirectiveNameParser::State *S = DirParser.initial();
84 if (
Tok.isAnnotation())
90 S = DirParser.consume(S, Concat);
94 while (!
Tok.isAnnotation()) {
97 if (!
Tok.isAnnotation()) {
99 S = DirParser.consume(S, TS);
107 assert(S &&
"Should have exited early");
116 bool WithOperator =
false;
117 if (
Tok.is(tok::kw_operator)) {
122 switch (
Tok.getKind()) {
147 case tok::identifier:
152 P.
Diag(
Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
153 P.
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
159 return OOK ==
OO_None ? DeclNames.getIdentifier(
Tok.getIdentifierInfo())
160 : DeclNames.getCXXOperatorName(OOK);
165 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
168 if (
T.expectAndConsume(
169 diag::err_expected_lparen_after,
170 getOpenMPDirectiveName(OMPD_declare_reduction, OMPVersion).data())) {
176 if (Name.
isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
180 bool IsCorrect = !ExpectAndConsume(tok::colon);
182 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
185 IsCorrect = IsCorrect && !Name.
isEmpty();
187 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
188 Diag(Tok.getLocation(), diag::err_expected_type);
192 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
195 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
202 QualType ReductionType = Actions.OpenMP().ActOnOpenMPDeclareReductionType(
203 Range.getBegin(), TR);
204 if (!ReductionType.
isNull()) {
205 ReductionTypes.push_back(
206 std::make_pair(ReductionType,
Range.getBegin()));
209 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
213 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
217 if (ExpectAndConsume(tok::comma)) {
219 if (Tok.is(tok::annot_pragma_openmp_end)) {
220 Diag(Tok.getLocation(), diag::err_expected_type);
224 }
while (Tok.isNot(tok::annot_pragma_openmp_end));
226 if (ReductionTypes.empty()) {
231 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
235 if (ExpectAndConsume(tok::colon))
238 if (Tok.is(tok::annot_pragma_openmp_end)) {
239 Diag(Tok.getLocation(), diag::err_expected_expression);
244 Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveStart(
245 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes,
250 unsigned I = 0, E = ReductionTypes.size();
251 for (Decl *D : DRD.get()) {
252 TentativeParsingAction TPA(*
this);
257 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerStart(
getCurScope(), D);
258 ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
260 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerEnd(
261 D, CombinerResult.
get());
263 if (CombinerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
264 Tok.isNot(tok::annot_pragma_openmp_end)) {
269 IsCorrect = !
T.consumeClose() && IsCorrect && CombinerResult.
isUsable();
271 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
273 if (Tok.is(tok::identifier) &&
274 Tok.getIdentifierInfo()->isStr(
"initializer")) {
277 Diag(Tok.getLocation(), diag::err_expected) <<
"'initializer'";
284 tok::annot_pragma_openmp_end);
286 !
T.expectAndConsume(diag::err_expected_lparen_after,
"initializer") &&
288 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
293 VarDecl *OmpPrivParm =
294 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerStart(
297 if (Tok.is(tok::identifier) &&
298 Tok.getIdentifierInfo()->isStr(
"omp_priv")) {
300 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
302 InitializerResult = Actions.ActOnFinishFullExpr(
306 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerEnd(
307 D, InitializerResult.
get(), OmpPrivParm);
308 if (InitializerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
309 Tok.isNot(tok::annot_pragma_openmp_end)) {
315 !
T.consumeClose() && IsCorrect && !InitializerResult.
isInvalid();
327 return Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveEnd(
331void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
334 if (isTokenEqualOrEqualTypo()) {
337 if (Tok.is(tok::code_completion)) {
339 Actions.CodeCompletion().CodeCompleteInitializer(
getCurScope(),
341 Actions.FinalizeDeclaration(OmpPrivParm);
345 PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
348 if (
Init.isInvalid()) {
350 Actions.ActOnInitializerError(OmpPrivParm);
352 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
355 }
else if (Tok.is(tok::l_paren)) {
362 SourceLocation LParLoc =
T.getOpenLocation();
363 auto RunSignatureHelp = [
this, OmpPrivParm, LParLoc, &Exprs]() {
364 QualType PreferredType =
365 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
367 OmpPrivParm->
getLocation(), Exprs, LParLoc,
false);
368 CalledSignatureHelp =
true;
369 return PreferredType;
371 if (ParseExpressionList(Exprs, [&] {
372 PreferredType.enterFunctionArgument(Tok.getLocation(),
375 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
377 Actions.ActOnInitializerError(OmpPrivParm);
381 SourceLocation RLoc = Tok.getLocation();
382 if (!
T.consumeClose())
383 RLoc =
T.getCloseLocation();
386 Actions.ActOnParenListExpr(
T.getOpenLocation(), RLoc, Exprs);
387 Actions.AddInitializerToDecl(OmpPrivParm,
Initializer.get(),
392 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
396 if (
Init.isInvalid()) {
397 Actions.ActOnInitializerError(OmpPrivParm);
399 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
403 Actions.ActOnUninitializedDecl(OmpPrivParm);
409 bool IsCorrect =
true;
410 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
413 if (
T.expectAndConsume(
414 diag::err_expected_lparen_after,
415 getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion).data())) {
421 auto &DeclNames = Actions.getASTContext().DeclarationNames;
422 DeclarationName MapperId;
423 if (PP.LookAhead(0).is(tok::colon)) {
424 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
425 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
428 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
432 ExpectAndConsume(tok::colon);
436 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get(
"default"));
439 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
443 DeclarationName VName;
448 MapperType = Actions.OpenMP().ActOnOpenMPDeclareMapperType(
Range.getBegin(),
458 IsCorrect &= !
T.consumeClose();
466 DeclarationNameInfo DirName;
467 SourceLocation Loc = Tok.getLocation();
470 ParseScope OMPDirectiveScope(
this, ScopeFlags);
471 Actions.OpenMP().StartOpenMPDSABlock(OMPD_declare_mapper, DirName,
476 Actions.OpenMP().ActOnOpenMPDeclareMapperDirectiveVarDecl(
480 SmallVector<OMPClause *, 6> Clauses;
481 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
484 : getOpenMPClauseKind(PP.getSpelling(Tok));
485 Actions.OpenMP().StartOpenMPClause(CKind);
487 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
489 Clauses.push_back(Clause);
493 if (Tok.is(tok::comma))
495 Actions.OpenMP().EndOpenMPClause();
497 if (Clauses.empty()) {
498 Diag(Tok, diag::err_omp_expected_clause)
499 << getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion);
508 DeclGroupPtrTy DG = Actions.OpenMP().ActOnOpenMPDeclareMapperDirective(
509 OuterScope, Actions.getCurLexicalContext(), MapperId, MapperType,
510 Range.getBegin(), VName, AS, MapperVarRef.
get(), Clauses);
512 Actions.OpenMP().EndOpenMPDSABlock(
nullptr);
513 OMPDirectiveScope.Exit();
524 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
525 DeclSpec DS(AttrFactory);
526 ParseSpecifierQualifierList(DS, AS, DSC);
531 ParseDeclarator(DeclaratorInfo);
532 Range = DeclaratorInfo.getSourceRange();
533 if (DeclaratorInfo.getIdentifier() ==
nullptr) {
534 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
537 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
539 return Actions.OpenMP().ActOnOpenMPDeclareMapperVarDecl(
getCurScope(),
551 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
554 if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
558 (void)ConsumeAnnotationToken();
563 skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
567 VariantMatchInfo VMI;
571 Loc](StringRef ISATrait) {
574 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
577 ASTCtx, std::move(DiagUnknownTrait),
580 Actions.OpenMP().getOpenMPDeviceNum());
582 if (isVariantApplicableInContext(VMI, OMPCtx,
584 Actions.OpenMP().ActOnOpenMPBeginDeclareVariant(Loc, TI);
589 unsigned Nesting = 1;
593 DKLoc = Tok.getLocation();
595 if (DK == OMPD_end_declare_variant)
597 else if (DK == OMPD_begin_declare_variant)
599 if (!Nesting || isEofOrEom())
604 parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant, DK,
615class FNContextRAII final {
619 bool HasFunScope =
false;
620 FNContextRAII() =
delete;
621 FNContextRAII(
const FNContextRAII &) =
delete;
622 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
626 Decl *D = *Ptr.get().begin();
669 bool IsError =
false;
670 while (
Tok.isNot(tok::annot_pragma_openmp_end)) {
671 if (
Tok.isNot(tok::identifier))
673 OMPDeclareSimdDeclAttr::BranchStateTy Out;
675 StringRef ClauseName = II->
getName();
677 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
678 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
679 P.
Diag(
Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
681 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
687 }
else if (ClauseName ==
"simdlen") {
690 P.
Diag(
Tok, diag::err_omp_more_one_clause)
691 << getOpenMPDirectiveName(OMPD_declare_simd, OMPVersion)
702 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
703 CKind == OMPC_linear) {
706 if (CKind == OMPC_aligned) {
708 }
else if (CKind == OMPC_linear) {
709 Data.ExtraModifier = OMPC_LINEAR_val;
715 getOpenMPClauseKind(ClauseName), *Vars,
Data))
717 if (CKind == OMPC_aligned) {
718 Alignments.append(Aligneds.size() - Alignments.size(),
719 Data.DepModOrTailExpr);
720 }
else if (CKind == OMPC_linear) {
721 assert(0 <=
Data.ExtraModifier &&
723 "Unexpected linear modifier.");
726 Data.ExtraModifierLoc))
727 Data.ExtraModifier = OMPC_LINEAR_val;
728 LinModifiers.append(Linears.size() - LinModifiers.size(),
730 Steps.append(Linears.size() - Steps.size(),
Data.DepModOrTailExpr);
737 if (
Tok.is(tok::comma))
746 PP.EnterToken(Tok,
true);
747 PP.EnterTokenStream(Toks,
true,
753 FNContextRAII FnContext(*
this, Ptr);
754 OMPDeclareSimdDeclAttr::BranchStateTy BS =
755 OMPDeclareSimdDeclAttr::BS_Undefined;
757 SmallVector<Expr *, 4> Uniforms;
758 SmallVector<Expr *, 4> Aligneds;
759 SmallVector<Expr *, 4> Alignments;
760 SmallVector<Expr *, 4> Linears;
761 SmallVector<unsigned, 4> LinModifiers;
762 SmallVector<Expr *, 4> Steps;
765 Alignments, Linears, LinModifiers, Steps);
766 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
768 SourceLocation EndLoc = ConsumeAnnotationToken();
771 return Actions.OpenMP().ActOnOpenMPDeclareSimdDirective(
772 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
773 LinModifiers, Steps, SourceRange(Loc, EndLoc));
780 CONTEXT_SELECTOR_SET_LVL = 0,
781 CONTEXT_SELECTOR_LVL = 1,
782 CONTEXT_TRAIT_LVL = 2,
785static StringRef stringLiteralParser(
Parser &P) {
792 if (
Tok.
is(tok::identifier) ||
Tok.
is(tok::kw_for)) {
800 return stringLiteralParser(P);
803 diag::warn_omp_declare_variant_string_literal_or_identifier)
808static bool checkForDuplicates(
Parser &P, StringRef Name,
810 llvm::StringMap<SourceLocation> &Seen,
812 auto Res = Seen.try_emplace(Name, NameLoc);
818 P.
Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
820 P.
Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
826void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
827 llvm::omp::TraitSet
Set,
829 llvm::StringMap<SourceLocation> &Seen) {
830 TIProperty.
Kind = TraitProperty::invalid;
832 SourceLocation NameLoc = Tok.getLocation();
834 if (Selector == llvm::omp::TraitSelector::target_device_device_num) {
836 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
838 if (DeviceNumExprResult.
isUsable()) {
839 Expr *DeviceNumExpr = DeviceNumExprResult.
get();
840 Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr);
844 Name = getNameFromIdOrString(*
this, Tok, CONTEXT_TRAIT_LVL);
846 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
847 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
852 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
853 if (TIProperty.
Kind != TraitProperty::invalid) {
854 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
855 TIProperty.
Kind = TraitProperty::invalid;
861 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
862 << Name << getOpenMPContextTraitSelectorName(Selector)
863 << getOpenMPContextTraitSetName(
Set);
865 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
866 if (SetForName != TraitSet::invalid) {
867 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
868 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
869 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
870 << Name <<
"<selector-name>"
871 <<
"(<property-name>)";
874 TraitSelector SelectorForName =
875 getOpenMPContextTraitSelectorKind(Name, SetForName);
876 if (SelectorForName != TraitSelector::invalid) {
877 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
878 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
879 bool AllowsTraitScore =
false;
880 bool RequiresProperty =
false;
881 isValidTraitSelectorForTraitSet(
882 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
883 AllowsTraitScore, RequiresProperty);
884 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
885 << getOpenMPContextTraitSetName(
886 getOpenMPContextTraitSetForSelector(SelectorForName))
887 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
890 for (
const auto &PotentialSet :
891 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
892 TraitSet::device, TraitSet::target_device}) {
893 TraitProperty PropertyForName =
894 getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
895 if (PropertyForName == TraitProperty::invalid)
897 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
898 << getOpenMPContextTraitSetName(
899 getOpenMPContextTraitSetForProperty(PropertyForName))
900 << getOpenMPContextTraitSelectorName(
901 getOpenMPContextTraitSelectorForProperty(PropertyForName))
902 << (
"(" + Name +
")").str();
905 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
906 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
912 llvm::StringMap<SourceLocation> &Seen) {
913 assert(TISelector.
Kind ==
914 llvm::omp::TraitSelector::implementation_extension &&
915 "Only for extension properties, e.g., "
916 "`implementation={extension(PROPERTY)}`");
917 if (TIProperty.
Kind == TraitProperty::invalid)
920 if (TIProperty.
Kind ==
921 TraitProperty::implementation_extension_disable_implicit_base)
924 if (TIProperty.
Kind ==
925 TraitProperty::implementation_extension_allow_templates)
928 if (TIProperty.
Kind ==
929 TraitProperty::implementation_extension_bind_to_declaration)
934 llvm::omp::TraitProperty::implementation_extension_match_all ||
936 llvm::omp::TraitProperty::implementation_extension_match_any ||
938 llvm::omp::TraitProperty::implementation_extension_match_none);
941 if (IsMatchExtension(TIProperty)) {
943 if (IsMatchExtension(SeenProp)) {
944 P.
Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
945 StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
948 P.
Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
949 << CONTEXT_TRAIT_LVL << SeenName;
955 llvm_unreachable(
"Unknown extension property!");
958void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
959 llvm::omp::TraitSet
Set,
960 llvm::StringMap<SourceLocation> &Seen) {
961 assert(TISelector.
Kind != TraitSelector::user_condition &&
962 "User conditions are special properties not handled here!");
964 SourceLocation PropertyLoc = Tok.getLocation();
965 OMPTraitProperty TIProperty;
966 parseOMPTraitPropertyKind(TIProperty,
Set, TISelector.
Kind, Seen);
968 if (TISelector.
Kind == llvm::omp::TraitSelector::implementation_extension)
971 TIProperty.
Kind = TraitProperty::invalid;
974 if (TIProperty.
Kind == TraitProperty::invalid) {
975 if (PropertyLoc != Tok.getLocation())
976 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
977 << CONTEXT_TRAIT_LVL;
981 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.
Kind,
990 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
991 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
993 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
994 << getOpenMPContextTraitSetName(
Set);
995 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
996 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
998 << getOpenMPContextTraitSelectorName(
999 getOpenMPContextTraitSelectorForProperty(TIProperty.
Kind))
1000 << getOpenMPContextTraitSetName(
1001 getOpenMPContextTraitSetForProperty(TIProperty.
Kind));
1002 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1003 << CONTEXT_TRAIT_LVL;
1006void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
1007 llvm::omp::TraitSet
Set,
1008 llvm::StringMap<SourceLocation> &Seen) {
1009 TISelector.
Kind = TraitSelector::invalid;
1011 SourceLocation NameLoc = Tok.getLocation();
1012 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_LVL);
1014 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1015 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1019 TISelector.
Kind = getOpenMPContextTraitSelectorKind(Name,
Set);
1020 if (TISelector.
Kind != TraitSelector::invalid) {
1021 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1022 TISelector.
Kind = TraitSelector::invalid;
1027 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1028 << Name << getOpenMPContextTraitSetName(
Set);
1030 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1031 if (SetForName != TraitSet::invalid) {
1032 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1033 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1034 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1035 << Name <<
"<selector-name>"
1036 <<
"<property-name>";
1039 for (
const auto &PotentialSet :
1040 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1041 TraitSet::device, TraitSet::target_device}) {
1042 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1043 PotentialSet, TraitSelector::invalid, Name);
1044 if (PropertyForName == TraitProperty::invalid)
1046 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1047 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1048 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1049 << getOpenMPContextTraitSetName(
1050 getOpenMPContextTraitSetForProperty(PropertyForName))
1051 << getOpenMPContextTraitSelectorName(
1052 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1053 << (
"(" + Name +
")").str();
1056 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1057 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1064 StringRef SelectorName =
1066 if (SelectorName !=
"score")
1077 <<
"score expression";
1081void Parser::parseOMPContextSelector(
1082 OMPTraitSelector &TISelector, llvm::omp::TraitSet
Set,
1083 llvm::StringMap<SourceLocation> &SeenSelectors) {
1084 unsigned short OuterPC = ParenCount;
1089 auto FinishSelector = [OuterPC,
this]() ->
void {
1092 while (!
SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1093 tok::annot_pragma_openmp_end},
1096 if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1097 (void)ConsumeParen();
1098 if (OuterPC <= ParenCount) {
1102 if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1108 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1109 << CONTEXT_SELECTOR_LVL;
1112 SourceLocation SelectorLoc = Tok.getLocation();
1113 parseOMPTraitSelectorKind(TISelector,
Set, SeenSelectors);
1114 if (TISelector.
Kind == TraitSelector::invalid)
1115 return FinishSelector();
1117 bool AllowsTraitScore =
false;
1118 bool RequiresProperty =
false;
1119 if (!isValidTraitSelectorForTraitSet(TISelector.
Kind,
Set, AllowsTraitScore,
1120 RequiresProperty)) {
1121 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1122 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1123 << getOpenMPContextTraitSetName(
Set);
1124 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1125 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1126 << getOpenMPContextTraitSetName(
1127 getOpenMPContextTraitSetForSelector(TISelector.
Kind))
1128 << RequiresProperty;
1129 return FinishSelector();
1132 if (!RequiresProperty) {
1134 {getOpenMPContextTraitPropertyForSelector(TISelector.
Kind),
1135 getOpenMPContextTraitSelectorName(TISelector.
Kind)});
1139 if (!Tok.is(tok::l_paren)) {
1140 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1141 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1142 << getOpenMPContextTraitSetName(
Set);
1143 return FinishSelector();
1146 if (TISelector.
Kind == TraitSelector::user_condition) {
1147 SourceLocation RLoc;
1150 return FinishSelector();
1153 {TraitProperty::user_condition_unknown,
"<condition>"});
1158 tok::annot_pragma_openmp_end);
1160 (void)BDT.consumeOpen();
1162 SourceLocation ScoreLoc = Tok.getLocation();
1165 if (!AllowsTraitScore && !Score.
isUnset()) {
1167 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1168 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1169 << getOpenMPContextTraitSetName(
Set) << Score.
get();
1171 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1172 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1173 << getOpenMPContextTraitSetName(
Set) <<
"<invalid>";
1181 llvm::StringMap<SourceLocation> SeenProperties;
1183 parseOMPContextProperty(TISelector,
Set, SeenProperties);
1190void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1191 llvm::StringMap<SourceLocation> &Seen) {
1192 TISet.
Kind = TraitSet::invalid;
1194 SourceLocation NameLoc = Tok.getLocation();
1195 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_SET_LVL);
1197 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1198 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1202 TISet.
Kind = getOpenMPContextTraitSetKind(Name);
1203 if (TISet.
Kind != TraitSet::invalid) {
1204 if (checkForDuplicates(*
this, Name, NameLoc, Seen,
1205 CONTEXT_SELECTOR_SET_LVL))
1206 TISet.
Kind = TraitSet::invalid;
1211 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1213 TraitSelector SelectorForName =
1214 getOpenMPContextTraitSelectorKind(Name, TISet.
Kind);
1215 if (SelectorForName != TraitSelector::invalid) {
1216 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1217 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1218 bool AllowsTraitScore =
false;
1219 bool RequiresProperty =
false;
1220 isValidTraitSelectorForTraitSet(
1221 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1222 AllowsTraitScore, RequiresProperty);
1223 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1224 << getOpenMPContextTraitSetName(
1225 getOpenMPContextTraitSetForSelector(SelectorForName))
1226 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
1229 for (
const auto &PotentialSet :
1230 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1231 TraitSet::device, TraitSet::target_device}) {
1232 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1233 PotentialSet, TraitSelector::invalid, Name);
1234 if (PropertyForName == TraitProperty::invalid)
1236 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1237 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1238 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1239 << getOpenMPContextTraitSetName(
1240 getOpenMPContextTraitSetForProperty(PropertyForName))
1241 << getOpenMPContextTraitSelectorName(
1242 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1243 << (
"(" + Name +
")").str();
1246 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1247 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1250void Parser::parseOMPContextSelectorSet(
1251 OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1252 auto OuterBC = BraceCount;
1257 auto FinishSelectorSet = [
this, OuterBC]() ->
void {
1260 while (!
SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1261 tok::annot_pragma_openmp_end},
1264 if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1265 (void)ConsumeBrace();
1266 if (OuterBC <= BraceCount) {
1270 if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1276 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1277 << CONTEXT_SELECTOR_SET_LVL;
1280 parseOMPTraitSetKind(TISet, SeenSets);
1281 if (TISet.
Kind == TraitSet::invalid)
1282 return FinishSelectorSet();
1286 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1288 << (
"context set name \"" + getOpenMPContextTraitSetName(TISet.
Kind) +
1292 if (Tok.is(tok::l_brace)) {
1293 (void)ConsumeBrace();
1295 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1297 << (
"'=' that follows the context set name \"" +
1298 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1302 llvm::StringMap<SourceLocation> SeenSelectors;
1304 OMPTraitSelector TISelector;
1305 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1306 if (TISelector.
Kind != TraitSelector::invalid &&
1312 if (Tok.is(tok::r_brace)) {
1313 (void)ConsumeBrace();
1315 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1317 << (
"context selectors for the context set \"" +
1318 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1323bool Parser::parseOMPContextSelectors(
SourceLocation Loc, OMPTraitInfo &TI) {
1324 llvm::StringMap<SourceLocation> SeenSets;
1327 parseOMPContextSelectorSet(TISet, SeenSets);
1328 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1329 TI.
Sets.push_back(TISet);
1338 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1339 PP.EnterToken(Tok,
true);
1340 PP.EnterTokenStream(Toks,
true,
1346 FNContextRAII FnContext(*
this, Ptr);
1348 SourceLocation RLoc;
1358 getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion), RLoc,
1361 if (!AssociatedFunction.
isUsable()) {
1362 if (!Tok.is(tok::annot_pragma_openmp_end))
1366 (void)ConsumeAnnotationToken();
1370 OMPTraitInfo *ParentTI =
1371 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
1372 ASTContext &ASTCtx = Actions.getASTContext();
1374 SmallVector<Expr *, 6> AdjustNothing;
1375 SmallVector<Expr *, 6> AdjustNeedDevicePtr;
1376 SmallVector<Expr *, 6> AdjustNeedDeviceAddr;
1377 SmallVector<OMPInteropInfo, 3> AppendArgs;
1378 SourceLocation AdjustArgsLoc, AppendArgsLoc;
1381 if (Tok.is(tok::annot_pragma_openmp_end)) {
1382 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1386 bool IsError =
false;
1387 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1390 : getOpenMPClauseKind(PP.getSpelling(Tok));
1391 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1393 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1400 IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1402 case OMPC_adjust_args: {
1403 AdjustArgsLoc = Tok.getLocation();
1405 SemaOpenMP::OpenMPVarListDataTy
Data;
1406 SmallVector<Expr *> Vars;
1410 switch (
Data.ExtraModifier) {
1411 case OMPC_ADJUST_ARGS_nothing:
1412 llvm::append_range(AdjustNothing, Vars);
1414 case OMPC_ADJUST_ARGS_need_device_ptr:
1415 llvm::append_range(AdjustNeedDevicePtr, Vars);
1417 case OMPC_ADJUST_ARGS_need_device_addr:
1418 llvm::append_range(AdjustNeedDeviceAddr, Vars);
1421 llvm_unreachable(
"Unexpected 'adjust_args' clause modifier.");
1426 case OMPC_append_args:
1427 if (!AppendArgs.empty()) {
1428 Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1429 << getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion)
1430 << getOpenMPClauseName(CKind) << 0;
1434 AppendArgsLoc = Tok.getLocation();
1436 IsError = parseOpenMPAppendArgs(AppendArgs);
1440 llvm_unreachable(
"Unexpected clause for declare variant.");
1447 (void)ConsumeAnnotationToken();
1451 if (Tok.is(tok::comma))
1455 std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1456 Actions.OpenMP().checkOpenMPDeclareVariantFunction(
1457 Ptr, AssociatedFunction.
get(), TI, AppendArgs.size(),
1458 SourceRange(Loc, Tok.getLocation()));
1460 if (DeclVarData && !TI.
Sets.empty())
1461 Actions.OpenMP().ActOnOpenMPDeclareVariantDirective(
1462 DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1463 AdjustNeedDevicePtr, AdjustNeedDeviceAddr, AppendArgs, AdjustArgsLoc,
1464 AppendArgsLoc, SourceRange(Loc, Tok.getLocation()));
1467 (void)ConsumeAnnotationToken();
1470bool Parser::parseOpenMPAppendArgs(
1472 bool HasError =
false;
1475 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1476 getOpenMPClauseName(OMPC_append_args).data()))
1481 while (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"interop")) {
1484 tok::annot_pragma_openmp_end);
1485 if (IT.expectAndConsume(diag::err_expected_lparen_after,
"interop"))
1488 OMPInteropInfo InteropInfo;
1489 if (ParseOMPInteropInfo(InteropInfo, OMPC_append_args))
1492 InteropInfos.push_back(InteropInfo);
1495 if (Tok.is(tok::comma))
1498 if (!HasError && InteropInfos.empty()) {
1500 Diag(Tok.getLocation(), diag::err_omp_unexpected_append_op);
1501 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1504 HasError =
T.consumeClose() || HasError;
1508bool Parser::parseOMPDeclareVariantMatchClause(
SourceLocation Loc,
1510 OMPTraitInfo *ParentTI) {
1514 : getOpenMPClauseKind(PP.getSpelling(Tok));
1515 if (CKind != OMPC_match) {
1516 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1523 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1524 getOpenMPClauseName(OMPC_match).data()))
1528 parseOMPContextSelectors(Loc, TI);
1531 (void)
T.consumeClose();
1541 for (
const OMPTraitSet &ParentSet : ParentTI->
Sets) {
1542 bool MergedSet =
false;
1543 for (OMPTraitSet &
Set : TI.
Sets) {
1544 if (
Set.Kind != ParentSet.
Kind)
1547 for (
const OMPTraitSelector &ParentSelector : ParentSet.
Selectors) {
1548 bool MergedSelector =
false;
1549 for (OMPTraitSelector &Selector :
Set.Selectors) {
1550 if (Selector.
Kind != ParentSelector.
Kind)
1552 MergedSelector =
true;
1553 for (
const OMPTraitProperty &ParentProperty :
1555 bool MergedProperty =
false;
1569 if (Selector.
Kind == llvm::omp::TraitSelector::user_condition) {
1570 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1573 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1574 << getOpenMPContextTraitPropertyName(
1576 << getOpenMPContextTraitSelectorName(ParentSelector.
Kind)
1577 << getOpenMPContextTraitSetName(ParentSet.
Kind);
1580 if (!MergedProperty)
1581 Selector.
Properties.push_back(ParentProperty);
1584 if (!MergedSelector)
1585 Set.Selectors.push_back(ParentSelector);
1589 TI.
Sets.push_back(ParentSet);
1598 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
1599 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1602 : getOpenMPClauseKind(PP.getSpelling(Tok));
1603 if (DKind == OMPD_depobj && CKind == OMPC_update)
1604 CKind = OMPC_update_depend_objects;
1605 Actions.OpenMP().StartOpenMPClause(CKind);
1607 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
1608 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1610 SeenClauses[unsigned(CKind)] =
true;
1611 if (Clause !=
nullptr)
1612 Clauses.push_back(Clause);
1613 if (Tok.is(tok::annot_pragma_openmp_end)) {
1614 Actions.OpenMP().EndOpenMPClause();
1618 if (Tok.is(tok::comma))
1620 Actions.OpenMP().EndOpenMPClause();
1626 SmallVector<std::string, 4> Assumptions;
1627 bool SkippedClauses =
false;
1629 auto SkipBraces = [&](llvm::StringRef Spelling,
bool IssueNote) {
1631 tok::annot_pragma_openmp_end);
1632 if (
T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1635 if (IssueNote &&
T.getCloseLocation().isValid())
1636 Diag(
T.getCloseLocation(),
1637 diag::note_omp_assumption_clause_continue_here);
1643 auto MatchACMClause = [&](StringRef RawString) {
1644 llvm::StringSwitch<int> SS(RawString);
1645 unsigned ACMIdx = 0;
1646 for (
const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1647 if (ACMI.StartsWith)
1648 SS.StartsWith(ACMI.Identifier, ACMIdx++);
1650 SS.Case(ACMI.Identifier, ACMIdx++);
1652 return SS.Default(-1);
1655 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1656 IdentifierInfo *II =
nullptr;
1657 SourceLocation StartLoc = Tok.getLocation();
1659 if (Tok.isAnyIdentifier()) {
1660 II = Tok.getIdentifierInfo();
1661 Idx = MatchACMClause(II->
getName());
1665 bool NextIsLPar = Tok.is(tok::l_paren);
1668 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1669 Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1670 << llvm::omp::getOpenMPDirectiveName(DKind, OMPVersion)
1671 << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1673 SkipBraces(II ? II->
getName() :
"",
true);
1674 SkippedClauses =
true;
1677 const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1678 if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1681 SkippedClauses =
true;
1682 SkipBraces(II->
getName(),
false);
1687 Diag(Tok.getLocation(),
1688 diag::warn_omp_unknown_assumption_clause_without_args)
1690 SkipBraces(II->
getName(),
true);
1693 assert(II &&
"Expected an identifier clause!");
1694 std::string Assumption = II->
getName().str();
1695 if (ACMI.StartsWith)
1696 Assumption =
"ompx_" + Assumption.substr(ACMI.Identifier.size());
1698 Assumption =
"omp_" + Assumption;
1699 Assumptions.push_back(Assumption);
1702 Actions.OpenMP().ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions,
1707 if (Actions.OpenMP().isInOpenMPAssumeScope())
1708 Actions.OpenMP().ActOnOpenMPEndAssumesDirective();
1710 Diag(Loc, diag::err_expected_begin_assumes);
1724struct SimpleClauseData {
1727 SourceLocation LOpen;
1728 SourceLocation TypeLoc;
1729 SourceLocation RLoc;
1730 SimpleClauseData(
unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1731 SourceLocation TypeLoc, SourceLocation RLoc)
1732 :
Type(
Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1736static std::optional<SimpleClauseData>
1743 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1744 getOpenMPClauseName(Kind).data()))
1745 return std::nullopt;
1751 if (
Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::comma) &&
1752 Tok.isNot(tok::annot_pragma_openmp_end))
1757 if (!
T.consumeClose())
1758 RLoc =
T.getCloseLocation();
1760 return SimpleClauseData(
Type, Loc, LOpen,
TypeLoc, RLoc);
1763void Parser::ParseOMPDeclareTargetClauses(
1765 SourceLocation DeviceTypeLoc;
1766 bool RequiresToLinkLocalOrIndirectClause =
false;
1767 bool HasToLinkLocalOrIndirectClause =
false;
1768 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1769 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1770 bool HasIdentifier = Tok.is(tok::identifier);
1771 if (HasIdentifier) {
1773 RequiresToLinkLocalOrIndirectClause =
true;
1774 IdentifierInfo *II = Tok.getIdentifierInfo();
1775 StringRef ClauseName = II->
getName();
1776 bool IsDeviceTypeClause =
1778 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1780 bool IsIndirectClause =
getLangOpts().OpenMP >= 51 &&
1781 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1783 if (DTCI.
Indirect && IsIndirectClause) {
1784 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1785 Diag(Tok, diag::err_omp_more_one_clause)
1786 << getOpenMPDirectiveName(OMPD_declare_target, OMPVersion)
1787 << getOpenMPClauseName(OMPC_indirect) << 0;
1790 bool IsToEnterLinkOrLocalClause =
1791 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1792 assert((!IsDeviceTypeClause || !IsToEnterLinkOrLocalClause) &&
1797 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1798 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1801 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1802 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1807 if (
getLangOpts().OpenMP < 60 && ClauseName ==
"local") {
1809 ? diag::err_omp_declare_target_unexpected_clause_52
1810 : diag::err_omp_declare_target_unexpected_clause)
1818 if (!IsDeviceTypeClause && !IsIndirectClause &&
1819 DTCI.
Kind == OMPD_begin_declare_target) {
1821 ? diag::err_omp_declare_target_unexpected_clause_52
1822 : diag::err_omp_declare_target_unexpected_clause)
1823 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1827 if (!IsDeviceTypeClause && !IsToEnterLinkOrLocalClause &&
1828 !IsIndirectClause) {
1830 ? diag::err_omp_declare_target_unexpected_clause_52
1831 : diag::err_omp_declare_target_unexpected_clause)
1840 if (IsToEnterLinkOrLocalClause || IsIndirectClause)
1841 HasToLinkLocalOrIndirectClause =
true;
1843 if (IsIndirectClause) {
1844 if (!ParseOpenMPIndirectClause(DTCI,
false))
1849 if (IsDeviceTypeClause) {
1850 std::optional<SimpleClauseData> DevTypeData =
1853 if (DeviceTypeLoc.
isValid()) {
1855 Diag(DevTypeData->Loc,
1856 diag::warn_omp_more_one_device_type_clause);
1860 case OMPC_DEVICE_TYPE_any:
1861 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Any;
1863 case OMPC_DEVICE_TYPE_host:
1864 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Host;
1866 case OMPC_DEVICE_TYPE_nohost:
1867 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1870 llvm_unreachable(
"Unexpected device_type");
1872 DeviceTypeLoc = DevTypeData->Loc;
1879 if (DTCI.
Kind == OMPD_declare_target || HasIdentifier) {
1880 auto &&Callback = [
this, MT, &DTCI](CXXScopeSpec &SS,
1881 DeclarationNameInfo NameInfo) {
1882 NamedDecl *ND = Actions.OpenMP().lookupOpenMPDeclareTargetName(
1886 SemaOpenMP::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.
getLoc()};
1889 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1892 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1897 if (Tok.is(tok::l_paren)) {
1899 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1902 if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1905 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1906 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1911 if (Tok.is(tok::comma))
1915 if (DTCI.
Indirect && DTCI.
DT != OMPDeclareTargetDeclAttr::DT_Any)
1916 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1919 if (DTCI.
Kind == OMPD_declare_target && RequiresToLinkLocalOrIndirectClause &&
1920 !HasToLinkLocalOrIndirectClause)
1921 Diag(DTCI.
Loc, diag::err_omp_declare_target_missing_required_clause)
1933 if (Tok.is(tok::annot_pragma_openmp_end))
1936 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1937 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1938 << getOpenMPDirectiveName(DKind, OMPVersion);
1939 while (Tok.isNot(tok::annot_pragma_openmp_end))
1948 bool SkipUntilOpenMPEnd) {
1949 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1951 if (FoundKind == ExpectedKind) {
1953 skipUntilPragmaOpenMPEnd(ExpectedKind);
1957 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1958 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1960 Diag(BeginLoc, diag::note_matching)
1961 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind, OMPVersion) +
"'")
1963 if (SkipUntilOpenMPEnd)
1970 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1974 if (Tok.is(tok::annot_pragma_openmp_end))
1975 ConsumeAnnotationToken();
1981 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
1982 "Not an OpenMP directive!");
1985 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1990 TentativeParsingAction TPA(*
this);
1991 Loc = ConsumeAnnotationToken();
1993 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1998 Toks.push_back(Tok);
1999 while (Cnt && Tok.isNot(tok::eof)) {
2001 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
2003 else if (Tok.is(tok::annot_pragma_openmp_end))
2005 Toks.push_back(Tok);
2010 auto *LP =
new LateParsedPragma(
this, AS);
2012 getCurrentClass().LateParsedDeclarations.push_back(LP);
2017 Loc = ConsumeAnnotationToken();
2022 case OMPD_threadprivate: {
2024 DeclDirectiveListParserHelper Helper(
this, DKind);
2025 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2027 skipUntilPragmaOpenMPEnd(DKind);
2029 ConsumeAnnotationToken();
2030 return Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2031 Loc, Helper.getIdentifiers());
2035 case OMPD_groupprivate: {
2037 DeclDirectiveListParserHelper Helper(
this, DKind);
2038 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2040 skipUntilPragmaOpenMPEnd(DKind);
2042 ConsumeAnnotationToken();
2043 return Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2044 Loc, Helper.getIdentifiers());
2048 case OMPD_allocate: {
2050 DeclDirectiveListParserHelper Helper(
this, DKind);
2051 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2053 SmallVector<OMPClause *, 1> Clauses;
2054 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2055 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
2056 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2058 Tok.isAnnotation() ? OMPC_unknown
2059 : getOpenMPClauseKind(PP.getSpelling(Tok));
2060 Actions.OpenMP().StartOpenMPClause(CKind);
2061 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2062 !SeenClauses[
unsigned(CKind)]);
2063 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2065 SeenClauses[unsigned(CKind)] =
true;
2066 if (Clause !=
nullptr)
2067 Clauses.push_back(Clause);
2068 if (Tok.is(tok::annot_pragma_openmp_end)) {
2069 Actions.OpenMP().EndOpenMPClause();
2073 if (Tok.is(tok::comma))
2075 Actions.OpenMP().EndOpenMPClause();
2077 skipUntilPragmaOpenMPEnd(DKind);
2080 ConsumeAnnotationToken();
2081 return Actions.OpenMP().ActOnOpenMPAllocateDirective(
2082 Loc, Helper.getIdentifiers(), Clauses);
2086 case OMPD_requires: {
2088 SmallVector<OMPClause *, 5> Clauses;
2089 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2090 if (Tok.is(tok::annot_pragma_openmp_end)) {
2091 Diag(Tok, diag::err_omp_expected_clause)
2092 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2095 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2098 : getOpenMPClauseKind(PP.getSpelling(Tok));
2099 Actions.OpenMP().StartOpenMPClause(CKind);
2100 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
2101 !SeenClauses[
unsigned(CKind)]);
2102 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2104 SeenClauses[unsigned(CKind)] =
true;
2105 if (Clause !=
nullptr)
2106 Clauses.push_back(Clause);
2107 if (Tok.is(tok::annot_pragma_openmp_end)) {
2108 Actions.OpenMP().EndOpenMPClause();
2112 if (Tok.is(tok::comma))
2114 Actions.OpenMP().EndOpenMPClause();
2117 if (Clauses.empty()) {
2118 Diag(Tok, diag::err_omp_expected_clause)
2119 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2120 ConsumeAnnotationToken();
2123 ConsumeAnnotationToken();
2124 return Actions.OpenMP().ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2127 SmallVector<OMPClause *, 1> Clauses;
2129 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2130 Actions.OpenMP().ActOnOpenMPErrorDirective(Clauses, StartLoc,
2136 case OMPD_begin_assumes:
2139 case OMPD_end_assumes:
2142 case OMPD_declare_reduction:
2144 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2145 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2147 ConsumeAnnotationToken();
2151 case OMPD_declare_mapper: {
2153 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2155 ConsumeAnnotationToken();
2160 case OMPD_begin_declare_variant: {
2165 ConsumeAnnotationToken();
2169 case OMPD_end_declare_variant: {
2171 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2172 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2174 Diag(Loc, diag::err_expected_begin_declare_variant);
2176 ConsumeAnnotationToken();
2179 case OMPD_declare_variant:
2180 case OMPD_declare_simd: {
2186 Toks.push_back(Tok);
2188 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2189 Toks.push_back(Tok);
2192 Toks.push_back(Tok);
2196 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2197 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2199 }
else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2203 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2204 MaybeParseCXX11Attributes(Attrs);
2205 ParsingDeclSpec PDS(*
this);
2206 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2209 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2213 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2214 << (DKind == OMPD_declare_simd ? 0 : 1);
2218 DeclGroupRef DG =
Ptr.get();
2219 SourceManager &SM = PP.getSourceManager();
2220 if (llvm::none_of(DG, [&](
const Decl *D) {
2223 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2224 << (DKind == OMPD_declare_simd ? 0 : 1);
2228 if (DKind == OMPD_declare_simd)
2229 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2230 assert(DKind == OMPD_declare_variant &&
2231 "Expected declare variant directive only");
2232 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2235 case OMPD_begin_declare_target:
2236 case OMPD_declare_target: {
2238 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2239 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2240 if (DKind == OMPD_declare_target && !HasClauses &&
2242 Diag(DTLoc, diag::warn_omp_deprecated_declare_target_delimited_form);
2244 ParseOMPDeclareTargetClauses(DTCI);
2245 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2252 if (HasImplicitMappings) {
2253 Actions.OpenMP().ActOnStartOpenMPDeclareTargetContext(DTCI);
2257 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2258 llvm::SmallVector<Decl *, 4> Decls;
2260 Decls.push_back(It.first);
2261 return Actions.BuildDeclaratorGroup(Decls);
2263 case OMPD_end_declare_target: {
2264 if (!Actions.OpenMP().isInOpenMPDeclareTargetContext()) {
2265 Diag(Tok, diag::err_omp_unexpected_directive)
2266 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2269 const SemaOpenMP::DeclareTargetContextInfo &DTCI =
2270 Actions.OpenMP().ActOnOpenMPEndDeclareTargetDirective();
2271 ParseOMPEndDeclareTargetDirective(DTCI.
Kind, DKind, DTCI.
Loc);
2275 Diag(Tok, diag::err_omp_unexpected_directive)
2276 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2280 Diag(Tok, diag::err_omp_unknown_directive);
2283 switch (getDirectiveCategory(DKind)) {
2284 case Category::Executable:
2285 case Category::Meta:
2286 case Category::Subsidiary:
2287 case Category::Utility:
2288 Diag(Tok, diag::err_omp_unexpected_directive)
2289 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2291 case Category::Declarative:
2292 case Category::Informational:
2296 while (Tok.isNot(tok::annot_pragma_openmp_end))
2302StmtResult Parser::ParseOpenMPExecutableDirective(
2304 bool ReadDirectiveWithinMetadirective) {
2306 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2308 bool HasAssociatedStatement =
true;
2309 Association Assoc = getDirectiveAssociation(DKind);
2313 if (DKind != OMPD_ordered_standalone && DKind != OMPD_section &&
2314 (Assoc == Association::None || Assoc == Association::Separating)) {
2315 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2316 ParsedStmtContext()) {
2317 Diag(Tok, diag::err_omp_immediate_directive)
2318 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2319 if (DKind == OMPD_error) {
2320 SkipUntil(tok::annot_pragma_openmp_end);
2324 HasAssociatedStatement =
false;
2327 SourceLocation EndLoc;
2328 SmallVector<OMPClause *, 5> Clauses;
2329 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2330 DeclarationNameInfo DirName;
2337 bool ImplicitClauseAllowed =
false;
2338 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2340 ImplicitClauseAllowed =
true;
2344 if (DKind == OMPD_critical) {
2346 tok::annot_pragma_openmp_end);
2347 if (!
T.consumeOpen()) {
2348 if (Tok.isAnyIdentifier()) {
2350 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2353 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2357 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2359 if (Tok.isNot(tok::annot_pragma_openmp_end))
2367 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2368 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2371 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2374 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2375 while (Tok.isNot(tok::annot_pragma_openmp_end))
2379 bool HasImplicitClause =
false;
2380 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2381 HasImplicitClause =
true;
2384 PP.EnterToken(Tok,
true);
2385 PP.EnterToken(ImplicitTok,
true);
2390 : getOpenMPClauseKind(PP.getSpelling(Tok));
2391 if (DKind == OMPD_depobj && CKind == OMPC_update)
2392 CKind = OMPC_update_depend_objects;
2394 if (HasImplicitClause) {
2395 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2396 if (DKind == OMPD_flush) {
2399 assert(DKind == OMPD_depobj &&
"Expected flush or depobj directives.");
2400 CKind = OMPC_depobj;
2404 ImplicitClauseAllowed =
false;
2405 Actions.OpenMP().StartOpenMPClause(CKind);
2406 HasImplicitClause =
false;
2407 SourceLocation ClauseLoc = Tok.getLocation();
2410 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2411 SeenClauses[unsigned(CKind)] =
true;
2413 Clauses.push_back(Clause);
2416 if (Tok.is(tok::comma))
2418 Actions.OpenMP().EndOpenMPClause();
2422 if (Tok.getLocation() == ClauseLoc) {
2423 skipUntilPragmaOpenMPEnd(DKind);
2428 EndLoc = Tok.getLocation();
2430 ConsumeAnnotationToken();
2432 assert(DKind != OMPD_ordered_blockassoc &&
2433 "Wrong kind for ordered directive");
2434 if (DKind == OMPD_ordered_standalone) {
2437 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2438 if (SeenClauses[
unsigned(CK)]) {
2439 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2440 ParsedStmtContext()) {
2441 Diag(Loc, diag::err_omp_immediate_directive)
2442 << getOpenMPDirectiveName(DKind, OMPVersion) << 1
2443 << getOpenMPClauseName(CK);
2445 HasAssociatedStatement =
false;
2449 if (HasAssociatedStatement)
2450 DKind = OMPD_ordered_blockassoc;
2453 if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
2454 !SeenClauses[
unsigned(OMPC_sizes)]) {
2455 Diag(Loc, diag::err_omp_required_clause)
2456 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"sizes";
2458 if (DKind == OMPD_split && !SeenClauses[
unsigned(OMPC_counts)]) {
2459 Diag(Loc, diag::err_omp_required_clause)
2460 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"counts";
2464 if (HasAssociatedStatement) {
2466 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2472 Sema::CompoundScopeRAII Scope(Actions);
2473 AssociatedStmt = ParseStatement();
2478 Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
2481 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2482 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2483 DKind == OMPD_target_exit_data) {
2484 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2485 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2486 Actions.ActOnCompoundStmt(Loc, Loc, {},
2489 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2493 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2496 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2497 OMPDirectiveScope.Exit();
2502StmtResult Parser::ParseOpenMPInformationalDirective(
2504 bool ReadDirectiveWithinMetadirective) {
2506 "Unexpected directive category");
2508 bool HasAssociatedStatement =
true;
2510 SmallVector<OMPClause *, 5> Clauses;
2511 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2512 DeclarationNameInfo DirName;
2515 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2517 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2520 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2521 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2522 while (Tok.isNot(tok::annot_pragma_openmp_end))
2529 : getOpenMPClauseKind(PP.getSpelling(Tok));
2530 Actions.OpenMP().StartOpenMPClause(CKind);
2532 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2533 SeenClauses[unsigned(CKind)] =
true;
2535 Clauses.push_back(Clause);
2537 if (Tok.is(tok::comma))
2539 Actions.OpenMP().EndOpenMPClause();
2542 SourceLocation EndLoc = Tok.getLocation();
2543 ConsumeAnnotationToken();
2546 if (HasAssociatedStatement) {
2547 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2550 Sema::CompoundScopeRAII Scope(Actions);
2551 AssociatedStmt = ParseStatement();
2554 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2558 DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2560 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2561 OMPDirectiveScope.Exit();
2566StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2567 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2568 if (!ReadDirectiveWithinMetadirective)
2569 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2570 "Not an OpenMP directive!");
2573 SourceLocation Loc = ReadDirectiveWithinMetadirective
2575 : ConsumeAnnotationToken();
2576 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2578 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2579 Diag(Tok, diag::err_omp_unknown_directive);
2585 bool IsExecutable = [&]() {
2586 if (DKind == OMPD_error)
2588 auto Res = getDirectiveCategory(DKind);
2589 return Res == Category::Executable || Res == Category::Subsidiary;
2593 Directive = ParseOpenMPExecutableDirective(
2594 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2595 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2604 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
2605 while (Tok.isNot(tok::annot_pragma_openmp_end))
2608 skipUntilPragmaOpenMPEnd(DKind);
2609 if (Tok.is(tok::annot_pragma_openmp_end))
2610 ConsumeAnnotationToken();
2613 case OMPD_metadirective: {
2615 SmallVector<VariantMatchInfo, 4> VMIs;
2620 TentativeParsingAction TPA(*
this);
2621 ASTContext &ASTContext = Actions.getASTContext();
2624 tok::annot_pragma_openmp_end);
2625 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2628 : getOpenMPClauseKind(PP.getSpelling(Tok));
2630 if (CKind == OMPC_unknown) {
2631 Diag(Tok, diag::err_omp_expected_clause) <<
"metadirective";
2633 SkipUntil(tok::annot_pragma_openmp_end);
2636 if (
getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
2637 Diag(Tok, diag::err_omp_unexpected_clause)
2638 << getOpenMPClauseName(CKind) <<
"metadirective";
2639 if (CKind == OMPC_default &&
getLangOpts().OpenMP >= 52)
2640 Diag(Tok, diag::warn_omp_default_deprecated);
2645 if (
T.expectAndConsume(diag::err_expected_lparen_after,
2646 getOpenMPClauseName(CKind).data())) {
2648 SkipUntil(tok::annot_pragma_openmp_end);
2652 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2653 if (CKind == OMPC_when) {
2655 parseOMPContextSelectors(Loc, TI);
2656 if (TI.
Sets.size() == 0) {
2657 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2663 if (Tok.is(tok::colon))
2666 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2674 while (Tok.isNot(tok::r_paren) || paren != 0) {
2675 if (Tok.is(tok::l_paren))
2677 if (Tok.is(tok::r_paren))
2679 if (Tok.is(tok::annot_pragma_openmp_end)) {
2680 Diag(Tok, diag::err_omp_expected_punc)
2681 << getOpenMPClauseName(CKind) << 0;
2688 if (Tok.is(tok::r_paren))
2691 VariantMatchInfo VMI;
2694 VMIs.push_back(VMI);
2701 [
this, Loc](StringRef ISATrait) {
2704 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2706 TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2708 ArrayRef<llvm::omp::TraitProperty>(),
2709 Actions.OpenMP().getOpenMPDeviceNum());
2712 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2719 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2721 if (Idx++ != BestIdx) {
2726 while (Tok.isNot(tok::r_paren) || paren != 0) {
2727 if (Tok.is(tok::l_paren))
2729 if (Tok.is(tok::r_paren))
2734 if (Tok.is(tok::r_paren))
2741 : getOpenMPClauseKind(PP.getSpelling(Tok));
2748 if (CKind == OMPC_when) {
2749 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2751 parseOMPContextSelectors(Loc, TI);
2759 if (Tok.is(tok::r_paren)) {
2760 SkipUntil(tok::annot_pragma_openmp_end);
2765 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2773 if (BestIdx == -1 && Idx > 0) {
2774 assert(Tok.is(tok::annot_pragma_openmp_end) &&
2775 "Expecting the end of the pragma here");
2776 ConsumeAnnotationToken();
2781 case OMPD_threadprivate: {
2783 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2784 ParsedStmtContext()) {
2785 Diag(Tok, diag::err_omp_immediate_directive)
2786 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2789 DeclDirectiveListParserHelper Helper(
this, DKind);
2790 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2792 skipUntilPragmaOpenMPEnd(DKind);
2793 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2794 Loc, Helper.getIdentifiers());
2795 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2797 SkipUntil(tok::annot_pragma_openmp_end);
2800 case OMPD_groupprivate: {
2801 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2802 ParsedStmtContext()) {
2803 Diag(Tok, diag::err_omp_immediate_directive)
2804 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2807 DeclDirectiveListParserHelper Helper(
this, DKind);
2808 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2810 skipUntilPragmaOpenMPEnd(DKind);
2811 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2812 Loc, Helper.getIdentifiers());
2813 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2815 SkipUntil(tok::annot_pragma_openmp_end);
2818 case OMPD_allocate: {
2820 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2821 ParsedStmtContext()) {
2822 Diag(Tok, diag::err_omp_immediate_directive)
2823 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2826 DeclDirectiveListParserHelper Helper(
this, DKind);
2827 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2829 SmallVector<OMPClause *, 1> Clauses;
2830 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2831 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2832 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2834 Tok.isAnnotation() ? OMPC_unknown
2835 : getOpenMPClauseKind(PP.getSpelling(Tok));
2836 Actions.OpenMP().StartOpenMPClause(CKind);
2837 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2838 !SeenClauses[
unsigned(CKind)]);
2839 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2841 SeenClauses[unsigned(CKind)] =
true;
2842 if (Clause !=
nullptr)
2843 Clauses.push_back(Clause);
2844 if (Tok.is(tok::annot_pragma_openmp_end)) {
2845 Actions.OpenMP().EndOpenMPClause();
2849 if (Tok.is(tok::comma))
2851 Actions.OpenMP().EndOpenMPClause();
2853 skipUntilPragmaOpenMPEnd(DKind);
2855 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPAllocateDirective(
2856 Loc, Helper.getIdentifiers(), Clauses);
2857 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2859 SkipUntil(tok::annot_pragma_openmp_end);
2862 case OMPD_declare_reduction:
2865 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2866 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2868 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2870 SkipUntil(tok::annot_pragma_openmp_end);
2873 case OMPD_declare_mapper: {
2876 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2878 ConsumeAnnotationToken();
2879 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2881 SkipUntil(tok::annot_pragma_openmp_end);
2885 case OMPD_declare_target: {
2887 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2888 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2890 ParseOMPDeclareTargetClauses(DTCI);
2891 bool HasImplicitMappings =
2894 if (HasImplicitMappings) {
2895 Diag(Tok, diag::err_omp_unexpected_directive)
2896 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2897 SkipUntil(tok::annot_pragma_openmp_end);
2904 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2907 case OMPD_begin_declare_variant: {
2912 ConsumeAnnotationToken();
2916 case OMPD_end_declare_variant: {
2918 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2919 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2921 Diag(Loc, diag::err_expected_begin_declare_variant);
2922 ConsumeAnnotationToken();
2925 case OMPD_declare_simd:
2926 case OMPD_begin_declare_target:
2927 case OMPD_end_declare_target:
2929 case OMPD_declare_variant:
2930 Diag(Tok, diag::err_omp_unexpected_directive)
2931 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2932 SkipUntil(tok::annot_pragma_openmp_end);
2936 Directive = ParseOpenMPInformationalDirective(
2937 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2939 "Informational directive remains unprocessed");
2944 Diag(Tok, diag::err_omp_unknown_directive);
2945 SkipUntil(tok::annot_pragma_openmp_end);
2951bool Parser::ParseOpenMPSimpleVarList(
2955 bool AllowScopeSpecifier) {
2956 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2959 if (
T.expectAndConsume(diag::err_expected_lparen_after,
2960 getOpenMPDirectiveName(Kind, OMPVersion).data()))
2962 bool IsCorrect =
true;
2963 bool NoIdentIsFound =
true;
2966 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2970 Token PrevTok = Tok;
2971 NoIdentIsFound =
false;
2974 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2977 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2980 false,
false,
false,
2981 false,
false,
nullptr, Name)) {
2983 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2985 }
else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2986 Tok.isNot(tok::annot_pragma_openmp_end)) {
2988 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2992 << SourceRange(PrevTok.
getLocation(), PrevTokLocation);
2994 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2997 if (Tok.is(tok::comma)) {
3002 if (NoIdentIsFound) {
3003 Diag(Tok, diag::err_expected) << tok::identifier;
3008 IsCorrect = !
T.consumeClose() && IsCorrect;
3013OMPClause *Parser::ParseOpenMPSizesClause() {
3014 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3015 SmallVector<Expr *, 4> ValExprs;
3016 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
3020 return Actions.OpenMP().ActOnOpenMPSizesClause(ValExprs, ClauseNameLoc,
3024OMPClause *Parser::ParseOpenMPCountsClause() {
3025 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3026 SmallVector<Expr *, 4> ValExprs;
3027 std::optional<unsigned> FillIdx;
3028 unsigned FillCount = 0;
3029 SourceLocation FillLoc;
3031 assert(getOpenMPClauseName(OMPC_counts) == PP.getSpelling(Tok) &&
3032 "Expected parsing to start at clause name");
3036 if (
T.consumeOpen()) {
3037 Diag(Tok, diag::err_expected) << tok::l_paren;
3042 if (Tok.is(tok::identifier) &&
3043 Tok.getIdentifierInfo()->getName() ==
"omp_fill") {
3045 FillIdx = ValExprs.size();
3047 FillLoc = Tok.getLocation();
3049 ValExprs.push_back(
nullptr);
3056 ValExprs.push_back(Val.
get());
3060 if (
T.consumeClose())
3062 OpenLoc =
T.getOpenLocation();
3063 CloseLoc =
T.getCloseLocation();
3065 return Actions.OpenMP().ActOnOpenMPCountsClause(
3066 ValExprs, ClauseNameLoc, OpenLoc, CloseLoc, FillIdx, FillLoc, FillCount);
3069OMPClause *Parser::ParseOpenMPLoopRangeClause() {
3071 SourceLocation FirstLoc, CountLoc;
3074 if (
T.consumeOpen()) {
3075 Diag(Tok, diag::err_expected) << tok::l_paren;
3079 FirstLoc = Tok.getLocation();
3086 ExpectAndConsume(tok::comma);
3088 CountLoc = Tok.getLocation();
3097 return Actions.OpenMP().ActOnOpenMPLoopRangeClause(
3098 FirstVal.
get(), CountVal.
get(), ClauseNameLoc,
T.getOpenLocation(),
3099 FirstLoc, CountLoc,
T.getCloseLocation());
3102OMPClause *Parser::ParseOpenMPPermutationClause() {
3103 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3104 SmallVector<Expr *> ArgExprs;
3105 if (ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,
3110 return Actions.OpenMP().ActOnOpenMPPermutationClause(ArgExprs, ClauseNameLoc,
3115 SourceLocation Loc = Tok.getLocation();
3120 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3122 SmallVector<SemaOpenMP::UsesAllocatorsData, 4>
Data;
3125 if (
getLangOpts().OpenMP >= 52 && Tok.is(tok::identifier) &&
3126 Tok.getIdentifierInfo()->getName() ==
"traits") {
3128 SemaOpenMP::UsesAllocatorsData &D =
Data.emplace_back();
3134 tok::annot_pragma_openmp_end);
3135 TraitParens.consumeOpen();
3138 TraitParens.consumeClose();
3142 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3148 if (Tok.isNot(tok::colon)) {
3149 Diag(Tok, diag::err_expected) << tok::colon;
3151 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3160 ? ParseCXXIdExpression()
3161 : tryParseCXXIdExpression(SS,
false);
3165 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3172 D.
LParenLoc = TraitParens.getOpenLocation();
3173 D.
RParenLoc = TraitParens.getCloseLocation();
3176 if (Tok.is(tok::comma)) {
3178 Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3181 }
else if (Tok.is(tok::semi)) {
3191 getLangOpts().CPlusPlus
3192 ? ParseCXXIdExpression()
3193 : tryParseCXXIdExpression(SS,
false);
3195 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3202 BalancedDelimiterTracker T(*this, tok::l_paren,
3203 tok::annot_pragma_openmp_end);
3205 ExprResult AllocatorTraits =
3206 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3208 if (AllocatorTraits.isInvalid()) {
3209 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3218 if (getLangOpts().OpenMP >= 52) {
3219 Diag(Loc, diag::err_omp_deprecate_old_syntax)
3220 <<
"allocator(expr)"
3221 <<
"uses_allocators"
3222 <<
"traits(expr): alloc";
3226 Diag(
Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3228 if (
Tok.
is(tok::comma))
3230 }
while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end));
3233 Loc,
T.getOpenLocation(),
T.getCloseLocation(),
Data);
3238 OMPClauseKind = CKind;
3239 OMPClause *Clause =
nullptr;
3240 bool ErrorFound =
false;
3241 bool WrongDirective =
false;
3242 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
3245 if (!isAllowedClauseForDirective(D,
C, OMPVersion)) {
3246 Diag(Tok, diag::err_omp_unexpected_clause)
3247 << getOpenMPClauseName(
C) << getOpenMPDirectiveName(D, OMPVersion);
3249 WrongDirective =
true;
3253 if (CKind != OMPC_unknown) {
3255 assert(DKind != OMPD_ordered_blockassoc &&
3256 "Wrong kind for ordered directive");
3257 if (DKind == OMPD_ordered_standalone) {
3260 if (!isAllowedClauseForDirective(DKind, CKind, OMPVersion))
3261 CheckClauseValid(OMPD_ordered_blockassoc, CKind);
3263 CheckClauseValid(DKind, CKind);
3274 case OMPC_grainsize:
3275 case OMPC_num_tasks:
3277 case OMPC_allocator:
3280 case OMPC_novariants:
3281 case OMPC_nocontext:
3286 case OMPC_ompx_dyn_cgroup_mem:
3287 case OMPC_dyn_groupprivate:
3288 case OMPC_transparent:
3317 Diag(Tok, diag::err_omp_more_one_clause)
3318 << getOpenMPDirectiveName(DKind, OMPVersion)
3319 << getOpenMPClauseName(CKind) << 0;
3323 if (CKind == OMPC_transparent && PP.LookAhead(0).isNot(tok::l_paren)) {
3325 SourceLocation LLoc = Tok.getLocation();
3326 if (!WrongDirective)
3327 Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(
nullptr, LLoc,
3331 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3332 PP.LookAhead(0).isNot(tok::l_paren))
3333 Clause = ParseOpenMPClause(CKind, WrongDirective);
3334 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3335 CKind == OMPC_dyn_groupprivate)
3336 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3338 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3340 case OMPC_threadset:
3342 case OMPC_proc_bind:
3343 case OMPC_atomic_default_mem_order:
3361 Diag(Tok, diag::err_omp_more_one_clause)
3362 << getOpenMPDirectiveName(DKind, OMPVersion)
3363 << getOpenMPClauseName(CKind) << 0;
3367 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3371 case OMPC_dist_schedule:
3372 case OMPC_defaultmap:
3383 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3384 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3385 Diag(Tok, diag::err_omp_more_one_clause)
3386 << getOpenMPDirectiveName(DKind, OMPVersion)
3387 << getOpenMPClauseName(CKind) << 0;
3392 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3395 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3399 case OMPC_mergeable:
3413 case OMPC_unified_address:
3414 case OMPC_unified_shared_memory:
3415 case OMPC_reverse_offload:
3416 case OMPC_dynamic_allocators:
3425 Diag(Tok, diag::err_omp_more_one_clause)
3426 << getOpenMPDirectiveName(DKind, OMPVersion)
3427 << getOpenMPClauseName(CKind) << 0;
3431 if (CKind == OMPC_nowait && PP.LookAhead(0).is(tok::l_paren) &&
3433 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3435 Clause = ParseOpenMPClause(CKind, WrongDirective);
3437 case OMPC_self_maps:
3440 Diag(Tok, diag::err_omp_expected_clause)
3441 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3445 Diag(Tok, diag::err_omp_more_one_clause)
3446 << getOpenMPDirectiveName(DKind, OMPVersion)
3447 << getOpenMPClauseName(CKind) << 0;
3450 Clause = ParseOpenMPClause(CKind, WrongDirective);
3454 Diag(Tok, diag::err_omp_more_one_clause)
3455 << getOpenMPDirectiveName(DKind, OMPVersion)
3456 << getOpenMPClauseName(CKind) << 0;
3459 Clause = ParseOpenMPClause(CKind, WrongDirective);
3461 case OMPC_update_depend_objects:
3463 Diag(Tok, diag::err_omp_more_one_clause)
3464 << getOpenMPDirectiveName(DKind, OMPVersion)
3465 << getOpenMPClauseName(CKind) << 0;
3469 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3471 case OMPC_num_teams:
3472 case OMPC_thread_limit:
3473 case OMPC_num_threads:
3475 Diag(Tok, diag::err_omp_more_one_clause)
3476 << getOpenMPDirectiveName(DKind, OMPVersion)
3477 << getOpenMPClauseName(CKind) << 0;
3482 case OMPC_firstprivate:
3483 case OMPC_lastprivate:
3485 case OMPC_reduction:
3486 case OMPC_task_reduction:
3487 case OMPC_in_reduction:
3491 case OMPC_copyprivate:
3497 case OMPC_use_device_ptr:
3498 case OMPC_use_device_addr:
3499 case OMPC_is_device_ptr:
3500 case OMPC_has_device_addr:
3502 case OMPC_nontemporal:
3503 case OMPC_inclusive:
3504 case OMPC_exclusive:
3508 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered_standalone &&
3509 CKind == OMPC_depend)
3510 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3511 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3515 Diag(Tok, diag::err_omp_more_one_clause)
3516 << getOpenMPDirectiveName(DKind, OMPVersion)
3517 << getOpenMPClauseName(CKind) << 0;
3521 Clause = ParseOpenMPSizesClause();
3523 case OMPC_permutation:
3525 Diag(Tok, diag::err_omp_more_one_clause)
3526 << getOpenMPDirectiveName(DKind, OMPVersion)
3527 << getOpenMPClauseName(CKind) << 0;
3530 Clause = ParseOpenMPPermutationClause();
3534 Diag(Tok, diag::err_omp_more_one_clause)
3535 << getOpenMPDirectiveName(DKind, OMPVersion)
3536 << getOpenMPClauseName(CKind) << 0;
3539 Clause = ParseOpenMPCountsClause();
3541 case OMPC_uses_allocators:
3542 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3545 if (DKind != OMPD_interop) {
3547 Diag(Tok, diag::err_omp_more_one_clause)
3548 << getOpenMPDirectiveName(DKind, OMPVersion)
3549 << getOpenMPClauseName(CKind) << 0;
3552 Clause = ParseOpenMPClause(CKind, WrongDirective);
3558 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3560 case OMPC_device_type:
3562 skipUntilPragmaOpenMPEnd(DKind);
3564 case OMPC_threadprivate:
3565 case OMPC_groupprivate:
3568 if (!WrongDirective)
3569 Diag(Tok, diag::err_omp_unexpected_clause)
3570 << getOpenMPClauseName(CKind)
3571 << getOpenMPDirectiveName(DKind, OMPVersion);
3575 case OMPC_contains: {
3577 SourceLocation LLoc = Tok.getLocation();
3578 SourceLocation RLoc;
3579 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3584 if (DK == OMPD_unknown) {
3585 skipUntilPragmaOpenMPEnd(OMPD_assume);
3586 Diag(Tok, diag::err_omp_unexpected_clause)
3587 << getOpenMPClauseName(CKind)
3588 << getOpenMPDirectiveName(DKind, OMPVersion);
3592 DKVec.push_back(DK);
3595 Diag(Tok, diag::err_omp_unexpected_clause)
3596 << getOpenMPClauseName(CKind)
3597 << getOpenMPDirectiveName(DKind, OMPVersion);
3600 RLoc = Tok.getLocation();
3602 if (!WrongDirective)
3603 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3604 CKind, DKVec, Loc, LLoc, RLoc);
3607 case OMPC_no_openmp:
3608 case OMPC_no_openmp_routines:
3609 case OMPC_no_openmp_constructs:
3610 case OMPC_no_parallelism: {
3612 Diag(Tok, diag::err_omp_more_one_clause)
3613 << getOpenMPDirectiveName(DKind, OMPVersion)
3614 << getOpenMPClauseName(CKind) << 0;
3618 if (!WrongDirective)
3619 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3620 CKind, Loc, Tok.getLocation());
3623 case OMPC_ompx_attribute:
3624 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3626 case OMPC_ompx_bare:
3627 if (DKind == llvm::omp::Directive::OMPD_target) {
3632 Diag(Tok, diag::err_omp_unexpected_clause)
3633 << getOpenMPClauseName(CKind)
3634 << getOpenMPDirectiveName(DKind, OMPVersion);
3636 WrongDirective =
true;
3639 Diag(Tok, diag::note_ompx_bare_clause)
3640 << getOpenMPClauseName(CKind) <<
"target teams";
3641 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3642 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3643 << getOpenMPClauseName(CKind)
3644 << getOpenMPDirectiveName(DKind, OMPVersion);
3647 Clause = ParseOpenMPClause(CKind, WrongDirective);
3649 case OMPC_looprange:
3650 Clause = ParseOpenMPLoopRangeClause();
3655 return ErrorFound ?
nullptr : Clause;
3663 bool IsAddressOfOperand) {
3665 if (
T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3673 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3676 RLoc = Tok.getLocation();
3677 if (!
T.consumeClose())
3678 RLoc =
T.getCloseLocation();
3700bool Parser::ParseOpenMPIndirectClause(
3705 if (
Tok.isNot(tok::l_paren)) {
3724 if (
Ret.isInvalid())
3727 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3729 if (
Ret.isInvalid())
3737ExprResult Parser::ParseOMPInteropFrSelector() {
3740 tok::annot_pragma_openmp_end);
3741 if (FT.expectAndConsume(diag::err_expected_lparen_after,
"fr")) {
3743 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3747 SourceLocation Loc = Tok.getLocation();
3750 Arg = Actions.ActOnFinishFullExpr(Arg.
get(), Loc,
false);
3758 tok::annot_pragma_openmp_end);
3759 if (AT.expectAndConsume(diag::err_expected_lparen_after,
"attr")) {
3761 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3765 bool HasError =
false;
3768 if (Tok.is(tok::r_paren)) {
3769 Diag(Tok, diag::err_omp_interop_attr_not_string);
3772 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::r_brace) &&
3773 Tok.isNot(tok::annot_pragma_openmp_end)) {
3774 if (Tok.is(tok::string_literal)) {
3777 Attrs.push_back(S.
get());
3782 Diag(Tok, diag::err_omp_interop_attr_not_string);
3785 if (Tok.is(tok::comma))
3795 bool HasError =
false;
3796 bool IsTarget =
false;
3797 bool IsTargetSync =
false;
3799 while (Tok.is(tok::identifier)) {
3801 bool PreferTypeAllowed = (
Kind == OMPC_init ||
Kind == OMPC_append_args) &&
3802 InteropInfo.
Prefs.empty() && !IsTarget &&
3804 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3809 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3812 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3814 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3815 IsTargetSync =
true;
3817 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3818 PreferTypeAllowed) {
3819 if (Kind == OMPC_append_args &&
getLangOpts().OpenMP < 60) {
3820 Diag(Tok, diag::err_omp_append_args_prefer_type_60);
3825 tok::annot_pragma_openmp_end);
3826 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3830 if (Tok.is(tok::r_paren)) {
3831 Diag(Tok, diag::err_omp_expected_pref_spec);
3835 while (Tok.isNot(tok::r_paren) &&
3836 Tok.isNot(tok::annot_pragma_openmp_end)) {
3838 if (Tok.is(tok::l_brace)) {
3842 Diag(Tok, diag::err_omp_prefer_type_brace_60);
3846 tok::annot_pragma_openmp_end);
3848 Expr *FrExpr =
nullptr;
3849 SmallVector<Expr *, 2> AttrExprs;
3850 bool SeenFr =
false;
3854 if (Tok.is(tok::r_brace)) {
3855 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3859 while (Tok.isNot(tok::r_brace) &&
3860 Tok.isNot(tok::annot_pragma_openmp_end)) {
3861 if (Tok.is(tok::identifier) &&
3862 Tok.getIdentifierInfo()->isStr(
"fr")) {
3864 Diag(Tok, diag::err_omp_interop_multiple_fr);
3868 {tok::comma, tok::r_brace, tok::annot_pragma_openmp_end},
3878 }
else if (Tok.is(tok::identifier) &&
3879 Tok.getIdentifierInfo()->isStr(
"attr")) {
3880 if (ParseOMPInteropAttrSelector(AttrExprs))
3885 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3888 if (Tok.is(tok::comma))
3891 if (BT.consumeClose())
3894 if (FrExpr || !AttrExprs.empty())
3895 InteropInfo.
Prefs.emplace_back(FrExpr, AttrExprs);
3900 SourceLocation Loc = Tok.getLocation();
3904 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
3907 InteropInfo.
Prefs.emplace_back(PTExpr.
get(),
3908 llvm::SmallVector<Expr *, 2>{});
3911 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3916 if (Tok.is(tok::comma))
3922 Diag(Tok, diag::err_omp_expected_interop_type);
3925 if (!Tok.is(tok::comma))
3930 if (!HasError && !IsTarget && !IsTargetSync) {
3931 Diag(Tok, diag::err_omp_expected_interop_type);
3935 if (Kind == OMPC_init) {
3936 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
3937 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3938 if (Tok.is(tok::colon))
3955 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3956 getOpenMPClauseName(Kind).data()))
3959 bool InteropError =
false;
3960 OMPInteropInfo InteropInfo;
3961 if (Kind == OMPC_init)
3962 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3965 SourceLocation VarLoc = Tok.getLocation();
3968 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3973 SourceLocation RLoc = Tok.getLocation();
3974 if (!
T.consumeClose())
3975 RLoc =
T.getCloseLocation();
3977 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3980 if (Kind == OMPC_init)
3981 return Actions.OpenMP().ActOnOpenMPInitClause(
3982 InteropVarExpr.
get(), InteropInfo, Loc,
T.getOpenLocation(), VarLoc,
3984 if (Kind == OMPC_use)
3985 return Actions.OpenMP().ActOnOpenMPUseClause(
3986 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
3988 if (Kind == OMPC_destroy)
3989 return Actions.OpenMP().ActOnOpenMPDestroyClause(
3990 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
3992 llvm_unreachable(
"Unexpected interop variable clause.");
3995OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
3999 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4000 getOpenMPClauseName(OMPC_ompx_attribute).data()))
4003 ParsedAttributes ParsedAttrs(AttrFactory);
4004 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
4007 if (
T.consumeClose())
4013 SmallVector<Attr *> Attrs;
4014 for (
const ParsedAttr &PA : ParsedAttrs) {
4015 switch (PA.getKind()) {
4016 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
4017 if (!PA.checkExactlyNumArgs(Actions, 2))
4019 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
4020 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
4023 case ParsedAttr::AT_AMDGPUWavesPerEU:
4024 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
4025 !PA.checkAtMostNumArgs(Actions, 2))
4027 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
4028 PA, PA.getArgAsExpr(0),
4029 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
4032 case ParsedAttr::AT_CUDALaunchBounds:
4033 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
4034 !PA.checkAtMostNumArgs(Actions, 3))
4036 if (
auto *A = Actions.CreateLaunchBoundsAttr(
4037 PA, PA.getArgAsExpr(0),
4038 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
4039 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr,
4044 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
4049 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
4050 Attrs, Loc,
T.getOpenLocation(),
T.getCloseLocation());
4056 if (!Val || ParseOnly)
4058 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
4059 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
4060 static_cast<DefaultKind
>(Val->Type) ==
4061 OMP_DEFAULT_firstprivate)) {
4062 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
4063 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
4066 : OMPC_firstprivate)
4067 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4070 return Actions.OpenMP().ActOnOpenMPSimpleClause(
4071 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
4075 SourceLocation Loc = Tok.getLocation();
4080 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
4087 SourceLocation DelimLoc;
4090 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4091 getOpenMPClauseName(Kind).data()))
4095 SmallVector<unsigned, 4> Arg;
4096 SmallVector<SourceLocation, 4> KLoc;
4097 if (Kind == OMPC_schedule) {
4098 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
4099 Arg.resize(NumberOfElements);
4100 KLoc.resize(NumberOfElements);
4105 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4108 Arg[Modifier1] = KindModifier;
4109 KLoc[Modifier1] = Tok.getLocation();
4110 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4111 Tok.isNot(tok::annot_pragma_openmp_end))
4113 if (Tok.is(tok::comma)) {
4117 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4121 KLoc[Modifier2] = Tok.getLocation();
4122 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4123 Tok.isNot(tok::annot_pragma_openmp_end))
4127 if (Tok.is(tok::colon))
4130 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
4132 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4134 Arg[ScheduleKind] = KindModifier;
4135 KLoc[ScheduleKind] = Tok.getLocation();
4136 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4137 Tok.isNot(tok::annot_pragma_openmp_end))
4139 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
4140 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
4141 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
4144 }
else if (Kind == OMPC_dist_schedule) {
4146 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4147 KLoc.push_back(Tok.getLocation());
4148 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4149 Tok.isNot(tok::annot_pragma_openmp_end))
4151 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
4153 }
else if (Kind == OMPC_default) {
4156 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4158 Arg.push_back(Modifier);
4159 KLoc.push_back(Tok.getLocation());
4160 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4161 Tok.isNot(tok::annot_pragma_openmp_end))
4164 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
4169 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4170 Arg.push_back(VariableCategory);
4171 KLoc.push_back(Tok.getLocation());
4172 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4173 Tok.isNot(tok::annot_pragma_openmp_end))
4176 Arg.push_back(OMPC_DEFAULT_VC_all);
4177 KLoc.push_back(SourceLocation());
4179 }
else if (Kind == OMPC_defaultmap) {
4182 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4188 Arg.push_back(Modifier);
4189 KLoc.push_back(Tok.getLocation());
4190 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4191 Tok.isNot(tok::annot_pragma_openmp_end))
4194 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
4195 if (Tok.is(tok::colon))
4198 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
4201 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4202 KLoc.push_back(Tok.getLocation());
4203 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4204 Tok.isNot(tok::annot_pragma_openmp_end))
4208 KLoc.push_back(SourceLocation());
4210 }
else if (Kind == OMPC_order) {
4211 enum { Modifier, OrderKind, NumberOfElements };
4212 Arg.resize(NumberOfElements);
4213 KLoc.resize(NumberOfElements);
4217 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4220 Arg[Modifier] = KindModifier;
4221 KLoc[Modifier] = Tok.getLocation();
4222 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4223 Tok.isNot(tok::annot_pragma_openmp_end))
4226 if (Tok.is(tok::colon))
4229 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
4231 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4233 Arg[OrderKind] = KindModifier;
4234 KLoc[OrderKind] = Tok.getLocation();
4235 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4236 Tok.isNot(tok::annot_pragma_openmp_end))
4238 }
else if (Kind == OMPC_device) {
4244 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4245 KLoc.push_back(Tok.getLocation());
4251 KLoc.emplace_back();
4253 }
else if (Kind == OMPC_grainsize) {
4257 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4261 Arg.push_back(Modifier);
4262 KLoc.push_back(Tok.getLocation());
4268 if (Modifier == OMPC_GRAINSIZE_strict) {
4269 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4274 KLoc.emplace_back();
4278 KLoc.emplace_back();
4280 }
else if (Kind == OMPC_dyn_groupprivate) {
4281 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4282 Arg.resize(NumberOfModifiers);
4283 KLoc.resize(NumberOfModifiers);
4287 auto ConsumeModifier = [&]() {
4288 unsigned Type = NumberOfModifiers;
4291 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4295 ParenT.consumeOpen();
4298 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4301 Diag(Tok.getLocation(), diag::err_expected)
4302 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4304 return std::make_tuple(
Type, Modifier, Loc);
4306 Type = ComplexModifier;
4307 Loc = Tok.getLocation();
4308 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4309 Tok.isNot(tok::annot_pragma_openmp_end))
4311 ParenT.consumeClose();
4314 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4316 Type = SimpleModifier;
4317 Loc = Tok.getLocation();
4318 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4319 Tok.isNot(tok::annot_pragma_openmp_end))
4323 return std::make_tuple(
Type, Modifier, Loc);
4326 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4327 SourceLocation Loc) {
4328 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4329 if (!KLoc[
Type].isValid()) {
4330 Arg[
Type] = Modifier;
4333 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4340 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4341 if (Type1 < NumberOfModifiers) {
4342 SaveModifier(Type1, Mod1, Loc1);
4343 if (Tok.is(tok::comma)) {
4346 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4347 if (Type2 < NumberOfModifiers)
4348 SaveModifier(Type2, Mod2, Loc2);
4351 if (Tok.is(tok::colon))
4354 Diag(Tok, diag::warn_pragma_expected_colon)
4355 <<
"dyn_groupprivate modifier";
4357 }
else if (Kind == OMPC_num_tasks) {
4361 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4365 Arg.push_back(Modifier);
4366 KLoc.push_back(Tok.getLocation());
4372 if (Modifier == OMPC_NUMTASKS_strict) {
4373 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4378 KLoc.emplace_back();
4382 KLoc.emplace_back();
4385 assert(Kind == OMPC_if);
4386 KLoc.push_back(Tok.getLocation());
4387 TentativeParsingAction TPA(*
this);
4389 Arg.push_back(
static_cast<unsigned>(DK));
4390 if (DK != OMPD_unknown) {
4392 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4397 Arg.back() = unsigned(OMPD_unknown);
4404 bool NeedAnExpression = (
Kind == OMPC_schedule && DelimLoc.
isValid()) ||
4405 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
4406 Kind == OMPC_if ||
Kind == OMPC_device ||
4407 Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4408 Kind == OMPC_dyn_groupprivate;
4409 if (NeedAnExpression) {
4410 SourceLocation ELoc = Tok.getLocation();
4416 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4420 SourceLocation RLoc = Tok.getLocation();
4421 if (!
T.consumeClose())
4422 RLoc =
T.getCloseLocation();
4424 if (NeedAnExpression && Val.
isInvalid())
4427 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4428 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4429 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4430 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4431 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4434 : OMPC_firstprivate)
4435 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4441 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4442 Kind, Arg, Val.
get(), Loc,
T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4447 if (ReductionIdScopeSpec.
isEmpty()) {
4485 ReductionIdScopeSpec,
nullptr,
4489 false,
nullptr, ReductionId);
4496 if (!
Tok.is(tok::identifier))
4503 return TypeModifier;
4509 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4510 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4516 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4520 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4521 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4522 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4526 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4528 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4531 return T.consumeClose();
4537 bool HasMapType =
false;
4539 StringRef PreMapName =
"";
4543 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4544 TypeModifier == OMPC_MAP_MODIFIER_close ||
4545 TypeModifier == OMPC_MAP_MODIFIER_present ||
4546 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4547 Data.MapTypeModifiers.push_back(TypeModifier);
4548 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4549 if (PP.LookAhead(0).isNot(tok::comma) &&
4550 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4551 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4552 <<
"map type modifier";
4554 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4555 Data.MapTypeModifiers.push_back(TypeModifier);
4556 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4560 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4562 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4563 <<
"map type modifier";
4568 Data.ExtraModifier = MapKind;
4570 PreMapLoc = Tok.getLocation();
4571 PreMapName = Tok.getIdentifierInfo()->getName();
4573 Diag(Tok, diag::err_omp_more_one_map_type);
4574 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4578 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4579 Data.MapTypeModifiers.push_back(TypeModifier);
4580 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4581 if (PP.LookAhead(0).isNot(tok::comma) &&
4582 PP.LookAhead(0).isNot(tok::colon))
4583 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4584 <<
"map type modifier";
4586 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4596 if (Tok.is(tok::comma)) {
4597 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4602 if (PP.LookAhead(0).is(tok::colon)) {
4610 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4621 if (!Tok.is(tok::colon)) {
4622 Diag(Tok, diag::err_omp_unknown_map_type);
4636 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4641 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4642 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4643 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4653 if (
Tok.is(tok::colon)) {
4654 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4659 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4663ExprResult Parser::ParseOpenMPIteratorsExpr() {
4664 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4665 "Expected 'iterator' token.");
4669 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4672 SourceLocation LLoc =
T.getOpenLocation();
4673 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4674 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4677 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4684 IteratorType = TR.
get();
4688 IdentifierInfo *II =
nullptr;
4689 SourceLocation IdLoc;
4690 if (Tok.is(tok::identifier)) {
4691 II = Tok.getIdentifierInfo();
4694 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4698 SourceLocation AssignLoc;
4699 if (Tok.is(tok::equal))
4702 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4707 SourceLocation Loc = Tok.getLocation();
4710 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4713 SourceLocation ColonLoc;
4714 if (Tok.is(tok::colon))
4718 Loc = Tok.getLocation();
4721 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4724 SourceLocation SecColonLoc;
4727 if (Tok.is(tok::colon)) {
4731 Loc = Tok.getLocation();
4734 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4739 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4740 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4741 if (Tok.is(tok::comma))
4744 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4747 D.
Type = IteratorType;
4757 SourceLocation RLoc = Tok.getLocation();
4758 if (!
T.consumeClose())
4759 RLoc =
T.getCloseLocation();
4761 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4770 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4773 if (Tok.is(tok::identifier) &&
4774 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4776 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4777 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4778 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4779 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4780 Data.ExtraModifier != OMPC_DEPEND_inout)
4781 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4783 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4784 ? OMPC_DEPEND_outallmemory
4785 : OMPC_DEPEND_inoutallmemory;
4801 Data.DepModOrTailExpr = Tail.
get();
4803 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4804 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4822 bool AllocatorSeen =
false;
4823 bool AlignSeen =
false;
4842 if (
Tok.is(tok::l_paren)) {
4843 switch (CurrentModifier) {
4844 case OMPC_ALLOCATE_allocator: {
4845 if (AllocatorSeen) {
4846 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4848 << getOpenMPClauseName(Kind);
4850 Data.AllocClauseModifiers.push_back(CurrentModifier);
4851 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4854 tok::annot_pragma_openmp_end);
4858 AllocatorSeen =
true;
4861 case OMPC_ALLOCATE_align: {
4863 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4865 << getOpenMPClauseName(Kind);
4867 Data.AllocClauseModifiers.push_back(CurrentModifier);
4868 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4872 Data.AllocateAlignment = Val.
get();
4877 llvm_unreachable(
"Unexpected allocate modifier");
4880 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4882 if (
Tok.isNot(tok::comma))
4885 CurrentModifierLoc =
Tok.getLocation();
4890 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4893 }
while (!AllocatorSeen || !AlignSeen);
4902 bool InvalidReductionId =
false;
4903 bool IsInvalidMapperModifier =
false;
4907 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4908 getOpenMPClauseName(Kind).data()))
4911 bool HasIterator =
false;
4912 bool InvalidIterator =
false;
4913 bool NeedRParenForLinear =
false;
4915 tok::annot_pragma_openmp_end);
4917 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4918 Kind == OMPC_in_reduction) {
4920 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4921 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4924 Data.ExtraModifier =
4926 Data.ExtraModifierLoc = Tok.getLocation();
4928 assert(Tok.is(tok::comma) &&
"Expected comma.");
4932 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4933 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4939 if (Tok.is(tok::kw_private)) {
4940 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4941 Data.OriginalSharingModifierLoc = Tok.getLocation();
4943 }
else if (Tok.is(tok::identifier) &&
4944 (PP.getSpelling(Tok) ==
"shared" ||
4945 PP.getSpelling(Tok) ==
"default")) {
4946 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4947 Data.OriginalSharingModifierLoc = Tok.getLocation();
4950 Diag(Tok.getLocation(), diag::err_expected)
4951 <<
"'private or shared or default'";
4956 if (!Tok.is(tok::comma)) {
4957 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4964 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4969 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4970 if (InvalidReductionId) {
4971 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4974 if (Tok.is(tok::colon))
4977 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4978 if (!InvalidReductionId)
4979 Data.ReductionOrMapperId =
4980 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4981 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4983 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4992 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4993 Data.DepModOrTailExpr = IteratorRes.
get();
4995 ExpectAndConsume(tok::comma);
5001 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5003 Data.ExtraModifierLoc = Tok.getLocation();
5005 (Kind == OMPC_doacross &&
5007 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5012 if (DKind == OMPD_ordered_standalone && Kind == OMPC_depend &&
5013 Data.ExtraModifier == OMPC_DEPEND_source) {
5019 if (Tok.is(tok::colon)) {
5021 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
5022 Diag(Tok, DKind == OMPD_ordered_standalone
5023 ? diag::warn_pragma_expected_colon_r_paren
5024 : diag::warn_pragma_expected_colon)
5025 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
5027 if (Kind == OMPC_doacross) {
5028 if (Tok.is(tok::identifier) &&
5029 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
5030 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
5031 ? OMPC_DOACROSS_source_omp_cur_iteration
5032 : OMPC_DOACROSS_sink_omp_cur_iteration;
5035 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
5036 if (Tok.isNot(tok::minus)) {
5037 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5038 << getOpenMPClauseName(Kind) << 0 << 0;
5045 if (Tok.isNot(tok::numeric_constant) ||
5046 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
5047 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
5048 << getOpenMPClauseName(Kind) << 0 << 0;
5054 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
5055 if (Tok.isNot(tok::r_paren)) {
5056 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5057 << getOpenMPClauseName(Kind) << 1 << 1;
5063 if (Kind == OMPC_doacross &&
5064 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
5065 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
5066 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
5072 }
else if (Kind == OMPC_linear) {
5074 Data.ExtraModifier = OMPC_LINEAR_val;
5075 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
5076 Data.ExtraModifier =
5080 NeedRParenForLinear =
true;
5082 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
5083 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
5084 <<
"linear(list: [linear-modifier,] step(step-size))";
5086 }
else if (Kind == OMPC_lastprivate) {
5093 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
5094 Data.ExtraModifier =
5096 Data.ExtraModifierLoc = Tok.getLocation();
5098 assert(Tok.is(tok::colon) &&
"Expected colon.");
5101 }
else if (Kind == OMPC_map) {
5103 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
5106 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
5107 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
5108 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
5109 Data.IteratorExpr = IteratorRes.
get();
5111 ExpectAndConsume(tok::comma);
5113 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
5116 InvalidIterator =
true;
5126 Data.ExtraModifierLoc = Tok.getLocation();
5129 TentativeParsingAction TPA(*
this);
5130 bool ColonPresent =
false;
5131 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5133 if (Tok.is(tok::colon))
5134 ColonPresent =
true;
5141 Diag(Tok, diag::err_omp_map_modifier_specification_list);
5143 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
5149 Data.ExtraModifier = OMPC_MAP_tofrom;
5151 if (DKind == OMPD_target_enter_data)
5152 Data.ExtraModifier = OMPC_MAP_to;
5153 else if (DKind == OMPD_target_exit_data)
5154 Data.ExtraModifier = OMPC_MAP_from;
5156 Data.IsMapTypeImplicit =
true;
5159 if (Tok.is(tok::colon))
5161 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
5162 while (Tok.is(tok::identifier)) {
5167 Data.MotionModifiers.push_back(Modifier);
5168 Data.MotionModifiersLoc.push_back(Tok.getLocation());
5169 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
5171 Tail = ParseOpenMPIteratorsExpr();
5172 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
5175 Data.IteratorExpr = Tail.
get();
5178 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
5180 if (IsInvalidMapperModifier)
5188 if (Tok.is(tok::comma))
5192 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
5193 if (!IsInvalidMapperModifier) {
5195 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
5197 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
5199 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5207 }
else if (Kind == OMPC_allocate ||
5208 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
5209 PP.getSpelling(Tok) ==
"iterator")) {
5213 TentativeParsingAction TPA(*
this);
5218 if (Kind == OMPC_allocate) {
5223 Tail = ParseOpenMPIteratorsExpr();
5225 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
5228 if (Tok.is(tok::colon)) {
5235 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5236 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5238 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5245 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5248 }
else if (Kind == OMPC_adjust_args) {
5252 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5254 Data.ExtraModifierLoc = Tok.getLocation();
5256 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5261 if (Tok.is(tok::colon))
5262 Data.ColonLoc = Tok.getLocation();
5266 if (Tok.is(tok::l_paren)) {
5269 if (Tok.is(tok::identifier)) {
5270 std::string Modifier = PP.getSpelling(Tok);
5271 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5272 Data.NeedDevicePtrModifier =
5273 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5274 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5276 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5277 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5282 if (Tok.is(tok::r_paren)) {
5283 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5286 Diag(Tok, diag::err_expected) << tok::r_paren;
5287 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5296 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5299 }
else if (Kind == OMPC_use_device_ptr) {
5303 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5307 Data.ExtraModifier = FallbackModifier;
5308 Data.ExtraModifierLoc = Tok.getLocation();
5310 if (Tok.is(tok::colon))
5313 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5316 }
else if (Kind == OMPC_num_teams || Kind == OMPC_thread_limit) {
5320 Data.ExtraModifierArray[0] =
Data.ExtraModifierArray[1] =
5325 bool CanParseLowerBoundModifier = (Kind == OMPC_num_teams);
5326 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"dims") &&
5333 Data.ExtraModifierArray[Mod] =
5334 Kind == OMPC_num_teams ?
static_cast<int>(OMPC_NUMTEAMS_dims)
5335 :
static_cast<int>(OMPC_THREADLIMIT_dims);
5336 Data.ExtraModifierExprArray[Mod] = ExprR.
get();
5337 Data.ExtraModifierLocArray[Mod] = TLoc;
5341 if (Tok.is(tok::colon)) {
5344 CanParseLowerBoundModifier =
false;
5345 }
else if (CanParseLowerBoundModifier && Tok.is(tok::comma)) {
5350 Diag(Tok, diag::err_modifier_expected_colon)
5351 << getOpenMPClauseName(Kind);
5353 Data.RLoc = Tok.getLocation();
5354 if (!
T.consumeClose())
5355 Data.RLoc =
T.getCloseLocation();
5361 if (CanParseLowerBoundModifier) {
5362 TentativeParsingAction TPA(*
this);
5367 Data.RLoc = Tok.getLocation();
5368 if (!
T.consumeClose())
5369 Data.RLoc =
T.getCloseLocation();
5374 if (Tok.is(tok::colon)) {
5377 Data.ExtraModifierArray[Mod] = OMPC_NUMTEAMS_lower_bound;
5378 Data.ExtraModifierExprArray[Mod] = FirstExpr.
get();
5379 Data.ExtraModifierLocArray[Mod] = TLoc;
5387 }
else if (Kind == OMPC_num_threads) {
5391 bool HasModifier =
false;
5393 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"dims") &&
5404 Diag(TLoc, diag::err_omp_incompatible_modifiers)
5407 << getOpenMPClauseName(Kind);
5409 Data.ExtraModifierArray[1] =
static_cast<int>(OMPC_NUMTHREADS_dims);
5410 Data.ExtraModifierExprArray[1] =
5412 Data.ExtraModifierLocArray[1] = TLoc;
5419 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5424 Diag(Tok, diag::err_omp_incompatible_modifiers)
5427 Data.ExtraModifierArray[0])
5428 << getOpenMPClauseName(Kind);
5429 Data.ExtraModifierArray[0] = Modifier;
5430 Data.ExtraModifierLocArray[0] = Tok.getLocation();
5440 if (Tok.is(tok::comma))
5448 if (!Tok.is(tok::colon)) {
5449 Diag(Tok, diag::err_modifier_expected_colon)
5450 << getOpenMPClauseName(Kind);
5452 Data.RLoc = Tok.getLocation();
5453 if (!
T.consumeClose())
5454 Data.RLoc =
T.getCloseLocation();
5462 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5463 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5464 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5465 (Kind == OMPC_reduction && !InvalidReductionId) ||
5469 (Kind == OMPC_adjust_args &&
5471 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5472 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5473 Tok.isNot(tok::annot_pragma_openmp_end))) {
5480 Vars.push_back(VarExpr.
get());
5482 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5487 IsComma = Tok.is(tok::comma);
5490 else if (Tok.isNot(tok::r_paren) &&
5491 Tok.isNot(tok::annot_pragma_openmp_end) &&
5492 (!MayHaveTail || Tok.isNot(tok::colon))) {
5493 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
5494 Diag(Tok, diag::err_omp_expected_punc)
5495 << ((Kind == OMPC_flush)
5496 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5497 : getOpenMPClauseName(Kind))
5498 << (Kind == OMPC_flush);
5503 if (NeedRParenForLinear)
5507 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5508 bool StepFound =
false;
5509 bool ModifierFound =
false;
5511 Data.ColonLoc = Tok.getLocation();
5514 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5515 bool Malformed =
false;
5516 while (Tok.isNot(tok::r_paren)) {
5517 if (Tok.is(tok::identifier)) {
5522 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5525 if (LinKind == OMPC_LINEAR_step) {
5527 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5530 tok::annot_pragma_openmp_end);
5534 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5539 Data.StepModifierLoc = StepModifierLoc;
5543 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5545 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5547 Data.ExtraModifier = LinKind;
5549 ModifierFound =
true;
5554 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5563 if (Tok.is(tok::comma))
5565 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5568 if (!Malformed && !StepFound && !ModifierFound)
5569 Diag(ELoc, diag::err_expected_expression);
5573 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5576 Data.DepModOrTailExpr = Tail.
get();
5578 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5584 Data.RLoc = Tok.getLocation();
5585 if (!
T.consumeClose())
5586 Data.RLoc =
T.getCloseLocation();
5590 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5592 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5593 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5620 "Expected parsing to start at clause name");
5625 if (
T.consumeOpen()) {
5626 Diag(
Tok, diag::err_expected) << tok::l_paren;
5639 Exprs.push_back(Val.
get());
5642 bool Result =
T.consumeClose();
5643 OpenLoc =
T.getOpenLocation();
5644 CloseLoc =
T.getCloseLocation();
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.
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
static OpenMPDirectiveKind checkOpenMPDirectiveName(Parser &P, SourceLocation Loc, OpenMPDirectiveKind Kind, StringRef Name)
static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P)
static OpenMPMapModifierKind isMapModifier(Parser &P)
Checks if the token is a valid map-type-modifier.
static std::optional< SimpleClauseData > parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind)
static bool checkExtensionProperty(Parser &P, SourceLocation Loc, OMPTraitProperty &TIProperty, OMPTraitSelector &TISelector, llvm::StringMap< SourceLocation > &Seen)
static ExprResult parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data)
Parse 'allocate' clause modifiers.
static DeclarationName parseOpenMPReductionId(Parser &P)
static ExprResult parseContextScore(Parser &P)
Parse optional 'score' '(' <expr> ')' ':'.
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, UnqualifiedId &ReductionId)
static bool parseStepSize(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data, OpenMPClauseKind CKind, SourceLocation ELoc)
Parse step size expression.
static void parseMapType(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data)
Parse map-type in map clause.
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.
static OpenMPMapClauseKind isMapType(Parser &P)
Checks if the token is a valid map-type.
This file declares semantic analysis functions specific to AMDGPU.
This file declares facilities that support code completion.
This file declares semantic analysis for OpenMP constructs and clauses.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
void getAsVariantMatchInfo(ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const
Create a variant match info object from this trait info object.
llvm::SmallVector< OMPTraitSet, 2 > Sets
The outermost level of selector sets.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
DeclarationNameTable DeclarationNames
OMPTraitInfo & getNewOMPTraitInfo()
Return a new OMPTraitInfo object owned by this context.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
Represents a C++ nested-name-specifier or a global scope specifier.
bool isEmpty() const
No scope specifier.
static const TST TST_unspecified
Decl - This represents one declaration (or definition), e.g.
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
The name of a declaration.
bool isEmpty() const
Evaluates true when this declaration name is empty.
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
This represents a decl that may have a name.
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
This is a basic class for representing single OpenMP clause.
static const ParsedAttributesView & none()
ParsedAttributes - A collection of parsed attributes.
Introduces zero or more scopes for parsing.
void Enter(unsigned ScopeFlags)
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, SmallVectorImpl< Expr * > &Vars, SemaOpenMP::OpenMPVarListDataTy &Data)
Parses clauses with list.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Preprocessor & getPreprocessor() const
bool parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data)
Parse map-type-modifiers in map clause.
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
ParseStringLiteralExpression - This handles the various token types that form string literals,...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
bool parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data)
Parses the mapper modifier in map, to, and from clauses.
friend class ParsingOpenMPDirectiveRAII
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
friend class ColonProtectionRAIIObject
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
const Token & getCurToken() const
void ExitScope()
ExitScope - Pop a scope off the scope stack.
ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc, bool IsAddressOfOperand=false)
Parses simple expression in parens for single-expression clauses of OpenMP constructs.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data, const LangOptions &LangOpts)
Parses a reserved locator like 'omp_all_memory'.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D)
Re-enter a possible template scope, creating as many template parameter scopes as necessary.
bool ParseOpenMPDeclareBeginVariantDirective(SourceLocation Loc)
Parses 'omp begin declare variant' directive.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
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 ...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
The collection of all-type qualifiers we support.
Represents a struct/union/class.
@ OpenMPDirectiveScope
This is the scope of OpenMP executable directive.
@ CompoundStmtScope
This is a compound statement scope.
@ OpenMPSimdDirectiveScope
This is the scope of some OpenMP simd directive.
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ OpenMPLoopDirectiveScope
This is the scope of some OpenMP loop directive.
@ DeclScope
This is a scope that can contain a declaration.
Smart pointer class that efficiently represents Objective-C method names.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
void ActOnExitFunctionContext()
void ActOnReenterFunctionContext(Scope *S, Decl *D)
Push the parameters of D, which must be a function, into scope.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
Token - This structure provides full information about a lexed token.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isNot(tok::TokenKind K) const
Base wrapper for a particular "section" of type source info.
The base class of the type hierarchy.
QualType getCanonicalTypeInternal() const
Represents a C++ unqualified-id that has been parsed.
void setOperatorFunctionId(SourceLocation OperatorLoc, OverloadedOperatorKind Op, SourceLocation SymbolLocations[3])
Specify that this unqualified-id was parsed as an operator-function-id.
Represents a variable declaration or definition.
Defines the clang::TargetInfo interface.
PRESERVE_NONE bool Ret(InterpState &S)
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.
Top level wrappers for InstallAPI frontend operations.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
OpenMPDefaultClauseVariableCategory
OpenMP variable-category for 'default' clause.
@ OMPC_DEFAULTMAP_MODIFIER_unknown
@ OMPC_ORDER_MODIFIER_unknown
@ OMPC_NEED_DEVICE_PTR_unknown
@ OMPC_ADJUST_ARGS_unknown
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
OpenMPDeviceType
OpenMP device type for 'device_type' clause.
@ OMPC_DEVICE_TYPE_unknown
@ OMPC_SCHEDULE_MODIFIER_unknown
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
@ OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown
@ OMPC_DYN_GROUPPRIVATE_FALLBACK_last
@ Property
The type of a property.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ OMPC_LASTPRIVATE_unknown
OpenMPGrainsizeClauseModifier
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str, const LangOptions &LangOpts)
OpenMPNumTasksClauseModifier
OpenMPUseDevicePtrFallbackModifier
OpenMP 6.1 use_device_ptr fallback modifier.
@ OMPC_USE_DEVICE_PTR_FALLBACK_unknown
@ Type
The name was classified as a type.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OpenMPMotionModifierKind
OpenMP modifier kind for 'to' or 'from' clause.
@ OMPC_MOTION_MODIFIER_unknown
@ OMPC_DEFAULTMAP_unknown
OpenMPAllocateClauseModifier
OpenMP modifiers for 'allocate' clause.
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "executable".
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
@ OMPC_DYN_GROUPPRIVATE_unknown
bool isOpenMPInformationalDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "informational".
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
@ OMPC_THREADLIMIT_unknown
OpenMPNumThreadsClauseModifier
@ OMPC_NUMTHREADS_unknown
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
@ OMPC_MAP_MODIFIER_unknown
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
ActionResult< Expr * > ExprResult
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
ActionResult< Stmt * > StmtResult
OpenMPDefaultClauseVariableCategory getOpenMPDefaultVariableCategory(StringRef Str, const LangOptions &LangOpts)
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
int const char * function
llvm::omp::TraitProperty Kind
StringRef RawString
The raw string as we parsed it. This is needed for the isa trait set (which accepts anything) and (la...
llvm::omp::TraitSelector Kind
SmallVector< OMPTraitProperty, 1 > Properties
SmallVector< OMPTraitSelector, 2 > Selectors
Clang specific specialization of the OMPContext to lookup target features.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
llvm::SmallVector< OMPInteropPref, 4 > Prefs
This structure contains most locations needed for by an OMPVarListClause.
std::optional< Expr * > Indirect
The directive with indirect clause.
OpenMPDirectiveKind Kind
The directive kind, begin declare target or declare target.
OMPDeclareTargetDeclAttr::DevTypeTy DT
The 'device_type' as parsed from the clause.
SourceLocation Loc
The directive location.
llvm::DenseMap< NamedDecl *, MapInfo > ExplicitlyMapped
Explicitly listed variables and functions in a 'to' or 'link' clause.
SourceLocation DeclIdentLoc
SourceLocation SecColonLoc
IdentifierInfo * DeclIdent
OMPIteratorExpr::IteratorRange Range
Data used for processing a list of variables in OpenMP clauses.
Data for list of allocators.
Expr * AllocatorTraits
Allocator traits.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Expr * Allocator
Allocator.