24#include "llvm/ADT/PointerIntPair.h"
25#include "llvm/ADT/StringSwitch.h"
26#include "llvm/ADT/UniqueVector.h"
27#include "llvm/Frontend/OpenMP/OMPAssume.h"
28#include "llvm/Frontend/OpenMP/OMPContext.h"
32using namespace llvm::omp;
39enum OpenMPDirectiveKindEx {
40 OMPD_cancellation = llvm::omp::Directive_enumSize + 1,
52 OMPD_distribute_parallel,
53 OMPD_teams_distribute_parallel,
54 OMPD_target_teams_distribute_parallel,
64struct OpenMPDirectiveKindExWrapper {
67 bool operator==(OpenMPDirectiveKindExWrapper
V)
const {
70 bool operator!=(OpenMPDirectiveKindExWrapper
V)
const {
81class DeclDirectiveListParserHelper final {
90 ExprResult Res =
P->getActions().ActOnOpenMPIdExpression(
91 P->getCurScope(), SS, NameInfo, Kind);
93 Identifiers.push_back(Res.
get());
102 OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);
103 if (DKind != OMPD_unknown)
106 return llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)
107 .Case(
"cancellation", OMPD_cancellation)
108 .Case(
"data", OMPD_data)
109 .Case(
"declare", OMPD_declare)
110 .Case(
"end", OMPD_end)
111 .Case(
"enter", OMPD_enter)
112 .Case(
"exit", OMPD_exit)
113 .Case(
"point", OMPD_point)
114 .Case(
"reduction", OMPD_reduction)
115 .Case(
"update", OMPD_update)
116 .Case(
"mapper", OMPD_mapper)
117 .Case(
"variant", OMPD_variant)
118 .Case(
"begin", OMPD_begin)
119 .Default(OMPD_unknown);
126 static const OpenMPDirectiveKindExWrapper F[][3] = {
127 {OMPD_begin, OMPD_declare, OMPD_begin_declare},
128 {OMPD_begin, OMPD_assumes, OMPD_begin_assumes},
129 {OMPD_end, OMPD_declare, OMPD_end_declare},
130 {OMPD_end, OMPD_assumes, OMPD_end_assumes},
131 {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
132 {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
133 {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
134 {OMPD_declare, OMPD_simd, OMPD_declare_simd},
135 {OMPD_declare, OMPD_target, OMPD_declare_target},
136 {OMPD_declare, OMPD_variant, OMPD_declare_variant},
137 {OMPD_begin_declare, OMPD_target, OMPD_begin_declare_target},
138 {OMPD_begin_declare, OMPD_variant, OMPD_begin_declare_variant},
139 {OMPD_end_declare, OMPD_variant, OMPD_end_declare_variant},
140 {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
141 {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
142 {OMPD_distribute_parallel_for, OMPD_simd,
143 OMPD_distribute_parallel_for_simd},
144 {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
145 {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
146 {OMPD_target, OMPD_data, OMPD_target_data},
147 {OMPD_target, OMPD_enter, OMPD_target_enter},
148 {OMPD_target, OMPD_exit, OMPD_target_exit},
149 {OMPD_target, OMPD_update, OMPD_target_update},
150 {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
151 {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
152 {OMPD_for, OMPD_simd, OMPD_for_simd},
153 {OMPD_parallel, OMPD_for, OMPD_parallel_for},
154 {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
155 {OMPD_parallel, OMPD_loop, OMPD_parallel_loop},
156 {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
157 {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
158 {OMPD_target, OMPD_parallel, OMPD_target_parallel},
159 {OMPD_target, OMPD_simd, OMPD_target_simd},
160 {OMPD_target_parallel, OMPD_loop, OMPD_target_parallel_loop},
161 {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
162 {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
163 {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
164 {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
165 {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
166 {OMPD_teams_distribute_parallel, OMPD_for,
167 OMPD_teams_distribute_parallel_for},
168 {OMPD_teams_distribute_parallel_for, OMPD_simd,
169 OMPD_teams_distribute_parallel_for_simd},
170 {OMPD_teams, OMPD_loop, OMPD_teams_loop},
171 {OMPD_target, OMPD_teams, OMPD_target_teams},
172 {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
173 {OMPD_target_teams, OMPD_loop, OMPD_target_teams_loop},
174 {OMPD_target_teams_distribute, OMPD_parallel,
175 OMPD_target_teams_distribute_parallel},
176 {OMPD_target_teams_distribute, OMPD_simd,
177 OMPD_target_teams_distribute_simd},
178 {OMPD_target_teams_distribute_parallel, OMPD_for,
179 OMPD_target_teams_distribute_parallel_for},
180 {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
181 OMPD_target_teams_distribute_parallel_for_simd},
182 {OMPD_master, OMPD_taskloop, OMPD_master_taskloop},
183 {OMPD_masked, OMPD_taskloop, OMPD_masked_taskloop},
184 {OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},
185 {OMPD_masked_taskloop, OMPD_simd, OMPD_masked_taskloop_simd},
186 {OMPD_parallel, OMPD_master, OMPD_parallel_master},
187 {OMPD_parallel, OMPD_masked, OMPD_parallel_masked},
188 {OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},
189 {OMPD_parallel_masked, OMPD_taskloop, OMPD_parallel_masked_taskloop},
190 {OMPD_parallel_master_taskloop, OMPD_simd,
191 OMPD_parallel_master_taskloop_simd},
192 {OMPD_parallel_masked_taskloop, OMPD_simd,
193 OMPD_parallel_masked_taskloop_simd}};
194 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
195 Token Tok =
P.getCurToken();
196 OpenMPDirectiveKindExWrapper DKind =
198 ?
static_cast<unsigned>(OMPD_unknown)
200 if (DKind == OMPD_unknown)
203 for (
const auto &I : F) {
207 Tok =
P.getPreprocessor().LookAhead(0);
208 OpenMPDirectiveKindExWrapper SDKind =
210 ?
static_cast<unsigned>(OMPD_unknown)
212 if (SDKind == OMPD_unknown)
215 if (SDKind == I[1]) {
220 return unsigned(DKind) < llvm::omp::Directive_enumSize
226 Token Tok =
P.getCurToken();
227 Sema &Actions =
P.getActions();
230 bool WithOperator =
false;
231 if (Tok.
is(tok::kw_operator)) {
233 Tok =
P.getCurToken();
261 case tok::identifier:
266 P.Diag(Tok.
getLocation(), diag::err_omp_expected_reduction_identifier);
267 P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
274 : DeclNames.getCXXOperatorName(OOK);
291 if (T.expectAndConsume(
292 diag::err_expected_lparen_after,
293 getOpenMPDirectiveName(OMPD_declare_reduction).data())) {
299 if (Name.isEmpty() && Tok.
is(tok::annot_pragma_openmp_end))
303 bool IsCorrect = !ExpectAndConsume(tok::colon);
305 if (!IsCorrect && Tok.
is(tok::annot_pragma_openmp_end))
308 IsCorrect = IsCorrect && !Name.isEmpty();
310 if (Tok.
is(tok::colon) || Tok.
is(tok::annot_pragma_openmp_end)) {
315 if (!IsCorrect && Tok.
is(tok::annot_pragma_openmp_end))
327 if (!ReductionType.
isNull()) {
328 ReductionTypes.push_back(
329 std::make_pair(ReductionType,
Range.getBegin()));
332 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
336 if (Tok.
is(tok::colon) || Tok.
is(tok::annot_pragma_openmp_end))
340 if (ExpectAndConsume(tok::comma)) {
342 if (Tok.
is(tok::annot_pragma_openmp_end)) {
347 }
while (Tok.
isNot(tok::annot_pragma_openmp_end));
349 if (ReductionTypes.empty()) {
354 if (!IsCorrect && Tok.
is(tok::annot_pragma_openmp_end))
358 if (ExpectAndConsume(tok::colon))
361 if (Tok.
is(tok::annot_pragma_openmp_end)) {
371 unsigned I = 0, E = ReductionTypes.size();
372 for (
Decl *D : DRD.get()) {
373 TentativeParsingAction TPA(*
this);
384 Tok.
isNot(tok::annot_pragma_openmp_end)) {
389 IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.
isUsable();
391 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
393 if (Tok.
is(tok::identifier) &&
404 tok::annot_pragma_openmp_end);
406 !T.expectAndConsume(diag::err_expected_lparen_after,
"initializer") &&
408 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
417 if (Tok.
is(tok::identifier) &&
420 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
427 D, InitializerResult.
get(), OmpPrivParm);
429 Tok.
isNot(tok::annot_pragma_openmp_end)) {
435 !T.consumeClose() && IsCorrect && !InitializerResult.
isInvalid();
451void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
454 if (isTokenEqualOrEqualTypo()) {
457 if (Tok.
is(tok::code_completion)) {
467 if (
Init.isInvalid()) {
474 }
else if (Tok.
is(tok::l_paren)) {
482 auto RunSignatureHelp = [
this, OmpPrivParm, LParLoc, &Exprs]() {
485 OmpPrivParm->
getLocation(), Exprs, LParLoc,
false);
486 CalledSignatureHelp =
true;
487 return PreferredType;
489 if (ParseExpressionList(Exprs, [&] {
490 PreferredType.enterFunctionArgument(Tok.
getLocation(),
500 if (!T.consumeClose())
501 RLoc = T.getCloseLocation();
510 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
514 if (
Init.isInvalid()) {
535 bool IsCorrect =
true;
538 if (T.expectAndConsume(diag::err_expected_lparen_after,
539 getOpenMPDirectiveName(OMPD_declare_mapper).data())) {
548 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::kw_default)) {
556 ExpectAndConsume(tok::colon);
563 if (!IsCorrect && Tok.
is(tok::annot_pragma_openmp_end))
582 IsCorrect &= !T.consumeClose();
593 ParseScope OMPDirectiveScope(
this, ScopeFlags);
602 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
608 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
610 Clauses.push_back(Clause);
614 if (Tok.
is(tok::comma))
618 if (Clauses.empty()) {
619 Diag(Tok, diag::err_omp_expected_clause)
620 << getOpenMPDirectiveName(OMPD_declare_mapper);
626 OMPDirectiveScope.Exit();
629 Range.getBegin(), VName, AS, MapperVarRef.
get(), Clauses);
640 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
642 ParseSpecifierQualifierList(DS, AS, DSC);
647 ParseDeclarator(DeclaratorInfo);
648 Range = DeclaratorInfo.getSourceRange();
649 if (DeclaratorInfo.getIdentifier() ==
nullptr) {
664class FNContextRAII final {
668 bool HasFunScope =
false;
669 FNContextRAII() =
delete;
670 FNContextRAII(
const FNContextRAII &) =
delete;
671 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
678 Sema &Actions =
P.getActions();
686 P.ReenterTemplateScopes(Scopes, D);
698 P.getActions().ActOnExitFunctionContext();
717 const Token &Tok =
P.getCurToken();
718 bool IsError =
false;
719 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
720 if (Tok.
isNot(tok::identifier))
722 OMPDeclareSimdDeclAttr::BranchStateTy Out;
724 StringRef ClauseName = II->
getName();
726 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
727 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
728 P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
730 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
736 }
else if (ClauseName.equals(
"simdlen")) {
738 P.Diag(Tok, diag::err_omp_more_one_clause)
739 << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
744 SimdLen =
P.ParseOpenMPParensExpr(ClauseName, RLoc);
749 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
750 CKind == OMPC_linear) {
753 if (CKind == OMPC_aligned) {
755 }
else if (CKind == OMPC_linear) {
756 Data.ExtraModifier = OMPC_LINEAR_val;
761 if (
P.ParseOpenMPVarList(OMPD_declare_simd,
762 getOpenMPClauseKind(ClauseName), *Vars,
Data))
764 if (CKind == OMPC_aligned) {
765 Alignments.append(Aligneds.size() - Alignments.size(),
766 Data.DepModOrTailExpr);
767 }
else if (CKind == OMPC_linear) {
768 assert(0 <=
Data.ExtraModifier &&
770 "Unexpected linear modifier.");
771 if (
P.getActions().CheckOpenMPLinearModifier(
773 Data.ExtraModifierLoc))
774 Data.ExtraModifier = OMPC_LINEAR_val;
775 LinModifiers.append(Linears.size() - LinModifiers.size(),
777 Steps.append(Linears.size() - Steps.size(),
Data.DepModOrTailExpr);
784 if (Tok.
is(tok::comma))
795 PP.EnterTokenStream(Toks,
true,
801 FNContextRAII FnContext(*
this, Ptr);
802 OMPDeclareSimdDeclAttr::BranchStateTy BS =
803 OMPDeclareSimdDeclAttr::BS_Undefined;
813 Alignments, Linears, LinModifiers, Steps);
814 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
820 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
828 CONTEXT_SELECTOR_SET_LVL = 0,
829 CONTEXT_SELECTOR_LVL = 1,
830 CONTEXT_TRAIT_LVL = 2,
833static StringRef stringLiteralParser(
Parser &
P) {
834 ExprResult Res =
P.ParseStringLiteralExpression(
true);
838static StringRef getNameFromIdOrString(
Parser &
P,
Token &Tok,
840 if (Tok.
is(tok::identifier) || Tok.
is(tok::kw_for)) {
842 StringRef Name =
P.getPreprocessor().getSpelling(Tok, Buffer);
843 (void)
P.ConsumeToken();
848 return stringLiteralParser(
P);
851 diag::warn_omp_declare_variant_string_literal_or_identifier)
856static bool checkForDuplicates(
Parser &
P, StringRef Name,
858 llvm::StringMap<SourceLocation> &Seen,
860 auto Res = Seen.try_emplace(Name, NameLoc);
866 P.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
868 P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
875 llvm::omp::TraitSet
Set,
877 llvm::StringMap<SourceLocation> &Seen) {
878 TIProperty.
Kind = TraitProperty::invalid;
881 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_TRAIT_LVL);
884 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set,
Selector);
889 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set,
Selector, Name);
890 if (TIProperty.
Kind != TraitProperty::invalid) {
891 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
892 TIProperty.
Kind = TraitProperty::invalid;
898 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
899 << Name << getOpenMPContextTraitSelectorName(
Selector)
900 << getOpenMPContextTraitSetName(
Set);
902 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
903 if (SetForName != TraitSet::invalid) {
904 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
905 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
906 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
907 << Name <<
"<selector-name>"
908 <<
"(<property-name>)";
911 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
912 if (SelectorForName != TraitSelector::invalid) {
913 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
914 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
915 bool AllowsTraitScore =
false;
916 bool RequiresProperty =
false;
917 isValidTraitSelectorForTraitSet(
918 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
919 AllowsTraitScore, RequiresProperty);
920 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
921 << getOpenMPContextTraitSetName(
922 getOpenMPContextTraitSetForSelector(SelectorForName))
923 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
926 for (
const auto &PotentialSet :
927 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
929 TraitProperty PropertyForName =
930 getOpenMPContextTraitPropertyKind(PotentialSet,
Selector, Name);
931 if (PropertyForName == TraitProperty::invalid)
933 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
934 << getOpenMPContextTraitSetName(
935 getOpenMPContextTraitSetForProperty(PropertyForName))
936 << getOpenMPContextTraitSelectorName(
937 getOpenMPContextTraitSelectorForProperty(PropertyForName))
938 << (
"(" + Name +
")").str();
941 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
942 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set,
Selector);
948 llvm::StringMap<SourceLocation> &Seen) {
949 assert(TISelector.
Kind ==
950 llvm::omp::TraitSelector::implementation_extension &&
951 "Only for extension properties, e.g., "
952 "`implementation={extension(PROPERTY)}`");
953 if (TIProperty.
Kind == TraitProperty::invalid)
956 if (TIProperty.
Kind ==
957 TraitProperty::implementation_extension_disable_implicit_base)
960 if (TIProperty.
Kind ==
961 TraitProperty::implementation_extension_allow_templates)
964 if (TIProperty.
Kind ==
965 TraitProperty::implementation_extension_bind_to_declaration)
970 llvm::omp::TraitProperty::implementation_extension_match_all ||
972 llvm::omp::TraitProperty::implementation_extension_match_any ||
974 llvm::omp::TraitProperty::implementation_extension_match_none);
977 if (IsMatchExtension(TIProperty)) {
979 if (IsMatchExtension(SeenProp)) {
980 P.Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
981 StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
984 P.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
985 << CONTEXT_TRAIT_LVL << SeenName;
991 llvm_unreachable(
"Unknown extension property!");
995 llvm::omp::TraitSet
Set,
996 llvm::StringMap<SourceLocation> &Seen) {
997 assert(TISelector.
Kind != TraitSelector::user_condition &&
998 "User conditions are special properties not handled here!");
1002 parseOMPTraitPropertyKind(TIProperty,
Set, TISelector.
Kind, Seen);
1004 if (TISelector.
Kind == llvm::omp::TraitSelector::implementation_extension)
1007 TIProperty.
Kind = TraitProperty::invalid;
1010 if (TIProperty.
Kind == TraitProperty::invalid) {
1012 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1013 << CONTEXT_TRAIT_LVL;
1017 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.
Kind,
1026 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
1027 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
1029 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1030 << getOpenMPContextTraitSetName(
Set);
1031 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
1032 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
1034 << getOpenMPContextTraitSelectorName(
1035 getOpenMPContextTraitSelectorForProperty(TIProperty.
Kind))
1036 << getOpenMPContextTraitSetName(
1037 getOpenMPContextTraitSetForProperty(TIProperty.
Kind));
1038 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1039 << CONTEXT_TRAIT_LVL;
1043 llvm::omp::TraitSet
Set,
1044 llvm::StringMap<SourceLocation> &Seen) {
1045 TISelector.
Kind = TraitSelector::invalid;
1048 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_LVL);
1051 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1055 TISelector.
Kind = getOpenMPContextTraitSelectorKind(Name);
1056 if (TISelector.
Kind != TraitSelector::invalid) {
1057 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1058 TISelector.
Kind = TraitSelector::invalid;
1063 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1064 << Name << getOpenMPContextTraitSetName(
Set);
1066 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1067 if (SetForName != TraitSet::invalid) {
1068 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1069 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1070 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1071 << Name <<
"<selector-name>"
1072 <<
"<property-name>";
1075 for (
const auto &PotentialSet :
1076 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1077 TraitSet::device}) {
1078 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1079 PotentialSet, TraitSelector::invalid, Name);
1080 if (PropertyForName == TraitProperty::invalid)
1082 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1083 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1084 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1085 << getOpenMPContextTraitSetName(
1086 getOpenMPContextTraitSetForProperty(PropertyForName))
1087 << getOpenMPContextTraitSelectorName(
1088 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1089 << (
"(" + Name +
")").str();
1092 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1093 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1100 StringRef SelectorName =
1101 P.getPreprocessor().getSpelling(
P.getCurToken(), Buffer);
1102 if (!SelectorName.equals(
"score"))
1104 (void)
P.ConsumeToken();
1106 ScoreExpr =
P.ParseOpenMPParensExpr(SelectorName, RLoc);
1108 if (
P.getCurToken().is(tok::colon))
1109 (
void)
P.ConsumeAnyToken();
1111 P.Diag(
P.getCurToken(), diag::warn_omp_declare_variant_expected)
1113 <<
"score expression";
1120void Parser::parseOMPContextSelector(
1122 llvm::StringMap<SourceLocation> &SeenSelectors) {
1123 unsigned short OuterPC = ParenCount;
1128 auto FinishSelector = [OuterPC,
this]() ->
void {
1131 while (!
SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1132 tok::annot_pragma_openmp_end},
1135 if (Tok.
is(tok::r_paren) && OuterPC > ParenCount)
1136 (
void)ConsumeParen();
1137 if (OuterPC <= ParenCount) {
1141 if (!Tok.
is(tok::comma) && !Tok.
is(tok::r_paren)) {
1147 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1148 << CONTEXT_SELECTOR_LVL;
1152 parseOMPTraitSelectorKind(TISelector,
Set, SeenSelectors);
1153 if (TISelector.
Kind == TraitSelector::invalid)
1154 return FinishSelector();
1156 bool AllowsTraitScore =
false;
1157 bool RequiresProperty =
false;
1158 if (!isValidTraitSelectorForTraitSet(TISelector.
Kind,
Set, AllowsTraitScore,
1159 RequiresProperty)) {
1160 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1161 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1162 << getOpenMPContextTraitSetName(
Set);
1163 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1164 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1165 << getOpenMPContextTraitSetName(
1166 getOpenMPContextTraitSetForSelector(TISelector.
Kind))
1167 << RequiresProperty;
1168 return FinishSelector();
1171 if (!RequiresProperty) {
1173 {getOpenMPContextTraitPropertyForSelector(TISelector.
Kind),
1174 getOpenMPContextTraitSelectorName(TISelector.
Kind)});
1178 if (!Tok.
is(tok::l_paren)) {
1179 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1180 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1181 << getOpenMPContextTraitSetName(
Set);
1182 return FinishSelector();
1185 if (TISelector.
Kind == TraitSelector::user_condition) {
1189 return FinishSelector();
1192 {TraitProperty::user_condition_unknown,
"<condition>"});
1197 tok::annot_pragma_openmp_end);
1199 (void)BDT.consumeOpen();
1204 if (!AllowsTraitScore && !Score.
isUnset()) {
1206 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1207 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1208 << getOpenMPContextTraitSetName(
Set) << Score.
get();
1210 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1211 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1212 << getOpenMPContextTraitSetName(
Set) <<
"<invalid>";
1220 llvm::StringMap<SourceLocation> SeenProperties;
1222 parseOMPContextProperty(TISelector,
Set, SeenProperties);
1229void Parser::parseOMPTraitSetKind(
OMPTraitSet &TISet,
1230 llvm::StringMap<SourceLocation> &Seen) {
1231 TISet.
Kind = TraitSet::invalid;
1234 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_SET_LVL);
1237 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1241 TISet.
Kind = getOpenMPContextTraitSetKind(Name);
1242 if (TISet.
Kind != TraitSet::invalid) {
1243 if (checkForDuplicates(*
this, Name, NameLoc, Seen,
1244 CONTEXT_SELECTOR_SET_LVL))
1245 TISet.
Kind = TraitSet::invalid;
1250 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1252 TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1253 if (SelectorForName != TraitSelector::invalid) {
1254 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1255 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1256 bool AllowsTraitScore =
false;
1257 bool RequiresProperty =
false;
1258 isValidTraitSelectorForTraitSet(
1259 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1260 AllowsTraitScore, RequiresProperty);
1261 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1262 << getOpenMPContextTraitSetName(
1263 getOpenMPContextTraitSetForSelector(SelectorForName))
1264 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
1267 for (
const auto &PotentialSet :
1268 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1269 TraitSet::device}) {
1270 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1271 PotentialSet, TraitSelector::invalid, Name);
1272 if (PropertyForName == TraitProperty::invalid)
1274 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1275 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1276 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1277 << getOpenMPContextTraitSetName(
1278 getOpenMPContextTraitSetForProperty(PropertyForName))
1279 << getOpenMPContextTraitSelectorName(
1280 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1281 << (
"(" + Name +
")").str();
1284 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1285 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1291void Parser::parseOMPContextSelectorSet(
1292 OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1293 auto OuterBC = BraceCount;
1298 auto FinishSelectorSet = [
this, OuterBC]() ->
void {
1301 while (!
SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1302 tok::annot_pragma_openmp_end},
1305 if (Tok.
is(tok::r_brace) && OuterBC > BraceCount)
1306 (
void)ConsumeBrace();
1307 if (OuterBC <= BraceCount) {
1311 if (!Tok.
is(tok::comma) && !Tok.
is(tok::r_brace)) {
1317 Diag(Tok.
getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1318 << CONTEXT_SELECTOR_SET_LVL;
1321 parseOMPTraitSetKind(TISet, SeenSets);
1322 if (TISet.
Kind == TraitSet::invalid)
1323 return FinishSelectorSet();
1329 << (
"context set name \"" + getOpenMPContextTraitSetName(TISet.
Kind) +
1334 if (Tok.
is(tok::l_brace)) {
1335 (void)ConsumeBrace();
1339 << (
"'=' that follows the context set name \"" +
1340 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1344 llvm::StringMap<SourceLocation> SeenSelectors;
1347 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1348 if (TISelector.
Kind != TraitSelector::invalid &&
1354 if (Tok.
is(tok::r_brace)) {
1355 (void)ConsumeBrace();
1359 << (
"context selectors for the context set \"" +
1360 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1369 llvm::StringMap<SourceLocation> SeenSets;
1372 parseOMPContextSelectorSet(TISet, SeenSets);
1373 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1374 TI.
Sets.push_back(TISet);
1385 PP.EnterTokenStream(Toks,
true,
1391 FNContextRAII FnContext(*
this, Ptr);
1403 getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1406 if (!AssociatedFunction.
isUsable()) {
1407 if (!Tok.
is(tok::annot_pragma_openmp_end))
1411 (void)ConsumeAnnotationToken();
1415 OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
1424 if (Tok.
is(tok::annot_pragma_openmp_end)) {
1429 bool IsError =
false;
1430 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1434 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1443 IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1445 case OMPC_adjust_args: {
1453 llvm::append_range(
Data.ExtraModifier == OMPC_ADJUST_ARGS_nothing
1455 : AdjustNeedDevicePtr,
1459 case OMPC_append_args:
1460 if (!AppendArgs.empty()) {
1461 Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1462 << getOpenMPDirectiveName(OMPD_declare_variant)
1463 << getOpenMPClauseName(CKind) << 0;
1469 IsError = parseOpenMPAppendArgs(AppendArgs);
1473 llvm_unreachable(
"Unexpected clause for declare variant.");
1480 (void)ConsumeAnnotationToken();
1484 if (Tok.
is(tok::comma))
1488 std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1490 Ptr, AssociatedFunction.
get(), TI, AppendArgs.size(),
1493 if (DeclVarData && !TI.
Sets.empty())
1495 DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1496 AdjustNeedDevicePtr, AppendArgs, AdjustArgsLoc, AppendArgsLoc,
1500 (void)ConsumeAnnotationToken();
1503bool Parser::parseOpenMPAppendArgs(
1505 bool HasError =
false;
1508 if (T.expectAndConsume(diag::err_expected_lparen_after,
1509 getOpenMPClauseName(OMPC_append_args).data()))
1517 tok::annot_pragma_openmp_end);
1518 if (IT.expectAndConsume(diag::err_expected_lparen_after,
"interop"))
1522 if (ParseOMPInteropInfo(InteropInfo, OMPC_append_args))
1525 InteropInfos.push_back(InteropInfo);
1528 if (Tok.
is(tok::comma))
1531 if (!HasError && InteropInfos.empty()) {
1534 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1537 HasError = T.consumeClose() || HasError;
1541bool Parser::parseOMPDeclareVariantMatchClause(
SourceLocation Loc,
1548 if (CKind != OMPC_match) {
1556 if (T.expectAndConsume(diag::err_expected_lparen_after,
1557 getOpenMPClauseName(OMPC_match).data()))
1561 parseOMPContextSelectors(Loc, TI);
1564 (void)T.consumeClose();
1575 bool MergedSet =
false;
1577 if (
Set.Kind != ParentSet.
Kind)
1581 bool MergedSelector =
false;
1585 MergedSelector =
true;
1588 bool MergedProperty =
false;
1602 if (
Selector.Kind == llvm::omp::TraitSelector::user_condition) {
1603 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1604 }
else if (
Selector.ScoreOrCondition !=
1606 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1607 << getOpenMPContextTraitPropertyName(
1609 << getOpenMPContextTraitSelectorName(ParentSelector.
Kind)
1610 << getOpenMPContextTraitSetName(ParentSet.
Kind);
1613 if (!MergedProperty)
1614 Selector.Properties.push_back(ParentProperty);
1617 if (!MergedSelector)
1618 Set.Selectors.push_back(ParentSelector);
1622 TI.
Sets.push_back(ParentSet);
1639 llvm::omp::Clause_enumSize + 1>
1640 FirstClauses(llvm::omp::Clause_enumSize + 1);
1641 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1647 DKind, CKind, !FirstClauses[
unsigned(CKind)].getInt());
1648 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1650 FirstClauses[
unsigned(CKind)].setInt(
true);
1651 if (Clause !=
nullptr)
1652 Clauses.push_back(Clause);
1653 if (Tok.
is(tok::annot_pragma_openmp_end)) {
1658 if (Tok.
is(tok::comma))
1679 bool SkippedClauses =
false;
1681 auto SkipBraces = [&](llvm::StringRef Spelling,
bool IssueNote) {
1683 tok::annot_pragma_openmp_end);
1684 if (T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1687 if (IssueNote && T.getCloseLocation().isValid())
1688 Diag(T.getCloseLocation(),
1689 diag::note_omp_assumption_clause_continue_here);
1695 auto MatchACMClause = [&](StringRef RawString) {
1696 llvm::StringSwitch<int> SS(RawString);
1697 unsigned ACMIdx = 0;
1698 for (
const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1699 if (ACMI.StartsWith)
1700 SS.StartsWith(ACMI.Identifier, ACMIdx++);
1702 SS.Case(ACMI.Identifier, ACMIdx++);
1704 return SS.Default(-1);
1707 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1713 Idx = MatchACMClause(II->
getName());
1717 bool NextIsLPar = Tok.
is(tok::l_paren);
1720 Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1721 << llvm::omp::getOpenMPDirectiveName(DKind)
1722 << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1724 SkipBraces(II ? II->
getName() :
"",
true);
1725 SkippedClauses =
true;
1728 const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1729 if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1732 SkippedClauses =
true;
1733 SkipBraces(II->
getName(),
false);
1739 diag::warn_omp_unknown_assumption_clause_without_args)
1741 SkipBraces(II->
getName(),
true);
1744 assert(II &&
"Expected an identifier clause!");
1745 std::string Assumption = II->
getName().str();
1746 if (ACMI.StartsWith)
1747 Assumption =
"ompx_" + Assumption.substr(ACMI.Identifier.size());
1749 Assumption =
"omp_" + Assumption;
1750 Assumptions.push_back(Assumption);
1760 Diag(Loc, diag::err_expected_begin_assumes);
1774struct SimpleClauseData {
1786static std::optional<SimpleClauseData>
1788 const Token &Tok =
P.getCurToken();
1794 getOpenMPClauseName(Kind).data()))
1795 return std::nullopt;
1798 Kind, Tok.
isAnnotation() ?
"" :
P.getPreprocessor().getSpelling(Tok),
1801 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
1802 Tok.
isNot(tok::annot_pragma_openmp_end))
1803 P.ConsumeAnyToken();
1810 return SimpleClauseData(
Type, Loc, LOpen,
TypeLoc, RLoc);
1813void Parser::ParseOMPDeclareTargetClauses(
1814 Sema::DeclareTargetContextInfo &DTCI) {
1816 bool RequiresToOrLinkOrIndirectClause =
false;
1817 bool HasToOrLinkOrIndirectClause =
false;
1818 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
1819 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1820 bool HasIdentifier = Tok.
is(tok::identifier);
1821 if (HasIdentifier) {
1823 RequiresToOrLinkOrIndirectClause =
true;
1825 StringRef ClauseName = II->
getName();
1826 bool IsDeviceTypeClause =
1828 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1830 bool IsIndirectClause =
getLangOpts().OpenMP >= 51 &&
1831 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1832 if (DTCI.Indirect && IsIndirectClause) {
1833 Diag(Tok, diag::err_omp_more_one_clause)
1834 << getOpenMPDirectiveName(OMPD_declare_target)
1835 << getOpenMPClauseName(OMPC_indirect) << 0;
1838 bool IsToEnterOrLinkClause =
1839 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1840 assert((!IsDeviceTypeClause || !IsToEnterOrLinkClause) &&
1845 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1846 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1849 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1850 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1854 if (!IsDeviceTypeClause && !IsIndirectClause &&
1855 DTCI.Kind == OMPD_begin_declare_target) {
1856 Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1857 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1860 if (!IsDeviceTypeClause && !IsToEnterOrLinkClause && !IsIndirectClause) {
1862 ? diag::err_omp_declare_target_unexpected_clause_52
1863 : diag::err_omp_declare_target_unexpected_clause)
1871 if (IsToEnterOrLinkClause || IsIndirectClause)
1872 HasToOrLinkOrIndirectClause =
true;
1874 if (IsIndirectClause) {
1875 if (!ParseOpenMPIndirectClause(DTCI,
false))
1880 if (IsDeviceTypeClause) {
1881 std::optional<SimpleClauseData> DevTypeData =
1884 if (DeviceTypeLoc.
isValid()) {
1886 Diag(DevTypeData->Loc,
1887 diag::warn_omp_more_one_device_type_clause);
1891 case OMPC_DEVICE_TYPE_any:
1892 DTCI.DT = OMPDeclareTargetDeclAttr::DT_Any;
1894 case OMPC_DEVICE_TYPE_host:
1895 DTCI.DT = OMPDeclareTargetDeclAttr::DT_Host;
1897 case OMPC_DEVICE_TYPE_nohost:
1898 DTCI.DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1901 llvm_unreachable(
"Unexpected device_type");
1903 DeviceTypeLoc = DevTypeData->Loc;
1910 if (DTCI.Kind == OMPD_declare_target || HasIdentifier) {
1918 bool FirstMapping = DTCI.ExplicitlyMapped.try_emplace(ND, MI).second;
1920 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1923 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1928 if (Tok.
is(tok::l_paren)) {
1930 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1933 if (!HasIdentifier && Tok.
isNot(tok::annot_pragma_openmp_end)) {
1936 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1937 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1942 if (Tok.
is(tok::comma))
1946 if (DTCI.Indirect && DTCI.DT != OMPDeclareTargetDeclAttr::DT_Any)
1947 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1950 if (DTCI.Kind == OMPD_declare_target && RequiresToOrLinkOrIndirectClause &&
1951 !HasToOrLinkOrIndirectClause)
1954 ? diag::err_omp_declare_target_missing_enter_or_link_clause
1955 : diag::err_omp_declare_target_missing_to_or_link_clause)
1964 if (Tok.
is(tok::annot_pragma_openmp_end))
1967 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1968 << getOpenMPDirectiveName(DKind);
1969 while (Tok.
isNot(tok::annot_pragma_openmp_end))
1978 bool SkipUntilOpenMPEnd) {
1979 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1981 if (FoundKind == ExpectedKind) {
1983 skipUntilPragmaOpenMPEnd(ExpectedKind);
1987 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1989 Diag(BeginLoc, diag::note_matching)
1990 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind) +
"'").str();
1991 if (SkipUntilOpenMPEnd)
1998 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
2002 if (Tok.
is(tok::annot_pragma_openmp_end))
2003 ConsumeAnnotationToken();
2045 assert(Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2046 "Not an OpenMP directive!");
2053 TentativeParsingAction TPA(*
this);
2054 Loc = ConsumeAnnotationToken();
2056 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
2061 Toks.push_back(Tok);
2062 while (Cnt && Tok.
isNot(tok::eof)) {
2064 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
2066 else if (Tok.
is(tok::annot_pragma_openmp_end))
2068 Toks.push_back(Tok);
2073 auto *LP =
new LateParsedPragma(
this, AS);
2075 getCurrentClass().LateParsedDeclarations.push_back(LP);
2080 Loc = ConsumeAnnotationToken();
2085 case OMPD_threadprivate: {
2087 DeclDirectiveListParserHelper Helper(
this, DKind);
2088 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2090 skipUntilPragmaOpenMPEnd(DKind);
2092 ConsumeAnnotationToken();
2094 Helper.getIdentifiers());
2098 case OMPD_allocate: {
2100 DeclDirectiveListParserHelper Helper(
this, DKind);
2101 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2104 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2106 llvm::omp::Clause_enumSize + 1>
2107 FirstClauses(llvm::omp::Clause_enumSize + 1);
2108 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2114 OMPD_allocate, CKind, !FirstClauses[
unsigned(CKind)].getInt());
2115 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2117 FirstClauses[
unsigned(CKind)].setInt(
true);
2118 if (Clause !=
nullptr)
2119 Clauses.push_back(Clause);
2120 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2125 if (Tok.
is(tok::comma))
2129 skipUntilPragmaOpenMPEnd(DKind);
2132 ConsumeAnnotationToken();
2138 case OMPD_requires: {
2142 llvm::omp::Clause_enumSize + 1>
2143 FirstClauses(llvm::omp::Clause_enumSize + 1);
2144 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2145 Diag(Tok, diag::err_omp_expected_clause)
2146 << getOpenMPDirectiveName(OMPD_requires);
2149 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2155 OMPD_requires, CKind, !FirstClauses[
unsigned(CKind)].getInt());
2156 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2158 FirstClauses[
unsigned(CKind)].setInt(
true);
2159 if (Clause !=
nullptr)
2160 Clauses.push_back(Clause);
2161 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2166 if (Tok.
is(tok::comma))
2171 if (Clauses.empty()) {
2172 Diag(Tok, diag::err_omp_expected_clause)
2173 << getOpenMPDirectiveName(OMPD_requires);
2174 ConsumeAnnotationToken();
2177 ConsumeAnnotationToken();
2183 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2189 case OMPD_begin_assumes:
2192 case OMPD_end_assumes:
2195 case OMPD_declare_reduction:
2197 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2198 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2200 ConsumeAnnotationToken();
2204 case OMPD_declare_mapper: {
2206 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2208 ConsumeAnnotationToken();
2213 case OMPD_begin_declare_variant: {
2220 OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
2223 if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
2227 (void)ConsumeAnnotationToken();
2232 skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
2236 VariantMatchInfo VMI;
2239 std::function<void(StringRef)> DiagUnknownTrait =
2240 [
this, Loc](StringRef ISATrait) {
2243 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2246 ASTCtx, std::move(DiagUnknownTrait),
2250 if (isVariantApplicableInContext(VMI, OMPCtx,
true)) {
2256 unsigned Nesting = 1;
2262 if (DK == OMPD_end_declare_variant)
2264 else if (DK == OMPD_begin_declare_variant)
2266 if (!Nesting || isEofOrEom())
2271 parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
2272 DK, Loc, DKLoc,
true);
2277 case OMPD_end_declare_variant: {
2281 Diag(Loc, diag::err_expected_begin_declare_variant);
2285 case OMPD_declare_variant:
2286 case OMPD_declare_simd: {
2292 Toks.push_back(Tok);
2294 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2295 Toks.push_back(Tok);
2298 Toks.push_back(Tok);
2302 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2303 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2305 }
else if (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
2310 MaybeParseCXX11Attributes(Attrs);
2312 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2315 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs,
TagType, Tag);
2319 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2320 << (DKind == OMPD_declare_simd ? 0 : 1);
2323 if (DKind == OMPD_declare_simd)
2324 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2325 assert(DKind == OMPD_declare_variant &&
2326 "Expected declare variant directive only");
2327 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2330 case OMPD_begin_declare_target:
2331 case OMPD_declare_target: {
2333 bool HasClauses = Tok.
isNot(tok::annot_pragma_openmp_end);
2334 Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2336 ParseOMPDeclareTargetClauses(DTCI);
2337 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2339 (DTCI.ExplicitlyMapped.empty() && DTCI.Indirect);
2344 if (HasImplicitMappings) {
2351 for (
auto &It : DTCI.ExplicitlyMapped)
2352 Decls.push_back(It.first);
2355 case OMPD_end_declare_target: {
2357 Diag(Tok, diag::err_omp_unexpected_directive)
2358 << 1 << getOpenMPDirectiveName(DKind);
2361 const Sema::DeclareTargetContextInfo &DTCI =
2363 ParseOMPEndDeclareTargetDirective(DTCI.Kind, DKind, DTCI.Loc);
2367 Diag(Tok, diag::err_omp_unknown_directive);
2374 case OMPD_taskyield:
2377 case OMPD_taskgroup:
2389 case OMPD_parallel_for:
2390 case OMPD_parallel_for_simd:
2391 case OMPD_parallel_sections:
2392 case OMPD_parallel_master:
2393 case OMPD_parallel_masked:
2397 case OMPD_cancellation_point:
2399 case OMPD_target_data:
2400 case OMPD_target_enter_data:
2401 case OMPD_target_exit_data:
2402 case OMPD_target_parallel:
2403 case OMPD_target_parallel_for:
2405 case OMPD_taskloop_simd:
2406 case OMPD_master_taskloop:
2407 case OMPD_master_taskloop_simd:
2408 case OMPD_parallel_master_taskloop:
2409 case OMPD_parallel_master_taskloop_simd:
2410 case OMPD_masked_taskloop:
2411 case OMPD_masked_taskloop_simd:
2412 case OMPD_parallel_masked_taskloop:
2413 case OMPD_parallel_masked_taskloop_simd:
2414 case OMPD_distribute:
2415 case OMPD_target_update:
2416 case OMPD_distribute_parallel_for:
2417 case OMPD_distribute_parallel_for_simd:
2418 case OMPD_distribute_simd:
2419 case OMPD_target_parallel_for_simd:
2420 case OMPD_target_simd:
2422 case OMPD_teams_distribute:
2423 case OMPD_teams_distribute_simd:
2424 case OMPD_teams_distribute_parallel_for_simd:
2425 case OMPD_teams_distribute_parallel_for:
2426 case OMPD_target_teams:
2427 case OMPD_target_teams_distribute:
2428 case OMPD_target_teams_distribute_parallel_for:
2429 case OMPD_target_teams_distribute_parallel_for_simd:
2430 case OMPD_target_teams_distribute_simd:
2433 case OMPD_metadirective:
2435 case OMPD_teams_loop:
2436 case OMPD_target_teams_loop:
2437 case OMPD_parallel_loop:
2438 case OMPD_target_parallel_loop:
2439 Diag(Tok, diag::err_omp_unexpected_directive)
2440 << 1 << getOpenMPDirectiveName(DKind);
2445 while (Tok.
isNot(tok::annot_pragma_openmp_end))
2491StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2492 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2493 if (!ReadDirectiveWithinMetadirective)
2494 assert(Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2495 "Not an OpenMP directive!");
2500 llvm::omp::Clause_enumSize + 1>
2501 FirstClauses(llvm::omp::Clause_enumSize + 1);
2506 : ConsumeAnnotationToken(),
2509 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2510 Diag(Tok, diag::err_omp_unknown_directive);
2517 bool HasAssociatedStatement =
true;
2524 if (ReadDirectiveWithinMetadirective && Tok.
is(tok::r_paren))
2525 while (Tok.
isNot(tok::annot_pragma_openmp_end))
2528 skipUntilPragmaOpenMPEnd(DKind);
2529 if (Tok.
is(tok::annot_pragma_openmp_end))
2530 ConsumeAnnotationToken();
2533 case OMPD_metadirective: {
2540 TentativeParsingAction TPA(*
this);
2544 tok::annot_pragma_openmp_end);
2545 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2552 if (T.expectAndConsume(diag::err_expected_lparen_after,
2553 getOpenMPClauseName(CKind).data()))
2557 if (CKind == OMPC_when) {
2559 parseOMPContextSelectors(Loc, TI);
2560 if (TI.
Sets.size() == 0) {
2561 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2567 if (Tok.
is(tok::colon))
2570 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2577 while (Tok.
isNot(tok::r_paren) || paren != 0) {
2578 if (Tok.
is(tok::l_paren))
2580 if (Tok.
is(tok::r_paren))
2582 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2583 Diag(Tok, diag::err_omp_expected_punc)
2584 << getOpenMPClauseName(CKind) << 0;
2591 if (Tok.
is(tok::r_paren))
2594 VariantMatchInfo VMI;
2597 VMIs.push_back(VMI);
2603 std::function<void(StringRef)> DiagUnknownTrait =
2604 [
this, Loc](StringRef ISATrait) {
2607 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2614 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2621 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2623 if (Idx++ != BestIdx) {
2628 while (Tok.
isNot(tok::r_paren) || paren != 0) {
2629 if (Tok.
is(tok::l_paren))
2631 if (Tok.
is(tok::r_paren))
2636 if (Tok.
is(tok::r_paren))
2650 if (CKind == OMPC_when) {
2653 parseOMPContextSelectors(Loc, TI);
2661 if (Tok.
is(tok::r_paren)) {
2662 SkipUntil(tok::annot_pragma_openmp_end);
2667 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2674 case OMPD_threadprivate: {
2676 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2677 ParsedStmtContext()) {
2678 Diag(Tok, diag::err_omp_immediate_directive)
2679 << getOpenMPDirectiveName(DKind) << 0;
2682 DeclDirectiveListParserHelper Helper(
this, DKind);
2683 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2685 skipUntilPragmaOpenMPEnd(DKind);
2687 Loc, Helper.getIdentifiers());
2690 SkipUntil(tok::annot_pragma_openmp_end);
2693 case OMPD_allocate: {
2695 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2696 ParsedStmtContext()) {
2697 Diag(Tok, diag::err_omp_immediate_directive)
2698 << getOpenMPDirectiveName(DKind) << 0;
2701 DeclDirectiveListParserHelper Helper(
this, DKind);
2702 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2705 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2707 llvm::omp::Clause_enumSize + 1>
2708 FirstClauses(llvm::omp::Clause_enumSize + 1);
2709 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2715 OMPD_allocate, CKind, !FirstClauses[
unsigned(CKind)].getInt());
2716 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2718 FirstClauses[
unsigned(CKind)].setInt(
true);
2719 if (Clause !=
nullptr)
2720 Clauses.push_back(Clause);
2721 if (Tok.
is(tok::annot_pragma_openmp_end)) {
2726 if (Tok.
is(tok::comma))
2730 skipUntilPragmaOpenMPEnd(DKind);
2733 Loc, Helper.getIdentifiers(), Clauses);
2736 SkipUntil(tok::annot_pragma_openmp_end);
2739 case OMPD_declare_reduction:
2742 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2743 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2747 SkipUntil(tok::annot_pragma_openmp_end);
2750 case OMPD_declare_mapper: {
2753 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2755 ConsumeAnnotationToken();
2758 SkipUntil(tok::annot_pragma_openmp_end);
2765 case OMPD_taskyield:
2769 case OMPD_cancellation_point:
2771 case OMPD_target_enter_data:
2772 case OMPD_target_exit_data:
2773 case OMPD_target_update:
2775 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2776 ParsedStmtContext()) {
2777 Diag(Tok, diag::err_omp_immediate_directive)
2778 << getOpenMPDirectiveName(DKind) << 0;
2779 if (DKind == OMPD_error) {
2780 SkipUntil(tok::annot_pragma_openmp_end);
2784 HasAssociatedStatement =
false;
2798 case OMPD_parallel_for:
2799 case OMPD_parallel_for_simd:
2800 case OMPD_parallel_sections:
2801 case OMPD_parallel_master:
2802 case OMPD_parallel_masked:
2808 case OMPD_taskgroup:
2809 case OMPD_target_data:
2810 case OMPD_target_parallel:
2811 case OMPD_target_parallel_for:
2813 case OMPD_teams_loop:
2814 case OMPD_target_teams_loop:
2815 case OMPD_parallel_loop:
2816 case OMPD_target_parallel_loop:
2819 case OMPD_taskloop_simd:
2820 case OMPD_master_taskloop:
2821 case OMPD_masked_taskloop:
2822 case OMPD_master_taskloop_simd:
2823 case OMPD_masked_taskloop_simd:
2824 case OMPD_parallel_master_taskloop:
2825 case OMPD_parallel_masked_taskloop:
2826 case OMPD_parallel_master_taskloop_simd:
2827 case OMPD_parallel_masked_taskloop_simd:
2828 case OMPD_distribute:
2829 case OMPD_distribute_parallel_for:
2830 case OMPD_distribute_parallel_for_simd:
2831 case OMPD_distribute_simd:
2832 case OMPD_target_parallel_for_simd:
2833 case OMPD_target_simd:
2834 case OMPD_teams_distribute:
2835 case OMPD_teams_distribute_simd:
2836 case OMPD_teams_distribute_parallel_for_simd:
2837 case OMPD_teams_distribute_parallel_for:
2838 case OMPD_target_teams:
2839 case OMPD_target_teams_distribute:
2840 case OMPD_target_teams_distribute_parallel_for:
2841 case OMPD_target_teams_distribute_parallel_for_simd:
2842 case OMPD_target_teams_distribute_simd:
2847 bool ImplicitClauseAllowed =
false;
2848 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2850 ImplicitClauseAllowed =
true;
2854 if (DKind == OMPD_critical) {
2856 tok::annot_pragma_openmp_end);
2857 if (!T.consumeOpen()) {
2863 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2867 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2869 if (Tok.
isNot(tok::annot_pragma_openmp_end))
2877 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2880 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
2883 if (ReadDirectiveWithinMetadirective && Tok.
is(tok::r_paren)) {
2884 while (Tok.
isNot(tok::annot_pragma_openmp_end))
2888 bool HasImplicitClause =
false;
2889 if (ImplicitClauseAllowed && Tok.
is(tok::l_paren)) {
2890 HasImplicitClause =
true;
2900 if (HasImplicitClause) {
2901 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2902 if (DKind == OMPD_flush) {
2905 assert(DKind == OMPD_depobj &&
2906 "Expected flush or depobj directives.");
2907 CKind = OMPC_depobj;
2911 ImplicitClauseAllowed =
false;
2913 HasImplicitClause =
false;
2915 DKind, CKind, !FirstClauses[
unsigned(CKind)].getInt());
2916 FirstClauses[
unsigned(CKind)].setInt(
true);
2918 FirstClauses[
unsigned(CKind)].setPointer(Clause);
2919 Clauses.push_back(Clause);
2923 if (Tok.
is(tok::comma))
2930 ConsumeAnnotationToken();
2932 if (DKind == OMPD_ordered) {
2935 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2936 if (FirstClauses[
unsigned(CK)].getInt()) {
2937 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2938 ParsedStmtContext()) {
2939 Diag(Loc, diag::err_omp_immediate_directive)
2940 << getOpenMPDirectiveName(DKind) << 1
2941 << getOpenMPClauseName(CK);
2943 HasAssociatedStatement =
false;
2948 if (DKind == OMPD_tile && !FirstClauses[
unsigned(OMPC_sizes)].getInt()) {
2949 Diag(Loc, diag::err_omp_required_clause)
2950 << getOpenMPDirectiveName(OMPD_tile) <<
"sizes";
2954 if (HasAssociatedStatement) {
2963 AssociatedStmt = ParseStatement();
2970 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2971 DKind == OMPD_target_exit_data) {
2979 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.
get(), Loc,
2984 OMPDirectiveScope.Exit();
2987 case OMPD_declare_simd:
2988 case OMPD_declare_target:
2989 case OMPD_begin_declare_target:
2990 case OMPD_end_declare_target:
2992 case OMPD_begin_declare_variant:
2993 case OMPD_end_declare_variant:
2994 case OMPD_declare_variant:
2995 Diag(Tok, diag::err_omp_unexpected_directive)
2996 << 1 << getOpenMPDirectiveName(DKind);
2997 SkipUntil(tok::annot_pragma_openmp_end);
3001 Diag(Tok, diag::err_omp_unknown_directive);
3002 SkipUntil(tok::annot_pragma_openmp_end);
3012bool Parser::ParseOpenMPSimpleVarList(
3016 bool AllowScopeSpecifier) {
3019 if (T.expectAndConsume(diag::err_expected_lparen_after,
3020 getOpenMPDirectiveName(Kind).data()))
3022 bool IsCorrect =
true;
3023 bool NoIdentIsFound =
true;
3026 while (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::annot_pragma_openmp_end)) {
3030 Token PrevTok = Tok;
3031 NoIdentIsFound =
false;
3034 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
3037 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3040 false,
false,
false,
3041 false,
false,
nullptr, Name)) {
3043 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3045 }
else if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::r_paren) &&
3046 Tok.
isNot(tok::annot_pragma_openmp_end)) {
3048 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3057 if (Tok.
is(tok::comma)) {
3062 if (NoIdentIsFound) {
3063 Diag(Tok, diag::err_expected) << tok::identifier;
3068 IsCorrect = !T.consumeClose() && IsCorrect;
3073OMPClause *Parser::ParseOpenMPSizesClause() {
3078 if (T.consumeOpen()) {
3079 Diag(Tok, diag::err_expected) << tok::l_paren;
3090 ValExprs.push_back(Val.
get());
3092 if (Tok.
is(tok::r_paren) || Tok.
is(tok::annot_pragma_openmp_end))
3095 ExpectAndConsume(tok::comma);
3101 ValExprs, ClauseNameLoc, T.getOpenLocation(), T.getCloseLocation());
3110 if (T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3118 ? ParseCXXIdExpression()
3119 : tryParseCXXIdExpression(SS,
false,
3121 if (Allocator.isInvalid()) {
3122 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3128 if (Tok.
is(tok::l_paren)) {
3130 tok::annot_pragma_openmp_end);
3136 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3144 if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::r_paren))
3145 Diag(Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3147 if (Tok.
is(tok::comma))
3149 }
while (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::annot_pragma_openmp_end));
3152 T.getCloseLocation(),
Data);
3177 OMPClauseKind = CKind;
3179 bool ErrorFound =
false;
3180 bool WrongDirective =
false;
3182 if (CKind != OMPC_unknown &&
3183 !isAllowedClauseForDirective(DKind, CKind,
getLangOpts().OpenMP)) {
3184 Diag(Tok, diag::err_omp_unexpected_clause)
3185 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3187 WrongDirective =
true;
3192 case OMPC_num_threads:
3197 case OMPC_num_teams:
3198 case OMPC_thread_limit:
3200 case OMPC_grainsize:
3201 case OMPC_num_tasks:
3203 case OMPC_allocator:
3206 case OMPC_novariants:
3207 case OMPC_nocontext:
3212 case OMPC_ompx_dyn_cgroup_mem:
3241 Diag(Tok, diag::err_omp_more_one_clause)
3242 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3246 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3248 Clause = ParseOpenMPClause(CKind, WrongDirective);
3249 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks)
3250 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3252 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3256 case OMPC_proc_bind:
3257 case OMPC_atomic_default_mem_order:
3275 Diag(Tok, diag::err_omp_more_one_clause)
3276 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3280 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3284 case OMPC_dist_schedule:
3285 case OMPC_defaultmap:
3295 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3296 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3297 Diag(Tok, diag::err_omp_more_one_clause)
3298 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3303 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3307 case OMPC_mergeable:
3320 case OMPC_unified_address:
3321 case OMPC_unified_shared_memory:
3322 case OMPC_reverse_offload:
3323 case OMPC_dynamic_allocators:
3332 Diag(Tok, diag::err_omp_more_one_clause)
3333 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3337 Clause = ParseOpenMPClause(CKind, WrongDirective);
3341 Diag(Tok, diag::err_omp_more_one_clause)
3342 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3346 Clause = (DKind == OMPD_depobj)
3347 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3348 : ParseOpenMPClause(CKind, WrongDirective);
3351 case OMPC_firstprivate:
3352 case OMPC_lastprivate:
3354 case OMPC_reduction:
3355 case OMPC_task_reduction:
3356 case OMPC_in_reduction:
3360 case OMPC_copyprivate:
3366 case OMPC_use_device_ptr:
3367 case OMPC_use_device_addr:
3368 case OMPC_is_device_ptr:
3369 case OMPC_has_device_addr:
3371 case OMPC_nontemporal:
3372 case OMPC_inclusive:
3373 case OMPC_exclusive:
3377 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
3378 CKind == OMPC_depend)
3379 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3380 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3384 Diag(Tok, diag::err_omp_more_one_clause)
3385 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3389 Clause = ParseOpenMPSizesClause();
3391 case OMPC_uses_allocators:
3392 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3395 if (DKind != OMPD_interop) {
3397 Diag(Tok, diag::err_omp_more_one_clause)
3398 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3401 Clause = ParseOpenMPClause(CKind, WrongDirective);
3407 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3409 case OMPC_device_type:
3411 skipUntilPragmaOpenMPEnd(DKind);
3413 case OMPC_threadprivate:
3416 if (!WrongDirective)
3417 Diag(Tok, diag::err_omp_unexpected_clause)
3418 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3421 case OMPC_ompx_attribute:
3422 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3424 case OMPC_ompx_bare:
3426 Diag(Tok, diag::note_ompx_bare_clause)
3427 << getOpenMPClauseName(CKind) <<
"target teams";
3428 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3429 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3430 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3433 Clause = ParseOpenMPClause(CKind, WrongDirective);
3438 return ErrorFound ? nullptr : Clause;
3446 bool IsAddressOfOperand) {
3448 if (T.
expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3453 ParseCastExpression(AnyCastExpr, IsAddressOfOperand,
NotTypeCast));
3526bool Parser::ParseOpenMPIndirectClause(Sema::DeclareTargetContextInfo &DTCI,
3531 if (Tok.
isNot(tok::l_paren)) {
3534 DTCI.Indirect =
nullptr;
3550 if (
Ret.isInvalid())
3555 if (
Ret.isInvalid())
3557 DTCI.Indirect = Val.
get();
3568 bool HasError =
false;
3569 bool IsTarget =
false;
3570 bool IsTargetSync =
false;
3572 while (Tok.
is(tok::identifier)) {
3574 bool PreferTypeAllowed =
Kind == OMPC_init &&
3582 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3587 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3588 IsTargetSync =
true;
3591 PreferTypeAllowed) {
3594 tok::annot_pragma_openmp_end);
3595 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3598 while (Tok.
isNot(tok::r_paren)) {
3600 ExprResult LHS = ParseCastExpression(AnyCastExpr);
3609 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3613 if (Tok.
is(tok::comma))
3619 Diag(Tok, diag::err_omp_expected_interop_type);
3622 if (!Tok.
is(tok::comma))
3627 if (!HasError && !IsTarget && !IsTargetSync) {
3628 Diag(Tok, diag::err_omp_expected_interop_type);
3632 if (Kind == OMPC_init) {
3633 if (Tok.
isNot(tok::colon) && (IsTarget || IsTargetSync))
3634 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3635 if (Tok.
is(tok::colon))
3675 if (T.expectAndConsume(diag::err_expected_lparen_after,
3676 getOpenMPClauseName(Kind).data()))
3679 bool InteropError =
false;
3681 if (Kind == OMPC_init)
3682 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3689 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3695 if (!T.consumeClose())
3696 RLoc = T.getCloseLocation();
3698 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3701 if (Kind == OMPC_init)
3703 T.getOpenLocation(), VarLoc, RLoc);
3704 if (Kind == OMPC_use)
3706 T.getOpenLocation(), VarLoc, RLoc);
3708 if (Kind == OMPC_destroy)
3710 T.getOpenLocation(), VarLoc, RLoc);
3712 llvm_unreachable(
"Unexpected interop variable clause.");
3715OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
3719 if (T.expectAndConsume(diag::err_expected_lparen_after,
3720 getOpenMPClauseName(OMPC_ompx_attribute).data()))
3724 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
3727 if (T.consumeClose())
3735 switch (PA.getKind()) {
3736 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
3737 if (!PA.checkExactlyNumArgs(Actions, 2))
3740 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
3743 case ParsedAttr::AT_AMDGPUWavesPerEU:
3744 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3745 !PA.checkAtMostNumArgs(Actions, 2))
3748 PA, PA.getArgAsExpr(0),
3749 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
3752 case ParsedAttr::AT_CUDALaunchBounds:
3753 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3754 !PA.checkAtMostNumArgs(Actions, 2))
3757 PA, PA.getArgAsExpr(0),
3758 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
3759 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr))
3763 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
3769 T.getCloseLocation());
3790 if (!Val || ParseOnly)
3792 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3793 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
3794 static_cast<DefaultKind
>(Val->Type) ==
3795 OMP_DEFAULT_firstprivate)) {
3796 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
3797 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
3800 : OMPC_firstprivate)
3801 << getOpenMPClauseName(OMPC_default) <<
"5.1";
3805 Val->TypeLoc, Val->LOpen,
3806 Val->Loc, Val->RLoc);
3867 if (T.expectAndConsume(diag::err_expected_lparen_after,
3868 getOpenMPClauseName(Kind).data()))
3874 if (Kind == OMPC_schedule) {
3875 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3876 Arg.resize(NumberOfElements);
3877 KLoc.resize(NumberOfElements);
3885 Arg[Modifier1] = KindModifier;
3887 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3888 Tok.
isNot(tok::annot_pragma_openmp_end))
3890 if (Tok.
is(tok::comma)) {
3899 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3900 Tok.
isNot(tok::annot_pragma_openmp_end))
3904 if (Tok.
is(tok::colon))
3907 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
3911 Arg[ScheduleKind] = KindModifier;
3913 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3914 Tok.
isNot(tok::annot_pragma_openmp_end))
3916 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3917 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3918 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3921 }
else if (Kind == OMPC_dist_schedule) {
3925 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3926 Tok.
isNot(tok::annot_pragma_openmp_end))
3928 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.
is(tok::comma))
3930 }
else if (Kind == OMPC_defaultmap) {
3938 Arg.push_back(Modifier);
3940 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3941 Tok.
isNot(tok::annot_pragma_openmp_end))
3945 if (Tok.
is(tok::colon))
3948 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
3953 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3954 Tok.
isNot(tok::annot_pragma_openmp_end))
3960 }
else if (Kind == OMPC_order) {
3961 enum { Modifier, OrderKind, NumberOfElements };
3962 Arg.resize(NumberOfElements);
3963 KLoc.resize(NumberOfElements);
3970 Arg[Modifier] = KindModifier;
3972 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3973 Tok.
isNot(tok::annot_pragma_openmp_end))
3976 if (Tok.
is(tok::colon))
3979 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
3983 Arg[OrderKind] = KindModifier;
3985 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
3986 Tok.
isNot(tok::annot_pragma_openmp_end))
3988 }
else if (Kind == OMPC_device) {
4001 KLoc.emplace_back();
4003 }
else if (Kind == OMPC_grainsize) {
4011 Arg.push_back(Modifier);
4018 if (Modifier == OMPC_GRAINSIZE_strict) {
4019 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4024 KLoc.emplace_back();
4028 KLoc.emplace_back();
4030 }
else if (Kind == OMPC_num_tasks) {
4038 Arg.push_back(Modifier);
4045 if (Modifier == OMPC_NUMTASKS_strict) {
4046 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4051 KLoc.emplace_back();
4055 KLoc.emplace_back();
4058 assert(Kind == OMPC_if);
4060 TentativeParsingAction TPA(*
this);
4063 if (DK != OMPD_unknown) {
4070 Arg.back() =
unsigned(OMPD_unknown);
4077 bool NeedAnExpression = (
Kind == OMPC_schedule && DelimLoc.
isValid()) ||
4078 (Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
4079 Kind == OMPC_if || Kind == OMPC_device ||
4080 Kind == OMPC_grainsize || Kind == OMPC_num_tasks;
4081 if (NeedAnExpression) {
4091 if (!T.consumeClose())
4092 RLoc = T.getCloseLocation();
4094 if (NeedAnExpression && Val.
isInvalid())
4100 Kind, Arg, Val.
get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4105 if (ReductionIdScopeSpec.
isEmpty()) {
4107 switch (
P.getCurToken().getKind()) {
4142 return P.ParseUnqualifiedId(
4143 ReductionIdScopeSpec,
nullptr,
4147 false,
nullptr, ReductionId);
4153 Token Tok =
P.getCurToken();
4154 if (!Tok.
is(tok::identifier))
4161 return TypeModifier;
4169 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4175 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4179 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::kw_default)) {
4181 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4200 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4201 TypeModifier == OMPC_MAP_MODIFIER_close ||
4202 TypeModifier == OMPC_MAP_MODIFIER_present ||
4203 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4204 Data.MapTypeModifiers.push_back(TypeModifier);
4209 <<
"map type modifier";
4211 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4212 Data.MapTypeModifiers.push_back(TypeModifier);
4217 if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::colon) &&
4219 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4220 <<
"map type modifier";
4226 if (Tok.
is(tok::comma)) {
4227 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4234 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4249 Token Tok =
P.getCurToken();
4251 if (!Tok.
isOneOf(tok::identifier, tok::kw_delete))
4264 Token Tok =
P.getCurToken();
4265 if (Tok.
is(tok::colon)) {
4266 P.Diag(Tok, diag::err_omp_map_type_missing);
4271 P.Diag(Tok, diag::err_omp_unknown_map_type);
4277ExprResult Parser::ParseOpenMPIteratorsExpr() {
4278 assert(Tok.
is(tok::identifier) && PP.
getSpelling(Tok) ==
"iterator" &&
4279 "Expected 'iterator' token.");
4283 if (T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4288 while (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::annot_pragma_openmp_end)) {
4291 if (Tok.
isNot(tok::identifier) ||
NextToken().isNot(tok::equal)) {
4298 IteratorType = TR.
get();
4304 if (Tok.
is(tok::identifier)) {
4308 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4313 if (Tok.
is(tok::equal))
4316 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4322 ExprResult LHS = ParseCastExpression(AnyCastExpr);
4329 if (Tok.
is(tok::colon))
4334 LHS = ParseCastExpression(AnyCastExpr);
4343 if (Tok.
is(tok::colon)) {
4348 LHS = ParseCastExpression(AnyCastExpr);
4356 if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::r_paren))
4357 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4358 if (Tok.
is(tok::comma))
4364 D.
Type = IteratorType;
4375 if (!T.consumeClose())
4376 RLoc = T.getCloseLocation();
4387 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4390 if (Tok.
is(tok::identifier) &&
4393 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4394 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4395 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4396 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4397 Data.ExtraModifier != OMPC_DEPEND_inout)
4398 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4400 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4401 ? OMPC_DEPEND_outallmemory
4402 : OMPC_DEPEND_inoutallmemory;
4414 Sema &Actions =
P.getActions();
4418 Data.DepModOrTailExpr = Tail.
get();
4419 Token CurTok =
P.getCurToken();
4420 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4421 P.Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4434 bool InvalidReductionId =
false;
4435 bool IsInvalidMapperModifier =
false;
4440 getOpenMPClauseName(Kind).data()))
4443 bool HasIterator =
false;
4444 bool InvalidIterator =
false;
4445 bool NeedRParenForLinear =
false;
4447 tok::annot_pragma_openmp_end);
4449 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4450 Kind == OMPC_in_reduction) {
4452 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4453 (Tok.
is(tok::identifier) || Tok.
is(tok::kw_default)) &&
4456 Data.ExtraModifier =
4460 assert(Tok.
is(tok::comma) &&
"Expected comma.");
4465 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4470 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4471 if (InvalidReductionId) {
4472 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4475 if (Tok.
is(tok::colon))
4478 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4479 if (!InvalidReductionId)
4480 Data.ReductionOrMapperId =
4482 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4484 if (Tok.
is(tok::identifier) && PP.
getSpelling(Tok) ==
"iterator") {
4493 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4494 Data.DepModOrTailExpr = IteratorRes.
get();
4496 ExpectAndConsume(tok::comma);
4506 (Kind == OMPC_doacross &&
4508 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4513 if (DKind == OMPD_ordered && Kind == OMPC_depend &&
4514 Data.ExtraModifier == OMPC_DEPEND_source) {
4520 if (Tok.
is(tok::colon)) {
4522 }
else if (Kind != OMPC_doacross || Tok.
isNot(tok::r_paren)) {
4523 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4524 : diag::warn_pragma_expected_colon)
4525 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
4527 if (Kind == OMPC_doacross) {
4528 if (Tok.
is(tok::identifier) &&
4530 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
4531 ? OMPC_DOACROSS_source_omp_cur_iteration
4532 : OMPC_DOACROSS_sink_omp_cur_iteration;
4535 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
4536 if (Tok.
isNot(tok::minus)) {
4537 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4538 << getOpenMPClauseName(Kind) << 0 << 0;
4545 if (Tok.
isNot(tok::numeric_constant) ||
4547 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
4548 << getOpenMPClauseName(Kind) << 0 << 0;
4554 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
4555 if (Tok.
isNot(tok::r_paren)) {
4556 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4557 << getOpenMPClauseName(Kind) << 1 << 1;
4563 if (Kind == OMPC_doacross &&
4564 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
4565 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
4566 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
4572 }
else if (Kind == OMPC_linear) {
4574 Data.ExtraModifier = OMPC_LINEAR_val;
4575 if (Tok.
is(tok::identifier) && PP.
LookAhead(0).
is(tok::l_paren)) {
4576 Data.ExtraModifier =
4580 NeedRParenForLinear =
true;
4582 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
4583 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
4584 <<
"linear(list: [linear-modifier,] step(step-size))";
4586 }
else if (Kind == OMPC_lastprivate) {
4593 Tok.
is(tok::identifier) && PP.
LookAhead(0).
is(tok::colon)) {
4594 Data.ExtraModifier =
4598 assert(Tok.
is(tok::colon) &&
"Expected colon.");
4601 }
else if (Kind == OMPC_map) {
4603 if (Tok.
is(tok::identifier) && PP.
getSpelling(Tok) ==
"iterator") {
4606 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
4608 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4609 Data.IteratorExpr = IteratorRes.
get();
4611 ExpectAndConsume(tok::comma);
4613 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4616 InvalidIterator =
true;
4629 TentativeParsingAction TPA(*
this);
4630 bool ColonPresent =
false;
4631 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4633 if (Tok.
is(tok::colon))
4634 ColonPresent =
true;
4641 if (!IsInvalidMapperModifier)
4647 Data.ExtraModifier = OMPC_MAP_tofrom;
4649 if (DKind == OMPD_target_enter_data)
4650 Data.ExtraModifier = OMPC_MAP_to;
4651 else if (DKind == OMPD_target_exit_data)
4652 Data.ExtraModifier = OMPC_MAP_from;
4654 Data.IsMapTypeImplicit =
true;
4657 if (Tok.
is(tok::colon))
4659 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
4660 while (Tok.
is(tok::identifier)) {
4665 Data.MotionModifiers.push_back(Modifier);
4668 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
4670 if (IsInvalidMapperModifier)
4678 if (Tok.
is(tok::comma))
4681 if (!
Data.MotionModifiers.empty() && Tok.
isNot(tok::colon)) {
4682 if (!IsInvalidMapperModifier) {
4684 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
4686 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
4688 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4696 }
else if (Kind == OMPC_allocate ||
4697 (Kind == OMPC_affinity && Tok.
is(tok::identifier) &&
4701 TentativeParsingAction TPA(*
this);
4706 if (Kind == OMPC_allocate) {
4711 Tail = ParseOpenMPIteratorsExpr();
4717 if (Tok.
is(tok::colon)) {
4718 Data.DepModOrTailExpr = Tail.
get();
4729 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4732 }
else if (Kind == OMPC_adjust_args) {
4740 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4744 if (Tok.
is(tok::colon))
4746 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
4752 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
4753 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
4754 Kind != OMPC_doacross && Kind != OMPC_map) ||
4755 (Kind == OMPC_reduction && !InvalidReductionId) ||
4759 (Kind == OMPC_adjust_args &&
4761 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
4762 while (IsComma || (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::colon) &&
4763 Tok.
isNot(tok::annot_pragma_openmp_end))) {
4771 Vars.push_back(VarExpr.
get());
4773 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4778 IsComma = Tok.
is(tok::comma);
4781 else if (Tok.
isNot(tok::r_paren) &&
4782 Tok.
isNot(tok::annot_pragma_openmp_end) &&
4783 (!MayHaveTail || Tok.
isNot(tok::colon)))
4784 Diag(Tok, diag::err_omp_expected_punc)
4785 << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
4786 : getOpenMPClauseName(Kind))
4787 << (Kind == OMPC_flush);
4791 if (NeedRParenForLinear)
4796 const bool MustHaveTail = MayHaveTail && Tok.
is(tok::colon);
4797 bool StepFound =
false;
4798 bool ModifierFound =
false;
4803 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
4804 while (Tok.
isNot(tok::r_paren)) {
4805 if (Tok.
is(tok::identifier)) {
4813 if (LinKind == OMPC_LINEAR_step) {
4815 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
4818 tok::annot_pragma_openmp_end);
4822 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
4827 Data.StepModifierLoc = StepModifierLoc;
4831 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
4833 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
4835 Data.ExtraModifier = LinKind;
4837 ModifierFound =
true;
4846 if (Tok.
is(tok::comma))
4848 if (Tok.
is(tok::r_paren) || Tok.
is(tok::annot_pragma_openmp_end))
4851 if (!StepFound && !ModifierFound)
4852 Diag(ELoc, diag::err_expected_expression);
4859 Data.DepModOrTailExpr = Tail.
get();
4861 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4873 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
4875 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
4876 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
Defines the clang::ASTContext interface.
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
static void parseMapType(Parser &P, Sema::OpenMPVarListDataTy &Data)
Parse map-type in map clause.
static bool parseStepSize(Parser &P, Sema::OpenMPVarListDataTy &Data, OpenMPClauseKind CKind, SourceLocation ELoc)
Parse step size expression.
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 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 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 { ....
bool expectAndConsume(unsigned DiagID=diag::err_expected, const char *Msg="", tok::TokenKind SkipToTok=tok::unknown)
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
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.
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)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
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.
bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, SmallVectorImpl< Expr * > &Vars, Sema::OpenMPVarListDataTy &Data)
Parses clauses with list.
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.
bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind, Sema::OpenMPVarListDataTy &Data, const LangOptions &LangOpts)
Parses a reserved locator like 'omp_all_memory'.
bool parseMapperModifier(Sema::OpenMPVarListDataTy &Data)
Parses the mapper modifier in map, to, and from clauses.
bool parseMapTypeModifiers(Sema::OpenMPVarListDataTy &Data)
Parses map-type-modifiers in map clause.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
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.
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.
OMPClause * ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'init' clause.
Scope * getCurScope() const
Retrieve the parser's current scope.
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'.
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 * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
void ActOnOpenMPEndAssumesDirective()
Called on well-formed '#pragma omp end assumes'.
void CodeCompleteInitializer(Scope *S, Decl *D)
QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
AMDGPUFlatWorkGroupSizeAttr * CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
Create an AMDGPUWavesPerEUAttr attribute.
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=NoFold)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
StmtResult ActOnOpenMPLoopnest(Stmt *AStmt)
Process a canonical OpenMP loop nest that can either be a canonical literal loop (ForStmt or CXXForRa...
ExprResult ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)
Build the mapper variable of '#pragma omp declare mapper'.
TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D)
Check variable declaration in 'omp declare mapper' construct.
void ActOnReenterFunctionContext(Scope *S, Decl *D)
Push the parameters of D, which must be a function, into scope.
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause * > ClauseList)
Called on well-formed '#pragma omp requires'.
OMPClause * ActOnOpenMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'destroy' clause.
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.
AMDGPUWavesPerEUAttr * CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
Create an AMDGPUWavesPerEUAttr attribute.
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
ASTContext & getASTContext() const
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind PrevMappedDirective=llvm::omp::OMPD_unknown)
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList, ArrayRef< OMPClause * > Clauses, DeclContext *Owner=nullptr)
Called on well-formed '#pragma omp allocate'.
bool isInOpenMPAssumeScope() const
Check if there is an active global omp begin assumes directive.
DeclContext * getCurLexicalContext() const
bool isInOpenMPDeclareTargetContext() const
Return true inside OpenMP declare target region.
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
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.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name)
Retrieves the declaration name from a parsed unqualified-id.
bool isInOpenMPDeclareVariantScope() const
Can we exit an OpenMP declare variant scope at the moment.
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
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 ActOnOpenMPEndDeclareVariant()
Handle a omp end declare variant.
OMPClause * ActOnOpenMPXAttributeClause(ArrayRef< const Attr * > Attrs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_attribute' clause.
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'.
void ActOnInitializerError(Decl *Dcl)
ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...
NamedDecl * lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Searches for the provided declaration name for OpenMP declare target directive.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI)
Handle a omp begin declare variant.
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare mapper' construct.
bool ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called on the start of target region i.e. '#pragma omp declare target'.
const DeclareTargetContextInfo ActOnOpenMPEndDeclareTargetDirective()
Called at the end of target region i.e. '#pragma omp end declare target'.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
@ 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 StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
StmtResult ActOnOpenMPErrorDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, bool InExContext=true)
Called on well-formed '#pragma omp error'.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
void ActOnOpenMPAssumesDirective(SourceLocation Loc, OpenMPDirectiveKind DKind, ArrayRef< std::string > Assumptions, bool SkippedClauses)
Called on well-formed '#pragma omp [begin] assume[s]'.
OMPClause * ActOnOpenMPSizesClause(ArrayRef< Expr * > SizeExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'sizes' clause.
void EndOpenMPClause()
End analysis of clauses.
CUDALaunchBoundsAttr * CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks)
Create an CUDALaunchBoundsAttr attribute.