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) +
1290 if (Tok.is(tok::l_brace)) {
1291 (void)ConsumeBrace();
1293 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1295 << (
"'=' that follows the context set name \"" +
1296 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1300 llvm::StringMap<SourceLocation> SeenSelectors;
1302 OMPTraitSelector TISelector;
1303 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1304 if (TISelector.
Kind != TraitSelector::invalid &&
1310 if (Tok.is(tok::r_brace)) {
1311 (void)ConsumeBrace();
1313 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1315 << (
"context selectors for the context set \"" +
1316 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1321bool Parser::parseOMPContextSelectors(
SourceLocation Loc, OMPTraitInfo &TI) {
1322 llvm::StringMap<SourceLocation> SeenSets;
1325 parseOMPContextSelectorSet(TISet, SeenSets);
1326 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1327 TI.
Sets.push_back(TISet);
1336 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1337 PP.EnterToken(Tok,
true);
1338 PP.EnterTokenStream(Toks,
true,
1344 FNContextRAII FnContext(*
this, Ptr);
1346 SourceLocation RLoc;
1356 getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion), RLoc,
1359 if (!AssociatedFunction.
isUsable()) {
1360 if (!Tok.is(tok::annot_pragma_openmp_end))
1364 (void)ConsumeAnnotationToken();
1368 OMPTraitInfo *ParentTI =
1369 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
1370 ASTContext &ASTCtx = Actions.getASTContext();
1372 SmallVector<Expr *, 6> AdjustNothing;
1373 SmallVector<Expr *, 6> AdjustNeedDevicePtr;
1374 SmallVector<Expr *, 6> AdjustNeedDeviceAddr;
1375 SmallVector<OMPInteropInfo, 3> AppendArgs;
1376 SourceLocation AdjustArgsLoc, AppendArgsLoc;
1379 if (Tok.is(tok::annot_pragma_openmp_end)) {
1380 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1384 bool IsError =
false;
1385 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1388 : getOpenMPClauseKind(PP.getSpelling(Tok));
1389 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1391 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1398 IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1400 case OMPC_adjust_args: {
1401 AdjustArgsLoc = Tok.getLocation();
1403 SemaOpenMP::OpenMPVarListDataTy
Data;
1404 SmallVector<Expr *> Vars;
1408 switch (
Data.ExtraModifier) {
1409 case OMPC_ADJUST_ARGS_nothing:
1410 llvm::append_range(AdjustNothing, Vars);
1412 case OMPC_ADJUST_ARGS_need_device_ptr:
1413 llvm::append_range(AdjustNeedDevicePtr, Vars);
1415 case OMPC_ADJUST_ARGS_need_device_addr:
1416 llvm::append_range(AdjustNeedDeviceAddr, Vars);
1419 llvm_unreachable(
"Unexpected 'adjust_args' clause modifier.");
1424 case OMPC_append_args:
1425 if (!AppendArgs.empty()) {
1426 Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1427 << getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion)
1428 << getOpenMPClauseName(CKind) << 0;
1432 AppendArgsLoc = Tok.getLocation();
1434 IsError = parseOpenMPAppendArgs(AppendArgs);
1438 llvm_unreachable(
"Unexpected clause for declare variant.");
1445 (void)ConsumeAnnotationToken();
1449 if (Tok.is(tok::comma))
1453 std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1454 Actions.OpenMP().checkOpenMPDeclareVariantFunction(
1455 Ptr, AssociatedFunction.
get(), TI, AppendArgs.size(),
1456 SourceRange(Loc, Tok.getLocation()));
1458 if (DeclVarData && !TI.
Sets.empty())
1459 Actions.OpenMP().ActOnOpenMPDeclareVariantDirective(
1460 DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1461 AdjustNeedDevicePtr, AdjustNeedDeviceAddr, AppendArgs, AdjustArgsLoc,
1462 AppendArgsLoc, SourceRange(Loc, Tok.getLocation()));
1465 (void)ConsumeAnnotationToken();
1468bool Parser::parseOpenMPAppendArgs(
1470 bool HasError =
false;
1473 if (T.expectAndConsume(diag::err_expected_lparen_after,
1474 getOpenMPClauseName(OMPC_append_args).data()))
1479 while (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"interop")) {
1482 tok::annot_pragma_openmp_end);
1483 if (IT.expectAndConsume(diag::err_expected_lparen_after,
"interop"))
1486 OMPInteropInfo InteropInfo;
1487 if (ParseOMPInteropInfo(InteropInfo, OMPC_append_args))
1490 InteropInfos.push_back(InteropInfo);
1493 if (Tok.is(tok::comma))
1496 if (!HasError && InteropInfos.empty()) {
1498 Diag(Tok.getLocation(), diag::err_omp_unexpected_append_op);
1499 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1502 HasError = T.consumeClose() || HasError;
1506bool Parser::parseOMPDeclareVariantMatchClause(
SourceLocation Loc,
1508 OMPTraitInfo *ParentTI) {
1512 : getOpenMPClauseKind(PP.getSpelling(Tok));
1513 if (CKind != OMPC_match) {
1514 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1521 if (T.expectAndConsume(diag::err_expected_lparen_after,
1522 getOpenMPClauseName(OMPC_match).data()))
1526 parseOMPContextSelectors(Loc, TI);
1529 (void)T.consumeClose();
1539 for (
const OMPTraitSet &ParentSet : ParentTI->
Sets) {
1540 bool MergedSet =
false;
1541 for (OMPTraitSet &
Set : TI.
Sets) {
1542 if (
Set.Kind != ParentSet.
Kind)
1545 for (
const OMPTraitSelector &ParentSelector : ParentSet.
Selectors) {
1546 bool MergedSelector =
false;
1547 for (OMPTraitSelector &Selector :
Set.Selectors) {
1548 if (Selector.
Kind != ParentSelector.
Kind)
1550 MergedSelector =
true;
1551 for (
const OMPTraitProperty &ParentProperty :
1553 bool MergedProperty =
false;
1567 if (Selector.
Kind == llvm::omp::TraitSelector::user_condition) {
1568 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1571 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1572 << getOpenMPContextTraitPropertyName(
1574 << getOpenMPContextTraitSelectorName(ParentSelector.
Kind)
1575 << getOpenMPContextTraitSetName(ParentSet.
Kind);
1578 if (!MergedProperty)
1579 Selector.
Properties.push_back(ParentProperty);
1582 if (!MergedSelector)
1583 Set.Selectors.push_back(ParentSelector);
1587 TI.
Sets.push_back(ParentSet);
1596 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
1597 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1600 : getOpenMPClauseKind(PP.getSpelling(Tok));
1601 Actions.OpenMP().StartOpenMPClause(CKind);
1603 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
1604 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1606 SeenClauses[unsigned(CKind)] =
true;
1607 if (Clause !=
nullptr)
1608 Clauses.push_back(Clause);
1609 if (Tok.is(tok::annot_pragma_openmp_end)) {
1610 Actions.OpenMP().EndOpenMPClause();
1614 if (Tok.is(tok::comma))
1616 Actions.OpenMP().EndOpenMPClause();
1622 SmallVector<std::string, 4> Assumptions;
1623 bool SkippedClauses =
false;
1625 auto SkipBraces = [&](llvm::StringRef Spelling,
bool IssueNote) {
1627 tok::annot_pragma_openmp_end);
1628 if (T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1631 if (IssueNote && T.getCloseLocation().isValid())
1632 Diag(T.getCloseLocation(),
1633 diag::note_omp_assumption_clause_continue_here);
1639 auto MatchACMClause = [&](StringRef RawString) {
1640 llvm::StringSwitch<int> SS(RawString);
1641 unsigned ACMIdx = 0;
1642 for (
const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1643 if (ACMI.StartsWith)
1644 SS.StartsWith(ACMI.Identifier, ACMIdx++);
1646 SS.Case(ACMI.Identifier, ACMIdx++);
1648 return SS.Default(-1);
1651 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1652 IdentifierInfo *II =
nullptr;
1653 SourceLocation StartLoc = Tok.getLocation();
1655 if (Tok.isAnyIdentifier()) {
1656 II = Tok.getIdentifierInfo();
1657 Idx = MatchACMClause(II->
getName());
1661 bool NextIsLPar = Tok.is(tok::l_paren);
1664 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1665 Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1666 << llvm::omp::getOpenMPDirectiveName(DKind, OMPVersion)
1667 << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1669 SkipBraces(II ? II->
getName() :
"",
true);
1670 SkippedClauses =
true;
1673 const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1674 if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1677 SkippedClauses =
true;
1678 SkipBraces(II->
getName(),
false);
1683 Diag(Tok.getLocation(),
1684 diag::warn_omp_unknown_assumption_clause_without_args)
1686 SkipBraces(II->
getName(),
true);
1689 assert(II &&
"Expected an identifier clause!");
1690 std::string Assumption = II->
getName().str();
1691 if (ACMI.StartsWith)
1692 Assumption =
"ompx_" + Assumption.substr(ACMI.Identifier.size());
1694 Assumption =
"omp_" + Assumption;
1695 Assumptions.push_back(Assumption);
1698 Actions.OpenMP().ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions,
1703 if (Actions.OpenMP().isInOpenMPAssumeScope())
1704 Actions.OpenMP().ActOnOpenMPEndAssumesDirective();
1706 Diag(Loc, diag::err_expected_begin_assumes);
1720struct SimpleClauseData {
1723 SourceLocation LOpen;
1724 SourceLocation TypeLoc;
1725 SourceLocation RLoc;
1726 SimpleClauseData(
unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1727 SourceLocation TypeLoc, SourceLocation RLoc)
1728 :
Type(
Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1732static std::optional<SimpleClauseData>
1739 if (T.expectAndConsume(diag::err_expected_lparen_after,
1740 getOpenMPClauseName(Kind).data()))
1741 return std::nullopt;
1747 if (
Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::comma) &&
1748 Tok.isNot(tok::annot_pragma_openmp_end))
1753 if (!T.consumeClose())
1754 RLoc = T.getCloseLocation();
1756 return SimpleClauseData(
Type, Loc, LOpen,
TypeLoc, RLoc);
1759void Parser::ParseOMPDeclareTargetClauses(
1761 SourceLocation DeviceTypeLoc;
1762 bool RequiresToLinkLocalOrIndirectClause =
false;
1763 bool HasToLinkLocalOrIndirectClause =
false;
1764 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1765 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1766 bool HasIdentifier = Tok.is(tok::identifier);
1767 if (HasIdentifier) {
1769 RequiresToLinkLocalOrIndirectClause =
true;
1770 IdentifierInfo *II = Tok.getIdentifierInfo();
1771 StringRef ClauseName = II->
getName();
1772 bool IsDeviceTypeClause =
1774 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1776 bool IsIndirectClause =
getLangOpts().OpenMP >= 51 &&
1777 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1779 if (DTCI.
Indirect && IsIndirectClause) {
1780 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1781 Diag(Tok, diag::err_omp_more_one_clause)
1782 << getOpenMPDirectiveName(OMPD_declare_target, OMPVersion)
1783 << getOpenMPClauseName(OMPC_indirect) << 0;
1786 bool IsToEnterLinkOrLocalClause =
1787 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1788 assert((!IsDeviceTypeClause || !IsToEnterLinkOrLocalClause) &&
1793 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1794 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1797 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1798 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1803 if (
getLangOpts().OpenMP < 60 && ClauseName ==
"local") {
1805 ? diag::err_omp_declare_target_unexpected_clause_52
1806 : diag::err_omp_declare_target_unexpected_clause)
1814 if (!IsDeviceTypeClause && !IsIndirectClause &&
1815 DTCI.
Kind == OMPD_begin_declare_target) {
1817 ? diag::err_omp_declare_target_unexpected_clause_52
1818 : diag::err_omp_declare_target_unexpected_clause)
1819 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1823 if (!IsDeviceTypeClause && !IsToEnterLinkOrLocalClause &&
1824 !IsIndirectClause) {
1826 ? diag::err_omp_declare_target_unexpected_clause_52
1827 : diag::err_omp_declare_target_unexpected_clause)
1836 if (IsToEnterLinkOrLocalClause || IsIndirectClause)
1837 HasToLinkLocalOrIndirectClause =
true;
1839 if (IsIndirectClause) {
1840 if (!ParseOpenMPIndirectClause(DTCI,
false))
1845 if (IsDeviceTypeClause) {
1846 std::optional<SimpleClauseData> DevTypeData =
1849 if (DeviceTypeLoc.
isValid()) {
1851 Diag(DevTypeData->Loc,
1852 diag::warn_omp_more_one_device_type_clause);
1856 case OMPC_DEVICE_TYPE_any:
1857 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Any;
1859 case OMPC_DEVICE_TYPE_host:
1860 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Host;
1862 case OMPC_DEVICE_TYPE_nohost:
1863 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1866 llvm_unreachable(
"Unexpected device_type");
1868 DeviceTypeLoc = DevTypeData->Loc;
1875 if (DTCI.
Kind == OMPD_declare_target || HasIdentifier) {
1876 auto &&Callback = [
this, MT, &DTCI](CXXScopeSpec &SS,
1877 DeclarationNameInfo NameInfo) {
1878 NamedDecl *ND = Actions.OpenMP().lookupOpenMPDeclareTargetName(
1882 SemaOpenMP::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.
getLoc()};
1885 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1888 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1893 if (Tok.is(tok::l_paren)) {
1895 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1898 if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1901 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1902 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1907 if (Tok.is(tok::comma))
1911 if (DTCI.
Indirect && DTCI.
DT != OMPDeclareTargetDeclAttr::DT_Any)
1912 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1915 if (DTCI.
Kind == OMPD_declare_target && RequiresToLinkLocalOrIndirectClause &&
1916 !HasToLinkLocalOrIndirectClause)
1917 Diag(DTCI.
Loc, diag::err_omp_declare_target_missing_required_clause)
1929 if (Tok.is(tok::annot_pragma_openmp_end))
1932 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1933 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1934 << getOpenMPDirectiveName(DKind, OMPVersion);
1935 while (Tok.isNot(tok::annot_pragma_openmp_end))
1944 bool SkipUntilOpenMPEnd) {
1945 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1947 if (FoundKind == ExpectedKind) {
1949 skipUntilPragmaOpenMPEnd(ExpectedKind);
1953 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1954 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1956 Diag(BeginLoc, diag::note_matching)
1957 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind, OMPVersion) +
"'")
1959 if (SkipUntilOpenMPEnd)
1966 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1970 if (Tok.is(tok::annot_pragma_openmp_end))
1971 ConsumeAnnotationToken();
1977 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
1978 "Not an OpenMP directive!");
1981 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1986 TentativeParsingAction TPA(*
this);
1987 Loc = ConsumeAnnotationToken();
1989 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1994 Toks.push_back(Tok);
1995 while (Cnt && Tok.isNot(tok::eof)) {
1997 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
1999 else if (Tok.is(tok::annot_pragma_openmp_end))
2001 Toks.push_back(Tok);
2006 auto *LP =
new LateParsedPragma(
this, AS);
2008 getCurrentClass().LateParsedDeclarations.push_back(LP);
2013 Loc = ConsumeAnnotationToken();
2018 case OMPD_threadprivate: {
2020 DeclDirectiveListParserHelper Helper(
this, DKind);
2021 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2023 skipUntilPragmaOpenMPEnd(DKind);
2025 ConsumeAnnotationToken();
2026 return Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2027 Loc, Helper.getIdentifiers());
2031 case OMPD_groupprivate: {
2033 DeclDirectiveListParserHelper Helper(
this, DKind);
2034 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2036 skipUntilPragmaOpenMPEnd(DKind);
2038 ConsumeAnnotationToken();
2039 return Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2040 Loc, Helper.getIdentifiers());
2044 case OMPD_allocate: {
2046 DeclDirectiveListParserHelper Helper(
this, DKind);
2047 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2049 SmallVector<OMPClause *, 1> Clauses;
2050 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2051 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
2052 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2054 Tok.isAnnotation() ? OMPC_unknown
2055 : getOpenMPClauseKind(PP.getSpelling(Tok));
2056 Actions.OpenMP().StartOpenMPClause(CKind);
2057 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2058 !SeenClauses[
unsigned(CKind)]);
2059 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2061 SeenClauses[unsigned(CKind)] =
true;
2062 if (Clause !=
nullptr)
2063 Clauses.push_back(Clause);
2064 if (Tok.is(tok::annot_pragma_openmp_end)) {
2065 Actions.OpenMP().EndOpenMPClause();
2069 if (Tok.is(tok::comma))
2071 Actions.OpenMP().EndOpenMPClause();
2073 skipUntilPragmaOpenMPEnd(DKind);
2076 ConsumeAnnotationToken();
2077 return Actions.OpenMP().ActOnOpenMPAllocateDirective(
2078 Loc, Helper.getIdentifiers(), Clauses);
2082 case OMPD_requires: {
2084 SmallVector<OMPClause *, 5> Clauses;
2085 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2086 if (Tok.is(tok::annot_pragma_openmp_end)) {
2087 Diag(Tok, diag::err_omp_expected_clause)
2088 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2091 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2094 : getOpenMPClauseKind(PP.getSpelling(Tok));
2095 Actions.OpenMP().StartOpenMPClause(CKind);
2096 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
2097 !SeenClauses[
unsigned(CKind)]);
2098 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2100 SeenClauses[unsigned(CKind)] =
true;
2101 if (Clause !=
nullptr)
2102 Clauses.push_back(Clause);
2103 if (Tok.is(tok::annot_pragma_openmp_end)) {
2104 Actions.OpenMP().EndOpenMPClause();
2108 if (Tok.is(tok::comma))
2110 Actions.OpenMP().EndOpenMPClause();
2113 if (Clauses.empty()) {
2114 Diag(Tok, diag::err_omp_expected_clause)
2115 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2116 ConsumeAnnotationToken();
2119 ConsumeAnnotationToken();
2120 return Actions.OpenMP().ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2123 SmallVector<OMPClause *, 1> Clauses;
2125 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2126 Actions.OpenMP().ActOnOpenMPErrorDirective(Clauses, StartLoc,
2132 case OMPD_begin_assumes:
2135 case OMPD_end_assumes:
2138 case OMPD_declare_reduction:
2140 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2141 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2143 ConsumeAnnotationToken();
2147 case OMPD_declare_mapper: {
2149 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2151 ConsumeAnnotationToken();
2156 case OMPD_begin_declare_variant: {
2161 ConsumeAnnotationToken();
2165 case OMPD_end_declare_variant: {
2167 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2168 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2170 Diag(Loc, diag::err_expected_begin_declare_variant);
2172 ConsumeAnnotationToken();
2175 case OMPD_declare_variant:
2176 case OMPD_declare_simd: {
2182 Toks.push_back(Tok);
2184 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2185 Toks.push_back(Tok);
2188 Toks.push_back(Tok);
2192 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2193 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2195 }
else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2199 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2200 MaybeParseCXX11Attributes(Attrs);
2201 ParsingDeclSpec PDS(*
this);
2202 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2205 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2209 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2210 << (DKind == OMPD_declare_simd ? 0 : 1);
2213 if (DKind == OMPD_declare_simd)
2214 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2215 assert(DKind == OMPD_declare_variant &&
2216 "Expected declare variant directive only");
2217 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2220 case OMPD_begin_declare_target:
2221 case OMPD_declare_target: {
2223 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2224 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2225 if (DKind == OMPD_declare_target && !HasClauses &&
2227 Diag(DTLoc, diag::warn_omp_deprecated_declare_target_delimited_form);
2229 ParseOMPDeclareTargetClauses(DTCI);
2230 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2237 if (HasImplicitMappings) {
2238 Actions.OpenMP().ActOnStartOpenMPDeclareTargetContext(DTCI);
2242 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2243 llvm::SmallVector<Decl *, 4> Decls;
2245 Decls.push_back(It.first);
2246 return Actions.BuildDeclaratorGroup(Decls);
2248 case OMPD_end_declare_target: {
2249 if (!Actions.OpenMP().isInOpenMPDeclareTargetContext()) {
2250 Diag(Tok, diag::err_omp_unexpected_directive)
2251 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2254 const SemaOpenMP::DeclareTargetContextInfo &DTCI =
2255 Actions.OpenMP().ActOnOpenMPEndDeclareTargetDirective();
2256 ParseOMPEndDeclareTargetDirective(DTCI.
Kind, DKind, DTCI.
Loc);
2260 Diag(Tok, diag::err_omp_unexpected_directive)
2261 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2265 Diag(Tok, diag::err_omp_unknown_directive);
2268 switch (getDirectiveCategory(DKind)) {
2269 case Category::Executable:
2270 case Category::Meta:
2271 case Category::Subsidiary:
2272 case Category::Utility:
2273 Diag(Tok, diag::err_omp_unexpected_directive)
2274 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2276 case Category::Declarative:
2277 case Category::Informational:
2281 while (Tok.isNot(tok::annot_pragma_openmp_end))
2287StmtResult Parser::ParseOpenMPExecutableDirective(
2289 bool ReadDirectiveWithinMetadirective) {
2291 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2293 bool HasAssociatedStatement =
true;
2294 Association Assoc = getDirectiveAssociation(DKind);
2300 if (DKind != OMPD_ordered && DKind != OMPD_section &&
2301 (Assoc == Association::None || Assoc == Association::Separating)) {
2302 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2303 ParsedStmtContext()) {
2304 Diag(Tok, diag::err_omp_immediate_directive)
2305 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2306 if (DKind == OMPD_error) {
2307 SkipUntil(tok::annot_pragma_openmp_end);
2311 HasAssociatedStatement =
false;
2314 SourceLocation EndLoc;
2315 SmallVector<OMPClause *, 5> Clauses;
2316 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2317 DeclarationNameInfo DirName;
2324 bool ImplicitClauseAllowed =
false;
2325 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2327 ImplicitClauseAllowed =
true;
2331 if (DKind == OMPD_critical) {
2333 tok::annot_pragma_openmp_end);
2334 if (!T.consumeOpen()) {
2335 if (Tok.isAnyIdentifier()) {
2337 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2340 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2344 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2346 if (Tok.isNot(tok::annot_pragma_openmp_end))
2354 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2355 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2358 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2361 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2362 while (Tok.isNot(tok::annot_pragma_openmp_end))
2366 bool HasImplicitClause =
false;
2367 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2368 HasImplicitClause =
true;
2371 PP.EnterToken(Tok,
true);
2372 PP.EnterToken(ImplicitTok,
true);
2377 : getOpenMPClauseKind(PP.getSpelling(Tok));
2378 if (HasImplicitClause) {
2379 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2380 if (DKind == OMPD_flush) {
2383 assert(DKind == OMPD_depobj &&
"Expected flush or depobj directives.");
2384 CKind = OMPC_depobj;
2388 ImplicitClauseAllowed =
false;
2389 Actions.OpenMP().StartOpenMPClause(CKind);
2390 HasImplicitClause =
false;
2391 SourceLocation ClauseLoc = Tok.getLocation();
2394 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2395 SeenClauses[unsigned(CKind)] =
true;
2397 Clauses.push_back(Clause);
2400 if (Tok.is(tok::comma))
2402 Actions.OpenMP().EndOpenMPClause();
2406 if (Tok.getLocation() == ClauseLoc) {
2407 skipUntilPragmaOpenMPEnd(DKind);
2412 EndLoc = Tok.getLocation();
2414 ConsumeAnnotationToken();
2416 if (DKind == OMPD_ordered) {
2419 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2420 if (SeenClauses[
unsigned(CK)]) {
2421 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2422 ParsedStmtContext()) {
2423 Diag(Loc, diag::err_omp_immediate_directive)
2424 << getOpenMPDirectiveName(DKind, OMPVersion) << 1
2425 << getOpenMPClauseName(CK);
2427 HasAssociatedStatement =
false;
2432 if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
2433 !SeenClauses[
unsigned(OMPC_sizes)]) {
2434 Diag(Loc, diag::err_omp_required_clause)
2435 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"sizes";
2437 if (DKind == OMPD_split && !SeenClauses[
unsigned(OMPC_counts)]) {
2438 Diag(Loc, diag::err_omp_required_clause)
2439 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"counts";
2443 if (HasAssociatedStatement) {
2445 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2451 Sema::CompoundScopeRAII Scope(Actions);
2452 AssociatedStmt = ParseStatement();
2457 Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
2460 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2461 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2462 DKind == OMPD_target_exit_data) {
2463 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2464 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2465 Actions.ActOnCompoundStmt(Loc, Loc, {},
2468 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2472 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2475 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2476 OMPDirectiveScope.Exit();
2481StmtResult Parser::ParseOpenMPInformationalDirective(
2483 bool ReadDirectiveWithinMetadirective) {
2485 "Unexpected directive category");
2487 bool HasAssociatedStatement =
true;
2489 SmallVector<OMPClause *, 5> Clauses;
2490 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2491 DeclarationNameInfo DirName;
2494 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2496 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2499 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2500 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2501 while (Tok.isNot(tok::annot_pragma_openmp_end))
2508 : getOpenMPClauseKind(PP.getSpelling(Tok));
2509 Actions.OpenMP().StartOpenMPClause(CKind);
2511 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2512 SeenClauses[unsigned(CKind)] =
true;
2514 Clauses.push_back(Clause);
2516 if (Tok.is(tok::comma))
2518 Actions.OpenMP().EndOpenMPClause();
2521 SourceLocation EndLoc = Tok.getLocation();
2522 ConsumeAnnotationToken();
2525 if (HasAssociatedStatement) {
2526 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2529 Sema::CompoundScopeRAII Scope(Actions);
2530 AssociatedStmt = ParseStatement();
2533 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2537 DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2539 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2540 OMPDirectiveScope.Exit();
2545StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2546 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2547 if (!ReadDirectiveWithinMetadirective)
2548 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2549 "Not an OpenMP directive!");
2552 SourceLocation Loc = ReadDirectiveWithinMetadirective
2554 : ConsumeAnnotationToken();
2555 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2557 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2558 Diag(Tok, diag::err_omp_unknown_directive);
2564 bool IsExecutable = [&]() {
2565 if (DKind == OMPD_error)
2567 auto Res = getDirectiveCategory(DKind);
2568 return Res == Category::Executable || Res == Category::Subsidiary;
2572 Directive = ParseOpenMPExecutableDirective(
2573 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2574 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2583 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
2584 while (Tok.isNot(tok::annot_pragma_openmp_end))
2587 skipUntilPragmaOpenMPEnd(DKind);
2588 if (Tok.is(tok::annot_pragma_openmp_end))
2589 ConsumeAnnotationToken();
2592 case OMPD_metadirective: {
2594 SmallVector<VariantMatchInfo, 4> VMIs;
2599 TentativeParsingAction TPA(*
this);
2600 ASTContext &ASTContext = Actions.getASTContext();
2603 tok::annot_pragma_openmp_end);
2604 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2607 : getOpenMPClauseKind(PP.getSpelling(Tok));
2609 if (CKind == OMPC_unknown) {
2610 Diag(Tok, diag::err_omp_expected_clause) <<
"metadirective";
2612 SkipUntil(tok::annot_pragma_openmp_end);
2615 if (
getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
2616 Diag(Tok, diag::err_omp_unexpected_clause)
2617 << getOpenMPClauseName(CKind) <<
"metadirective";
2618 if (CKind == OMPC_default &&
getLangOpts().OpenMP >= 52)
2619 Diag(Tok, diag::warn_omp_default_deprecated);
2624 if (T.expectAndConsume(diag::err_expected_lparen_after,
2625 getOpenMPClauseName(CKind).data())) {
2627 SkipUntil(tok::annot_pragma_openmp_end);
2631 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2632 if (CKind == OMPC_when) {
2634 parseOMPContextSelectors(Loc, TI);
2635 if (TI.
Sets.size() == 0) {
2636 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2642 if (Tok.is(tok::colon))
2645 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2653 while (Tok.isNot(tok::r_paren) || paren != 0) {
2654 if (Tok.is(tok::l_paren))
2656 if (Tok.is(tok::r_paren))
2658 if (Tok.is(tok::annot_pragma_openmp_end)) {
2659 Diag(Tok, diag::err_omp_expected_punc)
2660 << getOpenMPClauseName(CKind) << 0;
2667 if (Tok.is(tok::r_paren))
2670 VariantMatchInfo VMI;
2673 VMIs.push_back(VMI);
2680 [
this, Loc](StringRef ISATrait) {
2683 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2685 TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2687 ArrayRef<llvm::omp::TraitProperty>(),
2688 Actions.OpenMP().getOpenMPDeviceNum());
2691 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2698 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2700 if (Idx++ != BestIdx) {
2705 while (Tok.isNot(tok::r_paren) || paren != 0) {
2706 if (Tok.is(tok::l_paren))
2708 if (Tok.is(tok::r_paren))
2713 if (Tok.is(tok::r_paren))
2720 : getOpenMPClauseKind(PP.getSpelling(Tok));
2727 if (CKind == OMPC_when) {
2728 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2730 parseOMPContextSelectors(Loc, TI);
2738 if (Tok.is(tok::r_paren)) {
2739 SkipUntil(tok::annot_pragma_openmp_end);
2744 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2752 if (BestIdx == -1 && Idx > 0) {
2753 assert(Tok.is(tok::annot_pragma_openmp_end) &&
2754 "Expecting the end of the pragma here");
2755 ConsumeAnnotationToken();
2760 case OMPD_threadprivate: {
2762 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2763 ParsedStmtContext()) {
2764 Diag(Tok, diag::err_omp_immediate_directive)
2765 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2768 DeclDirectiveListParserHelper Helper(
this, DKind);
2769 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2771 skipUntilPragmaOpenMPEnd(DKind);
2772 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2773 Loc, Helper.getIdentifiers());
2774 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2776 SkipUntil(tok::annot_pragma_openmp_end);
2779 case OMPD_groupprivate: {
2780 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2781 ParsedStmtContext()) {
2782 Diag(Tok, diag::err_omp_immediate_directive)
2783 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2786 DeclDirectiveListParserHelper Helper(
this, DKind);
2787 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2789 skipUntilPragmaOpenMPEnd(DKind);
2790 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2791 Loc, Helper.getIdentifiers());
2792 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2794 SkipUntil(tok::annot_pragma_openmp_end);
2797 case OMPD_allocate: {
2799 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2800 ParsedStmtContext()) {
2801 Diag(Tok, diag::err_omp_immediate_directive)
2802 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2805 DeclDirectiveListParserHelper Helper(
this, DKind);
2806 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2808 SmallVector<OMPClause *, 1> Clauses;
2809 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2810 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2811 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2813 Tok.isAnnotation() ? OMPC_unknown
2814 : getOpenMPClauseKind(PP.getSpelling(Tok));
2815 Actions.OpenMP().StartOpenMPClause(CKind);
2816 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2817 !SeenClauses[
unsigned(CKind)]);
2818 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2820 SeenClauses[unsigned(CKind)] =
true;
2821 if (Clause !=
nullptr)
2822 Clauses.push_back(Clause);
2823 if (Tok.is(tok::annot_pragma_openmp_end)) {
2824 Actions.OpenMP().EndOpenMPClause();
2828 if (Tok.is(tok::comma))
2830 Actions.OpenMP().EndOpenMPClause();
2832 skipUntilPragmaOpenMPEnd(DKind);
2834 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPAllocateDirective(
2835 Loc, Helper.getIdentifiers(), Clauses);
2836 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2838 SkipUntil(tok::annot_pragma_openmp_end);
2841 case OMPD_declare_reduction:
2844 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2845 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2847 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2849 SkipUntil(tok::annot_pragma_openmp_end);
2852 case OMPD_declare_mapper: {
2855 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2857 ConsumeAnnotationToken();
2858 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2860 SkipUntil(tok::annot_pragma_openmp_end);
2864 case OMPD_declare_target: {
2866 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2867 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2869 ParseOMPDeclareTargetClauses(DTCI);
2870 bool HasImplicitMappings =
2873 if (HasImplicitMappings) {
2874 Diag(Tok, diag::err_omp_unexpected_directive)
2875 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2876 SkipUntil(tok::annot_pragma_openmp_end);
2883 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2886 case OMPD_begin_declare_variant: {
2891 ConsumeAnnotationToken();
2895 case OMPD_end_declare_variant: {
2897 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2898 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2900 Diag(Loc, diag::err_expected_begin_declare_variant);
2901 ConsumeAnnotationToken();
2904 case OMPD_declare_simd:
2905 case OMPD_begin_declare_target:
2906 case OMPD_end_declare_target:
2908 case OMPD_declare_variant:
2909 Diag(Tok, diag::err_omp_unexpected_directive)
2910 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2911 SkipUntil(tok::annot_pragma_openmp_end);
2915 Directive = ParseOpenMPInformationalDirective(
2916 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2918 "Informational directive remains unprocessed");
2923 Diag(Tok, diag::err_omp_unknown_directive);
2924 SkipUntil(tok::annot_pragma_openmp_end);
2930bool Parser::ParseOpenMPSimpleVarList(
2934 bool AllowScopeSpecifier) {
2935 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2938 if (T.expectAndConsume(diag::err_expected_lparen_after,
2939 getOpenMPDirectiveName(Kind, OMPVersion).data()))
2941 bool IsCorrect =
true;
2942 bool NoIdentIsFound =
true;
2945 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2949 Token PrevTok = Tok;
2950 NoIdentIsFound =
false;
2953 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2956 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2959 false,
false,
false,
2960 false,
false,
nullptr, Name)) {
2962 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2964 }
else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2965 Tok.isNot(tok::annot_pragma_openmp_end)) {
2967 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2971 << SourceRange(PrevTok.
getLocation(), PrevTokLocation);
2973 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2976 if (Tok.is(tok::comma)) {
2981 if (NoIdentIsFound) {
2982 Diag(Tok, diag::err_expected) << tok::identifier;
2987 IsCorrect = !T.consumeClose() && IsCorrect;
2992OMPClause *Parser::ParseOpenMPSizesClause() {
2993 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
2994 SmallVector<Expr *, 4> ValExprs;
2995 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
2999 return Actions.OpenMP().ActOnOpenMPSizesClause(ValExprs, ClauseNameLoc,
3003OMPClause *Parser::ParseOpenMPCountsClause() {
3004 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3005 SmallVector<Expr *, 4> ValExprs;
3006 std::optional<unsigned> FillIdx;
3007 unsigned FillCount = 0;
3008 SourceLocation FillLoc;
3010 assert(getOpenMPClauseName(OMPC_counts) == PP.getSpelling(Tok) &&
3011 "Expected parsing to start at clause name");
3015 if (T.consumeOpen()) {
3016 Diag(Tok, diag::err_expected) << tok::l_paren;
3021 if (Tok.is(tok::identifier) &&
3022 Tok.getIdentifierInfo()->getName() ==
"omp_fill") {
3024 FillIdx = ValExprs.size();
3026 FillLoc = Tok.getLocation();
3028 ValExprs.push_back(
nullptr);
3035 ValExprs.push_back(Val.
get());
3039 if (T.consumeClose())
3041 OpenLoc = T.getOpenLocation();
3042 CloseLoc = T.getCloseLocation();
3044 return Actions.OpenMP().ActOnOpenMPCountsClause(
3045 ValExprs, ClauseNameLoc, OpenLoc, CloseLoc, FillIdx, FillLoc, FillCount);
3048OMPClause *Parser::ParseOpenMPLoopRangeClause() {
3050 SourceLocation FirstLoc, CountLoc;
3053 if (T.consumeOpen()) {
3054 Diag(Tok, diag::err_expected) << tok::l_paren;
3058 FirstLoc = Tok.getLocation();
3065 ExpectAndConsume(tok::comma);
3067 CountLoc = Tok.getLocation();
3076 return Actions.OpenMP().ActOnOpenMPLoopRangeClause(
3077 FirstVal.
get(), CountVal.
get(), ClauseNameLoc, T.getOpenLocation(),
3078 FirstLoc, CountLoc, T.getCloseLocation());
3081OMPClause *Parser::ParseOpenMPPermutationClause() {
3082 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3083 SmallVector<Expr *> ArgExprs;
3084 if (ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,
3089 return Actions.OpenMP().ActOnOpenMPPermutationClause(ArgExprs, ClauseNameLoc,
3094 SourceLocation Loc = Tok.getLocation();
3099 if (T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3101 SmallVector<SemaOpenMP::UsesAllocatorsData, 4>
Data;
3104 if (
getLangOpts().OpenMP >= 52 && Tok.is(tok::identifier) &&
3105 Tok.getIdentifierInfo()->getName() ==
"traits") {
3107 SemaOpenMP::UsesAllocatorsData &D =
Data.emplace_back();
3113 tok::annot_pragma_openmp_end);
3114 TraitParens.consumeOpen();
3117 TraitParens.consumeClose();
3121 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3127 if (Tok.isNot(tok::colon)) {
3128 Diag(Tok, diag::err_expected) << tok::colon;
3130 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3139 ? ParseCXXIdExpression()
3140 : tryParseCXXIdExpression(SS,
false);
3144 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3151 D.
LParenLoc = TraitParens.getOpenLocation();
3152 D.
RParenLoc = TraitParens.getCloseLocation();
3155 if (Tok.is(tok::comma)) {
3157 Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3160 }
else if (Tok.is(tok::semi)) {
3170 getLangOpts().CPlusPlus
3171 ? ParseCXXIdExpression()
3172 : tryParseCXXIdExpression(SS,
false);
3174 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3181 BalancedDelimiterTracker T(*this, tok::l_paren,
3182 tok::annot_pragma_openmp_end);
3184 ExprResult AllocatorTraits =
3185 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3187 if (AllocatorTraits.isInvalid()) {
3188 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3197 if (getLangOpts().OpenMP >= 52) {
3198 Diag(Loc, diag::err_omp_deprecate_old_syntax)
3199 <<
"allocator(expr)"
3200 <<
"uses_allocators"
3201 <<
"traits(expr): alloc";
3205 Diag(
Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3207 if (
Tok.
is(tok::comma))
3209 }
while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end));
3212 Loc, T.getOpenLocation(), T.getCloseLocation(),
Data);
3217 OMPClauseKind = CKind;
3218 OMPClause *Clause =
nullptr;
3219 bool ErrorFound =
false;
3220 bool WrongDirective =
false;
3221 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
3224 if (CKind != OMPC_unknown &&
3225 !isAllowedClauseForDirective(DKind, CKind,
getLangOpts().OpenMP)) {
3226 Diag(Tok, diag::err_omp_unexpected_clause)
3227 << getOpenMPClauseName(CKind)
3228 << getOpenMPDirectiveName(DKind, OMPVersion);
3230 WrongDirective =
true;
3235 case OMPC_num_threads:
3241 case OMPC_grainsize:
3242 case OMPC_num_tasks:
3244 case OMPC_allocator:
3247 case OMPC_novariants:
3248 case OMPC_nocontext:
3253 case OMPC_ompx_dyn_cgroup_mem:
3254 case OMPC_dyn_groupprivate:
3255 case OMPC_transparent:
3284 Diag(Tok, diag::err_omp_more_one_clause)
3285 << getOpenMPDirectiveName(DKind, OMPVersion)
3286 << getOpenMPClauseName(CKind) << 0;
3290 if (CKind == OMPC_transparent && PP.LookAhead(0).isNot(tok::l_paren)) {
3292 SourceLocation LLoc = Tok.getLocation();
3293 Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(
nullptr, LLoc,
3297 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3298 PP.LookAhead(0).isNot(tok::l_paren))
3299 Clause = ParseOpenMPClause(CKind, WrongDirective);
3300 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3301 CKind == OMPC_num_threads || CKind == OMPC_dyn_groupprivate)
3302 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3304 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3306 case OMPC_threadset:
3308 case OMPC_proc_bind:
3309 case OMPC_atomic_default_mem_order:
3327 Diag(Tok, diag::err_omp_more_one_clause)
3328 << getOpenMPDirectiveName(DKind, OMPVersion)
3329 << getOpenMPClauseName(CKind) << 0;
3333 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3337 case OMPC_dist_schedule:
3338 case OMPC_defaultmap:
3349 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3350 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3351 Diag(Tok, diag::err_omp_more_one_clause)
3352 << getOpenMPDirectiveName(DKind, OMPVersion)
3353 << getOpenMPClauseName(CKind) << 0;
3358 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3361 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3365 case OMPC_mergeable:
3379 case OMPC_unified_address:
3380 case OMPC_unified_shared_memory:
3381 case OMPC_reverse_offload:
3382 case OMPC_dynamic_allocators:
3391 Diag(Tok, diag::err_omp_more_one_clause)
3392 << getOpenMPDirectiveName(DKind, OMPVersion)
3393 << getOpenMPClauseName(CKind) << 0;
3397 if (CKind == OMPC_nowait && PP.LookAhead(0).is(tok::l_paren) &&
3399 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3401 Clause = ParseOpenMPClause(CKind, WrongDirective);
3403 case OMPC_self_maps:
3406 Diag(Tok, diag::err_omp_expected_clause)
3407 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3411 Diag(Tok, diag::err_omp_more_one_clause)
3412 << getOpenMPDirectiveName(DKind, OMPVersion)
3413 << getOpenMPClauseName(CKind) << 0;
3416 Clause = ParseOpenMPClause(CKind, WrongDirective);
3420 Diag(Tok, diag::err_omp_more_one_clause)
3421 << getOpenMPDirectiveName(DKind, OMPVersion)
3422 << getOpenMPClauseName(CKind) << 0;
3426 Clause = (DKind == OMPD_depobj)
3427 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3428 : ParseOpenMPClause(CKind, WrongDirective);
3430 case OMPC_num_teams:
3431 case OMPC_thread_limit:
3433 Diag(Tok, diag::err_omp_more_one_clause)
3434 << getOpenMPDirectiveName(DKind, OMPVersion)
3435 << getOpenMPClauseName(CKind) << 0;
3440 case OMPC_firstprivate:
3441 case OMPC_lastprivate:
3443 case OMPC_reduction:
3444 case OMPC_task_reduction:
3445 case OMPC_in_reduction:
3449 case OMPC_copyprivate:
3455 case OMPC_use_device_ptr:
3456 case OMPC_use_device_addr:
3457 case OMPC_is_device_ptr:
3458 case OMPC_has_device_addr:
3460 case OMPC_nontemporal:
3461 case OMPC_inclusive:
3462 case OMPC_exclusive:
3466 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
3467 CKind == OMPC_depend)
3468 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3469 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3473 Diag(Tok, diag::err_omp_more_one_clause)
3474 << getOpenMPDirectiveName(DKind, OMPVersion)
3475 << getOpenMPClauseName(CKind) << 0;
3479 Clause = ParseOpenMPSizesClause();
3481 case OMPC_permutation:
3483 Diag(Tok, diag::err_omp_more_one_clause)
3484 << getOpenMPDirectiveName(DKind, OMPVersion)
3485 << getOpenMPClauseName(CKind) << 0;
3488 Clause = ParseOpenMPPermutationClause();
3492 Diag(Tok, diag::err_omp_more_one_clause)
3493 << getOpenMPDirectiveName(DKind, OMPVersion)
3494 << getOpenMPClauseName(CKind) << 0;
3497 Clause = ParseOpenMPCountsClause();
3499 case OMPC_uses_allocators:
3500 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3503 if (DKind != OMPD_interop) {
3505 Diag(Tok, diag::err_omp_more_one_clause)
3506 << getOpenMPDirectiveName(DKind, OMPVersion)
3507 << getOpenMPClauseName(CKind) << 0;
3510 Clause = ParseOpenMPClause(CKind, WrongDirective);
3516 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3518 case OMPC_device_type:
3520 skipUntilPragmaOpenMPEnd(DKind);
3522 case OMPC_threadprivate:
3523 case OMPC_groupprivate:
3526 if (!WrongDirective)
3527 Diag(Tok, diag::err_omp_unexpected_clause)
3528 << getOpenMPClauseName(CKind)
3529 << getOpenMPDirectiveName(DKind, OMPVersion);
3533 case OMPC_contains: {
3535 SourceLocation LLoc = Tok.getLocation();
3536 SourceLocation RLoc;
3537 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3542 if (DK == OMPD_unknown) {
3543 skipUntilPragmaOpenMPEnd(OMPD_assume);
3544 Diag(Tok, diag::err_omp_unexpected_clause)
3545 << getOpenMPClauseName(CKind)
3546 << getOpenMPDirectiveName(DKind, OMPVersion);
3550 DKVec.push_back(DK);
3553 Diag(Tok, diag::err_omp_unexpected_clause)
3554 << getOpenMPClauseName(CKind)
3555 << getOpenMPDirectiveName(DKind, OMPVersion);
3558 RLoc = Tok.getLocation();
3560 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3561 CKind, DKVec, Loc, LLoc, RLoc);
3564 case OMPC_no_openmp:
3565 case OMPC_no_openmp_routines:
3566 case OMPC_no_openmp_constructs:
3567 case OMPC_no_parallelism: {
3569 Diag(Tok, diag::err_omp_more_one_clause)
3570 << getOpenMPDirectiveName(DKind, OMPVersion)
3571 << getOpenMPClauseName(CKind) << 0;
3575 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3576 CKind, Loc, Tok.getLocation());
3579 case OMPC_ompx_attribute:
3580 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3582 case OMPC_ompx_bare:
3583 if (DKind == llvm::omp::Directive::OMPD_target) {
3588 Diag(Tok, diag::err_omp_unexpected_clause)
3589 << getOpenMPClauseName(CKind)
3590 << getOpenMPDirectiveName(DKind, OMPVersion);
3592 WrongDirective =
true;
3595 Diag(Tok, diag::note_ompx_bare_clause)
3596 << getOpenMPClauseName(CKind) <<
"target teams";
3597 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3598 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3599 << getOpenMPClauseName(CKind)
3600 << getOpenMPDirectiveName(DKind, OMPVersion);
3603 Clause = ParseOpenMPClause(CKind, WrongDirective);
3605 case OMPC_looprange:
3606 Clause = ParseOpenMPLoopRangeClause();
3611 return ErrorFound ?
nullptr : Clause;
3619 bool IsAddressOfOperand) {
3621 if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3629 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3632 RLoc = Tok.getLocation();
3633 if (!T.consumeClose())
3634 RLoc = T.getCloseLocation();
3656bool Parser::ParseOpenMPIndirectClause(
3661 if (
Tok.isNot(tok::l_paren)) {
3680 if (
Ret.isInvalid())
3683 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3685 if (
Ret.isInvalid())
3696 bool HasError =
false;
3697 bool IsTarget =
false;
3698 bool IsTargetSync =
false;
3700 while (Tok.is(tok::identifier)) {
3702 bool PreferTypeAllowed =
Kind == OMPC_init &&
3705 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3710 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3713 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3715 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3716 IsTargetSync =
true;
3718 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3719 PreferTypeAllowed) {
3722 tok::annot_pragma_openmp_end);
3723 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3726 while (Tok.isNot(tok::r_paren)) {
3727 SourceLocation Loc = Tok.getLocation();
3730 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
3736 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3740 if (Tok.is(tok::comma))
3746 Diag(Tok, diag::err_omp_expected_interop_type);
3749 if (!Tok.is(tok::comma))
3754 if (!HasError && !IsTarget && !IsTargetSync) {
3755 Diag(Tok, diag::err_omp_expected_interop_type);
3759 if (Kind == OMPC_init) {
3760 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
3761 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3762 if (Tok.is(tok::colon))
3779 if (T.expectAndConsume(diag::err_expected_lparen_after,
3780 getOpenMPClauseName(Kind).data()))
3783 bool InteropError =
false;
3784 OMPInteropInfo InteropInfo;
3785 if (Kind == OMPC_init)
3786 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3789 SourceLocation VarLoc = Tok.getLocation();
3792 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3797 SourceLocation RLoc = Tok.getLocation();
3798 if (!T.consumeClose())
3799 RLoc = T.getCloseLocation();
3801 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3804 if (Kind == OMPC_init)
3805 return Actions.OpenMP().ActOnOpenMPInitClause(
3806 InteropVarExpr.
get(), InteropInfo, Loc, T.getOpenLocation(), VarLoc,
3808 if (Kind == OMPC_use)
3809 return Actions.OpenMP().ActOnOpenMPUseClause(
3810 InteropVarExpr.
get(), Loc, T.getOpenLocation(), VarLoc, RLoc);
3812 if (Kind == OMPC_destroy)
3813 return Actions.OpenMP().ActOnOpenMPDestroyClause(
3814 InteropVarExpr.
get(), Loc, T.getOpenLocation(), VarLoc, RLoc);
3816 llvm_unreachable(
"Unexpected interop variable clause.");
3819OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
3823 if (T.expectAndConsume(diag::err_expected_lparen_after,
3824 getOpenMPClauseName(OMPC_ompx_attribute).data()))
3827 ParsedAttributes ParsedAttrs(AttrFactory);
3828 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
3831 if (T.consumeClose())
3837 SmallVector<Attr *> Attrs;
3838 for (
const ParsedAttr &PA : ParsedAttrs) {
3839 switch (PA.getKind()) {
3840 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
3841 if (!PA.checkExactlyNumArgs(Actions, 2))
3843 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
3844 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
3847 case ParsedAttr::AT_AMDGPUWavesPerEU:
3848 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3849 !PA.checkAtMostNumArgs(Actions, 2))
3851 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
3852 PA, PA.getArgAsExpr(0),
3853 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
3856 case ParsedAttr::AT_CUDALaunchBounds:
3857 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3858 !PA.checkAtMostNumArgs(Actions, 3))
3860 if (
auto *A = Actions.CreateLaunchBoundsAttr(
3861 PA, PA.getArgAsExpr(0),
3862 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
3863 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr,
3868 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
3873 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
3874 Attrs, Loc, T.getOpenLocation(), T.getCloseLocation());
3880 if (!Val || ParseOnly)
3882 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3883 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
3884 static_cast<DefaultKind
>(Val->Type) ==
3885 OMP_DEFAULT_firstprivate)) {
3886 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
3887 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
3890 : OMPC_firstprivate)
3891 << getOpenMPClauseName(OMPC_default) <<
"5.1";
3894 return Actions.OpenMP().ActOnOpenMPSimpleClause(
3895 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
3899 SourceLocation Loc = Tok.getLocation();
3904 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3911 SourceLocation DelimLoc;
3914 if (T.expectAndConsume(diag::err_expected_lparen_after,
3915 getOpenMPClauseName(Kind).data()))
3919 SmallVector<unsigned, 4> Arg;
3920 SmallVector<SourceLocation, 4> KLoc;
3921 if (Kind == OMPC_schedule) {
3922 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3923 Arg.resize(NumberOfElements);
3924 KLoc.resize(NumberOfElements);
3929 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3932 Arg[Modifier1] = KindModifier;
3933 KLoc[Modifier1] = Tok.getLocation();
3934 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3935 Tok.isNot(tok::annot_pragma_openmp_end))
3937 if (Tok.is(tok::comma)) {
3941 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3945 KLoc[Modifier2] = Tok.getLocation();
3946 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3947 Tok.isNot(tok::annot_pragma_openmp_end))
3951 if (Tok.is(tok::colon))
3954 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
3956 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3958 Arg[ScheduleKind] = KindModifier;
3959 KLoc[ScheduleKind] = Tok.getLocation();
3960 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3961 Tok.isNot(tok::annot_pragma_openmp_end))
3963 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3964 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3965 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3968 }
else if (Kind == OMPC_dist_schedule) {
3970 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3971 KLoc.push_back(Tok.getLocation());
3972 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3973 Tok.isNot(tok::annot_pragma_openmp_end))
3975 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3977 }
else if (Kind == OMPC_default) {
3980 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3982 Arg.push_back(Modifier);
3983 KLoc.push_back(Tok.getLocation());
3984 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3985 Tok.isNot(tok::annot_pragma_openmp_end))
3988 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
3993 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3994 Arg.push_back(VariableCategory);
3995 KLoc.push_back(Tok.getLocation());
3996 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3997 Tok.isNot(tok::annot_pragma_openmp_end))
4000 Arg.push_back(OMPC_DEFAULT_VC_all);
4001 KLoc.push_back(SourceLocation());
4003 }
else if (Kind == OMPC_defaultmap) {
4006 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4012 Arg.push_back(Modifier);
4013 KLoc.push_back(Tok.getLocation());
4014 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4015 Tok.isNot(tok::annot_pragma_openmp_end))
4018 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
4019 if (Tok.is(tok::colon))
4022 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
4025 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4026 KLoc.push_back(Tok.getLocation());
4027 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4028 Tok.isNot(tok::annot_pragma_openmp_end))
4032 KLoc.push_back(SourceLocation());
4034 }
else if (Kind == OMPC_order) {
4035 enum { Modifier, OrderKind, NumberOfElements };
4036 Arg.resize(NumberOfElements);
4037 KLoc.resize(NumberOfElements);
4041 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4044 Arg[Modifier] = KindModifier;
4045 KLoc[Modifier] = Tok.getLocation();
4046 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4047 Tok.isNot(tok::annot_pragma_openmp_end))
4050 if (Tok.is(tok::colon))
4053 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
4055 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4057 Arg[OrderKind] = KindModifier;
4058 KLoc[OrderKind] = Tok.getLocation();
4059 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4060 Tok.isNot(tok::annot_pragma_openmp_end))
4062 }
else if (Kind == OMPC_device) {
4068 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4069 KLoc.push_back(Tok.getLocation());
4075 KLoc.emplace_back();
4077 }
else if (Kind == OMPC_grainsize) {
4081 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4085 Arg.push_back(Modifier);
4086 KLoc.push_back(Tok.getLocation());
4092 if (Modifier == OMPC_GRAINSIZE_strict) {
4093 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4098 KLoc.emplace_back();
4102 KLoc.emplace_back();
4104 }
else if (Kind == OMPC_dyn_groupprivate) {
4105 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4106 Arg.resize(NumberOfModifiers);
4107 KLoc.resize(NumberOfModifiers);
4111 auto ConsumeModifier = [&]() {
4112 unsigned Type = NumberOfModifiers;
4115 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4119 ParenT.consumeOpen();
4122 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4125 Diag(Tok.getLocation(), diag::err_expected)
4126 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4128 return std::make_tuple(
Type, Modifier, Loc);
4130 Type = ComplexModifier;
4131 Loc = Tok.getLocation();
4132 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4133 Tok.isNot(tok::annot_pragma_openmp_end))
4135 ParenT.consumeClose();
4138 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4140 Type = SimpleModifier;
4141 Loc = Tok.getLocation();
4142 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4143 Tok.isNot(tok::annot_pragma_openmp_end))
4147 return std::make_tuple(
Type, Modifier, Loc);
4150 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4151 SourceLocation Loc) {
4152 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4153 if (!KLoc[
Type].isValid()) {
4154 Arg[
Type] = Modifier;
4157 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4164 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4165 if (Type1 < NumberOfModifiers) {
4166 SaveModifier(Type1, Mod1, Loc1);
4167 if (Tok.is(tok::comma)) {
4170 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4171 if (Type2 < NumberOfModifiers)
4172 SaveModifier(Type2, Mod2, Loc2);
4175 if (Tok.is(tok::colon))
4178 Diag(Tok, diag::warn_pragma_expected_colon)
4179 <<
"dyn_groupprivate modifier";
4181 }
else if (Kind == OMPC_num_tasks) {
4185 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4189 Arg.push_back(Modifier);
4190 KLoc.push_back(Tok.getLocation());
4196 if (Modifier == OMPC_NUMTASKS_strict) {
4197 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4202 KLoc.emplace_back();
4206 KLoc.emplace_back();
4208 }
else if (Kind == OMPC_num_threads) {
4212 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4216 Arg.push_back(Modifier);
4217 KLoc.push_back(Tok.getLocation());
4223 if (Modifier == OMPC_NUMTHREADS_strict) {
4224 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4229 KLoc.emplace_back();
4233 KLoc.emplace_back();
4236 assert(Kind == OMPC_if);
4237 KLoc.push_back(Tok.getLocation());
4238 TentativeParsingAction TPA(*
this);
4240 Arg.push_back(
static_cast<unsigned>(DK));
4241 if (DK != OMPD_unknown) {
4243 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4248 Arg.back() = unsigned(OMPD_unknown);
4255 bool NeedAnExpression =
4257 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
Kind == OMPC_if ||
4258 Kind == OMPC_device ||
Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4259 Kind == OMPC_num_threads ||
Kind == OMPC_dyn_groupprivate;
4260 if (NeedAnExpression) {
4261 SourceLocation ELoc = Tok.getLocation();
4267 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4271 SourceLocation RLoc = Tok.getLocation();
4272 if (!T.consumeClose())
4273 RLoc = T.getCloseLocation();
4275 if (NeedAnExpression && Val.
isInvalid())
4278 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4279 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4280 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4281 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4282 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4285 : OMPC_firstprivate)
4286 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4292 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4293 Kind, Arg, Val.
get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4298 if (ReductionIdScopeSpec.
isEmpty()) {
4336 ReductionIdScopeSpec,
nullptr,
4340 false,
nullptr, ReductionId);
4347 if (!
Tok.is(tok::identifier))
4354 return TypeModifier;
4360 if (T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4361 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4367 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4371 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4372 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4373 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4377 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4379 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4382 return T.consumeClose();
4388 bool HasMapType =
false;
4390 StringRef PreMapName =
"";
4394 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4395 TypeModifier == OMPC_MAP_MODIFIER_close ||
4396 TypeModifier == OMPC_MAP_MODIFIER_present ||
4397 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4398 Data.MapTypeModifiers.push_back(TypeModifier);
4399 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4400 if (PP.LookAhead(0).isNot(tok::comma) &&
4401 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4402 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4403 <<
"map type modifier";
4405 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4406 Data.MapTypeModifiers.push_back(TypeModifier);
4407 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4411 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4413 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4414 <<
"map type modifier";
4419 Data.ExtraModifier = MapKind;
4421 PreMapLoc = Tok.getLocation();
4422 PreMapName = Tok.getIdentifierInfo()->getName();
4424 Diag(Tok, diag::err_omp_more_one_map_type);
4425 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4429 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4430 Data.MapTypeModifiers.push_back(TypeModifier);
4431 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4432 if (PP.LookAhead(0).isNot(tok::comma) &&
4433 PP.LookAhead(0).isNot(tok::colon))
4434 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4435 <<
"map type modifier";
4437 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4447 if (Tok.is(tok::comma)) {
4448 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4453 if (PP.LookAhead(0).is(tok::colon)) {
4461 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4472 if (!Tok.is(tok::colon)) {
4473 Diag(Tok, diag::err_omp_unknown_map_type);
4487 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4492 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4493 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4494 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4504 if (
Tok.is(tok::colon)) {
4505 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4510 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4514ExprResult Parser::ParseOpenMPIteratorsExpr() {
4515 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4516 "Expected 'iterator' token.");
4520 if (T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4523 SourceLocation LLoc = T.getOpenLocation();
4524 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4525 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4528 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4535 IteratorType = TR.
get();
4539 IdentifierInfo *II =
nullptr;
4540 SourceLocation IdLoc;
4541 if (Tok.is(tok::identifier)) {
4542 II = Tok.getIdentifierInfo();
4545 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4549 SourceLocation AssignLoc;
4550 if (Tok.is(tok::equal))
4553 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4558 SourceLocation Loc = Tok.getLocation();
4561 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4564 SourceLocation ColonLoc;
4565 if (Tok.is(tok::colon))
4569 Loc = Tok.getLocation();
4572 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4575 SourceLocation SecColonLoc;
4578 if (Tok.is(tok::colon)) {
4582 Loc = Tok.getLocation();
4585 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4590 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4591 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4592 if (Tok.is(tok::comma))
4595 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4598 D.
Type = IteratorType;
4608 SourceLocation RLoc = Tok.getLocation();
4609 if (!T.consumeClose())
4610 RLoc = T.getCloseLocation();
4612 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4621 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4624 if (Tok.is(tok::identifier) &&
4625 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4627 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4628 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4629 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4630 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4631 Data.ExtraModifier != OMPC_DEPEND_inout)
4632 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4634 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4635 ? OMPC_DEPEND_outallmemory
4636 : OMPC_DEPEND_inoutallmemory;
4652 Data.DepModOrTailExpr = Tail.
get();
4654 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4655 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4673 bool AllocatorSeen =
false;
4674 bool AlignSeen =
false;
4693 if (
Tok.is(tok::l_paren)) {
4694 switch (CurrentModifier) {
4695 case OMPC_ALLOCATE_allocator: {
4696 if (AllocatorSeen) {
4697 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4699 << getOpenMPClauseName(Kind);
4701 Data.AllocClauseModifiers.push_back(CurrentModifier);
4702 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4705 tok::annot_pragma_openmp_end);
4709 AllocatorSeen =
true;
4712 case OMPC_ALLOCATE_align: {
4714 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4716 << getOpenMPClauseName(Kind);
4718 Data.AllocClauseModifiers.push_back(CurrentModifier);
4719 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4723 Data.AllocateAlignment = Val.
get();
4728 llvm_unreachable(
"Unexpected allocate modifier");
4731 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4733 if (
Tok.isNot(tok::comma))
4736 CurrentModifierLoc =
Tok.getLocation();
4741 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4744 }
while (!AllocatorSeen || !AlignSeen);
4753 bool InvalidReductionId =
false;
4754 bool IsInvalidMapperModifier =
false;
4758 if (T.expectAndConsume(diag::err_expected_lparen_after,
4759 getOpenMPClauseName(Kind).data()))
4762 bool HasIterator =
false;
4763 bool InvalidIterator =
false;
4764 bool NeedRParenForLinear =
false;
4766 tok::annot_pragma_openmp_end);
4768 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4769 Kind == OMPC_in_reduction) {
4771 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4772 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4775 Data.ExtraModifier =
4777 Data.ExtraModifierLoc = Tok.getLocation();
4779 assert(Tok.is(tok::comma) &&
"Expected comma.");
4783 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4784 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4790 if (Tok.is(tok::kw_private)) {
4791 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4792 Data.OriginalSharingModifierLoc = Tok.getLocation();
4794 }
else if (Tok.is(tok::identifier) &&
4795 (PP.getSpelling(Tok) ==
"shared" ||
4796 PP.getSpelling(Tok) ==
"default")) {
4797 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4798 Data.OriginalSharingModifierLoc = Tok.getLocation();
4801 Diag(Tok.getLocation(), diag::err_expected)
4802 <<
"'private or shared or default'";
4807 if (!Tok.is(tok::comma)) {
4808 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4815 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4820 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4821 if (InvalidReductionId) {
4822 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4825 if (Tok.is(tok::colon))
4828 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4829 if (!InvalidReductionId)
4830 Data.ReductionOrMapperId =
4831 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4832 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4834 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4843 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4844 Data.DepModOrTailExpr = IteratorRes.
get();
4846 ExpectAndConsume(tok::comma);
4852 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4854 Data.ExtraModifierLoc = Tok.getLocation();
4856 (Kind == OMPC_doacross &&
4858 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4863 if (DKind == OMPD_ordered && Kind == OMPC_depend &&
4864 Data.ExtraModifier == OMPC_DEPEND_source) {
4870 if (Tok.is(tok::colon)) {
4872 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
4873 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4874 : diag::warn_pragma_expected_colon)
4875 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
4877 if (Kind == OMPC_doacross) {
4878 if (Tok.is(tok::identifier) &&
4879 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
4880 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
4881 ? OMPC_DOACROSS_source_omp_cur_iteration
4882 : OMPC_DOACROSS_sink_omp_cur_iteration;
4885 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
4886 if (Tok.isNot(tok::minus)) {
4887 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4888 << getOpenMPClauseName(Kind) << 0 << 0;
4895 if (Tok.isNot(tok::numeric_constant) ||
4896 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
4897 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
4898 << getOpenMPClauseName(Kind) << 0 << 0;
4904 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
4905 if (Tok.isNot(tok::r_paren)) {
4906 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4907 << getOpenMPClauseName(Kind) << 1 << 1;
4913 if (Kind == OMPC_doacross &&
4914 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
4915 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
4916 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
4922 }
else if (Kind == OMPC_linear) {
4924 Data.ExtraModifier = OMPC_LINEAR_val;
4925 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
4926 Data.ExtraModifier =
4930 NeedRParenForLinear =
true;
4932 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
4933 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
4934 <<
"linear(list: [linear-modifier,] step(step-size))";
4936 }
else if (Kind == OMPC_lastprivate) {
4943 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
4944 Data.ExtraModifier =
4946 Data.ExtraModifierLoc = Tok.getLocation();
4948 assert(Tok.is(tok::colon) &&
"Expected colon.");
4951 }
else if (Kind == OMPC_map) {
4953 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4956 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
4957 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4958 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4959 Data.IteratorExpr = IteratorRes.
get();
4961 ExpectAndConsume(tok::comma);
4963 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4966 InvalidIterator =
true;
4976 Data.ExtraModifierLoc = Tok.getLocation();
4979 TentativeParsingAction TPA(*
this);
4980 bool ColonPresent =
false;
4981 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4983 if (Tok.is(tok::colon))
4984 ColonPresent =
true;
4991 Diag(Tok, diag::err_omp_map_modifier_specification_list);
4993 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
4999 Data.ExtraModifier = OMPC_MAP_tofrom;
5001 if (DKind == OMPD_target_enter_data)
5002 Data.ExtraModifier = OMPC_MAP_to;
5003 else if (DKind == OMPD_target_exit_data)
5004 Data.ExtraModifier = OMPC_MAP_from;
5006 Data.IsMapTypeImplicit =
true;
5009 if (Tok.is(tok::colon))
5011 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
5012 while (Tok.is(tok::identifier)) {
5017 Data.MotionModifiers.push_back(Modifier);
5018 Data.MotionModifiersLoc.push_back(Tok.getLocation());
5019 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
5021 Tail = ParseOpenMPIteratorsExpr();
5022 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
5025 Data.IteratorExpr = Tail.
get();
5028 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
5030 if (IsInvalidMapperModifier)
5038 if (Tok.is(tok::comma))
5042 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
5043 if (!IsInvalidMapperModifier) {
5045 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
5047 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
5049 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5057 }
else if (Kind == OMPC_allocate ||
5058 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
5059 PP.getSpelling(Tok) ==
"iterator")) {
5063 TentativeParsingAction TPA(*
this);
5068 if (Kind == OMPC_allocate) {
5073 Tail = ParseOpenMPIteratorsExpr();
5075 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
5078 if (Tok.is(tok::colon)) {
5085 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5086 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5088 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5095 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5098 }
else if (Kind == OMPC_adjust_args) {
5102 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5104 Data.ExtraModifierLoc = Tok.getLocation();
5106 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5111 if (Tok.is(tok::colon))
5112 Data.ColonLoc = Tok.getLocation();
5116 if (Tok.is(tok::l_paren)) {
5119 if (Tok.is(tok::identifier)) {
5120 std::string Modifier = PP.getSpelling(Tok);
5121 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5122 Data.NeedDevicePtrModifier =
5123 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5124 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5126 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5127 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5132 if (Tok.is(tok::r_paren)) {
5133 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5136 Diag(Tok, diag::err_expected) << tok::r_paren;
5137 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5146 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5149 }
else if (Kind == OMPC_use_device_ptr) {
5153 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5157 Data.ExtraModifier = FallbackModifier;
5158 Data.ExtraModifierLoc = Tok.getLocation();
5160 if (Tok.is(tok::colon))
5163 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5167 if (Kind == OMPC_num_teams && !Tok.is(tok::r_paren) &&
5168 !Tok.is(tok::annot_pragma_openmp_end)) {
5172 Data.RLoc = Tok.getLocation();
5173 if (!T.consumeClose())
5174 Data.RLoc = T.getCloseLocation();
5178 if (Tok.is(tok::colon)) {
5184 Data.RLoc = Tok.getLocation();
5185 if (!T.consumeClose())
5186 Data.RLoc = T.getCloseLocation();
5189 Vars.push_back(FirstExpr.
get());
5190 Vars.push_back(UpperBound.
get());
5191 Data.RLoc = Tok.getLocation();
5192 if (!T.consumeClose())
5193 Data.RLoc = T.getCloseLocation();
5196 if (Tok.is(tok::comma)) {
5197 Vars.push_back(FirstExpr.
get());
5198 while (Tok.is(tok::comma)) {
5202 Vars.push_back(NextExpr.
get());
5204 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5209 Data.RLoc = Tok.getLocation();
5210 bool HadError = T.consumeClose();
5212 Data.RLoc = T.getCloseLocation();
5217 Vars.push_back(FirstExpr.
get());
5218 Data.RLoc = Tok.getLocation();
5219 if (!T.consumeClose())
5220 Data.RLoc = T.getCloseLocation();
5225 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5226 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5227 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5228 (Kind == OMPC_reduction && !InvalidReductionId) ||
5232 (Kind == OMPC_adjust_args &&
5234 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5235 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5236 Tok.isNot(tok::annot_pragma_openmp_end))) {
5243 Vars.push_back(VarExpr.
get());
5245 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5250 IsComma = Tok.is(tok::comma);
5253 else if (Tok.isNot(tok::r_paren) &&
5254 Tok.isNot(tok::annot_pragma_openmp_end) &&
5255 (!MayHaveTail || Tok.isNot(tok::colon))) {
5256 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
5257 Diag(Tok, diag::err_omp_expected_punc)
5258 << ((Kind == OMPC_flush)
5259 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5260 : getOpenMPClauseName(Kind))
5261 << (Kind == OMPC_flush);
5266 if (NeedRParenForLinear)
5270 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5271 bool StepFound =
false;
5272 bool ModifierFound =
false;
5274 Data.ColonLoc = Tok.getLocation();
5277 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5278 bool Malformed =
false;
5279 while (Tok.isNot(tok::r_paren)) {
5280 if (Tok.is(tok::identifier)) {
5285 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5288 if (LinKind == OMPC_LINEAR_step) {
5290 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5293 tok::annot_pragma_openmp_end);
5297 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5302 Data.StepModifierLoc = StepModifierLoc;
5306 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5308 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5310 Data.ExtraModifier = LinKind;
5312 ModifierFound =
true;
5317 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5326 if (Tok.is(tok::comma))
5328 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5331 if (!Malformed && !StepFound && !ModifierFound)
5332 Diag(ELoc, diag::err_expected_expression);
5336 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5339 Data.DepModOrTailExpr = Tail.
get();
5341 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5347 Data.RLoc = Tok.getLocation();
5348 if (!T.consumeClose())
5349 Data.RLoc = T.getCloseLocation();
5353 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5355 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5356 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5383 "Expected parsing to start at clause name");
5388 if (T.consumeOpen()) {
5389 Diag(
Tok, diag::err_expected) << tok::l_paren;
5402 Exprs.push_back(Val.
get());
5405 bool Result = T.consumeClose();
5406 OpenLoc = T.getOpenLocation();
5407 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< Expr *, 4 > PreferTypes
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.