26#include "llvm/ADT/SmallBitVector.h"
27#include "llvm/ADT/StringSwitch.h"
28#include "llvm/Frontend/OpenMP/DirectiveNameParser.h"
29#include "llvm/Frontend/OpenMP/OMPAssume.h"
30#include "llvm/Frontend/OpenMP/OMPContext.h"
35using namespace llvm::omp;
42class DeclDirectiveListParserHelper final {
43 SmallVector<Expr *, 4> Identifiers;
50 void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
51 ExprResult Res = P->getActions().OpenMP().ActOnOpenMPIdExpression(
52 P->getCurScope(), SS, NameInfo, Kind);
54 Identifiers.push_back(Res.
get());
56 llvm::ArrayRef<Expr *> getIdentifiers()
const {
return Identifiers; }
65 auto [D, VR] = getOpenMPDirectiveKindAndVersions(Name);
67 if (D == Directive::OMPD_ordered_blockassoc)
68 D = Directive::OMPD_ordered_standalone;
69 assert(D == Kind &&
"Directive kind mismatch");
73 P.
Diag(Loc, diag::warn_omp_future_directive_spelling) << Name;
79 static const DirectiveNameParser DirParser;
81 const DirectiveNameParser::State *S = DirParser.initial();
84 if (
Tok.isAnnotation())
90 S = DirParser.consume(S, Concat);
94 while (!
Tok.isAnnotation()) {
97 if (!
Tok.isAnnotation()) {
99 S = DirParser.consume(S, TS);
107 assert(S &&
"Should have exited early");
116 bool WithOperator =
false;
117 if (
Tok.is(tok::kw_operator)) {
122 switch (
Tok.getKind()) {
147 case tok::identifier:
152 P.
Diag(
Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
153 P.
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
159 return OOK ==
OO_None ? DeclNames.getIdentifier(
Tok.getIdentifierInfo())
160 : DeclNames.getCXXOperatorName(OOK);
165 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
168 if (
T.expectAndConsume(
169 diag::err_expected_lparen_after,
170 getOpenMPDirectiveName(OMPD_declare_reduction, OMPVersion).data())) {
176 if (Name.
isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
180 bool IsCorrect = !ExpectAndConsume(tok::colon);
182 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
185 IsCorrect = IsCorrect && !Name.
isEmpty();
187 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
188 Diag(Tok.getLocation(), diag::err_expected_type);
192 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
195 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
202 QualType ReductionType = Actions.OpenMP().ActOnOpenMPDeclareReductionType(
203 Range.getBegin(), TR);
204 if (!ReductionType.
isNull()) {
205 ReductionTypes.push_back(
206 std::make_pair(ReductionType,
Range.getBegin()));
209 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
213 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
217 if (ExpectAndConsume(tok::comma)) {
219 if (Tok.is(tok::annot_pragma_openmp_end)) {
220 Diag(Tok.getLocation(), diag::err_expected_type);
224 }
while (Tok.isNot(tok::annot_pragma_openmp_end));
226 if (ReductionTypes.empty()) {
231 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
235 if (ExpectAndConsume(tok::colon))
238 if (Tok.is(tok::annot_pragma_openmp_end)) {
239 Diag(Tok.getLocation(), diag::err_expected_expression);
244 Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveStart(
245 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes,
250 unsigned I = 0, E = ReductionTypes.size();
251 for (Decl *D : DRD.get()) {
252 TentativeParsingAction TPA(*
this);
257 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerStart(
getCurScope(), D);
258 ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
260 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerEnd(
261 D, CombinerResult.
get());
263 if (CombinerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
264 Tok.isNot(tok::annot_pragma_openmp_end)) {
269 IsCorrect = !
T.consumeClose() && IsCorrect && CombinerResult.
isUsable();
271 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
273 if (Tok.is(tok::identifier) &&
274 Tok.getIdentifierInfo()->isStr(
"initializer")) {
277 Diag(Tok.getLocation(), diag::err_expected) <<
"'initializer'";
284 tok::annot_pragma_openmp_end);
286 !
T.expectAndConsume(diag::err_expected_lparen_after,
"initializer") &&
288 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
293 VarDecl *OmpPrivParm =
294 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerStart(
297 if (Tok.is(tok::identifier) &&
298 Tok.getIdentifierInfo()->isStr(
"omp_priv")) {
300 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
302 InitializerResult = Actions.ActOnFinishFullExpr(
306 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerEnd(
307 D, InitializerResult.
get(), OmpPrivParm);
308 if (InitializerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
309 Tok.isNot(tok::annot_pragma_openmp_end)) {
315 !
T.consumeClose() && IsCorrect && !InitializerResult.
isInvalid();
327 return Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveEnd(
331void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
334 if (isTokenEqualOrEqualTypo()) {
337 if (Tok.is(tok::code_completion)) {
339 Actions.CodeCompletion().CodeCompleteInitializer(
getCurScope(),
341 Actions.FinalizeDeclaration(OmpPrivParm);
345 PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
348 if (
Init.isInvalid()) {
350 Actions.ActOnInitializerError(OmpPrivParm);
352 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
355 }
else if (Tok.is(tok::l_paren)) {
362 SourceLocation LParLoc =
T.getOpenLocation();
363 auto RunSignatureHelp = [
this, OmpPrivParm, LParLoc, &Exprs]() {
364 QualType PreferredType =
365 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
367 OmpPrivParm->
getLocation(), Exprs, LParLoc,
false);
368 CalledSignatureHelp =
true;
369 return PreferredType;
371 if (ParseExpressionList(Exprs, [&] {
372 PreferredType.enterFunctionArgument(Tok.getLocation(),
375 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
377 Actions.ActOnInitializerError(OmpPrivParm);
381 SourceLocation RLoc = Tok.getLocation();
382 if (!
T.consumeClose())
383 RLoc =
T.getCloseLocation();
386 Actions.ActOnParenListExpr(
T.getOpenLocation(), RLoc, Exprs);
387 Actions.AddInitializerToDecl(OmpPrivParm,
Initializer.get(),
392 Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
396 if (
Init.isInvalid()) {
397 Actions.ActOnInitializerError(OmpPrivParm);
399 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
403 Actions.ActOnUninitializedDecl(OmpPrivParm);
409 bool IsCorrect =
true;
410 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
413 if (
T.expectAndConsume(
414 diag::err_expected_lparen_after,
415 getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion).data())) {
421 auto &DeclNames = Actions.getASTContext().DeclarationNames;
422 DeclarationName MapperId;
423 if (PP.LookAhead(0).is(tok::colon)) {
424 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
425 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
428 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
432 ExpectAndConsume(tok::colon);
436 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get(
"default"));
439 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
443 DeclarationName VName;
448 MapperType = Actions.OpenMP().ActOnOpenMPDeclareMapperType(
Range.getBegin(),
458 IsCorrect &= !
T.consumeClose();
466 DeclarationNameInfo DirName;
467 SourceLocation Loc = Tok.getLocation();
470 ParseScope OMPDirectiveScope(
this, ScopeFlags);
471 Actions.OpenMP().StartOpenMPDSABlock(OMPD_declare_mapper, DirName,
476 Actions.OpenMP().ActOnOpenMPDeclareMapperDirectiveVarDecl(
480 SmallVector<OMPClause *, 6> Clauses;
481 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
484 : getOpenMPClauseKind(PP.getSpelling(Tok));
485 Actions.OpenMP().StartOpenMPClause(CKind);
487 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
489 Clauses.push_back(Clause);
493 if (Tok.is(tok::comma))
495 Actions.OpenMP().EndOpenMPClause();
497 if (Clauses.empty()) {
498 Diag(Tok, diag::err_omp_expected_clause)
499 << getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion);
508 DeclGroupPtrTy DG = Actions.OpenMP().ActOnOpenMPDeclareMapperDirective(
509 OuterScope, Actions.getCurLexicalContext(), MapperId, MapperType,
510 Range.getBegin(), VName, AS, MapperVarRef.
get(), Clauses);
512 Actions.OpenMP().EndOpenMPDSABlock(
nullptr);
513 OMPDirectiveScope.Exit();
524 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
525 DeclSpec DS(AttrFactory);
526 ParseSpecifierQualifierList(DS, AS, DSC);
531 ParseDeclarator(DeclaratorInfo);
532 Range = DeclaratorInfo.getSourceRange();
533 if (DeclaratorInfo.getIdentifier() ==
nullptr) {
534 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
537 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
539 return Actions.OpenMP().ActOnOpenMPDeclareMapperVarDecl(
getCurScope(),
551 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
554 if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
558 (void)ConsumeAnnotationToken();
563 skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
567 VariantMatchInfo VMI;
571 Loc](StringRef ISATrait) {
574 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
577 ASTCtx, std::move(DiagUnknownTrait),
580 Actions.OpenMP().getOpenMPDeviceNum());
582 if (isVariantApplicableInContext(VMI, OMPCtx,
584 Actions.OpenMP().ActOnOpenMPBeginDeclareVariant(Loc, TI);
589 unsigned Nesting = 1;
593 DKLoc = Tok.getLocation();
595 if (DK == OMPD_end_declare_variant)
597 else if (DK == OMPD_begin_declare_variant)
599 if (!Nesting || isEofOrEom())
604 parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant, DK,
615class FNContextRAII final {
619 bool HasFunScope =
false;
620 FNContextRAII() =
delete;
621 FNContextRAII(
const FNContextRAII &) =
delete;
622 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
626 Decl *D = *Ptr.get().begin();
669 bool IsError =
false;
670 while (
Tok.isNot(tok::annot_pragma_openmp_end)) {
671 if (
Tok.isNot(tok::identifier))
673 OMPDeclareSimdDeclAttr::BranchStateTy Out;
675 StringRef ClauseName = II->
getName();
677 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
678 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
679 P.
Diag(
Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
681 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
687 }
else if (ClauseName ==
"simdlen") {
689 llvm::omp::Version OMPVersion =
691 P.
Diag(
Tok, diag::err_omp_more_one_clause)
692 << getOpenMPDirectiveName(OMPD_declare_simd, OMPVersion)
703 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
704 CKind == OMPC_linear) {
707 if (CKind == OMPC_aligned) {
709 }
else if (CKind == OMPC_linear) {
710 Data.ExtraModifier = OMPC_LINEAR_val;
717 getOpenMPClauseKind(ClauseName), *Vars,
Data,
720 if (CKind == OMPC_aligned) {
721 Alignments.append(Aligneds.size() - Alignments.size(),
722 Data.DepModOrTailExpr);
723 }
else if (CKind == OMPC_linear) {
724 assert(0 <=
Data.ExtraModifier &&
726 "Unexpected linear modifier.");
729 Data.ExtraModifierLoc))
730 Data.ExtraModifier = OMPC_LINEAR_val;
731 LinModifiers.append(Linears.size() - LinModifiers.size(),
733 Steps.append(Linears.size() - Steps.size(),
Data.DepModOrTailExpr);
740 if (
Tok.is(tok::comma))
749 PP.EnterToken(Tok,
true);
750 PP.EnterTokenStream(Toks,
true,
756 FNContextRAII FnContext(*
this, Ptr);
757 OMPDeclareSimdDeclAttr::BranchStateTy BS =
758 OMPDeclareSimdDeclAttr::BS_Undefined;
760 SmallVector<Expr *, 4> Uniforms;
761 SmallVector<Expr *, 4> Aligneds;
762 SmallVector<Expr *, 4> Alignments;
763 SmallVector<Expr *, 4> Linears;
764 SmallVector<unsigned, 4> LinModifiers;
765 SmallVector<Expr *, 4> Steps;
768 Alignments, Linears, LinModifiers, Steps);
769 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
771 SourceLocation EndLoc = ConsumeAnnotationToken();
774 return Actions.OpenMP().ActOnOpenMPDeclareSimdDirective(
775 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
776 LinModifiers, Steps, SourceRange(Loc, EndLoc));
783 CONTEXT_SELECTOR_SET_LVL = 0,
784 CONTEXT_SELECTOR_LVL = 1,
785 CONTEXT_TRAIT_LVL = 2,
788static StringRef stringLiteralParser(
Parser &P) {
795 if (
Tok.
is(tok::identifier) ||
Tok.
is(tok::kw_for)) {
803 return stringLiteralParser(P);
806 diag::warn_omp_declare_variant_string_literal_or_identifier)
811static bool checkForDuplicates(
Parser &P, StringRef Name,
813 llvm::StringMap<SourceLocation> &Seen,
815 auto Res = Seen.try_emplace(Name, NameLoc);
821 P.
Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
823 P.
Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
829void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
830 llvm::omp::TraitSet
Set,
832 llvm::StringMap<SourceLocation> &Seen) {
833 TIProperty.
Kind = TraitProperty::invalid;
835 SourceLocation NameLoc = Tok.getLocation();
837 if (Selector == llvm::omp::TraitSelector::target_device_device_num) {
839 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
841 if (DeviceNumExprResult.
isUsable()) {
842 Expr *DeviceNumExpr = DeviceNumExprResult.
get();
843 Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr);
847 Name = getNameFromIdOrString(*
this, Tok, CONTEXT_TRAIT_LVL);
849 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
850 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
855 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
856 if (TIProperty.
Kind != TraitProperty::invalid) {
857 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
858 TIProperty.
Kind = TraitProperty::invalid;
864 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
865 << Name << getOpenMPContextTraitSelectorName(Selector)
866 << getOpenMPContextTraitSetName(
Set);
868 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
869 if (SetForName != TraitSet::invalid) {
870 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
871 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
872 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
873 << Name <<
"<selector-name>"
874 <<
"(<property-name>)";
877 TraitSelector SelectorForName =
878 getOpenMPContextTraitSelectorKind(Name, SetForName);
879 if (SelectorForName != TraitSelector::invalid) {
880 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
881 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
882 bool AllowsTraitScore =
false;
883 bool RequiresProperty =
false;
884 isValidTraitSelectorForTraitSet(
885 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
886 AllowsTraitScore, RequiresProperty);
887 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
888 << getOpenMPContextTraitSetName(
889 getOpenMPContextTraitSetForSelector(SelectorForName))
890 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
893 for (
const auto &PotentialSet :
894 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
895 TraitSet::device, TraitSet::target_device}) {
896 TraitProperty PropertyForName =
897 getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
898 if (PropertyForName == TraitProperty::invalid)
900 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
901 << getOpenMPContextTraitSetName(
902 getOpenMPContextTraitSetForProperty(PropertyForName))
903 << getOpenMPContextTraitSelectorName(
904 getOpenMPContextTraitSelectorForProperty(PropertyForName))
905 << (
"(" + Name +
")").str();
908 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
909 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
915 llvm::StringMap<SourceLocation> &Seen) {
916 assert(TISelector.
Kind ==
917 llvm::omp::TraitSelector::implementation_extension &&
918 "Only for extension properties, e.g., "
919 "`implementation={extension(PROPERTY)}`");
920 if (TIProperty.
Kind == TraitProperty::invalid)
923 if (TIProperty.
Kind ==
924 TraitProperty::implementation_extension_disable_implicit_base)
927 if (TIProperty.
Kind ==
928 TraitProperty::implementation_extension_allow_templates)
931 if (TIProperty.
Kind ==
932 TraitProperty::implementation_extension_bind_to_declaration)
937 llvm::omp::TraitProperty::implementation_extension_match_all ||
939 llvm::omp::TraitProperty::implementation_extension_match_any ||
941 llvm::omp::TraitProperty::implementation_extension_match_none);
944 if (IsMatchExtension(TIProperty)) {
946 if (IsMatchExtension(SeenProp)) {
947 P.
Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
948 StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
951 P.
Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
952 << CONTEXT_TRAIT_LVL << SeenName;
958 llvm_unreachable(
"Unknown extension property!");
961void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
962 llvm::omp::TraitSet
Set,
963 llvm::StringMap<SourceLocation> &Seen) {
964 assert(TISelector.
Kind != TraitSelector::user_condition &&
965 "User conditions are special properties not handled here!");
967 SourceLocation PropertyLoc = Tok.getLocation();
968 OMPTraitProperty TIProperty;
969 parseOMPTraitPropertyKind(TIProperty,
Set, TISelector.
Kind, Seen);
971 if (TISelector.
Kind == llvm::omp::TraitSelector::implementation_extension)
974 TIProperty.
Kind = TraitProperty::invalid;
977 if (TIProperty.
Kind == TraitProperty::invalid) {
978 if (PropertyLoc != Tok.getLocation())
979 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
980 << CONTEXT_TRAIT_LVL;
984 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.
Kind,
993 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
994 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
996 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
997 << getOpenMPContextTraitSetName(
Set);
998 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
999 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
1001 << getOpenMPContextTraitSelectorName(
1002 getOpenMPContextTraitSelectorForProperty(TIProperty.
Kind))
1003 << getOpenMPContextTraitSetName(
1004 getOpenMPContextTraitSetForProperty(TIProperty.
Kind));
1005 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1006 << CONTEXT_TRAIT_LVL;
1009void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
1010 llvm::omp::TraitSet
Set,
1011 llvm::StringMap<SourceLocation> &Seen) {
1012 TISelector.
Kind = TraitSelector::invalid;
1014 SourceLocation NameLoc = Tok.getLocation();
1015 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_LVL);
1017 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1018 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1022 TISelector.
Kind = getOpenMPContextTraitSelectorKind(Name,
Set);
1023 if (TISelector.
Kind != TraitSelector::invalid) {
1024 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1025 TISelector.
Kind = TraitSelector::invalid;
1030 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1031 << Name << getOpenMPContextTraitSetName(
Set);
1033 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1034 if (SetForName != TraitSet::invalid) {
1035 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1036 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1037 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1038 << Name <<
"<selector-name>"
1039 <<
"<property-name>";
1042 for (
const auto &PotentialSet :
1043 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1044 TraitSet::device, TraitSet::target_device}) {
1045 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1046 PotentialSet, TraitSelector::invalid, Name);
1047 if (PropertyForName == TraitProperty::invalid)
1049 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1050 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1051 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1052 << getOpenMPContextTraitSetName(
1053 getOpenMPContextTraitSetForProperty(PropertyForName))
1054 << getOpenMPContextTraitSelectorName(
1055 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1056 << (
"(" + Name +
")").str();
1059 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1060 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1067 StringRef SelectorName =
1069 if (SelectorName !=
"score")
1080 <<
"score expression";
1084void Parser::parseOMPContextSelector(
1085 OMPTraitSelector &TISelector, llvm::omp::TraitSet
Set,
1086 llvm::StringMap<SourceLocation> &SeenSelectors) {
1087 unsigned short OuterPC = ParenCount;
1092 auto FinishSelector = [OuterPC,
this]() ->
void {
1095 while (!
SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1096 tok::annot_pragma_openmp_end},
1099 if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1100 (void)ConsumeParen();
1101 if (OuterPC <= ParenCount) {
1105 if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1111 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1112 << CONTEXT_SELECTOR_LVL;
1115 SourceLocation SelectorLoc = Tok.getLocation();
1116 parseOMPTraitSelectorKind(TISelector,
Set, SeenSelectors);
1117 if (TISelector.
Kind == TraitSelector::invalid)
1118 return FinishSelector();
1120 bool AllowsTraitScore =
false;
1121 bool RequiresProperty =
false;
1122 if (!isValidTraitSelectorForTraitSet(TISelector.
Kind,
Set, AllowsTraitScore,
1123 RequiresProperty)) {
1124 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1125 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1126 << getOpenMPContextTraitSetName(
Set);
1127 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1128 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1129 << getOpenMPContextTraitSetName(
1130 getOpenMPContextTraitSetForSelector(TISelector.
Kind))
1131 << RequiresProperty;
1132 return FinishSelector();
1135 if (!RequiresProperty) {
1137 {getOpenMPContextTraitPropertyForSelector(TISelector.
Kind),
1138 getOpenMPContextTraitSelectorName(TISelector.
Kind)});
1142 if (!Tok.is(tok::l_paren)) {
1143 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1144 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1145 << getOpenMPContextTraitSetName(
Set);
1146 return FinishSelector();
1149 if (TISelector.
Kind == TraitSelector::user_condition) {
1150 SourceLocation RLoc;
1153 return FinishSelector();
1156 {TraitProperty::user_condition_unknown,
"<condition>"});
1161 tok::annot_pragma_openmp_end);
1163 (void)BDT.consumeOpen();
1165 SourceLocation ScoreLoc = Tok.getLocation();
1168 if (!AllowsTraitScore && !Score.
isUnset()) {
1170 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1171 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1172 << getOpenMPContextTraitSetName(
Set) << Score.
get();
1174 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1175 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1176 << getOpenMPContextTraitSetName(
Set) <<
"<invalid>";
1184 llvm::StringMap<SourceLocation> SeenProperties;
1186 parseOMPContextProperty(TISelector,
Set, SeenProperties);
1193void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1194 llvm::StringMap<SourceLocation> &Seen) {
1195 TISet.
Kind = TraitSet::invalid;
1197 SourceLocation NameLoc = Tok.getLocation();
1198 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_SET_LVL);
1200 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1201 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1205 TISet.
Kind = getOpenMPContextTraitSetKind(Name);
1206 if (TISet.
Kind != TraitSet::invalid) {
1207 if (checkForDuplicates(*
this, Name, NameLoc, Seen,
1208 CONTEXT_SELECTOR_SET_LVL))
1209 TISet.
Kind = TraitSet::invalid;
1214 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1216 TraitSelector SelectorForName =
1217 getOpenMPContextTraitSelectorKind(Name, TISet.
Kind);
1218 if (SelectorForName != TraitSelector::invalid) {
1219 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1220 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1221 bool AllowsTraitScore =
false;
1222 bool RequiresProperty =
false;
1223 isValidTraitSelectorForTraitSet(
1224 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1225 AllowsTraitScore, RequiresProperty);
1226 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1227 << getOpenMPContextTraitSetName(
1228 getOpenMPContextTraitSetForSelector(SelectorForName))
1229 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
1232 for (
const auto &PotentialSet :
1233 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1234 TraitSet::device, TraitSet::target_device}) {
1235 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1236 PotentialSet, TraitSelector::invalid, Name);
1237 if (PropertyForName == TraitProperty::invalid)
1239 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1240 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1241 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1242 << getOpenMPContextTraitSetName(
1243 getOpenMPContextTraitSetForProperty(PropertyForName))
1244 << getOpenMPContextTraitSelectorName(
1245 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1246 << (
"(" + Name +
")").str();
1249 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1250 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1253void Parser::parseOMPContextSelectorSet(
1254 OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1255 auto OuterBC = BraceCount;
1260 auto FinishSelectorSet = [
this, OuterBC]() ->
void {
1263 while (!
SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1264 tok::annot_pragma_openmp_end},
1267 if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1268 (void)ConsumeBrace();
1269 if (OuterBC <= BraceCount) {
1273 if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1279 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1280 << CONTEXT_SELECTOR_SET_LVL;
1283 parseOMPTraitSetKind(TISet, SeenSets);
1284 if (TISet.
Kind == TraitSet::invalid)
1285 return FinishSelectorSet();
1289 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1291 << (
"context set name \"" + getOpenMPContextTraitSetName(TISet.
Kind) +
1295 if (Tok.is(tok::l_brace)) {
1296 (void)ConsumeBrace();
1298 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1300 << (
"'=' that follows the context set name \"" +
1301 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1305 llvm::StringMap<SourceLocation> SeenSelectors;
1307 OMPTraitSelector TISelector;
1308 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1309 if (TISelector.
Kind != TraitSelector::invalid &&
1315 if (Tok.is(tok::r_brace)) {
1316 (void)ConsumeBrace();
1318 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1320 << (
"context selectors for the context set \"" +
1321 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1326bool Parser::parseOMPContextSelectors(
SourceLocation Loc, OMPTraitInfo &TI) {
1327 llvm::StringMap<SourceLocation> SeenSets;
1330 parseOMPContextSelectorSet(TISet, SeenSets);
1331 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1332 TI.
Sets.push_back(TISet);
1341 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
1342 PP.EnterToken(Tok,
true);
1343 PP.EnterTokenStream(Toks,
true,
1349 FNContextRAII FnContext(*
this, Ptr);
1351 SourceLocation RLoc;
1361 getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion), RLoc,
1364 if (!AssociatedFunction.
isUsable()) {
1365 if (!Tok.is(tok::annot_pragma_openmp_end))
1369 (void)ConsumeAnnotationToken();
1373 OMPTraitInfo *ParentTI =
1374 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
1375 ASTContext &ASTCtx = Actions.getASTContext();
1377 SmallVector<OMPAdjustArgsDescriptor *, 3> AdjustArgs;
1378 SmallVector<OMPInteropInfo, 3> AppendArgs;
1379 SourceLocation AdjustArgsLoc, AppendArgsLoc;
1382 if (Tok.is(tok::annot_pragma_openmp_end)) {
1383 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1387 bool IsError =
false;
1388 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1391 : getOpenMPClauseKind(PP.getSpelling(Tok));
1392 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind, OMPVersion)) {
1393 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1394 << (OMPVersion < 51 ? 0 : 1);
1400 IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1402 case OMPC_adjust_args: {
1403 AdjustArgsLoc = Tok.getLocation();
1405 SemaOpenMP::OpenMPVarListDataTy
Data;
1406 SmallVector<Expr *> Vars;
1407 SmallVector<OMPAdjustArgsItem, 4> Items;
1411 for (Expr *E : Vars) {
1412 OMPAdjustArgsItem Item;
1414 Items.push_back(Item);
1420 if (
Data.NeedDevicePtrModifierLoc.isValid())
1422 Data.NeedDevicePtrModifier);
1423 OMPAdjustArgsDescriptor *Desc =
1424 Actions.OpenMP().ActOnOpenMPAdjustArgsClause(
1425 AdjustOp, NeedDevicePtrModifier, Items, AdjustArgsLoc);
1427 AdjustArgs.push_back(Desc);
1433 case OMPC_append_args:
1434 if (!AppendArgs.empty()) {
1435 Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1436 << getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion)
1437 << getOpenMPClauseName(CKind) << 0;
1441 AppendArgsLoc = Tok.getLocation();
1443 IsError = parseOpenMPAppendArgs(AppendArgs);
1447 llvm_unreachable(
"Unexpected clause for declare variant.");
1454 (void)ConsumeAnnotationToken();
1458 if (Tok.is(tok::comma))
1462 std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1463 Actions.OpenMP().checkOpenMPDeclareVariantFunction(
1464 Ptr, AssociatedFunction.
get(), TI, AppendArgs.size(),
1465 SourceRange(Loc, Tok.getLocation()));
1467 if (DeclVarData && !TI.
Sets.empty())
1468 Actions.OpenMP().ActOnOpenMPDeclareVariantDirective(
1469 DeclVarData->first, DeclVarData->second, TI, AdjustArgs, AppendArgs,
1470 AdjustArgsLoc, AppendArgsLoc, SourceRange(Loc, Tok.getLocation()));
1473 (void)ConsumeAnnotationToken();
1476bool Parser::parseOpenMPAppendArgs(
1478 bool HasError =
false;
1481 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1482 getOpenMPClauseName(OMPC_append_args).data()))
1487 while (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"interop")) {
1490 tok::annot_pragma_openmp_end);
1491 if (IT.expectAndConsume(diag::err_expected_lparen_after,
"interop"))
1494 OMPInteropInfo InteropInfo;
1495 if (ParseOMPInteropInfo(InteropInfo, OMPC_append_args))
1498 InteropInfos.push_back(InteropInfo);
1501 if (Tok.is(tok::comma))
1504 if (!HasError && InteropInfos.empty()) {
1506 Diag(Tok.getLocation(), diag::err_omp_unexpected_append_op);
1507 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1510 HasError =
T.consumeClose() || HasError;
1514bool Parser::parseOMPDeclareVariantMatchClause(
SourceLocation Loc,
1516 OMPTraitInfo *ParentTI) {
1520 : getOpenMPClauseKind(PP.getSpelling(Tok));
1521 if (CKind != OMPC_match) {
1522 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1529 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1530 getOpenMPClauseName(OMPC_match).data()))
1534 parseOMPContextSelectors(Loc, TI);
1537 (void)
T.consumeClose();
1547 for (
const OMPTraitSet &ParentSet : ParentTI->
Sets) {
1548 bool MergedSet =
false;
1549 for (OMPTraitSet &
Set : TI.
Sets) {
1550 if (
Set.Kind != ParentSet.
Kind)
1553 for (
const OMPTraitSelector &ParentSelector : ParentSet.
Selectors) {
1554 bool MergedSelector =
false;
1555 for (OMPTraitSelector &Selector :
Set.Selectors) {
1556 if (Selector.
Kind != ParentSelector.
Kind)
1558 MergedSelector =
true;
1559 for (
const OMPTraitProperty &ParentProperty :
1561 bool MergedProperty =
false;
1575 if (Selector.
Kind == llvm::omp::TraitSelector::user_condition) {
1576 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1579 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1580 << getOpenMPContextTraitPropertyName(
1582 << getOpenMPContextTraitSelectorName(ParentSelector.
Kind)
1583 << getOpenMPContextTraitSetName(ParentSet.
Kind);
1586 if (!MergedProperty)
1587 Selector.
Properties.push_back(ParentProperty);
1590 if (!MergedSelector)
1591 Set.Selectors.push_back(ParentSelector);
1595 TI.
Sets.push_back(ParentSet);
1604 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
1605 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1608 : getOpenMPClauseKind(PP.getSpelling(Tok));
1609 if (DKind == OMPD_depobj && CKind == OMPC_update)
1610 CKind = OMPC_update_depend_objects;
1611 Actions.OpenMP().StartOpenMPClause(CKind);
1613 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
1614 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1616 SeenClauses[unsigned(CKind)] =
true;
1617 if (Clause !=
nullptr)
1618 Clauses.push_back(Clause);
1619 if (Tok.is(tok::annot_pragma_openmp_end)) {
1620 Actions.OpenMP().EndOpenMPClause();
1624 if (Tok.is(tok::comma))
1626 Actions.OpenMP().EndOpenMPClause();
1632 SmallVector<std::string, 4> Assumptions;
1633 bool SkippedClauses =
false;
1635 auto SkipBraces = [&](llvm::StringRef Spelling,
bool IssueNote) {
1637 tok::annot_pragma_openmp_end);
1638 if (
T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1641 if (IssueNote &&
T.getCloseLocation().isValid())
1642 Diag(
T.getCloseLocation(),
1643 diag::note_omp_assumption_clause_continue_here);
1649 auto MatchACMClause = [&](StringRef RawString) {
1650 llvm::StringSwitch<int> SS(RawString);
1651 unsigned ACMIdx = 0;
1652 for (
const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1653 if (ACMI.StartsWith)
1654 SS.StartsWith(ACMI.Identifier, ACMIdx++);
1656 SS.Case(ACMI.Identifier, ACMIdx++);
1658 return SS.Default(-1);
1661 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1662 IdentifierInfo *II =
nullptr;
1663 SourceLocation StartLoc = Tok.getLocation();
1665 if (Tok.isAnyIdentifier()) {
1666 II = Tok.getIdentifierInfo();
1667 Idx = MatchACMClause(II->
getName());
1671 bool NextIsLPar = Tok.is(tok::l_paren);
1674 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
1675 Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1676 << llvm::omp::getOpenMPDirectiveName(DKind, OMPVersion)
1677 << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1679 SkipBraces(II ? II->
getName() :
"",
true);
1680 SkippedClauses =
true;
1683 const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1684 if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1687 SkippedClauses =
true;
1688 SkipBraces(II->
getName(),
false);
1693 Diag(Tok.getLocation(),
1694 diag::warn_omp_unknown_assumption_clause_without_args)
1696 SkipBraces(II->
getName(),
true);
1699 assert(II &&
"Expected an identifier clause!");
1700 std::string Assumption = II->
getName().str();
1701 if (ACMI.StartsWith)
1702 Assumption =
"ompx_" + Assumption.substr(ACMI.Identifier.size());
1704 Assumption =
"omp_" + Assumption;
1705 Assumptions.push_back(Assumption);
1708 Actions.OpenMP().ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions,
1713 if (Actions.OpenMP().isInOpenMPAssumeScope())
1714 Actions.OpenMP().ActOnOpenMPEndAssumesDirective();
1716 Diag(Loc, diag::err_expected_begin_assumes);
1730struct SimpleClauseData {
1733 SourceLocation LOpen;
1734 SourceLocation TypeLoc;
1735 SourceLocation RLoc;
1736 SimpleClauseData(
unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1737 SourceLocation TypeLoc, SourceLocation RLoc)
1738 :
Type(
Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1742static std::optional<SimpleClauseData>
1749 if (
T.expectAndConsume(diag::err_expected_lparen_after,
1750 getOpenMPClauseName(Kind).data()))
1751 return std::nullopt;
1757 if (
Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::comma) &&
1758 Tok.isNot(tok::annot_pragma_openmp_end))
1763 if (!
T.consumeClose())
1764 RLoc =
T.getCloseLocation();
1766 return SimpleClauseData(
Type, Loc, LOpen,
TypeLoc, RLoc);
1769void Parser::ParseOMPDeclareTargetClauses(
1771 SourceLocation DeviceTypeLoc;
1772 bool RequiresToLinkLocalOrIndirectClause =
false;
1773 bool HasToLinkLocalOrIndirectClause =
false;
1774 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1775 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1776 bool HasIdentifier = Tok.is(tok::identifier);
1777 if (HasIdentifier) {
1779 RequiresToLinkLocalOrIndirectClause =
true;
1780 IdentifierInfo *II = Tok.getIdentifierInfo();
1781 StringRef ClauseName = II->
getName();
1782 bool IsDeviceTypeClause =
1784 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1786 bool IsIndirectClause =
getLangOpts().OpenMP >= 51 &&
1787 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1789 if (DTCI.
Indirect && IsIndirectClause) {
1790 llvm::omp::Version OMPVersion =
1791 Actions.getLangOpts().getOpenMPVersion();
1792 Diag(Tok, diag::err_omp_more_one_clause)
1793 << getOpenMPDirectiveName(OMPD_declare_target, OMPVersion)
1794 << getOpenMPClauseName(OMPC_indirect) << 0;
1797 bool IsToEnterLinkOrLocalClause =
1798 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1799 assert((!IsDeviceTypeClause || !IsToEnterLinkOrLocalClause) &&
1804 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1805 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1808 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1809 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1814 if (
getLangOpts().OpenMP < 60 && ClauseName ==
"local") {
1816 ? diag::err_omp_declare_target_unexpected_clause_52
1817 : diag::err_omp_declare_target_unexpected_clause)
1825 if (!IsDeviceTypeClause && !IsIndirectClause &&
1826 DTCI.
Kind == OMPD_begin_declare_target) {
1828 ? diag::err_omp_declare_target_unexpected_clause_52
1829 : diag::err_omp_declare_target_unexpected_clause)
1830 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1834 if (!IsDeviceTypeClause && !IsToEnterLinkOrLocalClause &&
1835 !IsIndirectClause) {
1837 ? diag::err_omp_declare_target_unexpected_clause_52
1838 : diag::err_omp_declare_target_unexpected_clause)
1847 if (IsToEnterLinkOrLocalClause || IsIndirectClause)
1848 HasToLinkLocalOrIndirectClause =
true;
1850 if (IsIndirectClause) {
1851 if (!ParseOpenMPIndirectClause(DTCI,
false))
1856 if (IsDeviceTypeClause) {
1857 std::optional<SimpleClauseData> DevTypeData =
1860 if (DeviceTypeLoc.
isValid()) {
1862 Diag(DevTypeData->Loc,
1863 diag::warn_omp_more_one_device_type_clause);
1867 case OMPC_DEVICE_TYPE_any:
1868 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Any;
1870 case OMPC_DEVICE_TYPE_host:
1871 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Host;
1873 case OMPC_DEVICE_TYPE_nohost:
1874 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1877 llvm_unreachable(
"Unexpected device_type");
1879 DeviceTypeLoc = DevTypeData->Loc;
1886 if (DTCI.
Kind == OMPD_declare_target || HasIdentifier) {
1887 auto &&
Callback = [
this, MT, &DTCI](CXXScopeSpec &SS,
1888 DeclarationNameInfo NameInfo) {
1889 NamedDecl *ND = Actions.OpenMP().lookupOpenMPDeclareTargetName(
1893 SemaOpenMP::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.
getLoc()};
1896 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1899 if (ParseOpenMPSimpleVarList(OMPD_declare_target,
Callback,
1904 if (Tok.is(tok::l_paren)) {
1906 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1909 if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1912 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1913 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1918 if (Tok.is(tok::comma))
1922 if (DTCI.
Indirect && DTCI.
DT != OMPDeclareTargetDeclAttr::DT_Any)
1923 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1926 if (DTCI.
Kind == OMPD_declare_target && RequiresToLinkLocalOrIndirectClause &&
1927 !HasToLinkLocalOrIndirectClause)
1928 Diag(DTCI.
Loc, diag::err_omp_declare_target_missing_required_clause)
1940 if (Tok.is(tok::annot_pragma_openmp_end))
1943 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
1944 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1945 << getOpenMPDirectiveName(DKind, OMPVersion);
1946 while (Tok.isNot(tok::annot_pragma_openmp_end))
1955 bool SkipUntilOpenMPEnd) {
1956 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1958 if (FoundKind == ExpectedKind) {
1960 skipUntilPragmaOpenMPEnd(ExpectedKind);
1964 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
1965 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1967 Diag(BeginLoc, diag::note_matching)
1968 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind, OMPVersion) +
"'")
1970 if (SkipUntilOpenMPEnd)
1977 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1981 if (Tok.is(tok::annot_pragma_openmp_end))
1982 ConsumeAnnotationToken();
1988 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
1989 "Not an OpenMP directive!");
1992 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
1997 TentativeParsingAction TPA(*
this);
1998 Loc = ConsumeAnnotationToken();
2000 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
2005 Toks.push_back(Tok);
2006 while (Cnt && Tok.isNot(tok::eof)) {
2008 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
2010 else if (Tok.is(tok::annot_pragma_openmp_end))
2012 Toks.push_back(Tok);
2017 auto *LP =
new LateParsedPragma(
this, AS);
2019 getCurrentClass().LateParsedDeclarations.push_back(LP);
2024 Loc = ConsumeAnnotationToken();
2029 case OMPD_threadprivate: {
2031 DeclDirectiveListParserHelper Helper(
this, DKind);
2032 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2034 skipUntilPragmaOpenMPEnd(DKind);
2036 ConsumeAnnotationToken();
2037 return Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2038 Loc, Helper.getIdentifiers());
2042 case OMPD_groupprivate: {
2044 DeclDirectiveListParserHelper Helper(
this, DKind);
2045 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2047 skipUntilPragmaOpenMPEnd(DKind);
2049 ConsumeAnnotationToken();
2050 return Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2051 Loc, Helper.getIdentifiers());
2055 case OMPD_allocate: {
2057 DeclDirectiveListParserHelper Helper(
this, DKind);
2058 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2060 SmallVector<OMPClause *, 1> Clauses;
2061 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2062 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
2063 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2065 Tok.isAnnotation() ? OMPC_unknown
2066 : getOpenMPClauseKind(PP.getSpelling(Tok));
2067 Actions.OpenMP().StartOpenMPClause(CKind);
2068 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2069 !SeenClauses[
unsigned(CKind)]);
2070 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2072 SeenClauses[unsigned(CKind)] =
true;
2073 if (Clause !=
nullptr)
2074 Clauses.push_back(Clause);
2075 if (Tok.is(tok::annot_pragma_openmp_end)) {
2076 Actions.OpenMP().EndOpenMPClause();
2080 if (Tok.is(tok::comma))
2082 Actions.OpenMP().EndOpenMPClause();
2084 skipUntilPragmaOpenMPEnd(DKind);
2087 ConsumeAnnotationToken();
2088 return Actions.OpenMP().ActOnOpenMPAllocateDirective(
2089 Loc, Helper.getIdentifiers(), Clauses);
2093 case OMPD_requires: {
2095 SmallVector<OMPClause *, 5> Clauses;
2096 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2097 if (Tok.is(tok::annot_pragma_openmp_end)) {
2098 Diag(Tok, diag::err_omp_expected_clause)
2099 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2102 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2105 : getOpenMPClauseKind(PP.getSpelling(Tok));
2106 Actions.OpenMP().StartOpenMPClause(CKind);
2107 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
2108 !SeenClauses[
unsigned(CKind)]);
2109 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2111 SeenClauses[unsigned(CKind)] =
true;
2112 if (Clause !=
nullptr)
2113 Clauses.push_back(Clause);
2114 if (Tok.is(tok::annot_pragma_openmp_end)) {
2115 Actions.OpenMP().EndOpenMPClause();
2119 if (Tok.is(tok::comma))
2121 Actions.OpenMP().EndOpenMPClause();
2124 if (Clauses.empty()) {
2125 Diag(Tok, diag::err_omp_expected_clause)
2126 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2127 ConsumeAnnotationToken();
2130 ConsumeAnnotationToken();
2131 return Actions.OpenMP().ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2134 SmallVector<OMPClause *, 1> Clauses;
2136 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2137 Actions.OpenMP().ActOnOpenMPErrorDirective(Clauses, StartLoc,
2143 case OMPD_begin_assumes:
2146 case OMPD_end_assumes:
2149 case OMPD_declare_reduction:
2151 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2152 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2154 ConsumeAnnotationToken();
2158 case OMPD_declare_mapper: {
2160 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2162 ConsumeAnnotationToken();
2167 case OMPD_begin_declare_variant: {
2172 ConsumeAnnotationToken();
2176 case OMPD_end_declare_variant: {
2178 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2179 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2181 Diag(Loc, diag::err_expected_begin_declare_variant);
2183 ConsumeAnnotationToken();
2186 case OMPD_declare_variant:
2187 case OMPD_declare_simd: {
2193 Toks.push_back(Tok);
2195 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2196 Toks.push_back(Tok);
2199 Toks.push_back(Tok);
2203 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2204 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2206 }
else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2210 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2211 MaybeParseCXX11Attributes(Attrs);
2212 ParsingDeclSpec PDS(*
this);
2213 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2216 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2220 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2221 << (DKind == OMPD_declare_simd ? 0 : 1);
2225 DeclGroupRef DG =
Ptr.get();
2226 SourceManager &SM = PP.getSourceManager();
2227 if (llvm::none_of(DG, [&](
const Decl *D) {
2230 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2231 << (DKind == OMPD_declare_simd ? 0 : 1);
2235 if (DKind == OMPD_declare_simd)
2236 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2237 assert(DKind == OMPD_declare_variant &&
2238 "Expected declare variant directive only");
2239 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2242 case OMPD_begin_declare_target:
2243 case OMPD_declare_target: {
2245 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2246 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2247 if (DKind == OMPD_declare_target && !HasClauses &&
2249 Diag(DTLoc, diag::warn_omp_deprecated_declare_target_delimited_form);
2251 ParseOMPDeclareTargetClauses(DTCI);
2252 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2259 if (HasImplicitMappings) {
2260 Actions.OpenMP().ActOnStartOpenMPDeclareTargetContext(DTCI);
2264 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2265 llvm::SmallVector<Decl *, 4> Decls;
2267 Decls.push_back(It.first);
2268 return Actions.BuildDeclaratorGroup(Decls);
2270 case OMPD_end_declare_target: {
2271 if (!Actions.OpenMP().isInOpenMPDeclareTargetContext()) {
2272 Diag(Tok, diag::err_omp_unexpected_directive)
2273 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2276 const SemaOpenMP::DeclareTargetContextInfo &DTCI =
2277 Actions.OpenMP().ActOnOpenMPEndDeclareTargetDirective();
2278 ParseOMPEndDeclareTargetDirective(DTCI.
Kind, DKind, DTCI.
Loc);
2282 Diag(Tok, diag::err_omp_unexpected_directive)
2283 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2287 Diag(Tok, diag::err_omp_unknown_directive);
2290 switch (getDirectiveCategory(DKind)) {
2291 case Category::Executable:
2292 case Category::Meta:
2293 case Category::Subsidiary:
2294 case Category::Utility:
2295 Diag(Tok, diag::err_omp_unexpected_directive)
2296 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2298 case Category::Declarative:
2299 case Category::Informational:
2303 while (Tok.isNot(tok::annot_pragma_openmp_end))
2309StmtResult Parser::ParseOpenMPExecutableDirective(
2311 bool ReadDirectiveWithinMetadirective) {
2313 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
2315 bool HasAssociatedStatement =
true;
2316 Association Assoc = getDirectiveAssociation(DKind);
2320 if (DKind != OMPD_ordered_standalone && DKind != OMPD_section &&
2321 (Assoc == Association::None || Assoc == Association::Separating)) {
2322 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2323 ParsedStmtContext()) {
2324 Diag(Tok, diag::err_omp_immediate_directive)
2325 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2326 if (DKind == OMPD_error) {
2327 SkipUntil(tok::annot_pragma_openmp_end);
2331 HasAssociatedStatement =
false;
2334 SourceLocation EndLoc;
2335 SmallVector<OMPClause *, 5> Clauses;
2336 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2337 DeclarationNameInfo DirName;
2344 bool ImplicitClauseAllowed =
false;
2345 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2347 ImplicitClauseAllowed =
true;
2351 if (DKind == OMPD_critical) {
2353 tok::annot_pragma_openmp_end);
2354 if (!
T.consumeOpen()) {
2355 if (Tok.isAnyIdentifier()) {
2357 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2360 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2364 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2366 if (Tok.isNot(tok::annot_pragma_openmp_end))
2374 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2375 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2378 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2381 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2382 while (Tok.isNot(tok::annot_pragma_openmp_end))
2386 bool HasImplicitClause =
false;
2387 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2388 HasImplicitClause =
true;
2391 PP.EnterToken(Tok,
true);
2392 PP.EnterToken(ImplicitTok,
true);
2397 : getOpenMPClauseKind(PP.getSpelling(Tok));
2398 if (DKind == OMPD_depobj && CKind == OMPC_update)
2399 CKind = OMPC_update_depend_objects;
2401 if (HasImplicitClause) {
2402 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2403 if (DKind == OMPD_flush) {
2406 assert(DKind == OMPD_depobj &&
"Expected flush or depobj directives.");
2407 CKind = OMPC_depobj;
2411 ImplicitClauseAllowed =
false;
2412 Actions.OpenMP().StartOpenMPClause(CKind);
2413 HasImplicitClause =
false;
2414 SourceLocation ClauseLoc = Tok.getLocation();
2417 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2418 SeenClauses[unsigned(CKind)] =
true;
2420 Clauses.push_back(Clause);
2423 if (Tok.is(tok::comma))
2425 Actions.OpenMP().EndOpenMPClause();
2429 if (Tok.getLocation() == ClauseLoc) {
2430 skipUntilPragmaOpenMPEnd(DKind);
2435 EndLoc = Tok.getLocation();
2437 ConsumeAnnotationToken();
2439 assert(DKind != OMPD_ordered_blockassoc &&
2440 "Wrong kind for ordered directive");
2441 if (DKind == OMPD_ordered_standalone) {
2444 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2445 if (SeenClauses[
unsigned(CK)]) {
2446 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2447 ParsedStmtContext()) {
2448 Diag(Loc, diag::err_omp_immediate_directive)
2449 << getOpenMPDirectiveName(DKind, OMPVersion) << 1
2450 << getOpenMPClauseName(CK);
2452 HasAssociatedStatement =
false;
2456 if (HasAssociatedStatement)
2457 DKind = OMPD_ordered_blockassoc;
2460 if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
2461 !SeenClauses[
unsigned(OMPC_sizes)]) {
2462 Diag(Loc, diag::err_omp_required_clause)
2463 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"sizes";
2465 if (DKind == OMPD_split && !SeenClauses[
unsigned(OMPC_counts)]) {
2466 Diag(Loc, diag::err_omp_required_clause)
2467 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"counts";
2471 if (HasAssociatedStatement) {
2473 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2479 Sema::CompoundScopeRAII Scope(Actions);
2480 AssociatedStmt = ParseStatement();
2485 Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
2488 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2489 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2490 DKind == OMPD_target_exit_data) {
2491 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2492 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2493 Actions.ActOnCompoundStmt(Loc, Loc, {},
2496 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2500 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2503 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2504 OMPDirectiveScope.Exit();
2509StmtResult Parser::ParseOpenMPInformationalDirective(
2511 bool ReadDirectiveWithinMetadirective) {
2513 "Unexpected directive category");
2515 bool HasAssociatedStatement =
true;
2517 SmallVector<OMPClause *, 5> Clauses;
2518 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2519 DeclarationNameInfo DirName;
2522 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2524 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2527 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2528 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2529 while (Tok.isNot(tok::annot_pragma_openmp_end))
2536 : getOpenMPClauseKind(PP.getSpelling(Tok));
2537 Actions.OpenMP().StartOpenMPClause(CKind);
2539 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2540 SeenClauses[unsigned(CKind)] =
true;
2542 Clauses.push_back(Clause);
2544 if (Tok.is(tok::comma))
2546 Actions.OpenMP().EndOpenMPClause();
2549 SourceLocation EndLoc = Tok.getLocation();
2550 ConsumeAnnotationToken();
2553 if (HasAssociatedStatement) {
2554 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2557 Sema::CompoundScopeRAII Scope(Actions);
2558 AssociatedStmt = ParseStatement();
2561 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2565 DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2567 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2568 OMPDirectiveScope.Exit();
2573StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2574 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2575 if (!ReadDirectiveWithinMetadirective)
2576 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2577 "Not an OpenMP directive!");
2580 SourceLocation Loc = ReadDirectiveWithinMetadirective
2582 : ConsumeAnnotationToken();
2583 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
2585 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2586 Diag(Tok, diag::err_omp_unknown_directive);
2592 bool IsExecutable = [&]() {
2593 if (DKind == OMPD_error)
2595 auto Res = getDirectiveCategory(DKind);
2596 return Res == Category::Executable || Res == Category::Subsidiary;
2600 Directive = ParseOpenMPExecutableDirective(
2601 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2602 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2611 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
2612 while (Tok.isNot(tok::annot_pragma_openmp_end))
2615 skipUntilPragmaOpenMPEnd(DKind);
2616 if (Tok.is(tok::annot_pragma_openmp_end))
2617 ConsumeAnnotationToken();
2620 case OMPD_metadirective: {
2622 SmallVector<VariantMatchInfo, 4> VMIs;
2623 SmallVector<OMPTraitInfo *, 4> TraitInfos;
2628 TentativeParsingAction TPA(*
this);
2629 ASTContext &ASTContext = Actions.getASTContext();
2632 tok::annot_pragma_openmp_end);
2633 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2636 : getOpenMPClauseKind(PP.getSpelling(Tok));
2638 if (CKind == OMPC_unknown) {
2639 Diag(Tok, diag::err_omp_expected_clause) <<
"metadirective";
2641 SkipUntil(tok::annot_pragma_openmp_end);
2644 if (
getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
2645 Diag(Tok, diag::err_omp_unexpected_clause)
2646 << getOpenMPClauseName(CKind) <<
"metadirective";
2647 if (CKind == OMPC_default &&
getLangOpts().OpenMP >= 52)
2648 Diag(Tok, diag::warn_omp_default_deprecated);
2653 if (
T.expectAndConsume(diag::err_expected_lparen_after,
2654 getOpenMPClauseName(CKind).data())) {
2656 SkipUntil(tok::annot_pragma_openmp_end);
2660 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2661 if (CKind == OMPC_when) {
2663 parseOMPContextSelectors(Loc, TI);
2664 if (TI.
Sets.size() == 0) {
2665 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2671 if (Tok.is(tok::colon))
2674 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2682 while (Tok.isNot(tok::r_paren) || paren != 0) {
2683 if (Tok.is(tok::l_paren))
2685 if (Tok.is(tok::r_paren))
2687 if (Tok.is(tok::annot_pragma_openmp_end)) {
2688 Diag(Tok, diag::err_omp_expected_punc)
2689 << getOpenMPClauseName(CKind) << 0;
2696 if (Tok.is(tok::r_paren))
2699 VariantMatchInfo VMI;
2702 VMIs.push_back(VMI);
2703 TraitInfos.push_back(&TI);
2706 SourceLocation EndLoc = Tok.getLocation();
2711 [
this, Loc](StringRef ISATrait) {
2714 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2716 TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2718 ArrayRef<llvm::omp::TraitProperty>(),
2719 Actions.OpenMP().getOpenMPDeviceNum());
2722 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2726 bool HasNonConstUserCondition =
2727 llvm::any_of(TraitInfos, [&](OMPTraitInfo *TI) {
2733 if (HasNonConstUserCondition &&
2734 getLangOpts().OpenMPMetadirectiveRuntimeSelection) {
2738 unsigned NumClauses = TraitInfos.size();
2739 if (llvm::none_of(TraitInfos, [](
const OMPTraitInfo *TI) {
2740 return TI->
Sets.empty();
2748 SmallVector<Stmt *, 4> Variants;
2749 bool HasError =
false;
2750 for (
unsigned I : llvm::seq<unsigned>(TraitInfos.size())) {
2751 bool HasDirective =
false;
2752 if (I < NumClauses) {
2756 if (CKind == OMPC_when) {
2762 HasDirective = Tok.isNot(tok::r_paren) &&
2763 Tok.isNot(tok::annot_pragma_openmp_end);
2766 std::optional<TentativeParsingAction> VariantTPA;
2767 if (I + 1 < TraitInfos.size())
2768 VariantTPA.emplace(*
this,
true);
2772 Variant = ParseOpenMPDeclarativeOrExecutableDirective(
2776 while (Tok.isNot(tok::annot_pragma_openmp_end))
2778 ConsumeAnnotationToken();
2781 if (!Variant.isInvalid() && !Variant.isUsable()) {
2783 Variant = ParseStatement();
2787 if (
auto *D = dyn_cast_or_null<OMPExecutableDirective>(Variant.get());
2788 D && !D->hasAssociatedStmt()) {
2789 Diag(Loc, diag::err_omp_metadirective_standalone_variant);
2794 VariantTPA->Revert();
2798 if (Variant.isInvalid())
2801 Variants.push_back(Variant.get());
2805 return Actions.OpenMP().ActOnOpenMPMetaDirective(Loc, EndLoc, TraitInfos,
2814 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2816 if (Idx++ != BestIdx) {
2821 while (Tok.isNot(tok::r_paren) || paren != 0) {
2822 if (Tok.is(tok::l_paren))
2824 if (Tok.is(tok::r_paren))
2829 if (Tok.is(tok::r_paren))
2836 : getOpenMPClauseKind(PP.getSpelling(Tok));
2843 if (CKind == OMPC_when) {
2844 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2846 parseOMPContextSelectors(Loc, TI);
2854 if (Tok.is(tok::r_paren)) {
2855 SkipUntil(tok::annot_pragma_openmp_end);
2860 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2868 if (BestIdx == -1 && Idx > 0) {
2869 assert(Tok.is(tok::annot_pragma_openmp_end) &&
2870 "Expecting the end of the pragma here");
2871 ConsumeAnnotationToken();
2876 case OMPD_threadprivate: {
2878 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2879 ParsedStmtContext()) {
2880 Diag(Tok, diag::err_omp_immediate_directive)
2881 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2884 DeclDirectiveListParserHelper Helper(
this, DKind);
2885 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2887 skipUntilPragmaOpenMPEnd(DKind);
2888 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2889 Loc, Helper.getIdentifiers());
2890 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2892 SkipUntil(tok::annot_pragma_openmp_end);
2895 case OMPD_groupprivate: {
2896 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2897 ParsedStmtContext()) {
2898 Diag(Tok, diag::err_omp_immediate_directive)
2899 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2902 DeclDirectiveListParserHelper Helper(
this, DKind);
2903 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2905 skipUntilPragmaOpenMPEnd(DKind);
2906 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2907 Loc, Helper.getIdentifiers());
2908 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2910 SkipUntil(tok::annot_pragma_openmp_end);
2913 case OMPD_allocate: {
2915 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2916 ParsedStmtContext()) {
2917 Diag(Tok, diag::err_omp_immediate_directive)
2918 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2921 DeclDirectiveListParserHelper Helper(
this, DKind);
2922 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2924 SmallVector<OMPClause *, 1> Clauses;
2925 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2926 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2927 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2929 Tok.isAnnotation() ? OMPC_unknown
2930 : getOpenMPClauseKind(PP.getSpelling(Tok));
2931 Actions.OpenMP().StartOpenMPClause(CKind);
2932 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2933 !SeenClauses[
unsigned(CKind)]);
2934 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2936 SeenClauses[unsigned(CKind)] =
true;
2937 if (Clause !=
nullptr)
2938 Clauses.push_back(Clause);
2939 if (Tok.is(tok::annot_pragma_openmp_end)) {
2940 Actions.OpenMP().EndOpenMPClause();
2944 if (Tok.is(tok::comma))
2946 Actions.OpenMP().EndOpenMPClause();
2948 skipUntilPragmaOpenMPEnd(DKind);
2950 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPAllocateDirective(
2951 Loc, Helper.getIdentifiers(), Clauses);
2952 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2954 SkipUntil(tok::annot_pragma_openmp_end);
2957 case OMPD_declare_reduction:
2960 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2961 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2963 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2965 SkipUntil(tok::annot_pragma_openmp_end);
2968 case OMPD_declare_mapper: {
2971 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2973 ConsumeAnnotationToken();
2974 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2976 SkipUntil(tok::annot_pragma_openmp_end);
2980 case OMPD_declare_target: {
2982 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2983 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2985 ParseOMPDeclareTargetClauses(DTCI);
2986 bool HasImplicitMappings =
2989 if (HasImplicitMappings) {
2990 Diag(Tok, diag::err_omp_unexpected_directive)
2991 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2992 SkipUntil(tok::annot_pragma_openmp_end);
2999 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
3002 case OMPD_begin_declare_variant: {
3007 ConsumeAnnotationToken();
3011 case OMPD_end_declare_variant: {
3013 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
3014 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
3016 Diag(Loc, diag::err_expected_begin_declare_variant);
3017 ConsumeAnnotationToken();
3020 case OMPD_declare_simd:
3021 case OMPD_begin_declare_target:
3022 case OMPD_end_declare_target:
3024 case OMPD_declare_variant:
3025 Diag(Tok, diag::err_omp_unexpected_directive)
3026 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
3027 SkipUntil(tok::annot_pragma_openmp_end);
3031 Directive = ParseOpenMPInformationalDirective(
3032 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
3034 "Informational directive remains unprocessed");
3039 Diag(Tok, diag::err_omp_unknown_directive);
3040 SkipUntil(tok::annot_pragma_openmp_end);
3046bool Parser::ParseOpenMPSimpleVarList(
3050 bool AllowScopeSpecifier) {
3051 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
3054 if (
T.expectAndConsume(diag::err_expected_lparen_after,
3055 getOpenMPDirectiveName(Kind, OMPVersion).data()))
3057 bool IsCorrect =
true;
3058 bool NoIdentIsFound =
true;
3061 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
3065 Token PrevTok = Tok;
3066 NoIdentIsFound =
false;
3069 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
3072 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3075 false,
false,
false,
3076 false,
false,
nullptr, Name)) {
3078 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3080 }
else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
3081 Tok.isNot(tok::annot_pragma_openmp_end)) {
3083 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3087 << SourceRange(PrevTok.
getLocation(), PrevTokLocation);
3089 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
3092 if (Tok.is(tok::comma)) {
3097 if (NoIdentIsFound) {
3098 Diag(Tok, diag::err_expected) << tok::identifier;
3103 IsCorrect = !
T.consumeClose() && IsCorrect;
3108OMPClause *Parser::ParseOpenMPSizesClause() {
3109 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3110 SmallVector<Expr *, 4> ValExprs;
3111 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
3115 return Actions.OpenMP().ActOnOpenMPSizesClause(ValExprs, ClauseNameLoc,
3119OMPClause *Parser::ParseOpenMPCountsClause() {
3120 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3121 SmallVector<Expr *, 4> ValExprs;
3122 std::optional<unsigned> FillIdx;
3123 unsigned FillCount = 0;
3124 SourceLocation FillLoc;
3126 assert(getOpenMPClauseName(OMPC_counts) == PP.getSpelling(Tok) &&
3127 "Expected parsing to start at clause name");
3131 if (
T.consumeOpen()) {
3132 Diag(Tok, diag::err_expected) << tok::l_paren;
3137 if (Tok.is(tok::identifier) &&
3138 Tok.getIdentifierInfo()->getName() ==
"omp_fill") {
3140 FillIdx = ValExprs.size();
3142 FillLoc = Tok.getLocation();
3144 ValExprs.push_back(
nullptr);
3151 ValExprs.push_back(Val.
get());
3155 if (
T.consumeClose())
3157 OpenLoc =
T.getOpenLocation();
3158 CloseLoc =
T.getCloseLocation();
3160 return Actions.OpenMP().ActOnOpenMPCountsClause(
3161 ValExprs, ClauseNameLoc, OpenLoc, CloseLoc, FillIdx, FillLoc, FillCount);
3164OMPClause *Parser::ParseOpenMPLoopRangeClause() {
3166 SourceLocation FirstLoc, CountLoc;
3169 if (
T.consumeOpen()) {
3170 Diag(Tok, diag::err_expected) << tok::l_paren;
3174 FirstLoc = Tok.getLocation();
3181 ExpectAndConsume(tok::comma);
3183 CountLoc = Tok.getLocation();
3192 return Actions.OpenMP().ActOnOpenMPLoopRangeClause(
3193 FirstVal.
get(), CountVal.
get(), ClauseNameLoc,
T.getOpenLocation(),
3194 FirstLoc, CountLoc,
T.getCloseLocation());
3197OMPClause *Parser::ParseOpenMPPermutationClause() {
3198 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3199 SmallVector<Expr *> ArgExprs;
3200 if (ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,
3205 return Actions.OpenMP().ActOnOpenMPPermutationClause(ArgExprs, ClauseNameLoc,
3210 SourceLocation Loc = Tok.getLocation();
3215 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3217 SmallVector<SemaOpenMP::UsesAllocatorsData, 4>
Data;
3220 if (
getLangOpts().OpenMP >= 52 && Tok.is(tok::identifier) &&
3221 Tok.getIdentifierInfo()->getName() ==
"traits") {
3223 SemaOpenMP::UsesAllocatorsData &D =
Data.emplace_back();
3229 tok::annot_pragma_openmp_end);
3230 TraitParens.consumeOpen();
3233 TraitParens.consumeClose();
3237 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3243 if (Tok.isNot(tok::colon)) {
3244 Diag(Tok, diag::err_expected) << tok::colon;
3246 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3255 ? ParseCXXIdExpression()
3256 : tryParseCXXIdExpression(SS,
false);
3260 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3267 D.
LParenLoc = TraitParens.getOpenLocation();
3268 D.
RParenLoc = TraitParens.getCloseLocation();
3271 if (Tok.is(tok::comma)) {
3273 Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3276 }
else if (Tok.is(tok::semi)) {
3286 getLangOpts().CPlusPlus
3287 ? ParseCXXIdExpression()
3288 : tryParseCXXIdExpression(SS,
false);
3290 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3297 BalancedDelimiterTracker T(*this, tok::l_paren,
3298 tok::annot_pragma_openmp_end);
3300 ExprResult AllocatorTraits =
3301 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3303 if (AllocatorTraits.isInvalid()) {
3304 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3313 if (getLangOpts().OpenMP >= 52) {
3314 Diag(Loc, diag::err_omp_deprecate_old_syntax)
3315 <<
"allocator(expr)"
3316 <<
"uses_allocators"
3317 <<
"traits(expr): alloc";
3321 Diag(
Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3323 if (
Tok.
is(tok::comma))
3325 }
while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end));
3328 Loc,
T.getOpenLocation(),
T.getCloseLocation(),
Data);
3333 OMPClauseKind = CKind;
3334 OMPClause *Clause =
nullptr;
3335 bool ErrorFound =
false;
3336 bool WrongDirective =
false;
3337 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
3340 if (!isAllowedClauseForDirective(D,
C, OMPVersion)) {
3341 Diag(Tok, diag::err_omp_unexpected_clause)
3342 << getOpenMPClauseName(
C) << getOpenMPDirectiveName(D, OMPVersion);
3344 WrongDirective =
true;
3348 if (CKind != OMPC_unknown) {
3350 assert(DKind != OMPD_ordered_blockassoc &&
3351 "Wrong kind for ordered directive");
3352 if (DKind == OMPD_ordered_standalone) {
3355 if (!isAllowedClauseForDirective(DKind, CKind, OMPVersion))
3356 CheckClauseValid(OMPD_ordered_blockassoc, CKind);
3358 CheckClauseValid(DKind, CKind);
3369 case OMPC_grainsize:
3370 case OMPC_num_tasks:
3372 case OMPC_allocator:
3375 case OMPC_novariants:
3376 case OMPC_nocontext:
3382 case OMPC_ompx_dyn_cgroup_mem:
3383 case OMPC_dyn_groupprivate:
3384 case OMPC_transparent:
3413 Diag(Tok, diag::err_omp_more_one_clause)
3414 << getOpenMPDirectiveName(DKind, OMPVersion)
3415 << getOpenMPClauseName(CKind) << 0;
3419 if (CKind == OMPC_transparent && PP.LookAhead(0).isNot(tok::l_paren)) {
3421 SourceLocation LLoc = Tok.getLocation();
3422 if (!WrongDirective)
3423 Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(
nullptr, LLoc,
3427 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3428 PP.LookAhead(0).isNot(tok::l_paren))
3429 Clause = ParseOpenMPClause(CKind, WrongDirective);
3430 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3431 CKind == OMPC_dyn_groupprivate)
3432 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3434 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3436 case OMPC_threadset:
3438 case OMPC_proc_bind:
3439 case OMPC_atomic_default_mem_order:
3457 Diag(Tok, diag::err_omp_more_one_clause)
3458 << getOpenMPDirectiveName(DKind, OMPVersion)
3459 << getOpenMPClauseName(CKind) << 0;
3463 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3467 case OMPC_dist_schedule:
3468 case OMPC_defaultmap:
3479 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3480 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3481 Diag(Tok, diag::err_omp_more_one_clause)
3482 << getOpenMPDirectiveName(DKind, OMPVersion)
3483 << getOpenMPClauseName(CKind) << 0;
3488 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3491 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3495 case OMPC_mergeable:
3509 case OMPC_unified_address:
3510 case OMPC_unified_shared_memory:
3511 case OMPC_reverse_offload:
3512 case OMPC_dynamic_allocators:
3521 Diag(Tok, diag::err_omp_more_one_clause)
3522 << getOpenMPDirectiveName(DKind, OMPVersion)
3523 << getOpenMPClauseName(CKind) << 0;
3527 if (CKind == OMPC_nowait && PP.LookAhead(0).is(tok::l_paren) &&
3529 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3531 Clause = ParseOpenMPClause(CKind, WrongDirective);
3533 case OMPC_self_maps:
3536 Diag(Tok, diag::err_omp_expected_clause)
3537 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3541 Diag(Tok, diag::err_omp_more_one_clause)
3542 << getOpenMPDirectiveName(DKind, OMPVersion)
3543 << getOpenMPClauseName(CKind) << 0;
3546 Clause = ParseOpenMPClause(CKind, WrongDirective);
3550 Diag(Tok, diag::err_omp_more_one_clause)
3551 << getOpenMPDirectiveName(DKind, OMPVersion)
3552 << getOpenMPClauseName(CKind) << 0;
3555 Clause = ParseOpenMPClause(CKind, WrongDirective);
3557 case OMPC_update_depend_objects:
3559 Diag(Tok, diag::err_omp_more_one_clause)
3560 << getOpenMPDirectiveName(DKind, OMPVersion)
3561 << getOpenMPClauseName(CKind) << 0;
3565 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3567 case OMPC_num_teams:
3568 case OMPC_thread_limit:
3569 case OMPC_num_threads:
3571 Diag(Tok, diag::err_omp_more_one_clause)
3572 << getOpenMPDirectiveName(DKind, OMPVersion)
3573 << getOpenMPClauseName(CKind) << 0;
3578 case OMPC_firstprivate:
3579 case OMPC_lastprivate:
3581 case OMPC_reduction:
3582 case OMPC_task_reduction:
3583 case OMPC_in_reduction:
3587 case OMPC_copyprivate:
3593 case OMPC_use_device_ptr:
3594 case OMPC_use_device_addr:
3595 case OMPC_is_device_ptr:
3596 case OMPC_has_device_addr:
3598 case OMPC_nontemporal:
3599 case OMPC_inclusive:
3600 case OMPC_exclusive:
3604 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered_standalone &&
3605 CKind == OMPC_depend)
3606 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3607 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3611 Diag(Tok, diag::err_omp_more_one_clause)
3612 << getOpenMPDirectiveName(DKind, OMPVersion)
3613 << getOpenMPClauseName(CKind) << 0;
3617 Clause = ParseOpenMPSizesClause();
3619 case OMPC_permutation:
3621 Diag(Tok, diag::err_omp_more_one_clause)
3622 << getOpenMPDirectiveName(DKind, OMPVersion)
3623 << getOpenMPClauseName(CKind) << 0;
3626 Clause = ParseOpenMPPermutationClause();
3630 Diag(Tok, diag::err_omp_more_one_clause)
3631 << getOpenMPDirectiveName(DKind, OMPVersion)
3632 << getOpenMPClauseName(CKind) << 0;
3635 Clause = ParseOpenMPCountsClause();
3637 case OMPC_uses_allocators:
3638 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3641 if (DKind != OMPD_interop) {
3643 Diag(Tok, diag::err_omp_more_one_clause)
3644 << getOpenMPDirectiveName(DKind, OMPVersion)
3645 << getOpenMPClauseName(CKind) << 0;
3648 Clause = ParseOpenMPClause(CKind, WrongDirective);
3654 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3656 case OMPC_device_type:
3658 skipUntilPragmaOpenMPEnd(DKind);
3660 case OMPC_threadprivate:
3661 case OMPC_groupprivate:
3664 if (!WrongDirective)
3665 Diag(Tok, diag::err_omp_unexpected_clause)
3666 << getOpenMPClauseName(CKind)
3667 << getOpenMPDirectiveName(DKind, OMPVersion);
3671 case OMPC_contains: {
3673 SourceLocation LLoc = Tok.getLocation();
3674 SourceLocation RLoc;
3675 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3680 if (DK == OMPD_unknown) {
3681 skipUntilPragmaOpenMPEnd(OMPD_assume);
3682 Diag(Tok, diag::err_omp_unexpected_clause)
3683 << getOpenMPClauseName(CKind)
3684 << getOpenMPDirectiveName(DKind, OMPVersion);
3688 DKVec.push_back(DK);
3691 Diag(Tok, diag::err_omp_unexpected_clause)
3692 << getOpenMPClauseName(CKind)
3693 << getOpenMPDirectiveName(DKind, OMPVersion);
3696 RLoc = Tok.getLocation();
3698 if (!WrongDirective)
3699 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3700 CKind, DKVec, Loc, LLoc, RLoc);
3703 case OMPC_no_openmp:
3704 case OMPC_no_openmp_routines:
3705 case OMPC_no_openmp_constructs:
3706 case OMPC_no_parallelism: {
3708 Diag(Tok, diag::err_omp_more_one_clause)
3709 << getOpenMPDirectiveName(DKind, OMPVersion)
3710 << getOpenMPClauseName(CKind) << 0;
3714 if (!WrongDirective)
3715 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3716 CKind, Loc, Tok.getLocation());
3719 case OMPC_ompx_attribute:
3720 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3722 case OMPC_ompx_bare:
3723 if (DKind == llvm::omp::Directive::OMPD_target) {
3728 Diag(Tok, diag::err_omp_unexpected_clause)
3729 << getOpenMPClauseName(CKind)
3730 << getOpenMPDirectiveName(DKind, OMPVersion);
3732 WrongDirective =
true;
3735 Diag(Tok, diag::note_ompx_bare_clause)
3736 << getOpenMPClauseName(CKind) <<
"target teams";
3737 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3738 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3739 << getOpenMPClauseName(CKind)
3740 << getOpenMPDirectiveName(DKind, OMPVersion);
3743 Clause = ParseOpenMPClause(CKind, WrongDirective);
3745 case OMPC_looprange:
3746 Clause = ParseOpenMPLoopRangeClause();
3751 return ErrorFound ?
nullptr : Clause;
3759 bool IsAddressOfOperand) {
3761 if (
T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3769 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3772 RLoc = Tok.getLocation();
3773 if (!
T.consumeClose())
3774 RLoc =
T.getCloseLocation();
3796bool Parser::ParseOpenMPIndirectClause(
3801 if (
Tok.isNot(tok::l_paren)) {
3820 if (
Ret.isInvalid())
3823 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3825 if (
Ret.isInvalid())
3833ExprResult Parser::ParseOMPInteropFrSelector() {
3836 tok::annot_pragma_openmp_end);
3837 if (FT.expectAndConsume(diag::err_expected_lparen_after,
"fr")) {
3839 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3843 SourceLocation Loc = Tok.getLocation();
3846 Arg = Actions.ActOnFinishFullExpr(Arg.
get(), Loc,
false);
3854 tok::annot_pragma_openmp_end);
3855 if (AT.expectAndConsume(diag::err_expected_lparen_after,
"attr")) {
3857 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3861 bool HasError =
false;
3864 if (Tok.is(tok::r_paren)) {
3865 Diag(Tok, diag::err_omp_interop_attr_not_string);
3868 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::r_brace) &&
3869 Tok.isNot(tok::annot_pragma_openmp_end)) {
3870 if (Tok.is(tok::string_literal)) {
3873 Attrs.push_back(S.
get());
3878 Diag(Tok, diag::err_omp_interop_attr_not_string);
3881 if (Tok.is(tok::comma))
3891 bool HasError =
false;
3892 bool IsTarget =
false;
3893 bool IsTargetSync =
false;
3895 while (Tok.is(tok::identifier)) {
3897 bool PreferTypeAllowed = (
Kind == OMPC_init ||
Kind == OMPC_append_args) &&
3898 InteropInfo.
Prefs.empty() && !IsTarget &&
3900 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3905 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3908 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3910 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3911 IsTargetSync =
true;
3913 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3914 PreferTypeAllowed) {
3915 if (Kind == OMPC_append_args &&
getLangOpts().OpenMP < 60) {
3916 Diag(Tok, diag::err_omp_append_args_prefer_type_60);
3921 tok::annot_pragma_openmp_end);
3922 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3926 if (Tok.is(tok::r_paren)) {
3927 Diag(Tok, diag::err_omp_expected_pref_spec);
3931 while (Tok.isNot(tok::r_paren) &&
3932 Tok.isNot(tok::annot_pragma_openmp_end)) {
3934 if (Tok.is(tok::l_brace)) {
3938 Diag(Tok, diag::err_omp_prefer_type_brace_60);
3942 tok::annot_pragma_openmp_end);
3944 Expr *FrExpr =
nullptr;
3945 SmallVector<Expr *, 2> AttrExprs;
3946 bool SeenFr =
false;
3950 if (Tok.is(tok::r_brace)) {
3951 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3955 while (Tok.isNot(tok::r_brace) &&
3956 Tok.isNot(tok::annot_pragma_openmp_end)) {
3957 if (Tok.is(tok::identifier) &&
3958 Tok.getIdentifierInfo()->isStr(
"fr")) {
3960 Diag(Tok, diag::err_omp_interop_multiple_fr);
3964 {tok::comma, tok::r_brace, tok::annot_pragma_openmp_end},
3974 }
else if (Tok.is(tok::identifier) &&
3975 Tok.getIdentifierInfo()->isStr(
"attr")) {
3976 if (ParseOMPInteropAttrSelector(AttrExprs))
3981 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3984 if (Tok.is(tok::comma))
3987 if (BT.consumeClose())
3990 if (FrExpr || !AttrExprs.empty())
3991 InteropInfo.
Prefs.emplace_back(FrExpr, AttrExprs);
3996 SourceLocation Loc = Tok.getLocation();
4000 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
4003 InteropInfo.
Prefs.emplace_back(PTExpr.
get(),
4004 llvm::SmallVector<Expr *, 2>{});
4007 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4012 if (Tok.is(tok::comma))
4018 Diag(Tok, diag::err_omp_expected_interop_type);
4021 if (!Tok.is(tok::comma))
4026 if (!HasError && !IsTarget && !IsTargetSync) {
4027 Diag(Tok, diag::err_omp_expected_interop_type);
4031 if (Kind == OMPC_init) {
4032 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
4033 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
4034 if (Tok.is(tok::colon))
4051 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4052 getOpenMPClauseName(Kind).data()))
4055 bool InteropError =
false;
4056 OMPInteropInfo InteropInfo;
4057 if (Kind == OMPC_init)
4058 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
4061 SourceLocation VarLoc = Tok.getLocation();
4064 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4069 SourceLocation RLoc = Tok.getLocation();
4070 if (!
T.consumeClose())
4071 RLoc =
T.getCloseLocation();
4073 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
4076 if (Kind == OMPC_init)
4077 return Actions.OpenMP().ActOnOpenMPInitClause(
4078 InteropVarExpr.
get(), InteropInfo, Loc,
T.getOpenLocation(), VarLoc,
4080 if (Kind == OMPC_use)
4081 return Actions.OpenMP().ActOnOpenMPUseClause(
4082 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
4084 if (Kind == OMPC_destroy)
4085 return Actions.OpenMP().ActOnOpenMPDestroyClause(
4086 InteropVarExpr.
get(), Loc,
T.getOpenLocation(), VarLoc, RLoc);
4088 llvm_unreachable(
"Unexpected interop variable clause.");
4091OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
4095 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4096 getOpenMPClauseName(OMPC_ompx_attribute).data()))
4099 ParsedAttributes ParsedAttrs(AttrFactory);
4100 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
4103 if (
T.consumeClose())
4109 SmallVector<Attr *> Attrs;
4110 for (
const ParsedAttr &PA : ParsedAttrs) {
4111 switch (PA.getKind()) {
4112 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
4113 if (!PA.checkExactlyNumArgs(Actions, 2))
4115 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
4116 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
4119 case ParsedAttr::AT_AMDGPUWavesPerEU:
4120 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
4121 !PA.checkAtMostNumArgs(Actions, 2))
4123 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
4124 PA, PA.getArgAsExpr(0),
4125 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
4128 case ParsedAttr::AT_CUDALaunchBounds:
4129 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
4130 !PA.checkAtMostNumArgs(Actions, 3))
4132 if (
auto *A = Actions.CreateLaunchBoundsAttr(
4133 PA, PA.getArgAsExpr(0),
4134 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
4135 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr,
4140 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
4145 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
4146 Attrs, Loc,
T.getOpenLocation(),
T.getCloseLocation());
4152 if (!Val || ParseOnly)
4154 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
4155 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
4156 static_cast<DefaultKind
>(Val->Type) ==
4157 OMP_DEFAULT_firstprivate)) {
4158 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
4159 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
4162 : OMPC_firstprivate)
4163 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4166 return Actions.OpenMP().ActOnOpenMPSimpleClause(
4167 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
4171 SourceLocation Loc = Tok.getLocation();
4176 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
4183 SourceLocation DelimLoc;
4186 if (
T.expectAndConsume(diag::err_expected_lparen_after,
4187 getOpenMPClauseName(Kind).data()))
4191 SmallVector<unsigned, 4> Arg;
4192 SmallVector<SourceLocation, 4> KLoc;
4193 if (Kind == OMPC_schedule) {
4194 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
4195 Arg.resize(NumberOfElements);
4196 KLoc.resize(NumberOfElements);
4201 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4204 Arg[Modifier1] = KindModifier;
4205 KLoc[Modifier1] = Tok.getLocation();
4206 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4207 Tok.isNot(tok::annot_pragma_openmp_end))
4209 if (Tok.is(tok::comma)) {
4213 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4217 KLoc[Modifier2] = Tok.getLocation();
4218 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4219 Tok.isNot(tok::annot_pragma_openmp_end))
4223 if (Tok.is(tok::colon))
4226 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
4228 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4230 Arg[ScheduleKind] = KindModifier;
4231 KLoc[ScheduleKind] = Tok.getLocation();
4232 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4233 Tok.isNot(tok::annot_pragma_openmp_end))
4235 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
4236 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
4237 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
4240 }
else if (Kind == OMPC_dist_schedule) {
4242 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4243 KLoc.push_back(Tok.getLocation());
4244 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4245 Tok.isNot(tok::annot_pragma_openmp_end))
4247 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
4249 }
else if (Kind == OMPC_default) {
4252 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4254 Arg.push_back(Modifier);
4255 KLoc.push_back(Tok.getLocation());
4256 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4257 Tok.isNot(tok::annot_pragma_openmp_end))
4260 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
4265 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4266 Arg.push_back(VariableCategory);
4267 KLoc.push_back(Tok.getLocation());
4268 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4269 Tok.isNot(tok::annot_pragma_openmp_end))
4272 Arg.push_back(OMPC_DEFAULT_VC_all);
4273 KLoc.push_back(SourceLocation());
4275 }
else if (Kind == OMPC_defaultmap) {
4278 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4284 Arg.push_back(Modifier);
4285 KLoc.push_back(Tok.getLocation());
4286 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4287 Tok.isNot(tok::annot_pragma_openmp_end))
4290 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
4291 if (Tok.is(tok::colon))
4294 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
4297 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4298 KLoc.push_back(Tok.getLocation());
4299 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4300 Tok.isNot(tok::annot_pragma_openmp_end))
4304 KLoc.push_back(SourceLocation());
4306 }
else if (Kind == OMPC_order) {
4307 enum { Modifier, OrderKind, NumberOfElements };
4308 Arg.resize(NumberOfElements);
4309 KLoc.resize(NumberOfElements);
4313 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4316 Arg[Modifier] = KindModifier;
4317 KLoc[Modifier] = Tok.getLocation();
4318 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4319 Tok.isNot(tok::annot_pragma_openmp_end))
4322 if (Tok.is(tok::colon))
4325 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
4327 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4329 Arg[OrderKind] = KindModifier;
4330 KLoc[OrderKind] = Tok.getLocation();
4331 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4332 Tok.isNot(tok::annot_pragma_openmp_end))
4334 }
else if (Kind == OMPC_device) {
4340 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4341 KLoc.push_back(Tok.getLocation());
4347 KLoc.emplace_back();
4349 }
else if (Kind == OMPC_grainsize) {
4353 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4357 Arg.push_back(Modifier);
4358 KLoc.push_back(Tok.getLocation());
4364 if (Modifier == OMPC_GRAINSIZE_strict) {
4365 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4370 KLoc.emplace_back();
4374 KLoc.emplace_back();
4376 }
else if (Kind == OMPC_dyn_groupprivate) {
4377 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4378 Arg.resize(NumberOfModifiers);
4379 KLoc.resize(NumberOfModifiers);
4383 auto ConsumeModifier = [&]() {
4384 unsigned Type = NumberOfModifiers;
4387 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4391 ParenT.consumeOpen();
4394 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4397 Diag(Tok.getLocation(), diag::err_expected)
4398 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4400 return std::make_tuple(
Type, Modifier, Loc);
4402 Type = ComplexModifier;
4403 Loc = Tok.getLocation();
4404 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4405 Tok.isNot(tok::annot_pragma_openmp_end))
4407 ParenT.consumeClose();
4410 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4412 Type = SimpleModifier;
4413 Loc = Tok.getLocation();
4414 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4415 Tok.isNot(tok::annot_pragma_openmp_end))
4419 return std::make_tuple(
Type, Modifier, Loc);
4422 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4423 SourceLocation Loc) {
4424 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4425 if (!KLoc[
Type].isValid()) {
4426 Arg[
Type] = Modifier;
4429 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4436 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4437 if (Type1 < NumberOfModifiers) {
4438 SaveModifier(Type1, Mod1, Loc1);
4439 if (Tok.is(tok::comma)) {
4442 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4443 if (Type2 < NumberOfModifiers)
4444 SaveModifier(Type2, Mod2, Loc2);
4447 if (Tok.is(tok::colon))
4450 Diag(Tok, diag::warn_pragma_expected_colon)
4451 <<
"dyn_groupprivate modifier";
4453 }
else if (Kind == OMPC_num_tasks) {
4457 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4461 Arg.push_back(Modifier);
4462 KLoc.push_back(Tok.getLocation());
4468 if (Modifier == OMPC_NUMTASKS_strict) {
4469 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4474 KLoc.emplace_back();
4478 KLoc.emplace_back();
4481 assert(Kind == OMPC_if);
4482 KLoc.push_back(Tok.getLocation());
4483 TentativeParsingAction TPA(*
this);
4485 Arg.push_back(
static_cast<unsigned>(DK));
4486 if (DK != OMPD_unknown) {
4488 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4493 Arg.back() = unsigned(OMPD_unknown);
4500 bool NeedAnExpression = (
Kind == OMPC_schedule && DelimLoc.
isValid()) ||
4501 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
4502 Kind == OMPC_if ||
Kind == OMPC_device ||
4503 Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4504 Kind == OMPC_dyn_groupprivate;
4505 if (NeedAnExpression) {
4506 SourceLocation ELoc = Tok.getLocation();
4512 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4516 SourceLocation RLoc = Tok.getLocation();
4517 if (!
T.consumeClose())
4518 RLoc =
T.getCloseLocation();
4520 if (NeedAnExpression && Val.
isInvalid())
4523 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4524 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4525 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4526 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4527 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4530 : OMPC_firstprivate)
4531 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4537 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4538 Kind, Arg, Val.
get(), Loc,
T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4543 if (ReductionIdScopeSpec.
isEmpty()) {
4581 ReductionIdScopeSpec,
nullptr,
4585 false,
nullptr, ReductionId);
4592 if (!
Tok.is(tok::identifier))
4599 return TypeModifier;
4605 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4606 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4612 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4616 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4617 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4618 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4622 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4624 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4627 return T.consumeClose();
4633 bool HasMapType =
false;
4635 StringRef PreMapName =
"";
4639 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4640 TypeModifier == OMPC_MAP_MODIFIER_close ||
4641 TypeModifier == OMPC_MAP_MODIFIER_present ||
4642 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4643 Data.MapTypeModifiers.push_back(TypeModifier);
4644 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4645 if (PP.LookAhead(0).isNot(tok::comma) &&
4646 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4647 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4648 <<
"map type modifier";
4650 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4651 Data.MapTypeModifiers.push_back(TypeModifier);
4652 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4656 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4658 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4659 <<
"map type modifier";
4664 Data.ExtraModifier = MapKind;
4666 PreMapLoc = Tok.getLocation();
4667 PreMapName = Tok.getIdentifierInfo()->getName();
4669 Diag(Tok, diag::err_omp_more_one_map_type);
4670 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4674 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4675 Data.MapTypeModifiers.push_back(TypeModifier);
4676 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4677 if (PP.LookAhead(0).isNot(tok::comma) &&
4678 PP.LookAhead(0).isNot(tok::colon))
4679 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4680 <<
"map type modifier";
4682 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4692 if (Tok.is(tok::comma)) {
4693 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4698 if (PP.LookAhead(0).is(tok::colon)) {
4706 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4717 if (!Tok.is(tok::colon)) {
4718 Diag(Tok, diag::err_omp_unknown_map_type);
4732 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4737 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4738 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4739 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4749 if (
Tok.is(tok::colon)) {
4750 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4755 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4759ExprResult Parser::ParseOpenMPIteratorsExpr() {
4760 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4761 "Expected 'iterator' token.");
4765 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4768 SourceLocation LLoc =
T.getOpenLocation();
4769 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4770 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4773 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4780 IteratorType = TR.
get();
4784 IdentifierInfo *II =
nullptr;
4785 SourceLocation IdLoc;
4786 if (Tok.is(tok::identifier)) {
4787 II = Tok.getIdentifierInfo();
4790 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4794 SourceLocation AssignLoc;
4795 if (Tok.is(tok::equal))
4798 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4803 SourceLocation Loc = Tok.getLocation();
4806 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4809 SourceLocation ColonLoc;
4810 if (Tok.is(tok::colon))
4814 Loc = Tok.getLocation();
4817 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4820 SourceLocation SecColonLoc;
4823 if (Tok.is(tok::colon)) {
4827 Loc = Tok.getLocation();
4830 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4835 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4836 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4837 if (Tok.is(tok::comma))
4840 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4843 D.
Type = IteratorType;
4853 SourceLocation RLoc = Tok.getLocation();
4854 if (!
T.consumeClose())
4855 RLoc =
T.getCloseLocation();
4857 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4866 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4869 if (Tok.is(tok::identifier) &&
4870 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4872 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4873 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4874 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4875 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4876 Data.ExtraModifier != OMPC_DEPEND_inout)
4877 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4879 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4880 ? OMPC_DEPEND_outallmemory
4881 : OMPC_DEPEND_inoutallmemory;
4891 if (Tok.isNot(tok::identifier) ||
4892 !Tok.getIdentifierInfo()->isStr(
"omp_num_args")) {
4907 if (Tok.isOneOf(tok::plus, tok::minus)) {
4912 if (Offset.isInvalid())
4914 Bound.
E = Offset.get();
4918 if (!Tok.isOneOf(tok::colon, tok::comma, tok::r_paren,
4919 tok::annot_pragma_openmp_end)) {
4920 Diag(Tok, diag::err_omp_num_args_invalid_form) << 1;
4928 bool IsError =
false;
4934 bool ItemError =
false;
4935 if (Tok.isNot(tok::colon)) {
4939 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4944 if (Tok.is(tok::colon)) {
4948 if (!Tok.isOneOf(tok::comma, tok::r_paren,
4949 tok::annot_pragma_openmp_end)) {
4953 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4960 Item.
Lower = LowerBound;
4961 Item.
Upper = UpperBound;
4962 Items.push_back(Item);
4964 }
else if (!ItemError &&
4969 Diag(ItemLoc, diag::err_omp_num_args_invalid_form) << 0;
4973 Item.
E = LowerBound.
E;
4974 Items.push_back(Item);
4980 if (Tok.isNot(tok::comma)) {
4981 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4982 Diag(Tok, diag::err_omp_expected_punc)
4983 << getOpenMPClauseName(OMPC_adjust_args) << 0;
4985 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4988 if (Tok.isNot(tok::comma))
5005 Data.DepModOrTailExpr = Tail.
get();
5007 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
5008 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
5026 bool AllocatorSeen =
false;
5027 bool AlignSeen =
false;
5046 if (
Tok.is(tok::l_paren)) {
5047 switch (CurrentModifier) {
5048 case OMPC_ALLOCATE_allocator: {
5049 if (AllocatorSeen) {
5050 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
5052 << getOpenMPClauseName(Kind);
5054 Data.AllocClauseModifiers.push_back(CurrentModifier);
5055 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
5058 tok::annot_pragma_openmp_end);
5062 AllocatorSeen =
true;
5065 case OMPC_ALLOCATE_align: {
5067 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
5069 << getOpenMPClauseName(Kind);
5071 Data.AllocClauseModifiers.push_back(CurrentModifier);
5072 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
5076 Data.AllocateAlignment = Val.
get();
5081 llvm_unreachable(
"Unexpected allocate modifier");
5084 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
5086 if (
Tok.isNot(tok::comma))
5089 CurrentModifierLoc =
Tok.getLocation();
5094 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
5097 }
while (!AllocatorSeen || !AlignSeen);
5106 bool InvalidReductionId =
false;
5107 bool IsInvalidMapperModifier =
false;
5111 if (
T.expectAndConsume(diag::err_expected_lparen_after,
5112 getOpenMPClauseName(Kind).data()))
5115 bool HasIterator =
false;
5116 bool InvalidIterator =
false;
5117 bool NeedRParenForLinear =
false;
5121 bool ParsedAdjustArgsList =
false;
5122 bool InvalidAdjustArgsList =
false;
5124 tok::annot_pragma_openmp_end);
5126 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
5127 Kind == OMPC_in_reduction) {
5129 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
5130 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
5133 Data.ExtraModifier =
5135 Data.ExtraModifierLoc = Tok.getLocation();
5137 assert(Tok.is(tok::comma) &&
"Expected comma.");
5141 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
5142 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
5148 if (Tok.is(tok::kw_private)) {
5149 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
5150 Data.OriginalSharingModifierLoc = Tok.getLocation();
5152 }
else if (Tok.is(tok::identifier) &&
5153 (PP.getSpelling(Tok) ==
"shared" ||
5154 PP.getSpelling(Tok) ==
"default")) {
5155 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
5156 Data.OriginalSharingModifierLoc = Tok.getLocation();
5159 Diag(Tok.getLocation(), diag::err_expected)
5160 <<
"'private or shared or default'";
5165 if (!Tok.is(tok::comma)) {
5166 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
5173 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
5178 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
5179 if (InvalidReductionId) {
5180 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5183 if (Tok.is(tok::colon))
5186 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
5187 if (!InvalidReductionId)
5188 Data.ReductionOrMapperId =
5189 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
5190 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
5192 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
5201 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
5202 Data.DepModOrTailExpr = IteratorRes.
get();
5204 ExpectAndConsume(tok::comma);
5210 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5212 Data.ExtraModifierLoc = Tok.getLocation();
5214 (Kind == OMPC_doacross &&
5216 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5221 if (DKind == OMPD_ordered_standalone && Kind == OMPC_depend &&
5222 Data.ExtraModifier == OMPC_DEPEND_source) {
5228 if (Tok.is(tok::colon)) {
5230 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
5231 Diag(Tok, DKind == OMPD_ordered_standalone
5232 ? diag::warn_pragma_expected_colon_r_paren
5233 : diag::warn_pragma_expected_colon)
5234 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
5236 if (Kind == OMPC_doacross) {
5237 if (Tok.is(tok::identifier) &&
5238 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
5239 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
5240 ? OMPC_DOACROSS_source_omp_cur_iteration
5241 : OMPC_DOACROSS_sink_omp_cur_iteration;
5244 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
5245 if (Tok.isNot(tok::minus)) {
5246 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5247 << getOpenMPClauseName(Kind) << 0 << 0;
5254 if (Tok.isNot(tok::numeric_constant) ||
5255 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
5256 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
5257 << getOpenMPClauseName(Kind) << 0 << 0;
5263 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
5264 if (Tok.isNot(tok::r_paren)) {
5265 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5266 << getOpenMPClauseName(Kind) << 1 << 1;
5272 if (Kind == OMPC_doacross &&
5273 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
5274 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
5275 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
5281 }
else if (Kind == OMPC_linear) {
5283 Data.ExtraModifier = OMPC_LINEAR_val;
5284 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
5285 Data.ExtraModifier =
5289 NeedRParenForLinear =
true;
5291 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
5292 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
5293 <<
"linear(list: [linear-modifier,] step(step-size))";
5295 }
else if (Kind == OMPC_lastprivate) {
5302 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
5303 Data.ExtraModifier =
5305 Data.ExtraModifierLoc = Tok.getLocation();
5307 assert(Tok.is(tok::colon) &&
"Expected colon.");
5310 }
else if (Kind == OMPC_map) {
5312 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
5315 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
5316 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
5317 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
5318 Data.IteratorExpr = IteratorRes.
get();
5320 ExpectAndConsume(tok::comma);
5322 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
5325 InvalidIterator =
true;
5335 Data.ExtraModifierLoc = Tok.getLocation();
5338 TentativeParsingAction TPA(*
this);
5339 bool ColonPresent =
false;
5340 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5342 if (Tok.is(tok::colon))
5343 ColonPresent =
true;
5350 Diag(Tok, diag::err_omp_map_modifier_specification_list);
5352 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
5358 Data.ExtraModifier = OMPC_MAP_tofrom;
5360 if (DKind == OMPD_target_enter_data)
5361 Data.ExtraModifier = OMPC_MAP_to;
5362 else if (DKind == OMPD_target_exit_data)
5363 Data.ExtraModifier = OMPC_MAP_from;
5365 Data.IsMapTypeImplicit =
true;
5368 if (Tok.is(tok::colon))
5370 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
5371 while (Tok.is(tok::identifier)) {
5376 Data.MotionModifiers.push_back(Modifier);
5377 Data.MotionModifiersLoc.push_back(Tok.getLocation());
5378 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
5380 Tail = ParseOpenMPIteratorsExpr();
5381 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
5384 Data.IteratorExpr = Tail.
get();
5387 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
5389 if (IsInvalidMapperModifier)
5397 if (Tok.is(tok::comma))
5401 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
5402 if (!IsInvalidMapperModifier) {
5404 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
5406 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
5408 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5416 }
else if (Kind == OMPC_allocate ||
5417 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
5418 PP.getSpelling(Tok) ==
"iterator")) {
5422 TentativeParsingAction TPA(*
this);
5427 if (Kind == OMPC_allocate) {
5432 Tail = ParseOpenMPIteratorsExpr();
5434 Tail = Actions.ActOnFinishFullExpr(Tail.
get(),
T.getOpenLocation(),
5437 if (Tok.is(tok::colon)) {
5444 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5445 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5447 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5454 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5457 }
else if (Kind == OMPC_adjust_args) {
5461 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5463 Data.ExtraModifierLoc = Tok.getLocation();
5465 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5470 if (Tok.is(tok::colon))
5471 Data.ColonLoc = Tok.getLocation();
5475 if (Tok.is(tok::l_paren)) {
5478 if (Tok.is(tok::identifier)) {
5479 std::string Modifier = PP.getSpelling(Tok);
5480 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5481 Data.NeedDevicePtrModifier =
5482 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5483 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5485 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5486 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5491 if (Tok.is(tok::r_paren)) {
5492 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5495 Diag(Tok, diag::err_expected) << tok::r_paren;
5496 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5505 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5511 ParsedAdjustArgsList =
true;
5515 }
else if (Kind == OMPC_use_device_ptr) {
5519 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5523 Data.ExtraModifier = FallbackModifier;
5524 Data.ExtraModifierLoc = Tok.getLocation();
5526 if (Tok.is(tok::colon))
5529 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5532 }
else if (Kind == OMPC_num_teams || Kind == OMPC_thread_limit) {
5536 Data.ExtraModifierArray[0] =
Data.ExtraModifierArray[1] =
5541 bool CanParseLowerBoundModifier = (Kind == OMPC_num_teams);
5542 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"dims") &&
5549 Data.ExtraModifierArray[Mod] =
5550 Kind == OMPC_num_teams ?
static_cast<int>(OMPC_NUMTEAMS_dims)
5551 :
static_cast<int>(OMPC_THREADLIMIT_dims);
5552 Data.ExtraModifierExprArray[Mod] = ExprR.
get();
5553 Data.ExtraModifierLocArray[Mod] = TLoc;
5557 if (Tok.is(tok::colon)) {
5560 CanParseLowerBoundModifier =
false;
5561 }
else if (CanParseLowerBoundModifier && Tok.is(tok::comma)) {
5566 Diag(Tok, diag::err_modifier_expected_colon)
5567 << getOpenMPClauseName(Kind);
5569 Data.RLoc = Tok.getLocation();
5570 if (!
T.consumeClose())
5571 Data.RLoc =
T.getCloseLocation();
5577 if (CanParseLowerBoundModifier) {
5578 TentativeParsingAction TPA(*
this);
5583 Data.RLoc = Tok.getLocation();
5584 if (!
T.consumeClose())
5585 Data.RLoc =
T.getCloseLocation();
5590 if (Tok.is(tok::colon)) {
5593 Data.ExtraModifierArray[Mod] = OMPC_NUMTEAMS_lower_bound;
5594 Data.ExtraModifierExprArray[Mod] = FirstExpr.
get();
5595 Data.ExtraModifierLocArray[Mod] = TLoc;
5603 }
else if (Kind == OMPC_num_threads) {
5607 bool HasModifier =
false;
5609 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"dims") &&
5620 Diag(TLoc, diag::err_omp_incompatible_modifiers)
5623 << getOpenMPClauseName(Kind);
5625 Data.ExtraModifierArray[1] =
static_cast<int>(OMPC_NUMTHREADS_dims);
5626 Data.ExtraModifierExprArray[1] =
5628 Data.ExtraModifierLocArray[1] = TLoc;
5635 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5640 Diag(Tok, diag::err_omp_incompatible_modifiers)
5643 Data.ExtraModifierArray[0])
5644 << getOpenMPClauseName(Kind);
5645 Data.ExtraModifierArray[0] = Modifier;
5646 Data.ExtraModifierLocArray[0] = Tok.getLocation();
5656 if (Tok.is(tok::comma))
5664 if (!Tok.is(tok::colon)) {
5665 Diag(Tok, diag::err_modifier_expected_colon)
5666 << getOpenMPClauseName(Kind);
5668 Data.RLoc = Tok.getLocation();
5669 if (!
T.consumeClose())
5670 Data.RLoc =
T.getCloseLocation();
5678 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5679 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5680 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5681 (Kind == OMPC_reduction && !InvalidReductionId) ||
5685 (Kind == OMPC_adjust_args &&
5687 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5688 while (!ParsedAdjustArgsList &&
5689 (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5690 Tok.isNot(tok::annot_pragma_openmp_end)))) {
5697 Vars.push_back(VarExpr.
get());
5699 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5704 IsComma = Tok.is(tok::comma);
5707 else if (Tok.isNot(tok::r_paren) &&
5708 Tok.isNot(tok::annot_pragma_openmp_end) &&
5709 (!MayHaveTail || Tok.isNot(tok::colon))) {
5710 llvm::omp::Version OMPVersion = Actions.getLangOpts().getOpenMPVersion();
5711 Diag(Tok, diag::err_omp_expected_punc)
5712 << ((Kind == OMPC_flush)
5713 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5714 : getOpenMPClauseName(Kind))
5715 << (Kind == OMPC_flush);
5720 if (NeedRParenForLinear)
5724 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5725 bool StepFound =
false;
5726 bool ModifierFound =
false;
5728 Data.ColonLoc = Tok.getLocation();
5731 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5732 bool Malformed =
false;
5733 while (Tok.isNot(tok::r_paren)) {
5734 if (Tok.is(tok::identifier)) {
5739 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5742 if (LinKind == OMPC_LINEAR_step) {
5744 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5747 tok::annot_pragma_openmp_end);
5751 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5756 Data.StepModifierLoc = StepModifierLoc;
5760 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5762 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5764 Data.ExtraModifier = LinKind;
5766 ModifierFound =
true;
5771 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5780 if (Tok.is(tok::comma))
5782 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5785 if (!Malformed && !StepFound && !ModifierFound)
5786 Diag(ELoc, diag::err_expected_expression);
5790 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5793 Data.DepModOrTailExpr = Tail.
get();
5795 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5801 Data.RLoc = Tok.getLocation();
5802 if (!
T.consumeClose())
5803 Data.RLoc =
T.getCloseLocation();
5807 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5808 Vars.empty() && AdjustArgsItems.empty()) ||
5809 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5810 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator ||
5811 InvalidAdjustArgsList;
5839 "Expected parsing to start at clause name");
5844 if (
T.consumeOpen()) {
5845 Diag(
Tok, diag::err_expected) << tok::l_paren;
5858 Exprs.push_back(Val.
get());
5861 bool Result =
T.consumeClose();
5862 OpenLoc =
T.getOpenLocation();
5863 CloseLoc =
T.getCloseLocation();
Defines the clang::ASTContext interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
static OpenMPDirectiveKind checkOpenMPDirectiveName(Parser &P, SourceLocation Loc, OpenMPDirectiveKind Kind, StringRef Name)
static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P)
static OpenMPMapModifierKind isMapModifier(Parser &P)
Checks if the token is a valid map-type-modifier.
static std::optional< SimpleClauseData > parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind)
static bool checkExtensionProperty(Parser &P, SourceLocation Loc, OMPTraitProperty &TIProperty, OMPTraitSelector &TISelector, llvm::StringMap< SourceLocation > &Seen)
static ExprResult parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data)
Parse 'allocate' clause modifiers.
static DeclarationName parseOpenMPReductionId(Parser &P)
static ExprResult parseContextScore(Parser &P)
Parse optional 'score' '(' <expr> ')' ':'.
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, UnqualifiedId &ReductionId)
static bool parseStepSize(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data, OpenMPClauseKind CKind, SourceLocation ELoc)
Parse step size expression.
static void parseMapType(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data)
Parse map-type in map clause.
static bool parseDeclareSimdClauses(Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen, SmallVectorImpl< Expr * > &Uniforms, SmallVectorImpl< Expr * > &Aligneds, SmallVectorImpl< Expr * > &Alignments, SmallVectorImpl< Expr * > &Linears, SmallVectorImpl< unsigned > &LinModifiers, SmallVectorImpl< Expr * > &Steps)
Parses clauses for 'declare simd' directive.
static OpenMPMapClauseKind isMapType(Parser &P)
Checks if the token is a valid map-type.
This file declares semantic analysis functions specific to AMDGPU.
This file declares facilities that support code completion.
This file declares semantic analysis for OpenMP constructs and clauses.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
void getAsVariantMatchInfo(ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const
Create a variant match info object from this trait info object.
llvm::SmallVector< OMPTraitSet, 2 > Sets
The outermost level of selector sets.
bool anyScoreOrCondition(llvm::function_ref< bool(Expr *&, bool)> Cond)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
DeclarationNameTable DeclarationNames
OMPTraitInfo & getNewOMPTraitInfo()
Return a new OMPTraitInfo object owned by this context.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
Represents a C++ nested-name-specifier or a global scope specifier.
bool isEmpty() const
No scope specifier.
static const TST TST_unspecified
Decl - This represents one declaration (or definition), e.g.
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
The name of a declaration.
bool isEmpty() const
Evaluates true when this declaration name is empty.
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
llvm::omp::Version getOpenMPVersion() const
Return the OpenMP version.
This represents a decl that may have a name.
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
This is a basic class for representing single OpenMP clause.
static const ParsedAttributesView & none()
ParsedAttributes - A collection of parsed attributes.
Introduces zero or more scopes for parsing.
void Enter(unsigned ScopeFlags)
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
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.
bool ParseOpenMPAdjustArgsList(SmallVectorImpl< OMPAdjustArgsItem > &Items)
Parses an OpenMP 6.0 'adjust_args' parameter list, whose items may be parameter names,...
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 ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, SmallVectorImpl< Expr * > &Vars, SemaOpenMP::OpenMPVarListDataTy &Data, SmallVectorImpl< OMPAdjustArgsItem > &AdjustArgsItems)
Parses clauses with list.
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
bool ParseOpenMPAdjustArgsBound(OMPAdjustArgsItem::Bound &Bound)
Parses one bound of an OpenMP 6.0 'adjust_args' parameter range, which may be 'omp_num_args' with an ...
void ExitScope()
ExitScope - Pop a scope off the scope stack.
ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc, bool IsAddressOfOperand=false)
Parses simple expression in parens for single-expression clauses of OpenMP constructs.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data, const LangOptions &LangOpts)
Parses a reserved locator like 'omp_all_memory'.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D)
Re-enter a possible template scope, creating as many template parameter scopes as necessary.
bool ParseOpenMPDeclareBeginVariantDirective(SourceLocation Loc)
Parses 'omp begin declare variant' directive.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
The collection of all-type qualifiers we support.
Represents a struct/union/class.
@ OpenMPDirectiveScope
This is the scope of OpenMP executable directive.
@ CompoundStmtScope
This is a compound statement scope.
@ OpenMPSimdDirectiveScope
This is the scope of some OpenMP simd directive.
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ OpenMPLoopDirectiveScope
This is the scope of some OpenMP loop directive.
@ DeclScope
This is a scope that can contain a declaration.
Smart pointer class that efficiently represents Objective-C method names.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
void ActOnExitFunctionContext()
void ActOnReenterFunctionContext(Scope *S, Decl *D)
Push the parameters of D, which must be a function, into scope.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
Token - This structure provides full information about a lexed token.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isNot(tok::TokenKind K) const
Base wrapper for a particular "section" of type source info.
The base class of the type hierarchy.
QualType getCanonicalTypeInternal() const
Represents a C++ unqualified-id that has been parsed.
void setOperatorFunctionId(SourceLocation OperatorLoc, OverloadedOperatorKind Op, SourceLocation SymbolLocations[3])
Specify that this unqualified-id was parsed as an operator-function-id.
Represents a variable declaration or definition.
Defines the clang::TargetInfo interface.
PRESERVE_NONE bool Ret(InterpState &S)
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.
Top level wrappers for InstallAPI frontend operations.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
OpenMPDefaultClauseVariableCategory
OpenMP variable-category for 'default' clause.
@ OMPC_DEFAULTMAP_MODIFIER_unknown
@ OMPC_ORDER_MODIFIER_unknown
OpenMPNeedDevicePtrModifier
OpenMP 6.1 need_device modifier.
@ OMPC_NEED_DEVICE_PTR_unknown
OpenMPAdjustArgsOpKind
OpenMP adjust-op kinds for 'adjust_args' clause.
@ OMPC_ADJUST_ARGS_unknown
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
OpenMPDeviceType
OpenMP device type for 'device_type' clause.
@ OMPC_DEVICE_TYPE_unknown
@ OMPC_SCHEDULE_MODIFIER_unknown
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
@ OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown
@ OMPC_DYN_GROUPPRIVATE_FALLBACK_last
@ Property
The type of a property.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ OMPC_LASTPRIVATE_unknown
OpenMPGrainsizeClauseModifier
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str, const LangOptions &LangOpts)
OpenMPNumTasksClauseModifier
OpenMPUseDevicePtrFallbackModifier
OpenMP 6.1 use_device_ptr fallback modifier.
@ OMPC_USE_DEVICE_PTR_FALLBACK_unknown
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OpenMPMotionModifierKind
OpenMP modifier kind for 'to' or 'from' clause.
@ OMPC_MOTION_MODIFIER_unknown
@ OMPC_DEFAULTMAP_unknown
OpenMPAllocateClauseModifier
OpenMP modifiers for 'allocate' clause.
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "executable".
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
@ OMPC_DYN_GROUPPRIVATE_unknown
bool isOpenMPInformationalDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "informational".
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
@ OMPC_THREADLIMIT_unknown
OpenMPNumThreadsClauseModifier
@ OMPC_NUMTHREADS_unknown
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
@ OMPC_MAP_MODIFIER_unknown
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
ActionResult< Expr * > ExprResult
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
ActionResult< Stmt * > StmtResult
OpenMPDefaultClauseVariableCategory getOpenMPDefaultVariableCategory(StringRef Str, const LangOptions &LangOpts)
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
int const char * function
llvm::omp::TraitProperty Kind
StringRef RawString
The raw string as we parsed it. This is needed for the isa trait set (which accepts anything) and (la...
llvm::omp::TraitSelector Kind
SmallVector< OMPTraitProperty, 1 > Properties
SmallVector< OMPTraitSelector, 2 > Selectors
Clang specific specialization of the OMPContext to lookup target features.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
One bound of a parameter range.
Expr * E
The bound expression, or the logical offset for a NumArgs bound.
One item in an OpenMP 'adjust_args' parameter list.
Expr * E
A named parameter or positional expression for a Single item.
llvm::SmallVector< OMPInteropPref, 4 > Prefs
This structure contains most locations needed for by an OMPVarListClause.
std::optional< Expr * > Indirect
The directive with indirect clause.
OpenMPDirectiveKind Kind
The directive kind, begin declare target or declare target.
OMPDeclareTargetDeclAttr::DevTypeTy DT
The 'device_type' as parsed from the clause.
SourceLocation Loc
The directive location.
llvm::DenseMap< NamedDecl *, MapInfo > ExplicitlyMapped
Explicitly listed variables and functions in a 'to' or 'link' clause.
SourceLocation DeclIdentLoc
SourceLocation SecColonLoc
IdentifierInfo * DeclIdent
OMPIteratorExpr::IteratorRange Range
Data used for processing a list of variables in OpenMP clauses.
Data for list of allocators.
Expr * AllocatorTraits
Allocator traits.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Expr * Allocator
Allocator.