27#include "llvm/ADT/SmallBitVector.h"
28#include "llvm/ADT/StringSwitch.h"
29#include "llvm/Frontend/OpenMP/OMPAssume.h"
30#include "llvm/Frontend/OpenMP/OMPContext.h"
34using namespace llvm::omp;
41enum OpenMPDirectiveKindEx {
42 OMPD_cancellation = llvm::omp::Directive_enumSize + 1,
54 OMPD_distribute_parallel,
55 OMPD_teams_distribute_parallel,
56 OMPD_target_teams_distribute_parallel,
66struct OpenMPDirectiveKindExWrapper {
69 bool operator==(OpenMPDirectiveKindExWrapper
V)
const {
72 bool operator!=(OpenMPDirectiveKindExWrapper
V)
const {
83class DeclDirectiveListParserHelper final {
92 ExprResult Res =
P->getActions().OpenMP().ActOnOpenMPIdExpression(
93 P->getCurScope(), SS, NameInfo, Kind);
95 Identifiers.push_back(Res.
get());
104 OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);
105 if (DKind != OMPD_unknown)
108 return llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)
109 .Case(
"cancellation", OMPD_cancellation)
110 .Case(
"data", OMPD_data)
111 .Case(
"declare", OMPD_declare)
112 .Case(
"end", OMPD_end)
113 .Case(
"enter", OMPD_enter)
114 .Case(
"exit", OMPD_exit)
115 .Case(
"point", OMPD_point)
116 .Case(
"reduction", OMPD_reduction)
117 .Case(
"update", OMPD_update)
118 .Case(
"mapper", OMPD_mapper)
119 .Case(
"variant", OMPD_variant)
120 .Case(
"begin", OMPD_begin)
121 .Default(OMPD_unknown);
128 static const OpenMPDirectiveKindExWrapper F[][3] = {
129 {OMPD_begin, OMPD_declare, OMPD_begin_declare},
130 {OMPD_begin, OMPD_assumes, OMPD_begin_assumes},
131 {OMPD_end, OMPD_declare, OMPD_end_declare},
132 {OMPD_end, OMPD_assumes, OMPD_end_assumes},
133 {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
134 {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
135 {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
136 {OMPD_declare, OMPD_simd, OMPD_declare_simd},
137 {OMPD_declare, OMPD_target, OMPD_declare_target},
138 {OMPD_declare, OMPD_variant, OMPD_declare_variant},
139 {OMPD_begin_declare, OMPD_target, OMPD_begin_declare_target},
140 {OMPD_begin_declare, OMPD_variant, OMPD_begin_declare_variant},
141 {OMPD_end_declare, OMPD_variant, OMPD_end_declare_variant},
142 {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
143 {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
144 {OMPD_distribute_parallel_for, OMPD_simd,
145 OMPD_distribute_parallel_for_simd},
146 {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
147 {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
148 {OMPD_target, OMPD_data, OMPD_target_data},
149 {OMPD_target, OMPD_enter, OMPD_target_enter},
150 {OMPD_target, OMPD_exit, OMPD_target_exit},
151 {OMPD_target, OMPD_update, OMPD_target_update},
152 {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
153 {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
154 {OMPD_for, OMPD_simd, OMPD_for_simd},
155 {OMPD_parallel, OMPD_for, OMPD_parallel_for},
156 {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
157 {OMPD_parallel, OMPD_loop, OMPD_parallel_loop},
158 {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
159 {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
160 {OMPD_target, OMPD_parallel, OMPD_target_parallel},
161 {OMPD_target, OMPD_simd, OMPD_target_simd},
162 {OMPD_target_parallel, OMPD_loop, OMPD_target_parallel_loop},
163 {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
164 {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
165 {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
166 {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
167 {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
168 {OMPD_teams_distribute_parallel, OMPD_for,
169 OMPD_teams_distribute_parallel_for},
170 {OMPD_teams_distribute_parallel_for, OMPD_simd,
171 OMPD_teams_distribute_parallel_for_simd},
172 {OMPD_teams, OMPD_loop, OMPD_teams_loop},
173 {OMPD_target, OMPD_teams, OMPD_target_teams},
174 {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
175 {OMPD_target_teams, OMPD_loop, OMPD_target_teams_loop},
176 {OMPD_target_teams_distribute, OMPD_parallel,
177 OMPD_target_teams_distribute_parallel},
178 {OMPD_target_teams_distribute, OMPD_simd,
179 OMPD_target_teams_distribute_simd},
180 {OMPD_target_teams_distribute_parallel, OMPD_for,
181 OMPD_target_teams_distribute_parallel_for},
182 {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
183 OMPD_target_teams_distribute_parallel_for_simd},
184 {OMPD_master, OMPD_taskloop, OMPD_master_taskloop},
185 {OMPD_masked, OMPD_taskloop, OMPD_masked_taskloop},
186 {OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},
187 {OMPD_masked_taskloop, OMPD_simd, OMPD_masked_taskloop_simd},
188 {OMPD_parallel, OMPD_master, OMPD_parallel_master},
189 {OMPD_parallel, OMPD_masked, OMPD_parallel_masked},
190 {OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},
191 {OMPD_parallel_masked, OMPD_taskloop, OMPD_parallel_masked_taskloop},
192 {OMPD_parallel_master_taskloop, OMPD_simd,
193 OMPD_parallel_master_taskloop_simd},
194 {OMPD_parallel_masked_taskloop, OMPD_simd,
195 OMPD_parallel_masked_taskloop_simd}};
196 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
197 Token Tok =
P.getCurToken();
198 OpenMPDirectiveKindExWrapper DKind =
200 ?
static_cast<unsigned>(OMPD_unknown)
202 if (DKind == OMPD_unknown)
205 for (
const auto &I : F) {
209 Tok =
P.getPreprocessor().LookAhead(0);
210 OpenMPDirectiveKindExWrapper SDKind =
212 ?
static_cast<unsigned>(OMPD_unknown)
214 if (SDKind == OMPD_unknown)
217 if (SDKind == I[1]) {
222 return unsigned(DKind) < llvm::omp::Directive_enumSize
228 Token Tok =
P.getCurToken();
229 Sema &Actions =
P.getActions();
232 bool WithOperator =
false;
233 if (Tok.
is(tok::kw_operator)) {
235 Tok =
P.getCurToken();
263 case tok::identifier:
268 P.Diag(Tok.
getLocation(), diag::err_omp_expected_reduction_identifier);
269 P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
276 : DeclNames.getCXXOperatorName(OOK);
293 if (
T.expectAndConsume(
294 diag::err_expected_lparen_after,
295 getOpenMPDirectiveName(OMPD_declare_reduction).data())) {
301 if (Name.isEmpty() && Tok.
is(tok::annot_pragma_openmp_end))
305 bool IsCorrect = !ExpectAndConsume(tok::colon);
307 if (!IsCorrect && Tok.
is(tok::annot_pragma_openmp_end))
310 IsCorrect = IsCorrect && !Name.isEmpty();
312 if (Tok.
is(tok::colon) || Tok.
is(tok::annot_pragma_openmp_end)) {
317 if (!IsCorrect && Tok.
is(tok::annot_pragma_openmp_end))
329 if (!ReductionType.
isNull()) {
330 ReductionTypes.push_back(
334 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
338 if (Tok.
is(tok::colon) || Tok.
is(tok::annot_pragma_openmp_end))
342 if (ExpectAndConsume(tok::comma)) {
344 if (Tok.
is(tok::annot_pragma_openmp_end)) {
349 }
while (Tok.
isNot(tok::annot_pragma_openmp_end));
351 if (ReductionTypes.empty()) {
356 if (!IsCorrect && Tok.
is(tok::annot_pragma_openmp_end))
360 if (ExpectAndConsume(tok::colon))
363 if (Tok.
is(tok::annot_pragma_openmp_end)) {
375 unsigned I = 0,
E = ReductionTypes.size();
376 for (
Decl *
D : DRD.get()) {
377 TentativeParsingAction TPA(*
this);
386 D, CombinerResult.
get());
389 Tok.
isNot(tok::annot_pragma_openmp_end)) {
394 IsCorrect = !
T.consumeClose() && IsCorrect && CombinerResult.
isUsable();
396 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
398 if (Tok.
is(tok::identifier) &&
409 tok::annot_pragma_openmp_end);
411 !
T.expectAndConsume(diag::err_expected_lparen_after,
"initializer") &&
413 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
422 if (Tok.
is(tok::identifier) &&
425 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
432 D, InitializerResult.
get(), OmpPrivParm);
434 Tok.
isNot(tok::annot_pragma_openmp_end)) {
440 !
T.consumeClose() && IsCorrect && !InitializerResult.
isInvalid();
456void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
459 if (isTokenEqualOrEqualTypo()) {
462 if (Tok.
is(tok::code_completion)) {
473 if (
Init.isInvalid()) {
480 }
else if (Tok.
is(tok::l_paren)) {
488 auto RunSignatureHelp = [
this, OmpPrivParm, LParLoc, &Exprs]() {
492 OmpPrivParm->
getLocation(), Exprs, LParLoc,
false);
493 CalledSignatureHelp =
true;
494 return PreferredType;
496 if (ParseExpressionList(Exprs, [&] {
497 PreferredType.enterFunctionArgument(Tok.
getLocation(),
507 if (!
T.consumeClose())
508 RLoc =
T.getCloseLocation();
517 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
521 if (
Init.isInvalid()) {
542 bool IsCorrect =
true;
545 if (
T.expectAndConsume(diag::err_expected_lparen_after,
546 getOpenMPDirectiveName(OMPD_declare_mapper).data())) {
555 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::kw_default)) {
563 ExpectAndConsume(tok::colon);
570 if (!IsCorrect && Tok.
is(tok::annot_pragma_openmp_end))
589 IsCorrect &= !
T.consumeClose();
600 ParseScope OMPDirectiveScope(
this, ScopeFlags);
611 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
617 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
619 Clauses.push_back(Clause);
623 if (Tok.
is(tok::comma))
627 if (Clauses.empty()) {
628 Diag(Tok, diag::err_omp_expected_clause)
629 << getOpenMPDirectiveName(OMPD_declare_mapper);
635 OMPDirectiveScope.Exit();
649 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
651 ParseSpecifierQualifierList(DS, AS, DSC);
656 ParseDeclarator(DeclaratorInfo);
657 Range = DeclaratorInfo.getSourceRange();
658 if (DeclaratorInfo.getIdentifier() ==
nullptr) {
674class FNContextRAII final {
678 bool HasFunScope =
false;
679 FNContextRAII() =
delete;
680 FNContextRAII(
const FNContextRAII &) =
delete;
681 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
688 Sema &Actions =
P.getActions();
696 P.ReenterTemplateScopes(Scopes,
D);
708 P.getActions().ActOnExitFunctionContext();
727 const Token &Tok =
P.getCurToken();
728 bool IsError =
false;
729 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
730 if (Tok.
isNot(tok::identifier))
732 OMPDeclareSimdDeclAttr::BranchStateTy Out;
734 StringRef ClauseName = II->
getName();
736 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
737 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
738 P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
740 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
746 }
else if (ClauseName ==
"simdlen") {
748 P.Diag(Tok, diag::err_omp_more_one_clause)
749 << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
754 SimdLen =
P.ParseOpenMPParensExpr(ClauseName, RLoc);
759 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
760 CKind == OMPC_linear) {
763 if (CKind == OMPC_aligned) {
765 }
else if (CKind == OMPC_linear) {
766 Data.ExtraModifier = OMPC_LINEAR_val;
771 if (
P.ParseOpenMPVarList(OMPD_declare_simd,
772 getOpenMPClauseKind(ClauseName), *Vars,
Data))
774 if (CKind == OMPC_aligned) {
775 Alignments.append(Aligneds.size() - Alignments.size(),
776 Data.DepModOrTailExpr);
777 }
else if (CKind == OMPC_linear) {
778 assert(0 <=
Data.ExtraModifier &&
780 "Unexpected linear modifier.");
781 if (
P.getActions().OpenMP().CheckOpenMPLinearModifier(
783 Data.ExtraModifierLoc))
784 Data.ExtraModifier = OMPC_LINEAR_val;
785 LinModifiers.append(Linears.size() - LinModifiers.size(),
787 Steps.append(Linears.size() - Steps.size(),
Data.DepModOrTailExpr);
794 if (Tok.
is(tok::comma))
805 PP.EnterTokenStream(Toks,
true,
811 FNContextRAII FnContext(*
this, Ptr);
812 OMPDeclareSimdDeclAttr::BranchStateTy BS =
813 OMPDeclareSimdDeclAttr::BS_Undefined;
823 Alignments, Linears, LinModifiers, Steps);
824 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
830 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
838 CONTEXT_SELECTOR_SET_LVL = 0,
839 CONTEXT_SELECTOR_LVL = 1,
840 CONTEXT_TRAIT_LVL = 2,
843static StringRef stringLiteralParser(
Parser &
P) {
844 ExprResult Res =
P.ParseStringLiteralExpression(
true);
848static StringRef getNameFromIdOrString(
Parser &
P,
Token &Tok,
850 if (Tok.
is(tok::identifier) || Tok.
is(tok::kw_for)) {
852 StringRef Name =
P.getPreprocessor().getSpelling(Tok, Buffer);
853 (void)
P.ConsumeToken();
858 return stringLiteralParser(
P);
861 diag::warn_omp_declare_variant_string_literal_or_identifier)
866static bool checkForDuplicates(
Parser &
P, StringRef Name,
868 llvm::StringMap<SourceLocation> &Seen,
870 auto Res = Seen.try_emplace(Name, NameLoc);
876 P.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
878 P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
885 llvm::omp::TraitSet
Set,
887 llvm::StringMap<SourceLocation> &Seen) {
888 TIProperty.
Kind = TraitProperty::invalid;
891 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_TRAIT_LVL);
894 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set,
Selector);
899 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set,
Selector, Name);
900 if (TIProperty.
Kind != TraitProperty::invalid) {
901 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
902 TIProperty.
Kind = TraitProperty::invalid;
908 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
909 << Name << getOpenMPContextTraitSelectorName(
Selector)
910 << getOpenMPContextTraitSetName(
Set);
912 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
913 if (SetForName != TraitSet::invalid) {
914 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
915 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
916 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
917 << Name <<
"<selector-name>"
918 <<
"(<property-name>)";
921 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
922 if (SelectorForName != TraitSelector::invalid) {
923 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
924 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
925 bool AllowsTraitScore =
false;
926 bool RequiresProperty =
false;
927 isValidTraitSelectorForTraitSet(
928 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
929 AllowsTraitScore, RequiresProperty);
930 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
931 << getOpenMPContextTraitSetName(
932 getOpenMPContextTraitSetForSelector(SelectorForName))
933 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
936 for (
const auto &PotentialSet :
937 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
939 TraitProperty PropertyForName =
940 getOpenMPContextTraitPropertyKind(PotentialSet,
Selector, Name);
941 if (PropertyForName == TraitProperty::invalid)
943 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
944 << getOpenMPContextTraitSetName(
945 getOpenMPContextTraitSetForProperty(PropertyForName))
946 << getOpenMPContextTraitSelectorName(
947 getOpenMPContextTraitSelectorForProperty(PropertyForName))
948 << (
"(" + Name +
")").str();
951 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
952 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set,
Selector);
958 llvm::StringMap<SourceLocation> &Seen) {
959 assert(TISelector.
Kind ==
960 llvm::omp::TraitSelector::implementation_extension &&
961 "Only for extension properties, e.g., "
962 "`implementation={extension(PROPERTY)}`");
963 if (TIProperty.
Kind == TraitProperty::invalid)
966 if (TIProperty.
Kind ==
967 TraitProperty::implementation_extension_disable_implicit_base)
970 if (TIProperty.
Kind ==
971 TraitProperty::implementation_extension_allow_templates)
974 if (TIProperty.
Kind ==
975 TraitProperty::implementation_extension_bind_to_declaration)
980 llvm::omp::TraitProperty::implementation_extension_match_all ||
982 llvm::omp::TraitProperty::implementation_extension_match_any ||
984 llvm::omp::TraitProperty::implementation_extension_match_none);
987 if (IsMatchExtension(TIProperty)) {
989 if (IsMatchExtension(SeenProp)) {
990 P.Diag(
Loc, diag::err_omp_variant_ctx_second_match_extension);
991 StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
994 P.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
995 << CONTEXT_TRAIT_LVL << SeenName;
1001 llvm_unreachable(
"Unknown extension property!");
1005 llvm::omp::TraitSet
Set,
1006 llvm::StringMap<SourceLocation> &Seen) {
1007 assert(TISelector.
Kind != TraitSelector::user_condition &&
1008 "User conditions are special properties not handled here!");
1012 parseOMPTraitPropertyKind(TIProperty,
Set, TISelector.
Kind, Seen);
1014 if (TISelector.
Kind == llvm::omp::TraitSelector::implementation_extension)
1017 TIProperty.
Kind = TraitProperty::invalid;
1020 if (TIProperty.
Kind == TraitProperty::invalid) {
1022 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1023 << CONTEXT_TRAIT_LVL;
1027 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.
Kind,
1036 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
1037 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
1039 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1040 << getOpenMPContextTraitSetName(
Set);
1041 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
1042 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
1044 << getOpenMPContextTraitSelectorName(
1045 getOpenMPContextTraitSelectorForProperty(TIProperty.
Kind))
1046 << getOpenMPContextTraitSetName(
1047 getOpenMPContextTraitSetForProperty(TIProperty.
Kind));
1048 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1049 << CONTEXT_TRAIT_LVL;
1053 llvm::omp::TraitSet
Set,
1054 llvm::StringMap<SourceLocation> &Seen) {
1055 TISelector.
Kind = TraitSelector::invalid;
1058 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_LVL);
1061 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1065 TISelector.
Kind = getOpenMPContextTraitSelectorKind(Name);
1066 if (TISelector.
Kind != TraitSelector::invalid) {
1067 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1068 TISelector.
Kind = TraitSelector::invalid;
1073 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1074 << Name << getOpenMPContextTraitSetName(
Set);
1076 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1077 if (SetForName != TraitSet::invalid) {
1078 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1079 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1080 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1081 << Name <<
"<selector-name>"
1082 <<
"<property-name>";
1085 for (
const auto &PotentialSet :
1086 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1087 TraitSet::device}) {
1088 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1089 PotentialSet, TraitSelector::invalid, Name);
1090 if (PropertyForName == TraitProperty::invalid)
1092 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1093 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1094 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1095 << getOpenMPContextTraitSetName(
1096 getOpenMPContextTraitSetForProperty(PropertyForName))
1097 << getOpenMPContextTraitSelectorName(
1098 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1099 << (
"(" + Name +
")").str();
1102 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1103 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1110 StringRef SelectorName =
1111 P.getPreprocessor().getSpelling(
P.getCurToken(), Buffer);
1112 if (SelectorName !=
"score")
1114 (void)
P.ConsumeToken();
1116 ScoreExpr =
P.ParseOpenMPParensExpr(SelectorName, RLoc);
1118 if (
P.getCurToken().is(tok::colon))
1119 (
void)
P.ConsumeAnyToken();
1121 P.Diag(
P.getCurToken(), diag::warn_omp_declare_variant_expected)
1123 <<
"score expression";
1130void Parser::parseOMPContextSelector(
1132 llvm::StringMap<SourceLocation> &SeenSelectors) {
1133 unsigned short OuterPC = ParenCount;
1138 auto FinishSelector = [OuterPC,
this]() ->
void {
1141 while (!
SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1142 tok::annot_pragma_openmp_end},
1145 if (Tok.
is(tok::r_paren) && OuterPC > ParenCount)
1146 (
void)ConsumeParen();
1147 if (OuterPC <= ParenCount) {
1151 if (!Tok.
is(tok::comma) && !Tok.
is(tok::r_paren)) {
1157 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1158 << CONTEXT_SELECTOR_LVL;
1162 parseOMPTraitSelectorKind(TISelector,
Set, SeenSelectors);
1163 if (TISelector.
Kind == TraitSelector::invalid)
1164 return FinishSelector();
1166 bool AllowsTraitScore =
false;
1167 bool RequiresProperty =
false;
1168 if (!isValidTraitSelectorForTraitSet(TISelector.
Kind,
Set, AllowsTraitScore,
1169 RequiresProperty)) {
1170 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1171 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1172 << getOpenMPContextTraitSetName(
Set);
1173 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1174 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1175 << getOpenMPContextTraitSetName(
1176 getOpenMPContextTraitSetForSelector(TISelector.
Kind))
1177 << RequiresProperty;
1178 return FinishSelector();
1181 if (!RequiresProperty) {
1183 {getOpenMPContextTraitPropertyForSelector(TISelector.
Kind),
1184 getOpenMPContextTraitSelectorName(TISelector.
Kind)});
1188 if (!Tok.
is(tok::l_paren)) {
1189 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1190 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1191 << getOpenMPContextTraitSetName(
Set);
1192 return FinishSelector();
1195 if (TISelector.
Kind == TraitSelector::user_condition) {
1199 return FinishSelector();
1202 {TraitProperty::user_condition_unknown,
"<condition>"});
1207 tok::annot_pragma_openmp_end);
1209 (void)BDT.consumeOpen();
1214 if (!AllowsTraitScore && !Score.
isUnset()) {
1216 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1217 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1218 << getOpenMPContextTraitSetName(
Set) << Score.
get();
1220 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1221 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1222 << getOpenMPContextTraitSetName(
Set) <<
"<invalid>";
1230 llvm::StringMap<SourceLocation> SeenProperties;
1232 parseOMPContextProperty(TISelector,
Set, SeenProperties);
1239void Parser::parseOMPTraitSetKind(
OMPTraitSet &TISet,
1240 llvm::StringMap<SourceLocation> &Seen) {
1241 TISet.
Kind = TraitSet::invalid;
1244 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_SET_LVL);
1247 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1251 TISet.
Kind = getOpenMPContextTraitSetKind(Name);
1252 if (TISet.
Kind != TraitSet::invalid) {
1253 if (checkForDuplicates(*
this, Name, NameLoc, Seen,
1254 CONTEXT_SELECTOR_SET_LVL))
1255 TISet.
Kind = TraitSet::invalid;
1260 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1262 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1263 if (SelectorForName != TraitSelector::invalid) {
1264 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1265 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1266 bool AllowsTraitScore =
false;
1267 bool RequiresProperty =
false;
1268 isValidTraitSelectorForTraitSet(
1269 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1270 AllowsTraitScore, RequiresProperty);
1271 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1272 << getOpenMPContextTraitSetName(
1273 getOpenMPContextTraitSetForSelector(SelectorForName))
1274 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
1277 for (
const auto &PotentialSet :
1278 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1279 TraitSet::device}) {
1280 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1281 PotentialSet, TraitSelector::invalid, Name);
1282 if (PropertyForName == TraitProperty::invalid)
1284 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1285 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1286 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1287 << getOpenMPContextTraitSetName(
1288 getOpenMPContextTraitSetForProperty(PropertyForName))
1289 << getOpenMPContextTraitSelectorName(
1290 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1291 << (
"(" + Name +
")").str();
1294 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1295 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1301void Parser::parseOMPContextSelectorSet(
1302 OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1303 auto OuterBC = BraceCount;
1308 auto FinishSelectorSet = [
this, OuterBC]() ->
void {
1311 while (!
SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1312 tok::annot_pragma_openmp_end},
1315 if (Tok.
is(tok::r_brace) && OuterBC > BraceCount)
1316 (
void)ConsumeBrace();
1317 if (OuterBC <= BraceCount) {
1321 if (!Tok.
is(tok::comma) && !Tok.
is(tok::r_brace)) {
1327 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1328 << CONTEXT_SELECTOR_SET_LVL;
1331 parseOMPTraitSetKind(TISet, SeenSets);
1332 if (TISet.
Kind == TraitSet::invalid)
1333 return FinishSelectorSet();
1339 << (
"context set name \"" + getOpenMPContextTraitSetName(TISet.
Kind) +
1344 if (Tok.
is(tok::l_brace)) {
1345 (void)ConsumeBrace();
1349 << (
"'=' that follows the context set name \"" +
1350 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1354 llvm::StringMap<SourceLocation> SeenSelectors;
1357 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1358 if (TISelector.
Kind != TraitSelector::invalid &&
1364 if (Tok.
is(tok::r_brace)) {
1365 (void)ConsumeBrace();
1369 << (
"context selectors for the context set \"" +
1370 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1379 llvm::StringMap<SourceLocation> SeenSets;
1382 parseOMPContextSelectorSet(TISet, SeenSets);
1383 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1384 TI.
Sets.push_back(TISet);
1395 PP.EnterTokenStream(Toks,
true,
1401 FNContextRAII FnContext(*
this, Ptr);
1413 getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1416 if (!AssociatedFunction.
isUsable()) {
1417 if (!Tok.
is(tok::annot_pragma_openmp_end))
1421 (void)ConsumeAnnotationToken();
1426 Actions.
OpenMP().getOMPTraitInfoForSurroundingScope();
1435 if (Tok.
is(tok::annot_pragma_openmp_end)) {
1440 bool IsError =
false;
1441 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1445 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1454 IsError = parseOMPDeclareVariantMatchClause(
Loc, TI, ParentTI);
1456 case OMPC_adjust_args: {
1464 llvm::append_range(
Data.ExtraModifier == OMPC_ADJUST_ARGS_nothing
1466 : AdjustNeedDevicePtr,
1470 case OMPC_append_args:
1471 if (!AppendArgs.empty()) {
1472 Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1473 << getOpenMPDirectiveName(OMPD_declare_variant)
1474 << getOpenMPClauseName(CKind) << 0;
1480 IsError = parseOpenMPAppendArgs(AppendArgs);
1484 llvm_unreachable(
"Unexpected clause for declare variant.");
1491 (void)ConsumeAnnotationToken();
1495 if (Tok.
is(tok::comma))
1499 std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1501 Ptr, AssociatedFunction.
get(), TI, AppendArgs.size(),
1504 if (DeclVarData && !TI.
Sets.empty())
1506 DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1507 AdjustNeedDevicePtr, AppendArgs, AdjustArgsLoc, AppendArgsLoc,
1511 (void)ConsumeAnnotationToken();
1514bool Parser::parseOpenMPAppendArgs(
1516 bool HasError =
false;
1519 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1520 getOpenMPClauseName(OMPC_append_args).data()))
1528 tok::annot_pragma_openmp_end);
1529 if (IT.expectAndConsume(diag::err_expected_lparen_after,
"interop"))
1533 if (ParseOMPInteropInfo(InteropInfo, OMPC_append_args))
1536 InteropInfos.push_back(InteropInfo);
1539 if (Tok.
is(tok::comma))
1542 if (!HasError && InteropInfos.empty()) {
1545 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1548 HasError =
T.consumeClose() || HasError;
1559 if (CKind != OMPC_match) {
1567 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1568 getOpenMPClauseName(OMPC_match).data()))
1572 parseOMPContextSelectors(
Loc, TI);
1575 (void)
T.consumeClose();
1586 bool MergedSet =
false;
1588 if (
Set.Kind != ParentSet.
Kind)
1592 bool MergedSelector =
false;
1596 MergedSelector =
true;
1599 bool MergedProperty =
false;
1613 if (
Selector.Kind == llvm::omp::TraitSelector::user_condition) {
1614 Diag(
Loc, diag::err_omp_declare_variant_nested_user_condition);
1615 }
else if (
Selector.ScoreOrCondition !=
1617 Diag(
Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1618 << getOpenMPContextTraitPropertyName(
1620 << getOpenMPContextTraitSelectorName(ParentSelector.
Kind)
1621 << getOpenMPContextTraitSetName(ParentSet.
Kind);
1624 if (!MergedProperty)
1625 Selector.Properties.push_back(ParentProperty);
1628 if (!MergedSelector)
1629 Set.Selectors.push_back(ParentSelector);
1633 TI.
Sets.push_back(ParentSet);
1649 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
1650 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1656 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
1657 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1659 SeenClauses[
unsigned(CKind)] =
true;
1660 if (Clause !=
nullptr)
1661 Clauses.push_back(Clause);
1662 if (Tok.
is(tok::annot_pragma_openmp_end)) {
1667 if (Tok.
is(tok::comma))
1688 bool SkippedClauses =
false;
1690 auto SkipBraces = [&](llvm::StringRef Spelling,
bool IssueNote) {
1692 tok::annot_pragma_openmp_end);
1693 if (
T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1696 if (IssueNote &&
T.getCloseLocation().isValid())
1697 Diag(
T.getCloseLocation(),
1698 diag::note_omp_assumption_clause_continue_here);
1704 auto MatchACMClause = [&](StringRef RawString) {
1705 llvm::StringSwitch<int> SS(RawString);
1706 unsigned ACMIdx = 0;
1707 for (
const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1708 if (ACMI.StartsWith)
1709 SS.StartsWith(ACMI.Identifier, ACMIdx++);
1711 SS.Case(ACMI.Identifier, ACMIdx++);
1713 return SS.Default(-1);
1716 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1722 Idx = MatchACMClause(II->
getName());
1726 bool NextIsLPar = Tok.
is(tok::l_paren);
1729 Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1730 << llvm::omp::getOpenMPDirectiveName(DKind)
1731 << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1733 SkipBraces(II ? II->
getName() :
"",
true);
1734 SkippedClauses =
true;
1737 const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1738 if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1741 SkippedClauses =
true;
1742 SkipBraces(II->
getName(),
false);
1748 diag::warn_omp_unknown_assumption_clause_without_args)
1750 SkipBraces(II->
getName(),
true);
1753 assert(II &&
"Expected an identifier clause!");
1754 std::string Assumption = II->
getName().str();
1755 if (ACMI.StartsWith)
1756 Assumption =
"ompx_" + Assumption.substr(ACMI.Identifier.size());
1758 Assumption =
"omp_" + Assumption;
1759 Assumptions.push_back(Assumption);
1770 Diag(
Loc, diag::err_expected_begin_assumes);
1784struct SimpleClauseData {
1796static std::optional<SimpleClauseData>
1798 const Token &Tok =
P.getCurToken();
1803 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1804 getOpenMPClauseName(Kind).data()))
1805 return std::nullopt;
1808 Kind, Tok.
isAnnotation() ?
"" :
P.getPreprocessor().getSpelling(Tok),
1811 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
1812 Tok.
isNot(tok::annot_pragma_openmp_end))
1813 P.ConsumeAnyToken();
1817 if (!
T.consumeClose())
1818 RLoc =
T.getCloseLocation();
1823void Parser::ParseOMPDeclareTargetClauses(
1826 bool RequiresToOrLinkOrIndirectClause =
false;
1827 bool HasToOrLinkOrIndirectClause =
false;
1828 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1829 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1830 bool HasIdentifier = Tok.
is(tok::identifier);
1831 if (HasIdentifier) {
1833 RequiresToOrLinkOrIndirectClause =
true;
1835 StringRef ClauseName = II->
getName();
1836 bool IsDeviceTypeClause =
1838 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1840 bool IsIndirectClause =
getLangOpts().OpenMP >= 51 &&
1841 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1842 if (DTCI.
Indirect && IsIndirectClause) {
1843 Diag(Tok, diag::err_omp_more_one_clause)
1844 << getOpenMPDirectiveName(OMPD_declare_target)
1845 << getOpenMPClauseName(OMPC_indirect) << 0;
1848 bool IsToEnterOrLinkClause =
1849 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1850 assert((!IsDeviceTypeClause || !IsToEnterOrLinkClause) &&
1855 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1856 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1859 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1860 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1864 if (!IsDeviceTypeClause && !IsIndirectClause &&
1865 DTCI.
Kind == OMPD_begin_declare_target) {
1866 Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1867 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1870 if (!IsDeviceTypeClause && !IsToEnterOrLinkClause && !IsIndirectClause) {
1872 ? diag::err_omp_declare_target_unexpected_clause_52
1873 : diag::err_omp_declare_target_unexpected_clause)
1881 if (IsToEnterOrLinkClause || IsIndirectClause)
1882 HasToOrLinkOrIndirectClause =
true;
1884 if (IsIndirectClause) {
1885 if (!ParseOpenMPIndirectClause(DTCI,
false))
1890 if (IsDeviceTypeClause) {
1891 std::optional<SimpleClauseData> DevTypeData =
1894 if (DeviceTypeLoc.
isValid()) {
1896 Diag(DevTypeData->Loc,
1897 diag::warn_omp_more_one_device_type_clause);
1901 case OMPC_DEVICE_TYPE_any:
1902 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Any;
1904 case OMPC_DEVICE_TYPE_host:
1905 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Host;
1907 case OMPC_DEVICE_TYPE_nohost:
1908 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1911 llvm_unreachable(
"Unexpected device_type");
1913 DeviceTypeLoc = DevTypeData->Loc;
1920 if (DTCI.
Kind == OMPD_declare_target || HasIdentifier) {
1930 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1933 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1938 if (Tok.
is(tok::l_paren)) {
1940 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1943 if (!HasIdentifier && Tok.
isNot(tok::annot_pragma_openmp_end)) {
1946 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1947 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1952 if (Tok.
is(tok::comma))
1956 if (DTCI.
Indirect && DTCI.
DT != OMPDeclareTargetDeclAttr::DT_Any)
1957 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1960 if (DTCI.
Kind == OMPD_declare_target && RequiresToOrLinkOrIndirectClause &&
1961 !HasToOrLinkOrIndirectClause)
1964 ? diag::err_omp_declare_target_missing_enter_or_link_clause
1965 : diag::err_omp_declare_target_missing_to_or_link_clause)
1974 if (Tok.
is(tok::annot_pragma_openmp_end))
1977 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1978 << getOpenMPDirectiveName(DKind);
1979 while (Tok.
isNot(tok::annot_pragma_openmp_end))
1988 bool SkipUntilOpenMPEnd) {
1989 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1991 if (FoundKind == ExpectedKind) {
1993 skipUntilPragmaOpenMPEnd(ExpectedKind);
1997 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1999 Diag(BeginLoc, diag::note_matching)
2000 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind) +
"'").str();
2001 if (SkipUntilOpenMPEnd)
2008 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
2012 if (Tok.
is(tok::annot_pragma_openmp_end))
2013 ConsumeAnnotationToken();
2055 assert(Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2056 "Not an OpenMP directive!");
2063 TentativeParsingAction TPA(*
this);
2064 Loc = ConsumeAnnotationToken();
2066 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
2071 Toks.push_back(Tok);
2072 while (Cnt && Tok.
isNot(tok::eof)) {
2074 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
2076 else if (Tok.
is(tok::annot_pragma_openmp_end))
2078 Toks.push_back(Tok);
2083 auto *LP =
new LateParsedPragma(
this, AS);
2085 getCurrentClass().LateParsedDeclarations.push_back(LP);
2090 Loc = ConsumeAnnotationToken();
2095 case OMPD_threadprivate: {
2097 DeclDirectiveListParserHelper Helper(
this, DKind);
2098 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2100 skipUntilPragmaOpenMPEnd(DKind);
2102 ConsumeAnnotationToken();
2104 Loc, Helper.getIdentifiers());
2108 case OMPD_allocate: {
2110 DeclDirectiveListParserHelper Helper(
this, DKind);
2111 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2114 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2115 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
2116 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2121 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2122 !SeenClauses[
unsigned(CKind)]);
2123 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2125 SeenClauses[
unsigned(CKind)] =
true;
2126 if (Clause !=
nullptr)
2127 Clauses.push_back(Clause);
2128 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2133 if (Tok.
is(tok::comma))
2137 skipUntilPragmaOpenMPEnd(DKind);
2140 ConsumeAnnotationToken();
2142 Loc, Helper.getIdentifiers(), Clauses);
2146 case OMPD_requires: {
2149 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2150 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2151 Diag(Tok, diag::err_omp_expected_clause)
2152 << getOpenMPDirectiveName(OMPD_requires);
2155 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2160 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
2161 !SeenClauses[
unsigned(CKind)]);
2162 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2164 SeenClauses[
unsigned(CKind)] =
true;
2165 if (Clause !=
nullptr)
2166 Clauses.push_back(Clause);
2167 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2172 if (Tok.
is(tok::comma))
2177 if (Clauses.empty()) {
2178 Diag(Tok, diag::err_omp_expected_clause)
2179 << getOpenMPDirectiveName(OMPD_requires);
2180 ConsumeAnnotationToken();
2183 ConsumeAnnotationToken();
2189 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2196 case OMPD_begin_assumes:
2199 case OMPD_end_assumes:
2202 case OMPD_declare_reduction:
2204 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2205 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2207 ConsumeAnnotationToken();
2211 case OMPD_declare_mapper: {
2213 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2215 ConsumeAnnotationToken();
2220 case OMPD_begin_declare_variant: {
2228 Actions.
OpenMP().getOMPTraitInfoForSurroundingScope();
2231 if (parseOMPDeclareVariantMatchClause(
Loc, TI, ParentTI)) {
2235 (void)ConsumeAnnotationToken();
2240 skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
2244 VariantMatchInfo VMI;
2247 std::function<void(StringRef)> DiagUnknownTrait =
2248 [
this,
Loc](StringRef ISATrait) {
2251 Diag(
Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2254 ASTCtx, std::move(DiagUnknownTrait),
2258 if (isVariantApplicableInContext(VMI, OMPCtx,
true)) {
2264 unsigned Nesting = 1;
2270 if (DK == OMPD_end_declare_variant)
2272 else if (DK == OMPD_begin_declare_variant)
2274 if (!Nesting || isEofOrEom())
2279 parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
2280 DK,
Loc, DKLoc,
true);
2285 case OMPD_end_declare_variant: {
2289 Diag(
Loc, diag::err_expected_begin_declare_variant);
2293 case OMPD_declare_variant:
2294 case OMPD_declare_simd: {
2300 Toks.push_back(Tok);
2302 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2303 Toks.push_back(Tok);
2306 Toks.push_back(Tok);
2310 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2311 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2313 }
else if (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
2318 MaybeParseCXX11Attributes(Attrs);
2320 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2323 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs,
TagType, Tag);
2327 Diag(
Loc, diag::err_omp_decl_in_declare_simd_variant)
2328 << (DKind == OMPD_declare_simd ? 0 : 1);
2331 if (DKind == OMPD_declare_simd)
2332 return ParseOMPDeclareSimdClauses(Ptr, Toks,
Loc);
2333 assert(DKind == OMPD_declare_variant &&
2334 "Expected declare variant directive only");
2335 ParseOMPDeclareVariantClauses(Ptr, Toks,
Loc);
2338 case OMPD_begin_declare_target:
2339 case OMPD_declare_target: {
2341 bool HasClauses = Tok.
isNot(tok::annot_pragma_openmp_end);
2344 ParseOMPDeclareTargetClauses(DTCI);
2345 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2352 if (HasImplicitMappings) {
2360 Decls.push_back(It.first);
2363 case OMPD_end_declare_target: {
2365 Diag(Tok, diag::err_omp_unexpected_directive)
2366 << 1 << getOpenMPDirectiveName(DKind);
2371 ParseOMPEndDeclareTargetDirective(DTCI.
Kind, DKind, DTCI.
Loc);
2375 Diag(Tok, diag::err_omp_unexpected_directive)
2376 << 1 << getOpenMPDirectiveName(DKind);
2380 Diag(Tok, diag::err_omp_unknown_directive);
2383 switch (getDirectiveCategory(DKind)) {
2384 case Category::Executable:
2385 case Category::Meta:
2386 case Category::Subsidiary:
2387 case Category::Utility:
2388 Diag(Tok, diag::err_omp_unexpected_directive)
2389 << 1 << getOpenMPDirectiveName(DKind);
2391 case Category::Declarative:
2392 case Category::Informational:
2396 while (Tok.
isNot(tok::annot_pragma_openmp_end))
2402StmtResult Parser::ParseOpenMPExecutableDirective(
2404 bool ReadDirectiveWithinMetadirective) {
2407 bool HasAssociatedStatement =
true;
2408 Association Assoc = getDirectiveAssociation(DKind);
2414 if (DKind != OMPD_ordered && DKind != OMPD_section &&
2415 (Assoc == Association::None || Assoc == Association::Separating)) {
2416 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2417 ParsedStmtContext()) {
2418 Diag(Tok, diag::err_omp_immediate_directive)
2419 << getOpenMPDirectiveName(DKind) << 0;
2420 if (DKind == OMPD_error) {
2421 SkipUntil(tok::annot_pragma_openmp_end);
2425 HasAssociatedStatement =
false;
2430 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2438 bool ImplicitClauseAllowed =
false;
2439 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2441 ImplicitClauseAllowed =
true;
2445 if (DKind == OMPD_critical) {
2447 tok::annot_pragma_openmp_end);
2448 if (!
T.consumeOpen()) {
2454 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2458 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2460 if (Tok.
isNot(tok::annot_pragma_openmp_end))
2468 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2472 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2475 if (ReadDirectiveWithinMetadirective && Tok.
is(tok::r_paren)) {
2476 while (Tok.
isNot(tok::annot_pragma_openmp_end))
2480 bool HasImplicitClause =
false;
2481 if (ImplicitClauseAllowed && Tok.
is(tok::l_paren)) {
2482 HasImplicitClause =
true;
2492 if (HasImplicitClause) {
2493 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2494 if (DKind == OMPD_flush) {
2497 assert(DKind == OMPD_depobj &&
"Expected flush or depobj directives.");
2498 CKind = OMPC_depobj;
2502 ImplicitClauseAllowed =
false;
2504 HasImplicitClause =
false;
2506 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2507 SeenClauses[
unsigned(CKind)] =
true;
2509 Clauses.push_back(Clause);
2512 if (Tok.
is(tok::comma))
2519 ConsumeAnnotationToken();
2521 if (DKind == OMPD_ordered) {
2524 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2525 if (SeenClauses[
unsigned(CK)]) {
2526 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2527 ParsedStmtContext()) {
2528 Diag(
Loc, diag::err_omp_immediate_directive)
2529 << getOpenMPDirectiveName(DKind) << 1 << getOpenMPClauseName(CK);
2531 HasAssociatedStatement =
false;
2536 if (DKind == OMPD_tile && !SeenClauses[
unsigned(OMPC_sizes)]) {
2537 Diag(
Loc, diag::err_omp_required_clause)
2538 << getOpenMPDirectiveName(OMPD_tile) <<
"sizes";
2542 if (HasAssociatedStatement) {
2551 AssociatedStmt = ParseStatement();
2560 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2561 DKind == OMPD_target_exit_data) {
2571 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.
get(),
Loc, EndLoc);
2575 OMPDirectiveScope.Exit();
2580StmtResult Parser::ParseOpenMPInformationalDirective(
2582 bool ReadDirectiveWithinMetadirective) {
2584 "Unexpected directive category");
2586 bool HasAssociatedStatement =
true;
2589 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2593 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2598 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2599 if (ReadDirectiveWithinMetadirective && Tok.
is(tok::r_paren)) {
2600 while (Tok.
isNot(tok::annot_pragma_openmp_end))
2610 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2611 SeenClauses[
unsigned(CKind)] =
true;
2613 Clauses.push_back(Clause);
2615 if (Tok.
is(tok::comma))
2621 ConsumeAnnotationToken();
2624 if (HasAssociatedStatement) {
2629 AssociatedStmt = ParseStatement();
2636 DKind, DirName, Clauses, AssociatedStmt.
get(),
Loc, EndLoc);
2639 OMPDirectiveScope.Exit();
2684StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2685 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2686 if (!ReadDirectiveWithinMetadirective)
2687 assert(Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2688 "Not an OpenMP directive!");
2693 : ConsumeAnnotationToken();
2695 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2696 Diag(Tok, diag::err_omp_unknown_directive);
2702 bool IsExecutable = [&]() {
2703 if (DKind == OMPD_error)
2705 auto Res = getDirectiveCategory(DKind);
2706 return Res == Category::Executable || Res == Category::Subsidiary;
2710 Directive = ParseOpenMPExecutableDirective(
2711 StmtCtx, DKind,
Loc, ReadDirectiveWithinMetadirective);
2712 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2721 if (ReadDirectiveWithinMetadirective && Tok.
is(tok::r_paren))
2722 while (Tok.
isNot(tok::annot_pragma_openmp_end))
2725 skipUntilPragmaOpenMPEnd(DKind);
2726 if (Tok.
is(tok::annot_pragma_openmp_end))
2727 ConsumeAnnotationToken();
2730 case OMPD_metadirective: {
2737 TentativeParsingAction TPA(*
this);
2741 tok::annot_pragma_openmp_end);
2742 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2749 if (
T.expectAndConsume(diag::err_expected_lparen_after,
2750 getOpenMPClauseName(CKind).data()))
2754 if (CKind == OMPC_when) {
2756 parseOMPContextSelectors(
Loc, TI);
2757 if (TI.
Sets.size() == 0) {
2758 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2764 if (Tok.
is(tok::colon))
2767 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2774 while (Tok.
isNot(tok::r_paren) || paren != 0) {
2775 if (Tok.
is(tok::l_paren))
2777 if (Tok.
is(tok::r_paren))
2779 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2780 Diag(Tok, diag::err_omp_expected_punc)
2781 << getOpenMPClauseName(CKind) << 0;
2788 if (Tok.
is(tok::r_paren))
2791 VariantMatchInfo VMI;
2794 VMIs.push_back(VMI);
2800 std::function<void(StringRef)> DiagUnknownTrait =
2801 [
this,
Loc](StringRef ISATrait) {
2804 Diag(
Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2811 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2818 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2820 if (Idx++ != BestIdx) {
2825 while (Tok.
isNot(tok::r_paren) || paren != 0) {
2826 if (Tok.
is(tok::l_paren))
2828 if (Tok.
is(tok::r_paren))
2833 if (Tok.
is(tok::r_paren))
2847 if (CKind == OMPC_when) {
2850 parseOMPContextSelectors(
Loc, TI);
2858 if (Tok.
is(tok::r_paren)) {
2859 SkipUntil(tok::annot_pragma_openmp_end);
2864 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2871 case OMPD_threadprivate: {
2873 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2874 ParsedStmtContext()) {
2875 Diag(Tok, diag::err_omp_immediate_directive)
2876 << getOpenMPDirectiveName(DKind) << 0;
2879 DeclDirectiveListParserHelper Helper(
this, DKind);
2880 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2882 skipUntilPragmaOpenMPEnd(DKind);
2884 Loc, Helper.getIdentifiers());
2887 SkipUntil(tok::annot_pragma_openmp_end);
2890 case OMPD_allocate: {
2892 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2893 ParsedStmtContext()) {
2894 Diag(Tok, diag::err_omp_immediate_directive)
2895 << getOpenMPDirectiveName(DKind) << 0;
2898 DeclDirectiveListParserHelper Helper(
this, DKind);
2899 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2902 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2903 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2904 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2909 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2910 !SeenClauses[
unsigned(CKind)]);
2911 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2913 SeenClauses[
unsigned(CKind)] =
true;
2914 if (Clause !=
nullptr)
2915 Clauses.push_back(Clause);
2916 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2921 if (Tok.
is(tok::comma))
2925 skipUntilPragmaOpenMPEnd(DKind);
2928 Loc, Helper.getIdentifiers(), Clauses);
2931 SkipUntil(tok::annot_pragma_openmp_end);
2934 case OMPD_declare_reduction:
2937 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2938 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2942 SkipUntil(tok::annot_pragma_openmp_end);
2945 case OMPD_declare_mapper: {
2948 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2950 ConsumeAnnotationToken();
2953 SkipUntil(tok::annot_pragma_openmp_end);
2958 case OMPD_interchange:
2959 case OMPD_declare_target: {
2961 bool HasClauses = Tok.
isNot(tok::annot_pragma_openmp_end);
2964 ParseOMPDeclareTargetClauses(DTCI);
2965 bool HasImplicitMappings =
2968 if (HasImplicitMappings) {
2969 Diag(Tok, diag::err_omp_unexpected_directive)
2970 << 1 << getOpenMPDirectiveName(DKind);
2971 SkipUntil(tok::annot_pragma_openmp_end);
2981 case OMPD_declare_simd:
2982 case OMPD_begin_declare_target:
2983 case OMPD_end_declare_target:
2985 case OMPD_begin_declare_variant:
2986 case OMPD_end_declare_variant:
2987 case OMPD_declare_variant:
2988 Diag(Tok, diag::err_omp_unexpected_directive)
2989 << 1 << getOpenMPDirectiveName(DKind);
2990 SkipUntil(tok::annot_pragma_openmp_end);
2994 Directive = ParseOpenMPInformationalDirective(
2995 StmtCtx, DKind,
Loc, ReadDirectiveWithinMetadirective);
2997 "Informational directive remains unprocessed");
3002 Diag(Tok, diag::err_omp_unknown_directive);
3003 SkipUntil(tok::annot_pragma_openmp_end);
3013bool Parser::ParseOpenMPSimpleVarList(
3017 bool AllowScopeSpecifier) {
3020 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3021 getOpenMPDirectiveName(Kind).data()))
3023 bool IsCorrect =
true;
3024 bool NoIdentIsFound =
true;
3027 while (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::annot_pragma_openmp_end)) {
3031 Token PrevTok = Tok;
3032 NoIdentIsFound =
false;
3035 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
3038 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3041 false,
false,
false,
3042 false,
false,
nullptr, Name)) {
3044 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3046 }
else if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::r_paren) &&
3047 Tok.
isNot(tok::annot_pragma_openmp_end)) {
3049 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3058 if (Tok.
is(tok::comma)) {
3063 if (NoIdentIsFound) {
3064 Diag(Tok, diag::err_expected) << tok::identifier;
3069 IsCorrect = !
T.consumeClose() && IsCorrect;
3074OMPClause *Parser::ParseOpenMPSizesClause() {
3077 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
3091 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3099 ? ParseCXXIdExpression()
3100 : tryParseCXXIdExpression(SS,
false,
3102 if (Allocator.isInvalid()) {
3103 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3108 D.Allocator = Allocator.get();
3109 if (Tok.
is(tok::l_paren)) {
3111 tok::annot_pragma_openmp_end);
3117 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3121 D.AllocatorTraits = AllocatorTraits.
get();
3122 D.LParenLoc =
T.getOpenLocation();
3123 D.RParenLoc =
T.getCloseLocation();
3125 if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::r_paren))
3126 Diag(Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3128 if (Tok.
is(tok::comma))
3130 }
while (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::annot_pragma_openmp_end));
3133 Loc,
T.getOpenLocation(),
T.getCloseLocation(),
Data);
3158 OMPClauseKind = CKind;
3160 bool ErrorFound =
false;
3161 bool WrongDirective =
false;
3163 if (CKind != OMPC_unknown &&
3164 !isAllowedClauseForDirective(DKind, CKind,
getLangOpts().OpenMP)) {
3165 Diag(Tok, diag::err_omp_unexpected_clause)
3166 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3168 WrongDirective =
true;
3173 case OMPC_num_threads:
3179 case OMPC_grainsize:
3180 case OMPC_num_tasks:
3182 case OMPC_allocator:
3185 case OMPC_novariants:
3186 case OMPC_nocontext:
3191 case OMPC_ompx_dyn_cgroup_mem:
3220 Diag(Tok, diag::err_omp_more_one_clause)
3221 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3225 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3227 Clause = ParseOpenMPClause(CKind, WrongDirective);
3228 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks)
3229 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3231 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3235 case OMPC_proc_bind:
3236 case OMPC_atomic_default_mem_order:
3254 Diag(Tok, diag::err_omp_more_one_clause)
3255 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3259 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3263 case OMPC_dist_schedule:
3264 case OMPC_defaultmap:
3274 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3275 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3276 Diag(Tok, diag::err_omp_more_one_clause)
3277 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3282 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3285 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3289 case OMPC_mergeable:
3303 case OMPC_unified_address:
3304 case OMPC_unified_shared_memory:
3305 case OMPC_reverse_offload:
3306 case OMPC_dynamic_allocators:
3315 Diag(Tok, diag::err_omp_more_one_clause)
3316 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3320 Clause = ParseOpenMPClause(CKind, WrongDirective);
3324 Diag(Tok, diag::err_omp_more_one_clause)
3325 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3329 Clause = (DKind == OMPD_depobj)
3330 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3331 : ParseOpenMPClause(CKind, WrongDirective);
3333 case OMPC_num_teams:
3334 case OMPC_thread_limit:
3336 Diag(Tok, diag::err_omp_more_one_clause)
3337 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3342 case OMPC_firstprivate:
3343 case OMPC_lastprivate:
3345 case OMPC_reduction:
3346 case OMPC_task_reduction:
3347 case OMPC_in_reduction:
3351 case OMPC_copyprivate:
3357 case OMPC_use_device_ptr:
3358 case OMPC_use_device_addr:
3359 case OMPC_is_device_ptr:
3360 case OMPC_has_device_addr:
3362 case OMPC_nontemporal:
3363 case OMPC_inclusive:
3364 case OMPC_exclusive:
3368 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
3369 CKind == OMPC_depend)
3370 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3371 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3375 Diag(Tok, diag::err_omp_more_one_clause)
3376 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3380 Clause = ParseOpenMPSizesClause();
3382 case OMPC_uses_allocators:
3383 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3386 if (DKind != OMPD_interop) {
3388 Diag(Tok, diag::err_omp_more_one_clause)
3389 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3392 Clause = ParseOpenMPClause(CKind, WrongDirective);
3398 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3400 case OMPC_device_type:
3402 skipUntilPragmaOpenMPEnd(DKind);
3404 case OMPC_threadprivate:
3407 if (!WrongDirective)
3408 Diag(Tok, diag::err_omp_unexpected_clause)
3409 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3413 case OMPC_contains: {
3422 if (DK == OMPD_unknown) {
3423 skipUntilPragmaOpenMPEnd(OMPD_assume);
3424 Diag(Tok, diag::err_omp_unexpected_clause)
3425 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3429 DKVec.push_back(DK);
3432 Diag(Tok, diag::err_omp_unexpected_clause)
3433 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3439 CKind, DKVec,
Loc, LLoc, RLoc);
3442 case OMPC_no_openmp:
3443 case OMPC_no_openmp_routines:
3444 case OMPC_no_parallelism: {
3446 Diag(Tok, diag::err_omp_more_one_clause)
3447 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3455 case OMPC_ompx_attribute:
3456 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3458 case OMPC_ompx_bare:
3460 Diag(Tok, diag::note_ompx_bare_clause)
3461 << getOpenMPClauseName(CKind) <<
"target teams";
3462 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3463 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3464 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3467 Clause = ParseOpenMPClause(CKind, WrongDirective);
3472 return ErrorFound ? nullptr : Clause;
3480 bool IsAddressOfOperand) {
3482 if (
T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3487 ParseCastExpression(AnyCastExpr, IsAddressOfOperand,
NotTypeCast));
3493 if (!
T.consumeClose())
3494 RLoc =
T.getCloseLocation();
3564bool Parser::ParseOpenMPIndirectClause(
3569 if (Tok.
isNot(tok::l_paren)) {
3588 if (
Ret.isInvalid())
3593 if (
Ret.isInvalid())
3606 bool HasError =
false;
3607 bool IsTarget =
false;
3608 bool IsTargetSync =
false;
3610 while (Tok.
is(tok::identifier)) {
3612 bool PreferTypeAllowed =
Kind == OMPC_init &&
3620 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3625 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3626 IsTargetSync =
true;
3629 PreferTypeAllowed) {
3632 tok::annot_pragma_openmp_end);
3633 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3636 while (Tok.
isNot(tok::r_paren)) {
3638 ExprResult LHS = ParseCastExpression(AnyCastExpr);
3647 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3651 if (Tok.
is(tok::comma))
3657 Diag(Tok, diag::err_omp_expected_interop_type);
3660 if (!Tok.
is(tok::comma))
3665 if (!HasError && !IsTarget && !IsTargetSync) {
3666 Diag(Tok, diag::err_omp_expected_interop_type);
3670 if (Kind == OMPC_init) {
3671 if (Tok.
isNot(tok::colon) && (IsTarget || IsTargetSync))
3672 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3673 if (Tok.
is(tok::colon))
3713 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3714 getOpenMPClauseName(Kind).data()))
3717 bool InteropError =
false;
3719 if (Kind == OMPC_init)
3720 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3727 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3733 if (!
T.consumeClose())
3734 RLoc =
T.getCloseLocation();
3736 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3739 if (Kind == OMPC_init)
3741 InteropVarExpr.
get(), InteropInfo,
Loc,
T.getOpenLocation(), VarLoc,
3743 if (Kind == OMPC_use)
3745 InteropVarExpr.
get(),
Loc,
T.getOpenLocation(), VarLoc, RLoc);
3747 if (Kind == OMPC_destroy)
3749 InteropVarExpr.
get(),
Loc,
T.getOpenLocation(), VarLoc, RLoc);
3751 llvm_unreachable(
"Unexpected interop variable clause.");
3754OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
3758 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3759 getOpenMPClauseName(OMPC_ompx_attribute).data()))
3763 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
3766 if (
T.consumeClose())
3774 switch (PA.getKind()) {
3775 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
3776 if (!PA.checkExactlyNumArgs(Actions, 2))
3779 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
3782 case ParsedAttr::AT_AMDGPUWavesPerEU:
3783 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3784 !PA.checkAtMostNumArgs(Actions, 2))
3787 PA, PA.getArgAsExpr(0),
3788 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
3791 case ParsedAttr::AT_CUDALaunchBounds:
3792 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3793 !PA.checkAtMostNumArgs(Actions, 2))
3796 PA, PA.getArgAsExpr(0),
3797 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
3798 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr))
3802 Diag(
Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
3808 Attrs,
Loc,
T.getOpenLocation(),
T.getCloseLocation());
3829 if (!Val || ParseOnly)
3831 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3832 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
3833 static_cast<DefaultKind
>(Val->Type) ==
3834 OMP_DEFAULT_firstprivate)) {
3835 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
3836 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
3839 : OMPC_firstprivate)
3840 << getOpenMPClauseName(OMPC_default) <<
"5.1";
3844 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
3905 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3906 getOpenMPClauseName(Kind).data()))
3912 if (Kind == OMPC_schedule) {
3913 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3914 Arg.resize(NumberOfElements);
3915 KLoc.resize(NumberOfElements);
3923 Arg[Modifier1] = KindModifier;
3925 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3926 Tok.
isNot(tok::annot_pragma_openmp_end))
3928 if (Tok.
is(tok::comma)) {
3937 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3938 Tok.
isNot(tok::annot_pragma_openmp_end))
3942 if (Tok.
is(tok::colon))
3945 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
3949 Arg[ScheduleKind] = KindModifier;
3951 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3952 Tok.
isNot(tok::annot_pragma_openmp_end))
3954 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3955 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3956 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3959 }
else if (Kind == OMPC_dist_schedule) {
3963 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3964 Tok.
isNot(tok::annot_pragma_openmp_end))
3966 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.
is(tok::comma))
3968 }
else if (Kind == OMPC_defaultmap) {
3977 Arg.push_back(Modifier);
3979 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3980 Tok.
isNot(tok::annot_pragma_openmp_end))
3984 if (Tok.
is(tok::colon))
3987 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
3992 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3993 Tok.
isNot(tok::annot_pragma_openmp_end))
3999 }
else if (Kind == OMPC_order) {
4000 enum { Modifier, OrderKind, NumberOfElements };
4001 Arg.resize(NumberOfElements);
4002 KLoc.resize(NumberOfElements);
4009 Arg[Modifier] = KindModifier;
4011 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
4012 Tok.
isNot(tok::annot_pragma_openmp_end))
4015 if (Tok.
is(tok::colon))
4018 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
4022 Arg[OrderKind] = KindModifier;
4024 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
4025 Tok.
isNot(tok::annot_pragma_openmp_end))
4027 }
else if (Kind == OMPC_device) {
4040 KLoc.emplace_back();
4042 }
else if (Kind == OMPC_grainsize) {
4050 Arg.push_back(Modifier);
4057 if (Modifier == OMPC_GRAINSIZE_strict) {
4058 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4063 KLoc.emplace_back();
4067 KLoc.emplace_back();
4069 }
else if (Kind == OMPC_num_tasks) {
4077 Arg.push_back(Modifier);
4084 if (Modifier == OMPC_NUMTASKS_strict) {
4085 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4090 KLoc.emplace_back();
4094 KLoc.emplace_back();
4097 assert(Kind == OMPC_if);
4099 TentativeParsingAction TPA(*
this);
4102 if (DK != OMPD_unknown) {
4109 Arg.back() =
unsigned(OMPD_unknown);
4116 bool NeedAnExpression = (
Kind == OMPC_schedule && DelimLoc.
isValid()) ||
4117 (Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
4118 Kind == OMPC_if || Kind == OMPC_device ||
4119 Kind == OMPC_grainsize || Kind == OMPC_num_tasks;
4120 if (NeedAnExpression) {
4130 if (!
T.consumeClose())
4131 RLoc =
T.getCloseLocation();
4133 if (NeedAnExpression && Val.
isInvalid())
4139 Kind, Arg, Val.
get(),
Loc,
T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4144 if (ReductionIdScopeSpec.
isEmpty()) {
4146 switch (
P.getCurToken().getKind()) {
4181 return P.ParseUnqualifiedId(
4182 ReductionIdScopeSpec,
nullptr,
4186 false,
nullptr, ReductionId);
4192 Token Tok =
P.getCurToken();
4193 if (!Tok.
is(tok::identifier))
4200 return TypeModifier;
4207 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4208 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4214 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4218 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::kw_default)) {
4220 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4229 return T.consumeClose();
4240 bool HasMapType =
false;
4242 StringRef PreMapName =
"";
4246 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4247 TypeModifier == OMPC_MAP_MODIFIER_close ||
4248 TypeModifier == OMPC_MAP_MODIFIER_present ||
4249 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4250 Data.MapTypeModifiers.push_back(TypeModifier);
4255 <<
"map type modifier";
4257 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4258 Data.MapTypeModifiers.push_back(TypeModifier);
4263 if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::colon) &&
4265 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4266 <<
"map type modifier";
4271 Data.ExtraModifier = MapKind;
4276 Diag(Tok, diag::err_omp_more_one_map_type);
4277 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4285 if (Tok.
is(tok::comma)) {
4286 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4299 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4309 if (!Tok.
is(tok::colon)) {
4310 Diag(Tok, diag::err_omp_unknown_map_type);
4322 Token Tok =
P.getCurToken();
4324 if (!Tok.
isOneOf(tok::identifier, tok::kw_delete))
4329 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4330 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4331 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4340 Token Tok =
P.getCurToken();
4341 if (Tok.
is(tok::colon)) {
4342 P.Diag(Tok, diag::err_omp_map_type_missing);
4347 P.Diag(Tok, diag::err_omp_unknown_map_type);
4353ExprResult Parser::ParseOpenMPIteratorsExpr() {
4354 assert(Tok.
is(tok::identifier) && PP.
getSpelling(Tok) ==
"iterator" &&
4355 "Expected 'iterator' token.");
4359 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4364 while (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::annot_pragma_openmp_end)) {
4367 if (Tok.
isNot(tok::identifier) ||
NextToken().isNot(tok::equal)) {
4374 IteratorType = TR.
get();
4380 if (Tok.
is(tok::identifier)) {
4384 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4389 if (Tok.
is(tok::equal))
4392 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4398 ExprResult LHS = ParseCastExpression(AnyCastExpr);
4405 if (Tok.
is(tok::colon))
4410 LHS = ParseCastExpression(AnyCastExpr);
4419 if (Tok.
is(tok::colon)) {
4424 LHS = ParseCastExpression(AnyCastExpr);
4432 if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::r_paren))
4433 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4434 if (Tok.
is(tok::comma))
4439 D.DeclIdentLoc = IdLoc;
4440 D.Type = IteratorType;
4441 D.AssignLoc = AssignLoc;
4442 D.ColonLoc = ColonLoc;
4443 D.SecColonLoc = SecColonLoc;
4444 D.Range.Begin =
Begin.get();
4445 D.Range.End = End.get();
4446 D.Range.Step = Step.
get();
4451 if (!
T.consumeClose())
4452 RLoc =
T.getCloseLocation();
4463 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4466 if (Tok.
is(tok::identifier) &&
4469 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4470 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4471 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4472 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4473 Data.ExtraModifier != OMPC_DEPEND_inout)
4474 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4476 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4477 ? OMPC_DEPEND_outallmemory
4478 : OMPC_DEPEND_inoutallmemory;
4490 Sema &Actions =
P.getActions();
4494 Data.DepModOrTailExpr = Tail.
get();
4495 Token CurTok =
P.getCurToken();
4496 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4497 P.Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4510 bool InvalidReductionId =
false;
4511 bool IsInvalidMapperModifier =
false;
4515 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4516 getOpenMPClauseName(Kind).data()))
4519 bool HasIterator =
false;
4520 bool InvalidIterator =
false;
4521 bool NeedRParenForLinear =
false;
4523 tok::annot_pragma_openmp_end);
4525 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4526 Kind == OMPC_in_reduction) {
4528 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4529 (Tok.
is(tok::identifier) || Tok.
is(tok::kw_default)) &&
4532 Data.ExtraModifier =
4536 assert(Tok.
is(tok::comma) &&
"Expected comma.");
4541 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4546 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4547 if (InvalidReductionId) {
4548 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4551 if (Tok.
is(tok::colon))
4554 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4555 if (!InvalidReductionId)
4556 Data.ReductionOrMapperId =
4558 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4560 if (Tok.
is(tok::identifier) && PP.
getSpelling(Tok) ==
"iterator") {
4569 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4570 Data.DepModOrTailExpr = IteratorRes.
get();
4572 ExpectAndConsume(tok::comma);
4582 (Kind == OMPC_doacross &&
4584 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4589 if (DKind == OMPD_ordered && Kind == OMPC_depend &&
4590 Data.ExtraModifier == OMPC_DEPEND_source) {
4596 if (Tok.
is(tok::colon)) {
4598 }
else if (Kind != OMPC_doacross || Tok.
isNot(tok::r_paren)) {
4599 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4600 : diag::warn_pragma_expected_colon)
4601 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
4603 if (Kind == OMPC_doacross) {
4604 if (Tok.
is(tok::identifier) &&
4606 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
4607 ? OMPC_DOACROSS_source_omp_cur_iteration
4608 : OMPC_DOACROSS_sink_omp_cur_iteration;
4611 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
4612 if (Tok.
isNot(tok::minus)) {
4613 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4614 << getOpenMPClauseName(Kind) << 0 << 0;
4621 if (Tok.
isNot(tok::numeric_constant) ||
4623 Diag(
Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
4624 << getOpenMPClauseName(Kind) << 0 << 0;
4630 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
4631 if (Tok.
isNot(tok::r_paren)) {
4632 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4633 << getOpenMPClauseName(Kind) << 1 << 1;
4639 if (Kind == OMPC_doacross &&
4640 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
4641 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
4642 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
4648 }
else if (Kind == OMPC_linear) {
4650 Data.ExtraModifier = OMPC_LINEAR_val;
4651 if (Tok.
is(tok::identifier) && PP.
LookAhead(0).
is(tok::l_paren)) {
4652 Data.ExtraModifier =
4656 NeedRParenForLinear =
true;
4658 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
4659 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
4660 <<
"linear(list: [linear-modifier,] step(step-size))";
4662 }
else if (Kind == OMPC_lastprivate) {
4669 Tok.
is(tok::identifier) && PP.
LookAhead(0).
is(tok::colon)) {
4670 Data.ExtraModifier =
4674 assert(Tok.
is(tok::colon) &&
"Expected colon.");
4677 }
else if (Kind == OMPC_map) {
4679 if (Tok.
is(tok::identifier) && PP.
getSpelling(Tok) ==
"iterator") {
4682 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
4684 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4685 Data.IteratorExpr = IteratorRes.
get();
4687 ExpectAndConsume(tok::comma);
4689 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4692 InvalidIterator =
true;
4705 TentativeParsingAction TPA(*
this);
4706 bool ColonPresent =
false;
4707 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4709 if (Tok.
is(tok::colon))
4710 ColonPresent =
true;
4717 Diag(Tok, diag::err_omp_map_modifier_specification_list);
4719 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
4725 Data.ExtraModifier = OMPC_MAP_tofrom;
4727 if (DKind == OMPD_target_enter_data)
4728 Data.ExtraModifier = OMPC_MAP_to;
4729 else if (DKind == OMPD_target_exit_data)
4730 Data.ExtraModifier = OMPC_MAP_from;
4732 Data.IsMapTypeImplicit =
true;
4735 if (Tok.
is(tok::colon))
4737 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
4738 while (Tok.
is(tok::identifier)) {
4743 Data.MotionModifiers.push_back(Modifier);
4746 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
4748 if (IsInvalidMapperModifier)
4756 if (Tok.
is(tok::comma))
4759 if (!
Data.MotionModifiers.empty() && Tok.
isNot(tok::colon)) {
4760 if (!IsInvalidMapperModifier) {
4762 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
4764 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
4766 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4774 }
else if (Kind == OMPC_allocate ||
4775 (Kind == OMPC_affinity && Tok.
is(tok::identifier) &&
4779 TentativeParsingAction TPA(*
this);
4784 if (Kind == OMPC_allocate) {
4789 Tail = ParseOpenMPIteratorsExpr();
4795 if (Tok.
is(tok::colon)) {
4796 Data.DepModOrTailExpr = Tail.
get();
4807 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4810 }
else if (Kind == OMPC_adjust_args) {
4818 Diag(Tok, diag::err_omp_unknown_adjust_args_op);
4822 if (Tok.
is(tok::colon))
4824 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
4830 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
4831 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
4832 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
4833 (Kind == OMPC_reduction && !InvalidReductionId) ||
4837 (Kind == OMPC_adjust_args &&
4839 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
4840 while (IsComma || (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::colon) &&
4841 Tok.
isNot(tok::annot_pragma_openmp_end))) {
4849 Vars.push_back(VarExpr.
get());
4851 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4856 IsComma = Tok.
is(tok::comma);
4859 else if (Tok.
isNot(tok::r_paren) &&
4860 Tok.
isNot(tok::annot_pragma_openmp_end) &&
4861 (!MayHaveTail || Tok.
isNot(tok::colon)))
4862 Diag(Tok, diag::err_omp_expected_punc)
4863 << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
4864 : getOpenMPClauseName(Kind))
4865 << (Kind == OMPC_flush);
4869 if (NeedRParenForLinear)
4874 const bool MustHaveTail = MayHaveTail && Tok.
is(tok::colon);
4875 bool StepFound =
false;
4876 bool ModifierFound =
false;
4881 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
4882 while (Tok.
isNot(tok::r_paren)) {
4883 if (Tok.
is(tok::identifier)) {
4891 if (LinKind == OMPC_LINEAR_step) {
4893 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
4896 tok::annot_pragma_openmp_end);
4900 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
4905 Data.StepModifierLoc = StepModifierLoc;
4909 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
4911 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
4913 Data.ExtraModifier = LinKind;
4915 ModifierFound =
true;
4924 if (Tok.
is(tok::comma))
4926 if (Tok.
is(tok::r_paren) || Tok.
is(tok::annot_pragma_openmp_end))
4929 if (!StepFound && !ModifierFound)
4930 Diag(ELoc, diag::err_expected_expression);
4937 Data.DepModOrTailExpr = Tail.
get();
4939 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4946 if (!
T.consumeClose())
4947 Data.RLoc =
T.getCloseLocation();
4951 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
4953 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
4954 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5037 assert(getOpenMPClauseName(Kind) == PP.
getSpelling(Tok) &&
5038 "Expected parsing to start at clause name");
5043 if (
T.consumeOpen()) {
5044 Diag(Tok, diag::err_expected) << tok::l_paren;
5057 Exprs.push_back(Val.
get());
5060 bool Result =
T.consumeClose();
5061 OpenLoc =
T.getOpenLocation();
5062 CloseLoc =
T.getCloseLocation();
Defines the clang::ASTContext interface.
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
static OpenMPDirectiveKindExWrapper 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 unsigned getOpenMPDirectiveKindEx(StringRef S)
static bool checkExtensionProperty(Parser &P, SourceLocation Loc, OMPTraitProperty &TIProperty, OMPTraitSelector &TISelector, llvm::StringMap< SourceLocation > &Seen)
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.
This file defines OpenMP AST classes for executable directives and clauses.
Defines the clang::TokenKind enum and support functions.
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.
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
Captures information about "declaration specifiers".
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.
Information about one declarator, including the parsed type information and the identifier.
RAII object that enters a new expression evaluation context.
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.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
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.
Helper data structure representing the traits in a match clause of an declare variant or metadirectiv...
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.
Wrapper for void* pointer.
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
ParsedAttr - Represents a syntactic attribute.
static const ParsedAttributesView & none()
ParsedAttributes - A collection of parsed attributes.
Introduces zero or more scopes for parsing.
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 type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
bool parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data)
Parses map-type-modifiers in map clause.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
bool parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data)
Parses the mapper modifier in map, to, and from clauses.
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.
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 ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
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
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
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.
A class for parsing a DeclSpec.
Activates OpenMP parsing mode to preseve OpenMP specific annotation tokens.
void enterVariableInit(SourceLocation Tok, Decl *D)
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value)
Parses a simple integer literal to get its numeric value.
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 isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
A (possibly-)qualified type.
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.
Scope - A scope is a transient data structure that is used while parsing the program.
@ 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.
AMDGPUWavesPerEUAttr * CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
Create an AMDGPUWavesPerEUAttr attribute.
AMDGPUFlatWorkGroupSizeAttr * CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
Create an AMDGPUWavesPerEUAttr attribute.
QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)
void CodeCompleteInitializer(Scope *S, Decl *D)
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
OMPClause * ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'use' clause.
void ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called once a target context is completed, that can be when a '#pragma omp end declare target' was en...
OMPClause * ActOnOpenMPDirectivePresenceClause(OpenMPClauseKind CK, llvm::ArrayRef< OpenMPDirectiveKind > DKVec, SourceLocation Loc, SourceLocation LLoc, SourceLocation RLoc)
Called on well-formed 'absent' or 'contains' clauses.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
ExprResult ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)
Build the mapper variable of '#pragma omp declare mapper'.
StmtResult ActOnOpenMPErrorDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, bool InExContext=true)
Called on well-formed '#pragma omp error'.
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause * > ClauseList)
Called on well-formed '#pragma omp requires'.
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'destroy' clause.
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
void ActOnOpenMPEndAssumesDirective()
Called on well-formed '#pragma omp end assumes'.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList, ArrayRef< OMPClause * > Clauses, DeclContext *Owner=nullptr)
Called on well-formed '#pragma omp allocate'.
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
bool isInOpenMPDeclareVariantScope() const
Can we exit an OpenMP declare variant scope at the moment.
TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D)
Check variable declaration in 'omp declare mapper' construct.
ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, ArrayRef< OMPIteratorData > Data)
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation > > ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare reduction'.
void ActOnOpenMPEndDeclareVariant()
Handle a omp end declare variant.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
OMPClause * ActOnOpenMPSizesClause(ArrayRef< Expr * > SizeExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'sizes' clause.
bool ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called on the start of target region i.e. '#pragma omp declare target'.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
void EndOpenMPClause()
End analysis of clauses.
bool isInOpenMPAssumeScope() const
Check if there is an active global omp begin assumes directive.
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare mapper' construct.
std::optional< std::pair< FunctionDecl *, Expr * > > checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, OMPTraitInfo &TI, unsigned NumAppendArgs, SourceRange SR)
Checks '#pragma omp declare variant' variant function and original functions after parsing of the ass...
StmtResult ActOnOpenMPInformationalDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Process an OpenMP informational directive.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPNullaryAssumptionClause(OpenMPClauseKind CK, SourceLocation Loc, SourceLocation RLoc)
OMPClause * ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'init' clause.
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
bool isInOpenMPDeclareTargetContext() const
Return true inside OpenMP declare target region.
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, ArrayRef< Expr * > AdjustArgsNothing, ArrayRef< Expr * > AdjustArgsNeedDevicePtr, ArrayRef< OMPInteropInfo > AppendArgs, SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, SourceRange SR)
Called on well-formed '#pragma omp declare variant' after parsing of the associated method/function.
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr * > Uniforms, ArrayRef< Expr * > Aligneds, ArrayRef< Expr * > Alignments, ArrayRef< Expr * > Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr * > Steps, SourceRange SR)
Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.
OMPClause * ActOnOpenMPXAttributeClause(ArrayRef< const Attr * > Attrs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_attribute' clause.
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
NamedDecl * lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Searches for the provided declaration name for OpenMP declare target directive.
void ActOnOpenMPAssumesDirective(SourceLocation Loc, OpenMPDirectiveKind DKind, ArrayRef< std::string > Assumptions, bool SkippedClauses)
Called on well-formed '#pragma omp [begin] assume[s]'.
void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI)
Handle a omp begin declare variant.
StmtResult ActOnOpenMPLoopnest(Stmt *AStmt)
Process a canonical OpenMP loop nest that can either be a canonical literal loop (ForStmt or CXXForRa...
const DeclareTargetContextInfo ActOnOpenMPEndDeclareTargetDirective()
Called at the end of target region i.e. '#pragma omp end declare target'.
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
DeclGroupPtrTy ActOnOpenMPDeclareMapperDirective(Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, Expr *MapperVarRef, ArrayRef< OMPClause * > Clauses, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare mapper'.
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
A RAII object to enter scope of a compound statement.
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=NoFold)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
void ActOnReenterFunctionContext(Scope *S, Decl *D)
Push the parameters of D, which must be a function, into scope.
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
DeclarationNameInfo GetNameForDeclarator(Declarator &D)
GetNameForDeclarator - Determine the full declaration name for the given Declarator.
ASTContext & getASTContext() const
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
SemaCodeCompletion & CodeCompletion()
DeclContext * getCurLexicalContext() const
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name)
Retrieves the declaration name from a parsed unqualified-id.
void ActOnInitializerError(Decl *Dcl)
ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
CUDALaunchBoundsAttr * CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks)
Create an CUDALaunchBoundsAttr attribute.
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
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.
SourceLocation getBegin() const
StringLiteral - This represents a string literal expression, e.g.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
SourceLocation getEndLoc() const
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 isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
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.
Directive - Abstract class representing a parsed verify directive.
Defines the clang::TargetInfo interface.
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
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.
TypeSpecifierType
Specifies the kind of type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
@ OMPC_DEFAULTMAP_MODIFIER_unknown
@ OMPC_ORDER_MODIFIER_unknown
@ OMPC_ADJUST_ARGS_unknown
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
OpenMPDeviceType
OpenMP device type for 'device_type' clause.
@ OMPC_DEVICE_TYPE_unknown
@ OMPC_SCHEDULE_MODIFIER_unknown
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
@ Property
The type of a property.
@ Result
The result type of a method or function.
@ OMPC_LASTPRIVATE_unknown
OpenMPGrainsizeClauseModifier
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str, const LangOptions &LangOpts)
OpenMPNumTasksClauseModifier
ActionResult< Expr * > ExprResult
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
bool operator!=(CanQual< T > x, CanQual< U > y)
@ OMPC_DEFAULTMAP_unknown
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "executable".
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.
const FunctionProtoType * T
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
@ OMPC_MAP_MODIFIER_unknown
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
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< Expr *, 4 > PreferTypes
llvm::omp::TraitProperty Kind
StringRef RawString
The raw string as we parsed it.
llvm::omp::TraitSelector Kind
llvm::SmallVector< OMPTraitProperty, 1 > Properties
llvm::SmallVector< OMPTraitSelector, 2 > Selectors
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.
Data structure for iterator expression.
Data used for processing a list of variables in OpenMP clauses.
Data for list of allocators.
Clang specific specialization of the OMPContext to lookup target features.