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);
66 assert(D == Kind &&
"Directive kind mismatch");
69 if (
static_cast<int>(Version) < VR.Min)
70 P.
Diag(Loc, diag::warn_omp_future_directive_spelling) << Name;
76 static const DirectiveNameParser DirParser;
78 const DirectiveNameParser::State *S = DirParser.initial();
81 if (
Tok.isAnnotation())
87 S = DirParser.consume(S, Concat);
91 while (!
Tok.isAnnotation()) {
94 if (!
Tok.isAnnotation()) {
96 S = DirParser.consume(S, TS);
104 assert(S &&
"Should have exited early");
113 bool WithOperator =
false;
114 if (
Tok.is(tok::kw_operator)) {
119 switch (
Tok.getKind()) {
144 case tok::identifier:
149 P.
Diag(
Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
150 P.
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
156 return OOK ==
OO_None ? DeclNames.getIdentifier(
Tok.getIdentifierInfo())
157 : DeclNames.getCXXOperatorName(OOK);
162 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
165 if (
T.expectAndConsume(
166 diag::err_expected_lparen_after,
167 getOpenMPDirectiveName(OMPD_declare_reduction, OMPVersion).data())) {
173 if (Name.
isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
177 bool IsCorrect = !ExpectAndConsume(tok::colon);
179 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
182 IsCorrect = IsCorrect && !Name.
isEmpty();
184 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
185 Diag(Tok.getLocation(), diag::err_expected_type);
189 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
192 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
199 QualType ReductionType = Actions.OpenMP().ActOnOpenMPDeclareReductionType(
200 Range.getBegin(), TR);
201 if (!ReductionType.
isNull()) {
202 ReductionTypes.push_back(
203 std::make_pair(ReductionType,
Range.getBegin()));
206 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
210 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
214 if (ExpectAndConsume(tok::comma)) {
216 if (Tok.is(tok::annot_pragma_openmp_end)) {
217 Diag(Tok.getLocation(), diag::err_expected_type);
221 }
while (Tok.isNot(tok::annot_pragma_openmp_end));
223 if (ReductionTypes.empty()) {
228 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
232 if (ExpectAndConsume(tok::colon))
235 if (Tok.is(tok::annot_pragma_openmp_end)) {
236 Diag(Tok.getLocation(), diag::err_expected_expression);
241 Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveStart(
242 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes,
247 unsigned I = 0, E = ReductionTypes.size();
248 for (Decl *D : DRD.get()) {
249 TentativeParsingAction TPA(*
this);
254 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerStart(
getCurScope(), D);
255 ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
257 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerEnd(
258 D, CombinerResult.
get());
260 if (CombinerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
261 Tok.isNot(tok::annot_pragma_openmp_end)) {
266 IsCorrect = !
T.consumeClose() && IsCorrect && CombinerResult.
isUsable();
268 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
270 if (Tok.is(tok::identifier) &&
271 Tok.getIdentifierInfo()->isStr(
"initializer")) {
274 Diag(Tok.getLocation(), diag::err_expected) <<
"'initializer'";
281 tok::annot_pragma_openmp_end);
283 !
T.expectAndConsume(diag::err_expected_lparen_after,
"initializer") &&
285 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
290 VarDecl *OmpPrivParm =
291 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerStart(
294 if (Tok.is(tok::identifier) &&
295 Tok.getIdentifierInfo()->isStr(
"omp_priv")) {
297 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
299 InitializerResult = Actions.ActOnFinishFullExpr(
303 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerEnd(
304 D, InitializerResult.
get(), OmpPrivParm);
305 if (InitializerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
306 Tok.isNot(tok::annot_pragma_openmp_end)) {
312 !
T.consumeClose() && IsCorrect && !InitializerResult.
isInvalid();
324 return Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveEnd(
328void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
331 if (isTokenEqualOrEqualTypo()) {
334 if (Tok.is(tok::code_completion)) {
336 Actions.CodeCompletion().CodeCompleteInitializer(
getCurScope(),
338 Actions.FinalizeDeclaration(OmpPrivParm);
342 PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
345 if (
Init.isInvalid()) {
347 Actions.ActOnInitializerError(OmpPrivParm);
349 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
352 }
else if (Tok.is(tok::l_paren)) {
359 SourceLocation LParLoc =
T.getOpenLocation();
360 auto RunSignatureHelp = [
this, OmpPrivParm, LParLoc, &Exprs]() {
361 QualType PreferredType =
362 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
364 OmpPrivParm->
getLocation(), Exprs, LParLoc,
false);
365 CalledSignatureHelp =
true;
366 return PreferredType;
368 if (ParseExpressionList(Exprs, [&] {
369 PreferredType.enterFunctionArgument(Tok.getLocation(),
372 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
374 Actions.ActOnInitializerError(OmpPrivParm);
378 SourceLocation RLoc = Tok.getLocation();
379 if (!
T.consumeClose())
380 RLoc =
T.getCloseLocation();
383 Actions.ActOnParenListExpr(
T.getOpenLocation(), RLoc, Exprs);
384 Actions.AddInitializerToDecl(OmpPrivParm,
Initializer.get(),
389 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
393 if (
Init.isInvalid()) {
394 Actions.ActOnInitializerError(OmpPrivParm);
396 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
400 Actions.ActOnUninitializedDecl(OmpPrivParm);
406 bool IsCorrect =
true;
407 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
410 if (
T.expectAndConsume(
411 diag::err_expected_lparen_after,
412 getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion).data())) {
418 auto &DeclNames = Actions.getASTContext().DeclarationNames;
419 DeclarationName MapperId;
420 if (PP.LookAhead(0).is(tok::colon)) {
421 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
422 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
425 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
429 ExpectAndConsume(tok::colon);
433 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get(
"default"));
436 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
440 DeclarationName VName;
445 MapperType = Actions.OpenMP().ActOnOpenMPDeclareMapperType(
Range.getBegin(),
455 IsCorrect &= !
T.consumeClose();
463 DeclarationNameInfo DirName;
464 SourceLocation Loc = Tok.getLocation();
467 ParseScope OMPDirectiveScope(
this, ScopeFlags);
468 Actions.OpenMP().StartOpenMPDSABlock(OMPD_declare_mapper, DirName,
473 Actions.OpenMP().ActOnOpenMPDeclareMapperDirectiveVarDecl(
477 SmallVector<OMPClause *, 6> Clauses;
478 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
481 : getOpenMPClauseKind(PP.getSpelling(Tok));
482 Actions.OpenMP().StartOpenMPClause(CKind);
484 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
486 Clauses.push_back(Clause);
490 if (Tok.is(tok::comma))
492 Actions.OpenMP().EndOpenMPClause();
494 if (Clauses.empty()) {
495 Diag(Tok, diag::err_omp_expected_clause)
496 << getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion);
505 DeclGroupPtrTy DG = Actions.OpenMP().ActOnOpenMPDeclareMapperDirective(
506 OuterScope, Actions.getCurLexicalContext(), MapperId, MapperType,
507 Range.getBegin(), VName, AS, MapperVarRef.
get(), Clauses);
509 Actions.OpenMP().EndOpenMPDSABlock(
nullptr);
510 OMPDirectiveScope.Exit();
521 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
522 DeclSpec DS(AttrFactory);
523 ParseSpecifierQualifierList(DS, AS, DSC);
528 ParseDeclarator(DeclaratorInfo);
529 Range = DeclaratorInfo.getSourceRange();
530 if (DeclaratorInfo.getIdentifier() ==
nullptr) {
531 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
534 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
536 return Actions.OpenMP().ActOnOpenMPDeclareMapperVarDecl(
getCurScope(),
548 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
551 if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
555 (void)ConsumeAnnotationToken();
560 skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
564 VariantMatchInfo VMI;
568 Loc](StringRef ISATrait) {
571 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
574 ASTCtx, std::move(DiagUnknownTrait),
577 Actions.OpenMP().getOpenMPDeviceNum());
579 if (isVariantApplicableInContext(VMI, OMPCtx,
581 Actions.OpenMP().ActOnOpenMPBeginDeclareVariant(Loc, TI);
586 unsigned Nesting = 1;
590 DKLoc = Tok.getLocation();
592 if (DK == OMPD_end_declare_variant)
594 else if (DK == OMPD_begin_declare_variant)
596 if (!Nesting || isEofOrEom())
601 parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant, DK,
612class FNContextRAII final {
616 bool HasFunScope =
false;
617 FNContextRAII() =
delete;
618 FNContextRAII(
const FNContextRAII &) =
delete;
619 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
666 bool IsError =
false;
667 while (
Tok.isNot(tok::annot_pragma_openmp_end)) {
668 if (
Tok.isNot(tok::identifier))
670 OMPDeclareSimdDeclAttr::BranchStateTy Out;
672 StringRef ClauseName = II->
getName();
674 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
675 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
676 P.
Diag(
Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
678 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
684 }
else if (ClauseName ==
"simdlen") {
687 P.
Diag(
Tok, diag::err_omp_more_one_clause)
688 << getOpenMPDirectiveName(OMPD_declare_simd, OMPVersion)
699 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
700 CKind == OMPC_linear) {
703 if (CKind == OMPC_aligned) {
705 }
else if (CKind == OMPC_linear) {
706 Data.ExtraModifier = OMPC_LINEAR_val;
712 getOpenMPClauseKind(ClauseName), *Vars,
Data))
714 if (CKind == OMPC_aligned) {
715 Alignments.append(Aligneds.size() - Alignments.size(),
716 Data.DepModOrTailExpr);
717 }
else if (CKind == OMPC_linear) {
718 assert(0 <=
Data.ExtraModifier &&
720 "Unexpected linear modifier.");
723 Data.ExtraModifierLoc))
724 Data.ExtraModifier = OMPC_LINEAR_val;
725 LinModifiers.append(Linears.size() - LinModifiers.size(),
727 Steps.append(Linears.size() - Steps.size(),
Data.DepModOrTailExpr);
734 if (
Tok.is(tok::comma))
743 PP.EnterToken(Tok,
true);
744 PP.EnterTokenStream(Toks,
true,
750 FNContextRAII FnContext(*
this, Ptr);
751 OMPDeclareSimdDeclAttr::BranchStateTy BS =
752 OMPDeclareSimdDeclAttr::BS_Undefined;
754 SmallVector<Expr *, 4> Uniforms;
755 SmallVector<Expr *, 4> Aligneds;
756 SmallVector<Expr *, 4> Alignments;
757 SmallVector<Expr *, 4> Linears;
758 SmallVector<unsigned, 4> LinModifiers;
759 SmallVector<Expr *, 4> Steps;
762 Alignments, Linears, LinModifiers, Steps);
763 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
765 SourceLocation EndLoc = ConsumeAnnotationToken();
768 return Actions.OpenMP().ActOnOpenMPDeclareSimdDirective(
769 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
770 LinModifiers, Steps, SourceRange(Loc, EndLoc));
777 CONTEXT_SELECTOR_SET_LVL = 0,
778 CONTEXT_SELECTOR_LVL = 1,
779 CONTEXT_TRAIT_LVL = 2,
782static StringRef stringLiteralParser(
Parser &P) {
789 if (
Tok.
is(tok::identifier) ||
Tok.
is(tok::kw_for)) {
797 return stringLiteralParser(P);
800 diag::warn_omp_declare_variant_string_literal_or_identifier)
805static bool checkForDuplicates(
Parser &P, StringRef Name,
807 llvm::StringMap<SourceLocation> &Seen,
809 auto Res = Seen.try_emplace(Name, NameLoc);
815 P.
Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
817 P.
Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
823void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
824 llvm::omp::TraitSet
Set,
826 llvm::StringMap<SourceLocation> &Seen) {
827 TIProperty.
Kind = TraitProperty::invalid;
829 SourceLocation NameLoc = Tok.getLocation();
831 if (Selector == llvm::omp::TraitSelector::target_device_device_num) {
833 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
835 if (DeviceNumExprResult.
isUsable()) {
836 Expr *DeviceNumExpr = DeviceNumExprResult.
get();
837 Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr);
841 Name = getNameFromIdOrString(*
this, Tok, CONTEXT_TRAIT_LVL);
843 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
844 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
849 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
850 if (TIProperty.
Kind != TraitProperty::invalid) {
851 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
852 TIProperty.
Kind = TraitProperty::invalid;
858 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
859 << Name << getOpenMPContextTraitSelectorName(Selector)
860 << getOpenMPContextTraitSetName(
Set);
862 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
863 if (SetForName != TraitSet::invalid) {
864 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
865 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
866 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
867 << Name <<
"<selector-name>"
868 <<
"(<property-name>)";
871 TraitSelector SelectorForName =
872 getOpenMPContextTraitSelectorKind(Name, SetForName);
873 if (SelectorForName != TraitSelector::invalid) {
874 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
875 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
876 bool AllowsTraitScore =
false;
877 bool RequiresProperty =
false;
878 isValidTraitSelectorForTraitSet(
879 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
880 AllowsTraitScore, RequiresProperty);
881 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
882 << getOpenMPContextTraitSetName(
883 getOpenMPContextTraitSetForSelector(SelectorForName))
884 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
887 for (
const auto &PotentialSet :
888 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
889 TraitSet::device, TraitSet::target_device}) {
890 TraitProperty PropertyForName =
891 getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
892 if (PropertyForName == TraitProperty::invalid)
894 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
895 << getOpenMPContextTraitSetName(
896 getOpenMPContextTraitSetForProperty(PropertyForName))
897 << getOpenMPContextTraitSelectorName(
898 getOpenMPContextTraitSelectorForProperty(PropertyForName))
899 << (
"(" + Name +
")").str();
902 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
903 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
909 llvm::StringMap<SourceLocation> &Seen) {
910 assert(TISelector.
Kind ==
911 llvm::omp::TraitSelector::implementation_extension &&
912 "Only for extension properties, e.g., "
913 "`implementation={extension(PROPERTY)}`");
914 if (TIProperty.
Kind == TraitProperty::invalid)
917 if (TIProperty.
Kind ==
918 TraitProperty::implementation_extension_disable_implicit_base)
921 if (TIProperty.
Kind ==
922 TraitProperty::implementation_extension_allow_templates)
925 if (TIProperty.
Kind ==
926 TraitProperty::implementation_extension_bind_to_declaration)
931 llvm::omp::TraitProperty::implementation_extension_match_all ||
933 llvm::omp::TraitProperty::implementation_extension_match_any ||
935 llvm::omp::TraitProperty::implementation_extension_match_none);
938 if (IsMatchExtension(TIProperty)) {
940 if (IsMatchExtension(SeenProp)) {
941 P.
Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
942 StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
945 P.
Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
946 << CONTEXT_TRAIT_LVL << SeenName;
952 llvm_unreachable(
"Unknown extension property!");
955void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
956 llvm::omp::TraitSet
Set,
957 llvm::StringMap<SourceLocation> &Seen) {
958 assert(TISelector.
Kind != TraitSelector::user_condition &&
959 "User conditions are special properties not handled here!");
961 SourceLocation PropertyLoc = Tok.getLocation();
962 OMPTraitProperty TIProperty;
963 parseOMPTraitPropertyKind(TIProperty,
Set, TISelector.
Kind, Seen);
965 if (TISelector.
Kind == llvm::omp::TraitSelector::implementation_extension)
968 TIProperty.
Kind = TraitProperty::invalid;
971 if (TIProperty.
Kind == TraitProperty::invalid) {
972 if (PropertyLoc != Tok.getLocation())
973 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
974 << CONTEXT_TRAIT_LVL;
978 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.
Kind,
987 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
988 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
990 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
991 << getOpenMPContextTraitSetName(
Set);
992 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
993 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
995 << getOpenMPContextTraitSelectorName(
996 getOpenMPContextTraitSelectorForProperty(TIProperty.
Kind))
997 << getOpenMPContextTraitSetName(
998 getOpenMPContextTraitSetForProperty(TIProperty.
Kind));
999 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1000 << CONTEXT_TRAIT_LVL;
1003void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
1004 llvm::omp::TraitSet
Set,
1005 llvm::StringMap<SourceLocation> &Seen) {
1006 TISelector.
Kind = TraitSelector::invalid;
1008 SourceLocation NameLoc = Tok.getLocation();
1009 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_LVL);
1011 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1012 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1016 TISelector.
Kind = getOpenMPContextTraitSelectorKind(Name,
Set);
1017 if (TISelector.
Kind != TraitSelector::invalid) {
1018 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1019 TISelector.
Kind = TraitSelector::invalid;
1024 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1025 << Name << getOpenMPContextTraitSetName(
Set);
1027 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1028 if (SetForName != TraitSet::invalid) {
1029 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1030 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1031 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1032 << Name <<
"<selector-name>"
1033 <<
"<property-name>";
1036 for (
const auto &PotentialSet :
1037 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1038 TraitSet::device, TraitSet::target_device}) {
1039 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1040 PotentialSet, TraitSelector::invalid, Name);
1041 if (PropertyForName == TraitProperty::invalid)
1043 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1044 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1045 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1046 << getOpenMPContextTraitSetName(
1047 getOpenMPContextTraitSetForProperty(PropertyForName))
1048 << getOpenMPContextTraitSelectorName(
1049 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1050 << (
"(" + Name +
")").str();
1053 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1054 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1061 StringRef SelectorName =
1063 if (SelectorName !=
"score")
1074 <<
"score expression";
1078void Parser::parseOMPContextSelector(
1079 OMPTraitSelector &TISelector, llvm::omp::TraitSet
Set,
1080 llvm::StringMap<SourceLocation> &SeenSelectors) {
1081 unsigned short OuterPC = ParenCount;
1086 auto FinishSelector = [OuterPC,
this]() ->
void {
1089 while (!
SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1090 tok::annot_pragma_openmp_end},
1093 if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1094 (void)ConsumeParen();
1095 if (OuterPC <= ParenCount) {
1099 if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1105 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1106 << CONTEXT_SELECTOR_LVL;
1109 SourceLocation SelectorLoc = Tok.getLocation();
1110 parseOMPTraitSelectorKind(TISelector,
Set, SeenSelectors);
1111 if (TISelector.
Kind == TraitSelector::invalid)
1112 return FinishSelector();
1114 bool AllowsTraitScore =
false;
1115 bool RequiresProperty =
false;
1116 if (!isValidTraitSelectorForTraitSet(TISelector.
Kind,
Set, AllowsTraitScore,
1117 RequiresProperty)) {
1118 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1119 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1120 << getOpenMPContextTraitSetName(
Set);
1121 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1122 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1123 << getOpenMPContextTraitSetName(
1124 getOpenMPContextTraitSetForSelector(TISelector.
Kind))
1125 << RequiresProperty;
1126 return FinishSelector();
1129 if (!RequiresProperty) {
1131 {getOpenMPContextTraitPropertyForSelector(TISelector.
Kind),
1132 getOpenMPContextTraitSelectorName(TISelector.
Kind)});
1136 if (!Tok.is(tok::l_paren)) {
1137 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1138 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1139 << getOpenMPContextTraitSetName(
Set);
1140 return FinishSelector();
1143 if (TISelector.
Kind == TraitSelector::user_condition) {
1144 SourceLocation RLoc;
1147 return FinishSelector();
1150 {TraitProperty::user_condition_unknown,
"<condition>"});
1155 tok::annot_pragma_openmp_end);
1157 (void)BDT.consumeOpen();
1159 SourceLocation ScoreLoc = Tok.getLocation();
1162 if (!AllowsTraitScore && !Score.
isUnset()) {
1164 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1165 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1166 << getOpenMPContextTraitSetName(
Set) << Score.
get();
1168 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1169 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1170 << getOpenMPContextTraitSetName(
Set) <<
"<invalid>";
1178 llvm::StringMap<SourceLocation> SeenProperties;
1180 parseOMPContextProperty(TISelector,
Set, SeenProperties);
1187void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1188 llvm::StringMap<SourceLocation> &Seen) {
1189 TISet.
Kind = TraitSet::invalid;
1191 SourceLocation NameLoc = Tok.getLocation();
1192 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_SET_LVL);
1194 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1195 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1199 TISet.
Kind = getOpenMPContextTraitSetKind(Name);
1200 if (TISet.
Kind != TraitSet::invalid) {
1201 if (checkForDuplicates(*
this, Name, NameLoc, Seen,
1202 CONTEXT_SELECTOR_SET_LVL))
1203 TISet.
Kind = TraitSet::invalid;
1208 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1210 TraitSelector SelectorForName =
1211 getOpenMPContextTraitSelectorKind(Name, TISet.
Kind);
1212 if (SelectorForName != TraitSelector::invalid) {
1213 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1214 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1215 bool AllowsTraitScore =
false;
1216 bool RequiresProperty =
false;
1217 isValidTraitSelectorForTraitSet(
1218 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1219 AllowsTraitScore, RequiresProperty);
1220 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1221 << getOpenMPContextTraitSetName(
1222 getOpenMPContextTraitSetForSelector(SelectorForName))
1223 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
1226 for (
const auto &PotentialSet :
1227 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1228 TraitSet::device, TraitSet::target_device}) {
1229 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1230 PotentialSet, TraitSelector::invalid, Name);
1231 if (PropertyForName == TraitProperty::invalid)
1233 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1234 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1235 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1236 << getOpenMPContextTraitSetName(
1237 getOpenMPContextTraitSetForProperty(PropertyForName))
1238 << getOpenMPContextTraitSelectorName(
1239 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1240 << (
"(" + Name +
")").str();
1243 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1244 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1247void Parser::parseOMPContextSelectorSet(
1248 OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1249 auto OuterBC = BraceCount;
1254 auto FinishSelectorSet = [
this, OuterBC]() ->
void {
1257 while (!
SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1258 tok::annot_pragma_openmp_end},
1261 if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1262 (void)ConsumeBrace();
1263 if (OuterBC <= BraceCount) {
1267 if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1273 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1274 << CONTEXT_SELECTOR_SET_LVL;
1277 parseOMPTraitSetKind(TISet, SeenSets);
1278 if (TISet.
Kind == TraitSet::invalid)
1279 return FinishSelectorSet();
1283 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1285 << (
"context set name \"" + getOpenMPContextTraitSetName(TISet.
Kind) +
1289 if (Tok.is(tok::l_brace)) {
1290 (void)ConsumeBrace();
1292 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1294 << (
"'=' that follows the context set name \"" +
1295 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1299 llvm::StringMap<SourceLocation> SeenSelectors;
1301 OMPTraitSelector TISelector;
1302 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1303 if (TISelector.
Kind != TraitSelector::invalid &&
1309 if (Tok.is(tok::r_brace)) {
1310 (void)ConsumeBrace();
1312 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1314 << (
"context selectors for the context set \"" +
1315 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1320bool Parser::parseOMPContextSelectors(
SourceLocation Loc, OMPTraitInfo &TI) {
1321 llvm::StringMap<SourceLocation> SeenSets;
1324 parseOMPContextSelectorSet(TISet, SeenSets);
1325 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1326 TI.
Sets.push_back(TISet);
1335 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1336 PP.EnterToken(Tok,
true);
1337 PP.EnterTokenStream(Toks,
true,
1343 FNContextRAII FnContext(*
this, Ptr);
1345 SourceLocation RLoc;
1355 getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion), RLoc,
1358 if (!AssociatedFunction.
isUsable()) {
1359 if (!Tok.is(tok::annot_pragma_openmp_end))
1363 (void)ConsumeAnnotationToken();
1367 OMPTraitInfo *ParentTI =
1368 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
1369 ASTContext &ASTCtx = Actions.getASTContext();
1371 SmallVector<Expr *, 6> AdjustNothing;
1372 SmallVector<Expr *, 6> AdjustNeedDevicePtr;
1373 SmallVector<Expr *, 6> AdjustNeedDeviceAddr;
1374 SmallVector<OMPInteropInfo, 3> AppendArgs;
1375 SourceLocation AdjustArgsLoc, AppendArgsLoc;
1378 if (Tok.is(tok::annot_pragma_openmp_end)) {
1379 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1383 bool IsError =
false;
1384 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1387 : getOpenMPClauseKind(PP.getSpelling(Tok));
1388 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1390 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1397 IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1399 case OMPC_adjust_args: {
1400 AdjustArgsLoc = Tok.getLocation();
1402 SemaOpenMP::OpenMPVarListDataTy
Data;
1403 SmallVector<Expr *> Vars;
1407 switch (
Data.ExtraModifier) {
1408 case OMPC_ADJUST_ARGS_nothing:
1409 llvm::append_range(AdjustNothing, Vars);
1411 case OMPC_ADJUST_ARGS_need_device_ptr:
1412 llvm::append_range(AdjustNeedDevicePtr, Vars);
1414 case OMPC_ADJUST_ARGS_need_device_addr:
1415 llvm::append_range(AdjustNeedDeviceAddr, Vars);
1418 llvm_unreachable(
"Unexpected 'adjust_args' clause modifier.");
1423 case OMPC_append_args:
1424 if (!AppendArgs.empty()) {
1425 Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1426 << getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion)
1427 << getOpenMPClauseName(CKind) << 0;
1431 AppendArgsLoc = Tok.getLocation();
1433 IsError = parseOpenMPAppendArgs(AppendArgs);
1437 llvm_unreachable(
"Unexpected clause for declare variant.");
1444 (void)ConsumeAnnotationToken();
1448 if (Tok.is(tok::comma))
1452 std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1453 Actions.OpenMP().checkOpenMPDeclareVariantFunction(
1454 Ptr, AssociatedFunction.
get(), TI, AppendArgs.size(),
1455 SourceRange(Loc, Tok.getLocation()));
1457 if (DeclVarData && !TI.
Sets.empty())
1458 Actions.OpenMP().ActOnOpenMPDeclareVariantDirective(
1459 DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1460 AdjustNeedDevicePtr, AdjustNeedDeviceAddr, AppendArgs, AdjustArgsLoc,
1461 AppendArgsLoc, SourceRange(Loc, Tok.getLocation()));
1464 (void)ConsumeAnnotationToken();
1467bool Parser::parseOpenMPAppendArgs(
1469 bool HasError =
false;
1472 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1473 getOpenMPClauseName(OMPC_append_args).data()))
1478 while (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"interop")) {
1481 tok::annot_pragma_openmp_end);
1482 if (IT.expectAndConsume(diag::err_expected_lparen_after,
"interop"))
1485 OMPInteropInfo InteropInfo;
1486 if (ParseOMPInteropInfo(InteropInfo, OMPC_append_args))
1489 InteropInfos.push_back(InteropInfo);
1492 if (Tok.is(tok::comma))
1495 if (!HasError && InteropInfos.empty()) {
1497 Diag(Tok.getLocation(), diag::err_omp_unexpected_append_op);
1498 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1501 HasError =
T.consumeClose() || HasError;
1505bool Parser::parseOMPDeclareVariantMatchClause(
SourceLocation Loc,
1507 OMPTraitInfo *ParentTI) {
1511 : getOpenMPClauseKind(PP.getSpelling(Tok));
1512 if (CKind != OMPC_match) {
1513 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1520 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1521 getOpenMPClauseName(OMPC_match).data()))
1525 parseOMPContextSelectors(Loc, TI);
1528 (void)
T.consumeClose();
1538 for (
const OMPTraitSet &ParentSet : ParentTI->
Sets) {
1539 bool MergedSet =
false;
1540 for (OMPTraitSet &
Set : TI.
Sets) {
1541 if (
Set.Kind != ParentSet.
Kind)
1544 for (
const OMPTraitSelector &ParentSelector : ParentSet.
Selectors) {
1545 bool MergedSelector =
false;
1546 for (OMPTraitSelector &Selector :
Set.Selectors) {
1547 if (Selector.
Kind != ParentSelector.
Kind)
1549 MergedSelector =
true;
1550 for (
const OMPTraitProperty &ParentProperty :
1552 bool MergedProperty =
false;
1566 if (Selector.
Kind == llvm::omp::TraitSelector::user_condition) {
1567 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1570 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1571 << getOpenMPContextTraitPropertyName(
1573 << getOpenMPContextTraitSelectorName(ParentSelector.
Kind)
1574 << getOpenMPContextTraitSetName(ParentSet.
Kind);
1577 if (!MergedProperty)
1578 Selector.
Properties.push_back(ParentProperty);
1581 if (!MergedSelector)
1582 Set.Selectors.push_back(ParentSelector);
1586 TI.
Sets.push_back(ParentSet);
1595 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
1596 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1599 : getOpenMPClauseKind(PP.getSpelling(Tok));
1600 if (DKind == OMPD_depobj && CKind == OMPC_update)
1601 CKind = OMPC_update_depend_objects;
1602 Actions.OpenMP().StartOpenMPClause(CKind);
1604 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
1605 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1607 SeenClauses[unsigned(CKind)] =
true;
1608 if (Clause !=
nullptr)
1609 Clauses.push_back(Clause);
1610 if (Tok.is(tok::annot_pragma_openmp_end)) {
1611 Actions.OpenMP().EndOpenMPClause();
1615 if (Tok.is(tok::comma))
1617 Actions.OpenMP().EndOpenMPClause();
1623 SmallVector<std::string, 4> Assumptions;
1624 bool SkippedClauses =
false;
1626 auto SkipBraces = [&](llvm::StringRef Spelling,
bool IssueNote) {
1628 tok::annot_pragma_openmp_end);
1629 if (
T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1632 if (IssueNote &&
T.getCloseLocation().isValid())
1633 Diag(
T.getCloseLocation(),
1634 diag::note_omp_assumption_clause_continue_here);
1640 auto MatchACMClause = [&](StringRef RawString) {
1641 llvm::StringSwitch<int> SS(RawString);
1642 unsigned ACMIdx = 0;
1643 for (
const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1644 if (ACMI.StartsWith)
1645 SS.StartsWith(ACMI.Identifier, ACMIdx++);
1647 SS.Case(ACMI.Identifier, ACMIdx++);
1649 return SS.Default(-1);
1652 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1653 IdentifierInfo *II =
nullptr;
1654 SourceLocation StartLoc = Tok.getLocation();
1656 if (Tok.isAnyIdentifier()) {
1657 II = Tok.getIdentifierInfo();
1658 Idx = MatchACMClause(II->
getName());
1662 bool NextIsLPar = Tok.is(tok::l_paren);
1665 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1666 Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1667 << llvm::omp::getOpenMPDirectiveName(DKind, OMPVersion)
1668 << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1670 SkipBraces(II ? II->
getName() :
"",
true);
1671 SkippedClauses =
true;
1674 const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1675 if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1678 SkippedClauses =
true;
1679 SkipBraces(II->
getName(),
false);
1684 Diag(Tok.getLocation(),
1685 diag::warn_omp_unknown_assumption_clause_without_args)
1687 SkipBraces(II->
getName(),
true);
1690 assert(II &&
"Expected an identifier clause!");
1691 std::string Assumption = II->
getName().str();
1692 if (ACMI.StartsWith)
1693 Assumption =
"ompx_" + Assumption.substr(ACMI.Identifier.size());
1695 Assumption =
"omp_" + Assumption;
1696 Assumptions.push_back(Assumption);
1699 Actions.OpenMP().ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions,
1704 if (Actions.OpenMP().isInOpenMPAssumeScope())
1705 Actions.OpenMP().ActOnOpenMPEndAssumesDirective();
1707 Diag(Loc, diag::err_expected_begin_assumes);
1721struct SimpleClauseData {
1724 SourceLocation LOpen;
1725 SourceLocation TypeLoc;
1726 SourceLocation RLoc;
1727 SimpleClauseData(
unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1728 SourceLocation TypeLoc, SourceLocation RLoc)
1729 :
Type(
Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1733static std::optional<SimpleClauseData>
1740 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1741 getOpenMPClauseName(Kind).data()))
1742 return std::nullopt;
1748 if (
Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::comma) &&
1749 Tok.isNot(tok::annot_pragma_openmp_end))
1754 if (!
T.consumeClose())
1755 RLoc =
T.getCloseLocation();
1757 return SimpleClauseData(
Type, Loc, LOpen,
TypeLoc, RLoc);
1760void Parser::ParseOMPDeclareTargetClauses(
1762 SourceLocation DeviceTypeLoc;
1763 bool RequiresToLinkLocalOrIndirectClause =
false;
1764 bool HasToLinkLocalOrIndirectClause =
false;
1765 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1766 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1767 bool HasIdentifier = Tok.is(tok::identifier);
1768 if (HasIdentifier) {
1770 RequiresToLinkLocalOrIndirectClause =
true;
1771 IdentifierInfo *II = Tok.getIdentifierInfo();
1772 StringRef ClauseName = II->
getName();
1773 bool IsDeviceTypeClause =
1775 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1777 bool IsIndirectClause =
getLangOpts().OpenMP >= 51 &&
1778 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1780 if (DTCI.
Indirect && IsIndirectClause) {
1781 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1782 Diag(Tok, diag::err_omp_more_one_clause)
1783 << getOpenMPDirectiveName(OMPD_declare_target, OMPVersion)
1784 << getOpenMPClauseName(OMPC_indirect) << 0;
1787 bool IsToEnterLinkOrLocalClause =
1788 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1789 assert((!IsDeviceTypeClause || !IsToEnterLinkOrLocalClause) &&
1794 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1795 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1798 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1799 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1804 if (
getLangOpts().OpenMP < 60 && ClauseName ==
"local") {
1806 ? diag::err_omp_declare_target_unexpected_clause_52
1807 : diag::err_omp_declare_target_unexpected_clause)
1815 if (!IsDeviceTypeClause && !IsIndirectClause &&
1816 DTCI.
Kind == OMPD_begin_declare_target) {
1818 ? diag::err_omp_declare_target_unexpected_clause_52
1819 : diag::err_omp_declare_target_unexpected_clause)
1820 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1824 if (!IsDeviceTypeClause && !IsToEnterLinkOrLocalClause &&
1825 !IsIndirectClause) {
1827 ? diag::err_omp_declare_target_unexpected_clause_52
1828 : diag::err_omp_declare_target_unexpected_clause)
1837 if (IsToEnterLinkOrLocalClause || IsIndirectClause)
1838 HasToLinkLocalOrIndirectClause =
true;
1840 if (IsIndirectClause) {
1841 if (!ParseOpenMPIndirectClause(DTCI,
false))
1846 if (IsDeviceTypeClause) {
1847 std::optional<SimpleClauseData> DevTypeData =
1850 if (DeviceTypeLoc.
isValid()) {
1852 Diag(DevTypeData->Loc,
1853 diag::warn_omp_more_one_device_type_clause);
1857 case OMPC_DEVICE_TYPE_any:
1858 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Any;
1860 case OMPC_DEVICE_TYPE_host:
1861 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Host;
1863 case OMPC_DEVICE_TYPE_nohost:
1864 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1867 llvm_unreachable(
"Unexpected device_type");
1869 DeviceTypeLoc = DevTypeData->Loc;
1876 if (DTCI.
Kind == OMPD_declare_target || HasIdentifier) {
1877 auto &&Callback = [
this, MT, &DTCI](CXXScopeSpec &SS,
1878 DeclarationNameInfo NameInfo) {
1879 NamedDecl *ND = Actions.OpenMP().lookupOpenMPDeclareTargetName(
1883 SemaOpenMP::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.
getLoc()};
1886 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1889 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1894 if (Tok.is(tok::l_paren)) {
1896 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1899 if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1902 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1903 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1908 if (Tok.is(tok::comma))
1912 if (DTCI.
Indirect && DTCI.
DT != OMPDeclareTargetDeclAttr::DT_Any)
1913 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1916 if (DTCI.
Kind == OMPD_declare_target && RequiresToLinkLocalOrIndirectClause &&
1917 !HasToLinkLocalOrIndirectClause)
1918 Diag(DTCI.
Loc, diag::err_omp_declare_target_missing_required_clause)
1930 if (Tok.is(tok::annot_pragma_openmp_end))
1933 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1934 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1935 << getOpenMPDirectiveName(DKind, OMPVersion);
1936 while (Tok.isNot(tok::annot_pragma_openmp_end))
1945 bool SkipUntilOpenMPEnd) {
1946 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1948 if (FoundKind == ExpectedKind) {
1950 skipUntilPragmaOpenMPEnd(ExpectedKind);
1954 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1955 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1957 Diag(BeginLoc, diag::note_matching)
1958 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind, OMPVersion) +
"'")
1960 if (SkipUntilOpenMPEnd)
1967 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1971 if (Tok.is(tok::annot_pragma_openmp_end))
1972 ConsumeAnnotationToken();
1978 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
1979 "Not an OpenMP directive!");
1982 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1987 TentativeParsingAction TPA(*
this);
1988 Loc = ConsumeAnnotationToken();
1990 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1995 Toks.push_back(Tok);
1996 while (Cnt && Tok.isNot(tok::eof)) {
1998 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
2000 else if (Tok.is(tok::annot_pragma_openmp_end))
2002 Toks.push_back(Tok);
2007 auto *LP =
new LateParsedPragma(
this, AS);
2009 getCurrentClass().LateParsedDeclarations.push_back(LP);
2014 Loc = ConsumeAnnotationToken();
2019 case OMPD_threadprivate: {
2021 DeclDirectiveListParserHelper Helper(
this, DKind);
2022 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2024 skipUntilPragmaOpenMPEnd(DKind);
2026 ConsumeAnnotationToken();
2027 return Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2028 Loc, Helper.getIdentifiers());
2032 case OMPD_groupprivate: {
2034 DeclDirectiveListParserHelper Helper(
this, DKind);
2035 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2037 skipUntilPragmaOpenMPEnd(DKind);
2039 ConsumeAnnotationToken();
2040 return Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2041 Loc, Helper.getIdentifiers());
2045 case OMPD_allocate: {
2047 DeclDirectiveListParserHelper Helper(
this, DKind);
2048 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2050 SmallVector<OMPClause *, 1> Clauses;
2051 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2052 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
2053 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2055 Tok.isAnnotation() ? OMPC_unknown
2056 : getOpenMPClauseKind(PP.getSpelling(Tok));
2057 Actions.OpenMP().StartOpenMPClause(CKind);
2058 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2059 !SeenClauses[
unsigned(CKind)]);
2060 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2062 SeenClauses[unsigned(CKind)] =
true;
2063 if (Clause !=
nullptr)
2064 Clauses.push_back(Clause);
2065 if (Tok.is(tok::annot_pragma_openmp_end)) {
2066 Actions.OpenMP().EndOpenMPClause();
2070 if (Tok.is(tok::comma))
2072 Actions.OpenMP().EndOpenMPClause();
2074 skipUntilPragmaOpenMPEnd(DKind);
2077 ConsumeAnnotationToken();
2078 return Actions.OpenMP().ActOnOpenMPAllocateDirective(
2079 Loc, Helper.getIdentifiers(), Clauses);
2083 case OMPD_requires: {
2085 SmallVector<OMPClause *, 5> Clauses;
2086 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2087 if (Tok.is(tok::annot_pragma_openmp_end)) {
2088 Diag(Tok, diag::err_omp_expected_clause)
2089 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2092 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2095 : getOpenMPClauseKind(PP.getSpelling(Tok));
2096 Actions.OpenMP().StartOpenMPClause(CKind);
2097 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
2098 !SeenClauses[
unsigned(CKind)]);
2099 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2101 SeenClauses[unsigned(CKind)] =
true;
2102 if (Clause !=
nullptr)
2103 Clauses.push_back(Clause);
2104 if (Tok.is(tok::annot_pragma_openmp_end)) {
2105 Actions.OpenMP().EndOpenMPClause();
2109 if (Tok.is(tok::comma))
2111 Actions.OpenMP().EndOpenMPClause();
2114 if (Clauses.empty()) {
2115 Diag(Tok, diag::err_omp_expected_clause)
2116 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2117 ConsumeAnnotationToken();
2120 ConsumeAnnotationToken();
2121 return Actions.OpenMP().ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2124 SmallVector<OMPClause *, 1> Clauses;
2126 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2127 Actions.OpenMP().ActOnOpenMPErrorDirective(Clauses, StartLoc,
2133 case OMPD_begin_assumes:
2136 case OMPD_end_assumes:
2139 case OMPD_declare_reduction:
2141 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2142 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2144 ConsumeAnnotationToken();
2148 case OMPD_declare_mapper: {
2150 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2152 ConsumeAnnotationToken();
2157 case OMPD_begin_declare_variant: {
2162 ConsumeAnnotationToken();
2166 case OMPD_end_declare_variant: {
2168 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2169 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2171 Diag(Loc, diag::err_expected_begin_declare_variant);
2173 ConsumeAnnotationToken();
2176 case OMPD_declare_variant:
2177 case OMPD_declare_simd: {
2183 Toks.push_back(Tok);
2185 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2186 Toks.push_back(Tok);
2189 Toks.push_back(Tok);
2193 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2194 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2196 }
else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2200 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2201 MaybeParseCXX11Attributes(Attrs);
2202 ParsingDeclSpec PDS(*
this);
2203 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2206 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2210 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2211 << (DKind == OMPD_declare_simd ? 0 : 1);
2214 if (DKind == OMPD_declare_simd)
2215 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2216 assert(DKind == OMPD_declare_variant &&
2217 "Expected declare variant directive only");
2218 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2221 case OMPD_begin_declare_target:
2222 case OMPD_declare_target: {
2224 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2225 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2226 if (DKind == OMPD_declare_target && !HasClauses &&
2228 Diag(DTLoc, diag::warn_omp_deprecated_declare_target_delimited_form);
2230 ParseOMPDeclareTargetClauses(DTCI);
2231 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2238 if (HasImplicitMappings) {
2239 Actions.OpenMP().ActOnStartOpenMPDeclareTargetContext(DTCI);
2243 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2244 llvm::SmallVector<Decl *, 4> Decls;
2246 Decls.push_back(It.first);
2247 return Actions.BuildDeclaratorGroup(Decls);
2249 case OMPD_end_declare_target: {
2250 if (!Actions.OpenMP().isInOpenMPDeclareTargetContext()) {
2251 Diag(Tok, diag::err_omp_unexpected_directive)
2252 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2255 const SemaOpenMP::DeclareTargetContextInfo &DTCI =
2256 Actions.OpenMP().ActOnOpenMPEndDeclareTargetDirective();
2257 ParseOMPEndDeclareTargetDirective(DTCI.
Kind, DKind, DTCI.
Loc);
2261 Diag(Tok, diag::err_omp_unexpected_directive)
2262 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2266 Diag(Tok, diag::err_omp_unknown_directive);
2269 switch (getDirectiveCategory(DKind)) {
2270 case Category::Executable:
2271 case Category::Meta:
2272 case Category::Subsidiary:
2273 case Category::Utility:
2274 Diag(Tok, diag::err_omp_unexpected_directive)
2275 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2277 case Category::Declarative:
2278 case Category::Informational:
2282 while (Tok.isNot(tok::annot_pragma_openmp_end))
2288StmtResult Parser::ParseOpenMPExecutableDirective(
2290 bool ReadDirectiveWithinMetadirective) {
2292 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2294 bool HasAssociatedStatement =
true;
2295 Association Assoc = getDirectiveAssociation(DKind);
2301 if (DKind != OMPD_ordered && DKind != OMPD_section &&
2302 (Assoc == Association::None || Assoc == Association::Separating)) {
2303 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2304 ParsedStmtContext()) {
2305 Diag(Tok, diag::err_omp_immediate_directive)
2306 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2307 if (DKind == OMPD_error) {
2308 SkipUntil(tok::annot_pragma_openmp_end);
2312 HasAssociatedStatement =
false;
2315 SourceLocation EndLoc;
2316 SmallVector<OMPClause *, 5> Clauses;
2317 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2318 DeclarationNameInfo DirName;
2325 bool ImplicitClauseAllowed =
false;
2326 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2328 ImplicitClauseAllowed =
true;
2332 if (DKind == OMPD_critical) {
2334 tok::annot_pragma_openmp_end);
2335 if (!
T.consumeOpen()) {
2336 if (Tok.isAnyIdentifier()) {
2338 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2341 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2345 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2347 if (Tok.isNot(tok::annot_pragma_openmp_end))
2355 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2356 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2359 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2362 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2363 while (Tok.isNot(tok::annot_pragma_openmp_end))
2367 bool HasImplicitClause =
false;
2368 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2369 HasImplicitClause =
true;
2372 PP.EnterToken(Tok,
true);
2373 PP.EnterToken(ImplicitTok,
true);
2378 : getOpenMPClauseKind(PP.getSpelling(Tok));
2379 if (DKind == OMPD_depobj && CKind == OMPC_update)
2380 CKind = OMPC_update_depend_objects;
2382 if (HasImplicitClause) {
2383 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2384 if (DKind == OMPD_flush) {
2387 assert(DKind == OMPD_depobj &&
"Expected flush or depobj directives.");
2388 CKind = OMPC_depobj;
2392 ImplicitClauseAllowed =
false;
2393 Actions.OpenMP().StartOpenMPClause(CKind);
2394 HasImplicitClause =
false;
2395 SourceLocation ClauseLoc = Tok.getLocation();
2398 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2399 SeenClauses[unsigned(CKind)] =
true;
2401 Clauses.push_back(Clause);
2404 if (Tok.is(tok::comma))
2406 Actions.OpenMP().EndOpenMPClause();
2410 if (Tok.getLocation() == ClauseLoc) {
2411 skipUntilPragmaOpenMPEnd(DKind);
2416 EndLoc = Tok.getLocation();
2418 ConsumeAnnotationToken();
2420 if (DKind == OMPD_ordered) {
2423 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2424 if (SeenClauses[
unsigned(CK)]) {
2425 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2426 ParsedStmtContext()) {
2427 Diag(Loc, diag::err_omp_immediate_directive)
2428 << getOpenMPDirectiveName(DKind, OMPVersion) << 1
2429 << getOpenMPClauseName(CK);
2431 HasAssociatedStatement =
false;
2436 if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
2437 !SeenClauses[
unsigned(OMPC_sizes)]) {
2438 Diag(Loc, diag::err_omp_required_clause)
2439 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"sizes";
2441 if (DKind == OMPD_split && !SeenClauses[
unsigned(OMPC_counts)]) {
2442 Diag(Loc, diag::err_omp_required_clause)
2443 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"counts";
2447 if (HasAssociatedStatement) {
2449 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2455 Sema::CompoundScopeRAII Scope(Actions);
2456 AssociatedStmt = ParseStatement();
2461 Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
2464 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2465 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2466 DKind == OMPD_target_exit_data) {
2467 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2468 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2469 Actions.ActOnCompoundStmt(Loc, Loc, {},
2472 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2476 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2479 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2480 OMPDirectiveScope.Exit();
2485StmtResult Parser::ParseOpenMPInformationalDirective(
2487 bool ReadDirectiveWithinMetadirective) {
2489 "Unexpected directive category");
2491 bool HasAssociatedStatement =
true;
2493 SmallVector<OMPClause *, 5> Clauses;
2494 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2495 DeclarationNameInfo DirName;
2498 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2500 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2503 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2504 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2505 while (Tok.isNot(tok::annot_pragma_openmp_end))
2512 : getOpenMPClauseKind(PP.getSpelling(Tok));
2513 Actions.OpenMP().StartOpenMPClause(CKind);
2515 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2516 SeenClauses[unsigned(CKind)] =
true;
2518 Clauses.push_back(Clause);
2520 if (Tok.is(tok::comma))
2522 Actions.OpenMP().EndOpenMPClause();
2525 SourceLocation EndLoc = Tok.getLocation();
2526 ConsumeAnnotationToken();
2529 if (HasAssociatedStatement) {
2530 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2533 Sema::CompoundScopeRAII Scope(Actions);
2534 AssociatedStmt = ParseStatement();
2537 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2541 DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2543 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2544 OMPDirectiveScope.Exit();
2549StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2550 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2551 if (!ReadDirectiveWithinMetadirective)
2552 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2553 "Not an OpenMP directive!");
2556 SourceLocation Loc = ReadDirectiveWithinMetadirective
2558 : ConsumeAnnotationToken();
2559 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2561 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2562 Diag(Tok, diag::err_omp_unknown_directive);
2568 bool IsExecutable = [&]() {
2569 if (DKind == OMPD_error)
2571 auto Res = getDirectiveCategory(DKind);
2572 return Res == Category::Executable || Res == Category::Subsidiary;
2576 Directive = ParseOpenMPExecutableDirective(
2577 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2578 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2587 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
2588 while (Tok.isNot(tok::annot_pragma_openmp_end))
2591 skipUntilPragmaOpenMPEnd(DKind);
2592 if (Tok.is(tok::annot_pragma_openmp_end))
2593 ConsumeAnnotationToken();
2596 case OMPD_metadirective: {
2598 SmallVector<VariantMatchInfo, 4> VMIs;
2603 TentativeParsingAction TPA(*
this);
2604 ASTContext &ASTContext = Actions.getASTContext();
2607 tok::annot_pragma_openmp_end);
2608 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2611 : getOpenMPClauseKind(PP.getSpelling(Tok));
2613 if (CKind == OMPC_unknown) {
2614 Diag(Tok, diag::err_omp_expected_clause) <<
"metadirective";
2616 SkipUntil(tok::annot_pragma_openmp_end);
2619 if (
getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
2620 Diag(Tok, diag::err_omp_unexpected_clause)
2621 << getOpenMPClauseName(CKind) <<
"metadirective";
2622 if (CKind == OMPC_default &&
getLangOpts().OpenMP >= 52)
2623 Diag(Tok, diag::warn_omp_default_deprecated);
2628 if (
T.expectAndConsume(diag::err_expected_lparen_after,
2629 getOpenMPClauseName(CKind).data())) {
2631 SkipUntil(tok::annot_pragma_openmp_end);
2635 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2636 if (CKind == OMPC_when) {
2638 parseOMPContextSelectors(Loc, TI);
2639 if (TI.
Sets.size() == 0) {
2640 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2646 if (Tok.is(tok::colon))
2649 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2657 while (Tok.isNot(tok::r_paren) || paren != 0) {
2658 if (Tok.is(tok::l_paren))
2660 if (Tok.is(tok::r_paren))
2662 if (Tok.is(tok::annot_pragma_openmp_end)) {
2663 Diag(Tok, diag::err_omp_expected_punc)
2664 << getOpenMPClauseName(CKind) << 0;
2671 if (Tok.is(tok::r_paren))
2674 VariantMatchInfo VMI;
2677 VMIs.push_back(VMI);
2684 [
this, Loc](StringRef ISATrait) {
2687 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2689 TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2691 ArrayRef<llvm::omp::TraitProperty>(),
2692 Actions.OpenMP().getOpenMPDeviceNum());
2695 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2702 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2704 if (Idx++ != BestIdx) {
2709 while (Tok.isNot(tok::r_paren) || paren != 0) {
2710 if (Tok.is(tok::l_paren))
2712 if (Tok.is(tok::r_paren))
2717 if (Tok.is(tok::r_paren))
2724 : getOpenMPClauseKind(PP.getSpelling(Tok));
2731 if (CKind == OMPC_when) {
2732 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2734 parseOMPContextSelectors(Loc, TI);
2742 if (Tok.is(tok::r_paren)) {
2743 SkipUntil(tok::annot_pragma_openmp_end);
2748 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2756 if (BestIdx == -1 && Idx > 0) {
2757 assert(Tok.is(tok::annot_pragma_openmp_end) &&
2758 "Expecting the end of the pragma here");
2759 ConsumeAnnotationToken();
2764 case OMPD_threadprivate: {
2766 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2767 ParsedStmtContext()) {
2768 Diag(Tok, diag::err_omp_immediate_directive)
2769 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2772 DeclDirectiveListParserHelper Helper(
this, DKind);
2773 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2775 skipUntilPragmaOpenMPEnd(DKind);
2776 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2777 Loc, Helper.getIdentifiers());
2778 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2780 SkipUntil(tok::annot_pragma_openmp_end);
2783 case OMPD_groupprivate: {
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().ActOnOpenMPGroupPrivateDirective(
2795 Loc, Helper.getIdentifiers());
2796 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2798 SkipUntil(tok::annot_pragma_openmp_end);
2801 case OMPD_allocate: {
2803 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2804 ParsedStmtContext()) {
2805 Diag(Tok, diag::err_omp_immediate_directive)
2806 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2809 DeclDirectiveListParserHelper Helper(
this, DKind);
2810 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2812 SmallVector<OMPClause *, 1> Clauses;
2813 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2814 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2815 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2817 Tok.isAnnotation() ? OMPC_unknown
2818 : getOpenMPClauseKind(PP.getSpelling(Tok));
2819 Actions.OpenMP().StartOpenMPClause(CKind);
2820 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2821 !SeenClauses[
unsigned(CKind)]);
2822 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2824 SeenClauses[unsigned(CKind)] =
true;
2825 if (Clause !=
nullptr)
2826 Clauses.push_back(Clause);
2827 if (Tok.is(tok::annot_pragma_openmp_end)) {
2828 Actions.OpenMP().EndOpenMPClause();
2832 if (Tok.is(tok::comma))
2834 Actions.OpenMP().EndOpenMPClause();
2836 skipUntilPragmaOpenMPEnd(DKind);
2838 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPAllocateDirective(
2839 Loc, Helper.getIdentifiers(), Clauses);
2840 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2842 SkipUntil(tok::annot_pragma_openmp_end);
2845 case OMPD_declare_reduction:
2848 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2849 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2851 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2853 SkipUntil(tok::annot_pragma_openmp_end);
2856 case OMPD_declare_mapper: {
2859 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2861 ConsumeAnnotationToken();
2862 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2864 SkipUntil(tok::annot_pragma_openmp_end);
2868 case OMPD_declare_target: {
2870 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2871 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2873 ParseOMPDeclareTargetClauses(DTCI);
2874 bool HasImplicitMappings =
2877 if (HasImplicitMappings) {
2878 Diag(Tok, diag::err_omp_unexpected_directive)
2879 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2880 SkipUntil(tok::annot_pragma_openmp_end);
2887 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2890 case OMPD_begin_declare_variant: {
2895 ConsumeAnnotationToken();
2899 case OMPD_end_declare_variant: {
2901 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2902 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2904 Diag(Loc, diag::err_expected_begin_declare_variant);
2905 ConsumeAnnotationToken();
2908 case OMPD_declare_simd:
2909 case OMPD_begin_declare_target:
2910 case OMPD_end_declare_target:
2912 case OMPD_declare_variant:
2913 Diag(Tok, diag::err_omp_unexpected_directive)
2914 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2915 SkipUntil(tok::annot_pragma_openmp_end);
2919 Directive = ParseOpenMPInformationalDirective(
2920 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2922 "Informational directive remains unprocessed");
2927 Diag(Tok, diag::err_omp_unknown_directive);
2928 SkipUntil(tok::annot_pragma_openmp_end);
2934bool Parser::ParseOpenMPSimpleVarList(
2938 bool AllowScopeSpecifier) {
2939 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2942 if (
T.expectAndConsume(diag::err_expected_lparen_after,
2943 getOpenMPDirectiveName(Kind, OMPVersion).data()))
2945 bool IsCorrect =
true;
2946 bool NoIdentIsFound =
true;
2949 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2953 Token PrevTok = Tok;
2954 NoIdentIsFound =
false;
2957 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2960 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2963 false,
false,
false,
2964 false,
false,
nullptr, Name)) {
2966 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2968 }
else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2969 Tok.isNot(tok::annot_pragma_openmp_end)) {
2971 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2975 << SourceRange(PrevTok.
getLocation(), PrevTokLocation);
2977 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2980 if (Tok.is(tok::comma)) {
2985 if (NoIdentIsFound) {
2986 Diag(Tok, diag::err_expected) << tok::identifier;
2991 IsCorrect = !
T.consumeClose() && IsCorrect;
2996OMPClause *Parser::ParseOpenMPSizesClause() {
2997 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
2998 SmallVector<Expr *, 4> ValExprs;
2999 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
3003 return Actions.OpenMP().ActOnOpenMPSizesClause(ValExprs, ClauseNameLoc,
3007OMPClause *Parser::ParseOpenMPCountsClause() {
3008 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3009 SmallVector<Expr *, 4> ValExprs;
3010 std::optional<unsigned> FillIdx;
3011 unsigned FillCount = 0;
3012 SourceLocation FillLoc;
3014 assert(getOpenMPClauseName(OMPC_counts) == PP.getSpelling(Tok) &&
3015 "Expected parsing to start at clause name");
3019 if (
T.consumeOpen()) {
3020 Diag(Tok, diag::err_expected) << tok::l_paren;
3025 if (Tok.is(tok::identifier) &&
3026 Tok.getIdentifierInfo()->getName() ==
"omp_fill") {
3028 FillIdx = ValExprs.size();
3030 FillLoc = Tok.getLocation();
3032 ValExprs.push_back(
nullptr);
3039 ValExprs.push_back(Val.
get());
3043 if (
T.consumeClose())
3045 OpenLoc =
T.getOpenLocation();
3046 CloseLoc =
T.getCloseLocation();
3048 return Actions.OpenMP().ActOnOpenMPCountsClause(
3049 ValExprs, ClauseNameLoc, OpenLoc, CloseLoc, FillIdx, FillLoc, FillCount);
3052OMPClause *Parser::ParseOpenMPLoopRangeClause() {
3054 SourceLocation FirstLoc, CountLoc;
3057 if (
T.consumeOpen()) {
3058 Diag(Tok, diag::err_expected) << tok::l_paren;
3062 FirstLoc = Tok.getLocation();
3069 ExpectAndConsume(tok::comma);
3071 CountLoc = Tok.getLocation();
3080 return Actions.OpenMP().ActOnOpenMPLoopRangeClause(
3081 FirstVal.
get(), CountVal.
get(), ClauseNameLoc,
T.getOpenLocation(),
3082 FirstLoc, CountLoc,
T.getCloseLocation());
3085OMPClause *Parser::ParseOpenMPPermutationClause() {
3086 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3087 SmallVector<Expr *> ArgExprs;
3088 if (ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,
3093 return Actions.OpenMP().ActOnOpenMPPermutationClause(ArgExprs, ClauseNameLoc,
3098 SourceLocation Loc = Tok.getLocation();
3103 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3105 SmallVector<SemaOpenMP::UsesAllocatorsData, 4>
Data;
3108 if (
getLangOpts().OpenMP >= 52 && Tok.is(tok::identifier) &&
3109 Tok.getIdentifierInfo()->getName() ==
"traits") {
3111 SemaOpenMP::UsesAllocatorsData &D =
Data.emplace_back();
3117 tok::annot_pragma_openmp_end);
3118 TraitParens.consumeOpen();
3121 TraitParens.consumeClose();
3125 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3131 if (Tok.isNot(tok::colon)) {
3132 Diag(Tok, diag::err_expected) << tok::colon;
3134 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3143 ? ParseCXXIdExpression()
3144 : tryParseCXXIdExpression(SS,
false);
3148 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3155 D.
LParenLoc = TraitParens.getOpenLocation();
3156 D.
RParenLoc = TraitParens.getCloseLocation();
3159 if (Tok.is(tok::comma)) {
3161 Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3164 }
else if (Tok.is(tok::semi)) {
3174 getLangOpts().CPlusPlus
3175 ? ParseCXXIdExpression()
3176 : tryParseCXXIdExpression(SS,
false);
3178 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3185 BalancedDelimiterTracker T(*this, tok::l_paren,
3186 tok::annot_pragma_openmp_end);
3188 ExprResult AllocatorTraits =
3189 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3191 if (AllocatorTraits.isInvalid()) {
3192 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3201 if (getLangOpts().OpenMP >= 52) {
3202 Diag(Loc, diag::err_omp_deprecate_old_syntax)
3203 <<
"allocator(expr)"
3204 <<
"uses_allocators"
3205 <<
"traits(expr): alloc";
3209 Diag(
Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3211 if (
Tok.
is(tok::comma))
3213 }
while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end));
3216 Loc,
T.getOpenLocation(),
T.getCloseLocation(),
Data);
3221 OMPClauseKind = CKind;
3222 OMPClause *Clause =
nullptr;
3223 bool ErrorFound =
false;
3224 bool WrongDirective =
false;
3225 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
3228 if (CKind != OMPC_unknown &&
3229 !isAllowedClauseForDirective(DKind, CKind,
getLangOpts().OpenMP)) {
3230 Diag(Tok, diag::err_omp_unexpected_clause)
3231 << getOpenMPClauseName(CKind)
3232 << getOpenMPDirectiveName(DKind, OMPVersion);
3234 WrongDirective =
true;
3239 case OMPC_num_threads:
3245 case OMPC_grainsize:
3246 case OMPC_num_tasks:
3248 case OMPC_allocator:
3251 case OMPC_novariants:
3252 case OMPC_nocontext:
3257 case OMPC_ompx_dyn_cgroup_mem:
3258 case OMPC_dyn_groupprivate:
3259 case OMPC_transparent:
3288 Diag(Tok, diag::err_omp_more_one_clause)
3289 << getOpenMPDirectiveName(DKind, OMPVersion)
3290 << getOpenMPClauseName(CKind) << 0;
3294 if (CKind == OMPC_transparent && PP.LookAhead(0).isNot(tok::l_paren)) {
3296 SourceLocation LLoc = Tok.getLocation();
3297 if (!WrongDirective)
3298 Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(
nullptr, LLoc,
3302 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3303 PP.LookAhead(0).isNot(tok::l_paren))
3304 Clause = ParseOpenMPClause(CKind, WrongDirective);
3305 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3306 CKind == OMPC_num_threads || CKind == OMPC_dyn_groupprivate)
3307 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3309 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3311 case OMPC_threadset:
3313 case OMPC_proc_bind:
3314 case OMPC_atomic_default_mem_order:
3332 Diag(Tok, diag::err_omp_more_one_clause)
3333 << getOpenMPDirectiveName(DKind, OMPVersion)
3334 << getOpenMPClauseName(CKind) << 0;
3338 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3342 case OMPC_dist_schedule:
3343 case OMPC_defaultmap:
3354 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3355 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3356 Diag(Tok, diag::err_omp_more_one_clause)
3357 << getOpenMPDirectiveName(DKind, OMPVersion)
3358 << getOpenMPClauseName(CKind) << 0;
3363 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3366 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3370 case OMPC_mergeable:
3384 case OMPC_unified_address:
3385 case OMPC_unified_shared_memory:
3386 case OMPC_reverse_offload:
3387 case OMPC_dynamic_allocators:
3396 Diag(Tok, diag::err_omp_more_one_clause)
3397 << getOpenMPDirectiveName(DKind, OMPVersion)
3398 << getOpenMPClauseName(CKind) << 0;
3402 if (CKind == OMPC_nowait && PP.LookAhead(0).is(tok::l_paren) &&
3404 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3406 Clause = ParseOpenMPClause(CKind, WrongDirective);
3408 case OMPC_self_maps:
3411 Diag(Tok, diag::err_omp_expected_clause)
3412 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3416 Diag(Tok, diag::err_omp_more_one_clause)
3417 << getOpenMPDirectiveName(DKind, OMPVersion)
3418 << getOpenMPClauseName(CKind) << 0;
3421 Clause = ParseOpenMPClause(CKind, WrongDirective);
3425 Diag(Tok, diag::err_omp_more_one_clause)
3426 << getOpenMPDirectiveName(DKind, OMPVersion)
3427 << getOpenMPClauseName(CKind) << 0;
3430 Clause = ParseOpenMPClause(CKind, WrongDirective);
3432 case OMPC_update_depend_objects:
3434 Diag(Tok, diag::err_omp_more_one_clause)
3435 << getOpenMPDirectiveName(DKind, OMPVersion)
3436 << getOpenMPClauseName(CKind) << 0;
3440 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3442 case OMPC_num_teams:
3443 case OMPC_thread_limit:
3445 Diag(Tok, diag::err_omp_more_one_clause)
3446 << getOpenMPDirectiveName(DKind, OMPVersion)
3447 << getOpenMPClauseName(CKind) << 0;
3452 case OMPC_firstprivate:
3453 case OMPC_lastprivate:
3455 case OMPC_reduction:
3456 case OMPC_task_reduction:
3457 case OMPC_in_reduction:
3461 case OMPC_copyprivate:
3467 case OMPC_use_device_ptr:
3468 case OMPC_use_device_addr:
3469 case OMPC_is_device_ptr:
3470 case OMPC_has_device_addr:
3472 case OMPC_nontemporal:
3473 case OMPC_inclusive:
3474 case OMPC_exclusive:
3478 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
3479 CKind == OMPC_depend)
3480 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3481 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3485 Diag(Tok, diag::err_omp_more_one_clause)
3486 << getOpenMPDirectiveName(DKind, OMPVersion)
3487 << getOpenMPClauseName(CKind) << 0;
3491 Clause = ParseOpenMPSizesClause();
3493 case OMPC_permutation:
3495 Diag(Tok, diag::err_omp_more_one_clause)
3496 << getOpenMPDirectiveName(DKind, OMPVersion)
3497 << getOpenMPClauseName(CKind) << 0;
3500 Clause = ParseOpenMPPermutationClause();
3504 Diag(Tok, diag::err_omp_more_one_clause)
3505 << getOpenMPDirectiveName(DKind, OMPVersion)
3506 << getOpenMPClauseName(CKind) << 0;
3509 Clause = ParseOpenMPCountsClause();
3511 case OMPC_uses_allocators:
3512 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3515 if (DKind != OMPD_interop) {
3517 Diag(Tok, diag::err_omp_more_one_clause)
3518 << getOpenMPDirectiveName(DKind, OMPVersion)
3519 << getOpenMPClauseName(CKind) << 0;
3522 Clause = ParseOpenMPClause(CKind, WrongDirective);
3528 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3530 case OMPC_device_type:
3532 skipUntilPragmaOpenMPEnd(DKind);
3534 case OMPC_threadprivate:
3535 case OMPC_groupprivate:
3538 if (!WrongDirective)
3539 Diag(Tok, diag::err_omp_unexpected_clause)
3540 << getOpenMPClauseName(CKind)
3541 << getOpenMPDirectiveName(DKind, OMPVersion);
3545 case OMPC_contains: {
3547 SourceLocation LLoc = Tok.getLocation();
3548 SourceLocation RLoc;
3549 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3554 if (DK == OMPD_unknown) {
3555 skipUntilPragmaOpenMPEnd(OMPD_assume);
3556 Diag(Tok, diag::err_omp_unexpected_clause)
3557 << getOpenMPClauseName(CKind)
3558 << getOpenMPDirectiveName(DKind, OMPVersion);
3562 DKVec.push_back(DK);
3565 Diag(Tok, diag::err_omp_unexpected_clause)
3566 << getOpenMPClauseName(CKind)
3567 << getOpenMPDirectiveName(DKind, OMPVersion);
3570 RLoc = Tok.getLocation();
3572 if (!WrongDirective)
3573 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3574 CKind, DKVec, Loc, LLoc, RLoc);
3577 case OMPC_no_openmp:
3578 case OMPC_no_openmp_routines:
3579 case OMPC_no_openmp_constructs:
3580 case OMPC_no_parallelism: {
3582 Diag(Tok, diag::err_omp_more_one_clause)
3583 << getOpenMPDirectiveName(DKind, OMPVersion)
3584 << getOpenMPClauseName(CKind) << 0;
3588 if (!WrongDirective)
3589 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3590 CKind, Loc, Tok.getLocation());
3593 case OMPC_ompx_attribute:
3594 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3596 case OMPC_ompx_bare:
3597 if (DKind == llvm::omp::Directive::OMPD_target) {
3602 Diag(Tok, diag::err_omp_unexpected_clause)
3603 << getOpenMPClauseName(CKind)
3604 << getOpenMPDirectiveName(DKind, OMPVersion);
3606 WrongDirective =
true;
3609 Diag(Tok, diag::note_ompx_bare_clause)
3610 << getOpenMPClauseName(CKind) <<
"target teams";
3611 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3612 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3613 << getOpenMPClauseName(CKind)
3614 << getOpenMPDirectiveName(DKind, OMPVersion);
3617 Clause = ParseOpenMPClause(CKind, WrongDirective);
3619 case OMPC_looprange:
3620 Clause = ParseOpenMPLoopRangeClause();
3625 return ErrorFound ?
nullptr : Clause;
3633 bool IsAddressOfOperand) {
3635 if (
T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3643 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3646 RLoc = Tok.getLocation();
3647 if (!
T.consumeClose())
3648 RLoc =
T.getCloseLocation();
3670bool Parser::ParseOpenMPIndirectClause(
3675 if (
Tok.isNot(tok::l_paren)) {
3694 if (
Ret.isInvalid())
3697 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3699 if (
Ret.isInvalid())
3707ExprResult Parser::ParseOMPInteropFrSelector() {
3710 tok::annot_pragma_openmp_end);
3711 if (FT.expectAndConsume(diag::err_expected_lparen_after,
"fr")) {
3713 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3717 SourceLocation Loc = Tok.getLocation();
3720 Arg = Actions.ActOnFinishFullExpr(Arg.
get(), Loc,
false);
3728 tok::annot_pragma_openmp_end);
3729 if (AT.expectAndConsume(diag::err_expected_lparen_after,
"attr")) {
3731 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3735 bool HasError =
false;
3738 if (Tok.is(tok::r_paren)) {
3739 Diag(Tok, diag::err_omp_interop_attr_not_string);
3742 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::r_brace) &&
3743 Tok.isNot(tok::annot_pragma_openmp_end)) {
3744 if (Tok.is(tok::string_literal)) {
3747 Attrs.push_back(S.
get());
3752 Diag(Tok, diag::err_omp_interop_attr_not_string);
3755 if (Tok.is(tok::comma))
3765 bool HasError =
false;
3766 bool IsTarget =
false;
3767 bool IsTargetSync =
false;
3769 while (Tok.is(tok::identifier)) {
3771 bool PreferTypeAllowed =
Kind == OMPC_init && InteropInfo.
Prefs.empty() &&
3772 !IsTarget && !IsTargetSync;
3773 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3778 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3781 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3783 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3784 IsTargetSync =
true;
3786 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3787 PreferTypeAllowed) {
3790 tok::annot_pragma_openmp_end);
3791 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3795 if (Tok.is(tok::r_paren)) {
3796 Diag(Tok, diag::err_omp_expected_pref_spec);
3800 while (Tok.isNot(tok::r_paren) &&
3801 Tok.isNot(tok::annot_pragma_openmp_end)) {
3803 if (Tok.is(tok::l_brace)) {
3807 Diag(Tok, diag::err_omp_prefer_type_brace_60);
3811 tok::annot_pragma_openmp_end);
3813 Expr *FrExpr =
nullptr;
3814 SmallVector<Expr *, 2> AttrExprs;
3815 bool SeenFr =
false;
3819 if (Tok.is(tok::r_brace)) {
3820 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3824 while (Tok.isNot(tok::r_brace) &&
3825 Tok.isNot(tok::annot_pragma_openmp_end)) {
3826 if (Tok.is(tok::identifier) &&
3827 Tok.getIdentifierInfo()->isStr(
"fr")) {
3829 Diag(Tok, diag::err_omp_interop_multiple_fr);
3833 {tok::comma, tok::r_brace, tok::annot_pragma_openmp_end},
3843 }
else if (Tok.is(tok::identifier) &&
3844 Tok.getIdentifierInfo()->isStr(
"attr")) {
3845 if (ParseOMPInteropAttrSelector(AttrExprs))
3850 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3853 if (Tok.is(tok::comma))
3856 if (BT.consumeClose())
3859 if (FrExpr || !AttrExprs.empty())
3860 InteropInfo.
Prefs.emplace_back(FrExpr, AttrExprs);
3865 SourceLocation Loc = Tok.getLocation();
3869 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
3872 InteropInfo.
Prefs.emplace_back(PTExpr.
get(),
3873 llvm::SmallVector<Expr *, 2>{});
3876 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3881 if (Tok.is(tok::comma))
3887 Diag(Tok, diag::err_omp_expected_interop_type);
3890 if (!Tok.is(tok::comma))
3895 if (!HasError && !IsTarget && !IsTargetSync) {
3896 Diag(Tok, diag::err_omp_expected_interop_type);
3900 if (Kind == OMPC_init) {
3901 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
3902 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3903 if (Tok.is(tok::colon))
3920 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3921 getOpenMPClauseName(Kind).data()))
3924 bool InteropError =
false;
3925 OMPInteropInfo InteropInfo;
3926 if (Kind == OMPC_init)
3927 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3930 SourceLocation VarLoc = Tok.getLocation();
3933 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3938 SourceLocation RLoc = Tok.getLocation();
3939 if (!
T.consumeClose())
3940 RLoc =
T.getCloseLocation();
3942 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3945 if (Kind == OMPC_init)
3946 return Actions.OpenMP().ActOnOpenMPInitClause(
3947 InteropVarExpr.
get(), InteropInfo, Loc,
T.getOpenLocation(), VarLoc,
3949 if (Kind == OMPC_use)
3950 return Actions.OpenMP().ActOnOpenMPUseClause(
3951 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
3953 if (Kind == OMPC_destroy)
3954 return Actions.OpenMP().ActOnOpenMPDestroyClause(
3955 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
3957 llvm_unreachable(
"Unexpected interop variable clause.");
3960OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
3964 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3965 getOpenMPClauseName(OMPC_ompx_attribute).data()))
3968 ParsedAttributes ParsedAttrs(AttrFactory);
3969 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
3972 if (
T.consumeClose())
3978 SmallVector<Attr *> Attrs;
3979 for (
const ParsedAttr &PA : ParsedAttrs) {
3980 switch (PA.getKind()) {
3981 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
3982 if (!PA.checkExactlyNumArgs(Actions, 2))
3984 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
3985 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
3988 case ParsedAttr::AT_AMDGPUWavesPerEU:
3989 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3990 !PA.checkAtMostNumArgs(Actions, 2))
3992 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
3993 PA, PA.getArgAsExpr(0),
3994 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
3997 case ParsedAttr::AT_CUDALaunchBounds:
3998 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3999 !PA.checkAtMostNumArgs(Actions, 3))
4001 if (
auto *A = Actions.CreateLaunchBoundsAttr(
4002 PA, PA.getArgAsExpr(0),
4003 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
4004 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr,
4009 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
4014 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
4015 Attrs, Loc,
T.getOpenLocation(),
T.getCloseLocation());
4021 if (!Val || ParseOnly)
4023 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
4024 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
4025 static_cast<DefaultKind
>(Val->Type) ==
4026 OMP_DEFAULT_firstprivate)) {
4027 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
4028 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
4031 : OMPC_firstprivate)
4032 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4035 return Actions.OpenMP().ActOnOpenMPSimpleClause(
4036 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
4040 SourceLocation Loc = Tok.getLocation();
4045 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
4052 SourceLocation DelimLoc;
4055 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4056 getOpenMPClauseName(Kind).data()))
4060 SmallVector<unsigned, 4> Arg;
4061 SmallVector<SourceLocation, 4> KLoc;
4062 if (Kind == OMPC_schedule) {
4063 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
4064 Arg.resize(NumberOfElements);
4065 KLoc.resize(NumberOfElements);
4070 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4073 Arg[Modifier1] = KindModifier;
4074 KLoc[Modifier1] = Tok.getLocation();
4075 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4076 Tok.isNot(tok::annot_pragma_openmp_end))
4078 if (Tok.is(tok::comma)) {
4082 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4086 KLoc[Modifier2] = Tok.getLocation();
4087 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4088 Tok.isNot(tok::annot_pragma_openmp_end))
4092 if (Tok.is(tok::colon))
4095 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
4097 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4099 Arg[ScheduleKind] = KindModifier;
4100 KLoc[ScheduleKind] = Tok.getLocation();
4101 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4102 Tok.isNot(tok::annot_pragma_openmp_end))
4104 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
4105 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
4106 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
4109 }
else if (Kind == OMPC_dist_schedule) {
4111 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4112 KLoc.push_back(Tok.getLocation());
4113 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4114 Tok.isNot(tok::annot_pragma_openmp_end))
4116 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
4118 }
else if (Kind == OMPC_default) {
4121 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4123 Arg.push_back(Modifier);
4124 KLoc.push_back(Tok.getLocation());
4125 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4126 Tok.isNot(tok::annot_pragma_openmp_end))
4129 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
4134 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4135 Arg.push_back(VariableCategory);
4136 KLoc.push_back(Tok.getLocation());
4137 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4138 Tok.isNot(tok::annot_pragma_openmp_end))
4141 Arg.push_back(OMPC_DEFAULT_VC_all);
4142 KLoc.push_back(SourceLocation());
4144 }
else if (Kind == OMPC_defaultmap) {
4147 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4153 Arg.push_back(Modifier);
4154 KLoc.push_back(Tok.getLocation());
4155 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4156 Tok.isNot(tok::annot_pragma_openmp_end))
4159 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
4160 if (Tok.is(tok::colon))
4163 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
4166 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4167 KLoc.push_back(Tok.getLocation());
4168 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4169 Tok.isNot(tok::annot_pragma_openmp_end))
4173 KLoc.push_back(SourceLocation());
4175 }
else if (Kind == OMPC_order) {
4176 enum { Modifier, OrderKind, NumberOfElements };
4177 Arg.resize(NumberOfElements);
4178 KLoc.resize(NumberOfElements);
4182 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4185 Arg[Modifier] = KindModifier;
4186 KLoc[Modifier] = Tok.getLocation();
4187 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4188 Tok.isNot(tok::annot_pragma_openmp_end))
4191 if (Tok.is(tok::colon))
4194 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
4196 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4198 Arg[OrderKind] = KindModifier;
4199 KLoc[OrderKind] = Tok.getLocation();
4200 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4201 Tok.isNot(tok::annot_pragma_openmp_end))
4203 }
else if (Kind == OMPC_device) {
4209 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4210 KLoc.push_back(Tok.getLocation());
4216 KLoc.emplace_back();
4218 }
else if (Kind == OMPC_grainsize) {
4222 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4226 Arg.push_back(Modifier);
4227 KLoc.push_back(Tok.getLocation());
4233 if (Modifier == OMPC_GRAINSIZE_strict) {
4234 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4239 KLoc.emplace_back();
4243 KLoc.emplace_back();
4245 }
else if (Kind == OMPC_dyn_groupprivate) {
4246 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4247 Arg.resize(NumberOfModifiers);
4248 KLoc.resize(NumberOfModifiers);
4252 auto ConsumeModifier = [&]() {
4253 unsigned Type = NumberOfModifiers;
4256 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4260 ParenT.consumeOpen();
4263 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4266 Diag(Tok.getLocation(), diag::err_expected)
4267 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4269 return std::make_tuple(
Type, Modifier, Loc);
4271 Type = ComplexModifier;
4272 Loc = Tok.getLocation();
4273 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4274 Tok.isNot(tok::annot_pragma_openmp_end))
4276 ParenT.consumeClose();
4279 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4281 Type = SimpleModifier;
4282 Loc = Tok.getLocation();
4283 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4284 Tok.isNot(tok::annot_pragma_openmp_end))
4288 return std::make_tuple(
Type, Modifier, Loc);
4291 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4292 SourceLocation Loc) {
4293 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4294 if (!KLoc[
Type].isValid()) {
4295 Arg[
Type] = Modifier;
4298 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4305 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4306 if (Type1 < NumberOfModifiers) {
4307 SaveModifier(Type1, Mod1, Loc1);
4308 if (Tok.is(tok::comma)) {
4311 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4312 if (Type2 < NumberOfModifiers)
4313 SaveModifier(Type2, Mod2, Loc2);
4316 if (Tok.is(tok::colon))
4319 Diag(Tok, diag::warn_pragma_expected_colon)
4320 <<
"dyn_groupprivate modifier";
4322 }
else if (Kind == OMPC_num_tasks) {
4326 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4330 Arg.push_back(Modifier);
4331 KLoc.push_back(Tok.getLocation());
4337 if (Modifier == OMPC_NUMTASKS_strict) {
4338 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4343 KLoc.emplace_back();
4347 KLoc.emplace_back();
4349 }
else if (Kind == OMPC_num_threads) {
4353 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4357 Arg.push_back(Modifier);
4358 KLoc.push_back(Tok.getLocation());
4364 if (Modifier == OMPC_NUMTHREADS_strict) {
4365 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4370 KLoc.emplace_back();
4374 KLoc.emplace_back();
4377 assert(Kind == OMPC_if);
4378 KLoc.push_back(Tok.getLocation());
4379 TentativeParsingAction TPA(*
this);
4381 Arg.push_back(
static_cast<unsigned>(DK));
4382 if (DK != OMPD_unknown) {
4384 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4389 Arg.back() = unsigned(OMPD_unknown);
4396 bool NeedAnExpression =
4398 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
Kind == OMPC_if ||
4399 Kind == OMPC_device ||
Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4400 Kind == OMPC_num_threads ||
Kind == OMPC_dyn_groupprivate;
4401 if (NeedAnExpression) {
4402 SourceLocation ELoc = Tok.getLocation();
4408 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4412 SourceLocation RLoc = Tok.getLocation();
4413 if (!
T.consumeClose())
4414 RLoc =
T.getCloseLocation();
4416 if (NeedAnExpression && Val.
isInvalid())
4419 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4420 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4421 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4422 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4423 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4426 : OMPC_firstprivate)
4427 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4433 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4434 Kind, Arg, Val.
get(), Loc,
T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4439 if (ReductionIdScopeSpec.
isEmpty()) {
4477 ReductionIdScopeSpec,
nullptr,
4481 false,
nullptr, ReductionId);
4488 if (!
Tok.is(tok::identifier))
4495 return TypeModifier;
4501 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4502 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4508 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4512 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4513 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4514 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4518 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4520 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4523 return T.consumeClose();
4529 bool HasMapType =
false;
4531 StringRef PreMapName =
"";
4535 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4536 TypeModifier == OMPC_MAP_MODIFIER_close ||
4537 TypeModifier == OMPC_MAP_MODIFIER_present ||
4538 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4539 Data.MapTypeModifiers.push_back(TypeModifier);
4540 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4541 if (PP.LookAhead(0).isNot(tok::comma) &&
4542 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4543 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4544 <<
"map type modifier";
4546 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4547 Data.MapTypeModifiers.push_back(TypeModifier);
4548 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4552 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4554 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4555 <<
"map type modifier";
4560 Data.ExtraModifier = MapKind;
4562 PreMapLoc = Tok.getLocation();
4563 PreMapName = Tok.getIdentifierInfo()->getName();
4565 Diag(Tok, diag::err_omp_more_one_map_type);
4566 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4570 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4571 Data.MapTypeModifiers.push_back(TypeModifier);
4572 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4573 if (PP.LookAhead(0).isNot(tok::comma) &&
4574 PP.LookAhead(0).isNot(tok::colon))
4575 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4576 <<
"map type modifier";
4578 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4588 if (Tok.is(tok::comma)) {
4589 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4594 if (PP.LookAhead(0).is(tok::colon)) {
4602 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4613 if (!Tok.is(tok::colon)) {
4614 Diag(Tok, diag::err_omp_unknown_map_type);
4628 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4633 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4634 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4635 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4645 if (
Tok.is(tok::colon)) {
4646 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4651 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4655ExprResult Parser::ParseOpenMPIteratorsExpr() {
4656 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4657 "Expected 'iterator' token.");
4661 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4664 SourceLocation LLoc =
T.getOpenLocation();
4665 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4666 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4669 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4676 IteratorType = TR.
get();
4680 IdentifierInfo *II =
nullptr;
4681 SourceLocation IdLoc;
4682 if (Tok.is(tok::identifier)) {
4683 II = Tok.getIdentifierInfo();
4686 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4690 SourceLocation AssignLoc;
4691 if (Tok.is(tok::equal))
4694 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4699 SourceLocation Loc = Tok.getLocation();
4702 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4705 SourceLocation ColonLoc;
4706 if (Tok.is(tok::colon))
4710 Loc = Tok.getLocation();
4713 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4716 SourceLocation SecColonLoc;
4719 if (Tok.is(tok::colon)) {
4723 Loc = Tok.getLocation();
4726 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4731 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4732 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4733 if (Tok.is(tok::comma))
4736 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4739 D.
Type = IteratorType;
4749 SourceLocation RLoc = Tok.getLocation();
4750 if (!
T.consumeClose())
4751 RLoc =
T.getCloseLocation();
4753 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4762 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4765 if (Tok.is(tok::identifier) &&
4766 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4768 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4769 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4770 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4771 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4772 Data.ExtraModifier != OMPC_DEPEND_inout)
4773 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4775 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4776 ? OMPC_DEPEND_outallmemory
4777 : OMPC_DEPEND_inoutallmemory;
4793 Data.DepModOrTailExpr = Tail.
get();
4795 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4796 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4814 bool AllocatorSeen =
false;
4815 bool AlignSeen =
false;
4834 if (
Tok.is(tok::l_paren)) {
4835 switch (CurrentModifier) {
4836 case OMPC_ALLOCATE_allocator: {
4837 if (AllocatorSeen) {
4838 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4840 << getOpenMPClauseName(Kind);
4842 Data.AllocClauseModifiers.push_back(CurrentModifier);
4843 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4846 tok::annot_pragma_openmp_end);
4850 AllocatorSeen =
true;
4853 case OMPC_ALLOCATE_align: {
4855 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4857 << getOpenMPClauseName(Kind);
4859 Data.AllocClauseModifiers.push_back(CurrentModifier);
4860 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4864 Data.AllocateAlignment = Val.
get();
4869 llvm_unreachable(
"Unexpected allocate modifier");
4872 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4874 if (
Tok.isNot(tok::comma))
4877 CurrentModifierLoc =
Tok.getLocation();
4882 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4885 }
while (!AllocatorSeen || !AlignSeen);
4894 bool InvalidReductionId =
false;
4895 bool IsInvalidMapperModifier =
false;
4899 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4900 getOpenMPClauseName(Kind).data()))
4903 bool HasIterator =
false;
4904 bool InvalidIterator =
false;
4905 bool NeedRParenForLinear =
false;
4907 tok::annot_pragma_openmp_end);
4909 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4910 Kind == OMPC_in_reduction) {
4912 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4913 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4916 Data.ExtraModifier =
4918 Data.ExtraModifierLoc = Tok.getLocation();
4920 assert(Tok.is(tok::comma) &&
"Expected comma.");
4924 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4925 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4931 if (Tok.is(tok::kw_private)) {
4932 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4933 Data.OriginalSharingModifierLoc = Tok.getLocation();
4935 }
else if (Tok.is(tok::identifier) &&
4936 (PP.getSpelling(Tok) ==
"shared" ||
4937 PP.getSpelling(Tok) ==
"default")) {
4938 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4939 Data.OriginalSharingModifierLoc = Tok.getLocation();
4942 Diag(Tok.getLocation(), diag::err_expected)
4943 <<
"'private or shared or default'";
4948 if (!Tok.is(tok::comma)) {
4949 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4956 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4961 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4962 if (InvalidReductionId) {
4963 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4966 if (Tok.is(tok::colon))
4969 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4970 if (!InvalidReductionId)
4971 Data.ReductionOrMapperId =
4972 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4973 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4975 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4984 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4985 Data.DepModOrTailExpr = IteratorRes.
get();
4987 ExpectAndConsume(tok::comma);
4993 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4995 Data.ExtraModifierLoc = Tok.getLocation();
4997 (Kind == OMPC_doacross &&
4999 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5004 if (DKind == OMPD_ordered && Kind == OMPC_depend &&
5005 Data.ExtraModifier == OMPC_DEPEND_source) {
5011 if (Tok.is(tok::colon)) {
5013 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
5014 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
5015 : diag::warn_pragma_expected_colon)
5016 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
5018 if (Kind == OMPC_doacross) {
5019 if (Tok.is(tok::identifier) &&
5020 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
5021 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
5022 ? OMPC_DOACROSS_source_omp_cur_iteration
5023 : OMPC_DOACROSS_sink_omp_cur_iteration;
5026 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
5027 if (Tok.isNot(tok::minus)) {
5028 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5029 << getOpenMPClauseName(Kind) << 0 << 0;
5036 if (Tok.isNot(tok::numeric_constant) ||
5037 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
5038 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
5039 << getOpenMPClauseName(Kind) << 0 << 0;
5045 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
5046 if (Tok.isNot(tok::r_paren)) {
5047 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5048 << getOpenMPClauseName(Kind) << 1 << 1;
5054 if (Kind == OMPC_doacross &&
5055 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
5056 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
5057 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
5063 }
else if (Kind == OMPC_linear) {
5065 Data.ExtraModifier = OMPC_LINEAR_val;
5066 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
5067 Data.ExtraModifier =
5071 NeedRParenForLinear =
true;
5073 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
5074 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
5075 <<
"linear(list: [linear-modifier,] step(step-size))";
5077 }
else if (Kind == OMPC_lastprivate) {
5084 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
5085 Data.ExtraModifier =
5087 Data.ExtraModifierLoc = Tok.getLocation();
5089 assert(Tok.is(tok::colon) &&
"Expected colon.");
5092 }
else if (Kind == OMPC_map) {
5094 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
5097 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
5098 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
5099 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
5100 Data.IteratorExpr = IteratorRes.
get();
5102 ExpectAndConsume(tok::comma);
5104 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
5107 InvalidIterator =
true;
5117 Data.ExtraModifierLoc = Tok.getLocation();
5120 TentativeParsingAction TPA(*
this);
5121 bool ColonPresent =
false;
5122 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5124 if (Tok.is(tok::colon))
5125 ColonPresent =
true;
5132 Diag(Tok, diag::err_omp_map_modifier_specification_list);
5134 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
5140 Data.ExtraModifier = OMPC_MAP_tofrom;
5142 if (DKind == OMPD_target_enter_data)
5143 Data.ExtraModifier = OMPC_MAP_to;
5144 else if (DKind == OMPD_target_exit_data)
5145 Data.ExtraModifier = OMPC_MAP_from;
5147 Data.IsMapTypeImplicit =
true;
5150 if (Tok.is(tok::colon))
5152 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
5153 while (Tok.is(tok::identifier)) {
5158 Data.MotionModifiers.push_back(Modifier);
5159 Data.MotionModifiersLoc.push_back(Tok.getLocation());
5160 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
5162 Tail = ParseOpenMPIteratorsExpr();
5163 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
5166 Data.IteratorExpr = Tail.
get();
5169 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
5171 if (IsInvalidMapperModifier)
5179 if (Tok.is(tok::comma))
5183 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
5184 if (!IsInvalidMapperModifier) {
5186 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
5188 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
5190 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5198 }
else if (Kind == OMPC_allocate ||
5199 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
5200 PP.getSpelling(Tok) ==
"iterator")) {
5204 TentativeParsingAction TPA(*
this);
5209 if (Kind == OMPC_allocate) {
5214 Tail = ParseOpenMPIteratorsExpr();
5216 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
5219 if (Tok.is(tok::colon)) {
5226 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5227 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5229 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5236 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5239 }
else if (Kind == OMPC_adjust_args) {
5243 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5245 Data.ExtraModifierLoc = Tok.getLocation();
5247 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5252 if (Tok.is(tok::colon))
5253 Data.ColonLoc = Tok.getLocation();
5257 if (Tok.is(tok::l_paren)) {
5260 if (Tok.is(tok::identifier)) {
5261 std::string Modifier = PP.getSpelling(Tok);
5262 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5263 Data.NeedDevicePtrModifier =
5264 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5265 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5267 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5268 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5273 if (Tok.is(tok::r_paren)) {
5274 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5277 Diag(Tok, diag::err_expected) << tok::r_paren;
5278 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5287 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5290 }
else if (Kind == OMPC_use_device_ptr) {
5294 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5298 Data.ExtraModifier = FallbackModifier;
5299 Data.ExtraModifierLoc = Tok.getLocation();
5301 if (Tok.is(tok::colon))
5304 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5307 }
else if (Kind == OMPC_num_teams || Kind == OMPC_thread_limit) {
5311 Data.ExtraModifierArray[0] =
Data.ExtraModifierArray[1] =
5316 bool CanParseLowerBoundModifier = (Kind == OMPC_num_teams);
5317 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"dims") &&
5324 Data.ExtraModifierArray[Mod] =
5325 Kind == OMPC_num_teams ?
static_cast<int>(OMPC_NUMTEAMS_dims)
5326 :
static_cast<int>(OMPC_THREADLIMIT_dims);
5327 Data.ExtraModifierExprArray[Mod] = ExprR.
get();
5328 Data.ExtraModifierLocArray[Mod] = TLoc;
5332 if (Tok.is(tok::colon)) {
5335 CanParseLowerBoundModifier =
false;
5336 }
else if (CanParseLowerBoundModifier && Tok.is(tok::comma)) {
5341 Diag(Tok, diag::err_modifier_expected_colon)
5342 << getOpenMPClauseName(Kind);
5344 Data.RLoc = Tok.getLocation();
5345 if (!
T.consumeClose())
5346 Data.RLoc =
T.getCloseLocation();
5352 if (CanParseLowerBoundModifier) {
5353 TentativeParsingAction TPA(*
this);
5358 Data.RLoc = Tok.getLocation();
5359 if (!
T.consumeClose())
5360 Data.RLoc =
T.getCloseLocation();
5365 if (Tok.is(tok::colon)) {
5368 Data.ExtraModifierArray[Mod] = OMPC_NUMTEAMS_lower_bound;
5369 Data.ExtraModifierExprArray[Mod] = FirstExpr.
get();
5370 Data.ExtraModifierLocArray[Mod] = TLoc;
5381 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5382 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5383 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5384 (Kind == OMPC_reduction && !InvalidReductionId) ||
5388 (Kind == OMPC_adjust_args &&
5390 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5391 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5392 Tok.isNot(tok::annot_pragma_openmp_end))) {
5399 Vars.push_back(VarExpr.
get());
5401 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5406 IsComma = Tok.is(tok::comma);
5409 else if (Tok.isNot(tok::r_paren) &&
5410 Tok.isNot(tok::annot_pragma_openmp_end) &&
5411 (!MayHaveTail || Tok.isNot(tok::colon))) {
5412 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
5413 Diag(Tok, diag::err_omp_expected_punc)
5414 << ((Kind == OMPC_flush)
5415 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5416 : getOpenMPClauseName(Kind))
5417 << (Kind == OMPC_flush);
5422 if (NeedRParenForLinear)
5426 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5427 bool StepFound =
false;
5428 bool ModifierFound =
false;
5430 Data.ColonLoc = Tok.getLocation();
5433 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5434 bool Malformed =
false;
5435 while (Tok.isNot(tok::r_paren)) {
5436 if (Tok.is(tok::identifier)) {
5441 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5444 if (LinKind == OMPC_LINEAR_step) {
5446 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5449 tok::annot_pragma_openmp_end);
5453 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5458 Data.StepModifierLoc = StepModifierLoc;
5462 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5464 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5466 Data.ExtraModifier = LinKind;
5468 ModifierFound =
true;
5473 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5482 if (Tok.is(tok::comma))
5484 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5487 if (!Malformed && !StepFound && !ModifierFound)
5488 Diag(ELoc, diag::err_expected_expression);
5492 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5495 Data.DepModOrTailExpr = Tail.
get();
5497 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5503 Data.RLoc = Tok.getLocation();
5504 if (!
T.consumeClose())
5505 Data.RLoc =
T.getCloseLocation();
5509 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5511 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5512 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5539 "Expected parsing to start at clause name");
5544 if (
T.consumeOpen()) {
5545 Diag(
Tok, diag::err_expected) << tok::l_paren;
5558 Exprs.push_back(Val.
get());
5561 bool Result =
T.consumeClose();
5562 OpenLoc =
T.getOpenLocation();
5563 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()
The name of a declaration.
bool isEmpty() const
Evaluates true when this declaration name is empty.
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
This represents a decl that may have a name.
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
This is a basic class for representing single OpenMP clause.
static const ParsedAttributesView & none()
ParsedAttributes - A collection of parsed attributes.
Introduces zero or more scopes for parsing.
void Enter(unsigned ScopeFlags)
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, SmallVectorImpl< Expr * > &Vars, SemaOpenMP::OpenMPVarListDataTy &Data)
Parses clauses with list.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Preprocessor & getPreprocessor() const
bool parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data)
Parse map-type-modifiers in map clause.
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
ParseStringLiteralExpression - This handles the various token types that form string literals,...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
bool parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data)
Parses the mapper modifier in map, to, and from clauses.
friend class ParsingOpenMPDirectiveRAII
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
friend class ColonProtectionRAIIObject
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
const Token & getCurToken() const
void ExitScope()
ExitScope - Pop a scope off the scope stack.
ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc, bool IsAddressOfOperand=false)
Parses simple expression in parens for single-expression clauses of OpenMP constructs.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data, const LangOptions &LangOpts)
Parses a reserved locator like 'omp_all_memory'.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D)
Re-enter a possible template scope, creating as many template parameter scopes as necessary.
bool ParseOpenMPDeclareBeginVariantDirective(SourceLocation Loc)
Parses 'omp begin declare variant' directive.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
The collection of all-type qualifiers we support.
Represents a struct/union/class.
@ OpenMPDirectiveScope
This is the scope of OpenMP executable directive.
@ CompoundStmtScope
This is a compound statement scope.
@ OpenMPSimdDirectiveScope
This is the scope of some OpenMP simd directive.
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ OpenMPLoopDirectiveScope
This is the scope of some OpenMP loop directive.
@ DeclScope
This is a scope that can contain a declaration.
Smart pointer class that efficiently represents Objective-C method names.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
void ActOnExitFunctionContext()
void ActOnReenterFunctionContext(Scope *S, Decl *D)
Push the parameters of D, which must be a function, into scope.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
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.
The JSON file list parser is used to communicate input to InstallAPI.
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.