26#include "llvm/ADT/SmallBitVector.h"
27#include "llvm/ADT/StringSwitch.h"
28#include "llvm/Frontend/OpenMP/DirectiveNameParser.h"
29#include "llvm/Frontend/OpenMP/OMPAssume.h"
30#include "llvm/Frontend/OpenMP/OMPContext.h"
34using namespace llvm::omp;
41class DeclDirectiveListParserHelper final {
42 SmallVector<Expr *, 4> Identifiers;
49 void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
50 ExprResult Res = P->getActions().OpenMP().ActOnOpenMPIdExpression(
51 P->getCurScope(), SS, NameInfo, Kind);
53 Identifiers.push_back(Res.
get());
55 llvm::ArrayRef<Expr *> getIdentifiers()
const {
return Identifiers; }
64 auto [D, VR] = getOpenMPDirectiveKindAndVersions(Name);
65 assert(D == Kind &&
"Directive kind mismatch");
68 if (
static_cast<int>(Version) < VR.Min)
69 P.
Diag(Loc, diag::warn_omp_future_directive_spelling) << Name;
75 static const DirectiveNameParser DirParser;
77 const DirectiveNameParser::State *S = DirParser.initial();
80 if (
Tok.isAnnotation())
86 S = DirParser.consume(S, Concat);
90 while (!
Tok.isAnnotation()) {
93 if (!
Tok.isAnnotation()) {
95 S = DirParser.consume(S, TS);
103 assert(S &&
"Should have exited early");
112 bool WithOperator =
false;
113 if (
Tok.is(tok::kw_operator)) {
118 switch (
Tok.getKind()) {
143 case tok::identifier:
148 P.
Diag(
Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
149 P.
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
155 return OOK ==
OO_None ? DeclNames.getIdentifier(
Tok.getIdentifierInfo())
156 : DeclNames.getCXXOperatorName(OOK);
161 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
164 if (
T.expectAndConsume(
165 diag::err_expected_lparen_after,
166 getOpenMPDirectiveName(OMPD_declare_reduction, OMPVersion).data())) {
172 if (Name.
isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
176 bool IsCorrect = !ExpectAndConsume(tok::colon);
178 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
181 IsCorrect = IsCorrect && !Name.
isEmpty();
183 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
184 Diag(Tok.getLocation(), diag::err_expected_type);
188 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
191 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
198 QualType ReductionType = Actions.OpenMP().ActOnOpenMPDeclareReductionType(
199 Range.getBegin(), TR);
200 if (!ReductionType.
isNull()) {
201 ReductionTypes.push_back(
202 std::make_pair(ReductionType,
Range.getBegin()));
205 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
209 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
213 if (ExpectAndConsume(tok::comma)) {
215 if (Tok.is(tok::annot_pragma_openmp_end)) {
216 Diag(Tok.getLocation(), diag::err_expected_type);
220 }
while (Tok.isNot(tok::annot_pragma_openmp_end));
222 if (ReductionTypes.empty()) {
227 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
231 if (ExpectAndConsume(tok::colon))
234 if (Tok.is(tok::annot_pragma_openmp_end)) {
235 Diag(Tok.getLocation(), diag::err_expected_expression);
240 Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveStart(
241 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes,
246 unsigned I = 0, E = ReductionTypes.size();
247 for (Decl *D : DRD.get()) {
248 TentativeParsingAction TPA(*
this);
253 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerStart(
getCurScope(), D);
254 ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
256 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerEnd(
257 D, CombinerResult.
get());
259 if (CombinerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
260 Tok.isNot(tok::annot_pragma_openmp_end)) {
265 IsCorrect = !
T.consumeClose() && IsCorrect && CombinerResult.
isUsable();
267 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
269 if (Tok.is(tok::identifier) &&
270 Tok.getIdentifierInfo()->isStr(
"initializer")) {
273 Diag(Tok.getLocation(), diag::err_expected) <<
"'initializer'";
280 tok::annot_pragma_openmp_end);
282 !
T.expectAndConsume(diag::err_expected_lparen_after,
"initializer") &&
284 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
289 VarDecl *OmpPrivParm =
290 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerStart(
293 if (Tok.is(tok::identifier) &&
294 Tok.getIdentifierInfo()->isStr(
"omp_priv")) {
296 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
298 InitializerResult = Actions.ActOnFinishFullExpr(
302 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerEnd(
303 D, InitializerResult.
get(), OmpPrivParm);
304 if (InitializerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
305 Tok.isNot(tok::annot_pragma_openmp_end)) {
311 !
T.consumeClose() && IsCorrect && !InitializerResult.
isInvalid();
323 return Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveEnd(
327void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
330 if (isTokenEqualOrEqualTypo()) {
333 if (Tok.is(tok::code_completion)) {
335 Actions.CodeCompletion().CodeCompleteInitializer(
getCurScope(),
337 Actions.FinalizeDeclaration(OmpPrivParm);
341 PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
344 if (
Init.isInvalid()) {
346 Actions.ActOnInitializerError(OmpPrivParm);
348 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
351 }
else if (Tok.is(tok::l_paren)) {
358 SourceLocation LParLoc =
T.getOpenLocation();
359 auto RunSignatureHelp = [
this, OmpPrivParm, LParLoc, &Exprs]() {
360 QualType PreferredType =
361 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
363 OmpPrivParm->
getLocation(), Exprs, LParLoc,
false);
364 CalledSignatureHelp =
true;
365 return PreferredType;
367 if (ParseExpressionList(Exprs, [&] {
368 PreferredType.enterFunctionArgument(Tok.getLocation(),
371 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
373 Actions.ActOnInitializerError(OmpPrivParm);
377 SourceLocation RLoc = Tok.getLocation();
378 if (!
T.consumeClose())
379 RLoc =
T.getCloseLocation();
382 Actions.ActOnParenListExpr(
T.getOpenLocation(), RLoc, Exprs);
383 Actions.AddInitializerToDecl(OmpPrivParm,
Initializer.get(),
388 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
392 if (
Init.isInvalid()) {
393 Actions.ActOnInitializerError(OmpPrivParm);
395 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
399 Actions.ActOnUninitializedDecl(OmpPrivParm);
405 bool IsCorrect =
true;
406 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
409 if (
T.expectAndConsume(
410 diag::err_expected_lparen_after,
411 getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion).data())) {
417 auto &DeclNames = Actions.getASTContext().DeclarationNames;
418 DeclarationName MapperId;
419 if (PP.LookAhead(0).is(tok::colon)) {
420 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
421 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
424 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
428 ExpectAndConsume(tok::colon);
432 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get(
"default"));
435 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
439 DeclarationName VName;
444 MapperType = Actions.OpenMP().ActOnOpenMPDeclareMapperType(
Range.getBegin(),
454 IsCorrect &= !
T.consumeClose();
462 DeclarationNameInfo DirName;
463 SourceLocation Loc = Tok.getLocation();
466 ParseScope OMPDirectiveScope(
this, ScopeFlags);
467 Actions.OpenMP().StartOpenMPDSABlock(OMPD_declare_mapper, DirName,
472 Actions.OpenMP().ActOnOpenMPDeclareMapperDirectiveVarDecl(
476 SmallVector<OMPClause *, 6> Clauses;
477 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
480 : getOpenMPClauseKind(PP.getSpelling(Tok));
481 Actions.OpenMP().StartOpenMPClause(CKind);
483 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
485 Clauses.push_back(Clause);
489 if (Tok.is(tok::comma))
491 Actions.OpenMP().EndOpenMPClause();
493 if (Clauses.empty()) {
494 Diag(Tok, diag::err_omp_expected_clause)
495 << getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion);
504 DeclGroupPtrTy DG = Actions.OpenMP().ActOnOpenMPDeclareMapperDirective(
505 OuterScope, Actions.getCurLexicalContext(), MapperId, MapperType,
506 Range.getBegin(), VName, AS, MapperVarRef.
get(), Clauses);
508 Actions.OpenMP().EndOpenMPDSABlock(
nullptr);
509 OMPDirectiveScope.Exit();
520 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
521 DeclSpec DS(AttrFactory);
522 ParseSpecifierQualifierList(DS, AS, DSC);
527 ParseDeclarator(DeclaratorInfo);
528 Range = DeclaratorInfo.getSourceRange();
529 if (DeclaratorInfo.getIdentifier() ==
nullptr) {
530 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
533 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
535 return Actions.OpenMP().ActOnOpenMPDeclareMapperVarDecl(
getCurScope(),
547 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
550 if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
554 (void)ConsumeAnnotationToken();
559 skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
563 VariantMatchInfo VMI;
567 Loc](StringRef ISATrait) {
570 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
573 ASTCtx, std::move(DiagUnknownTrait),
576 Actions.OpenMP().getOpenMPDeviceNum());
578 if (isVariantApplicableInContext(VMI, OMPCtx,
580 Actions.OpenMP().ActOnOpenMPBeginDeclareVariant(Loc, TI);
585 unsigned Nesting = 1;
589 DKLoc = Tok.getLocation();
591 if (DK == OMPD_end_declare_variant)
593 else if (DK == OMPD_begin_declare_variant)
595 if (!Nesting || isEofOrEom())
600 parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant, DK,
611class FNContextRAII final {
615 bool HasFunScope =
false;
616 FNContextRAII() =
delete;
617 FNContextRAII(
const FNContextRAII &) =
delete;
618 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
665 bool IsError =
false;
666 while (
Tok.isNot(tok::annot_pragma_openmp_end)) {
667 if (
Tok.isNot(tok::identifier))
669 OMPDeclareSimdDeclAttr::BranchStateTy Out;
671 StringRef ClauseName = II->
getName();
673 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
674 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
675 P.
Diag(
Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
677 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
683 }
else if (ClauseName ==
"simdlen") {
686 P.
Diag(
Tok, diag::err_omp_more_one_clause)
687 << getOpenMPDirectiveName(OMPD_declare_simd, OMPVersion)
698 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
699 CKind == OMPC_linear) {
702 if (CKind == OMPC_aligned) {
704 }
else if (CKind == OMPC_linear) {
705 Data.ExtraModifier = OMPC_LINEAR_val;
711 getOpenMPClauseKind(ClauseName), *Vars,
Data))
713 if (CKind == OMPC_aligned) {
714 Alignments.append(Aligneds.size() - Alignments.size(),
715 Data.DepModOrTailExpr);
716 }
else if (CKind == OMPC_linear) {
717 assert(0 <=
Data.ExtraModifier &&
719 "Unexpected linear modifier.");
722 Data.ExtraModifierLoc))
723 Data.ExtraModifier = OMPC_LINEAR_val;
724 LinModifiers.append(Linears.size() - LinModifiers.size(),
726 Steps.append(Linears.size() - Steps.size(),
Data.DepModOrTailExpr);
733 if (
Tok.is(tok::comma))
742 PP.EnterToken(Tok,
true);
743 PP.EnterTokenStream(Toks,
true,
749 FNContextRAII FnContext(*
this, Ptr);
750 OMPDeclareSimdDeclAttr::BranchStateTy BS =
751 OMPDeclareSimdDeclAttr::BS_Undefined;
753 SmallVector<Expr *, 4> Uniforms;
754 SmallVector<Expr *, 4> Aligneds;
755 SmallVector<Expr *, 4> Alignments;
756 SmallVector<Expr *, 4> Linears;
757 SmallVector<unsigned, 4> LinModifiers;
758 SmallVector<Expr *, 4> Steps;
761 Alignments, Linears, LinModifiers, Steps);
762 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
764 SourceLocation EndLoc = ConsumeAnnotationToken();
767 return Actions.OpenMP().ActOnOpenMPDeclareSimdDirective(
768 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
769 LinModifiers, Steps, SourceRange(Loc, EndLoc));
776 CONTEXT_SELECTOR_SET_LVL = 0,
777 CONTEXT_SELECTOR_LVL = 1,
778 CONTEXT_TRAIT_LVL = 2,
781static StringRef stringLiteralParser(
Parser &P) {
788 if (
Tok.
is(tok::identifier) ||
Tok.
is(tok::kw_for)) {
796 return stringLiteralParser(P);
799 diag::warn_omp_declare_variant_string_literal_or_identifier)
804static bool checkForDuplicates(
Parser &P, StringRef Name,
806 llvm::StringMap<SourceLocation> &Seen,
808 auto Res = Seen.try_emplace(Name, NameLoc);
814 P.
Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
816 P.
Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
823 llvm::omp::TraitSet
Set,
825 llvm::StringMap<SourceLocation> &Seen) {
826 TIProperty.
Kind = TraitProperty::invalid;
828 SourceLocation NameLoc = Tok.getLocation();
830 if (Selector == llvm::omp::TraitSelector::target_device_device_num) {
832 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
834 if (DeviceNumExprResult.
isUsable()) {
835 Expr *DeviceNumExpr = DeviceNumExprResult.
get();
836 Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr);
840 Name = getNameFromIdOrString(*
this, Tok, CONTEXT_TRAIT_LVL);
842 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
843 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
848 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
849 if (TIProperty.
Kind != TraitProperty::invalid) {
850 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
851 TIProperty.
Kind = TraitProperty::invalid;
857 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
858 << Name << getOpenMPContextTraitSelectorName(Selector)
859 << getOpenMPContextTraitSetName(
Set);
861 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
862 if (SetForName != TraitSet::invalid) {
863 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
864 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
865 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
866 << Name <<
"<selector-name>"
867 <<
"(<property-name>)";
870 TraitSelector SelectorForName =
871 getOpenMPContextTraitSelectorKind(Name, SetForName);
872 if (SelectorForName != TraitSelector::invalid) {
873 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
874 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
875 bool AllowsTraitScore =
false;
876 bool RequiresProperty =
false;
877 isValidTraitSelectorForTraitSet(
878 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
879 AllowsTraitScore, RequiresProperty);
880 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
881 << getOpenMPContextTraitSetName(
882 getOpenMPContextTraitSetForSelector(SelectorForName))
883 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
886 for (
const auto &PotentialSet :
887 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
888 TraitSet::device, TraitSet::target_device}) {
889 TraitProperty PropertyForName =
890 getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
891 if (PropertyForName == TraitProperty::invalid)
893 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
894 << getOpenMPContextTraitSetName(
895 getOpenMPContextTraitSetForProperty(PropertyForName))
896 << getOpenMPContextTraitSelectorName(
897 getOpenMPContextTraitSelectorForProperty(PropertyForName))
898 << (
"(" + Name +
")").str();
901 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
902 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
908 llvm::StringMap<SourceLocation> &Seen) {
909 assert(TISelector.
Kind ==
910 llvm::omp::TraitSelector::implementation_extension &&
911 "Only for extension properties, e.g., "
912 "`implementation={extension(PROPERTY)}`");
913 if (TIProperty.
Kind == TraitProperty::invalid)
916 if (TIProperty.
Kind ==
917 TraitProperty::implementation_extension_disable_implicit_base)
920 if (TIProperty.
Kind ==
921 TraitProperty::implementation_extension_allow_templates)
924 if (TIProperty.
Kind ==
925 TraitProperty::implementation_extension_bind_to_declaration)
930 llvm::omp::TraitProperty::implementation_extension_match_all ||
932 llvm::omp::TraitProperty::implementation_extension_match_any ||
934 llvm::omp::TraitProperty::implementation_extension_match_none);
937 if (IsMatchExtension(TIProperty)) {
939 if (IsMatchExtension(SeenProp)) {
940 P.
Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
941 StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
944 P.
Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
945 << CONTEXT_TRAIT_LVL << SeenName;
951 llvm_unreachable(
"Unknown extension property!");
955 llvm::omp::TraitSet
Set,
956 llvm::StringMap<SourceLocation> &Seen) {
957 assert(TISelector.
Kind != TraitSelector::user_condition &&
958 "User conditions are special properties not handled here!");
960 SourceLocation PropertyLoc = Tok.getLocation();
961 OMPTraitProperty TIProperty;
962 parseOMPTraitPropertyKind(TIProperty,
Set, TISelector.
Kind, Seen);
964 if (TISelector.
Kind == llvm::omp::TraitSelector::implementation_extension)
967 TIProperty.
Kind = TraitProperty::invalid;
970 if (TIProperty.
Kind == TraitProperty::invalid) {
971 if (PropertyLoc != Tok.getLocation())
972 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
973 << CONTEXT_TRAIT_LVL;
977 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.
Kind,
986 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
987 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
989 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
990 << getOpenMPContextTraitSetName(
Set);
991 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
992 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
994 << getOpenMPContextTraitSelectorName(
995 getOpenMPContextTraitSelectorForProperty(TIProperty.
Kind))
996 << getOpenMPContextTraitSetName(
997 getOpenMPContextTraitSetForProperty(TIProperty.
Kind));
998 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
999 << CONTEXT_TRAIT_LVL;
1003 llvm::omp::TraitSet
Set,
1004 llvm::StringMap<SourceLocation> &Seen) {
1005 TISelector.
Kind = TraitSelector::invalid;
1007 SourceLocation NameLoc = Tok.getLocation();
1008 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_LVL);
1010 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1011 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1015 TISelector.
Kind = getOpenMPContextTraitSelectorKind(Name,
Set);
1016 if (TISelector.
Kind != TraitSelector::invalid) {
1017 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1018 TISelector.
Kind = TraitSelector::invalid;
1023 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1024 << Name << getOpenMPContextTraitSetName(
Set);
1026 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1027 if (SetForName != TraitSet::invalid) {
1028 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1029 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1030 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1031 << Name <<
"<selector-name>"
1032 <<
"<property-name>";
1035 for (
const auto &PotentialSet :
1036 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1037 TraitSet::device, TraitSet::target_device}) {
1038 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1039 PotentialSet, TraitSelector::invalid, Name);
1040 if (PropertyForName == TraitProperty::invalid)
1042 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1043 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1044 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1045 << getOpenMPContextTraitSetName(
1046 getOpenMPContextTraitSetForProperty(PropertyForName))
1047 << getOpenMPContextTraitSelectorName(
1048 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1049 << (
"(" + Name +
")").str();
1052 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1053 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1060 StringRef SelectorName =
1062 if (SelectorName !=
"score")
1073 <<
"score expression";
1077void Parser::parseOMPContextSelector(
1079 llvm::StringMap<SourceLocation> &SeenSelectors) {
1080 unsigned short OuterPC = ParenCount;
1085 auto FinishSelector = [OuterPC,
this]() ->
void {
1088 while (!
SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1089 tok::annot_pragma_openmp_end},
1092 if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1093 (void)ConsumeParen();
1094 if (OuterPC <= ParenCount) {
1098 if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1104 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1105 << CONTEXT_SELECTOR_LVL;
1108 SourceLocation SelectorLoc = Tok.getLocation();
1109 parseOMPTraitSelectorKind(TISelector,
Set, SeenSelectors);
1110 if (TISelector.
Kind == TraitSelector::invalid)
1111 return FinishSelector();
1113 bool AllowsTraitScore =
false;
1114 bool RequiresProperty =
false;
1115 if (!isValidTraitSelectorForTraitSet(TISelector.
Kind,
Set, AllowsTraitScore,
1116 RequiresProperty)) {
1117 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1118 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1119 << getOpenMPContextTraitSetName(
Set);
1120 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1121 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1122 << getOpenMPContextTraitSetName(
1123 getOpenMPContextTraitSetForSelector(TISelector.
Kind))
1124 << RequiresProperty;
1125 return FinishSelector();
1128 if (!RequiresProperty) {
1130 {getOpenMPContextTraitPropertyForSelector(TISelector.
Kind),
1131 getOpenMPContextTraitSelectorName(TISelector.
Kind)});
1135 if (!Tok.is(tok::l_paren)) {
1136 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1137 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1138 << getOpenMPContextTraitSetName(
Set);
1139 return FinishSelector();
1142 if (TISelector.
Kind == TraitSelector::user_condition) {
1143 SourceLocation RLoc;
1146 return FinishSelector();
1149 {TraitProperty::user_condition_unknown,
"<condition>"});
1154 tok::annot_pragma_openmp_end);
1156 (void)BDT.consumeOpen();
1158 SourceLocation ScoreLoc = Tok.getLocation();
1161 if (!AllowsTraitScore && !Score.
isUnset()) {
1163 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1164 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1165 << getOpenMPContextTraitSetName(
Set) << Score.
get();
1167 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1168 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1169 << getOpenMPContextTraitSetName(
Set) <<
"<invalid>";
1177 llvm::StringMap<SourceLocation> SeenProperties;
1179 parseOMPContextProperty(TISelector,
Set, SeenProperties);
1186void Parser::parseOMPTraitSetKind(
OMPTraitSet &TISet,
1187 llvm::StringMap<SourceLocation> &Seen) {
1188 TISet.
Kind = TraitSet::invalid;
1190 SourceLocation NameLoc = Tok.getLocation();
1191 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_SET_LVL);
1193 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1194 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1198 TISet.
Kind = getOpenMPContextTraitSetKind(Name);
1199 if (TISet.
Kind != TraitSet::invalid) {
1200 if (checkForDuplicates(*
this, Name, NameLoc, Seen,
1201 CONTEXT_SELECTOR_SET_LVL))
1202 TISet.
Kind = TraitSet::invalid;
1207 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1209 TraitSelector SelectorForName =
1210 getOpenMPContextTraitSelectorKind(Name, TISet.
Kind);
1211 if (SelectorForName != TraitSelector::invalid) {
1212 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1213 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1214 bool AllowsTraitScore =
false;
1215 bool RequiresProperty =
false;
1216 isValidTraitSelectorForTraitSet(
1217 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1218 AllowsTraitScore, RequiresProperty);
1219 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1220 << getOpenMPContextTraitSetName(
1221 getOpenMPContextTraitSetForSelector(SelectorForName))
1222 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
1225 for (
const auto &PotentialSet :
1226 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1227 TraitSet::device, TraitSet::target_device}) {
1228 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1229 PotentialSet, TraitSelector::invalid, Name);
1230 if (PropertyForName == TraitProperty::invalid)
1232 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1233 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1234 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1235 << getOpenMPContextTraitSetName(
1236 getOpenMPContextTraitSetForProperty(PropertyForName))
1237 << getOpenMPContextTraitSelectorName(
1238 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1239 << (
"(" + Name +
")").str();
1242 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1243 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1246void Parser::parseOMPContextSelectorSet(
1247 OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1248 auto OuterBC = BraceCount;
1253 auto FinishSelectorSet = [
this, OuterBC]() ->
void {
1256 while (!
SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1257 tok::annot_pragma_openmp_end},
1260 if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1261 (void)ConsumeBrace();
1262 if (OuterBC <= BraceCount) {
1266 if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1272 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1273 << CONTEXT_SELECTOR_SET_LVL;
1276 parseOMPTraitSetKind(TISet, SeenSets);
1277 if (TISet.
Kind == TraitSet::invalid)
1278 return FinishSelectorSet();
1282 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1284 << (
"context set name \"" + getOpenMPContextTraitSetName(TISet.
Kind) +
1289 if (Tok.is(tok::l_brace)) {
1290 (void)ConsumeBrace();
1292 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1294 << (
"'=' that follows the context set name \"" +
1295 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1299 llvm::StringMap<SourceLocation> SeenSelectors;
1301 OMPTraitSelector TISelector;
1302 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1303 if (TISelector.
Kind != TraitSelector::invalid &&
1309 if (Tok.is(tok::r_brace)) {
1310 (void)ConsumeBrace();
1312 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1314 << (
"context selectors for the context set \"" +
1315 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1321 llvm::StringMap<SourceLocation> SeenSets;
1324 parseOMPContextSelectorSet(TISet, SeenSets);
1325 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1326 TI.
Sets.push_back(TISet);
1335 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1336 PP.EnterToken(Tok,
true);
1337 PP.EnterTokenStream(Toks,
true,
1343 FNContextRAII FnContext(*
this, Ptr);
1345 SourceLocation RLoc;
1355 getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion), RLoc,
1358 if (!AssociatedFunction.
isUsable()) {
1359 if (!Tok.is(tok::annot_pragma_openmp_end))
1363 (void)ConsumeAnnotationToken();
1367 OMPTraitInfo *ParentTI =
1368 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
1369 ASTContext &ASTCtx = Actions.getASTContext();
1371 SmallVector<Expr *, 6> AdjustNothing;
1372 SmallVector<Expr *, 6> AdjustNeedDevicePtr;
1373 SmallVector<Expr *, 6> AdjustNeedDeviceAddr;
1374 SmallVector<OMPInteropInfo, 3> AppendArgs;
1375 SourceLocation AdjustArgsLoc, AppendArgsLoc;
1378 if (Tok.is(tok::annot_pragma_openmp_end)) {
1379 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1383 bool IsError =
false;
1384 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1387 : getOpenMPClauseKind(PP.getSpelling(Tok));
1388 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1390 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1397 IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1399 case OMPC_adjust_args: {
1400 AdjustArgsLoc = Tok.getLocation();
1402 SemaOpenMP::OpenMPVarListDataTy
Data;
1403 SmallVector<Expr *> Vars;
1407 switch (
Data.ExtraModifier) {
1408 case OMPC_ADJUST_ARGS_nothing:
1409 llvm::append_range(AdjustNothing, Vars);
1411 case OMPC_ADJUST_ARGS_need_device_ptr:
1412 llvm::append_range(AdjustNeedDevicePtr, Vars);
1414 case OMPC_ADJUST_ARGS_need_device_addr:
1415 llvm::append_range(AdjustNeedDeviceAddr, Vars);
1418 llvm_unreachable(
"Unexpected 'adjust_args' clause modifier.");
1423 case OMPC_append_args:
1424 if (!AppendArgs.empty()) {
1425 Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1426 << getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion)
1427 << getOpenMPClauseName(CKind) << 0;
1431 AppendArgsLoc = Tok.getLocation();
1433 IsError = parseOpenMPAppendArgs(AppendArgs);
1437 llvm_unreachable(
"Unexpected clause for declare variant.");
1444 (void)ConsumeAnnotationToken();
1448 if (Tok.is(tok::comma))
1452 std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1453 Actions.OpenMP().checkOpenMPDeclareVariantFunction(
1454 Ptr, AssociatedFunction.
get(), TI, AppendArgs.size(),
1455 SourceRange(Loc, Tok.getLocation()));
1457 if (DeclVarData && !TI.
Sets.empty())
1458 Actions.OpenMP().ActOnOpenMPDeclareVariantDirective(
1459 DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1460 AdjustNeedDevicePtr, AdjustNeedDeviceAddr, AppendArgs, AdjustArgsLoc,
1461 AppendArgsLoc, SourceRange(Loc, Tok.getLocation()));
1464 (void)ConsumeAnnotationToken();
1467bool Parser::parseOpenMPAppendArgs(
1469 bool HasError =
false;
1472 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1473 getOpenMPClauseName(OMPC_append_args).data()))
1478 while (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"interop")) {
1481 tok::annot_pragma_openmp_end);
1482 if (IT.expectAndConsume(diag::err_expected_lparen_after,
"interop"))
1485 OMPInteropInfo InteropInfo;
1486 if (ParseOMPInteropInfo(InteropInfo, OMPC_append_args))
1489 InteropInfos.push_back(InteropInfo);
1492 if (Tok.is(tok::comma))
1495 if (!HasError && InteropInfos.empty()) {
1497 Diag(Tok.getLocation(), diag::err_omp_unexpected_append_op);
1498 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1501 HasError =
T.consumeClose() || HasError;
1505bool Parser::parseOMPDeclareVariantMatchClause(
SourceLocation Loc,
1511 : getOpenMPClauseKind(PP.getSpelling(Tok));
1512 if (CKind != OMPC_match) {
1513 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1520 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1521 getOpenMPClauseName(OMPC_match).data()))
1525 parseOMPContextSelectors(Loc, TI);
1528 (void)
T.consumeClose();
1538 for (
const OMPTraitSet &ParentSet : ParentTI->
Sets) {
1539 bool MergedSet =
false;
1540 for (OMPTraitSet &
Set : TI.
Sets) {
1541 if (
Set.Kind != ParentSet.
Kind)
1544 for (
const OMPTraitSelector &ParentSelector : ParentSet.
Selectors) {
1545 bool MergedSelector =
false;
1546 for (OMPTraitSelector &Selector :
Set.Selectors) {
1547 if (Selector.
Kind != ParentSelector.
Kind)
1549 MergedSelector =
true;
1550 for (
const OMPTraitProperty &ParentProperty :
1552 bool MergedProperty =
false;
1566 if (Selector.
Kind == llvm::omp::TraitSelector::user_condition) {
1567 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1570 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1571 << getOpenMPContextTraitPropertyName(
1573 << getOpenMPContextTraitSelectorName(ParentSelector.
Kind)
1574 << getOpenMPContextTraitSetName(ParentSet.
Kind);
1577 if (!MergedProperty)
1578 Selector.
Properties.push_back(ParentProperty);
1581 if (!MergedSelector)
1582 Set.Selectors.push_back(ParentSelector);
1586 TI.
Sets.push_back(ParentSet);
1595 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
1596 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1599 : getOpenMPClauseKind(PP.getSpelling(Tok));
1600 Actions.OpenMP().StartOpenMPClause(CKind);
1602 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
1603 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1605 SeenClauses[unsigned(CKind)] =
true;
1606 if (Clause !=
nullptr)
1607 Clauses.push_back(Clause);
1608 if (Tok.is(tok::annot_pragma_openmp_end)) {
1609 Actions.OpenMP().EndOpenMPClause();
1613 if (Tok.is(tok::comma))
1615 Actions.OpenMP().EndOpenMPClause();
1621 SmallVector<std::string, 4> Assumptions;
1622 bool SkippedClauses =
false;
1624 auto SkipBraces = [&](llvm::StringRef Spelling,
bool IssueNote) {
1626 tok::annot_pragma_openmp_end);
1627 if (
T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1630 if (IssueNote &&
T.getCloseLocation().isValid())
1631 Diag(
T.getCloseLocation(),
1632 diag::note_omp_assumption_clause_continue_here);
1638 auto MatchACMClause = [&](StringRef RawString) {
1639 llvm::StringSwitch<int> SS(RawString);
1640 unsigned ACMIdx = 0;
1641 for (
const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1642 if (ACMI.StartsWith)
1643 SS.StartsWith(ACMI.Identifier, ACMIdx++);
1645 SS.Case(ACMI.Identifier, ACMIdx++);
1647 return SS.Default(-1);
1650 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1651 IdentifierInfo *II =
nullptr;
1652 SourceLocation StartLoc = Tok.getLocation();
1654 if (Tok.isAnyIdentifier()) {
1655 II = Tok.getIdentifierInfo();
1656 Idx = MatchACMClause(II->
getName());
1660 bool NextIsLPar = Tok.is(tok::l_paren);
1663 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1664 Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1665 << llvm::omp::getOpenMPDirectiveName(DKind, OMPVersion)
1666 << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1668 SkipBraces(II ? II->
getName() :
"",
true);
1669 SkippedClauses =
true;
1672 const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1673 if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1676 SkippedClauses =
true;
1677 SkipBraces(II->
getName(),
false);
1682 Diag(Tok.getLocation(),
1683 diag::warn_omp_unknown_assumption_clause_without_args)
1685 SkipBraces(II->
getName(),
true);
1688 assert(II &&
"Expected an identifier clause!");
1689 std::string Assumption = II->
getName().str();
1690 if (ACMI.StartsWith)
1691 Assumption =
"ompx_" + Assumption.substr(ACMI.Identifier.size());
1693 Assumption =
"omp_" + Assumption;
1694 Assumptions.push_back(Assumption);
1697 Actions.OpenMP().ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions,
1702 if (Actions.OpenMP().isInOpenMPAssumeScope())
1703 Actions.OpenMP().ActOnOpenMPEndAssumesDirective();
1705 Diag(Loc, diag::err_expected_begin_assumes);
1719struct SimpleClauseData {
1722 SourceLocation LOpen;
1723 SourceLocation TypeLoc;
1724 SourceLocation RLoc;
1725 SimpleClauseData(
unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1726 SourceLocation TypeLoc, SourceLocation RLoc)
1727 :
Type(
Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1731static std::optional<SimpleClauseData>
1738 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1739 getOpenMPClauseName(Kind).data()))
1740 return std::nullopt;
1746 if (
Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::comma) &&
1747 Tok.isNot(tok::annot_pragma_openmp_end))
1752 if (!
T.consumeClose())
1753 RLoc =
T.getCloseLocation();
1755 return SimpleClauseData(
Type, Loc, LOpen,
TypeLoc, RLoc);
1758void Parser::ParseOMPDeclareTargetClauses(
1760 SourceLocation DeviceTypeLoc;
1761 bool RequiresToOrLinkOrIndirectClause =
false;
1762 bool HasToOrLinkOrIndirectClause =
false;
1763 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1764 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1765 bool HasIdentifier = Tok.is(tok::identifier);
1766 if (HasIdentifier) {
1768 RequiresToOrLinkOrIndirectClause =
true;
1769 IdentifierInfo *II = Tok.getIdentifierInfo();
1770 StringRef ClauseName = II->
getName();
1771 bool IsDeviceTypeClause =
1773 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1775 bool IsIndirectClause =
getLangOpts().OpenMP >= 51 &&
1776 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1777 if (DTCI.
Indirect && IsIndirectClause) {
1778 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1779 Diag(Tok, diag::err_omp_more_one_clause)
1780 << getOpenMPDirectiveName(OMPD_declare_target, OMPVersion)
1781 << getOpenMPClauseName(OMPC_indirect) << 0;
1784 bool IsToEnterOrLinkClause =
1785 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1786 assert((!IsDeviceTypeClause || !IsToEnterOrLinkClause) &&
1791 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1792 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1795 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1796 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1800 if (!IsDeviceTypeClause && !IsIndirectClause &&
1801 DTCI.
Kind == OMPD_begin_declare_target) {
1802 Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1803 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1806 if (!IsDeviceTypeClause && !IsToEnterOrLinkClause && !IsIndirectClause) {
1808 ? diag::err_omp_declare_target_unexpected_clause_52
1809 : diag::err_omp_declare_target_unexpected_clause)
1817 if (IsToEnterOrLinkClause || IsIndirectClause)
1818 HasToOrLinkOrIndirectClause =
true;
1820 if (IsIndirectClause) {
1821 if (!ParseOpenMPIndirectClause(DTCI,
false))
1826 if (IsDeviceTypeClause) {
1827 std::optional<SimpleClauseData> DevTypeData =
1830 if (DeviceTypeLoc.
isValid()) {
1832 Diag(DevTypeData->Loc,
1833 diag::warn_omp_more_one_device_type_clause);
1837 case OMPC_DEVICE_TYPE_any:
1838 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Any;
1840 case OMPC_DEVICE_TYPE_host:
1841 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Host;
1843 case OMPC_DEVICE_TYPE_nohost:
1844 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1847 llvm_unreachable(
"Unexpected device_type");
1849 DeviceTypeLoc = DevTypeData->Loc;
1856 if (DTCI.
Kind == OMPD_declare_target || HasIdentifier) {
1857 auto &&Callback = [
this, MT, &DTCI](CXXScopeSpec &SS,
1858 DeclarationNameInfo NameInfo) {
1859 NamedDecl *ND = Actions.OpenMP().lookupOpenMPDeclareTargetName(
1863 SemaOpenMP::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.
getLoc()};
1866 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1869 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1874 if (Tok.is(tok::l_paren)) {
1876 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1879 if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1882 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1883 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1888 if (Tok.is(tok::comma))
1892 if (DTCI.
Indirect && DTCI.
DT != OMPDeclareTargetDeclAttr::DT_Any)
1893 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1896 if (DTCI.
Kind == OMPD_declare_target && RequiresToOrLinkOrIndirectClause &&
1897 !HasToOrLinkOrIndirectClause)
1900 ? diag::err_omp_declare_target_missing_enter_or_link_clause
1901 : diag::err_omp_declare_target_missing_to_or_link_clause)
1910 if (Tok.is(tok::annot_pragma_openmp_end))
1913 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1914 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1915 << getOpenMPDirectiveName(DKind, OMPVersion);
1916 while (Tok.isNot(tok::annot_pragma_openmp_end))
1925 bool SkipUntilOpenMPEnd) {
1926 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1928 if (FoundKind == ExpectedKind) {
1930 skipUntilPragmaOpenMPEnd(ExpectedKind);
1934 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1935 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1937 Diag(BeginLoc, diag::note_matching)
1938 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind, OMPVersion) +
"'")
1940 if (SkipUntilOpenMPEnd)
1947 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1951 if (Tok.is(tok::annot_pragma_openmp_end))
1952 ConsumeAnnotationToken();
1958 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
1959 "Not an OpenMP directive!");
1962 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1967 TentativeParsingAction TPA(*
this);
1968 Loc = ConsumeAnnotationToken();
1970 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1975 Toks.push_back(Tok);
1976 while (Cnt && Tok.isNot(tok::eof)) {
1978 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
1980 else if (Tok.is(tok::annot_pragma_openmp_end))
1982 Toks.push_back(Tok);
1987 auto *LP =
new LateParsedPragma(
this, AS);
1989 getCurrentClass().LateParsedDeclarations.push_back(LP);
1994 Loc = ConsumeAnnotationToken();
1999 case OMPD_threadprivate: {
2001 DeclDirectiveListParserHelper Helper(
this, DKind);
2002 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2004 skipUntilPragmaOpenMPEnd(DKind);
2006 ConsumeAnnotationToken();
2007 return Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2008 Loc, Helper.getIdentifiers());
2012 case OMPD_allocate: {
2014 DeclDirectiveListParserHelper Helper(
this, DKind);
2015 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2017 SmallVector<OMPClause *, 1> Clauses;
2018 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2019 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
2020 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2022 Tok.isAnnotation() ? OMPC_unknown
2023 : getOpenMPClauseKind(PP.getSpelling(Tok));
2024 Actions.OpenMP().StartOpenMPClause(CKind);
2025 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2026 !SeenClauses[
unsigned(CKind)]);
2027 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2029 SeenClauses[unsigned(CKind)] =
true;
2030 if (Clause !=
nullptr)
2031 Clauses.push_back(Clause);
2032 if (Tok.is(tok::annot_pragma_openmp_end)) {
2033 Actions.OpenMP().EndOpenMPClause();
2037 if (Tok.is(tok::comma))
2039 Actions.OpenMP().EndOpenMPClause();
2041 skipUntilPragmaOpenMPEnd(DKind);
2044 ConsumeAnnotationToken();
2045 return Actions.OpenMP().ActOnOpenMPAllocateDirective(
2046 Loc, Helper.getIdentifiers(), Clauses);
2050 case OMPD_requires: {
2052 SmallVector<OMPClause *, 5> Clauses;
2053 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2054 if (Tok.is(tok::annot_pragma_openmp_end)) {
2055 Diag(Tok, diag::err_omp_expected_clause)
2056 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2059 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2062 : getOpenMPClauseKind(PP.getSpelling(Tok));
2063 Actions.OpenMP().StartOpenMPClause(CKind);
2064 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
2065 !SeenClauses[
unsigned(CKind)]);
2066 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2068 SeenClauses[unsigned(CKind)] =
true;
2069 if (Clause !=
nullptr)
2070 Clauses.push_back(Clause);
2071 if (Tok.is(tok::annot_pragma_openmp_end)) {
2072 Actions.OpenMP().EndOpenMPClause();
2076 if (Tok.is(tok::comma))
2078 Actions.OpenMP().EndOpenMPClause();
2081 if (Clauses.empty()) {
2082 Diag(Tok, diag::err_omp_expected_clause)
2083 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2084 ConsumeAnnotationToken();
2087 ConsumeAnnotationToken();
2088 return Actions.OpenMP().ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2091 SmallVector<OMPClause *, 1> Clauses;
2093 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2094 Actions.OpenMP().ActOnOpenMPErrorDirective(Clauses, StartLoc,
2100 case OMPD_begin_assumes:
2103 case OMPD_end_assumes:
2106 case OMPD_declare_reduction:
2108 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2109 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2111 ConsumeAnnotationToken();
2115 case OMPD_declare_mapper: {
2117 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2119 ConsumeAnnotationToken();
2124 case OMPD_begin_declare_variant: {
2129 ConsumeAnnotationToken();
2133 case OMPD_end_declare_variant: {
2135 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2136 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2138 Diag(Loc, diag::err_expected_begin_declare_variant);
2140 ConsumeAnnotationToken();
2143 case OMPD_declare_variant:
2144 case OMPD_declare_simd: {
2150 Toks.push_back(Tok);
2152 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2153 Toks.push_back(Tok);
2156 Toks.push_back(Tok);
2160 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2161 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2163 }
else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2167 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2168 MaybeParseCXX11Attributes(Attrs);
2169 ParsingDeclSpec PDS(*
this);
2170 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2173 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2177 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2178 << (DKind == OMPD_declare_simd ? 0 : 1);
2181 if (DKind == OMPD_declare_simd)
2182 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2183 assert(DKind == OMPD_declare_variant &&
2184 "Expected declare variant directive only");
2185 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2188 case OMPD_begin_declare_target:
2189 case OMPD_declare_target: {
2191 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2192 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2193 if (DKind == OMPD_declare_target && !HasClauses &&
2195 Diag(DTLoc, diag::warn_omp_deprecated_declare_target_delimited_form);
2197 ParseOMPDeclareTargetClauses(DTCI);
2198 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2205 if (HasImplicitMappings) {
2206 Actions.OpenMP().ActOnStartOpenMPDeclareTargetContext(DTCI);
2210 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2211 llvm::SmallVector<Decl *, 4> Decls;
2213 Decls.push_back(It.first);
2214 return Actions.BuildDeclaratorGroup(Decls);
2216 case OMPD_end_declare_target: {
2217 if (!Actions.OpenMP().isInOpenMPDeclareTargetContext()) {
2218 Diag(Tok, diag::err_omp_unexpected_directive)
2219 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2222 const SemaOpenMP::DeclareTargetContextInfo &DTCI =
2223 Actions.OpenMP().ActOnOpenMPEndDeclareTargetDirective();
2224 ParseOMPEndDeclareTargetDirective(DTCI.
Kind, DKind, DTCI.
Loc);
2228 Diag(Tok, diag::err_omp_unexpected_directive)
2229 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2233 Diag(Tok, diag::err_omp_unknown_directive);
2236 switch (getDirectiveCategory(DKind)) {
2237 case Category::Executable:
2238 case Category::Meta:
2239 case Category::Subsidiary:
2240 case Category::Utility:
2241 Diag(Tok, diag::err_omp_unexpected_directive)
2242 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2244 case Category::Declarative:
2245 case Category::Informational:
2249 while (Tok.isNot(tok::annot_pragma_openmp_end))
2255StmtResult Parser::ParseOpenMPExecutableDirective(
2257 bool ReadDirectiveWithinMetadirective) {
2259 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2261 bool HasAssociatedStatement =
true;
2262 Association Assoc = getDirectiveAssociation(DKind);
2268 if (DKind != OMPD_ordered && DKind != OMPD_section &&
2269 (Assoc == Association::None || Assoc == Association::Separating)) {
2270 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2271 ParsedStmtContext()) {
2272 Diag(Tok, diag::err_omp_immediate_directive)
2273 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2274 if (DKind == OMPD_error) {
2275 SkipUntil(tok::annot_pragma_openmp_end);
2279 HasAssociatedStatement =
false;
2282 SourceLocation EndLoc;
2283 SmallVector<OMPClause *, 5> Clauses;
2284 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2285 DeclarationNameInfo DirName;
2292 bool ImplicitClauseAllowed =
false;
2293 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2295 ImplicitClauseAllowed =
true;
2299 if (DKind == OMPD_critical) {
2301 tok::annot_pragma_openmp_end);
2302 if (!
T.consumeOpen()) {
2303 if (Tok.isAnyIdentifier()) {
2305 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2308 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2312 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2314 if (Tok.isNot(tok::annot_pragma_openmp_end))
2322 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2323 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2326 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2329 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2330 while (Tok.isNot(tok::annot_pragma_openmp_end))
2334 bool HasImplicitClause =
false;
2335 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2336 HasImplicitClause =
true;
2339 PP.EnterToken(Tok,
true);
2340 PP.EnterToken(ImplicitTok,
true);
2345 : getOpenMPClauseKind(PP.getSpelling(Tok));
2346 if (HasImplicitClause) {
2347 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2348 if (DKind == OMPD_flush) {
2351 assert(DKind == OMPD_depobj &&
"Expected flush or depobj directives.");
2352 CKind = OMPC_depobj;
2356 ImplicitClauseAllowed =
false;
2357 Actions.OpenMP().StartOpenMPClause(CKind);
2358 HasImplicitClause =
false;
2360 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2361 SeenClauses[unsigned(CKind)] =
true;
2363 Clauses.push_back(Clause);
2366 if (Tok.is(tok::comma))
2368 Actions.OpenMP().EndOpenMPClause();
2371 EndLoc = Tok.getLocation();
2373 ConsumeAnnotationToken();
2375 if (DKind == OMPD_ordered) {
2378 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2379 if (SeenClauses[
unsigned(CK)]) {
2380 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2381 ParsedStmtContext()) {
2382 Diag(Loc, diag::err_omp_immediate_directive)
2383 << getOpenMPDirectiveName(DKind, OMPVersion) << 1
2384 << getOpenMPClauseName(CK);
2386 HasAssociatedStatement =
false;
2391 if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
2392 !SeenClauses[
unsigned(OMPC_sizes)]) {
2393 Diag(Loc, diag::err_omp_required_clause)
2394 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"sizes";
2398 if (HasAssociatedStatement) {
2400 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2406 Sema::CompoundScopeRAII Scope(Actions);
2407 AssociatedStmt = ParseStatement();
2412 Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
2415 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2416 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2417 DKind == OMPD_target_exit_data) {
2418 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2419 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2420 Actions.ActOnCompoundStmt(Loc, Loc, {},
2423 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2427 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2430 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2431 OMPDirectiveScope.Exit();
2436StmtResult Parser::ParseOpenMPInformationalDirective(
2438 bool ReadDirectiveWithinMetadirective) {
2440 "Unexpected directive category");
2442 bool HasAssociatedStatement =
true;
2444 SmallVector<OMPClause *, 5> Clauses;
2445 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2446 DeclarationNameInfo DirName;
2449 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2451 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2454 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2455 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2456 while (Tok.isNot(tok::annot_pragma_openmp_end))
2463 : getOpenMPClauseKind(PP.getSpelling(Tok));
2464 Actions.OpenMP().StartOpenMPClause(CKind);
2466 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2467 SeenClauses[unsigned(CKind)] =
true;
2469 Clauses.push_back(Clause);
2471 if (Tok.is(tok::comma))
2473 Actions.OpenMP().EndOpenMPClause();
2476 SourceLocation EndLoc = Tok.getLocation();
2477 ConsumeAnnotationToken();
2480 if (HasAssociatedStatement) {
2481 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2484 Sema::CompoundScopeRAII Scope(Actions);
2485 AssociatedStmt = ParseStatement();
2488 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2492 DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2494 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2495 OMPDirectiveScope.Exit();
2500StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2501 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2502 if (!ReadDirectiveWithinMetadirective)
2503 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2504 "Not an OpenMP directive!");
2507 SourceLocation Loc = ReadDirectiveWithinMetadirective
2509 : ConsumeAnnotationToken();
2510 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2512 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2513 Diag(Tok, diag::err_omp_unknown_directive);
2519 bool IsExecutable = [&]() {
2520 if (DKind == OMPD_error)
2522 auto Res = getDirectiveCategory(DKind);
2523 return Res == Category::Executable || Res == Category::Subsidiary;
2527 Directive = ParseOpenMPExecutableDirective(
2528 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2529 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2538 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
2539 while (Tok.isNot(tok::annot_pragma_openmp_end))
2542 skipUntilPragmaOpenMPEnd(DKind);
2543 if (Tok.is(tok::annot_pragma_openmp_end))
2544 ConsumeAnnotationToken();
2547 case OMPD_metadirective: {
2549 SmallVector<VariantMatchInfo, 4> VMIs;
2554 TentativeParsingAction TPA(*
this);
2555 ASTContext &ASTContext = Actions.getASTContext();
2558 tok::annot_pragma_openmp_end);
2559 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2562 : getOpenMPClauseKind(PP.getSpelling(Tok));
2564 if (CKind == OMPC_unknown) {
2565 Diag(Tok, diag::err_omp_expected_clause) <<
"metadirective";
2567 SkipUntil(tok::annot_pragma_openmp_end);
2570 if (
getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
2571 Diag(Tok, diag::err_omp_unexpected_clause)
2572 << getOpenMPClauseName(CKind) <<
"metadirective";
2573 if (CKind == OMPC_default &&
getLangOpts().OpenMP >= 52)
2574 Diag(Tok, diag::warn_omp_default_deprecated);
2579 if (
T.expectAndConsume(diag::err_expected_lparen_after,
2580 getOpenMPClauseName(CKind).data())) {
2582 SkipUntil(tok::annot_pragma_openmp_end);
2586 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2587 if (CKind == OMPC_when) {
2589 parseOMPContextSelectors(Loc, TI);
2590 if (TI.
Sets.size() == 0) {
2591 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2597 if (Tok.is(tok::colon))
2600 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2608 while (Tok.isNot(tok::r_paren) || paren != 0) {
2609 if (Tok.is(tok::l_paren))
2611 if (Tok.is(tok::r_paren))
2613 if (Tok.is(tok::annot_pragma_openmp_end)) {
2614 Diag(Tok, diag::err_omp_expected_punc)
2615 << getOpenMPClauseName(CKind) << 0;
2622 if (Tok.is(tok::r_paren))
2625 VariantMatchInfo VMI;
2628 VMIs.push_back(VMI);
2635 [
this, Loc](StringRef ISATrait) {
2638 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2640 TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2642 ArrayRef<llvm::omp::TraitProperty>(),
2643 Actions.OpenMP().getOpenMPDeviceNum());
2646 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2653 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2655 if (Idx++ != BestIdx) {
2660 while (Tok.isNot(tok::r_paren) || paren != 0) {
2661 if (Tok.is(tok::l_paren))
2663 if (Tok.is(tok::r_paren))
2668 if (Tok.is(tok::r_paren))
2675 : getOpenMPClauseKind(PP.getSpelling(Tok));
2682 if (CKind == OMPC_when) {
2683 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2685 parseOMPContextSelectors(Loc, TI);
2693 if (Tok.is(tok::r_paren)) {
2694 SkipUntil(tok::annot_pragma_openmp_end);
2699 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2707 if (BestIdx == -1 && Idx > 0) {
2708 assert(Tok.is(tok::annot_pragma_openmp_end) &&
2709 "Expecting the end of the pragma here");
2710 ConsumeAnnotationToken();
2715 case OMPD_threadprivate: {
2717 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2718 ParsedStmtContext()) {
2719 Diag(Tok, diag::err_omp_immediate_directive)
2720 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2723 DeclDirectiveListParserHelper Helper(
this, DKind);
2724 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2726 skipUntilPragmaOpenMPEnd(DKind);
2727 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2728 Loc, Helper.getIdentifiers());
2729 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2731 SkipUntil(tok::annot_pragma_openmp_end);
2734 case OMPD_allocate: {
2736 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2737 ParsedStmtContext()) {
2738 Diag(Tok, diag::err_omp_immediate_directive)
2739 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2742 DeclDirectiveListParserHelper Helper(
this, DKind);
2743 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2745 SmallVector<OMPClause *, 1> Clauses;
2746 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2747 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2748 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2750 Tok.isAnnotation() ? OMPC_unknown
2751 : getOpenMPClauseKind(PP.getSpelling(Tok));
2752 Actions.OpenMP().StartOpenMPClause(CKind);
2753 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2754 !SeenClauses[
unsigned(CKind)]);
2755 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2757 SeenClauses[unsigned(CKind)] =
true;
2758 if (Clause !=
nullptr)
2759 Clauses.push_back(Clause);
2760 if (Tok.is(tok::annot_pragma_openmp_end)) {
2761 Actions.OpenMP().EndOpenMPClause();
2765 if (Tok.is(tok::comma))
2767 Actions.OpenMP().EndOpenMPClause();
2769 skipUntilPragmaOpenMPEnd(DKind);
2771 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPAllocateDirective(
2772 Loc, Helper.getIdentifiers(), Clauses);
2773 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2775 SkipUntil(tok::annot_pragma_openmp_end);
2778 case OMPD_declare_reduction:
2781 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2782 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2784 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2786 SkipUntil(tok::annot_pragma_openmp_end);
2789 case OMPD_declare_mapper: {
2792 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2794 ConsumeAnnotationToken();
2795 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2797 SkipUntil(tok::annot_pragma_openmp_end);
2801 case OMPD_declare_target: {
2803 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2804 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2806 ParseOMPDeclareTargetClauses(DTCI);
2807 bool HasImplicitMappings =
2810 if (HasImplicitMappings) {
2811 Diag(Tok, diag::err_omp_unexpected_directive)
2812 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2813 SkipUntil(tok::annot_pragma_openmp_end);
2820 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2823 case OMPD_begin_declare_variant: {
2828 ConsumeAnnotationToken();
2832 case OMPD_end_declare_variant: {
2834 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2835 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2837 Diag(Loc, diag::err_expected_begin_declare_variant);
2838 ConsumeAnnotationToken();
2841 case OMPD_declare_simd:
2842 case OMPD_begin_declare_target:
2843 case OMPD_end_declare_target:
2845 case OMPD_declare_variant:
2846 Diag(Tok, diag::err_omp_unexpected_directive)
2847 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2848 SkipUntil(tok::annot_pragma_openmp_end);
2852 Directive = ParseOpenMPInformationalDirective(
2853 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2855 "Informational directive remains unprocessed");
2860 Diag(Tok, diag::err_omp_unknown_directive);
2861 SkipUntil(tok::annot_pragma_openmp_end);
2867bool Parser::ParseOpenMPSimpleVarList(
2871 bool AllowScopeSpecifier) {
2872 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2875 if (
T.expectAndConsume(diag::err_expected_lparen_after,
2876 getOpenMPDirectiveName(Kind, OMPVersion).data()))
2878 bool IsCorrect =
true;
2879 bool NoIdentIsFound =
true;
2882 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2886 Token PrevTok = Tok;
2887 NoIdentIsFound =
false;
2890 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2893 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2896 false,
false,
false,
2897 false,
false,
nullptr, Name)) {
2899 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2901 }
else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2902 Tok.isNot(tok::annot_pragma_openmp_end)) {
2904 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2908 << SourceRange(PrevTok.
getLocation(), PrevTokLocation);
2910 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2913 if (Tok.is(tok::comma)) {
2918 if (NoIdentIsFound) {
2919 Diag(Tok, diag::err_expected) << tok::identifier;
2924 IsCorrect = !
T.consumeClose() && IsCorrect;
2929OMPClause *Parser::ParseOpenMPSizesClause() {
2930 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
2931 SmallVector<Expr *, 4> ValExprs;
2932 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
2936 return Actions.OpenMP().ActOnOpenMPSizesClause(ValExprs, ClauseNameLoc,
2940OMPClause *Parser::ParseOpenMPPermutationClause() {
2941 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
2942 SmallVector<Expr *> ArgExprs;
2943 if (ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,
2948 return Actions.OpenMP().ActOnOpenMPPermutationClause(ArgExprs, ClauseNameLoc,
2953 SourceLocation Loc = Tok.getLocation();
2958 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
2960 SmallVector<SemaOpenMP::UsesAllocatorsData, 4>
Data;
2966 ? ParseCXXIdExpression()
2967 : tryParseCXXIdExpression(SS,
false,
2970 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2974 SemaOpenMP::UsesAllocatorsData &D =
Data.emplace_back();
2975 D.Allocator = Allocator.
get();
2976 if (Tok.is(tok::l_paren)) {
2977 BalancedDelimiterTracker T(*this, tok::l_paren,
2978 tok::annot_pragma_openmp_end);
2980 ExprResult AllocatorTraits =
2981 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
2983 if (AllocatorTraits.isInvalid()) {
2984 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2988 D.AllocatorTraits = AllocatorTraits.get();
2989 D.LParenLoc =
T.getOpenLocation();
2990 D.RParenLoc =
T.getCloseLocation();
2992 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
2993 Diag(Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
2995 if (Tok.is(tok::comma))
2997 }
while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end));
3000 Loc,
T.getOpenLocation(),
T.getCloseLocation(),
Data);
3005 OMPClauseKind = CKind;
3006 OMPClause *Clause =
nullptr;
3007 bool ErrorFound =
false;
3008 bool WrongDirective =
false;
3009 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
3012 if (CKind != OMPC_unknown &&
3013 !isAllowedClauseForDirective(DKind, CKind,
getLangOpts().OpenMP)) {
3014 Diag(Tok, diag::err_omp_unexpected_clause)
3015 << getOpenMPClauseName(CKind)
3016 << getOpenMPDirectiveName(DKind, OMPVersion);
3018 WrongDirective =
true;
3023 case OMPC_num_threads:
3029 case OMPC_grainsize:
3030 case OMPC_num_tasks:
3032 case OMPC_allocator:
3035 case OMPC_novariants:
3036 case OMPC_nocontext:
3041 case OMPC_ompx_dyn_cgroup_mem:
3070 Diag(Tok, diag::err_omp_more_one_clause)
3071 << getOpenMPDirectiveName(DKind, OMPVersion)
3072 << getOpenMPClauseName(CKind) << 0;
3076 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3077 PP.LookAhead(0).isNot(tok::l_paren))
3078 Clause = ParseOpenMPClause(CKind, WrongDirective);
3079 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3080 CKind == OMPC_num_threads)
3081 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3083 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3087 case OMPC_proc_bind:
3088 case OMPC_atomic_default_mem_order:
3106 Diag(Tok, diag::err_omp_more_one_clause)
3107 << getOpenMPDirectiveName(DKind, OMPVersion)
3108 << getOpenMPClauseName(CKind) << 0;
3112 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3116 case OMPC_dist_schedule:
3117 case OMPC_defaultmap:
3127 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3128 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3129 Diag(Tok, diag::err_omp_more_one_clause)
3130 << getOpenMPDirectiveName(DKind, OMPVersion)
3131 << getOpenMPClauseName(CKind) << 0;
3136 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3139 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3143 case OMPC_mergeable:
3157 case OMPC_unified_address:
3158 case OMPC_unified_shared_memory:
3159 case OMPC_reverse_offload:
3160 case OMPC_dynamic_allocators:
3169 Diag(Tok, diag::err_omp_more_one_clause)
3170 << getOpenMPDirectiveName(DKind, OMPVersion)
3171 << getOpenMPClauseName(CKind) << 0;
3175 Clause = ParseOpenMPClause(CKind, WrongDirective);
3177 case OMPC_self_maps:
3180 Diag(Tok, diag::err_omp_expected_clause)
3181 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3185 Diag(Tok, diag::err_omp_more_one_clause)
3186 << getOpenMPDirectiveName(DKind, OMPVersion)
3187 << getOpenMPClauseName(CKind) << 0;
3190 Clause = ParseOpenMPClause(CKind, WrongDirective);
3194 Diag(Tok, diag::err_omp_more_one_clause)
3195 << getOpenMPDirectiveName(DKind, OMPVersion)
3196 << getOpenMPClauseName(CKind) << 0;
3200 Clause = (DKind == OMPD_depobj)
3201 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3202 : ParseOpenMPClause(CKind, WrongDirective);
3204 case OMPC_num_teams:
3205 case OMPC_thread_limit:
3207 Diag(Tok, diag::err_omp_more_one_clause)
3208 << getOpenMPDirectiveName(DKind, OMPVersion)
3209 << getOpenMPClauseName(CKind) << 0;
3214 case OMPC_firstprivate:
3215 case OMPC_lastprivate:
3217 case OMPC_reduction:
3218 case OMPC_task_reduction:
3219 case OMPC_in_reduction:
3223 case OMPC_copyprivate:
3229 case OMPC_use_device_ptr:
3230 case OMPC_use_device_addr:
3231 case OMPC_is_device_ptr:
3232 case OMPC_has_device_addr:
3234 case OMPC_nontemporal:
3235 case OMPC_inclusive:
3236 case OMPC_exclusive:
3240 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
3241 CKind == OMPC_depend)
3242 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3243 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3247 Diag(Tok, diag::err_omp_more_one_clause)
3248 << getOpenMPDirectiveName(DKind, OMPVersion)
3249 << getOpenMPClauseName(CKind) << 0;
3253 Clause = ParseOpenMPSizesClause();
3255 case OMPC_permutation:
3257 Diag(Tok, diag::err_omp_more_one_clause)
3258 << getOpenMPDirectiveName(DKind, OMPVersion)
3259 << getOpenMPClauseName(CKind) << 0;
3262 Clause = ParseOpenMPPermutationClause();
3264 case OMPC_uses_allocators:
3265 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3268 if (DKind != OMPD_interop) {
3270 Diag(Tok, diag::err_omp_more_one_clause)
3271 << getOpenMPDirectiveName(DKind, OMPVersion)
3272 << getOpenMPClauseName(CKind) << 0;
3275 Clause = ParseOpenMPClause(CKind, WrongDirective);
3281 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3283 case OMPC_device_type:
3285 skipUntilPragmaOpenMPEnd(DKind);
3287 case OMPC_threadprivate:
3290 if (!WrongDirective)
3291 Diag(Tok, diag::err_omp_unexpected_clause)
3292 << getOpenMPClauseName(CKind)
3293 << getOpenMPDirectiveName(DKind, OMPVersion);
3297 case OMPC_contains: {
3299 SourceLocation LLoc = Tok.getLocation();
3300 SourceLocation RLoc;
3301 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3306 if (DK == OMPD_unknown) {
3307 skipUntilPragmaOpenMPEnd(OMPD_assume);
3308 Diag(Tok, diag::err_omp_unexpected_clause)
3309 << getOpenMPClauseName(CKind)
3310 << getOpenMPDirectiveName(DKind, OMPVersion);
3314 DKVec.push_back(DK);
3317 Diag(Tok, diag::err_omp_unexpected_clause)
3318 << getOpenMPClauseName(CKind)
3319 << getOpenMPDirectiveName(DKind, OMPVersion);
3322 RLoc = Tok.getLocation();
3324 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3325 CKind, DKVec, Loc, LLoc, RLoc);
3328 case OMPC_no_openmp:
3329 case OMPC_no_openmp_routines:
3330 case OMPC_no_openmp_constructs:
3331 case OMPC_no_parallelism: {
3333 Diag(Tok, diag::err_omp_more_one_clause)
3334 << getOpenMPDirectiveName(DKind, OMPVersion)
3335 << getOpenMPClauseName(CKind) << 0;
3339 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3340 CKind, Loc, Tok.getLocation());
3343 case OMPC_ompx_attribute:
3344 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3346 case OMPC_ompx_bare:
3347 if (DKind == llvm::omp::Directive::OMPD_target) {
3352 Diag(Tok, diag::err_omp_unexpected_clause)
3353 << getOpenMPClauseName(CKind)
3354 << getOpenMPDirectiveName(DKind, OMPVersion);
3356 WrongDirective =
true;
3359 Diag(Tok, diag::note_ompx_bare_clause)
3360 << getOpenMPClauseName(CKind) <<
"target teams";
3361 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3362 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3363 << getOpenMPClauseName(CKind)
3364 << getOpenMPDirectiveName(DKind, OMPVersion);
3367 Clause = ParseOpenMPClause(CKind, WrongDirective);
3372 return ErrorFound ?
nullptr : Clause;
3380 bool IsAddressOfOperand) {
3382 if (
T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3390 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3393 RLoc = Tok.getLocation();
3394 if (!
T.consumeClose())
3395 RLoc =
T.getCloseLocation();
3417bool Parser::ParseOpenMPIndirectClause(
3422 if (
Tok.isNot(tok::l_paren)) {
3441 if (
Ret.isInvalid())
3444 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3446 if (
Ret.isInvalid())
3457 bool HasError =
false;
3458 bool IsTarget =
false;
3459 bool IsTargetSync =
false;
3461 while (Tok.is(tok::identifier)) {
3463 bool PreferTypeAllowed =
Kind == OMPC_init &&
3466 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3471 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3474 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3476 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3477 IsTargetSync =
true;
3479 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3480 PreferTypeAllowed) {
3483 tok::annot_pragma_openmp_end);
3484 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3487 while (Tok.isNot(tok::r_paren)) {
3488 SourceLocation Loc = Tok.getLocation();
3491 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
3497 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3501 if (Tok.is(tok::comma))
3507 Diag(Tok, diag::err_omp_expected_interop_type);
3510 if (!Tok.is(tok::comma))
3515 if (!HasError && !IsTarget && !IsTargetSync) {
3516 Diag(Tok, diag::err_omp_expected_interop_type);
3520 if (Kind == OMPC_init) {
3521 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
3522 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3523 if (Tok.is(tok::colon))
3540 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3541 getOpenMPClauseName(Kind).data()))
3544 bool InteropError =
false;
3545 OMPInteropInfo InteropInfo;
3546 if (Kind == OMPC_init)
3547 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3550 SourceLocation VarLoc = Tok.getLocation();
3553 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3558 SourceLocation RLoc = Tok.getLocation();
3559 if (!
T.consumeClose())
3560 RLoc =
T.getCloseLocation();
3562 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3565 if (Kind == OMPC_init)
3566 return Actions.OpenMP().ActOnOpenMPInitClause(
3567 InteropVarExpr.
get(), InteropInfo, Loc,
T.getOpenLocation(), VarLoc,
3569 if (Kind == OMPC_use)
3570 return Actions.OpenMP().ActOnOpenMPUseClause(
3571 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
3573 if (Kind == OMPC_destroy)
3574 return Actions.OpenMP().ActOnOpenMPDestroyClause(
3575 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
3577 llvm_unreachable(
"Unexpected interop variable clause.");
3580OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
3584 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3585 getOpenMPClauseName(OMPC_ompx_attribute).data()))
3588 ParsedAttributes ParsedAttrs(AttrFactory);
3589 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
3592 if (
T.consumeClose())
3598 SmallVector<Attr *> Attrs;
3599 for (
const ParsedAttr &PA : ParsedAttrs) {
3600 switch (PA.getKind()) {
3601 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
3602 if (!PA.checkExactlyNumArgs(Actions, 2))
3604 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
3605 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
3608 case ParsedAttr::AT_AMDGPUWavesPerEU:
3609 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3610 !PA.checkAtMostNumArgs(Actions, 2))
3612 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
3613 PA, PA.getArgAsExpr(0),
3614 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
3617 case ParsedAttr::AT_CUDALaunchBounds:
3618 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3619 !PA.checkAtMostNumArgs(Actions, 2))
3621 if (
auto *A = Actions.CreateLaunchBoundsAttr(
3622 PA, PA.getArgAsExpr(0),
3623 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
3624 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr))
3628 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
3633 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
3634 Attrs, Loc,
T.getOpenLocation(),
T.getCloseLocation());
3640 if (!Val || ParseOnly)
3642 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3643 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
3644 static_cast<DefaultKind
>(Val->Type) ==
3645 OMP_DEFAULT_firstprivate)) {
3646 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
3647 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
3650 : OMPC_firstprivate)
3651 << getOpenMPClauseName(OMPC_default) <<
"5.1";
3654 return Actions.OpenMP().ActOnOpenMPSimpleClause(
3655 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
3659 SourceLocation Loc = Tok.getLocation();
3664 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3671 SourceLocation DelimLoc;
3674 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3675 getOpenMPClauseName(Kind).data()))
3679 SmallVector<unsigned, 4> Arg;
3680 SmallVector<SourceLocation, 4> KLoc;
3681 if (Kind == OMPC_schedule) {
3682 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3683 Arg.resize(NumberOfElements);
3684 KLoc.resize(NumberOfElements);
3689 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3692 Arg[Modifier1] = KindModifier;
3693 KLoc[Modifier1] = Tok.getLocation();
3694 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3695 Tok.isNot(tok::annot_pragma_openmp_end))
3697 if (Tok.is(tok::comma)) {
3701 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3705 KLoc[Modifier2] = Tok.getLocation();
3706 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3707 Tok.isNot(tok::annot_pragma_openmp_end))
3711 if (Tok.is(tok::colon))
3714 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
3716 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3718 Arg[ScheduleKind] = KindModifier;
3719 KLoc[ScheduleKind] = Tok.getLocation();
3720 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3721 Tok.isNot(tok::annot_pragma_openmp_end))
3723 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3724 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3725 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3728 }
else if (Kind == OMPC_dist_schedule) {
3730 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3731 KLoc.push_back(Tok.getLocation());
3732 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3733 Tok.isNot(tok::annot_pragma_openmp_end))
3735 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3737 }
else if (Kind == OMPC_defaultmap) {
3740 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3746 Arg.push_back(Modifier);
3747 KLoc.push_back(Tok.getLocation());
3748 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3749 Tok.isNot(tok::annot_pragma_openmp_end))
3752 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
3753 if (Tok.is(tok::colon))
3756 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
3759 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3760 KLoc.push_back(Tok.getLocation());
3761 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3762 Tok.isNot(tok::annot_pragma_openmp_end))
3766 KLoc.push_back(SourceLocation());
3768 }
else if (Kind == OMPC_order) {
3769 enum { Modifier, OrderKind, NumberOfElements };
3770 Arg.resize(NumberOfElements);
3771 KLoc.resize(NumberOfElements);
3775 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3778 Arg[Modifier] = KindModifier;
3779 KLoc[Modifier] = Tok.getLocation();
3780 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3781 Tok.isNot(tok::annot_pragma_openmp_end))
3784 if (Tok.is(tok::colon))
3787 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
3789 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3791 Arg[OrderKind] = KindModifier;
3792 KLoc[OrderKind] = Tok.getLocation();
3793 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3794 Tok.isNot(tok::annot_pragma_openmp_end))
3796 }
else if (Kind == OMPC_device) {
3802 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3803 KLoc.push_back(Tok.getLocation());
3809 KLoc.emplace_back();
3811 }
else if (Kind == OMPC_grainsize) {
3815 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
3819 Arg.push_back(Modifier);
3820 KLoc.push_back(Tok.getLocation());
3826 if (Modifier == OMPC_GRAINSIZE_strict) {
3827 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
3832 KLoc.emplace_back();
3836 KLoc.emplace_back();
3838 }
else if (Kind == OMPC_num_tasks) {
3842 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
3846 Arg.push_back(Modifier);
3847 KLoc.push_back(Tok.getLocation());
3853 if (Modifier == OMPC_NUMTASKS_strict) {
3854 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
3859 KLoc.emplace_back();
3863 KLoc.emplace_back();
3865 }
else if (Kind == OMPC_num_threads) {
3869 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
3873 Arg.push_back(Modifier);
3874 KLoc.push_back(Tok.getLocation());
3880 if (Modifier == OMPC_NUMTHREADS_strict) {
3881 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
3886 KLoc.emplace_back();
3890 KLoc.emplace_back();
3893 assert(Kind == OMPC_if);
3894 KLoc.push_back(Tok.getLocation());
3895 TentativeParsingAction TPA(*
this);
3897 Arg.push_back(
static_cast<unsigned>(DK));
3898 if (DK != OMPD_unknown) {
3900 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
3905 Arg.back() = unsigned(OMPD_unknown);
3912 bool NeedAnExpression = (
Kind == OMPC_schedule && DelimLoc.
isValid()) ||
3913 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
3914 Kind == OMPC_if ||
Kind == OMPC_device ||
3915 Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
3916 Kind == OMPC_num_threads;
3917 if (NeedAnExpression) {
3918 SourceLocation ELoc = Tok.getLocation();
3924 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3928 SourceLocation RLoc = Tok.getLocation();
3929 if (!
T.consumeClose())
3930 RLoc =
T.getCloseLocation();
3932 if (NeedAnExpression && Val.
isInvalid())
3937 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
3938 Kind, Arg, Val.
get(), Loc,
T.getOpenLocation(), KLoc, DelimLoc, RLoc);
3943 if (ReductionIdScopeSpec.
isEmpty()) {
3981 ReductionIdScopeSpec,
nullptr,
3985 false,
nullptr, ReductionId);
3992 if (!
Tok.is(tok::identifier))
3999 return TypeModifier;
4005 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4006 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4012 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4016 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4017 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4018 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4022 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4024 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4027 return T.consumeClose();
4033 bool HasMapType =
false;
4035 StringRef PreMapName =
"";
4039 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4040 TypeModifier == OMPC_MAP_MODIFIER_close ||
4041 TypeModifier == OMPC_MAP_MODIFIER_present ||
4042 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4043 Data.MapTypeModifiers.push_back(TypeModifier);
4044 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4045 if (PP.LookAhead(0).isNot(tok::comma) &&
4046 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4047 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4048 <<
"map type modifier";
4050 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4051 Data.MapTypeModifiers.push_back(TypeModifier);
4052 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4056 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4058 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4059 <<
"map type modifier";
4064 Data.ExtraModifier = MapKind;
4066 PreMapLoc = Tok.getLocation();
4067 PreMapName = Tok.getIdentifierInfo()->getName();
4069 Diag(Tok, diag::err_omp_more_one_map_type);
4070 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4074 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4075 Data.MapTypeModifiers.push_back(TypeModifier);
4076 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4077 if (PP.LookAhead(0).isNot(tok::comma) &&
4078 PP.LookAhead(0).isNot(tok::colon))
4079 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4080 <<
"map type modifier";
4082 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4092 if (Tok.is(tok::comma)) {
4093 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4098 if (PP.LookAhead(0).is(tok::colon)) {
4106 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4117 if (!Tok.is(tok::colon)) {
4118 Diag(Tok, diag::err_omp_unknown_map_type);
4132 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4137 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4138 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4139 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4149 if (
Tok.is(tok::colon)) {
4150 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4155 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4159ExprResult Parser::ParseOpenMPIteratorsExpr() {
4160 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4161 "Expected 'iterator' token.");
4165 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4168 SourceLocation LLoc =
T.getOpenLocation();
4169 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4170 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4173 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4180 IteratorType = TR.
get();
4184 IdentifierInfo *II =
nullptr;
4185 SourceLocation IdLoc;
4186 if (Tok.is(tok::identifier)) {
4187 II = Tok.getIdentifierInfo();
4190 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4194 SourceLocation AssignLoc;
4195 if (Tok.is(tok::equal))
4198 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4203 SourceLocation Loc = Tok.getLocation();
4206 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4209 SourceLocation ColonLoc;
4210 if (Tok.is(tok::colon))
4214 Loc = Tok.getLocation();
4217 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4220 SourceLocation SecColonLoc;
4223 if (Tok.is(tok::colon)) {
4227 Loc = Tok.getLocation();
4230 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4235 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4236 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4237 if (Tok.is(tok::comma))
4240 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4243 D.
Type = IteratorType;
4253 SourceLocation RLoc = Tok.getLocation();
4254 if (!
T.consumeClose())
4255 RLoc =
T.getCloseLocation();
4257 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4266 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4269 if (Tok.is(tok::identifier) &&
4270 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4272 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4273 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4274 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4275 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4276 Data.ExtraModifier != OMPC_DEPEND_inout)
4277 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4279 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4280 ? OMPC_DEPEND_outallmemory
4281 : OMPC_DEPEND_inoutallmemory;
4297 Data.DepModOrTailExpr = Tail.
get();
4299 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4300 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4318 bool AllocatorSeen =
false;
4319 bool AlignSeen =
false;
4338 if (
Tok.is(tok::l_paren)) {
4339 switch (CurrentModifier) {
4340 case OMPC_ALLOCATE_allocator: {
4341 if (AllocatorSeen) {
4342 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4344 << getOpenMPClauseName(Kind);
4346 Data.AllocClauseModifiers.push_back(CurrentModifier);
4347 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4350 tok::annot_pragma_openmp_end);
4354 AllocatorSeen =
true;
4357 case OMPC_ALLOCATE_align: {
4359 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4361 << getOpenMPClauseName(Kind);
4363 Data.AllocClauseModifiers.push_back(CurrentModifier);
4364 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4368 Data.AllocateAlignment = Val.
get();
4373 llvm_unreachable(
"Unexpected allocate modifier");
4376 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4378 if (
Tok.isNot(tok::comma))
4381 CurrentModifierLoc =
Tok.getLocation();
4386 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4389 }
while (!AllocatorSeen || !AlignSeen);
4398 bool InvalidReductionId =
false;
4399 bool IsInvalidMapperModifier =
false;
4403 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4404 getOpenMPClauseName(Kind).data()))
4407 bool HasIterator =
false;
4408 bool InvalidIterator =
false;
4409 bool NeedRParenForLinear =
false;
4411 tok::annot_pragma_openmp_end);
4413 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4414 Kind == OMPC_in_reduction) {
4416 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4417 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4420 Data.ExtraModifier =
4422 Data.ExtraModifierLoc = Tok.getLocation();
4424 assert(Tok.is(tok::comma) &&
"Expected comma.");
4428 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4429 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4435 if (Tok.is(tok::kw_private)) {
4436 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4437 Data.OriginalSharingModifierLoc = Tok.getLocation();
4439 }
else if (Tok.is(tok::identifier) &&
4440 (PP.getSpelling(Tok) ==
"shared" ||
4441 PP.getSpelling(Tok) ==
"default")) {
4442 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4443 Data.OriginalSharingModifierLoc = Tok.getLocation();
4446 Diag(Tok.getLocation(), diag::err_expected)
4447 <<
"'private or shared or default'";
4452 if (!Tok.is(tok::comma)) {
4453 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4460 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4465 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4466 if (InvalidReductionId) {
4467 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4470 if (Tok.is(tok::colon))
4473 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4474 if (!InvalidReductionId)
4475 Data.ReductionOrMapperId =
4476 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4477 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4479 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4488 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4489 Data.DepModOrTailExpr = IteratorRes.
get();
4491 ExpectAndConsume(tok::comma);
4497 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4499 Data.ExtraModifierLoc = Tok.getLocation();
4501 (Kind == OMPC_doacross &&
4503 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4508 if (DKind == OMPD_ordered && Kind == OMPC_depend &&
4509 Data.ExtraModifier == OMPC_DEPEND_source) {
4515 if (Tok.is(tok::colon)) {
4517 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
4518 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4519 : diag::warn_pragma_expected_colon)
4520 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
4522 if (Kind == OMPC_doacross) {
4523 if (Tok.is(tok::identifier) &&
4524 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
4525 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
4526 ? OMPC_DOACROSS_source_omp_cur_iteration
4527 : OMPC_DOACROSS_sink_omp_cur_iteration;
4530 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
4531 if (Tok.isNot(tok::minus)) {
4532 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4533 << getOpenMPClauseName(Kind) << 0 << 0;
4540 if (Tok.isNot(tok::numeric_constant) ||
4541 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
4542 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
4543 << getOpenMPClauseName(Kind) << 0 << 0;
4549 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
4550 if (Tok.isNot(tok::r_paren)) {
4551 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4552 << getOpenMPClauseName(Kind) << 1 << 1;
4558 if (Kind == OMPC_doacross &&
4559 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
4560 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
4561 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
4567 }
else if (Kind == OMPC_linear) {
4569 Data.ExtraModifier = OMPC_LINEAR_val;
4570 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
4571 Data.ExtraModifier =
4575 NeedRParenForLinear =
true;
4577 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
4578 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
4579 <<
"linear(list: [linear-modifier,] step(step-size))";
4581 }
else if (Kind == OMPC_lastprivate) {
4588 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
4589 Data.ExtraModifier =
4591 Data.ExtraModifierLoc = Tok.getLocation();
4593 assert(Tok.is(tok::colon) &&
"Expected colon.");
4596 }
else if (Kind == OMPC_map) {
4598 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4601 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
4602 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4603 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4604 Data.IteratorExpr = IteratorRes.
get();
4606 ExpectAndConsume(tok::comma);
4608 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4611 InvalidIterator =
true;
4621 Data.ExtraModifierLoc = Tok.getLocation();
4624 TentativeParsingAction TPA(*
this);
4625 bool ColonPresent =
false;
4626 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4628 if (Tok.is(tok::colon))
4629 ColonPresent =
true;
4636 Diag(Tok, diag::err_omp_map_modifier_specification_list);
4638 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
4644 Data.ExtraModifier = OMPC_MAP_tofrom;
4646 if (DKind == OMPD_target_enter_data)
4647 Data.ExtraModifier = OMPC_MAP_to;
4648 else if (DKind == OMPD_target_exit_data)
4649 Data.ExtraModifier = OMPC_MAP_from;
4651 Data.IsMapTypeImplicit =
true;
4654 if (Tok.is(tok::colon))
4656 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
4657 while (Tok.is(tok::identifier)) {
4662 Data.MotionModifiers.push_back(Modifier);
4663 Data.MotionModifiersLoc.push_back(Tok.getLocation());
4665 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
4667 if (IsInvalidMapperModifier)
4675 if (Tok.is(tok::comma))
4678 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
4679 if (!IsInvalidMapperModifier) {
4681 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
4683 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
4685 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4693 }
else if (Kind == OMPC_allocate ||
4694 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
4695 PP.getSpelling(Tok) ==
"iterator")) {
4699 TentativeParsingAction TPA(*
this);
4704 if (Kind == OMPC_allocate) {
4709 Tail = ParseOpenMPIteratorsExpr();
4711 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
4714 if (Tok.is(tok::colon)) {
4721 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
4722 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
4724 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
4731 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4734 }
else if (Kind == OMPC_adjust_args) {
4738 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4740 Data.ExtraModifierLoc = Tok.getLocation();
4742 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
4747 if (Tok.is(tok::colon))
4748 Data.ColonLoc = Tok.getLocation();
4749 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
4755 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
4756 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
4757 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
4758 (Kind == OMPC_reduction && !InvalidReductionId) ||
4762 (Kind == OMPC_adjust_args &&
4764 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
4765 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
4766 Tok.isNot(tok::annot_pragma_openmp_end))) {
4773 Vars.push_back(VarExpr.
get());
4775 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4780 IsComma = Tok.is(tok::comma);
4783 else if (Tok.isNot(tok::r_paren) &&
4784 Tok.isNot(tok::annot_pragma_openmp_end) &&
4785 (!MayHaveTail || Tok.isNot(tok::colon))) {
4786 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
4787 Diag(Tok, diag::err_omp_expected_punc)
4788 << ((Kind == OMPC_flush)
4789 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
4790 : getOpenMPClauseName(Kind))
4791 << (Kind == OMPC_flush);
4796 if (NeedRParenForLinear)
4800 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
4801 bool StepFound =
false;
4802 bool ModifierFound =
false;
4804 Data.ColonLoc = Tok.getLocation();
4807 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
4808 bool Malformed =
false;
4809 while (Tok.isNot(tok::r_paren)) {
4810 if (Tok.is(tok::identifier)) {
4815 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4818 if (LinKind == OMPC_LINEAR_step) {
4820 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
4823 tok::annot_pragma_openmp_end);
4827 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
4832 Data.StepModifierLoc = StepModifierLoc;
4836 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
4838 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
4840 Data.ExtraModifier = LinKind;
4842 ModifierFound =
true;
4847 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4856 if (Tok.is(tok::comma))
4858 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
4861 if (!Malformed && !StepFound && !ModifierFound)
4862 Diag(ELoc, diag::err_expected_expression);
4866 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
4869 Data.DepModOrTailExpr = Tail.
get();
4871 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4877 Data.RLoc = Tok.getLocation();
4878 if (!
T.consumeClose())
4879 Data.RLoc =
T.getCloseLocation();
4883 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
4885 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
4886 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
4913 "Expected parsing to start at clause name");
4918 if (
T.consumeOpen()) {
4919 Diag(
Tok, diag::err_expected) << tok::l_paren;
4932 Exprs.push_back(Val.
get());
4935 bool Result =
T.consumeClose();
4936 OpenLoc =
T.getOpenLocation();
4937 CloseLoc =
T.getCloseLocation();
Defines the clang::ASTContext interface.
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
static OpenMPDirectiveKind checkOpenMPDirectiveName(Parser &P, SourceLocation Loc, OpenMPDirectiveKind Kind, StringRef Name)
static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P)
static OpenMPMapModifierKind isMapModifier(Parser &P)
Checks if the token is a valid map-type-modifier.
static std::optional< SimpleClauseData > parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind)
static bool checkExtensionProperty(Parser &P, SourceLocation Loc, OMPTraitProperty &TIProperty, OMPTraitSelector &TISelector, llvm::StringMap< SourceLocation > &Seen)
static ExprResult parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data)
Parse 'allocate' clause modifiers.
static DeclarationName parseOpenMPReductionId(Parser &P)
static ExprResult parseContextScore(Parser &P)
Parse optional 'score' '(' <expr> ')' ':'.
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, UnqualifiedId &ReductionId)
static bool parseStepSize(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data, OpenMPClauseKind CKind, SourceLocation ELoc)
Parse step size expression.
static void parseMapType(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data)
Parse map-type in map clause.
static bool parseDeclareSimdClauses(Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen, SmallVectorImpl< Expr * > &Uniforms, SmallVectorImpl< Expr * > &Aligneds, SmallVectorImpl< Expr * > &Alignments, SmallVectorImpl< Expr * > &Linears, SmallVectorImpl< unsigned > &LinModifiers, SmallVectorImpl< Expr * > &Steps)
Parses clauses for 'declare simd' directive.
static OpenMPMapClauseKind isMapType(Parser &P)
Checks if the token is a valid map-type.
This file declares semantic analysis functions specific to AMDGPU.
This file declares facilities that support code completion.
This file declares semantic analysis for OpenMP constructs and clauses.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
DeclarationNameTable DeclarationNames
OMPTraitInfo & getNewOMPTraitInfo()
Return a new OMPTraitInfo object owned by this context.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
Represents a C++ nested-name-specifier or a global scope specifier.
bool isEmpty() const
No scope specifier.
static const TST TST_unspecified
Decl - This represents one declaration (or definition), e.g.
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
SourceLocation getLocation() const
DeclContext * getDeclContext()
The name of a declaration.
bool isEmpty() const
Evaluates true when this declaration name is empty.
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
This represents a decl that may have a name.
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
This is a basic class for representing single OpenMP clause.
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.
static const ParsedAttributesView & none()
ParsedAttributes - A collection of parsed attributes.
Introduces zero or more scopes for parsing.
void Enter(unsigned ScopeFlags)
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, SmallVectorImpl< Expr * > &Vars, SemaOpenMP::OpenMPVarListDataTy &Data)
Parses clauses with list.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Preprocessor & getPreprocessor() const
bool parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data)
Parse map-type-modifiers in map clause.
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
ParseStringLiteralExpression - This handles the various token types that form string literals,...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
bool parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data)
Parses the mapper modifier in map, to, and from clauses.
friend class ParsingOpenMPDirectiveRAII
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
friend class ColonProtectionRAIIObject
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
const Token & getCurToken() const
void ExitScope()
ExitScope - Pop a scope off the scope stack.
ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc, bool IsAddressOfOperand=false)
Parses simple expression in parens for single-expression clauses of OpenMP constructs.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data, const LangOptions &LangOpts)
Parses a reserved locator like 'omp_all_memory'.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D)
Re-enter a possible template scope, creating as many template parameter scopes as necessary.
bool ParseOpenMPDeclareBeginVariantDirective(SourceLocation Loc)
Parses 'omp begin declare variant' directive.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
The collection of all-type qualifiers we support.
Represents a struct/union/class.
@ OpenMPDirectiveScope
This is the scope of OpenMP executable directive.
@ CompoundStmtScope
This is a compound statement scope.
@ OpenMPSimdDirectiveScope
This is the scope of some OpenMP simd directive.
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ OpenMPLoopDirectiveScope
This is the scope of some OpenMP loop directive.
@ DeclScope
This is a scope that can contain a declaration.
Smart pointer class that efficiently represents Objective-C method names.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
void ActOnExitFunctionContext()
void ActOnReenterFunctionContext(Scope *S, Decl *D)
Push the parameters of D, which must be a function, into scope.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
Token - This structure provides full information about a lexed token.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isNot(tok::TokenKind K) const
Base wrapper for a particular "section" of type source info.
The base class of the type hierarchy.
QualType getCanonicalTypeInternal() const
Represents a C++ unqualified-id that has been parsed.
void setOperatorFunctionId(SourceLocation OperatorLoc, OverloadedOperatorKind Op, SourceLocation SymbolLocations[3])
Specify that this unqualified-id was parsed as an operator-function-id.
Represents a variable declaration or definition.
Defines the clang::TargetInfo interface.
bool Ret(InterpState &S, CodePtr &PC)
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ OMPC_DEFAULTMAP_MODIFIER_unknown
@ OMPC_ORDER_MODIFIER_unknown
@ OMPC_ADJUST_ARGS_unknown
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
OpenMPDeviceType
OpenMP device type for 'device_type' clause.
@ OMPC_DEVICE_TYPE_unknown
@ OMPC_SCHEDULE_MODIFIER_unknown
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
@ Property
The type of a property.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ OMPC_LASTPRIVATE_unknown
OpenMPGrainsizeClauseModifier
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str, const LangOptions &LangOpts)
OpenMPNumTasksClauseModifier
@ Type
The name was classified as a type.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OpenMPMotionModifierKind
OpenMP modifier kind for 'to' or 'from' clause.
@ OMPC_MOTION_MODIFIER_unknown
@ OMPC_DEFAULTMAP_unknown
OpenMPAllocateClauseModifier
OpenMP modifiers for 'allocate' clause.
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "executable".
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
bool isOpenMPInformationalDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "informational".
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
OpenMPNumThreadsClauseModifier
@ OMPC_NUMTHREADS_unknown
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
@ OMPC_MAP_MODIFIER_unknown
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
ActionResult< Expr * > ExprResult
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
ActionResult< Stmt * > StmtResult
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
int const char * function
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
llvm::SmallVector< Expr *, 4 > PreferTypes
llvm::omp::TraitProperty Kind
StringRef RawString
The raw string as we parsed it.
llvm::omp::TraitSelector Kind
SmallVector< OMPTraitProperty, 1 > Properties
SmallVector< OMPTraitSelector, 2 > Selectors
This structure contains most locations needed for by an OMPVarListClause.
std::optional< Expr * > Indirect
The directive with indirect clause.
OpenMPDirectiveKind Kind
The directive kind, begin declare target or declare target.
OMPDeclareTargetDeclAttr::DevTypeTy DT
The 'device_type' as parsed from the clause.
SourceLocation Loc
The directive location.
llvm::DenseMap< NamedDecl *, MapInfo > ExplicitlyMapped
Explicitly listed variables and functions in a 'to' or 'link' clause.
SourceLocation DeclIdentLoc
SourceLocation SecColonLoc
IdentifierInfo * DeclIdent
OMPIteratorExpr::IteratorRange Range
Data used for processing a list of variables in OpenMP clauses.
Clang specific specialization of the OMPContext to lookup target features.