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:
3287 case OMPC_ompx_dyn_cgroup_mem:
3288 case OMPC_dyn_groupprivate:
3289 case OMPC_transparent:
3318 Diag(Tok, diag::err_omp_more_one_clause)
3319 << getOpenMPDirectiveName(DKind, OMPVersion)
3320 << getOpenMPClauseName(CKind) << 0;
3324 if (CKind == OMPC_transparent && PP.LookAhead(0).isNot(tok::l_paren)) {
3326 SourceLocation LLoc = Tok.getLocation();
3327 if (!WrongDirective)
3328 Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(
nullptr, LLoc,
3332 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3333 PP.LookAhead(0).isNot(tok::l_paren))
3334 Clause = ParseOpenMPClause(CKind, WrongDirective);
3335 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3336 CKind == OMPC_dyn_groupprivate)
3337 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3339 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3341 case OMPC_threadset:
3343 case OMPC_proc_bind:
3344 case OMPC_atomic_default_mem_order:
3362 Diag(Tok, diag::err_omp_more_one_clause)
3363 << getOpenMPDirectiveName(DKind, OMPVersion)
3364 << getOpenMPClauseName(CKind) << 0;
3368 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3372 case OMPC_dist_schedule:
3373 case OMPC_defaultmap:
3384 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3385 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3386 Diag(Tok, diag::err_omp_more_one_clause)
3387 << getOpenMPDirectiveName(DKind, OMPVersion)
3388 << getOpenMPClauseName(CKind) << 0;
3393 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3396 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3400 case OMPC_mergeable:
3414 case OMPC_unified_address:
3415 case OMPC_unified_shared_memory:
3416 case OMPC_reverse_offload:
3417 case OMPC_dynamic_allocators:
3426 Diag(Tok, diag::err_omp_more_one_clause)
3427 << getOpenMPDirectiveName(DKind, OMPVersion)
3428 << getOpenMPClauseName(CKind) << 0;
3432 if (CKind == OMPC_nowait && PP.LookAhead(0).is(tok::l_paren) &&
3434 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3436 Clause = ParseOpenMPClause(CKind, WrongDirective);
3438 case OMPC_self_maps:
3441 Diag(Tok, diag::err_omp_expected_clause)
3442 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3446 Diag(Tok, diag::err_omp_more_one_clause)
3447 << getOpenMPDirectiveName(DKind, OMPVersion)
3448 << getOpenMPClauseName(CKind) << 0;
3451 Clause = ParseOpenMPClause(CKind, WrongDirective);
3455 Diag(Tok, diag::err_omp_more_one_clause)
3456 << getOpenMPDirectiveName(DKind, OMPVersion)
3457 << getOpenMPClauseName(CKind) << 0;
3460 Clause = ParseOpenMPClause(CKind, WrongDirective);
3462 case OMPC_update_depend_objects:
3464 Diag(Tok, diag::err_omp_more_one_clause)
3465 << getOpenMPDirectiveName(DKind, OMPVersion)
3466 << getOpenMPClauseName(CKind) << 0;
3470 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3472 case OMPC_num_teams:
3473 case OMPC_thread_limit:
3474 case OMPC_num_threads:
3476 Diag(Tok, diag::err_omp_more_one_clause)
3477 << getOpenMPDirectiveName(DKind, OMPVersion)
3478 << getOpenMPClauseName(CKind) << 0;
3483 case OMPC_firstprivate:
3484 case OMPC_lastprivate:
3486 case OMPC_reduction:
3487 case OMPC_task_reduction:
3488 case OMPC_in_reduction:
3492 case OMPC_copyprivate:
3498 case OMPC_use_device_ptr:
3499 case OMPC_use_device_addr:
3500 case OMPC_is_device_ptr:
3501 case OMPC_has_device_addr:
3503 case OMPC_nontemporal:
3504 case OMPC_inclusive:
3505 case OMPC_exclusive:
3509 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered_standalone &&
3510 CKind == OMPC_depend)
3511 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3512 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3516 Diag(Tok, diag::err_omp_more_one_clause)
3517 << getOpenMPDirectiveName(DKind, OMPVersion)
3518 << getOpenMPClauseName(CKind) << 0;
3522 Clause = ParseOpenMPSizesClause();
3524 case OMPC_permutation:
3526 Diag(Tok, diag::err_omp_more_one_clause)
3527 << getOpenMPDirectiveName(DKind, OMPVersion)
3528 << getOpenMPClauseName(CKind) << 0;
3531 Clause = ParseOpenMPPermutationClause();
3535 Diag(Tok, diag::err_omp_more_one_clause)
3536 << getOpenMPDirectiveName(DKind, OMPVersion)
3537 << getOpenMPClauseName(CKind) << 0;
3540 Clause = ParseOpenMPCountsClause();
3542 case OMPC_uses_allocators:
3543 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3546 if (DKind != OMPD_interop) {
3548 Diag(Tok, diag::err_omp_more_one_clause)
3549 << getOpenMPDirectiveName(DKind, OMPVersion)
3550 << getOpenMPClauseName(CKind) << 0;
3553 Clause = ParseOpenMPClause(CKind, WrongDirective);
3559 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3561 case OMPC_device_type:
3563 skipUntilPragmaOpenMPEnd(DKind);
3565 case OMPC_threadprivate:
3566 case OMPC_groupprivate:
3569 if (!WrongDirective)
3570 Diag(Tok, diag::err_omp_unexpected_clause)
3571 << getOpenMPClauseName(CKind)
3572 << getOpenMPDirectiveName(DKind, OMPVersion);
3576 case OMPC_contains: {
3578 SourceLocation LLoc = Tok.getLocation();
3579 SourceLocation RLoc;
3580 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3585 if (DK == OMPD_unknown) {
3586 skipUntilPragmaOpenMPEnd(OMPD_assume);
3587 Diag(Tok, diag::err_omp_unexpected_clause)
3588 << getOpenMPClauseName(CKind)
3589 << getOpenMPDirectiveName(DKind, OMPVersion);
3593 DKVec.push_back(DK);
3596 Diag(Tok, diag::err_omp_unexpected_clause)
3597 << getOpenMPClauseName(CKind)
3598 << getOpenMPDirectiveName(DKind, OMPVersion);
3601 RLoc = Tok.getLocation();
3603 if (!WrongDirective)
3604 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3605 CKind, DKVec, Loc, LLoc, RLoc);
3608 case OMPC_no_openmp:
3609 case OMPC_no_openmp_routines:
3610 case OMPC_no_openmp_constructs:
3611 case OMPC_no_parallelism: {
3613 Diag(Tok, diag::err_omp_more_one_clause)
3614 << getOpenMPDirectiveName(DKind, OMPVersion)
3615 << getOpenMPClauseName(CKind) << 0;
3619 if (!WrongDirective)
3620 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3621 CKind, Loc, Tok.getLocation());
3624 case OMPC_ompx_attribute:
3625 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3627 case OMPC_ompx_bare:
3628 if (DKind == llvm::omp::Directive::OMPD_target) {
3633 Diag(Tok, diag::err_omp_unexpected_clause)
3634 << getOpenMPClauseName(CKind)
3635 << getOpenMPDirectiveName(DKind, OMPVersion);
3637 WrongDirective =
true;
3640 Diag(Tok, diag::note_ompx_bare_clause)
3641 << getOpenMPClauseName(CKind) <<
"target teams";
3642 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3643 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3644 << getOpenMPClauseName(CKind)
3645 << getOpenMPDirectiveName(DKind, OMPVersion);
3648 Clause = ParseOpenMPClause(CKind, WrongDirective);
3650 case OMPC_looprange:
3651 Clause = ParseOpenMPLoopRangeClause();
3656 return ErrorFound ?
nullptr : Clause;
3664 bool IsAddressOfOperand) {
3666 if (
T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3674 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3677 RLoc = Tok.getLocation();
3678 if (!
T.consumeClose())
3679 RLoc =
T.getCloseLocation();
3701bool Parser::ParseOpenMPIndirectClause(
3706 if (
Tok.isNot(tok::l_paren)) {
3725 if (
Ret.isInvalid())
3728 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3730 if (
Ret.isInvalid())
3738ExprResult Parser::ParseOMPInteropFrSelector() {
3741 tok::annot_pragma_openmp_end);
3742 if (FT.expectAndConsume(diag::err_expected_lparen_after,
"fr")) {
3744 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3748 SourceLocation Loc = Tok.getLocation();
3751 Arg = Actions.ActOnFinishFullExpr(Arg.
get(), Loc,
false);
3759 tok::annot_pragma_openmp_end);
3760 if (AT.expectAndConsume(diag::err_expected_lparen_after,
"attr")) {
3762 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3766 bool HasError =
false;
3769 if (Tok.is(tok::r_paren)) {
3770 Diag(Tok, diag::err_omp_interop_attr_not_string);
3773 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::r_brace) &&
3774 Tok.isNot(tok::annot_pragma_openmp_end)) {
3775 if (Tok.is(tok::string_literal)) {
3778 Attrs.push_back(S.
get());
3783 Diag(Tok, diag::err_omp_interop_attr_not_string);
3786 if (Tok.is(tok::comma))
3796 bool HasError =
false;
3797 bool IsTarget =
false;
3798 bool IsTargetSync =
false;
3800 while (Tok.is(tok::identifier)) {
3802 bool PreferTypeAllowed = (
Kind == OMPC_init ||
Kind == OMPC_append_args) &&
3803 InteropInfo.
Prefs.empty() && !IsTarget &&
3805 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3810 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3813 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3815 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3816 IsTargetSync =
true;
3818 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3819 PreferTypeAllowed) {
3820 if (Kind == OMPC_append_args &&
getLangOpts().OpenMP < 60) {
3821 Diag(Tok, diag::err_omp_append_args_prefer_type_60);
3826 tok::annot_pragma_openmp_end);
3827 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3831 if (Tok.is(tok::r_paren)) {
3832 Diag(Tok, diag::err_omp_expected_pref_spec);
3836 while (Tok.isNot(tok::r_paren) &&
3837 Tok.isNot(tok::annot_pragma_openmp_end)) {
3839 if (Tok.is(tok::l_brace)) {
3843 Diag(Tok, diag::err_omp_prefer_type_brace_60);
3847 tok::annot_pragma_openmp_end);
3849 Expr *FrExpr =
nullptr;
3850 SmallVector<Expr *, 2> AttrExprs;
3851 bool SeenFr =
false;
3855 if (Tok.is(tok::r_brace)) {
3856 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3860 while (Tok.isNot(tok::r_brace) &&
3861 Tok.isNot(tok::annot_pragma_openmp_end)) {
3862 if (Tok.is(tok::identifier) &&
3863 Tok.getIdentifierInfo()->isStr(
"fr")) {
3865 Diag(Tok, diag::err_omp_interop_multiple_fr);
3869 {tok::comma, tok::r_brace, tok::annot_pragma_openmp_end},
3879 }
else if (Tok.is(tok::identifier) &&
3880 Tok.getIdentifierInfo()->isStr(
"attr")) {
3881 if (ParseOMPInteropAttrSelector(AttrExprs))
3886 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3889 if (Tok.is(tok::comma))
3892 if (BT.consumeClose())
3895 if (FrExpr || !AttrExprs.empty())
3896 InteropInfo.
Prefs.emplace_back(FrExpr, AttrExprs);
3901 SourceLocation Loc = Tok.getLocation();
3905 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
3908 InteropInfo.
Prefs.emplace_back(PTExpr.
get(),
3909 llvm::SmallVector<Expr *, 2>{});
3912 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3917 if (Tok.is(tok::comma))
3923 Diag(Tok, diag::err_omp_expected_interop_type);
3926 if (!Tok.is(tok::comma))
3931 if (!HasError && !IsTarget && !IsTargetSync) {
3932 Diag(Tok, diag::err_omp_expected_interop_type);
3936 if (Kind == OMPC_init) {
3937 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
3938 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3939 if (Tok.is(tok::colon))
3956 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3957 getOpenMPClauseName(Kind).data()))
3960 bool InteropError =
false;
3961 OMPInteropInfo InteropInfo;
3962 if (Kind == OMPC_init)
3963 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3966 SourceLocation VarLoc = Tok.getLocation();
3969 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3974 SourceLocation RLoc = Tok.getLocation();
3975 if (!
T.consumeClose())
3976 RLoc =
T.getCloseLocation();
3978 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3981 if (Kind == OMPC_init)
3982 return Actions.OpenMP().ActOnOpenMPInitClause(
3983 InteropVarExpr.
get(), InteropInfo, Loc,
T.getOpenLocation(), VarLoc,
3985 if (Kind == OMPC_use)
3986 return Actions.OpenMP().ActOnOpenMPUseClause(
3987 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
3989 if (Kind == OMPC_destroy)
3990 return Actions.OpenMP().ActOnOpenMPDestroyClause(
3991 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
3993 llvm_unreachable(
"Unexpected interop variable clause.");
3996OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
4000 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4001 getOpenMPClauseName(OMPC_ompx_attribute).data()))
4004 ParsedAttributes ParsedAttrs(AttrFactory);
4005 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
4008 if (
T.consumeClose())
4014 SmallVector<Attr *> Attrs;
4015 for (
const ParsedAttr &PA : ParsedAttrs) {
4016 switch (PA.getKind()) {
4017 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
4018 if (!PA.checkExactlyNumArgs(Actions, 2))
4020 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
4021 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
4024 case ParsedAttr::AT_AMDGPUWavesPerEU:
4025 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
4026 !PA.checkAtMostNumArgs(Actions, 2))
4028 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
4029 PA, PA.getArgAsExpr(0),
4030 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
4033 case ParsedAttr::AT_CUDALaunchBounds:
4034 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
4035 !PA.checkAtMostNumArgs(Actions, 3))
4037 if (
auto *A = Actions.CreateLaunchBoundsAttr(
4038 PA, PA.getArgAsExpr(0),
4039 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
4040 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr,
4045 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
4050 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
4051 Attrs, Loc,
T.getOpenLocation(),
T.getCloseLocation());
4057 if (!Val || ParseOnly)
4059 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
4060 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
4061 static_cast<DefaultKind
>(Val->Type) ==
4062 OMP_DEFAULT_firstprivate)) {
4063 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
4064 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
4067 : OMPC_firstprivate)
4068 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4071 return Actions.OpenMP().ActOnOpenMPSimpleClause(
4072 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
4076 SourceLocation Loc = Tok.getLocation();
4081 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
4088 SourceLocation DelimLoc;
4091 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4092 getOpenMPClauseName(Kind).data()))
4096 SmallVector<unsigned, 4> Arg;
4097 SmallVector<SourceLocation, 4> KLoc;
4098 if (Kind == OMPC_schedule) {
4099 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
4100 Arg.resize(NumberOfElements);
4101 KLoc.resize(NumberOfElements);
4106 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4109 Arg[Modifier1] = KindModifier;
4110 KLoc[Modifier1] = Tok.getLocation();
4111 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4112 Tok.isNot(tok::annot_pragma_openmp_end))
4114 if (Tok.is(tok::comma)) {
4118 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4122 KLoc[Modifier2] = Tok.getLocation();
4123 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4124 Tok.isNot(tok::annot_pragma_openmp_end))
4128 if (Tok.is(tok::colon))
4131 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
4133 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4135 Arg[ScheduleKind] = KindModifier;
4136 KLoc[ScheduleKind] = Tok.getLocation();
4137 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4138 Tok.isNot(tok::annot_pragma_openmp_end))
4140 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
4141 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
4142 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
4145 }
else if (Kind == OMPC_dist_schedule) {
4147 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4148 KLoc.push_back(Tok.getLocation());
4149 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4150 Tok.isNot(tok::annot_pragma_openmp_end))
4152 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
4154 }
else if (Kind == OMPC_default) {
4157 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4159 Arg.push_back(Modifier);
4160 KLoc.push_back(Tok.getLocation());
4161 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4162 Tok.isNot(tok::annot_pragma_openmp_end))
4165 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
4170 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4171 Arg.push_back(VariableCategory);
4172 KLoc.push_back(Tok.getLocation());
4173 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4174 Tok.isNot(tok::annot_pragma_openmp_end))
4177 Arg.push_back(OMPC_DEFAULT_VC_all);
4178 KLoc.push_back(SourceLocation());
4180 }
else if (Kind == OMPC_defaultmap) {
4183 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4189 Arg.push_back(Modifier);
4190 KLoc.push_back(Tok.getLocation());
4191 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4192 Tok.isNot(tok::annot_pragma_openmp_end))
4195 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
4196 if (Tok.is(tok::colon))
4199 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
4202 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4203 KLoc.push_back(Tok.getLocation());
4204 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4205 Tok.isNot(tok::annot_pragma_openmp_end))
4209 KLoc.push_back(SourceLocation());
4211 }
else if (Kind == OMPC_order) {
4212 enum { Modifier, OrderKind, NumberOfElements };
4213 Arg.resize(NumberOfElements);
4214 KLoc.resize(NumberOfElements);
4218 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4221 Arg[Modifier] = KindModifier;
4222 KLoc[Modifier] = Tok.getLocation();
4223 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4224 Tok.isNot(tok::annot_pragma_openmp_end))
4227 if (Tok.is(tok::colon))
4230 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
4232 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4234 Arg[OrderKind] = KindModifier;
4235 KLoc[OrderKind] = Tok.getLocation();
4236 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4237 Tok.isNot(tok::annot_pragma_openmp_end))
4239 }
else if (Kind == OMPC_device) {
4245 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4246 KLoc.push_back(Tok.getLocation());
4252 KLoc.emplace_back();
4254 }
else if (Kind == OMPC_grainsize) {
4258 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4262 Arg.push_back(Modifier);
4263 KLoc.push_back(Tok.getLocation());
4269 if (Modifier == OMPC_GRAINSIZE_strict) {
4270 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4275 KLoc.emplace_back();
4279 KLoc.emplace_back();
4281 }
else if (Kind == OMPC_dyn_groupprivate) {
4282 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4283 Arg.resize(NumberOfModifiers);
4284 KLoc.resize(NumberOfModifiers);
4288 auto ConsumeModifier = [&]() {
4289 unsigned Type = NumberOfModifiers;
4292 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4296 ParenT.consumeOpen();
4299 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4302 Diag(Tok.getLocation(), diag::err_expected)
4303 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4305 return std::make_tuple(
Type, Modifier, Loc);
4307 Type = ComplexModifier;
4308 Loc = Tok.getLocation();
4309 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4310 Tok.isNot(tok::annot_pragma_openmp_end))
4312 ParenT.consumeClose();
4315 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4317 Type = SimpleModifier;
4318 Loc = Tok.getLocation();
4319 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4320 Tok.isNot(tok::annot_pragma_openmp_end))
4324 return std::make_tuple(
Type, Modifier, Loc);
4327 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4328 SourceLocation Loc) {
4329 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4330 if (!KLoc[
Type].isValid()) {
4331 Arg[
Type] = Modifier;
4334 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4341 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4342 if (Type1 < NumberOfModifiers) {
4343 SaveModifier(Type1, Mod1, Loc1);
4344 if (Tok.is(tok::comma)) {
4347 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4348 if (Type2 < NumberOfModifiers)
4349 SaveModifier(Type2, Mod2, Loc2);
4352 if (Tok.is(tok::colon))
4355 Diag(Tok, diag::warn_pragma_expected_colon)
4356 <<
"dyn_groupprivate modifier";
4358 }
else if (Kind == OMPC_num_tasks) {
4362 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4366 Arg.push_back(Modifier);
4367 KLoc.push_back(Tok.getLocation());
4373 if (Modifier == OMPC_NUMTASKS_strict) {
4374 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4379 KLoc.emplace_back();
4383 KLoc.emplace_back();
4386 assert(Kind == OMPC_if);
4387 KLoc.push_back(Tok.getLocation());
4388 TentativeParsingAction TPA(*
this);
4390 Arg.push_back(
static_cast<unsigned>(DK));
4391 if (DK != OMPD_unknown) {
4393 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4398 Arg.back() = unsigned(OMPD_unknown);
4405 bool NeedAnExpression = (
Kind == OMPC_schedule && DelimLoc.
isValid()) ||
4406 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
4407 Kind == OMPC_if ||
Kind == OMPC_device ||
4408 Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4409 Kind == OMPC_dyn_groupprivate;
4410 if (NeedAnExpression) {
4411 SourceLocation ELoc = Tok.getLocation();
4417 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4421 SourceLocation RLoc = Tok.getLocation();
4422 if (!
T.consumeClose())
4423 RLoc =
T.getCloseLocation();
4425 if (NeedAnExpression && Val.
isInvalid())
4428 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4429 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4430 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4431 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4432 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4435 : OMPC_firstprivate)
4436 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4442 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4443 Kind, Arg, Val.
get(), Loc,
T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4448 if (ReductionIdScopeSpec.
isEmpty()) {
4486 ReductionIdScopeSpec,
nullptr,
4490 false,
nullptr, ReductionId);
4497 if (!
Tok.is(tok::identifier))
4504 return TypeModifier;
4510 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4511 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4517 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4521 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4522 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4523 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4527 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4529 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4532 return T.consumeClose();
4538 bool HasMapType =
false;
4540 StringRef PreMapName =
"";
4544 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4545 TypeModifier == OMPC_MAP_MODIFIER_close ||
4546 TypeModifier == OMPC_MAP_MODIFIER_present ||
4547 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4548 Data.MapTypeModifiers.push_back(TypeModifier);
4549 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4550 if (PP.LookAhead(0).isNot(tok::comma) &&
4551 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4552 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4553 <<
"map type modifier";
4555 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4556 Data.MapTypeModifiers.push_back(TypeModifier);
4557 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4561 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4563 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4564 <<
"map type modifier";
4569 Data.ExtraModifier = MapKind;
4571 PreMapLoc = Tok.getLocation();
4572 PreMapName = Tok.getIdentifierInfo()->getName();
4574 Diag(Tok, diag::err_omp_more_one_map_type);
4575 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4579 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4580 Data.MapTypeModifiers.push_back(TypeModifier);
4581 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4582 if (PP.LookAhead(0).isNot(tok::comma) &&
4583 PP.LookAhead(0).isNot(tok::colon))
4584 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4585 <<
"map type modifier";
4587 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4597 if (Tok.is(tok::comma)) {
4598 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4603 if (PP.LookAhead(0).is(tok::colon)) {
4611 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4622 if (!Tok.is(tok::colon)) {
4623 Diag(Tok, diag::err_omp_unknown_map_type);
4637 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4642 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4643 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4644 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4654 if (
Tok.is(tok::colon)) {
4655 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4660 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4664ExprResult Parser::ParseOpenMPIteratorsExpr() {
4665 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4666 "Expected 'iterator' token.");
4670 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4673 SourceLocation LLoc =
T.getOpenLocation();
4674 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4675 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4678 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4685 IteratorType = TR.
get();
4689 IdentifierInfo *II =
nullptr;
4690 SourceLocation IdLoc;
4691 if (Tok.is(tok::identifier)) {
4692 II = Tok.getIdentifierInfo();
4695 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4699 SourceLocation AssignLoc;
4700 if (Tok.is(tok::equal))
4703 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4708 SourceLocation Loc = Tok.getLocation();
4711 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4714 SourceLocation ColonLoc;
4715 if (Tok.is(tok::colon))
4719 Loc = Tok.getLocation();
4722 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4725 SourceLocation SecColonLoc;
4728 if (Tok.is(tok::colon)) {
4732 Loc = Tok.getLocation();
4735 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4740 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4741 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4742 if (Tok.is(tok::comma))
4745 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4748 D.
Type = IteratorType;
4758 SourceLocation RLoc = Tok.getLocation();
4759 if (!
T.consumeClose())
4760 RLoc =
T.getCloseLocation();
4762 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4771 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4774 if (Tok.is(tok::identifier) &&
4775 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4777 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4778 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4779 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4780 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4781 Data.ExtraModifier != OMPC_DEPEND_inout)
4782 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4784 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4785 ? OMPC_DEPEND_outallmemory
4786 : OMPC_DEPEND_inoutallmemory;
4802 Data.DepModOrTailExpr = Tail.
get();
4804 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4805 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4823 bool AllocatorSeen =
false;
4824 bool AlignSeen =
false;
4843 if (
Tok.is(tok::l_paren)) {
4844 switch (CurrentModifier) {
4845 case OMPC_ALLOCATE_allocator: {
4846 if (AllocatorSeen) {
4847 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4849 << getOpenMPClauseName(Kind);
4851 Data.AllocClauseModifiers.push_back(CurrentModifier);
4852 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4855 tok::annot_pragma_openmp_end);
4859 AllocatorSeen =
true;
4862 case OMPC_ALLOCATE_align: {
4864 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4866 << getOpenMPClauseName(Kind);
4868 Data.AllocClauseModifiers.push_back(CurrentModifier);
4869 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4873 Data.AllocateAlignment = Val.
get();
4878 llvm_unreachable(
"Unexpected allocate modifier");
4881 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4883 if (
Tok.isNot(tok::comma))
4886 CurrentModifierLoc =
Tok.getLocation();
4891 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4894 }
while (!AllocatorSeen || !AlignSeen);
4903 bool InvalidReductionId =
false;
4904 bool IsInvalidMapperModifier =
false;
4908 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4909 getOpenMPClauseName(Kind).data()))
4912 bool HasIterator =
false;
4913 bool InvalidIterator =
false;
4914 bool NeedRParenForLinear =
false;
4916 tok::annot_pragma_openmp_end);
4918 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4919 Kind == OMPC_in_reduction) {
4921 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4922 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4925 Data.ExtraModifier =
4927 Data.ExtraModifierLoc = Tok.getLocation();
4929 assert(Tok.is(tok::comma) &&
"Expected comma.");
4933 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4934 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4940 if (Tok.is(tok::kw_private)) {
4941 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4942 Data.OriginalSharingModifierLoc = Tok.getLocation();
4944 }
else if (Tok.is(tok::identifier) &&
4945 (PP.getSpelling(Tok) ==
"shared" ||
4946 PP.getSpelling(Tok) ==
"default")) {
4947 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4948 Data.OriginalSharingModifierLoc = Tok.getLocation();
4951 Diag(Tok.getLocation(), diag::err_expected)
4952 <<
"'private or shared or default'";
4957 if (!Tok.is(tok::comma)) {
4958 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4965 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4970 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4971 if (InvalidReductionId) {
4972 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4975 if (Tok.is(tok::colon))
4978 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4979 if (!InvalidReductionId)
4980 Data.ReductionOrMapperId =
4981 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4982 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4984 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4993 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4994 Data.DepModOrTailExpr = IteratorRes.
get();
4996 ExpectAndConsume(tok::comma);
5002 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5004 Data.ExtraModifierLoc = Tok.getLocation();
5006 (Kind == OMPC_doacross &&
5008 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5013 if (DKind == OMPD_ordered_standalone && Kind == OMPC_depend &&
5014 Data.ExtraModifier == OMPC_DEPEND_source) {
5020 if (Tok.is(tok::colon)) {
5022 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
5023 Diag(Tok, DKind == OMPD_ordered_standalone
5024 ? diag::warn_pragma_expected_colon_r_paren
5025 : diag::warn_pragma_expected_colon)
5026 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
5028 if (Kind == OMPC_doacross) {
5029 if (Tok.is(tok::identifier) &&
5030 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
5031 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
5032 ? OMPC_DOACROSS_source_omp_cur_iteration
5033 : OMPC_DOACROSS_sink_omp_cur_iteration;
5036 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
5037 if (Tok.isNot(tok::minus)) {
5038 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5039 << getOpenMPClauseName(Kind) << 0 << 0;
5046 if (Tok.isNot(tok::numeric_constant) ||
5047 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
5048 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
5049 << getOpenMPClauseName(Kind) << 0 << 0;
5055 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
5056 if (Tok.isNot(tok::r_paren)) {
5057 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5058 << getOpenMPClauseName(Kind) << 1 << 1;
5064 if (Kind == OMPC_doacross &&
5065 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
5066 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
5067 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
5073 }
else if (Kind == OMPC_linear) {
5075 Data.ExtraModifier = OMPC_LINEAR_val;
5076 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
5077 Data.ExtraModifier =
5081 NeedRParenForLinear =
true;
5083 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
5084 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
5085 <<
"linear(list: [linear-modifier,] step(step-size))";
5087 }
else if (Kind == OMPC_lastprivate) {
5094 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
5095 Data.ExtraModifier =
5097 Data.ExtraModifierLoc = Tok.getLocation();
5099 assert(Tok.is(tok::colon) &&
"Expected colon.");
5102 }
else if (Kind == OMPC_map) {
5104 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
5107 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
5108 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
5109 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
5110 Data.IteratorExpr = IteratorRes.
get();
5112 ExpectAndConsume(tok::comma);
5114 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
5117 InvalidIterator =
true;
5127 Data.ExtraModifierLoc = Tok.getLocation();
5130 TentativeParsingAction TPA(*
this);
5131 bool ColonPresent =
false;
5132 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5134 if (Tok.is(tok::colon))
5135 ColonPresent =
true;
5142 Diag(Tok, diag::err_omp_map_modifier_specification_list);
5144 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
5150 Data.ExtraModifier = OMPC_MAP_tofrom;
5152 if (DKind == OMPD_target_enter_data)
5153 Data.ExtraModifier = OMPC_MAP_to;
5154 else if (DKind == OMPD_target_exit_data)
5155 Data.ExtraModifier = OMPC_MAP_from;
5157 Data.IsMapTypeImplicit =
true;
5160 if (Tok.is(tok::colon))
5162 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
5163 while (Tok.is(tok::identifier)) {
5168 Data.MotionModifiers.push_back(Modifier);
5169 Data.MotionModifiersLoc.push_back(Tok.getLocation());
5170 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
5172 Tail = ParseOpenMPIteratorsExpr();
5173 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
5176 Data.IteratorExpr = Tail.
get();
5179 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
5181 if (IsInvalidMapperModifier)
5189 if (Tok.is(tok::comma))
5193 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
5194 if (!IsInvalidMapperModifier) {
5196 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
5198 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
5200 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5208 }
else if (Kind == OMPC_allocate ||
5209 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
5210 PP.getSpelling(Tok) ==
"iterator")) {
5214 TentativeParsingAction TPA(*
this);
5219 if (Kind == OMPC_allocate) {
5224 Tail = ParseOpenMPIteratorsExpr();
5226 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
5229 if (Tok.is(tok::colon)) {
5236 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5237 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5239 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5246 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5249 }
else if (Kind == OMPC_adjust_args) {
5253 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5255 Data.ExtraModifierLoc = Tok.getLocation();
5257 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5262 if (Tok.is(tok::colon))
5263 Data.ColonLoc = Tok.getLocation();
5267 if (Tok.is(tok::l_paren)) {
5270 if (Tok.is(tok::identifier)) {
5271 std::string Modifier = PP.getSpelling(Tok);
5272 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5273 Data.NeedDevicePtrModifier =
5274 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5275 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5277 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5278 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5283 if (Tok.is(tok::r_paren)) {
5284 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5287 Diag(Tok, diag::err_expected) << tok::r_paren;
5288 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5297 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5300 }
else if (Kind == OMPC_use_device_ptr) {
5304 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5308 Data.ExtraModifier = FallbackModifier;
5309 Data.ExtraModifierLoc = Tok.getLocation();
5311 if (Tok.is(tok::colon))
5314 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5317 }
else if (Kind == OMPC_num_teams || Kind == OMPC_thread_limit) {
5321 Data.ExtraModifierArray[0] =
Data.ExtraModifierArray[1] =
5326 bool CanParseLowerBoundModifier = (Kind == OMPC_num_teams);
5327 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"dims") &&
5334 Data.ExtraModifierArray[Mod] =
5335 Kind == OMPC_num_teams ?
static_cast<int>(OMPC_NUMTEAMS_dims)
5336 :
static_cast<int>(OMPC_THREADLIMIT_dims);
5337 Data.ExtraModifierExprArray[Mod] = ExprR.
get();
5338 Data.ExtraModifierLocArray[Mod] = TLoc;
5342 if (Tok.is(tok::colon)) {
5345 CanParseLowerBoundModifier =
false;
5346 }
else if (CanParseLowerBoundModifier && Tok.is(tok::comma)) {
5351 Diag(Tok, diag::err_modifier_expected_colon)
5352 << getOpenMPClauseName(Kind);
5354 Data.RLoc = Tok.getLocation();
5355 if (!
T.consumeClose())
5356 Data.RLoc =
T.getCloseLocation();
5362 if (CanParseLowerBoundModifier) {
5363 TentativeParsingAction TPA(*
this);
5368 Data.RLoc = Tok.getLocation();
5369 if (!
T.consumeClose())
5370 Data.RLoc =
T.getCloseLocation();
5375 if (Tok.is(tok::colon)) {
5378 Data.ExtraModifierArray[Mod] = OMPC_NUMTEAMS_lower_bound;
5379 Data.ExtraModifierExprArray[Mod] = FirstExpr.
get();
5380 Data.ExtraModifierLocArray[Mod] = TLoc;
5388 }
else if (Kind == OMPC_num_threads) {
5392 bool HasModifier =
false;
5394 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"dims") &&
5405 Diag(TLoc, diag::err_omp_incompatible_modifiers)
5408 << getOpenMPClauseName(Kind);
5410 Data.ExtraModifierArray[1] =
static_cast<int>(OMPC_NUMTHREADS_dims);
5411 Data.ExtraModifierExprArray[1] =
5413 Data.ExtraModifierLocArray[1] = TLoc;
5420 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5425 Diag(Tok, diag::err_omp_incompatible_modifiers)
5428 Data.ExtraModifierArray[0])
5429 << getOpenMPClauseName(Kind);
5430 Data.ExtraModifierArray[0] = Modifier;
5431 Data.ExtraModifierLocArray[0] = Tok.getLocation();
5441 if (Tok.is(tok::comma))
5449 if (!Tok.is(tok::colon)) {
5450 Diag(Tok, diag::err_modifier_expected_colon)
5451 << getOpenMPClauseName(Kind);
5453 Data.RLoc = Tok.getLocation();
5454 if (!
T.consumeClose())
5455 Data.RLoc =
T.getCloseLocation();
5463 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5464 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5465 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5466 (Kind == OMPC_reduction && !InvalidReductionId) ||
5470 (Kind == OMPC_adjust_args &&
5472 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5473 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5474 Tok.isNot(tok::annot_pragma_openmp_end))) {
5481 Vars.push_back(VarExpr.
get());
5483 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5488 IsComma = Tok.is(tok::comma);
5491 else if (Tok.isNot(tok::r_paren) &&
5492 Tok.isNot(tok::annot_pragma_openmp_end) &&
5493 (!MayHaveTail || Tok.isNot(tok::colon))) {
5494 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
5495 Diag(Tok, diag::err_omp_expected_punc)
5496 << ((Kind == OMPC_flush)
5497 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5498 : getOpenMPClauseName(Kind))
5499 << (Kind == OMPC_flush);
5504 if (NeedRParenForLinear)
5508 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5509 bool StepFound =
false;
5510 bool ModifierFound =
false;
5512 Data.ColonLoc = Tok.getLocation();
5515 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5516 bool Malformed =
false;
5517 while (Tok.isNot(tok::r_paren)) {
5518 if (Tok.is(tok::identifier)) {
5523 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5526 if (LinKind == OMPC_LINEAR_step) {
5528 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5531 tok::annot_pragma_openmp_end);
5535 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5540 Data.StepModifierLoc = StepModifierLoc;
5544 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5546 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5548 Data.ExtraModifier = LinKind;
5550 ModifierFound =
true;
5555 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5564 if (Tok.is(tok::comma))
5566 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5569 if (!Malformed && !StepFound && !ModifierFound)
5570 Diag(ELoc, diag::err_expected_expression);
5574 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5577 Data.DepModOrTailExpr = Tail.
get();
5579 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5585 Data.RLoc = Tok.getLocation();
5586 if (!
T.consumeClose())
5587 Data.RLoc =
T.getCloseLocation();
5591 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5593 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5594 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5621 "Expected parsing to start at clause name");
5626 if (
T.consumeOpen()) {
5627 Diag(
Tok, diag::err_expected) << tok::l_paren;
5640 Exprs.push_back(Val.
get());
5643 bool Result =
T.consumeClose();
5644 OpenLoc =
T.getOpenLocation();
5645 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
@ Type
The name was classified as a type.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OpenMPMotionModifierKind
OpenMP modifier kind for 'to' or 'from' clause.
@ OMPC_MOTION_MODIFIER_unknown
@ OMPC_DEFAULTMAP_unknown
OpenMPAllocateClauseModifier
OpenMP modifiers for 'allocate' clause.
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "executable".
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
@ OMPC_DYN_GROUPPRIVATE_unknown
bool isOpenMPInformationalDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "informational".
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
@ OMPC_THREADLIMIT_unknown
OpenMPNumThreadsClauseModifier
@ OMPC_NUMTHREADS_unknown
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
@ OMPC_MAP_MODIFIER_unknown
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
ActionResult< Expr * > ExprResult
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
ActionResult< Stmt * > StmtResult
OpenMPDefaultClauseVariableCategory getOpenMPDefaultVariableCategory(StringRef Str, const LangOptions &LangOpts)
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
int const char * function
llvm::omp::TraitProperty Kind
StringRef RawString
The raw string as we parsed it. This is needed for the isa trait set (which accepts anything) and (la...
llvm::omp::TraitSelector Kind
SmallVector< OMPTraitProperty, 1 > Properties
SmallVector< OMPTraitSelector, 2 > Selectors
Clang specific specialization of the OMPContext to lookup target features.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
llvm::SmallVector< OMPInteropPref, 4 > Prefs
This structure contains most locations needed for by an OMPVarListClause.
std::optional< Expr * > Indirect
The directive with indirect clause.
OpenMPDirectiveKind Kind
The directive kind, begin declare target or declare target.
OMPDeclareTargetDeclAttr::DevTypeTy DT
The 'device_type' as parsed from the clause.
SourceLocation Loc
The directive location.
llvm::DenseMap< NamedDecl *, MapInfo > ExplicitlyMapped
Explicitly listed variables and functions in a 'to' or 'link' clause.
SourceLocation DeclIdentLoc
SourceLocation SecColonLoc
IdentifierInfo * DeclIdent
OMPIteratorExpr::IteratorRange Range
Data used for processing a list of variables in OpenMP clauses.
Data for list of allocators.
Expr * AllocatorTraits
Allocator traits.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Expr * Allocator
Allocator.