26#include "llvm/ADT/SmallBitVector.h"
27#include "llvm/ADT/StringSwitch.h"
28#include "llvm/Frontend/OpenMP/DirectiveNameParser.h"
29#include "llvm/Frontend/OpenMP/OMPAssume.h"
30#include "llvm/Frontend/OpenMP/OMPContext.h"
35using namespace llvm::omp;
42class DeclDirectiveListParserHelper final {
43 SmallVector<Expr *, 4> Identifiers;
50 void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
51 ExprResult Res = P->getActions().OpenMP().ActOnOpenMPIdExpression(
52 P->getCurScope(), SS, NameInfo, Kind);
54 Identifiers.push_back(Res.
get());
56 llvm::ArrayRef<Expr *> getIdentifiers()
const {
return Identifiers; }
65 auto [D, VR] = getOpenMPDirectiveKindAndVersions(Name);
66 assert(D == Kind &&
"Directive kind mismatch");
69 if (
static_cast<int>(Version) < VR.Min)
70 P.
Diag(Loc, diag::warn_omp_future_directive_spelling) << Name;
76 static const DirectiveNameParser DirParser;
78 const DirectiveNameParser::State *S = DirParser.initial();
81 if (
Tok.isAnnotation())
87 S = DirParser.consume(S, Concat);
91 while (!
Tok.isAnnotation()) {
94 if (!
Tok.isAnnotation()) {
96 S = DirParser.consume(S, TS);
104 assert(S &&
"Should have exited early");
113 bool WithOperator =
false;
114 if (
Tok.is(tok::kw_operator)) {
119 switch (
Tok.getKind()) {
144 case tok::identifier:
149 P.
Diag(
Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
150 P.
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
156 return OOK ==
OO_None ? DeclNames.getIdentifier(
Tok.getIdentifierInfo())
157 : DeclNames.getCXXOperatorName(OOK);
162 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
165 if (T.expectAndConsume(
166 diag::err_expected_lparen_after,
167 getOpenMPDirectiveName(OMPD_declare_reduction, OMPVersion).data())) {
173 if (Name.
isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
177 bool IsCorrect = !ExpectAndConsume(tok::colon);
179 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
182 IsCorrect = IsCorrect && !Name.
isEmpty();
184 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
185 Diag(Tok.getLocation(), diag::err_expected_type);
189 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
192 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
199 QualType ReductionType = Actions.OpenMP().ActOnOpenMPDeclareReductionType(
200 Range.getBegin(), TR);
201 if (!ReductionType.
isNull()) {
202 ReductionTypes.push_back(
203 std::make_pair(ReductionType,
Range.getBegin()));
206 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
210 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
214 if (ExpectAndConsume(tok::comma)) {
216 if (Tok.is(tok::annot_pragma_openmp_end)) {
217 Diag(Tok.getLocation(), diag::err_expected_type);
221 }
while (Tok.isNot(tok::annot_pragma_openmp_end));
223 if (ReductionTypes.empty()) {
228 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
232 if (ExpectAndConsume(tok::colon))
235 if (Tok.is(tok::annot_pragma_openmp_end)) {
236 Diag(Tok.getLocation(), diag::err_expected_expression);
241 Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveStart(
242 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes,
247 unsigned I = 0, E = ReductionTypes.size();
248 for (Decl *D : DRD.get()) {
249 TentativeParsingAction TPA(*
this);
254 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerStart(
getCurScope(), D);
255 ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
257 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerEnd(
258 D, CombinerResult.
get());
260 if (CombinerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
261 Tok.isNot(tok::annot_pragma_openmp_end)) {
266 IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.
isUsable();
268 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
270 if (Tok.is(tok::identifier) &&
271 Tok.getIdentifierInfo()->isStr(
"initializer")) {
274 Diag(Tok.getLocation(), diag::err_expected) <<
"'initializer'";
281 tok::annot_pragma_openmp_end);
283 !T.expectAndConsume(diag::err_expected_lparen_after,
"initializer") &&
285 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
290 VarDecl *OmpPrivParm =
291 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerStart(
294 if (Tok.is(tok::identifier) &&
295 Tok.getIdentifierInfo()->isStr(
"omp_priv")) {
297 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
299 InitializerResult = Actions.ActOnFinishFullExpr(
303 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerEnd(
304 D, InitializerResult.
get(), OmpPrivParm);
305 if (InitializerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
306 Tok.isNot(tok::annot_pragma_openmp_end)) {
312 !T.consumeClose() && IsCorrect && !InitializerResult.
isInvalid();
324 return Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveEnd(
328void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
331 if (isTokenEqualOrEqualTypo()) {
334 if (Tok.is(tok::code_completion)) {
336 Actions.CodeCompletion().CodeCompleteInitializer(
getCurScope(),
338 Actions.FinalizeDeclaration(OmpPrivParm);
342 PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
345 if (
Init.isInvalid()) {
347 Actions.ActOnInitializerError(OmpPrivParm);
349 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
352 }
else if (Tok.is(tok::l_paren)) {
359 SourceLocation LParLoc = T.getOpenLocation();
360 auto RunSignatureHelp = [
this, OmpPrivParm, LParLoc, &Exprs]() {
361 QualType PreferredType =
362 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
364 OmpPrivParm->
getLocation(), Exprs, LParLoc,
false);
365 CalledSignatureHelp =
true;
366 return PreferredType;
368 if (ParseExpressionList(Exprs, [&] {
369 PreferredType.enterFunctionArgument(Tok.getLocation(),
372 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
374 Actions.ActOnInitializerError(OmpPrivParm);
378 SourceLocation RLoc = Tok.getLocation();
379 if (!T.consumeClose())
380 RLoc = T.getCloseLocation();
383 Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
384 Actions.AddInitializerToDecl(OmpPrivParm,
Initializer.get(),
389 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
393 if (
Init.isInvalid()) {
394 Actions.ActOnInitializerError(OmpPrivParm);
396 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
400 Actions.ActOnUninitializedDecl(OmpPrivParm);
406 bool IsCorrect =
true;
407 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
410 if (T.expectAndConsume(
411 diag::err_expected_lparen_after,
412 getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion).data())) {
418 auto &DeclNames = Actions.getASTContext().DeclarationNames;
419 DeclarationName MapperId;
420 if (PP.LookAhead(0).is(tok::colon)) {
421 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
422 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
425 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
429 ExpectAndConsume(tok::colon);
433 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get(
"default"));
436 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
440 DeclarationName VName;
445 MapperType = Actions.OpenMP().ActOnOpenMPDeclareMapperType(
Range.getBegin(),
455 IsCorrect &= !T.consumeClose();
463 DeclarationNameInfo DirName;
464 SourceLocation Loc = Tok.getLocation();
467 ParseScope OMPDirectiveScope(
this, ScopeFlags);
468 Actions.OpenMP().StartOpenMPDSABlock(OMPD_declare_mapper, DirName,
473 Actions.OpenMP().ActOnOpenMPDeclareMapperDirectiveVarDecl(
477 SmallVector<OMPClause *, 6> Clauses;
478 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
481 : getOpenMPClauseKind(PP.getSpelling(Tok));
482 Actions.OpenMP().StartOpenMPClause(CKind);
484 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
486 Clauses.push_back(Clause);
490 if (Tok.is(tok::comma))
492 Actions.OpenMP().EndOpenMPClause();
494 if (Clauses.empty()) {
495 Diag(Tok, diag::err_omp_expected_clause)
496 << getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion);
505 DeclGroupPtrTy DG = Actions.OpenMP().ActOnOpenMPDeclareMapperDirective(
506 OuterScope, Actions.getCurLexicalContext(), MapperId, MapperType,
507 Range.getBegin(), VName, AS, MapperVarRef.
get(), Clauses);
509 Actions.OpenMP().EndOpenMPDSABlock(
nullptr);
510 OMPDirectiveScope.Exit();
521 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
522 DeclSpec DS(AttrFactory);
523 ParseSpecifierQualifierList(DS, AS, DSC);
528 ParseDeclarator(DeclaratorInfo);
529 Range = DeclaratorInfo.getSourceRange();
530 if (DeclaratorInfo.getIdentifier() ==
nullptr) {
531 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
534 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
536 return Actions.OpenMP().ActOnOpenMPDeclareMapperVarDecl(
getCurScope(),
548 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
551 if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
555 (void)ConsumeAnnotationToken();
560 skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
564 VariantMatchInfo VMI;
568 Loc](StringRef ISATrait) {
571 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
574 ASTCtx, std::move(DiagUnknownTrait),
577 Actions.OpenMP().getOpenMPDeviceNum());
579 if (isVariantApplicableInContext(VMI, OMPCtx,
581 Actions.OpenMP().ActOnOpenMPBeginDeclareVariant(Loc, TI);
586 unsigned Nesting = 1;
590 DKLoc = Tok.getLocation();
592 if (DK == OMPD_end_declare_variant)
594 else if (DK == OMPD_begin_declare_variant)
596 if (!Nesting || isEofOrEom())
601 parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant, DK,
612class FNContextRAII final {
616 bool HasFunScope =
false;
617 FNContextRAII() =
delete;
618 FNContextRAII(
const FNContextRAII &) =
delete;
619 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
666 bool IsError =
false;
667 while (
Tok.isNot(tok::annot_pragma_openmp_end)) {
668 if (
Tok.isNot(tok::identifier))
670 OMPDeclareSimdDeclAttr::BranchStateTy Out;
672 StringRef ClauseName = II->
getName();
674 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
675 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
676 P.
Diag(
Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
678 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
684 }
else if (ClauseName ==
"simdlen") {
687 P.
Diag(
Tok, diag::err_omp_more_one_clause)
688 << getOpenMPDirectiveName(OMPD_declare_simd, OMPVersion)
699 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
700 CKind == OMPC_linear) {
703 if (CKind == OMPC_aligned) {
705 }
else if (CKind == OMPC_linear) {
706 Data.ExtraModifier = OMPC_LINEAR_val;
712 getOpenMPClauseKind(ClauseName), *Vars,
Data))
714 if (CKind == OMPC_aligned) {
715 Alignments.append(Aligneds.size() - Alignments.size(),
716 Data.DepModOrTailExpr);
717 }
else if (CKind == OMPC_linear) {
718 assert(0 <=
Data.ExtraModifier &&
720 "Unexpected linear modifier.");
723 Data.ExtraModifierLoc))
724 Data.ExtraModifier = OMPC_LINEAR_val;
725 LinModifiers.append(Linears.size() - LinModifiers.size(),
727 Steps.append(Linears.size() - Steps.size(),
Data.DepModOrTailExpr);
734 if (
Tok.is(tok::comma))
743 PP.EnterToken(Tok,
true);
744 PP.EnterTokenStream(Toks,
true,
750 FNContextRAII FnContext(*
this, Ptr);
751 OMPDeclareSimdDeclAttr::BranchStateTy BS =
752 OMPDeclareSimdDeclAttr::BS_Undefined;
754 SmallVector<Expr *, 4> Uniforms;
755 SmallVector<Expr *, 4> Aligneds;
756 SmallVector<Expr *, 4> Alignments;
757 SmallVector<Expr *, 4> Linears;
758 SmallVector<unsigned, 4> LinModifiers;
759 SmallVector<Expr *, 4> Steps;
762 Alignments, Linears, LinModifiers, Steps);
763 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
765 SourceLocation EndLoc = ConsumeAnnotationToken();
768 return Actions.OpenMP().ActOnOpenMPDeclareSimdDirective(
769 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
770 LinModifiers, Steps, SourceRange(Loc, EndLoc));
777 CONTEXT_SELECTOR_SET_LVL = 0,
778 CONTEXT_SELECTOR_LVL = 1,
779 CONTEXT_TRAIT_LVL = 2,
782static StringRef stringLiteralParser(
Parser &P) {
789 if (
Tok.
is(tok::identifier) ||
Tok.
is(tok::kw_for)) {
797 return stringLiteralParser(P);
800 diag::warn_omp_declare_variant_string_literal_or_identifier)
805static bool checkForDuplicates(
Parser &P, StringRef Name,
807 llvm::StringMap<SourceLocation> &Seen,
809 auto Res = Seen.try_emplace(Name, NameLoc);
815 P.
Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
817 P.
Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
823void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
824 llvm::omp::TraitSet
Set,
826 llvm::StringMap<SourceLocation> &Seen) {
827 TIProperty.
Kind = TraitProperty::invalid;
829 SourceLocation NameLoc = Tok.getLocation();
831 if (Selector == llvm::omp::TraitSelector::target_device_device_num) {
833 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
835 if (DeviceNumExprResult.
isUsable()) {
836 Expr *DeviceNumExpr = DeviceNumExprResult.
get();
837 Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr);
841 Name = getNameFromIdOrString(*
this, Tok, CONTEXT_TRAIT_LVL);
843 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
844 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
849 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
850 if (TIProperty.
Kind != TraitProperty::invalid) {
851 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
852 TIProperty.
Kind = TraitProperty::invalid;
858 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
859 << Name << getOpenMPContextTraitSelectorName(Selector)
860 << getOpenMPContextTraitSetName(
Set);
862 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
863 if (SetForName != TraitSet::invalid) {
864 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
865 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
866 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
867 << Name <<
"<selector-name>"
868 <<
"(<property-name>)";
871 TraitSelector SelectorForName =
872 getOpenMPContextTraitSelectorKind(Name, SetForName);
873 if (SelectorForName != TraitSelector::invalid) {
874 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
875 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
876 bool AllowsTraitScore =
false;
877 bool RequiresProperty =
false;
878 isValidTraitSelectorForTraitSet(
879 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
880 AllowsTraitScore, RequiresProperty);
881 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
882 << getOpenMPContextTraitSetName(
883 getOpenMPContextTraitSetForSelector(SelectorForName))
884 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
887 for (
const auto &PotentialSet :
888 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
889 TraitSet::device, TraitSet::target_device}) {
890 TraitProperty PropertyForName =
891 getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
892 if (PropertyForName == TraitProperty::invalid)
894 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
895 << getOpenMPContextTraitSetName(
896 getOpenMPContextTraitSetForProperty(PropertyForName))
897 << getOpenMPContextTraitSelectorName(
898 getOpenMPContextTraitSelectorForProperty(PropertyForName))
899 << (
"(" + Name +
")").str();
902 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
903 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
909 llvm::StringMap<SourceLocation> &Seen) {
910 assert(TISelector.
Kind ==
911 llvm::omp::TraitSelector::implementation_extension &&
912 "Only for extension properties, e.g., "
913 "`implementation={extension(PROPERTY)}`");
914 if (TIProperty.
Kind == TraitProperty::invalid)
917 if (TIProperty.
Kind ==
918 TraitProperty::implementation_extension_disable_implicit_base)
921 if (TIProperty.
Kind ==
922 TraitProperty::implementation_extension_allow_templates)
925 if (TIProperty.
Kind ==
926 TraitProperty::implementation_extension_bind_to_declaration)
931 llvm::omp::TraitProperty::implementation_extension_match_all ||
933 llvm::omp::TraitProperty::implementation_extension_match_any ||
935 llvm::omp::TraitProperty::implementation_extension_match_none);
938 if (IsMatchExtension(TIProperty)) {
940 if (IsMatchExtension(SeenProp)) {
941 P.
Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
942 StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
945 P.
Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
946 << CONTEXT_TRAIT_LVL << SeenName;
952 llvm_unreachable(
"Unknown extension property!");
955void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
956 llvm::omp::TraitSet
Set,
957 llvm::StringMap<SourceLocation> &Seen) {
958 assert(TISelector.
Kind != TraitSelector::user_condition &&
959 "User conditions are special properties not handled here!");
961 SourceLocation PropertyLoc = Tok.getLocation();
962 OMPTraitProperty TIProperty;
963 parseOMPTraitPropertyKind(TIProperty,
Set, TISelector.
Kind, Seen);
965 if (TISelector.
Kind == llvm::omp::TraitSelector::implementation_extension)
968 TIProperty.
Kind = TraitProperty::invalid;
971 if (TIProperty.
Kind == TraitProperty::invalid) {
972 if (PropertyLoc != Tok.getLocation())
973 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
974 << CONTEXT_TRAIT_LVL;
978 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.
Kind,
987 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
988 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
990 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
991 << getOpenMPContextTraitSetName(
Set);
992 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
993 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
995 << getOpenMPContextTraitSelectorName(
996 getOpenMPContextTraitSelectorForProperty(TIProperty.
Kind))
997 << getOpenMPContextTraitSetName(
998 getOpenMPContextTraitSetForProperty(TIProperty.
Kind));
999 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1000 << CONTEXT_TRAIT_LVL;
1003void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
1004 llvm::omp::TraitSet
Set,
1005 llvm::StringMap<SourceLocation> &Seen) {
1006 TISelector.
Kind = TraitSelector::invalid;
1008 SourceLocation NameLoc = Tok.getLocation();
1009 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_LVL);
1011 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1012 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1016 TISelector.
Kind = getOpenMPContextTraitSelectorKind(Name,
Set);
1017 if (TISelector.
Kind != TraitSelector::invalid) {
1018 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1019 TISelector.
Kind = TraitSelector::invalid;
1024 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1025 << Name << getOpenMPContextTraitSetName(
Set);
1027 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1028 if (SetForName != TraitSet::invalid) {
1029 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1030 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1031 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1032 << Name <<
"<selector-name>"
1033 <<
"<property-name>";
1036 for (
const auto &PotentialSet :
1037 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1038 TraitSet::device, TraitSet::target_device}) {
1039 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1040 PotentialSet, TraitSelector::invalid, Name);
1041 if (PropertyForName == TraitProperty::invalid)
1043 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1044 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1045 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1046 << getOpenMPContextTraitSetName(
1047 getOpenMPContextTraitSetForProperty(PropertyForName))
1048 << getOpenMPContextTraitSelectorName(
1049 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1050 << (
"(" + Name +
")").str();
1053 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1054 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1061 StringRef SelectorName =
1063 if (SelectorName !=
"score")
1074 <<
"score expression";
1078void Parser::parseOMPContextSelector(
1079 OMPTraitSelector &TISelector, llvm::omp::TraitSet
Set,
1080 llvm::StringMap<SourceLocation> &SeenSelectors) {
1081 unsigned short OuterPC = ParenCount;
1086 auto FinishSelector = [OuterPC,
this]() ->
void {
1089 while (!
SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1090 tok::annot_pragma_openmp_end},
1093 if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1094 (void)ConsumeParen();
1095 if (OuterPC <= ParenCount) {
1099 if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1105 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1106 << CONTEXT_SELECTOR_LVL;
1109 SourceLocation SelectorLoc = Tok.getLocation();
1110 parseOMPTraitSelectorKind(TISelector,
Set, SeenSelectors);
1111 if (TISelector.
Kind == TraitSelector::invalid)
1112 return FinishSelector();
1114 bool AllowsTraitScore =
false;
1115 bool RequiresProperty =
false;
1116 if (!isValidTraitSelectorForTraitSet(TISelector.
Kind,
Set, AllowsTraitScore,
1117 RequiresProperty)) {
1118 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1119 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1120 << getOpenMPContextTraitSetName(
Set);
1121 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1122 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1123 << getOpenMPContextTraitSetName(
1124 getOpenMPContextTraitSetForSelector(TISelector.
Kind))
1125 << RequiresProperty;
1126 return FinishSelector();
1129 if (!RequiresProperty) {
1131 {getOpenMPContextTraitPropertyForSelector(TISelector.
Kind),
1132 getOpenMPContextTraitSelectorName(TISelector.
Kind)});
1136 if (!Tok.is(tok::l_paren)) {
1137 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1138 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1139 << getOpenMPContextTraitSetName(
Set);
1140 return FinishSelector();
1143 if (TISelector.
Kind == TraitSelector::user_condition) {
1144 SourceLocation RLoc;
1147 return FinishSelector();
1150 {TraitProperty::user_condition_unknown,
"<condition>"});
1155 tok::annot_pragma_openmp_end);
1157 (void)BDT.consumeOpen();
1159 SourceLocation ScoreLoc = Tok.getLocation();
1162 if (!AllowsTraitScore && !Score.
isUnset()) {
1164 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1165 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1166 << getOpenMPContextTraitSetName(
Set) << Score.
get();
1168 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1169 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1170 << getOpenMPContextTraitSetName(
Set) <<
"<invalid>";
1178 llvm::StringMap<SourceLocation> SeenProperties;
1180 parseOMPContextProperty(TISelector,
Set, SeenProperties);
1187void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1188 llvm::StringMap<SourceLocation> &Seen) {
1189 TISet.
Kind = TraitSet::invalid;
1191 SourceLocation NameLoc = Tok.getLocation();
1192 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_SET_LVL);
1194 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1195 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1199 TISet.
Kind = getOpenMPContextTraitSetKind(Name);
1200 if (TISet.
Kind != TraitSet::invalid) {
1201 if (checkForDuplicates(*
this, Name, NameLoc, Seen,
1202 CONTEXT_SELECTOR_SET_LVL))
1203 TISet.
Kind = TraitSet::invalid;
1208 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1210 TraitSelector SelectorForName =
1211 getOpenMPContextTraitSelectorKind(Name, TISet.
Kind);
1212 if (SelectorForName != TraitSelector::invalid) {
1213 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1214 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1215 bool AllowsTraitScore =
false;
1216 bool RequiresProperty =
false;
1217 isValidTraitSelectorForTraitSet(
1218 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1219 AllowsTraitScore, RequiresProperty);
1220 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1221 << getOpenMPContextTraitSetName(
1222 getOpenMPContextTraitSetForSelector(SelectorForName))
1223 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
1226 for (
const auto &PotentialSet :
1227 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1228 TraitSet::device, TraitSet::target_device}) {
1229 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1230 PotentialSet, TraitSelector::invalid, Name);
1231 if (PropertyForName == TraitProperty::invalid)
1233 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1234 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1235 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1236 << getOpenMPContextTraitSetName(
1237 getOpenMPContextTraitSetForProperty(PropertyForName))
1238 << getOpenMPContextTraitSelectorName(
1239 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1240 << (
"(" + Name +
")").str();
1243 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1244 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1247void Parser::parseOMPContextSelectorSet(
1248 OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1249 auto OuterBC = BraceCount;
1254 auto FinishSelectorSet = [
this, OuterBC]() ->
void {
1257 while (!
SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1258 tok::annot_pragma_openmp_end},
1261 if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1262 (void)ConsumeBrace();
1263 if (OuterBC <= BraceCount) {
1267 if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1273 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1274 << CONTEXT_SELECTOR_SET_LVL;
1277 parseOMPTraitSetKind(TISet, SeenSets);
1278 if (TISet.
Kind == TraitSet::invalid)
1279 return FinishSelectorSet();
1283 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1285 << (
"context set name \"" + getOpenMPContextTraitSetName(TISet.
Kind) +
1289 if (Tok.is(tok::l_brace)) {
1290 (void)ConsumeBrace();
1292 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1294 << (
"'=' that follows the context set name \"" +
1295 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1299 llvm::StringMap<SourceLocation> SeenSelectors;
1301 OMPTraitSelector TISelector;
1302 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1303 if (TISelector.
Kind != TraitSelector::invalid &&
1309 if (Tok.is(tok::r_brace)) {
1310 (void)ConsumeBrace();
1312 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1314 << (
"context selectors for the context set \"" +
1315 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1320bool Parser::parseOMPContextSelectors(
SourceLocation Loc, OMPTraitInfo &TI) {
1321 llvm::StringMap<SourceLocation> SeenSets;
1324 parseOMPContextSelectorSet(TISet, SeenSets);
1325 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1326 TI.
Sets.push_back(TISet);
1335 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1336 PP.EnterToken(Tok,
true);
1337 PP.EnterTokenStream(Toks,
true,
1343 FNContextRAII FnContext(*
this, Ptr);
1345 SourceLocation RLoc;
1355 getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion), RLoc,
1358 if (!AssociatedFunction.
isUsable()) {
1359 if (!Tok.is(tok::annot_pragma_openmp_end))
1363 (void)ConsumeAnnotationToken();
1367 OMPTraitInfo *ParentTI =
1368 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
1369 ASTContext &ASTCtx = Actions.getASTContext();
1371 SmallVector<Expr *, 6> AdjustNothing;
1372 SmallVector<Expr *, 6> AdjustNeedDevicePtr;
1373 SmallVector<Expr *, 6> AdjustNeedDeviceAddr;
1374 SmallVector<OMPInteropInfo, 3> AppendArgs;
1375 SourceLocation AdjustArgsLoc, AppendArgsLoc;
1378 if (Tok.is(tok::annot_pragma_openmp_end)) {
1379 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1383 bool IsError =
false;
1384 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1387 : getOpenMPClauseKind(PP.getSpelling(Tok));
1388 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1390 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1397 IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1399 case OMPC_adjust_args: {
1400 AdjustArgsLoc = Tok.getLocation();
1402 SemaOpenMP::OpenMPVarListDataTy
Data;
1403 SmallVector<Expr *> Vars;
1407 switch (
Data.ExtraModifier) {
1408 case OMPC_ADJUST_ARGS_nothing:
1409 llvm::append_range(AdjustNothing, Vars);
1411 case OMPC_ADJUST_ARGS_need_device_ptr:
1412 llvm::append_range(AdjustNeedDevicePtr, Vars);
1414 case OMPC_ADJUST_ARGS_need_device_addr:
1415 llvm::append_range(AdjustNeedDeviceAddr, Vars);
1418 llvm_unreachable(
"Unexpected 'adjust_args' clause modifier.");
1423 case OMPC_append_args:
1424 if (!AppendArgs.empty()) {
1425 Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1426 << getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion)
1427 << getOpenMPClauseName(CKind) << 0;
1431 AppendArgsLoc = Tok.getLocation();
1433 IsError = parseOpenMPAppendArgs(AppendArgs);
1437 llvm_unreachable(
"Unexpected clause for declare variant.");
1444 (void)ConsumeAnnotationToken();
1448 if (Tok.is(tok::comma))
1452 std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1453 Actions.OpenMP().checkOpenMPDeclareVariantFunction(
1454 Ptr, AssociatedFunction.
get(), TI, AppendArgs.size(),
1455 SourceRange(Loc, Tok.getLocation()));
1457 if (DeclVarData && !TI.
Sets.empty())
1458 Actions.OpenMP().ActOnOpenMPDeclareVariantDirective(
1459 DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1460 AdjustNeedDevicePtr, AdjustNeedDeviceAddr, AppendArgs, AdjustArgsLoc,
1461 AppendArgsLoc, SourceRange(Loc, Tok.getLocation()));
1464 (void)ConsumeAnnotationToken();
1467bool Parser::parseOpenMPAppendArgs(
1469 bool HasError =
false;
1472 if (T.expectAndConsume(diag::err_expected_lparen_after,
1473 getOpenMPClauseName(OMPC_append_args).data()))
1478 while (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"interop")) {
1481 tok::annot_pragma_openmp_end);
1482 if (IT.expectAndConsume(diag::err_expected_lparen_after,
"interop"))
1485 OMPInteropInfo InteropInfo;
1486 if (ParseOMPInteropInfo(InteropInfo, OMPC_append_args))
1489 InteropInfos.push_back(InteropInfo);
1492 if (Tok.is(tok::comma))
1495 if (!HasError && InteropInfos.empty()) {
1497 Diag(Tok.getLocation(), diag::err_omp_unexpected_append_op);
1498 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1501 HasError = T.consumeClose() || HasError;
1505bool Parser::parseOMPDeclareVariantMatchClause(
SourceLocation Loc,
1507 OMPTraitInfo *ParentTI) {
1511 : getOpenMPClauseKind(PP.getSpelling(Tok));
1512 if (CKind != OMPC_match) {
1513 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1520 if (T.expectAndConsume(diag::err_expected_lparen_after,
1521 getOpenMPClauseName(OMPC_match).data()))
1525 parseOMPContextSelectors(Loc, TI);
1528 (void)T.consumeClose();
1538 for (
const OMPTraitSet &ParentSet : ParentTI->
Sets) {
1539 bool MergedSet =
false;
1540 for (OMPTraitSet &
Set : TI.
Sets) {
1541 if (
Set.Kind != ParentSet.
Kind)
1544 for (
const OMPTraitSelector &ParentSelector : ParentSet.
Selectors) {
1545 bool MergedSelector =
false;
1546 for (OMPTraitSelector &Selector :
Set.Selectors) {
1547 if (Selector.
Kind != ParentSelector.
Kind)
1549 MergedSelector =
true;
1550 for (
const OMPTraitProperty &ParentProperty :
1552 bool MergedProperty =
false;
1566 if (Selector.
Kind == llvm::omp::TraitSelector::user_condition) {
1567 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1570 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1571 << getOpenMPContextTraitPropertyName(
1573 << getOpenMPContextTraitSelectorName(ParentSelector.
Kind)
1574 << getOpenMPContextTraitSetName(ParentSet.
Kind);
1577 if (!MergedProperty)
1578 Selector.
Properties.push_back(ParentProperty);
1581 if (!MergedSelector)
1582 Set.Selectors.push_back(ParentSelector);
1586 TI.
Sets.push_back(ParentSet);
1595 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
1596 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1599 : getOpenMPClauseKind(PP.getSpelling(Tok));
1600 Actions.OpenMP().StartOpenMPClause(CKind);
1602 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
1603 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1605 SeenClauses[unsigned(CKind)] =
true;
1606 if (Clause !=
nullptr)
1607 Clauses.push_back(Clause);
1608 if (Tok.is(tok::annot_pragma_openmp_end)) {
1609 Actions.OpenMP().EndOpenMPClause();
1613 if (Tok.is(tok::comma))
1615 Actions.OpenMP().EndOpenMPClause();
1621 SmallVector<std::string, 4> Assumptions;
1622 bool SkippedClauses =
false;
1624 auto SkipBraces = [&](llvm::StringRef Spelling,
bool IssueNote) {
1626 tok::annot_pragma_openmp_end);
1627 if (T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1630 if (IssueNote && T.getCloseLocation().isValid())
1631 Diag(T.getCloseLocation(),
1632 diag::note_omp_assumption_clause_continue_here);
1638 auto MatchACMClause = [&](StringRef RawString) {
1639 llvm::StringSwitch<int> SS(RawString);
1640 unsigned ACMIdx = 0;
1641 for (
const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1642 if (ACMI.StartsWith)
1643 SS.StartsWith(ACMI.Identifier, ACMIdx++);
1645 SS.Case(ACMI.Identifier, ACMIdx++);
1647 return SS.Default(-1);
1650 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1651 IdentifierInfo *II =
nullptr;
1652 SourceLocation StartLoc = Tok.getLocation();
1654 if (Tok.isAnyIdentifier()) {
1655 II = Tok.getIdentifierInfo();
1656 Idx = MatchACMClause(II->
getName());
1660 bool NextIsLPar = Tok.is(tok::l_paren);
1663 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1664 Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1665 << llvm::omp::getOpenMPDirectiveName(DKind, OMPVersion)
1666 << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1668 SkipBraces(II ? II->
getName() :
"",
true);
1669 SkippedClauses =
true;
1672 const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1673 if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1676 SkippedClauses =
true;
1677 SkipBraces(II->
getName(),
false);
1682 Diag(Tok.getLocation(),
1683 diag::warn_omp_unknown_assumption_clause_without_args)
1685 SkipBraces(II->
getName(),
true);
1688 assert(II &&
"Expected an identifier clause!");
1689 std::string Assumption = II->
getName().str();
1690 if (ACMI.StartsWith)
1691 Assumption =
"ompx_" + Assumption.substr(ACMI.Identifier.size());
1693 Assumption =
"omp_" + Assumption;
1694 Assumptions.push_back(Assumption);
1697 Actions.OpenMP().ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions,
1702 if (Actions.OpenMP().isInOpenMPAssumeScope())
1703 Actions.OpenMP().ActOnOpenMPEndAssumesDirective();
1705 Diag(Loc, diag::err_expected_begin_assumes);
1719struct SimpleClauseData {
1722 SourceLocation LOpen;
1723 SourceLocation TypeLoc;
1724 SourceLocation RLoc;
1725 SimpleClauseData(
unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1726 SourceLocation TypeLoc, SourceLocation RLoc)
1727 :
Type(
Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1731static std::optional<SimpleClauseData>
1738 if (T.expectAndConsume(diag::err_expected_lparen_after,
1739 getOpenMPClauseName(Kind).data()))
1740 return std::nullopt;
1746 if (
Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::comma) &&
1747 Tok.isNot(tok::annot_pragma_openmp_end))
1752 if (!T.consumeClose())
1753 RLoc = T.getCloseLocation();
1755 return SimpleClauseData(
Type, Loc, LOpen,
TypeLoc, RLoc);
1758void Parser::ParseOMPDeclareTargetClauses(
1760 SourceLocation DeviceTypeLoc;
1761 bool RequiresToLinkLocalOrIndirectClause =
false;
1762 bool HasToLinkLocalOrIndirectClause =
false;
1763 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1764 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1765 bool HasIdentifier = Tok.is(tok::identifier);
1766 if (HasIdentifier) {
1768 RequiresToLinkLocalOrIndirectClause =
true;
1769 IdentifierInfo *II = Tok.getIdentifierInfo();
1770 StringRef ClauseName = II->
getName();
1771 bool IsDeviceTypeClause =
1773 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1775 bool IsIndirectClause =
getLangOpts().OpenMP >= 51 &&
1776 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1778 if (DTCI.
Indirect && IsIndirectClause) {
1779 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1780 Diag(Tok, diag::err_omp_more_one_clause)
1781 << getOpenMPDirectiveName(OMPD_declare_target, OMPVersion)
1782 << getOpenMPClauseName(OMPC_indirect) << 0;
1785 bool IsToEnterLinkOrLocalClause =
1786 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1787 assert((!IsDeviceTypeClause || !IsToEnterLinkOrLocalClause) &&
1792 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1793 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1796 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1797 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1802 if (
getLangOpts().OpenMP < 60 && ClauseName ==
"local") {
1804 ? diag::err_omp_declare_target_unexpected_clause_52
1805 : diag::err_omp_declare_target_unexpected_clause)
1813 if (!IsDeviceTypeClause && !IsIndirectClause &&
1814 DTCI.
Kind == OMPD_begin_declare_target) {
1816 ? diag::err_omp_declare_target_unexpected_clause_52
1817 : diag::err_omp_declare_target_unexpected_clause)
1818 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1822 if (!IsDeviceTypeClause && !IsToEnterLinkOrLocalClause &&
1823 !IsIndirectClause) {
1825 ? diag::err_omp_declare_target_unexpected_clause_52
1826 : diag::err_omp_declare_target_unexpected_clause)
1835 if (IsToEnterLinkOrLocalClause || IsIndirectClause)
1836 HasToLinkLocalOrIndirectClause =
true;
1838 if (IsIndirectClause) {
1839 if (!ParseOpenMPIndirectClause(DTCI,
false))
1844 if (IsDeviceTypeClause) {
1845 std::optional<SimpleClauseData> DevTypeData =
1848 if (DeviceTypeLoc.
isValid()) {
1850 Diag(DevTypeData->Loc,
1851 diag::warn_omp_more_one_device_type_clause);
1855 case OMPC_DEVICE_TYPE_any:
1856 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Any;
1858 case OMPC_DEVICE_TYPE_host:
1859 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Host;
1861 case OMPC_DEVICE_TYPE_nohost:
1862 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1865 llvm_unreachable(
"Unexpected device_type");
1867 DeviceTypeLoc = DevTypeData->Loc;
1874 if (DTCI.
Kind == OMPD_declare_target || HasIdentifier) {
1875 auto &&Callback = [
this, MT, &DTCI](CXXScopeSpec &SS,
1876 DeclarationNameInfo NameInfo) {
1877 NamedDecl *ND = Actions.OpenMP().lookupOpenMPDeclareTargetName(
1881 SemaOpenMP::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.
getLoc()};
1884 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1887 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1892 if (Tok.is(tok::l_paren)) {
1894 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1897 if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1900 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1901 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1906 if (Tok.is(tok::comma))
1910 if (DTCI.
Indirect && DTCI.
DT != OMPDeclareTargetDeclAttr::DT_Any)
1911 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1914 if (DTCI.
Kind == OMPD_declare_target && RequiresToLinkLocalOrIndirectClause &&
1915 !HasToLinkLocalOrIndirectClause)
1916 Diag(DTCI.
Loc, diag::err_omp_declare_target_missing_required_clause)
1928 if (Tok.is(tok::annot_pragma_openmp_end))
1931 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1932 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1933 << getOpenMPDirectiveName(DKind, OMPVersion);
1934 while (Tok.isNot(tok::annot_pragma_openmp_end))
1943 bool SkipUntilOpenMPEnd) {
1944 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1946 if (FoundKind == ExpectedKind) {
1948 skipUntilPragmaOpenMPEnd(ExpectedKind);
1952 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1953 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1955 Diag(BeginLoc, diag::note_matching)
1956 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind, OMPVersion) +
"'")
1958 if (SkipUntilOpenMPEnd)
1965 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1969 if (Tok.is(tok::annot_pragma_openmp_end))
1970 ConsumeAnnotationToken();
1976 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
1977 "Not an OpenMP directive!");
1980 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1985 TentativeParsingAction TPA(*
this);
1986 Loc = ConsumeAnnotationToken();
1988 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1993 Toks.push_back(Tok);
1994 while (Cnt && Tok.isNot(tok::eof)) {
1996 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
1998 else if (Tok.is(tok::annot_pragma_openmp_end))
2000 Toks.push_back(Tok);
2005 auto *LP =
new LateParsedPragma(
this, AS);
2007 getCurrentClass().LateParsedDeclarations.push_back(LP);
2012 Loc = ConsumeAnnotationToken();
2017 case OMPD_threadprivate: {
2019 DeclDirectiveListParserHelper Helper(
this, DKind);
2020 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2022 skipUntilPragmaOpenMPEnd(DKind);
2024 ConsumeAnnotationToken();
2025 return Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2026 Loc, Helper.getIdentifiers());
2030 case OMPD_groupprivate: {
2032 DeclDirectiveListParserHelper Helper(
this, DKind);
2033 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2035 skipUntilPragmaOpenMPEnd(DKind);
2037 ConsumeAnnotationToken();
2038 return Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2039 Loc, Helper.getIdentifiers());
2043 case OMPD_allocate: {
2045 DeclDirectiveListParserHelper Helper(
this, DKind);
2046 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2048 SmallVector<OMPClause *, 1> Clauses;
2049 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2050 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
2051 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2053 Tok.isAnnotation() ? OMPC_unknown
2054 : getOpenMPClauseKind(PP.getSpelling(Tok));
2055 Actions.OpenMP().StartOpenMPClause(CKind);
2056 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2057 !SeenClauses[
unsigned(CKind)]);
2058 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2060 SeenClauses[unsigned(CKind)] =
true;
2061 if (Clause !=
nullptr)
2062 Clauses.push_back(Clause);
2063 if (Tok.is(tok::annot_pragma_openmp_end)) {
2064 Actions.OpenMP().EndOpenMPClause();
2068 if (Tok.is(tok::comma))
2070 Actions.OpenMP().EndOpenMPClause();
2072 skipUntilPragmaOpenMPEnd(DKind);
2075 ConsumeAnnotationToken();
2076 return Actions.OpenMP().ActOnOpenMPAllocateDirective(
2077 Loc, Helper.getIdentifiers(), Clauses);
2081 case OMPD_requires: {
2083 SmallVector<OMPClause *, 5> Clauses;
2084 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2085 if (Tok.is(tok::annot_pragma_openmp_end)) {
2086 Diag(Tok, diag::err_omp_expected_clause)
2087 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2090 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2093 : getOpenMPClauseKind(PP.getSpelling(Tok));
2094 Actions.OpenMP().StartOpenMPClause(CKind);
2095 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
2096 !SeenClauses[
unsigned(CKind)]);
2097 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2099 SeenClauses[unsigned(CKind)] =
true;
2100 if (Clause !=
nullptr)
2101 Clauses.push_back(Clause);
2102 if (Tok.is(tok::annot_pragma_openmp_end)) {
2103 Actions.OpenMP().EndOpenMPClause();
2107 if (Tok.is(tok::comma))
2109 Actions.OpenMP().EndOpenMPClause();
2112 if (Clauses.empty()) {
2113 Diag(Tok, diag::err_omp_expected_clause)
2114 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2115 ConsumeAnnotationToken();
2118 ConsumeAnnotationToken();
2119 return Actions.OpenMP().ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2122 SmallVector<OMPClause *, 1> Clauses;
2124 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2125 Actions.OpenMP().ActOnOpenMPErrorDirective(Clauses, StartLoc,
2131 case OMPD_begin_assumes:
2134 case OMPD_end_assumes:
2137 case OMPD_declare_reduction:
2139 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2140 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2142 ConsumeAnnotationToken();
2146 case OMPD_declare_mapper: {
2148 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2150 ConsumeAnnotationToken();
2155 case OMPD_begin_declare_variant: {
2160 ConsumeAnnotationToken();
2164 case OMPD_end_declare_variant: {
2166 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2167 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2169 Diag(Loc, diag::err_expected_begin_declare_variant);
2171 ConsumeAnnotationToken();
2174 case OMPD_declare_variant:
2175 case OMPD_declare_simd: {
2181 Toks.push_back(Tok);
2183 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2184 Toks.push_back(Tok);
2187 Toks.push_back(Tok);
2191 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2192 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2194 }
else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2198 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2199 MaybeParseCXX11Attributes(Attrs);
2200 ParsingDeclSpec PDS(*
this);
2201 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2204 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2208 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2209 << (DKind == OMPD_declare_simd ? 0 : 1);
2212 if (DKind == OMPD_declare_simd)
2213 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2214 assert(DKind == OMPD_declare_variant &&
2215 "Expected declare variant directive only");
2216 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2219 case OMPD_begin_declare_target:
2220 case OMPD_declare_target: {
2222 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2223 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2224 if (DKind == OMPD_declare_target && !HasClauses &&
2226 Diag(DTLoc, diag::warn_omp_deprecated_declare_target_delimited_form);
2228 ParseOMPDeclareTargetClauses(DTCI);
2229 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2236 if (HasImplicitMappings) {
2237 Actions.OpenMP().ActOnStartOpenMPDeclareTargetContext(DTCI);
2241 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2242 llvm::SmallVector<Decl *, 4> Decls;
2244 Decls.push_back(It.first);
2245 return Actions.BuildDeclaratorGroup(Decls);
2247 case OMPD_end_declare_target: {
2248 if (!Actions.OpenMP().isInOpenMPDeclareTargetContext()) {
2249 Diag(Tok, diag::err_omp_unexpected_directive)
2250 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2253 const SemaOpenMP::DeclareTargetContextInfo &DTCI =
2254 Actions.OpenMP().ActOnOpenMPEndDeclareTargetDirective();
2255 ParseOMPEndDeclareTargetDirective(DTCI.
Kind, DKind, DTCI.
Loc);
2259 Diag(Tok, diag::err_omp_unexpected_directive)
2260 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2264 Diag(Tok, diag::err_omp_unknown_directive);
2267 switch (getDirectiveCategory(DKind)) {
2268 case Category::Executable:
2269 case Category::Meta:
2270 case Category::Subsidiary:
2271 case Category::Utility:
2272 Diag(Tok, diag::err_omp_unexpected_directive)
2273 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2275 case Category::Declarative:
2276 case Category::Informational:
2280 while (Tok.isNot(tok::annot_pragma_openmp_end))
2286StmtResult Parser::ParseOpenMPExecutableDirective(
2288 bool ReadDirectiveWithinMetadirective) {
2290 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2292 bool HasAssociatedStatement =
true;
2293 Association Assoc = getDirectiveAssociation(DKind);
2299 if (DKind != OMPD_ordered && DKind != OMPD_section &&
2300 (Assoc == Association::None || Assoc == Association::Separating)) {
2301 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2302 ParsedStmtContext()) {
2303 Diag(Tok, diag::err_omp_immediate_directive)
2304 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2305 if (DKind == OMPD_error) {
2306 SkipUntil(tok::annot_pragma_openmp_end);
2310 HasAssociatedStatement =
false;
2313 SourceLocation EndLoc;
2314 SmallVector<OMPClause *, 5> Clauses;
2315 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2316 DeclarationNameInfo DirName;
2323 bool ImplicitClauseAllowed =
false;
2324 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2326 ImplicitClauseAllowed =
true;
2330 if (DKind == OMPD_critical) {
2332 tok::annot_pragma_openmp_end);
2333 if (!T.consumeOpen()) {
2334 if (Tok.isAnyIdentifier()) {
2336 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2339 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2343 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2345 if (Tok.isNot(tok::annot_pragma_openmp_end))
2353 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2354 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2357 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2360 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2361 while (Tok.isNot(tok::annot_pragma_openmp_end))
2365 bool HasImplicitClause =
false;
2366 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2367 HasImplicitClause =
true;
2370 PP.EnterToken(Tok,
true);
2371 PP.EnterToken(ImplicitTok,
true);
2376 : getOpenMPClauseKind(PP.getSpelling(Tok));
2377 if (HasImplicitClause) {
2378 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2379 if (DKind == OMPD_flush) {
2382 assert(DKind == OMPD_depobj &&
"Expected flush or depobj directives.");
2383 CKind = OMPC_depobj;
2387 ImplicitClauseAllowed =
false;
2388 Actions.OpenMP().StartOpenMPClause(CKind);
2389 HasImplicitClause =
false;
2390 SourceLocation ClauseLoc = Tok.getLocation();
2393 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2394 SeenClauses[unsigned(CKind)] =
true;
2396 Clauses.push_back(Clause);
2399 if (Tok.is(tok::comma))
2401 Actions.OpenMP().EndOpenMPClause();
2405 if (Tok.getLocation() == ClauseLoc) {
2406 skipUntilPragmaOpenMPEnd(DKind);
2411 EndLoc = Tok.getLocation();
2413 ConsumeAnnotationToken();
2415 if (DKind == OMPD_ordered) {
2418 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2419 if (SeenClauses[
unsigned(CK)]) {
2420 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2421 ParsedStmtContext()) {
2422 Diag(Loc, diag::err_omp_immediate_directive)
2423 << getOpenMPDirectiveName(DKind, OMPVersion) << 1
2424 << getOpenMPClauseName(CK);
2426 HasAssociatedStatement =
false;
2431 if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
2432 !SeenClauses[
unsigned(OMPC_sizes)]) {
2433 Diag(Loc, diag::err_omp_required_clause)
2434 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"sizes";
2436 if (DKind == OMPD_split && !SeenClauses[
unsigned(OMPC_counts)]) {
2437 Diag(Loc, diag::err_omp_required_clause)
2438 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"counts";
2442 if (HasAssociatedStatement) {
2444 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2450 Sema::CompoundScopeRAII Scope(Actions);
2451 AssociatedStmt = ParseStatement();
2456 Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
2459 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2460 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2461 DKind == OMPD_target_exit_data) {
2462 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2463 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2464 Actions.ActOnCompoundStmt(Loc, Loc, {},
2467 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2471 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2474 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2475 OMPDirectiveScope.Exit();
2480StmtResult Parser::ParseOpenMPInformationalDirective(
2482 bool ReadDirectiveWithinMetadirective) {
2484 "Unexpected directive category");
2486 bool HasAssociatedStatement =
true;
2488 SmallVector<OMPClause *, 5> Clauses;
2489 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2490 DeclarationNameInfo DirName;
2493 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2495 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2498 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2499 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2500 while (Tok.isNot(tok::annot_pragma_openmp_end))
2507 : getOpenMPClauseKind(PP.getSpelling(Tok));
2508 Actions.OpenMP().StartOpenMPClause(CKind);
2510 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2511 SeenClauses[unsigned(CKind)] =
true;
2513 Clauses.push_back(Clause);
2515 if (Tok.is(tok::comma))
2517 Actions.OpenMP().EndOpenMPClause();
2520 SourceLocation EndLoc = Tok.getLocation();
2521 ConsumeAnnotationToken();
2524 if (HasAssociatedStatement) {
2525 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2528 Sema::CompoundScopeRAII Scope(Actions);
2529 AssociatedStmt = ParseStatement();
2532 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2536 DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2538 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2539 OMPDirectiveScope.Exit();
2544StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2545 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2546 if (!ReadDirectiveWithinMetadirective)
2547 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2548 "Not an OpenMP directive!");
2551 SourceLocation Loc = ReadDirectiveWithinMetadirective
2553 : ConsumeAnnotationToken();
2554 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2556 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2557 Diag(Tok, diag::err_omp_unknown_directive);
2563 bool IsExecutable = [&]() {
2564 if (DKind == OMPD_error)
2566 auto Res = getDirectiveCategory(DKind);
2567 return Res == Category::Executable || Res == Category::Subsidiary;
2571 Directive = ParseOpenMPExecutableDirective(
2572 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2573 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2582 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
2583 while (Tok.isNot(tok::annot_pragma_openmp_end))
2586 skipUntilPragmaOpenMPEnd(DKind);
2587 if (Tok.is(tok::annot_pragma_openmp_end))
2588 ConsumeAnnotationToken();
2591 case OMPD_metadirective: {
2593 SmallVector<VariantMatchInfo, 4> VMIs;
2598 TentativeParsingAction TPA(*
this);
2599 ASTContext &ASTContext = Actions.getASTContext();
2602 tok::annot_pragma_openmp_end);
2603 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2606 : getOpenMPClauseKind(PP.getSpelling(Tok));
2608 if (CKind == OMPC_unknown) {
2609 Diag(Tok, diag::err_omp_expected_clause) <<
"metadirective";
2611 SkipUntil(tok::annot_pragma_openmp_end);
2614 if (
getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
2615 Diag(Tok, diag::err_omp_unexpected_clause)
2616 << getOpenMPClauseName(CKind) <<
"metadirective";
2617 if (CKind == OMPC_default &&
getLangOpts().OpenMP >= 52)
2618 Diag(Tok, diag::warn_omp_default_deprecated);
2623 if (T.expectAndConsume(diag::err_expected_lparen_after,
2624 getOpenMPClauseName(CKind).data())) {
2626 SkipUntil(tok::annot_pragma_openmp_end);
2630 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2631 if (CKind == OMPC_when) {
2633 parseOMPContextSelectors(Loc, TI);
2634 if (TI.
Sets.size() == 0) {
2635 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2641 if (Tok.is(tok::colon))
2644 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2652 while (Tok.isNot(tok::r_paren) || paren != 0) {
2653 if (Tok.is(tok::l_paren))
2655 if (Tok.is(tok::r_paren))
2657 if (Tok.is(tok::annot_pragma_openmp_end)) {
2658 Diag(Tok, diag::err_omp_expected_punc)
2659 << getOpenMPClauseName(CKind) << 0;
2666 if (Tok.is(tok::r_paren))
2669 VariantMatchInfo VMI;
2672 VMIs.push_back(VMI);
2679 [
this, Loc](StringRef ISATrait) {
2682 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2684 TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2686 ArrayRef<llvm::omp::TraitProperty>(),
2687 Actions.OpenMP().getOpenMPDeviceNum());
2690 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2697 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2699 if (Idx++ != BestIdx) {
2704 while (Tok.isNot(tok::r_paren) || paren != 0) {
2705 if (Tok.is(tok::l_paren))
2707 if (Tok.is(tok::r_paren))
2712 if (Tok.is(tok::r_paren))
2719 : getOpenMPClauseKind(PP.getSpelling(Tok));
2726 if (CKind == OMPC_when) {
2727 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2729 parseOMPContextSelectors(Loc, TI);
2737 if (Tok.is(tok::r_paren)) {
2738 SkipUntil(tok::annot_pragma_openmp_end);
2743 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2751 if (BestIdx == -1 && Idx > 0) {
2752 assert(Tok.is(tok::annot_pragma_openmp_end) &&
2753 "Expecting the end of the pragma here");
2754 ConsumeAnnotationToken();
2759 case OMPD_threadprivate: {
2761 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2762 ParsedStmtContext()) {
2763 Diag(Tok, diag::err_omp_immediate_directive)
2764 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2767 DeclDirectiveListParserHelper Helper(
this, DKind);
2768 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2770 skipUntilPragmaOpenMPEnd(DKind);
2771 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2772 Loc, Helper.getIdentifiers());
2773 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2775 SkipUntil(tok::annot_pragma_openmp_end);
2778 case OMPD_groupprivate: {
2779 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2780 ParsedStmtContext()) {
2781 Diag(Tok, diag::err_omp_immediate_directive)
2782 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2785 DeclDirectiveListParserHelper Helper(
this, DKind);
2786 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2788 skipUntilPragmaOpenMPEnd(DKind);
2789 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2790 Loc, Helper.getIdentifiers());
2791 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2793 SkipUntil(tok::annot_pragma_openmp_end);
2796 case OMPD_allocate: {
2798 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2799 ParsedStmtContext()) {
2800 Diag(Tok, diag::err_omp_immediate_directive)
2801 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2804 DeclDirectiveListParserHelper Helper(
this, DKind);
2805 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2807 SmallVector<OMPClause *, 1> Clauses;
2808 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2809 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2810 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2812 Tok.isAnnotation() ? OMPC_unknown
2813 : getOpenMPClauseKind(PP.getSpelling(Tok));
2814 Actions.OpenMP().StartOpenMPClause(CKind);
2815 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2816 !SeenClauses[
unsigned(CKind)]);
2817 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2819 SeenClauses[unsigned(CKind)] =
true;
2820 if (Clause !=
nullptr)
2821 Clauses.push_back(Clause);
2822 if (Tok.is(tok::annot_pragma_openmp_end)) {
2823 Actions.OpenMP().EndOpenMPClause();
2827 if (Tok.is(tok::comma))
2829 Actions.OpenMP().EndOpenMPClause();
2831 skipUntilPragmaOpenMPEnd(DKind);
2833 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPAllocateDirective(
2834 Loc, Helper.getIdentifiers(), Clauses);
2835 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2837 SkipUntil(tok::annot_pragma_openmp_end);
2840 case OMPD_declare_reduction:
2843 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2844 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2846 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2848 SkipUntil(tok::annot_pragma_openmp_end);
2851 case OMPD_declare_mapper: {
2854 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2856 ConsumeAnnotationToken();
2857 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2859 SkipUntil(tok::annot_pragma_openmp_end);
2863 case OMPD_declare_target: {
2865 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2866 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2868 ParseOMPDeclareTargetClauses(DTCI);
2869 bool HasImplicitMappings =
2872 if (HasImplicitMappings) {
2873 Diag(Tok, diag::err_omp_unexpected_directive)
2874 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2875 SkipUntil(tok::annot_pragma_openmp_end);
2882 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2885 case OMPD_begin_declare_variant: {
2890 ConsumeAnnotationToken();
2894 case OMPD_end_declare_variant: {
2896 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2897 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2899 Diag(Loc, diag::err_expected_begin_declare_variant);
2900 ConsumeAnnotationToken();
2903 case OMPD_declare_simd:
2904 case OMPD_begin_declare_target:
2905 case OMPD_end_declare_target:
2907 case OMPD_declare_variant:
2908 Diag(Tok, diag::err_omp_unexpected_directive)
2909 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2910 SkipUntil(tok::annot_pragma_openmp_end);
2914 Directive = ParseOpenMPInformationalDirective(
2915 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2917 "Informational directive remains unprocessed");
2922 Diag(Tok, diag::err_omp_unknown_directive);
2923 SkipUntil(tok::annot_pragma_openmp_end);
2929bool Parser::ParseOpenMPSimpleVarList(
2933 bool AllowScopeSpecifier) {
2934 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2937 if (T.expectAndConsume(diag::err_expected_lparen_after,
2938 getOpenMPDirectiveName(Kind, OMPVersion).data()))
2940 bool IsCorrect =
true;
2941 bool NoIdentIsFound =
true;
2944 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2948 Token PrevTok = Tok;
2949 NoIdentIsFound =
false;
2952 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2955 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2958 false,
false,
false,
2959 false,
false,
nullptr, Name)) {
2961 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2963 }
else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2964 Tok.isNot(tok::annot_pragma_openmp_end)) {
2966 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2970 << SourceRange(PrevTok.
getLocation(), PrevTokLocation);
2972 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2975 if (Tok.is(tok::comma)) {
2980 if (NoIdentIsFound) {
2981 Diag(Tok, diag::err_expected) << tok::identifier;
2986 IsCorrect = !T.consumeClose() && IsCorrect;
2991OMPClause *Parser::ParseOpenMPSizesClause() {
2992 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
2993 SmallVector<Expr *, 4> ValExprs;
2994 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
2998 return Actions.OpenMP().ActOnOpenMPSizesClause(ValExprs, ClauseNameLoc,
3002OMPClause *Parser::ParseOpenMPCountsClause() {
3003 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3004 SmallVector<Expr *, 4> ValExprs;
3005 std::optional<unsigned> FillIdx;
3006 unsigned FillCount = 0;
3007 SourceLocation FillLoc;
3009 assert(getOpenMPClauseName(OMPC_counts) == PP.getSpelling(Tok) &&
3010 "Expected parsing to start at clause name");
3014 if (T.consumeOpen()) {
3015 Diag(Tok, diag::err_expected) << tok::l_paren;
3020 if (Tok.is(tok::identifier) &&
3021 Tok.getIdentifierInfo()->getName() ==
"omp_fill") {
3023 FillIdx = ValExprs.size();
3025 FillLoc = Tok.getLocation();
3027 ValExprs.push_back(
nullptr);
3034 ValExprs.push_back(Val.
get());
3038 if (T.consumeClose())
3040 OpenLoc = T.getOpenLocation();
3041 CloseLoc = T.getCloseLocation();
3043 return Actions.OpenMP().ActOnOpenMPCountsClause(
3044 ValExprs, ClauseNameLoc, OpenLoc, CloseLoc, FillIdx, FillLoc, FillCount);
3047OMPClause *Parser::ParseOpenMPLoopRangeClause() {
3049 SourceLocation FirstLoc, CountLoc;
3052 if (T.consumeOpen()) {
3053 Diag(Tok, diag::err_expected) << tok::l_paren;
3057 FirstLoc = Tok.getLocation();
3064 ExpectAndConsume(tok::comma);
3066 CountLoc = Tok.getLocation();
3075 return Actions.OpenMP().ActOnOpenMPLoopRangeClause(
3076 FirstVal.
get(), CountVal.
get(), ClauseNameLoc, T.getOpenLocation(),
3077 FirstLoc, CountLoc, T.getCloseLocation());
3080OMPClause *Parser::ParseOpenMPPermutationClause() {
3081 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3082 SmallVector<Expr *> ArgExprs;
3083 if (ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,
3088 return Actions.OpenMP().ActOnOpenMPPermutationClause(ArgExprs, ClauseNameLoc,
3093 SourceLocation Loc = Tok.getLocation();
3098 if (T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3100 SmallVector<SemaOpenMP::UsesAllocatorsData, 4>
Data;
3103 if (
getLangOpts().OpenMP >= 52 && Tok.is(tok::identifier) &&
3104 Tok.getIdentifierInfo()->getName() ==
"traits") {
3106 SemaOpenMP::UsesAllocatorsData &D =
Data.emplace_back();
3112 tok::annot_pragma_openmp_end);
3113 TraitParens.consumeOpen();
3116 TraitParens.consumeClose();
3120 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3126 if (Tok.isNot(tok::colon)) {
3127 Diag(Tok, diag::err_expected) << tok::colon;
3129 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3138 ? ParseCXXIdExpression()
3139 : tryParseCXXIdExpression(SS,
false);
3143 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3150 D.
LParenLoc = TraitParens.getOpenLocation();
3151 D.
RParenLoc = TraitParens.getCloseLocation();
3154 if (Tok.is(tok::comma)) {
3156 Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3159 }
else if (Tok.is(tok::semi)) {
3169 getLangOpts().CPlusPlus
3170 ? ParseCXXIdExpression()
3171 : tryParseCXXIdExpression(SS,
false);
3173 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3180 BalancedDelimiterTracker T(*this, tok::l_paren,
3181 tok::annot_pragma_openmp_end);
3183 ExprResult AllocatorTraits =
3184 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3186 if (AllocatorTraits.isInvalid()) {
3187 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3196 if (getLangOpts().OpenMP >= 52) {
3197 Diag(Loc, diag::err_omp_deprecate_old_syntax)
3198 <<
"allocator(expr)"
3199 <<
"uses_allocators"
3200 <<
"traits(expr): alloc";
3204 Diag(
Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3206 if (
Tok.
is(tok::comma))
3208 }
while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end));
3211 Loc, T.getOpenLocation(), T.getCloseLocation(),
Data);
3216 OMPClauseKind = CKind;
3217 OMPClause *Clause =
nullptr;
3218 bool ErrorFound =
false;
3219 bool WrongDirective =
false;
3220 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
3223 if (CKind != OMPC_unknown &&
3224 !isAllowedClauseForDirective(DKind, CKind,
getLangOpts().OpenMP)) {
3225 Diag(Tok, diag::err_omp_unexpected_clause)
3226 << getOpenMPClauseName(CKind)
3227 << getOpenMPDirectiveName(DKind, OMPVersion);
3229 WrongDirective =
true;
3234 case OMPC_num_threads:
3240 case OMPC_grainsize:
3241 case OMPC_num_tasks:
3243 case OMPC_allocator:
3246 case OMPC_novariants:
3247 case OMPC_nocontext:
3252 case OMPC_ompx_dyn_cgroup_mem:
3253 case OMPC_dyn_groupprivate:
3254 case OMPC_transparent:
3283 Diag(Tok, diag::err_omp_more_one_clause)
3284 << getOpenMPDirectiveName(DKind, OMPVersion)
3285 << getOpenMPClauseName(CKind) << 0;
3289 if (CKind == OMPC_transparent && PP.LookAhead(0).isNot(tok::l_paren)) {
3291 SourceLocation LLoc = Tok.getLocation();
3292 Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(
nullptr, LLoc,
3296 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3297 PP.LookAhead(0).isNot(tok::l_paren))
3298 Clause = ParseOpenMPClause(CKind, WrongDirective);
3299 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3300 CKind == OMPC_num_threads || CKind == OMPC_dyn_groupprivate)
3301 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3303 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3305 case OMPC_threadset:
3307 case OMPC_proc_bind:
3308 case OMPC_atomic_default_mem_order:
3326 Diag(Tok, diag::err_omp_more_one_clause)
3327 << getOpenMPDirectiveName(DKind, OMPVersion)
3328 << getOpenMPClauseName(CKind) << 0;
3332 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3336 case OMPC_dist_schedule:
3337 case OMPC_defaultmap:
3348 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3349 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3350 Diag(Tok, diag::err_omp_more_one_clause)
3351 << getOpenMPDirectiveName(DKind, OMPVersion)
3352 << getOpenMPClauseName(CKind) << 0;
3357 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3360 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3364 case OMPC_mergeable:
3378 case OMPC_unified_address:
3379 case OMPC_unified_shared_memory:
3380 case OMPC_reverse_offload:
3381 case OMPC_dynamic_allocators:
3390 Diag(Tok, diag::err_omp_more_one_clause)
3391 << getOpenMPDirectiveName(DKind, OMPVersion)
3392 << getOpenMPClauseName(CKind) << 0;
3396 if (CKind == OMPC_nowait && PP.LookAhead(0).is(tok::l_paren) &&
3398 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3400 Clause = ParseOpenMPClause(CKind, WrongDirective);
3402 case OMPC_self_maps:
3405 Diag(Tok, diag::err_omp_expected_clause)
3406 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3410 Diag(Tok, diag::err_omp_more_one_clause)
3411 << getOpenMPDirectiveName(DKind, OMPVersion)
3412 << getOpenMPClauseName(CKind) << 0;
3415 Clause = ParseOpenMPClause(CKind, WrongDirective);
3419 Diag(Tok, diag::err_omp_more_one_clause)
3420 << getOpenMPDirectiveName(DKind, OMPVersion)
3421 << getOpenMPClauseName(CKind) << 0;
3425 Clause = (DKind == OMPD_depobj)
3426 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3427 : ParseOpenMPClause(CKind, WrongDirective);
3429 case OMPC_num_teams:
3430 case OMPC_thread_limit:
3432 Diag(Tok, diag::err_omp_more_one_clause)
3433 << getOpenMPDirectiveName(DKind, OMPVersion)
3434 << getOpenMPClauseName(CKind) << 0;
3439 case OMPC_firstprivate:
3440 case OMPC_lastprivate:
3442 case OMPC_reduction:
3443 case OMPC_task_reduction:
3444 case OMPC_in_reduction:
3448 case OMPC_copyprivate:
3454 case OMPC_use_device_ptr:
3455 case OMPC_use_device_addr:
3456 case OMPC_is_device_ptr:
3457 case OMPC_has_device_addr:
3459 case OMPC_nontemporal:
3460 case OMPC_inclusive:
3461 case OMPC_exclusive:
3465 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
3466 CKind == OMPC_depend)
3467 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3468 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3472 Diag(Tok, diag::err_omp_more_one_clause)
3473 << getOpenMPDirectiveName(DKind, OMPVersion)
3474 << getOpenMPClauseName(CKind) << 0;
3478 Clause = ParseOpenMPSizesClause();
3480 case OMPC_permutation:
3482 Diag(Tok, diag::err_omp_more_one_clause)
3483 << getOpenMPDirectiveName(DKind, OMPVersion)
3484 << getOpenMPClauseName(CKind) << 0;
3487 Clause = ParseOpenMPPermutationClause();
3491 Diag(Tok, diag::err_omp_more_one_clause)
3492 << getOpenMPDirectiveName(DKind, OMPVersion)
3493 << getOpenMPClauseName(CKind) << 0;
3496 Clause = ParseOpenMPCountsClause();
3498 case OMPC_uses_allocators:
3499 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3502 if (DKind != OMPD_interop) {
3504 Diag(Tok, diag::err_omp_more_one_clause)
3505 << getOpenMPDirectiveName(DKind, OMPVersion)
3506 << getOpenMPClauseName(CKind) << 0;
3509 Clause = ParseOpenMPClause(CKind, WrongDirective);
3515 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3517 case OMPC_device_type:
3519 skipUntilPragmaOpenMPEnd(DKind);
3521 case OMPC_threadprivate:
3522 case OMPC_groupprivate:
3525 if (!WrongDirective)
3526 Diag(Tok, diag::err_omp_unexpected_clause)
3527 << getOpenMPClauseName(CKind)
3528 << getOpenMPDirectiveName(DKind, OMPVersion);
3532 case OMPC_contains: {
3534 SourceLocation LLoc = Tok.getLocation();
3535 SourceLocation RLoc;
3536 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3541 if (DK == OMPD_unknown) {
3542 skipUntilPragmaOpenMPEnd(OMPD_assume);
3543 Diag(Tok, diag::err_omp_unexpected_clause)
3544 << getOpenMPClauseName(CKind)
3545 << getOpenMPDirectiveName(DKind, OMPVersion);
3549 DKVec.push_back(DK);
3552 Diag(Tok, diag::err_omp_unexpected_clause)
3553 << getOpenMPClauseName(CKind)
3554 << getOpenMPDirectiveName(DKind, OMPVersion);
3557 RLoc = Tok.getLocation();
3559 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3560 CKind, DKVec, Loc, LLoc, RLoc);
3563 case OMPC_no_openmp:
3564 case OMPC_no_openmp_routines:
3565 case OMPC_no_openmp_constructs:
3566 case OMPC_no_parallelism: {
3568 Diag(Tok, diag::err_omp_more_one_clause)
3569 << getOpenMPDirectiveName(DKind, OMPVersion)
3570 << getOpenMPClauseName(CKind) << 0;
3574 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3575 CKind, Loc, Tok.getLocation());
3578 case OMPC_ompx_attribute:
3579 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3581 case OMPC_ompx_bare:
3582 if (DKind == llvm::omp::Directive::OMPD_target) {
3587 Diag(Tok, diag::err_omp_unexpected_clause)
3588 << getOpenMPClauseName(CKind)
3589 << getOpenMPDirectiveName(DKind, OMPVersion);
3591 WrongDirective =
true;
3594 Diag(Tok, diag::note_ompx_bare_clause)
3595 << getOpenMPClauseName(CKind) <<
"target teams";
3596 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3597 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3598 << getOpenMPClauseName(CKind)
3599 << getOpenMPDirectiveName(DKind, OMPVersion);
3602 Clause = ParseOpenMPClause(CKind, WrongDirective);
3604 case OMPC_looprange:
3605 Clause = ParseOpenMPLoopRangeClause();
3610 return ErrorFound ?
nullptr : Clause;
3618 bool IsAddressOfOperand) {
3620 if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3628 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3631 RLoc = Tok.getLocation();
3632 if (!T.consumeClose())
3633 RLoc = T.getCloseLocation();
3655bool Parser::ParseOpenMPIndirectClause(
3660 if (
Tok.isNot(tok::l_paren)) {
3679 if (
Ret.isInvalid())
3682 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3684 if (
Ret.isInvalid())
3692ExprResult Parser::ParseOMPInteropFrSelector() {
3695 tok::annot_pragma_openmp_end);
3696 if (FT.expectAndConsume(diag::err_expected_lparen_after,
"fr")) {
3698 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3702 SourceLocation Loc = Tok.getLocation();
3705 Arg = Actions.ActOnFinishFullExpr(Arg.
get(), Loc,
false);
3713 tok::annot_pragma_openmp_end);
3714 if (AT.expectAndConsume(diag::err_expected_lparen_after,
"attr")) {
3716 {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
3720 bool HasError =
false;
3723 if (Tok.is(tok::r_paren)) {
3724 Diag(Tok, diag::err_omp_interop_attr_not_string);
3727 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::r_brace) &&
3728 Tok.isNot(tok::annot_pragma_openmp_end)) {
3729 if (Tok.is(tok::string_literal)) {
3732 Attrs.push_back(S.
get());
3737 Diag(Tok, diag::err_omp_interop_attr_not_string);
3740 if (Tok.is(tok::comma))
3750 bool HasError =
false;
3751 bool IsTarget =
false;
3752 bool IsTargetSync =
false;
3754 while (Tok.is(tok::identifier)) {
3756 bool PreferTypeAllowed =
Kind == OMPC_init && InteropInfo.
Prefs.empty() &&
3757 !IsTarget && !IsTargetSync;
3758 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3763 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3766 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3768 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3769 IsTargetSync =
true;
3771 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3772 PreferTypeAllowed) {
3775 tok::annot_pragma_openmp_end);
3776 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3780 if (Tok.is(tok::r_paren)) {
3781 Diag(Tok, diag::err_omp_expected_pref_spec);
3785 while (Tok.isNot(tok::r_paren) &&
3786 Tok.isNot(tok::annot_pragma_openmp_end)) {
3788 if (Tok.is(tok::l_brace)) {
3792 Diag(Tok, diag::err_omp_prefer_type_brace_60);
3796 tok::annot_pragma_openmp_end);
3798 Expr *FrExpr =
nullptr;
3799 SmallVector<Expr *, 2> AttrExprs;
3800 bool SeenFr =
false;
3804 if (Tok.is(tok::r_brace)) {
3805 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3809 while (Tok.isNot(tok::r_brace) &&
3810 Tok.isNot(tok::annot_pragma_openmp_end)) {
3811 if (Tok.is(tok::identifier) &&
3812 Tok.getIdentifierInfo()->isStr(
"fr")) {
3814 Diag(Tok, diag::err_omp_interop_multiple_fr);
3818 {tok::comma, tok::r_brace, tok::annot_pragma_openmp_end},
3828 }
else if (Tok.is(tok::identifier) &&
3829 Tok.getIdentifierInfo()->isStr(
"attr")) {
3830 if (ParseOMPInteropAttrSelector(AttrExprs))
3835 Diag(Tok, diag::err_omp_expected_fr_or_attr_selector);
3838 if (Tok.is(tok::comma))
3841 if (BT.consumeClose())
3844 if (FrExpr || !AttrExprs.empty())
3845 InteropInfo.
Prefs.emplace_back(FrExpr, AttrExprs);
3850 SourceLocation Loc = Tok.getLocation();
3854 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
3857 InteropInfo.
Prefs.emplace_back(PTExpr.
get(),
3858 llvm::SmallVector<Expr *, 2>{});
3861 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3866 if (Tok.is(tok::comma))
3872 Diag(Tok, diag::err_omp_expected_interop_type);
3875 if (!Tok.is(tok::comma))
3880 if (!HasError && !IsTarget && !IsTargetSync) {
3881 Diag(Tok, diag::err_omp_expected_interop_type);
3885 if (Kind == OMPC_init) {
3886 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
3887 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3888 if (Tok.is(tok::colon))
3905 if (T.expectAndConsume(diag::err_expected_lparen_after,
3906 getOpenMPClauseName(Kind).data()))
3909 bool InteropError =
false;
3910 OMPInteropInfo InteropInfo;
3911 if (Kind == OMPC_init)
3912 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3915 SourceLocation VarLoc = Tok.getLocation();
3918 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3923 SourceLocation RLoc = Tok.getLocation();
3924 if (!T.consumeClose())
3925 RLoc = T.getCloseLocation();
3927 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3930 if (Kind == OMPC_init)
3931 return Actions.OpenMP().ActOnOpenMPInitClause(
3932 InteropVarExpr.
get(), InteropInfo, Loc, T.getOpenLocation(), VarLoc,
3934 if (Kind == OMPC_use)
3935 return Actions.OpenMP().ActOnOpenMPUseClause(
3936 InteropVarExpr.
get(), Loc, T.getOpenLocation(), VarLoc, RLoc);
3938 if (Kind == OMPC_destroy)
3939 return Actions.OpenMP().ActOnOpenMPDestroyClause(
3940 InteropVarExpr.
get(), Loc, T.getOpenLocation(), VarLoc, RLoc);
3942 llvm_unreachable(
"Unexpected interop variable clause.");
3945OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
3949 if (T.expectAndConsume(diag::err_expected_lparen_after,
3950 getOpenMPClauseName(OMPC_ompx_attribute).data()))
3953 ParsedAttributes ParsedAttrs(AttrFactory);
3954 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
3957 if (T.consumeClose())
3963 SmallVector<Attr *> Attrs;
3964 for (
const ParsedAttr &PA : ParsedAttrs) {
3965 switch (PA.getKind()) {
3966 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
3967 if (!PA.checkExactlyNumArgs(Actions, 2))
3969 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
3970 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
3973 case ParsedAttr::AT_AMDGPUWavesPerEU:
3974 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3975 !PA.checkAtMostNumArgs(Actions, 2))
3977 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
3978 PA, PA.getArgAsExpr(0),
3979 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
3982 case ParsedAttr::AT_CUDALaunchBounds:
3983 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3984 !PA.checkAtMostNumArgs(Actions, 3))
3986 if (
auto *A = Actions.CreateLaunchBoundsAttr(
3987 PA, PA.getArgAsExpr(0),
3988 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
3989 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr,
3994 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
3999 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
4000 Attrs, Loc, T.getOpenLocation(), T.getCloseLocation());
4006 if (!Val || ParseOnly)
4008 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
4009 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
4010 static_cast<DefaultKind
>(Val->Type) ==
4011 OMP_DEFAULT_firstprivate)) {
4012 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
4013 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
4016 : OMPC_firstprivate)
4017 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4020 return Actions.OpenMP().ActOnOpenMPSimpleClause(
4021 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
4025 SourceLocation Loc = Tok.getLocation();
4030 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
4037 SourceLocation DelimLoc;
4040 if (T.expectAndConsume(diag::err_expected_lparen_after,
4041 getOpenMPClauseName(Kind).data()))
4045 SmallVector<unsigned, 4> Arg;
4046 SmallVector<SourceLocation, 4> KLoc;
4047 if (Kind == OMPC_schedule) {
4048 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
4049 Arg.resize(NumberOfElements);
4050 KLoc.resize(NumberOfElements);
4055 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4058 Arg[Modifier1] = KindModifier;
4059 KLoc[Modifier1] = Tok.getLocation();
4060 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4061 Tok.isNot(tok::annot_pragma_openmp_end))
4063 if (Tok.is(tok::comma)) {
4067 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4071 KLoc[Modifier2] = Tok.getLocation();
4072 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4073 Tok.isNot(tok::annot_pragma_openmp_end))
4077 if (Tok.is(tok::colon))
4080 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
4082 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4084 Arg[ScheduleKind] = KindModifier;
4085 KLoc[ScheduleKind] = Tok.getLocation();
4086 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4087 Tok.isNot(tok::annot_pragma_openmp_end))
4089 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
4090 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
4091 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
4094 }
else if (Kind == OMPC_dist_schedule) {
4096 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4097 KLoc.push_back(Tok.getLocation());
4098 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4099 Tok.isNot(tok::annot_pragma_openmp_end))
4101 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
4103 }
else if (Kind == OMPC_default) {
4106 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4108 Arg.push_back(Modifier);
4109 KLoc.push_back(Tok.getLocation());
4110 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4111 Tok.isNot(tok::annot_pragma_openmp_end))
4114 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
4119 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4120 Arg.push_back(VariableCategory);
4121 KLoc.push_back(Tok.getLocation());
4122 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4123 Tok.isNot(tok::annot_pragma_openmp_end))
4126 Arg.push_back(OMPC_DEFAULT_VC_all);
4127 KLoc.push_back(SourceLocation());
4129 }
else if (Kind == OMPC_defaultmap) {
4132 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4138 Arg.push_back(Modifier);
4139 KLoc.push_back(Tok.getLocation());
4140 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4141 Tok.isNot(tok::annot_pragma_openmp_end))
4144 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
4145 if (Tok.is(tok::colon))
4148 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
4151 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4152 KLoc.push_back(Tok.getLocation());
4153 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4154 Tok.isNot(tok::annot_pragma_openmp_end))
4158 KLoc.push_back(SourceLocation());
4160 }
else if (Kind == OMPC_order) {
4161 enum { Modifier, OrderKind, NumberOfElements };
4162 Arg.resize(NumberOfElements);
4163 KLoc.resize(NumberOfElements);
4167 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4170 Arg[Modifier] = KindModifier;
4171 KLoc[Modifier] = Tok.getLocation();
4172 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4173 Tok.isNot(tok::annot_pragma_openmp_end))
4176 if (Tok.is(tok::colon))
4179 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
4181 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4183 Arg[OrderKind] = KindModifier;
4184 KLoc[OrderKind] = Tok.getLocation();
4185 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4186 Tok.isNot(tok::annot_pragma_openmp_end))
4188 }
else if (Kind == OMPC_device) {
4194 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4195 KLoc.push_back(Tok.getLocation());
4201 KLoc.emplace_back();
4203 }
else if (Kind == OMPC_grainsize) {
4207 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4211 Arg.push_back(Modifier);
4212 KLoc.push_back(Tok.getLocation());
4218 if (Modifier == OMPC_GRAINSIZE_strict) {
4219 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4224 KLoc.emplace_back();
4228 KLoc.emplace_back();
4230 }
else if (Kind == OMPC_dyn_groupprivate) {
4231 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4232 Arg.resize(NumberOfModifiers);
4233 KLoc.resize(NumberOfModifiers);
4237 auto ConsumeModifier = [&]() {
4238 unsigned Type = NumberOfModifiers;
4241 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4245 ParenT.consumeOpen();
4248 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4251 Diag(Tok.getLocation(), diag::err_expected)
4252 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4254 return std::make_tuple(
Type, Modifier, Loc);
4256 Type = ComplexModifier;
4257 Loc = Tok.getLocation();
4258 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4259 Tok.isNot(tok::annot_pragma_openmp_end))
4261 ParenT.consumeClose();
4264 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4266 Type = SimpleModifier;
4267 Loc = Tok.getLocation();
4268 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4269 Tok.isNot(tok::annot_pragma_openmp_end))
4273 return std::make_tuple(
Type, Modifier, Loc);
4276 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4277 SourceLocation Loc) {
4278 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4279 if (!KLoc[
Type].isValid()) {
4280 Arg[
Type] = Modifier;
4283 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4290 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4291 if (Type1 < NumberOfModifiers) {
4292 SaveModifier(Type1, Mod1, Loc1);
4293 if (Tok.is(tok::comma)) {
4296 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4297 if (Type2 < NumberOfModifiers)
4298 SaveModifier(Type2, Mod2, Loc2);
4301 if (Tok.is(tok::colon))
4304 Diag(Tok, diag::warn_pragma_expected_colon)
4305 <<
"dyn_groupprivate modifier";
4307 }
else if (Kind == OMPC_num_tasks) {
4311 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4315 Arg.push_back(Modifier);
4316 KLoc.push_back(Tok.getLocation());
4322 if (Modifier == OMPC_NUMTASKS_strict) {
4323 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4328 KLoc.emplace_back();
4332 KLoc.emplace_back();
4334 }
else if (Kind == OMPC_num_threads) {
4338 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4342 Arg.push_back(Modifier);
4343 KLoc.push_back(Tok.getLocation());
4349 if (Modifier == OMPC_NUMTHREADS_strict) {
4350 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4355 KLoc.emplace_back();
4359 KLoc.emplace_back();
4362 assert(Kind == OMPC_if);
4363 KLoc.push_back(Tok.getLocation());
4364 TentativeParsingAction TPA(*
this);
4366 Arg.push_back(
static_cast<unsigned>(DK));
4367 if (DK != OMPD_unknown) {
4369 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4374 Arg.back() = unsigned(OMPD_unknown);
4381 bool NeedAnExpression =
4383 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
Kind == OMPC_if ||
4384 Kind == OMPC_device ||
Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4385 Kind == OMPC_num_threads ||
Kind == OMPC_dyn_groupprivate;
4386 if (NeedAnExpression) {
4387 SourceLocation ELoc = Tok.getLocation();
4393 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4397 SourceLocation RLoc = Tok.getLocation();
4398 if (!T.consumeClose())
4399 RLoc = T.getCloseLocation();
4401 if (NeedAnExpression && Val.
isInvalid())
4404 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4405 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4406 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4407 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4408 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4411 : OMPC_firstprivate)
4412 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4418 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4419 Kind, Arg, Val.
get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4424 if (ReductionIdScopeSpec.
isEmpty()) {
4462 ReductionIdScopeSpec,
nullptr,
4466 false,
nullptr, ReductionId);
4473 if (!
Tok.is(tok::identifier))
4480 return TypeModifier;
4486 if (T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4487 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4493 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4497 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4498 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4499 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4503 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4505 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4508 return T.consumeClose();
4514 bool HasMapType =
false;
4516 StringRef PreMapName =
"";
4520 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4521 TypeModifier == OMPC_MAP_MODIFIER_close ||
4522 TypeModifier == OMPC_MAP_MODIFIER_present ||
4523 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4524 Data.MapTypeModifiers.push_back(TypeModifier);
4525 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4526 if (PP.LookAhead(0).isNot(tok::comma) &&
4527 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4528 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4529 <<
"map type modifier";
4531 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4532 Data.MapTypeModifiers.push_back(TypeModifier);
4533 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4537 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4539 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4540 <<
"map type modifier";
4545 Data.ExtraModifier = MapKind;
4547 PreMapLoc = Tok.getLocation();
4548 PreMapName = Tok.getIdentifierInfo()->getName();
4550 Diag(Tok, diag::err_omp_more_one_map_type);
4551 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4555 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4556 Data.MapTypeModifiers.push_back(TypeModifier);
4557 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4558 if (PP.LookAhead(0).isNot(tok::comma) &&
4559 PP.LookAhead(0).isNot(tok::colon))
4560 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4561 <<
"map type modifier";
4563 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4573 if (Tok.is(tok::comma)) {
4574 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4579 if (PP.LookAhead(0).is(tok::colon)) {
4587 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4598 if (!Tok.is(tok::colon)) {
4599 Diag(Tok, diag::err_omp_unknown_map_type);
4613 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4618 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4619 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4620 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4630 if (
Tok.is(tok::colon)) {
4631 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4636 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4640ExprResult Parser::ParseOpenMPIteratorsExpr() {
4641 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4642 "Expected 'iterator' token.");
4646 if (T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4649 SourceLocation LLoc = T.getOpenLocation();
4650 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4651 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4654 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4661 IteratorType = TR.
get();
4665 IdentifierInfo *II =
nullptr;
4666 SourceLocation IdLoc;
4667 if (Tok.is(tok::identifier)) {
4668 II = Tok.getIdentifierInfo();
4671 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4675 SourceLocation AssignLoc;
4676 if (Tok.is(tok::equal))
4679 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4684 SourceLocation Loc = Tok.getLocation();
4687 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4690 SourceLocation ColonLoc;
4691 if (Tok.is(tok::colon))
4695 Loc = Tok.getLocation();
4698 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4701 SourceLocation SecColonLoc;
4704 if (Tok.is(tok::colon)) {
4708 Loc = Tok.getLocation();
4711 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4716 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4717 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4718 if (Tok.is(tok::comma))
4721 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4724 D.
Type = IteratorType;
4734 SourceLocation RLoc = Tok.getLocation();
4735 if (!T.consumeClose())
4736 RLoc = T.getCloseLocation();
4738 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4747 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4750 if (Tok.is(tok::identifier) &&
4751 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4753 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4754 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4755 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4756 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4757 Data.ExtraModifier != OMPC_DEPEND_inout)
4758 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4760 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4761 ? OMPC_DEPEND_outallmemory
4762 : OMPC_DEPEND_inoutallmemory;
4778 Data.DepModOrTailExpr = Tail.
get();
4780 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4781 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4799 bool AllocatorSeen =
false;
4800 bool AlignSeen =
false;
4819 if (
Tok.is(tok::l_paren)) {
4820 switch (CurrentModifier) {
4821 case OMPC_ALLOCATE_allocator: {
4822 if (AllocatorSeen) {
4823 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4825 << getOpenMPClauseName(Kind);
4827 Data.AllocClauseModifiers.push_back(CurrentModifier);
4828 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4831 tok::annot_pragma_openmp_end);
4835 AllocatorSeen =
true;
4838 case OMPC_ALLOCATE_align: {
4840 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4842 << getOpenMPClauseName(Kind);
4844 Data.AllocClauseModifiers.push_back(CurrentModifier);
4845 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4849 Data.AllocateAlignment = Val.
get();
4854 llvm_unreachable(
"Unexpected allocate modifier");
4857 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4859 if (
Tok.isNot(tok::comma))
4862 CurrentModifierLoc =
Tok.getLocation();
4867 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4870 }
while (!AllocatorSeen || !AlignSeen);
4879 bool InvalidReductionId =
false;
4880 bool IsInvalidMapperModifier =
false;
4884 if (T.expectAndConsume(diag::err_expected_lparen_after,
4885 getOpenMPClauseName(Kind).data()))
4888 bool HasIterator =
false;
4889 bool InvalidIterator =
false;
4890 bool NeedRParenForLinear =
false;
4892 tok::annot_pragma_openmp_end);
4894 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4895 Kind == OMPC_in_reduction) {
4897 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4898 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4901 Data.ExtraModifier =
4903 Data.ExtraModifierLoc = Tok.getLocation();
4905 assert(Tok.is(tok::comma) &&
"Expected comma.");
4909 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4910 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4916 if (Tok.is(tok::kw_private)) {
4917 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4918 Data.OriginalSharingModifierLoc = Tok.getLocation();
4920 }
else if (Tok.is(tok::identifier) &&
4921 (PP.getSpelling(Tok) ==
"shared" ||
4922 PP.getSpelling(Tok) ==
"default")) {
4923 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4924 Data.OriginalSharingModifierLoc = Tok.getLocation();
4927 Diag(Tok.getLocation(), diag::err_expected)
4928 <<
"'private or shared or default'";
4933 if (!Tok.is(tok::comma)) {
4934 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4941 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4946 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4947 if (InvalidReductionId) {
4948 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4951 if (Tok.is(tok::colon))
4954 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4955 if (!InvalidReductionId)
4956 Data.ReductionOrMapperId =
4957 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4958 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4960 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4969 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4970 Data.DepModOrTailExpr = IteratorRes.
get();
4972 ExpectAndConsume(tok::comma);
4978 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4980 Data.ExtraModifierLoc = Tok.getLocation();
4982 (Kind == OMPC_doacross &&
4984 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4989 if (DKind == OMPD_ordered && Kind == OMPC_depend &&
4990 Data.ExtraModifier == OMPC_DEPEND_source) {
4996 if (Tok.is(tok::colon)) {
4998 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
4999 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
5000 : diag::warn_pragma_expected_colon)
5001 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
5003 if (Kind == OMPC_doacross) {
5004 if (Tok.is(tok::identifier) &&
5005 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
5006 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
5007 ? OMPC_DOACROSS_source_omp_cur_iteration
5008 : OMPC_DOACROSS_sink_omp_cur_iteration;
5011 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
5012 if (Tok.isNot(tok::minus)) {
5013 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5014 << getOpenMPClauseName(Kind) << 0 << 0;
5021 if (Tok.isNot(tok::numeric_constant) ||
5022 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
5023 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
5024 << getOpenMPClauseName(Kind) << 0 << 0;
5030 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
5031 if (Tok.isNot(tok::r_paren)) {
5032 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
5033 << getOpenMPClauseName(Kind) << 1 << 1;
5039 if (Kind == OMPC_doacross &&
5040 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
5041 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
5042 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
5048 }
else if (Kind == OMPC_linear) {
5050 Data.ExtraModifier = OMPC_LINEAR_val;
5051 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
5052 Data.ExtraModifier =
5056 NeedRParenForLinear =
true;
5058 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
5059 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
5060 <<
"linear(list: [linear-modifier,] step(step-size))";
5062 }
else if (Kind == OMPC_lastprivate) {
5069 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
5070 Data.ExtraModifier =
5072 Data.ExtraModifierLoc = Tok.getLocation();
5074 assert(Tok.is(tok::colon) &&
"Expected colon.");
5077 }
else if (Kind == OMPC_map) {
5079 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
5082 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
5083 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
5084 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
5085 Data.IteratorExpr = IteratorRes.
get();
5087 ExpectAndConsume(tok::comma);
5089 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
5092 InvalidIterator =
true;
5102 Data.ExtraModifierLoc = Tok.getLocation();
5105 TentativeParsingAction TPA(*
this);
5106 bool ColonPresent =
false;
5107 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5109 if (Tok.is(tok::colon))
5110 ColonPresent =
true;
5117 Diag(Tok, diag::err_omp_map_modifier_specification_list);
5119 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
5125 Data.ExtraModifier = OMPC_MAP_tofrom;
5127 if (DKind == OMPD_target_enter_data)
5128 Data.ExtraModifier = OMPC_MAP_to;
5129 else if (DKind == OMPD_target_exit_data)
5130 Data.ExtraModifier = OMPC_MAP_from;
5132 Data.IsMapTypeImplicit =
true;
5135 if (Tok.is(tok::colon))
5137 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
5138 while (Tok.is(tok::identifier)) {
5143 Data.MotionModifiers.push_back(Modifier);
5144 Data.MotionModifiersLoc.push_back(Tok.getLocation());
5145 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
5147 Tail = ParseOpenMPIteratorsExpr();
5148 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
5151 Data.IteratorExpr = Tail.
get();
5154 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
5156 if (IsInvalidMapperModifier)
5164 if (Tok.is(tok::comma))
5168 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
5169 if (!IsInvalidMapperModifier) {
5171 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
5173 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
5175 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5183 }
else if (Kind == OMPC_allocate ||
5184 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
5185 PP.getSpelling(Tok) ==
"iterator")) {
5189 TentativeParsingAction TPA(*
this);
5194 if (Kind == OMPC_allocate) {
5199 Tail = ParseOpenMPIteratorsExpr();
5201 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
5204 if (Tok.is(tok::colon)) {
5211 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5212 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5214 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5221 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5224 }
else if (Kind == OMPC_adjust_args) {
5228 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5230 Data.ExtraModifierLoc = Tok.getLocation();
5232 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5237 if (Tok.is(tok::colon))
5238 Data.ColonLoc = Tok.getLocation();
5242 if (Tok.is(tok::l_paren)) {
5245 if (Tok.is(tok::identifier)) {
5246 std::string Modifier = PP.getSpelling(Tok);
5247 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5248 Data.NeedDevicePtrModifier =
5249 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5250 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5252 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5253 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5258 if (Tok.is(tok::r_paren)) {
5259 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5262 Diag(Tok, diag::err_expected) << tok::r_paren;
5263 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5272 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5275 }
else if (Kind == OMPC_use_device_ptr) {
5279 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5283 Data.ExtraModifier = FallbackModifier;
5284 Data.ExtraModifierLoc = Tok.getLocation();
5286 if (Tok.is(tok::colon))
5289 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5293 if (Kind == OMPC_num_teams && !Tok.is(tok::r_paren) &&
5294 !Tok.is(tok::annot_pragma_openmp_end)) {
5298 Data.RLoc = Tok.getLocation();
5299 if (!T.consumeClose())
5300 Data.RLoc = T.getCloseLocation();
5304 if (Tok.is(tok::colon)) {
5310 Data.RLoc = Tok.getLocation();
5311 if (!T.consumeClose())
5312 Data.RLoc = T.getCloseLocation();
5315 Vars.push_back(FirstExpr.
get());
5316 Vars.push_back(UpperBound.
get());
5317 Data.RLoc = Tok.getLocation();
5318 if (!T.consumeClose())
5319 Data.RLoc = T.getCloseLocation();
5322 if (Tok.is(tok::comma)) {
5323 Vars.push_back(FirstExpr.
get());
5324 while (Tok.is(tok::comma)) {
5328 Vars.push_back(NextExpr.
get());
5330 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5335 Data.RLoc = Tok.getLocation();
5336 bool HadError = T.consumeClose();
5338 Data.RLoc = T.getCloseLocation();
5343 Vars.push_back(FirstExpr.
get());
5344 Data.RLoc = Tok.getLocation();
5345 if (!T.consumeClose())
5346 Data.RLoc = T.getCloseLocation();
5351 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5352 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5353 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5354 (Kind == OMPC_reduction && !InvalidReductionId) ||
5358 (Kind == OMPC_adjust_args &&
5360 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5361 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5362 Tok.isNot(tok::annot_pragma_openmp_end))) {
5369 Vars.push_back(VarExpr.
get());
5371 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5376 IsComma = Tok.is(tok::comma);
5379 else if (Tok.isNot(tok::r_paren) &&
5380 Tok.isNot(tok::annot_pragma_openmp_end) &&
5381 (!MayHaveTail || Tok.isNot(tok::colon))) {
5382 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
5383 Diag(Tok, diag::err_omp_expected_punc)
5384 << ((Kind == OMPC_flush)
5385 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5386 : getOpenMPClauseName(Kind))
5387 << (Kind == OMPC_flush);
5392 if (NeedRParenForLinear)
5396 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5397 bool StepFound =
false;
5398 bool ModifierFound =
false;
5400 Data.ColonLoc = Tok.getLocation();
5403 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5404 bool Malformed =
false;
5405 while (Tok.isNot(tok::r_paren)) {
5406 if (Tok.is(tok::identifier)) {
5411 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5414 if (LinKind == OMPC_LINEAR_step) {
5416 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5419 tok::annot_pragma_openmp_end);
5423 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5428 Data.StepModifierLoc = StepModifierLoc;
5432 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5434 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5436 Data.ExtraModifier = LinKind;
5438 ModifierFound =
true;
5443 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5452 if (Tok.is(tok::comma))
5454 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5457 if (!Malformed && !StepFound && !ModifierFound)
5458 Diag(ELoc, diag::err_expected_expression);
5462 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5465 Data.DepModOrTailExpr = Tail.
get();
5467 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5473 Data.RLoc = Tok.getLocation();
5474 if (!T.consumeClose())
5475 Data.RLoc = T.getCloseLocation();
5479 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5481 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5482 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5509 "Expected parsing to start at clause name");
5514 if (T.consumeOpen()) {
5515 Diag(
Tok, diag::err_expected) << tok::l_paren;
5528 Exprs.push_back(Val.
get());
5531 bool Result = T.consumeClose();
5532 OpenLoc = T.getOpenLocation();
5533 CloseLoc = T.getCloseLocation();
Defines the clang::ASTContext interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
static OpenMPDirectiveKind checkOpenMPDirectiveName(Parser &P, SourceLocation Loc, OpenMPDirectiveKind Kind, StringRef Name)
static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P)
static OpenMPMapModifierKind isMapModifier(Parser &P)
Checks if the token is a valid map-type-modifier.
static std::optional< SimpleClauseData > parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind)
static bool checkExtensionProperty(Parser &P, SourceLocation Loc, OMPTraitProperty &TIProperty, OMPTraitSelector &TISelector, llvm::StringMap< SourceLocation > &Seen)
static ExprResult parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data)
Parse 'allocate' clause modifiers.
static DeclarationName parseOpenMPReductionId(Parser &P)
static ExprResult parseContextScore(Parser &P)
Parse optional 'score' '(' <expr> ')' ':'.
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, UnqualifiedId &ReductionId)
static bool parseStepSize(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data, OpenMPClauseKind CKind, SourceLocation ELoc)
Parse step size expression.
static void parseMapType(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data)
Parse map-type in map clause.
static bool parseDeclareSimdClauses(Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen, SmallVectorImpl< Expr * > &Uniforms, SmallVectorImpl< Expr * > &Aligneds, SmallVectorImpl< Expr * > &Alignments, SmallVectorImpl< Expr * > &Linears, SmallVectorImpl< unsigned > &LinModifiers, SmallVectorImpl< Expr * > &Steps)
Parses clauses for 'declare simd' directive.
static OpenMPMapClauseKind isMapType(Parser &P)
Checks if the token is a valid map-type.
This file declares semantic analysis functions specific to AMDGPU.
This file declares facilities that support code completion.
This file declares semantic analysis for OpenMP constructs and clauses.
Defines the clang::TokenKind enum and support functions.
VerifyDiagnosticConsumer::Directive Directive
void getAsVariantMatchInfo(ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const
Create a variant match info object from this trait info object.
llvm::SmallVector< OMPTraitSet, 2 > Sets
The outermost level of selector sets.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
DeclarationNameTable DeclarationNames
OMPTraitInfo & getNewOMPTraitInfo()
Return a new OMPTraitInfo object owned by this context.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
Represents a C++ nested-name-specifier or a global scope specifier.
bool isEmpty() const
No scope specifier.
static const TST TST_unspecified
Decl - This represents one declaration (or definition), e.g.
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
SourceLocation getLocation() const
DeclContext * getDeclContext()
The name of a declaration.
bool isEmpty() const
Evaluates true when this declaration name is empty.
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
This represents a decl that may have a name.
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
This is a basic class for representing single OpenMP clause.
static const ParsedAttributesView & none()
ParsedAttributes - A collection of parsed attributes.
Introduces zero or more scopes for parsing.
void Enter(unsigned ScopeFlags)
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, SmallVectorImpl< Expr * > &Vars, SemaOpenMP::OpenMPVarListDataTy &Data)
Parses clauses with list.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Preprocessor & getPreprocessor() const
bool parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data)
Parse map-type-modifiers in map clause.
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
ParseStringLiteralExpression - This handles the various token types that form string literals,...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
bool parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data)
Parses the mapper modifier in map, to, and from clauses.
friend class ParsingOpenMPDirectiveRAII
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
friend class ColonProtectionRAIIObject
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
const Token & getCurToken() const
void ExitScope()
ExitScope - Pop a scope off the scope stack.
ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc, bool IsAddressOfOperand=false)
Parses simple expression in parens for single-expression clauses of OpenMP constructs.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data, const LangOptions &LangOpts)
Parses a reserved locator like 'omp_all_memory'.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D)
Re-enter a possible template scope, creating as many template parameter scopes as necessary.
bool ParseOpenMPDeclareBeginVariantDirective(SourceLocation Loc)
Parses 'omp begin declare variant' directive.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
The collection of all-type qualifiers we support.
Represents a struct/union/class.
@ OpenMPDirectiveScope
This is the scope of OpenMP executable directive.
@ CompoundStmtScope
This is a compound statement scope.
@ OpenMPSimdDirectiveScope
This is the scope of some OpenMP simd directive.
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ OpenMPLoopDirectiveScope
This is the scope of some OpenMP loop directive.
@ DeclScope
This is a scope that can contain a declaration.
Smart pointer class that efficiently represents Objective-C method names.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
void ActOnExitFunctionContext()
void ActOnReenterFunctionContext(Scope *S, Decl *D)
Push the parameters of D, which must be a function, into scope.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
Token - This structure provides full information about a lexed token.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isNot(tok::TokenKind K) const
Base wrapper for a particular "section" of type source info.
The base class of the type hierarchy.
QualType getCanonicalTypeInternal() const
Represents a C++ unqualified-id that has been parsed.
void setOperatorFunctionId(SourceLocation OperatorLoc, OverloadedOperatorKind Op, SourceLocation SymbolLocations[3])
Specify that this unqualified-id was parsed as an operator-function-id.
Represents a variable declaration or definition.
Defines the clang::TargetInfo interface.
PRESERVE_NONE bool Ret(InterpState &S, CodePtr &PC)
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
OpenMPDefaultClauseVariableCategory
OpenMP variable-category for 'default' clause.
@ OMPC_DEFAULTMAP_MODIFIER_unknown
@ OMPC_ORDER_MODIFIER_unknown
@ OMPC_NEED_DEVICE_PTR_unknown
@ OMPC_ADJUST_ARGS_unknown
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
OpenMPDeviceType
OpenMP device type for 'device_type' clause.
@ OMPC_DEVICE_TYPE_unknown
@ OMPC_SCHEDULE_MODIFIER_unknown
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
@ OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown
@ OMPC_DYN_GROUPPRIVATE_FALLBACK_last
@ Property
The type of a property.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
@ OMPC_LASTPRIVATE_unknown
OpenMPGrainsizeClauseModifier
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str, const LangOptions &LangOpts)
OpenMPNumTasksClauseModifier
OpenMPUseDevicePtrFallbackModifier
OpenMP 6.1 use_device_ptr fallback modifier.
@ OMPC_USE_DEVICE_PTR_FALLBACK_unknown
@ Type
The name was classified as a type.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OpenMPMotionModifierKind
OpenMP modifier kind for 'to' or 'from' clause.
@ OMPC_MOTION_MODIFIER_unknown
@ OMPC_DEFAULTMAP_unknown
OpenMPAllocateClauseModifier
OpenMP modifiers for 'allocate' clause.
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "executable".
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
@ OMPC_DYN_GROUPPRIVATE_unknown
bool isOpenMPInformationalDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is considered as "informational".
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
OpenMPNumThreadsClauseModifier
@ OMPC_NUMTHREADS_unknown
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
@ OMPC_MAP_MODIFIER_unknown
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
ActionResult< Expr * > ExprResult
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
ActionResult< Stmt * > StmtResult
OpenMPDefaultClauseVariableCategory getOpenMPDefaultVariableCategory(StringRef Str, const LangOptions &LangOpts)
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
int const char * function
llvm::omp::TraitProperty Kind
StringRef RawString
The raw string as we parsed it. This is needed for the isa trait set (which accepts anything) and (la...
llvm::omp::TraitSelector Kind
SmallVector< OMPTraitProperty, 1 > Properties
SmallVector< OMPTraitSelector, 2 > Selectors
Clang specific specialization of the OMPContext to lookup target features.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
llvm::SmallVector< OMPInteropPref, 4 > Prefs
This structure contains most locations needed for by an OMPVarListClause.
std::optional< Expr * > Indirect
The directive with indirect clause.
OpenMPDirectiveKind Kind
The directive kind, begin declare target or declare target.
OMPDeclareTargetDeclAttr::DevTypeTy DT
The 'device_type' as parsed from the clause.
SourceLocation Loc
The directive location.
llvm::DenseMap< NamedDecl *, MapInfo > ExplicitlyMapped
Explicitly listed variables and functions in a 'to' or 'link' clause.
SourceLocation DeclIdentLoc
SourceLocation SecColonLoc
IdentifierInfo * DeclIdent
OMPIteratorExpr::IteratorRange Range
Data used for processing a list of variables in OpenMP clauses.
Data for list of allocators.
Expr * AllocatorTraits
Allocator traits.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Expr * Allocator
Allocator.