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 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
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::compat_cxx11_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 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
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") {
689 llvm::omp::Version OMPVersion =
691 P.
Diag(
Tok, diag::err_omp_more_one_clause)
692 << getOpenMPDirectiveName(OMPD_declare_simd, OMPVersion)
703 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
704 CKind == OMPC_linear) {
707 if (CKind == OMPC_aligned) {
709 }
else if (CKind == OMPC_linear) {
710 Data.ExtraModifier = OMPC_LINEAR_val;
716 getOpenMPClauseKind(ClauseName), *Vars,
Data))
718 if (CKind == OMPC_aligned) {
719 Alignments.append(Aligneds.size() - Alignments.size(),
720 Data.DepModOrTailExpr);
721 }
else if (CKind == OMPC_linear) {
722 assert(0 <=
Data.ExtraModifier &&
724 "Unexpected linear modifier.");
727 Data.ExtraModifierLoc))
728 Data.ExtraModifier = OMPC_LINEAR_val;
729 LinModifiers.append(Linears.size() - LinModifiers.size(),
731 Steps.append(Linears.size() - Steps.size(),
Data.DepModOrTailExpr);
738 if (
Tok.is(tok::comma))
747 PP.EnterToken(Tok,
true);
748 PP.EnterTokenStream(Toks,
true,
754 FNContextRAII FnContext(*
this, Ptr);
755 OMPDeclareSimdDeclAttr::BranchStateTy BS =
756 OMPDeclareSimdDeclAttr::BS_Undefined;
758 SmallVector<Expr *, 4> Uniforms;
759 SmallVector<Expr *, 4> Aligneds;
760 SmallVector<Expr *, 4> Alignments;
761 SmallVector<Expr *, 4> Linears;
762 SmallVector<unsigned, 4> LinModifiers;
763 SmallVector<Expr *, 4> Steps;
766 Alignments, Linears, LinModifiers, Steps);
767 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
769 SourceLocation EndLoc = ConsumeAnnotationToken();
772 return Actions.OpenMP().ActOnOpenMPDeclareSimdDirective(
773 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
774 LinModifiers, Steps, SourceRange(Loc, EndLoc));
781 CONTEXT_SELECTOR_SET_LVL = 0,
782 CONTEXT_SELECTOR_LVL = 1,
783 CONTEXT_TRAIT_LVL = 2,
786static StringRef stringLiteralParser(
Parser &P) {
793 if (
Tok.
is(tok::identifier) ||
Tok.
is(tok::kw_for)) {
801 return stringLiteralParser(P);
804 diag::warn_omp_declare_variant_string_literal_or_identifier)
809static bool checkForDuplicates(
Parser &P, StringRef Name,
811 llvm::StringMap<SourceLocation> &Seen,
813 auto Res = Seen.try_emplace(Name, NameLoc);
819 P.
Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
821 P.
Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
827void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
828 llvm::omp::TraitSet
Set,
830 llvm::StringMap<SourceLocation> &Seen) {
831 TIProperty.
Kind = TraitProperty::invalid;
833 SourceLocation NameLoc = Tok.getLocation();
835 if (Selector == llvm::omp::TraitSelector::target_device_device_num) {
837 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
839 if (DeviceNumExprResult.
isUsable()) {
840 Expr *DeviceNumExpr = DeviceNumExprResult.
get();
841 Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr);
845 Name = getNameFromIdOrString(*
this, Tok, CONTEXT_TRAIT_LVL);
847 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
848 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
853 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
854 if (TIProperty.
Kind != TraitProperty::invalid) {
855 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
856 TIProperty.
Kind = TraitProperty::invalid;
862 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
863 << Name << getOpenMPContextTraitSelectorName(Selector)
864 << getOpenMPContextTraitSetName(
Set);
866 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
867 if (SetForName != TraitSet::invalid) {
868 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
869 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
870 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
871 << Name <<
"<selector-name>"
872 <<
"(<property-name>)";
875 TraitSelector SelectorForName =
876 getOpenMPContextTraitSelectorKind(Name, SetForName);
877 if (SelectorForName != TraitSelector::invalid) {
878 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
879 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
880 bool AllowsTraitScore =
false;
881 bool RequiresProperty =
false;
882 isValidTraitSelectorForTraitSet(
883 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
884 AllowsTraitScore, RequiresProperty);
885 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
886 << getOpenMPContextTraitSetName(
887 getOpenMPContextTraitSetForSelector(SelectorForName))
888 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
891 for (
const auto &PotentialSet :
892 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
893 TraitSet::device, TraitSet::target_device}) {
894 TraitProperty PropertyForName =
895 getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
896 if (PropertyForName == TraitProperty::invalid)
898 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
899 << getOpenMPContextTraitSetName(
900 getOpenMPContextTraitSetForProperty(PropertyForName))
901 << getOpenMPContextTraitSelectorName(
902 getOpenMPContextTraitSelectorForProperty(PropertyForName))
903 << (
"(" + Name +
")").str();
906 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
907 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
913 llvm::StringMap<SourceLocation> &Seen) {
914 assert(TISelector.
Kind ==
915 llvm::omp::TraitSelector::implementation_extension &&
916 "Only for extension properties, e.g., "
917 "`implementation={extension(PROPERTY)}`");
918 if (TIProperty.
Kind == TraitProperty::invalid)
921 if (TIProperty.
Kind ==
922 TraitProperty::implementation_extension_disable_implicit_base)
925 if (TIProperty.
Kind ==
926 TraitProperty::implementation_extension_allow_templates)
929 if (TIProperty.
Kind ==
930 TraitProperty::implementation_extension_bind_to_declaration)
935 llvm::omp::TraitProperty::implementation_extension_match_all ||
937 llvm::omp::TraitProperty::implementation_extension_match_any ||
939 llvm::omp::TraitProperty::implementation_extension_match_none);
942 if (IsMatchExtension(TIProperty)) {
944 if (IsMatchExtension(SeenProp)) {
945 P.
Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
946 StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
949 P.
Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
950 << CONTEXT_TRAIT_LVL << SeenName;
956 llvm_unreachable(
"Unknown extension property!");
959void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
960 llvm::omp::TraitSet
Set,
961 llvm::StringMap<SourceLocation> &Seen) {
962 assert(TISelector.
Kind != TraitSelector::user_condition &&
963 "User conditions are special properties not handled here!");
965 SourceLocation PropertyLoc = Tok.getLocation();
966 OMPTraitProperty TIProperty;
967 parseOMPTraitPropertyKind(TIProperty,
Set, TISelector.
Kind, Seen);
969 if (TISelector.
Kind == llvm::omp::TraitSelector::implementation_extension)
972 TIProperty.
Kind = TraitProperty::invalid;
975 if (TIProperty.
Kind == TraitProperty::invalid) {
976 if (PropertyLoc != Tok.getLocation())
977 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
978 << CONTEXT_TRAIT_LVL;
982 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.
Kind,
991 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
992 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
994 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
995 << getOpenMPContextTraitSetName(
Set);
996 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
997 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
999 << getOpenMPContextTraitSelectorName(
1000 getOpenMPContextTraitSelectorForProperty(TIProperty.
Kind))
1001 << getOpenMPContextTraitSetName(
1002 getOpenMPContextTraitSetForProperty(TIProperty.
Kind));
1003 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1004 << CONTEXT_TRAIT_LVL;
1007void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
1008 llvm::omp::TraitSet
Set,
1009 llvm::StringMap<SourceLocation> &Seen) {
1010 TISelector.
Kind = TraitSelector::invalid;
1012 SourceLocation NameLoc = Tok.getLocation();
1013 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_LVL);
1015 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1016 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1020 TISelector.
Kind = getOpenMPContextTraitSelectorKind(Name,
Set);
1021 if (TISelector.
Kind != TraitSelector::invalid) {
1022 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1023 TISelector.
Kind = TraitSelector::invalid;
1028 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1029 << Name << getOpenMPContextTraitSetName(
Set);
1031 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1032 if (SetForName != TraitSet::invalid) {
1033 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1034 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1035 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1036 << Name <<
"<selector-name>"
1037 <<
"<property-name>";
1040 for (
const auto &PotentialSet :
1041 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1042 TraitSet::device, TraitSet::target_device}) {
1043 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1044 PotentialSet, TraitSelector::invalid, Name);
1045 if (PropertyForName == TraitProperty::invalid)
1047 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1048 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1049 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1050 << getOpenMPContextTraitSetName(
1051 getOpenMPContextTraitSetForProperty(PropertyForName))
1052 << getOpenMPContextTraitSelectorName(
1053 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1054 << (
"(" + Name +
")").str();
1057 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1058 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1065 StringRef SelectorName =
1067 if (SelectorName !=
"score")
1078 <<
"score expression";
1082void Parser::parseOMPContextSelector(
1083 OMPTraitSelector &TISelector, llvm::omp::TraitSet
Set,
1084 llvm::StringMap<SourceLocation> &SeenSelectors) {
1085 unsigned short OuterPC = ParenCount;
1090 auto FinishSelector = [OuterPC,
this]() ->
void {
1093 while (!
SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1094 tok::annot_pragma_openmp_end},
1097 if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1098 (void)ConsumeParen();
1099 if (OuterPC <= ParenCount) {
1103 if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1109 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1110 << CONTEXT_SELECTOR_LVL;
1113 SourceLocation SelectorLoc = Tok.getLocation();
1114 parseOMPTraitSelectorKind(TISelector,
Set, SeenSelectors);
1115 if (TISelector.
Kind == TraitSelector::invalid)
1116 return FinishSelector();
1118 bool AllowsTraitScore =
false;
1119 bool RequiresProperty =
false;
1120 if (!isValidTraitSelectorForTraitSet(TISelector.
Kind,
Set, AllowsTraitScore,
1121 RequiresProperty)) {
1122 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1123 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1124 << getOpenMPContextTraitSetName(
Set);
1125 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1126 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1127 << getOpenMPContextTraitSetName(
1128 getOpenMPContextTraitSetForSelector(TISelector.
Kind))
1129 << RequiresProperty;
1130 return FinishSelector();
1133 if (!RequiresProperty) {
1135 {getOpenMPContextTraitPropertyForSelector(TISelector.
Kind),
1136 getOpenMPContextTraitSelectorName(TISelector.
Kind)});
1140 if (!Tok.is(tok::l_paren)) {
1141 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1142 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1143 << getOpenMPContextTraitSetName(
Set);
1144 return FinishSelector();
1147 if (TISelector.
Kind == TraitSelector::user_condition) {
1148 SourceLocation RLoc;
1151 return FinishSelector();
1154 {TraitProperty::user_condition_unknown,
"<condition>"});
1159 tok::annot_pragma_openmp_end);
1161 (void)BDT.consumeOpen();
1163 SourceLocation ScoreLoc = Tok.getLocation();
1166 if (!AllowsTraitScore && !Score.
isUnset()) {
1168 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1169 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1170 << getOpenMPContextTraitSetName(
Set) << Score.
get();
1172 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1173 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1174 << getOpenMPContextTraitSetName(
Set) <<
"<invalid>";
1182 llvm::StringMap<SourceLocation> SeenProperties;
1184 parseOMPContextProperty(TISelector,
Set, SeenProperties);
1191void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1192 llvm::StringMap<SourceLocation> &Seen) {
1193 TISet.
Kind = TraitSet::invalid;
1195 SourceLocation NameLoc = Tok.getLocation();
1196 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_SET_LVL);
1198 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1199 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1203 TISet.
Kind = getOpenMPContextTraitSetKind(Name);
1204 if (TISet.
Kind != TraitSet::invalid) {
1205 if (checkForDuplicates(*
this, Name, NameLoc, Seen,
1206 CONTEXT_SELECTOR_SET_LVL))
1207 TISet.
Kind = TraitSet::invalid;
1212 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1214 TraitSelector SelectorForName =
1215 getOpenMPContextTraitSelectorKind(Name, TISet.
Kind);
1216 if (SelectorForName != TraitSelector::invalid) {
1217 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1218 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1219 bool AllowsTraitScore =
false;
1220 bool RequiresProperty =
false;
1221 isValidTraitSelectorForTraitSet(
1222 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1223 AllowsTraitScore, RequiresProperty);
1224 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1225 << getOpenMPContextTraitSetName(
1226 getOpenMPContextTraitSetForSelector(SelectorForName))
1227 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
1230 for (
const auto &PotentialSet :
1231 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1232 TraitSet::device, TraitSet::target_device}) {
1233 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1234 PotentialSet, TraitSelector::invalid, Name);
1235 if (PropertyForName == TraitProperty::invalid)
1237 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1238 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1239 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1240 << getOpenMPContextTraitSetName(
1241 getOpenMPContextTraitSetForProperty(PropertyForName))
1242 << getOpenMPContextTraitSelectorName(
1243 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1244 << (
"(" + Name +
")").str();
1247 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1248 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1251void Parser::parseOMPContextSelectorSet(
1252 OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1253 auto OuterBC = BraceCount;
1258 auto FinishSelectorSet = [
this, OuterBC]() ->
void {
1261 while (!
SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1262 tok::annot_pragma_openmp_end},
1265 if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1266 (void)ConsumeBrace();
1267 if (OuterBC <= BraceCount) {
1271 if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1277 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1278 << CONTEXT_SELECTOR_SET_LVL;
1281 parseOMPTraitSetKind(TISet, SeenSets);
1282 if (TISet.
Kind == TraitSet::invalid)
1283 return FinishSelectorSet();
1287 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1289 << (
"context set name \"" + getOpenMPContextTraitSetName(TISet.
Kind) +
1293 if (Tok.is(tok::l_brace)) {
1294 (void)ConsumeBrace();
1296 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1298 << (
"'=' that follows the context set name \"" +
1299 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1303 llvm::StringMap<SourceLocation> SeenSelectors;
1305 OMPTraitSelector TISelector;
1306 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1307 if (TISelector.
Kind != TraitSelector::invalid &&
1313 if (Tok.is(tok::r_brace)) {
1314 (void)ConsumeBrace();
1316 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1318 << (
"context selectors for the context set \"" +
1319 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1324bool Parser::parseOMPContextSelectors(
SourceLocation Loc, OMPTraitInfo &TI) {
1325 llvm::StringMap<SourceLocation> SeenSets;
1328 parseOMPContextSelectorSet(TISet, SeenSets);
1329 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1330 TI.
Sets.push_back(TISet);
1339 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
1340 PP.EnterToken(Tok,
true);
1341 PP.EnterTokenStream(Toks,
true,
1347 FNContextRAII FnContext(*
this, Ptr);
1349 SourceLocation RLoc;
1359 getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion), RLoc,
1362 if (!AssociatedFunction.
isUsable()) {
1363 if (!Tok.is(tok::annot_pragma_openmp_end))
1367 (void)ConsumeAnnotationToken();
1371 OMPTraitInfo *ParentTI =
1372 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
1373 ASTContext &ASTCtx = Actions.getASTContext();
1375 SmallVector<Expr *, 6> AdjustNothing;
1376 SmallVector<Expr *, 6> AdjustNeedDevicePtr;
1377 SmallVector<Expr *, 6> AdjustNeedDeviceAddr;
1378 SmallVector<OMPInteropInfo, 3> AppendArgs;
1379 SourceLocation AdjustArgsLoc, AppendArgsLoc;
1382 if (Tok.is(tok::annot_pragma_openmp_end)) {
1383 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1387 bool IsError =
false;
1388 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1391 : getOpenMPClauseKind(PP.getSpelling(Tok));
1392 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind, OMPVersion)) {
1393 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1394 << (OMPVersion < 51 ? 0 : 1);
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 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
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 llvm::omp::Version OMPVersion =
1785 Actions.getLangOpts().getOpenMPVersion();
1786 Diag(Tok, diag::err_omp_more_one_clause)
1787 << getOpenMPDirectiveName(OMPD_declare_target, OMPVersion)
1788 << getOpenMPClauseName(OMPC_indirect) << 0;
1791 bool IsToEnterLinkOrLocalClause =
1792 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1793 assert((!IsDeviceTypeClause || !IsToEnterLinkOrLocalClause) &&
1798 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1799 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1802 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1803 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1808 if (
getLangOpts().OpenMP < 60 && ClauseName ==
"local") {
1810 ? diag::err_omp_declare_target_unexpected_clause_52
1811 : diag::err_omp_declare_target_unexpected_clause)
1819 if (!IsDeviceTypeClause && !IsIndirectClause &&
1820 DTCI.
Kind == OMPD_begin_declare_target) {
1822 ? diag::err_omp_declare_target_unexpected_clause_52
1823 : diag::err_omp_declare_target_unexpected_clause)
1824 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1828 if (!IsDeviceTypeClause && !IsToEnterLinkOrLocalClause &&
1829 !IsIndirectClause) {
1831 ? diag::err_omp_declare_target_unexpected_clause_52
1832 : diag::err_omp_declare_target_unexpected_clause)
1841 if (IsToEnterLinkOrLocalClause || IsIndirectClause)
1842 HasToLinkLocalOrIndirectClause =
true;
1844 if (IsIndirectClause) {
1845 if (!ParseOpenMPIndirectClause(DTCI,
false))
1850 if (IsDeviceTypeClause) {
1851 std::optional<SimpleClauseData> DevTypeData =
1854 if (DeviceTypeLoc.
isValid()) {
1856 Diag(DevTypeData->Loc,
1857 diag::warn_omp_more_one_device_type_clause);
1861 case OMPC_DEVICE_TYPE_any:
1862 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Any;
1864 case OMPC_DEVICE_TYPE_host:
1865 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Host;
1867 case OMPC_DEVICE_TYPE_nohost:
1868 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1871 llvm_unreachable(
"Unexpected device_type");
1873 DeviceTypeLoc = DevTypeData->Loc;
1880 if (DTCI.
Kind == OMPD_declare_target || HasIdentifier) {
1881 auto &&
Callback = [
this, MT, &DTCI](CXXScopeSpec &SS,
1882 DeclarationNameInfo NameInfo) {
1883 NamedDecl *ND = Actions.OpenMP().lookupOpenMPDeclareTargetName(
1887 SemaOpenMP::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.
getLoc()};
1890 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1893 if (ParseOpenMPSimpleVarList(OMPD_declare_target,
Callback,
1898 if (Tok.is(tok::l_paren)) {
1900 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1903 if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1906 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1907 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1912 if (Tok.is(tok::comma))
1916 if (DTCI.
Indirect && DTCI.
DT != OMPDeclareTargetDeclAttr::DT_Any)
1917 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1920 if (DTCI.
Kind == OMPD_declare_target && RequiresToLinkLocalOrIndirectClause &&
1921 !HasToLinkLocalOrIndirectClause)
1922 Diag(DTCI.
Loc, diag::err_omp_declare_target_missing_required_clause)
1934 if (Tok.is(tok::annot_pragma_openmp_end))
1937 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
1938 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1939 << getOpenMPDirectiveName(DKind, OMPVersion);
1940 while (Tok.isNot(tok::annot_pragma_openmp_end))
1949 bool SkipUntilOpenMPEnd) {
1950 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1952 if (FoundKind == ExpectedKind) {
1954 skipUntilPragmaOpenMPEnd(ExpectedKind);
1958 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
1959 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1961 Diag(BeginLoc, diag::note_matching)
1962 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind, OMPVersion) +
"'")
1964 if (SkipUntilOpenMPEnd)
1971 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1975 if (Tok.is(tok::annot_pragma_openmp_end))
1976 ConsumeAnnotationToken();
1982 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
1983 "Not an OpenMP directive!");
1986 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
1991 TentativeParsingAction TPA(*
this);
1992 Loc = ConsumeAnnotationToken();
1994 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1999 Toks.push_back(Tok);
2000 while (Cnt && Tok.isNot(tok::eof)) {
2002 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
2004 else if (Tok.is(tok::annot_pragma_openmp_end))
2006 Toks.push_back(Tok);
2011 auto *LP =
new LateParsedPragma(
this, AS);
2013 getCurrentClass().LateParsedDeclarations.push_back(LP);
2018 Loc = ConsumeAnnotationToken();
2023 case OMPD_threadprivate: {
2025 DeclDirectiveListParserHelper Helper(
this, DKind);
2026 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2028 skipUntilPragmaOpenMPEnd(DKind);
2030 ConsumeAnnotationToken();
2031 return Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2032 Loc, Helper.getIdentifiers());
2036 case OMPD_groupprivate: {
2038 DeclDirectiveListParserHelper Helper(
this, DKind);
2039 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2041 skipUntilPragmaOpenMPEnd(DKind);
2043 ConsumeAnnotationToken();
2044 return Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2045 Loc, Helper.getIdentifiers());
2049 case OMPD_allocate: {
2051 DeclDirectiveListParserHelper Helper(
this, DKind);
2052 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2054 SmallVector<OMPClause *, 1> Clauses;
2055 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2056 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
2057 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2059 Tok.isAnnotation() ? OMPC_unknown
2060 : getOpenMPClauseKind(PP.getSpelling(Tok));
2061 Actions.OpenMP().StartOpenMPClause(CKind);
2062 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2063 !SeenClauses[
unsigned(CKind)]);
2064 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2066 SeenClauses[unsigned(CKind)] =
true;
2067 if (Clause !=
nullptr)
2068 Clauses.push_back(Clause);
2069 if (Tok.is(tok::annot_pragma_openmp_end)) {
2070 Actions.OpenMP().EndOpenMPClause();
2074 if (Tok.is(tok::comma))
2076 Actions.OpenMP().EndOpenMPClause();
2078 skipUntilPragmaOpenMPEnd(DKind);
2081 ConsumeAnnotationToken();
2082 return Actions.OpenMP().ActOnOpenMPAllocateDirective(
2083 Loc, Helper.getIdentifiers(), Clauses);
2087 case OMPD_requires: {
2089 SmallVector<OMPClause *, 5> Clauses;
2090 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2091 if (Tok.is(tok::annot_pragma_openmp_end)) {
2092 Diag(Tok, diag::err_omp_expected_clause)
2093 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2096 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2099 : getOpenMPClauseKind(PP.getSpelling(Tok));
2100 Actions.OpenMP().StartOpenMPClause(CKind);
2101 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
2102 !SeenClauses[
unsigned(CKind)]);
2103 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2105 SeenClauses[unsigned(CKind)] =
true;
2106 if (Clause !=
nullptr)
2107 Clauses.push_back(Clause);
2108 if (Tok.is(tok::annot_pragma_openmp_end)) {
2109 Actions.OpenMP().EndOpenMPClause();
2113 if (Tok.is(tok::comma))
2115 Actions.OpenMP().EndOpenMPClause();
2118 if (Clauses.empty()) {
2119 Diag(Tok, diag::err_omp_expected_clause)
2120 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2121 ConsumeAnnotationToken();
2124 ConsumeAnnotationToken();
2125 return Actions.OpenMP().ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2128 SmallVector<OMPClause *, 1> Clauses;
2130 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2131 Actions.OpenMP().ActOnOpenMPErrorDirective(Clauses, StartLoc,
2137 case OMPD_begin_assumes:
2140 case OMPD_end_assumes:
2143 case OMPD_declare_reduction:
2145 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2146 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2148 ConsumeAnnotationToken();
2152 case OMPD_declare_mapper: {
2154 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2156 ConsumeAnnotationToken();
2161 case OMPD_begin_declare_variant: {
2166 ConsumeAnnotationToken();
2170 case OMPD_end_declare_variant: {
2172 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2173 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2175 Diag(Loc, diag::err_expected_begin_declare_variant);
2177 ConsumeAnnotationToken();
2180 case OMPD_declare_variant:
2181 case OMPD_declare_simd: {
2187 Toks.push_back(Tok);
2189 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2190 Toks.push_back(Tok);
2193 Toks.push_back(Tok);
2197 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2198 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2200 }
else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2204 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2205 MaybeParseCXX11Attributes(Attrs);
2206 ParsingDeclSpec PDS(*
this);
2207 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2210 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2214 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2215 << (DKind == OMPD_declare_simd ? 0 : 1);
2219 DeclGroupRef DG =
Ptr.get();
2220 SourceManager &SM = PP.getSourceManager();
2221 if (llvm::none_of(DG, [&](
const Decl *D) {
2224 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2225 << (DKind == OMPD_declare_simd ? 0 : 1);
2229 if (DKind == OMPD_declare_simd)
2230 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2231 assert(DKind == OMPD_declare_variant &&
2232 "Expected declare variant directive only");
2233 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2236 case OMPD_begin_declare_target:
2237 case OMPD_declare_target: {
2239 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2240 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2241 if (DKind == OMPD_declare_target && !HasClauses &&
2243 Diag(DTLoc, diag::warn_omp_deprecated_declare_target_delimited_form);
2245 ParseOMPDeclareTargetClauses(DTCI);
2246 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2253 if (HasImplicitMappings) {
2254 Actions.OpenMP().ActOnStartOpenMPDeclareTargetContext(DTCI);
2258 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2259 llvm::SmallVector<Decl *, 4> Decls;
2261 Decls.push_back(It.first);
2262 return Actions.BuildDeclaratorGroup(Decls);
2264 case OMPD_end_declare_target: {
2265 if (!Actions.OpenMP().isInOpenMPDeclareTargetContext()) {
2266 Diag(Tok, diag::err_omp_unexpected_directive)
2267 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2270 const SemaOpenMP::DeclareTargetContextInfo &DTCI =
2271 Actions.OpenMP().ActOnOpenMPEndDeclareTargetDirective();
2272 ParseOMPEndDeclareTargetDirective(DTCI.
Kind, DKind, DTCI.
Loc);
2276 Diag(Tok, diag::err_omp_unexpected_directive)
2277 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2281 Diag(Tok, diag::err_omp_unknown_directive);
2284 switch (getDirectiveCategory(DKind)) {
2285 case Category::Executable:
2286 case Category::Meta:
2287 case Category::Subsidiary:
2288 case Category::Utility:
2289 Diag(Tok, diag::err_omp_unexpected_directive)
2290 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2292 case Category::Declarative:
2293 case Category::Informational:
2297 while (Tok.isNot(tok::annot_pragma_openmp_end))
2303StmtResult Parser::ParseOpenMPExecutableDirective(
2305 bool ReadDirectiveWithinMetadirective) {
2307 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
2309 bool HasAssociatedStatement =
true;
2310 Association Assoc = getDirectiveAssociation(DKind);
2314 if (DKind != OMPD_ordered_standalone && DKind != OMPD_section &&
2315 (Assoc == Association::None || Assoc == Association::Separating)) {
2316 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2317 ParsedStmtContext()) {
2318 Diag(Tok, diag::err_omp_immediate_directive)
2319 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2320 if (DKind == OMPD_error) {
2321 SkipUntil(tok::annot_pragma_openmp_end);
2325 HasAssociatedStatement =
false;
2328 SourceLocation EndLoc;
2329 SmallVector<OMPClause *, 5> Clauses;
2330 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2331 DeclarationNameInfo DirName;
2338 bool ImplicitClauseAllowed =
false;
2339 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2341 ImplicitClauseAllowed =
true;
2345 if (DKind == OMPD_critical) {
2347 tok::annot_pragma_openmp_end);
2348 if (!
T.consumeOpen()) {
2349 if (Tok.isAnyIdentifier()) {
2351 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2354 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2358 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2360 if (Tok.isNot(tok::annot_pragma_openmp_end))
2368 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2369 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2372 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2375 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2376 while (Tok.isNot(tok::annot_pragma_openmp_end))
2380 bool HasImplicitClause =
false;
2381 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2382 HasImplicitClause =
true;
2385 PP.EnterToken(Tok,
true);
2386 PP.EnterToken(ImplicitTok,
true);
2391 : getOpenMPClauseKind(PP.getSpelling(Tok));
2392 if (DKind == OMPD_depobj && CKind == OMPC_update)
2393 CKind = OMPC_update_depend_objects;
2395 if (HasImplicitClause) {
2396 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2397 if (DKind == OMPD_flush) {
2400 assert(DKind == OMPD_depobj &&
"Expected flush or depobj directives.");
2401 CKind = OMPC_depobj;
2405 ImplicitClauseAllowed =
false;
2406 Actions.OpenMP().StartOpenMPClause(CKind);
2407 HasImplicitClause =
false;
2408 SourceLocation ClauseLoc = Tok.getLocation();
2411 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2412 SeenClauses[unsigned(CKind)] =
true;
2414 Clauses.push_back(Clause);
2417 if (Tok.is(tok::comma))
2419 Actions.OpenMP().EndOpenMPClause();
2423 if (Tok.getLocation() == ClauseLoc) {
2424 skipUntilPragmaOpenMPEnd(DKind);
2429 EndLoc = Tok.getLocation();
2431 ConsumeAnnotationToken();
2433 assert(DKind != OMPD_ordered_blockassoc &&
2434 "Wrong kind for ordered directive");
2435 if (DKind == OMPD_ordered_standalone) {
2438 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2439 if (SeenClauses[
unsigned(CK)]) {
2440 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2441 ParsedStmtContext()) {
2442 Diag(Loc, diag::err_omp_immediate_directive)
2443 << getOpenMPDirectiveName(DKind, OMPVersion) << 1
2444 << getOpenMPClauseName(CK);
2446 HasAssociatedStatement =
false;
2450 if (HasAssociatedStatement)
2451 DKind = OMPD_ordered_blockassoc;
2454 if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
2455 !SeenClauses[
unsigned(OMPC_sizes)]) {
2456 Diag(Loc, diag::err_omp_required_clause)
2457 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"sizes";
2459 if (DKind == OMPD_split && !SeenClauses[
unsigned(OMPC_counts)]) {
2460 Diag(Loc, diag::err_omp_required_clause)
2461 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"counts";
2465 if (HasAssociatedStatement) {
2467 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2473 Sema::CompoundScopeRAII Scope(Actions);
2474 AssociatedStmt = ParseStatement();
2479 Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
2482 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2483 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2484 DKind == OMPD_target_exit_data) {
2485 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2486 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2487 Actions.ActOnCompoundStmt(Loc, Loc, {},
2490 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2494 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2497 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2498 OMPDirectiveScope.Exit();
2503StmtResult Parser::ParseOpenMPInformationalDirective(
2505 bool ReadDirectiveWithinMetadirective) {
2507 "Unexpected directive category");
2509 bool HasAssociatedStatement =
true;
2511 SmallVector<OMPClause *, 5> Clauses;
2512 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2513 DeclarationNameInfo DirName;
2516 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2518 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2521 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2522 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2523 while (Tok.isNot(tok::annot_pragma_openmp_end))
2530 : getOpenMPClauseKind(PP.getSpelling(Tok));
2531 Actions.OpenMP().StartOpenMPClause(CKind);
2533 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2534 SeenClauses[unsigned(CKind)] =
true;
2536 Clauses.push_back(Clause);
2538 if (Tok.is(tok::comma))
2540 Actions.OpenMP().EndOpenMPClause();
2543 SourceLocation EndLoc = Tok.getLocation();
2544 ConsumeAnnotationToken();
2547 if (HasAssociatedStatement) {
2548 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2551 Sema::CompoundScopeRAII Scope(Actions);
2552 AssociatedStmt = ParseStatement();
2555 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2559 DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2561 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2562 OMPDirectiveScope.Exit();
2567StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2568 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2569 if (!ReadDirectiveWithinMetadirective)
2570 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2571 "Not an OpenMP directive!");
2574 SourceLocation Loc = ReadDirectiveWithinMetadirective
2576 : ConsumeAnnotationToken();
2577 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
2579 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2580 Diag(Tok, diag::err_omp_unknown_directive);
2586 bool IsExecutable = [&]() {
2587 if (DKind == OMPD_error)
2589 auto Res = getDirectiveCategory(DKind);
2590 return Res == Category::Executable || Res == Category::Subsidiary;
2594 Directive = ParseOpenMPExecutableDirective(
2595 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2596 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2605 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
2606 while (Tok.isNot(tok::annot_pragma_openmp_end))
2609 skipUntilPragmaOpenMPEnd(DKind);
2610 if (Tok.is(tok::annot_pragma_openmp_end))
2611 ConsumeAnnotationToken();
2614 case OMPD_metadirective: {
2616 SmallVector<VariantMatchInfo, 4> VMIs;
2621 TentativeParsingAction TPA(*
this);
2622 ASTContext &ASTContext = Actions.getASTContext();
2625 tok::annot_pragma_openmp_end);
2626 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2629 : getOpenMPClauseKind(PP.getSpelling(Tok));
2631 if (CKind == OMPC_unknown) {
2632 Diag(Tok, diag::err_omp_expected_clause) <<
"metadirective";
2634 SkipUntil(tok::annot_pragma_openmp_end);
2637 if (
getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
2638 Diag(Tok, diag::err_omp_unexpected_clause)
2639 << getOpenMPClauseName(CKind) <<
"metadirective";
2640 if (CKind == OMPC_default &&
getLangOpts().OpenMP >= 52)
2641 Diag(Tok, diag::warn_omp_default_deprecated);
2646 if (
T.expectAndConsume(diag::err_expected_lparen_after,
2647 getOpenMPClauseName(CKind).data())) {
2649 SkipUntil(tok::annot_pragma_openmp_end);
2653 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2654 if (CKind == OMPC_when) {
2656 parseOMPContextSelectors(Loc, TI);
2657 if (TI.
Sets.size() == 0) {
2658 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2664 if (Tok.is(tok::colon))
2667 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2675 while (Tok.isNot(tok::r_paren) || paren != 0) {
2676 if (Tok.is(tok::l_paren))
2678 if (Tok.is(tok::r_paren))
2680 if (Tok.is(tok::annot_pragma_openmp_end)) {
2681 Diag(Tok, diag::err_omp_expected_punc)
2682 << getOpenMPClauseName(CKind) << 0;
2689 if (Tok.is(tok::r_paren))
2692 VariantMatchInfo VMI;
2695 VMIs.push_back(VMI);
2702 [
this, Loc](StringRef ISATrait) {
2705 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2707 TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2709 ArrayRef<llvm::omp::TraitProperty>(),
2710 Actions.OpenMP().getOpenMPDeviceNum());
2713 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2720 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2722 if (Idx++ != BestIdx) {
2727 while (Tok.isNot(tok::r_paren) || paren != 0) {
2728 if (Tok.is(tok::l_paren))
2730 if (Tok.is(tok::r_paren))
2735 if (Tok.is(tok::r_paren))
2742 : getOpenMPClauseKind(PP.getSpelling(Tok));
2749 if (CKind == OMPC_when) {
2750 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2752 parseOMPContextSelectors(Loc, TI);
2760 if (Tok.is(tok::r_paren)) {
2761 SkipUntil(tok::annot_pragma_openmp_end);
2766 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2774 if (BestIdx == -1 && Idx > 0) {
2775 assert(Tok.is(tok::annot_pragma_openmp_end) &&
2776 "Expecting the end of the pragma here");
2777 ConsumeAnnotationToken();
2782 case OMPD_threadprivate: {
2784 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2785 ParsedStmtContext()) {
2786 Diag(Tok, diag::err_omp_immediate_directive)
2787 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2790 DeclDirectiveListParserHelper Helper(
this, DKind);
2791 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2793 skipUntilPragmaOpenMPEnd(DKind);
2794 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2795 Loc, Helper.getIdentifiers());
2796 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2798 SkipUntil(tok::annot_pragma_openmp_end);
2801 case OMPD_groupprivate: {
2802 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2803 ParsedStmtContext()) {
2804 Diag(Tok, diag::err_omp_immediate_directive)
2805 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2808 DeclDirectiveListParserHelper Helper(
this, DKind);
2809 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2811 skipUntilPragmaOpenMPEnd(DKind);
2812 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2813 Loc, Helper.getIdentifiers());
2814 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2816 SkipUntil(tok::annot_pragma_openmp_end);
2819 case OMPD_allocate: {
2821 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2822 ParsedStmtContext()) {
2823 Diag(Tok, diag::err_omp_immediate_directive)
2824 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2827 DeclDirectiveListParserHelper Helper(
this, DKind);
2828 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2830 SmallVector<OMPClause *, 1> Clauses;
2831 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2832 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2833 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2835 Tok.isAnnotation() ? OMPC_unknown
2836 : getOpenMPClauseKind(PP.getSpelling(Tok));
2837 Actions.OpenMP().StartOpenMPClause(CKind);
2838 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2839 !SeenClauses[
unsigned(CKind)]);
2840 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2842 SeenClauses[unsigned(CKind)] =
true;
2843 if (Clause !=
nullptr)
2844 Clauses.push_back(Clause);
2845 if (Tok.is(tok::annot_pragma_openmp_end)) {
2846 Actions.OpenMP().EndOpenMPClause();
2850 if (Tok.is(tok::comma))
2852 Actions.OpenMP().EndOpenMPClause();
2854 skipUntilPragmaOpenMPEnd(DKind);
2856 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPAllocateDirective(
2857 Loc, Helper.getIdentifiers(), Clauses);
2858 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2860 SkipUntil(tok::annot_pragma_openmp_end);
2863 case OMPD_declare_reduction:
2866 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2867 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2869 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2871 SkipUntil(tok::annot_pragma_openmp_end);
2874 case OMPD_declare_mapper: {
2877 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2879 ConsumeAnnotationToken();
2880 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2882 SkipUntil(tok::annot_pragma_openmp_end);
2886 case OMPD_declare_target: {
2888 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2889 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2891 ParseOMPDeclareTargetClauses(DTCI);
2892 bool HasImplicitMappings =
2895 if (HasImplicitMappings) {
2896 Diag(Tok, diag::err_omp_unexpected_directive)
2897 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2898 SkipUntil(tok::annot_pragma_openmp_end);
2905 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2908 case OMPD_begin_declare_variant: {
2913 ConsumeAnnotationToken();
2917 case OMPD_end_declare_variant: {
2919 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2920 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2922 Diag(Loc, diag::err_expected_begin_declare_variant);
2923 ConsumeAnnotationToken();
2926 case OMPD_declare_simd:
2927 case OMPD_begin_declare_target:
2928 case OMPD_end_declare_target:
2930 case OMPD_declare_variant:
2931 Diag(Tok, diag::err_omp_unexpected_directive)
2932 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2933 SkipUntil(tok::annot_pragma_openmp_end);
2937 Directive = ParseOpenMPInformationalDirective(
2938 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2940 "Informational directive remains unprocessed");
2945 Diag(Tok, diag::err_omp_unknown_directive);
2946 SkipUntil(tok::annot_pragma_openmp_end);
2952bool Parser::ParseOpenMPSimpleVarList(
2956 bool AllowScopeSpecifier) {
2957 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
2960 if (
T.expectAndConsume(diag::err_expected_lparen_after,
2961 getOpenMPDirectiveName(Kind, OMPVersion).data()))
2963 bool IsCorrect =
true;
2964 bool NoIdentIsFound =
true;
2967 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2971 Token PrevTok = Tok;
2972 NoIdentIsFound =
false;
2975 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2978 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2981 false,
false,
false,
2982 false,
false,
nullptr, Name)) {
2984 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2986 }
else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2987 Tok.isNot(tok::annot_pragma_openmp_end)) {
2989 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2993 << SourceRange(PrevTok.
getLocation(), PrevTokLocation);
2995 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2998 if (Tok.is(tok::comma)) {
3003 if (NoIdentIsFound) {
3004 Diag(Tok, diag::err_expected) << tok::identifier;
3009 IsCorrect = !
T.consumeClose() && IsCorrect;
3014OMPClause *Parser::ParseOpenMPSizesClause() {
3015 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3016 SmallVector<Expr *, 4> ValExprs;
3017 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
3021 return Actions.OpenMP().ActOnOpenMPSizesClause(ValExprs, ClauseNameLoc,
3025OMPClause *Parser::ParseOpenMPCountsClause() {
3026 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3027 SmallVector<Expr *, 4> ValExprs;
3028 std::optional<unsigned> FillIdx;
3029 unsigned FillCount = 0;
3030 SourceLocation FillLoc;
3032 assert(getOpenMPClauseName(OMPC_counts) == PP.getSpelling(Tok) &&
3033 "Expected parsing to start at clause name");
3037 if (
T.consumeOpen()) {
3038 Diag(Tok, diag::err_expected) << tok::l_paren;
3043 if (Tok.is(tok::identifier) &&
3044 Tok.getIdentifierInfo()->getName() ==
"omp_fill") {
3046 FillIdx = ValExprs.size();
3048 FillLoc = Tok.getLocation();
3050 ValExprs.push_back(
nullptr);
3057 ValExprs.push_back(Val.
get());
3061 if (
T.consumeClose())
3063 OpenLoc =
T.getOpenLocation();
3064 CloseLoc =
T.getCloseLocation();
3066 return Actions.OpenMP().ActOnOpenMPCountsClause(
3067 ValExprs, ClauseNameLoc, OpenLoc, CloseLoc, FillIdx, FillLoc, FillCount);
3070OMPClause *Parser::ParseOpenMPLoopRangeClause() {
3072 SourceLocation FirstLoc, CountLoc;
3075 if (
T.consumeOpen()) {
3076 Diag(Tok, diag::err_expected) << tok::l_paren;
3080 FirstLoc = Tok.getLocation();
3087 ExpectAndConsume(tok::comma);
3089 CountLoc = Tok.getLocation();
3098 return Actions.OpenMP().ActOnOpenMPLoopRangeClause(
3099 FirstVal.
get(), CountVal.
get(), ClauseNameLoc,
T.getOpenLocation(),
3100 FirstLoc, CountLoc,
T.getCloseLocation());
3103OMPClause *Parser::ParseOpenMPPermutationClause() {
3104 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3105 SmallVector<Expr *> ArgExprs;
3106 if (ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,
3111 return Actions.OpenMP().ActOnOpenMPPermutationClause(ArgExprs, ClauseNameLoc,
3116 SourceLocation Loc = Tok.getLocation();
3121 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3123 SmallVector<SemaOpenMP::UsesAllocatorsData, 4>
Data;
3126 if (
getLangOpts().OpenMP >= 52 && Tok.is(tok::identifier) &&
3127 Tok.getIdentifierInfo()->getName() ==
"traits") {
3129 SemaOpenMP::UsesAllocatorsData &D =
Data.emplace_back();
3135 tok::annot_pragma_openmp_end);
3136 TraitParens.consumeOpen();
3139 TraitParens.consumeClose();
3143 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3149 if (Tok.isNot(tok::colon)) {
3150 Diag(Tok, diag::err_expected) << tok::colon;
3152 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3161 ? ParseCXXIdExpression()
3162 : tryParseCXXIdExpression(SS,
false);
3166 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3173 D.
LParenLoc = TraitParens.getOpenLocation();
3174 D.
RParenLoc = TraitParens.getCloseLocation();
3177 if (Tok.is(tok::comma)) {
3179 Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3182 }
else if (Tok.is(tok::semi)) {
3192 getLangOpts().CPlusPlus
3193 ? ParseCXXIdExpression()
3194 : tryParseCXXIdExpression(SS,
false);
3196 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3203 BalancedDelimiterTracker T(*this, tok::l_paren,
3204 tok::annot_pragma_openmp_end);
3206 ExprResult AllocatorTraits =
3207 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3209 if (AllocatorTraits.isInvalid()) {
3210 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3219 if (getLangOpts().OpenMP >= 52) {
3220 Diag(Loc, diag::err_omp_deprecate_old_syntax)
3221 <<
"allocator(expr)"
3222 <<
"uses_allocators"
3223 <<
"traits(expr): alloc";
3227 Diag(
Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3229 if (
Tok.
is(tok::comma))
3231 }
while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end));
3234 Loc,
T.getOpenLocation(),
T.getCloseLocation(),
Data);
3239 OMPClauseKind = CKind;
3240 OMPClause *Clause =
nullptr;
3241 bool ErrorFound =
false;
3242 bool WrongDirective =
false;
3243 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
3246 if (!isAllowedClauseForDirective(D,
C, OMPVersion)) {
3247 Diag(Tok, diag::err_omp_unexpected_clause)
3248 << getOpenMPClauseName(
C) << getOpenMPDirectiveName(D, OMPVersion);
3250 WrongDirective =
true;
3254 if (CKind != OMPC_unknown) {
3256 assert(DKind != OMPD_ordered_blockassoc &&
3257 "Wrong kind for ordered directive");
3258 if (DKind == OMPD_ordered_standalone) {
3261 if (!isAllowedClauseForDirective(DKind, CKind, OMPVersion))
3262 CheckClauseValid(OMPD_ordered_blockassoc, CKind);
3264 CheckClauseValid(DKind, CKind);
3275 case OMPC_grainsize:
3276 case OMPC_num_tasks:
3278 case OMPC_allocator:
3281 case OMPC_novariants:
3282 case OMPC_nocontext:
3288 case OMPC_ompx_dyn_cgroup_mem:
3289 case OMPC_dyn_groupprivate:
3290 case OMPC_transparent:
3319 Diag(Tok, diag::err_omp_more_one_clause)
3320 << getOpenMPDirectiveName(DKind, OMPVersion)
3321 << getOpenMPClauseName(CKind) << 0;
3325 if (CKind == OMPC_transparent && PP.LookAhead(0).isNot(tok::l_paren)) {
3327 SourceLocation LLoc = Tok.getLocation();
3328 if (!WrongDirective)
3329 Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(
nullptr, LLoc,
3333 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3334 PP.LookAhead(0).isNot(tok::l_paren))
3335 Clause = ParseOpenMPClause(CKind, WrongDirective);
3336 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3337 CKind == OMPC_dyn_groupprivate)
3338 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3340 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3342 case OMPC_threadset:
3344 case OMPC_proc_bind:
3345 case OMPC_atomic_default_mem_order:
3363 Diag(Tok, diag::err_omp_more_one_clause)
3364 << getOpenMPDirectiveName(DKind, OMPVersion)
3365 << getOpenMPClauseName(CKind) << 0;
3369 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3373 case OMPC_dist_schedule:
3374 case OMPC_defaultmap:
3385 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3386 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3387 Diag(Tok, diag::err_omp_more_one_clause)
3388 << getOpenMPDirectiveName(DKind, OMPVersion)
3389 << getOpenMPClauseName(CKind) << 0;
3394 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3397 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3401 case OMPC_mergeable:
3415 case OMPC_unified_address:
3416 case OMPC_unified_shared_memory:
3417 case OMPC_reverse_offload:
3418 case OMPC_dynamic_allocators:
3427 Diag(Tok, diag::err_omp_more_one_clause)
3428 << getOpenMPDirectiveName(DKind, OMPVersion)
3429 << getOpenMPClauseName(CKind) << 0;
3433 if (CKind == OMPC_nowait && PP.LookAhead(0).is(tok::l_paren) &&
3435 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3437 Clause = ParseOpenMPClause(CKind, WrongDirective);
3439 case OMPC_self_maps:
3442 Diag(Tok, diag::err_omp_expected_clause)
3443 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3447 Diag(Tok, diag::err_omp_more_one_clause)
3448 << getOpenMPDirectiveName(DKind, OMPVersion)
3449 << getOpenMPClauseName(CKind) << 0;
3452 Clause = ParseOpenMPClause(CKind, WrongDirective);
3456 Diag(Tok, diag::err_omp_more_one_clause)
3457 << getOpenMPDirectiveName(DKind, OMPVersion)
3458 << getOpenMPClauseName(CKind) << 0;
3461 Clause = ParseOpenMPClause(CKind, WrongDirective);
3463 case OMPC_update_depend_objects:
3465 Diag(Tok, diag::err_omp_more_one_clause)
3466 << getOpenMPDirectiveName(DKind, OMPVersion)
3467 << getOpenMPClauseName(CKind) << 0;
3471 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3473 case OMPC_num_teams:
3474 case OMPC_thread_limit:
3475 case OMPC_num_threads:
3477 Diag(Tok, diag::err_omp_more_one_clause)
3478 << getOpenMPDirectiveName(DKind, OMPVersion)
3479 << getOpenMPClauseName(CKind) << 0;
3484 case OMPC_firstprivate:
3485 case OMPC_lastprivate:
3487 case OMPC_reduction:
3488 case OMPC_task_reduction:
3489 case OMPC_in_reduction:
3493 case OMPC_copyprivate:
3499 case OMPC_use_device_ptr:
3500 case OMPC_use_device_addr:
3501 case OMPC_is_device_ptr:
3502 case OMPC_has_device_addr:
3504 case OMPC_nontemporal:
3505 case OMPC_inclusive:
3506 case OMPC_exclusive:
3510 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered_standalone &&
3511 CKind == OMPC_depend)
3512 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3513 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3517 Diag(Tok, diag::err_omp_more_one_clause)
3518 << getOpenMPDirectiveName(DKind, OMPVersion)
3519 << getOpenMPClauseName(CKind) << 0;
3523 Clause = ParseOpenMPSizesClause();
3525 case OMPC_permutation:
3527 Diag(Tok, diag::err_omp_more_one_clause)
3528 << getOpenMPDirectiveName(DKind, OMPVersion)
3529 << getOpenMPClauseName(CKind) << 0;
3532 Clause = ParseOpenMPPermutationClause();
3536 Diag(Tok, diag::err_omp_more_one_clause)
3537 << getOpenMPDirectiveName(DKind, OMPVersion)
3538 << getOpenMPClauseName(CKind) << 0;
3541 Clause = ParseOpenMPCountsClause();
3543 case OMPC_uses_allocators:
3544 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3547 if (DKind != OMPD_interop) {
3549 Diag(Tok, diag::err_omp_more_one_clause)
3550 << getOpenMPDirectiveName(DKind, OMPVersion)
3551 << getOpenMPClauseName(CKind) << 0;
3554 Clause = ParseOpenMPClause(CKind, WrongDirective);
3560 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3562 case OMPC_device_type:
3564 skipUntilPragmaOpenMPEnd(DKind);
3566 case OMPC_threadprivate:
3567 case OMPC_groupprivate:
3570 if (!WrongDirective)
3571 Diag(Tok, diag::err_omp_unexpected_clause)
3572 << getOpenMPClauseName(CKind)
3573 << getOpenMPDirectiveName(DKind, OMPVersion);
3577 case OMPC_contains: {
3579 SourceLocation LLoc = Tok.getLocation();
3580 SourceLocation RLoc;
3581 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3586 if (DK == OMPD_unknown) {
3587 skipUntilPragmaOpenMPEnd(OMPD_assume);
3588 Diag(Tok, diag::err_omp_unexpected_clause)
3589 << getOpenMPClauseName(CKind)
3590 << getOpenMPDirectiveName(DKind, OMPVersion);
3594 DKVec.push_back(DK);
3597 Diag(Tok, diag::err_omp_unexpected_clause)
3598 << getOpenMPClauseName(CKind)
3599 << getOpenMPDirectiveName(DKind, OMPVersion);
3602 RLoc = Tok.getLocation();
3604 if (!WrongDirective)
3605 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3606 CKind, DKVec, Loc, LLoc, RLoc);
3609 case OMPC_no_openmp:
3610 case OMPC_no_openmp_routines:
3611 case OMPC_no_openmp_constructs:
3612 case OMPC_no_parallelism: {
3614 Diag(Tok, diag::err_omp_more_one_clause)
3615 << getOpenMPDirectiveName(DKind, OMPVersion)
3616 << getOpenMPClauseName(CKind) << 0;
3620 if (!WrongDirective)
3621 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3622 CKind, Loc, Tok.getLocation());
3625 case OMPC_ompx_attribute:
3626 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3628 case OMPC_ompx_bare:
3629 if (DKind == llvm::omp::Directive::OMPD_target) {
3634 Diag(Tok, diag::err_omp_unexpected_clause)
3635 << getOpenMPClauseName(CKind)
3636 << getOpenMPDirectiveName(DKind, OMPVersion);
3638 WrongDirective =
true;
3641 Diag(Tok, diag::note_ompx_bare_clause)
3642 << getOpenMPClauseName(CKind) <<
"target teams";
3643 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3644 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3645 << getOpenMPClauseName(CKind)
3646 << getOpenMPDirectiveName(DKind, OMPVersion);
3649 Clause = ParseOpenMPClause(CKind, WrongDirective);
3651 case OMPC_looprange:
3652 Clause = ParseOpenMPLoopRangeClause();
3657 return ErrorFound ?
nullptr : Clause;
3665 bool IsAddressOfOperand) {
3667 if (
T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3675 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3678 RLoc = Tok.getLocation();
3679 if (!
T.consumeClose())
3680 RLoc =
T.getCloseLocation();
3702bool Parser::ParseOpenMPIndirectClause(
3707 if (
Tok.isNot(tok::l_paren)) {
3726 if (
Ret.isInvalid())
3729 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3731 if (
Ret.isInvalid())
3739ExprResult Parser::ParseOMPInteropFrSelector() {
3742 tok::annot_pragma_openmp_end);
3743 if (FT.expectAndConsume(diag::err_expected_lparen_after,
"fr")) {
3745 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3749 SourceLocation Loc = Tok.getLocation();
3752 Arg = Actions.ActOnFinishFullExpr(Arg.
get(), Loc,
false);
3760 tok::annot_pragma_openmp_end);
3761 if (AT.expectAndConsume(diag::err_expected_lparen_after,
"attr")) {
3763 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3767 bool HasError =
false;
3770 if (Tok.is(tok::r_paren)) {
3771 Diag(Tok, diag::err_omp_interop_attr_not_string);
3774 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::r_brace) &&
3775 Tok.isNot(tok::annot_pragma_openmp_end)) {
3776 if (Tok.is(tok::string_literal)) {
3779 Attrs.push_back(S.
get());
3784 Diag(Tok, diag::err_omp_interop_attr_not_string);
3787 if (Tok.is(tok::comma))
3797 bool HasError =
false;
3798 bool IsTarget =
false;
3799 bool IsTargetSync =
false;
3801 while (Tok.is(tok::identifier)) {
3803 bool PreferTypeAllowed = (
Kind == OMPC_init ||
Kind == OMPC_append_args) &&
3804 InteropInfo.
Prefs.empty() && !IsTarget &&
3806 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3811 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3814 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3816 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3817 IsTargetSync =
true;
3819 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3820 PreferTypeAllowed) {
3821 if (Kind == OMPC_append_args &&
getLangOpts().OpenMP < 60) {
3822 Diag(Tok, diag::err_omp_append_args_prefer_type_60);
3827 tok::annot_pragma_openmp_end);
3828 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3832 if (Tok.is(tok::r_paren)) {
3833 Diag(Tok, diag::err_omp_expected_pref_spec);
3837 while (Tok.isNot(tok::r_paren) &&
3838 Tok.isNot(tok::annot_pragma_openmp_end)) {
3840 if (Tok.is(tok::l_brace)) {
3844 Diag(Tok, diag::err_omp_prefer_type_brace_60);
3848 tok::annot_pragma_openmp_end);
3850 Expr *FrExpr =
nullptr;
3851 SmallVector<Expr *, 2> AttrExprs;
3852 bool SeenFr =
false;
3856 if (Tok.is(tok::r_brace)) {
3857 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3861 while (Tok.isNot(tok::r_brace) &&
3862 Tok.isNot(tok::annot_pragma_openmp_end)) {
3863 if (Tok.is(tok::identifier) &&
3864 Tok.getIdentifierInfo()->isStr(
"fr")) {
3866 Diag(Tok, diag::err_omp_interop_multiple_fr);
3870 {tok::comma, tok::r_brace, tok::annot_pragma_openmp_end},
3880 }
else if (Tok.is(tok::identifier) &&
3881 Tok.getIdentifierInfo()->isStr(
"attr")) {
3882 if (ParseOMPInteropAttrSelector(AttrExprs))
3887 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3890 if (Tok.is(tok::comma))
3893 if (BT.consumeClose())
3896 if (FrExpr || !AttrExprs.empty())
3897 InteropInfo.
Prefs.emplace_back(FrExpr, AttrExprs);
3902 SourceLocation Loc = Tok.getLocation();
3906 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
3909 InteropInfo.
Prefs.emplace_back(PTExpr.
get(),
3910 llvm::SmallVector<Expr *, 2>{});
3913 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3918 if (Tok.is(tok::comma))
3924 Diag(Tok, diag::err_omp_expected_interop_type);
3927 if (!Tok.is(tok::comma))
3932 if (!HasError && !IsTarget && !IsTargetSync) {
3933 Diag(Tok, diag::err_omp_expected_interop_type);
3937 if (Kind == OMPC_init) {
3938 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
3939 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3940 if (Tok.is(tok::colon))
3957 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3958 getOpenMPClauseName(Kind).data()))
3961 bool InteropError =
false;
3962 OMPInteropInfo InteropInfo;
3963 if (Kind == OMPC_init)
3964 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3967 SourceLocation VarLoc = Tok.getLocation();
3970 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3975 SourceLocation RLoc = Tok.getLocation();
3976 if (!
T.consumeClose())
3977 RLoc =
T.getCloseLocation();
3979 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3982 if (Kind == OMPC_init)
3983 return Actions.OpenMP().ActOnOpenMPInitClause(
3984 InteropVarExpr.
get(), InteropInfo, Loc,
T.getOpenLocation(), VarLoc,
3986 if (Kind == OMPC_use)
3987 return Actions.OpenMP().ActOnOpenMPUseClause(
3988 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
3990 if (Kind == OMPC_destroy)
3991 return Actions.OpenMP().ActOnOpenMPDestroyClause(
3992 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
3994 llvm_unreachable(
"Unexpected interop variable clause.");
3997OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
4001 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4002 getOpenMPClauseName(OMPC_ompx_attribute).data()))
4005 ParsedAttributes ParsedAttrs(AttrFactory);
4006 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
4009 if (
T.consumeClose())
4015 SmallVector<Attr *> Attrs;
4016 for (
const ParsedAttr &PA : ParsedAttrs) {
4017 switch (PA.getKind()) {
4018 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
4019 if (!PA.checkExactlyNumArgs(Actions, 2))
4021 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
4022 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
4025 case ParsedAttr::AT_AMDGPUWavesPerEU:
4026 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
4027 !PA.checkAtMostNumArgs(Actions, 2))
4029 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
4030 PA, PA.getArgAsExpr(0),
4031 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
4034 case ParsedAttr::AT_CUDALaunchBounds:
4035 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
4036 !PA.checkAtMostNumArgs(Actions, 3))
4038 if (
auto *A = Actions.CreateLaunchBoundsAttr(
4039 PA, PA.getArgAsExpr(0),
4040 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
4041 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr,
4046 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
4051 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
4052 Attrs, Loc,
T.getOpenLocation(),
T.getCloseLocation());
4058 if (!Val || ParseOnly)
4060 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
4061 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
4062 static_cast<DefaultKind
>(Val->Type) ==
4063 OMP_DEFAULT_firstprivate)) {
4064 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
4065 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
4068 : OMPC_firstprivate)
4069 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4072 return Actions.OpenMP().ActOnOpenMPSimpleClause(
4073 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
4077 SourceLocation Loc = Tok.getLocation();
4082 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
4089 SourceLocation DelimLoc;
4092 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4093 getOpenMPClauseName(Kind).data()))
4097 SmallVector<unsigned, 4> Arg;
4098 SmallVector<SourceLocation, 4> KLoc;
4099 if (Kind == OMPC_schedule) {
4100 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
4101 Arg.resize(NumberOfElements);
4102 KLoc.resize(NumberOfElements);
4107 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4110 Arg[Modifier1] = KindModifier;
4111 KLoc[Modifier1] = Tok.getLocation();
4112 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4113 Tok.isNot(tok::annot_pragma_openmp_end))
4115 if (Tok.is(tok::comma)) {
4119 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4123 KLoc[Modifier2] = Tok.getLocation();
4124 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4125 Tok.isNot(tok::annot_pragma_openmp_end))
4129 if (Tok.is(tok::colon))
4132 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
4134 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4136 Arg[ScheduleKind] = KindModifier;
4137 KLoc[ScheduleKind] = Tok.getLocation();
4138 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4139 Tok.isNot(tok::annot_pragma_openmp_end))
4141 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
4142 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
4143 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
4146 }
else if (Kind == OMPC_dist_schedule) {
4148 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4149 KLoc.push_back(Tok.getLocation());
4150 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4151 Tok.isNot(tok::annot_pragma_openmp_end))
4153 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
4155 }
else if (Kind == OMPC_default) {
4158 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4160 Arg.push_back(Modifier);
4161 KLoc.push_back(Tok.getLocation());
4162 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4163 Tok.isNot(tok::annot_pragma_openmp_end))
4166 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
4171 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4172 Arg.push_back(VariableCategory);
4173 KLoc.push_back(Tok.getLocation());
4174 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4175 Tok.isNot(tok::annot_pragma_openmp_end))
4178 Arg.push_back(OMPC_DEFAULT_VC_all);
4179 KLoc.push_back(SourceLocation());
4181 }
else if (Kind == OMPC_defaultmap) {
4184 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4190 Arg.push_back(Modifier);
4191 KLoc.push_back(Tok.getLocation());
4192 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4193 Tok.isNot(tok::annot_pragma_openmp_end))
4196 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
4197 if (Tok.is(tok::colon))
4200 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
4203 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4204 KLoc.push_back(Tok.getLocation());
4205 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4206 Tok.isNot(tok::annot_pragma_openmp_end))
4210 KLoc.push_back(SourceLocation());
4212 }
else if (Kind == OMPC_order) {
4213 enum { Modifier, OrderKind, NumberOfElements };
4214 Arg.resize(NumberOfElements);
4215 KLoc.resize(NumberOfElements);
4219 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4222 Arg[Modifier] = KindModifier;
4223 KLoc[Modifier] = Tok.getLocation();
4224 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4225 Tok.isNot(tok::annot_pragma_openmp_end))
4228 if (Tok.is(tok::colon))
4231 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
4233 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4235 Arg[OrderKind] = KindModifier;
4236 KLoc[OrderKind] = Tok.getLocation();
4237 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4238 Tok.isNot(tok::annot_pragma_openmp_end))
4240 }
else if (Kind == OMPC_device) {
4246 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4247 KLoc.push_back(Tok.getLocation());
4253 KLoc.emplace_back();
4255 }
else if (Kind == OMPC_grainsize) {
4259 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4263 Arg.push_back(Modifier);
4264 KLoc.push_back(Tok.getLocation());
4270 if (Modifier == OMPC_GRAINSIZE_strict) {
4271 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4276 KLoc.emplace_back();
4280 KLoc.emplace_back();
4282 }
else if (Kind == OMPC_dyn_groupprivate) {
4283 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4284 Arg.resize(NumberOfModifiers);
4285 KLoc.resize(NumberOfModifiers);
4289 auto ConsumeModifier = [&]() {
4290 unsigned Type = NumberOfModifiers;
4293 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4297 ParenT.consumeOpen();
4300 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4303 Diag(Tok.getLocation(), diag::err_expected)
4304 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4306 return std::make_tuple(
Type, Modifier, Loc);
4308 Type = ComplexModifier;
4309 Loc = Tok.getLocation();
4310 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4311 Tok.isNot(tok::annot_pragma_openmp_end))
4313 ParenT.consumeClose();
4316 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4318 Type = SimpleModifier;
4319 Loc = Tok.getLocation();
4320 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4321 Tok.isNot(tok::annot_pragma_openmp_end))
4325 return std::make_tuple(
Type, Modifier, Loc);
4328 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4329 SourceLocation Loc) {
4330 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4331 if (!KLoc[
Type].isValid()) {
4332 Arg[
Type] = Modifier;
4335 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4342 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4343 if (Type1 < NumberOfModifiers) {
4344 SaveModifier(Type1, Mod1, Loc1);
4345 if (Tok.is(tok::comma)) {
4348 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4349 if (Type2 < NumberOfModifiers)
4350 SaveModifier(Type2, Mod2, Loc2);
4353 if (Tok.is(tok::colon))
4356 Diag(Tok, diag::warn_pragma_expected_colon)
4357 <<
"dyn_groupprivate modifier";
4359 }
else if (Kind == OMPC_num_tasks) {
4363 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4367 Arg.push_back(Modifier);
4368 KLoc.push_back(Tok.getLocation());
4374 if (Modifier == OMPC_NUMTASKS_strict) {
4375 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4380 KLoc.emplace_back();
4384 KLoc.emplace_back();
4387 assert(Kind == OMPC_if);
4388 KLoc.push_back(Tok.getLocation());
4389 TentativeParsingAction TPA(*
this);
4391 Arg.push_back(
static_cast<unsigned>(DK));
4392 if (DK != OMPD_unknown) {
4394 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4399 Arg.back() = unsigned(OMPD_unknown);
4406 bool NeedAnExpression = (
Kind == OMPC_schedule && DelimLoc.
isValid()) ||
4407 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
4408 Kind == OMPC_if ||
Kind == OMPC_device ||
4409 Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4410 Kind == OMPC_dyn_groupprivate;
4411 if (NeedAnExpression) {
4412 SourceLocation ELoc = Tok.getLocation();
4418 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4422 SourceLocation RLoc = Tok.getLocation();
4423 if (!
T.consumeClose())
4424 RLoc =
T.getCloseLocation();
4426 if (NeedAnExpression && Val.
isInvalid())
4429 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4430 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4431 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4432 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4433 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4436 : OMPC_firstprivate)
4437 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4443 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4444 Kind, Arg, Val.
get(), Loc,
T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4449 if (ReductionIdScopeSpec.
isEmpty()) {
4487 ReductionIdScopeSpec,
nullptr,
4491 false,
nullptr, ReductionId);
4498 if (!
Tok.is(tok::identifier))
4505 return TypeModifier;
4511 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4512 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4518 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4522 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4523 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4524 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4528 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4530 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4533 return T.consumeClose();
4539 bool HasMapType =
false;
4541 StringRef PreMapName =
"";
4545 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4546 TypeModifier == OMPC_MAP_MODIFIER_close ||
4547 TypeModifier == OMPC_MAP_MODIFIER_present ||
4548 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4549 Data.MapTypeModifiers.push_back(TypeModifier);
4550 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4551 if (PP.LookAhead(0).isNot(tok::comma) &&
4552 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4553 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4554 <<
"map type modifier";
4556 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4557 Data.MapTypeModifiers.push_back(TypeModifier);
4558 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4562 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4564 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4565 <<
"map type modifier";
4570 Data.ExtraModifier = MapKind;
4572 PreMapLoc = Tok.getLocation();
4573 PreMapName = Tok.getIdentifierInfo()->getName();
4575 Diag(Tok, diag::err_omp_more_one_map_type);
4576 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4580 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4581 Data.MapTypeModifiers.push_back(TypeModifier);
4582 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4583 if (PP.LookAhead(0).isNot(tok::comma) &&
4584 PP.LookAhead(0).isNot(tok::colon))
4585 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4586 <<
"map type modifier";
4588 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4598 if (Tok.is(tok::comma)) {
4599 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4604 if (PP.LookAhead(0).is(tok::colon)) {
4612 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4623 if (!Tok.is(tok::colon)) {
4624 Diag(Tok, diag::err_omp_unknown_map_type);
4638 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4643 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4644 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4645 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4655 if (
Tok.is(tok::colon)) {
4656 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4661 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4665ExprResult Parser::ParseOpenMPIteratorsExpr() {
4666 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4667 "Expected 'iterator' token.");
4671 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4674 SourceLocation LLoc =
T.getOpenLocation();
4675 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4676 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4679 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4686 IteratorType = TR.
get();
4690 IdentifierInfo *II =
nullptr;
4691 SourceLocation IdLoc;
4692 if (Tok.is(tok::identifier)) {
4693 II = Tok.getIdentifierInfo();
4696 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4700 SourceLocation AssignLoc;
4701 if (Tok.is(tok::equal))
4704 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4709 SourceLocation Loc = Tok.getLocation();
4712 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4715 SourceLocation ColonLoc;
4716 if (Tok.is(tok::colon))
4720 Loc = Tok.getLocation();
4723 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4726 SourceLocation SecColonLoc;
4729 if (Tok.is(tok::colon)) {
4733 Loc = Tok.getLocation();
4736 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4741 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4742 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4743 if (Tok.is(tok::comma))
4746 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4749 D.
Type = IteratorType;
4759 SourceLocation RLoc = Tok.getLocation();
4760 if (!
T.consumeClose())
4761 RLoc =
T.getCloseLocation();
4763 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4772 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4775 if (Tok.is(tok::identifier) &&
4776 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4778 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4779 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4780 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4781 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4782 Data.ExtraModifier != OMPC_DEPEND_inout)
4783 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4785 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4786 ? OMPC_DEPEND_outallmemory
4787 : OMPC_DEPEND_inoutallmemory;
4803 Data.DepModOrTailExpr = Tail.
get();
4805 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4806 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4824 bool AllocatorSeen =
false;
4825 bool AlignSeen =
false;
4844 if (
Tok.is(tok::l_paren)) {
4845 switch (CurrentModifier) {
4846 case OMPC_ALLOCATE_allocator: {
4847 if (AllocatorSeen) {
4848 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4850 << getOpenMPClauseName(Kind);
4852 Data.AllocClauseModifiers.push_back(CurrentModifier);
4853 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4856 tok::annot_pragma_openmp_end);
4860 AllocatorSeen =
true;
4863 case OMPC_ALLOCATE_align: {
4865 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4867 << getOpenMPClauseName(Kind);
4869 Data.AllocClauseModifiers.push_back(CurrentModifier);
4870 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4874 Data.AllocateAlignment = Val.
get();
4879 llvm_unreachable(
"Unexpected allocate modifier");
4882 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4884 if (
Tok.isNot(tok::comma))
4887 CurrentModifierLoc =
Tok.getLocation();
4892 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4895 }
while (!AllocatorSeen || !AlignSeen);
4904 bool InvalidReductionId =
false;
4905 bool IsInvalidMapperModifier =
false;
4909 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4910 getOpenMPClauseName(Kind).data()))
4913 bool HasIterator =
false;
4914 bool InvalidIterator =
false;
4915 bool NeedRParenForLinear =
false;
4917 tok::annot_pragma_openmp_end);
4919 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4920 Kind == OMPC_in_reduction) {
4922 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4923 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4926 Data.ExtraModifier =
4928 Data.ExtraModifierLoc = Tok.getLocation();
4930 assert(Tok.is(tok::comma) &&
"Expected comma.");
4934 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4935 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4941 if (Tok.is(tok::kw_private)) {
4942 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4943 Data.OriginalSharingModifierLoc = Tok.getLocation();
4945 }
else if (Tok.is(tok::identifier) &&
4946 (PP.getSpelling(Tok) ==
"shared" ||
4947 PP.getSpelling(Tok) ==
"default")) {
4948 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4949 Data.OriginalSharingModifierLoc = Tok.getLocation();
4952 Diag(Tok.getLocation(), diag::err_expected)
4953 <<
"'private or shared or default'";
4958 if (!Tok.is(tok::comma)) {
4959 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4966 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4971 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4972 if (InvalidReductionId) {
4973 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4976 if (Tok.is(tok::colon))
4979 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4980 if (!InvalidReductionId)
4981 Data.ReductionOrMapperId =
4982 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4983 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4985 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4994 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4995 Data.DepModOrTailExpr = IteratorRes.
get();
4997 ExpectAndConsume(tok::comma);
5003 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5005 Data.ExtraModifierLoc = Tok.getLocation();
5007 (Kind == OMPC_doacross &&
5009 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5014 if (DKind == OMPD_ordered_standalone && Kind == OMPC_depend &&
5015 Data.ExtraModifier == OMPC_DEPEND_source) {
5021 if (Tok.is(tok::colon)) {
5023 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
5024 Diag(Tok, DKind == OMPD_ordered_standalone
5025 ? diag::warn_pragma_expected_colon_r_paren
5026 : diag::warn_pragma_expected_colon)
5027 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
5029 if (Kind == OMPC_doacross) {
5030 if (Tok.is(tok::identifier) &&
5031 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
5032 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
5033 ? OMPC_DOACROSS_source_omp_cur_iteration
5034 : OMPC_DOACROSS_sink_omp_cur_iteration;
5037 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
5038 if (Tok.isNot(tok::minus)) {
5039 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5040 << getOpenMPClauseName(Kind) << 0 << 0;
5047 if (Tok.isNot(tok::numeric_constant) ||
5048 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
5049 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
5050 << getOpenMPClauseName(Kind) << 0 << 0;
5056 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
5057 if (Tok.isNot(tok::r_paren)) {
5058 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5059 << getOpenMPClauseName(Kind) << 1 << 1;
5065 if (Kind == OMPC_doacross &&
5066 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
5067 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
5068 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
5074 }
else if (Kind == OMPC_linear) {
5076 Data.ExtraModifier = OMPC_LINEAR_val;
5077 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
5078 Data.ExtraModifier =
5082 NeedRParenForLinear =
true;
5084 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
5085 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
5086 <<
"linear(list: [linear-modifier,] step(step-size))";
5088 }
else if (Kind == OMPC_lastprivate) {
5095 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
5096 Data.ExtraModifier =
5098 Data.ExtraModifierLoc = Tok.getLocation();
5100 assert(Tok.is(tok::colon) &&
"Expected colon.");
5103 }
else if (Kind == OMPC_map) {
5105 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
5108 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
5109 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
5110 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
5111 Data.IteratorExpr = IteratorRes.
get();
5113 ExpectAndConsume(tok::comma);
5115 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
5118 InvalidIterator =
true;
5128 Data.ExtraModifierLoc = Tok.getLocation();
5131 TentativeParsingAction TPA(*
this);
5132 bool ColonPresent =
false;
5133 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5135 if (Tok.is(tok::colon))
5136 ColonPresent =
true;
5143 Diag(Tok, diag::err_omp_map_modifier_specification_list);
5145 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
5151 Data.ExtraModifier = OMPC_MAP_tofrom;
5153 if (DKind == OMPD_target_enter_data)
5154 Data.ExtraModifier = OMPC_MAP_to;
5155 else if (DKind == OMPD_target_exit_data)
5156 Data.ExtraModifier = OMPC_MAP_from;
5158 Data.IsMapTypeImplicit =
true;
5161 if (Tok.is(tok::colon))
5163 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
5164 while (Tok.is(tok::identifier)) {
5169 Data.MotionModifiers.push_back(Modifier);
5170 Data.MotionModifiersLoc.push_back(Tok.getLocation());
5171 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
5173 Tail = ParseOpenMPIteratorsExpr();
5174 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
5177 Data.IteratorExpr = Tail.
get();
5180 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
5182 if (IsInvalidMapperModifier)
5190 if (Tok.is(tok::comma))
5194 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
5195 if (!IsInvalidMapperModifier) {
5197 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
5199 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
5201 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5209 }
else if (Kind == OMPC_allocate ||
5210 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
5211 PP.getSpelling(Tok) ==
"iterator")) {
5215 TentativeParsingAction TPA(*
this);
5220 if (Kind == OMPC_allocate) {
5225 Tail = ParseOpenMPIteratorsExpr();
5227 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
5230 if (Tok.is(tok::colon)) {
5237 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5238 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5240 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5247 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5250 }
else if (Kind == OMPC_adjust_args) {
5254 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5256 Data.ExtraModifierLoc = Tok.getLocation();
5258 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5263 if (Tok.is(tok::colon))
5264 Data.ColonLoc = Tok.getLocation();
5268 if (Tok.is(tok::l_paren)) {
5271 if (Tok.is(tok::identifier)) {
5272 std::string Modifier = PP.getSpelling(Tok);
5273 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5274 Data.NeedDevicePtrModifier =
5275 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5276 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5278 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5279 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5284 if (Tok.is(tok::r_paren)) {
5285 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5288 Diag(Tok, diag::err_expected) << tok::r_paren;
5289 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5298 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5301 }
else if (Kind == OMPC_use_device_ptr) {
5305 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5309 Data.ExtraModifier = FallbackModifier;
5310 Data.ExtraModifierLoc = Tok.getLocation();
5312 if (Tok.is(tok::colon))
5315 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5318 }
else if (Kind == OMPC_num_teams || Kind == OMPC_thread_limit) {
5322 Data.ExtraModifierArray[0] =
Data.ExtraModifierArray[1] =
5327 bool CanParseLowerBoundModifier = (Kind == OMPC_num_teams);
5328 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"dims") &&
5335 Data.ExtraModifierArray[Mod] =
5336 Kind == OMPC_num_teams ?
static_cast<int>(OMPC_NUMTEAMS_dims)
5337 :
static_cast<int>(OMPC_THREADLIMIT_dims);
5338 Data.ExtraModifierExprArray[Mod] = ExprR.
get();
5339 Data.ExtraModifierLocArray[Mod] = TLoc;
5343 if (Tok.is(tok::colon)) {
5346 CanParseLowerBoundModifier =
false;
5347 }
else if (CanParseLowerBoundModifier && Tok.is(tok::comma)) {
5352 Diag(Tok, diag::err_modifier_expected_colon)
5353 << getOpenMPClauseName(Kind);
5355 Data.RLoc = Tok.getLocation();
5356 if (!
T.consumeClose())
5357 Data.RLoc =
T.getCloseLocation();
5363 if (CanParseLowerBoundModifier) {
5364 TentativeParsingAction TPA(*
this);
5369 Data.RLoc = Tok.getLocation();
5370 if (!
T.consumeClose())
5371 Data.RLoc =
T.getCloseLocation();
5376 if (Tok.is(tok::colon)) {
5379 Data.ExtraModifierArray[Mod] = OMPC_NUMTEAMS_lower_bound;
5380 Data.ExtraModifierExprArray[Mod] = FirstExpr.
get();
5381 Data.ExtraModifierLocArray[Mod] = TLoc;
5389 }
else if (Kind == OMPC_num_threads) {
5393 bool HasModifier =
false;
5395 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"dims") &&
5406 Diag(TLoc, diag::err_omp_incompatible_modifiers)
5409 << getOpenMPClauseName(Kind);
5411 Data.ExtraModifierArray[1] =
static_cast<int>(OMPC_NUMTHREADS_dims);
5412 Data.ExtraModifierExprArray[1] =
5414 Data.ExtraModifierLocArray[1] = TLoc;
5421 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5426 Diag(Tok, diag::err_omp_incompatible_modifiers)
5429 Data.ExtraModifierArray[0])
5430 << getOpenMPClauseName(Kind);
5431 Data.ExtraModifierArray[0] = Modifier;
5432 Data.ExtraModifierLocArray[0] = Tok.getLocation();
5442 if (Tok.is(tok::comma))
5450 if (!Tok.is(tok::colon)) {
5451 Diag(Tok, diag::err_modifier_expected_colon)
5452 << getOpenMPClauseName(Kind);
5454 Data.RLoc = Tok.getLocation();
5455 if (!
T.consumeClose())
5456 Data.RLoc =
T.getCloseLocation();
5464 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5465 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5466 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5467 (Kind == OMPC_reduction && !InvalidReductionId) ||
5471 (Kind == OMPC_adjust_args &&
5473 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5474 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5475 Tok.isNot(tok::annot_pragma_openmp_end))) {
5482 Vars.push_back(VarExpr.
get());
5484 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5489 IsComma = Tok.is(tok::comma);
5492 else if (Tok.isNot(tok::r_paren) &&
5493 Tok.isNot(tok::annot_pragma_openmp_end) &&
5494 (!MayHaveTail || Tok.isNot(tok::colon))) {
5495 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
5496 Diag(Tok, diag::err_omp_expected_punc)
5497 << ((Kind == OMPC_flush)
5498 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5499 : getOpenMPClauseName(Kind))
5500 << (Kind == OMPC_flush);
5505 if (NeedRParenForLinear)
5509 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5510 bool StepFound =
false;
5511 bool ModifierFound =
false;
5513 Data.ColonLoc = Tok.getLocation();
5516 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5517 bool Malformed =
false;
5518 while (Tok.isNot(tok::r_paren)) {
5519 if (Tok.is(tok::identifier)) {
5524 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5527 if (LinKind == OMPC_LINEAR_step) {
5529 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5532 tok::annot_pragma_openmp_end);
5536 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5541 Data.StepModifierLoc = StepModifierLoc;
5545 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5547 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5549 Data.ExtraModifier = LinKind;
5551 ModifierFound =
true;
5556 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5565 if (Tok.is(tok::comma))
5567 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5570 if (!Malformed && !StepFound && !ModifierFound)
5571 Diag(ELoc, diag::err_expected_expression);
5575 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5578 Data.DepModOrTailExpr = Tail.
get();
5580 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5586 Data.RLoc = Tok.getLocation();
5587 if (!
T.consumeClose())
5588 Data.RLoc =
T.getCloseLocation();
5592 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5594 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5595 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5622 "Expected parsing to start at clause name");
5627 if (
T.consumeOpen()) {
5628 Diag(
Tok, diag::err_expected) << tok::l_paren;
5641 Exprs.push_back(Val.
get());
5644 bool Result =
T.consumeClose();
5645 OpenLoc =
T.getOpenLocation();
5646 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...
llvm::omp::Version getOpenMPVersion() const
Return the OpenMP version.
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
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.