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;
2392 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2393 SeenClauses[unsigned(CKind)] =
true;
2395 Clauses.push_back(Clause);
2398 if (Tok.is(tok::comma))
2400 Actions.OpenMP().EndOpenMPClause();
2403 EndLoc = Tok.getLocation();
2405 ConsumeAnnotationToken();
2407 if (DKind == OMPD_ordered) {
2410 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2411 if (SeenClauses[
unsigned(CK)]) {
2412 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2413 ParsedStmtContext()) {
2414 Diag(Loc, diag::err_omp_immediate_directive)
2415 << getOpenMPDirectiveName(DKind, OMPVersion) << 1
2416 << getOpenMPClauseName(CK);
2418 HasAssociatedStatement =
false;
2423 if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
2424 !SeenClauses[
unsigned(OMPC_sizes)]) {
2425 Diag(Loc, diag::err_omp_required_clause)
2426 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"sizes";
2428 if (DKind == OMPD_split && !SeenClauses[
unsigned(OMPC_counts)]) {
2429 Diag(Loc, diag::err_omp_required_clause)
2430 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"counts";
2434 if (HasAssociatedStatement) {
2436 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2442 Sema::CompoundScopeRAII Scope(Actions);
2443 AssociatedStmt = ParseStatement();
2448 Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
2451 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2452 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2453 DKind == OMPD_target_exit_data) {
2454 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2455 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2456 Actions.ActOnCompoundStmt(Loc, Loc, {},
2459 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2463 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2466 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2467 OMPDirectiveScope.Exit();
2472StmtResult Parser::ParseOpenMPInformationalDirective(
2474 bool ReadDirectiveWithinMetadirective) {
2476 "Unexpected directive category");
2478 bool HasAssociatedStatement =
true;
2480 SmallVector<OMPClause *, 5> Clauses;
2481 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2482 DeclarationNameInfo DirName;
2485 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2487 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2490 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2491 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2492 while (Tok.isNot(tok::annot_pragma_openmp_end))
2499 : getOpenMPClauseKind(PP.getSpelling(Tok));
2500 Actions.OpenMP().StartOpenMPClause(CKind);
2502 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2503 SeenClauses[unsigned(CKind)] =
true;
2505 Clauses.push_back(Clause);
2507 if (Tok.is(tok::comma))
2509 Actions.OpenMP().EndOpenMPClause();
2512 SourceLocation EndLoc = Tok.getLocation();
2513 ConsumeAnnotationToken();
2516 if (HasAssociatedStatement) {
2517 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2520 Sema::CompoundScopeRAII Scope(Actions);
2521 AssociatedStmt = ParseStatement();
2524 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2528 DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2530 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2531 OMPDirectiveScope.Exit();
2536StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2537 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2538 if (!ReadDirectiveWithinMetadirective)
2539 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2540 "Not an OpenMP directive!");
2543 SourceLocation Loc = ReadDirectiveWithinMetadirective
2545 : ConsumeAnnotationToken();
2546 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2548 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2549 Diag(Tok, diag::err_omp_unknown_directive);
2555 bool IsExecutable = [&]() {
2556 if (DKind == OMPD_error)
2558 auto Res = getDirectiveCategory(DKind);
2559 return Res == Category::Executable || Res == Category::Subsidiary;
2563 Directive = ParseOpenMPExecutableDirective(
2564 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2565 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2574 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
2575 while (Tok.isNot(tok::annot_pragma_openmp_end))
2578 skipUntilPragmaOpenMPEnd(DKind);
2579 if (Tok.is(tok::annot_pragma_openmp_end))
2580 ConsumeAnnotationToken();
2583 case OMPD_metadirective: {
2585 SmallVector<VariantMatchInfo, 4> VMIs;
2590 TentativeParsingAction TPA(*
this);
2591 ASTContext &ASTContext = Actions.getASTContext();
2594 tok::annot_pragma_openmp_end);
2595 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2598 : getOpenMPClauseKind(PP.getSpelling(Tok));
2600 if (CKind == OMPC_unknown) {
2601 Diag(Tok, diag::err_omp_expected_clause) <<
"metadirective";
2603 SkipUntil(tok::annot_pragma_openmp_end);
2606 if (
getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
2607 Diag(Tok, diag::err_omp_unexpected_clause)
2608 << getOpenMPClauseName(CKind) <<
"metadirective";
2609 if (CKind == OMPC_default &&
getLangOpts().OpenMP >= 52)
2610 Diag(Tok, diag::warn_omp_default_deprecated);
2615 if (T.expectAndConsume(diag::err_expected_lparen_after,
2616 getOpenMPClauseName(CKind).data())) {
2618 SkipUntil(tok::annot_pragma_openmp_end);
2622 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2623 if (CKind == OMPC_when) {
2625 parseOMPContextSelectors(Loc, TI);
2626 if (TI.
Sets.size() == 0) {
2627 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2633 if (Tok.is(tok::colon))
2636 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2644 while (Tok.isNot(tok::r_paren) || paren != 0) {
2645 if (Tok.is(tok::l_paren))
2647 if (Tok.is(tok::r_paren))
2649 if (Tok.is(tok::annot_pragma_openmp_end)) {
2650 Diag(Tok, diag::err_omp_expected_punc)
2651 << getOpenMPClauseName(CKind) << 0;
2658 if (Tok.is(tok::r_paren))
2661 VariantMatchInfo VMI;
2664 VMIs.push_back(VMI);
2671 [
this, Loc](StringRef ISATrait) {
2674 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2676 TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2678 ArrayRef<llvm::omp::TraitProperty>(),
2679 Actions.OpenMP().getOpenMPDeviceNum());
2682 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2689 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2691 if (Idx++ != BestIdx) {
2696 while (Tok.isNot(tok::r_paren) || paren != 0) {
2697 if (Tok.is(tok::l_paren))
2699 if (Tok.is(tok::r_paren))
2704 if (Tok.is(tok::r_paren))
2711 : getOpenMPClauseKind(PP.getSpelling(Tok));
2718 if (CKind == OMPC_when) {
2719 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2721 parseOMPContextSelectors(Loc, TI);
2729 if (Tok.is(tok::r_paren)) {
2730 SkipUntil(tok::annot_pragma_openmp_end);
2735 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2743 if (BestIdx == -1 && Idx > 0) {
2744 assert(Tok.is(tok::annot_pragma_openmp_end) &&
2745 "Expecting the end of the pragma here");
2746 ConsumeAnnotationToken();
2751 case OMPD_threadprivate: {
2753 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2754 ParsedStmtContext()) {
2755 Diag(Tok, diag::err_omp_immediate_directive)
2756 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2759 DeclDirectiveListParserHelper Helper(
this, DKind);
2760 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2762 skipUntilPragmaOpenMPEnd(DKind);
2763 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2764 Loc, Helper.getIdentifiers());
2765 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2767 SkipUntil(tok::annot_pragma_openmp_end);
2770 case OMPD_groupprivate: {
2771 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2772 ParsedStmtContext()) {
2773 Diag(Tok, diag::err_omp_immediate_directive)
2774 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2777 DeclDirectiveListParserHelper Helper(
this, DKind);
2778 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2780 skipUntilPragmaOpenMPEnd(DKind);
2781 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2782 Loc, Helper.getIdentifiers());
2783 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2785 SkipUntil(tok::annot_pragma_openmp_end);
2788 case OMPD_allocate: {
2790 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2791 ParsedStmtContext()) {
2792 Diag(Tok, diag::err_omp_immediate_directive)
2793 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2796 DeclDirectiveListParserHelper Helper(
this, DKind);
2797 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2799 SmallVector<OMPClause *, 1> Clauses;
2800 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2801 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2802 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2804 Tok.isAnnotation() ? OMPC_unknown
2805 : getOpenMPClauseKind(PP.getSpelling(Tok));
2806 Actions.OpenMP().StartOpenMPClause(CKind);
2807 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2808 !SeenClauses[
unsigned(CKind)]);
2809 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2811 SeenClauses[unsigned(CKind)] =
true;
2812 if (Clause !=
nullptr)
2813 Clauses.push_back(Clause);
2814 if (Tok.is(tok::annot_pragma_openmp_end)) {
2815 Actions.OpenMP().EndOpenMPClause();
2819 if (Tok.is(tok::comma))
2821 Actions.OpenMP().EndOpenMPClause();
2823 skipUntilPragmaOpenMPEnd(DKind);
2825 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPAllocateDirective(
2826 Loc, Helper.getIdentifiers(), Clauses);
2827 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2829 SkipUntil(tok::annot_pragma_openmp_end);
2832 case OMPD_declare_reduction:
2835 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2836 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2838 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2840 SkipUntil(tok::annot_pragma_openmp_end);
2843 case OMPD_declare_mapper: {
2846 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2848 ConsumeAnnotationToken();
2849 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2851 SkipUntil(tok::annot_pragma_openmp_end);
2855 case OMPD_declare_target: {
2857 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2858 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2860 ParseOMPDeclareTargetClauses(DTCI);
2861 bool HasImplicitMappings =
2864 if (HasImplicitMappings) {
2865 Diag(Tok, diag::err_omp_unexpected_directive)
2866 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2867 SkipUntil(tok::annot_pragma_openmp_end);
2874 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2877 case OMPD_begin_declare_variant: {
2882 ConsumeAnnotationToken();
2886 case OMPD_end_declare_variant: {
2888 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2889 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2891 Diag(Loc, diag::err_expected_begin_declare_variant);
2892 ConsumeAnnotationToken();
2895 case OMPD_declare_simd:
2896 case OMPD_begin_declare_target:
2897 case OMPD_end_declare_target:
2899 case OMPD_declare_variant:
2900 Diag(Tok, diag::err_omp_unexpected_directive)
2901 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2902 SkipUntil(tok::annot_pragma_openmp_end);
2906 Directive = ParseOpenMPInformationalDirective(
2907 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2909 "Informational directive remains unprocessed");
2914 Diag(Tok, diag::err_omp_unknown_directive);
2915 SkipUntil(tok::annot_pragma_openmp_end);
2921bool Parser::ParseOpenMPSimpleVarList(
2925 bool AllowScopeSpecifier) {
2926 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2929 if (T.expectAndConsume(diag::err_expected_lparen_after,
2930 getOpenMPDirectiveName(Kind, OMPVersion).data()))
2932 bool IsCorrect =
true;
2933 bool NoIdentIsFound =
true;
2936 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2940 Token PrevTok = Tok;
2941 NoIdentIsFound =
false;
2944 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2947 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2950 false,
false,
false,
2951 false,
false,
nullptr, Name)) {
2953 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2955 }
else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2956 Tok.isNot(tok::annot_pragma_openmp_end)) {
2958 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2962 << SourceRange(PrevTok.
getLocation(), PrevTokLocation);
2964 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2967 if (Tok.is(tok::comma)) {
2972 if (NoIdentIsFound) {
2973 Diag(Tok, diag::err_expected) << tok::identifier;
2978 IsCorrect = !T.consumeClose() && IsCorrect;
2983OMPClause *Parser::ParseOpenMPSizesClause() {
2984 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
2985 SmallVector<Expr *, 4> ValExprs;
2986 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
2990 return Actions.OpenMP().ActOnOpenMPSizesClause(ValExprs, ClauseNameLoc,
2994OMPClause *Parser::ParseOpenMPCountsClause() {
2995 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
2996 SmallVector<Expr *, 4> ValExprs;
2997 std::optional<unsigned> FillIdx;
2998 unsigned FillCount = 0;
2999 SourceLocation FillLoc;
3001 assert(getOpenMPClauseName(OMPC_counts) == PP.getSpelling(Tok) &&
3002 "Expected parsing to start at clause name");
3006 if (T.consumeOpen()) {
3007 Diag(Tok, diag::err_expected) << tok::l_paren;
3012 if (Tok.is(tok::identifier) &&
3013 Tok.getIdentifierInfo()->getName() ==
"omp_fill") {
3015 FillIdx = ValExprs.size();
3017 FillLoc = Tok.getLocation();
3019 ValExprs.push_back(
nullptr);
3026 ValExprs.push_back(Val.
get());
3030 if (T.consumeClose())
3032 OpenLoc = T.getOpenLocation();
3033 CloseLoc = T.getCloseLocation();
3035 return Actions.OpenMP().ActOnOpenMPCountsClause(
3036 ValExprs, ClauseNameLoc, OpenLoc, CloseLoc, FillIdx, FillLoc, FillCount);
3039OMPClause *Parser::ParseOpenMPLoopRangeClause() {
3041 SourceLocation FirstLoc, CountLoc;
3044 if (T.consumeOpen()) {
3045 Diag(Tok, diag::err_expected) << tok::l_paren;
3049 FirstLoc = Tok.getLocation();
3056 ExpectAndConsume(tok::comma);
3058 CountLoc = Tok.getLocation();
3067 return Actions.OpenMP().ActOnOpenMPLoopRangeClause(
3068 FirstVal.
get(), CountVal.
get(), ClauseNameLoc, T.getOpenLocation(),
3069 FirstLoc, CountLoc, T.getCloseLocation());
3072OMPClause *Parser::ParseOpenMPPermutationClause() {
3073 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3074 SmallVector<Expr *> ArgExprs;
3075 if (ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,
3080 return Actions.OpenMP().ActOnOpenMPPermutationClause(ArgExprs, ClauseNameLoc,
3085 SourceLocation Loc = Tok.getLocation();
3090 if (T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3092 SmallVector<SemaOpenMP::UsesAllocatorsData, 4>
Data;
3095 if (
getLangOpts().OpenMP >= 52 && Tok.is(tok::identifier) &&
3096 Tok.getIdentifierInfo()->getName() ==
"traits") {
3098 SemaOpenMP::UsesAllocatorsData &D =
Data.emplace_back();
3104 tok::annot_pragma_openmp_end);
3105 TraitParens.consumeOpen();
3108 TraitParens.consumeClose();
3112 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3118 if (Tok.isNot(tok::colon)) {
3119 Diag(Tok, diag::err_expected) << tok::colon;
3121 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3130 ? ParseCXXIdExpression()
3131 : tryParseCXXIdExpression(SS,
false);
3135 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3142 D.
LParenLoc = TraitParens.getOpenLocation();
3143 D.
RParenLoc = TraitParens.getCloseLocation();
3146 if (Tok.is(tok::comma)) {
3148 Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3151 }
else if (Tok.is(tok::semi)) {
3161 getLangOpts().CPlusPlus
3162 ? ParseCXXIdExpression()
3163 : tryParseCXXIdExpression(SS,
false);
3165 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3172 BalancedDelimiterTracker T(*this, tok::l_paren,
3173 tok::annot_pragma_openmp_end);
3175 ExprResult AllocatorTraits =
3176 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3178 if (AllocatorTraits.isInvalid()) {
3179 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3188 if (getLangOpts().OpenMP >= 52) {
3189 Diag(Loc, diag::err_omp_deprecate_old_syntax)
3190 <<
"allocator(expr)"
3191 <<
"uses_allocators"
3192 <<
"traits(expr): alloc";
3196 Diag(
Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3198 if (
Tok.
is(tok::comma))
3200 }
while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end));
3203 Loc, T.getOpenLocation(), T.getCloseLocation(),
Data);
3208 OMPClauseKind = CKind;
3209 OMPClause *Clause =
nullptr;
3210 bool ErrorFound =
false;
3211 bool WrongDirective =
false;
3212 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
3215 if (CKind != OMPC_unknown &&
3216 !isAllowedClauseForDirective(DKind, CKind,
getLangOpts().OpenMP)) {
3217 Diag(Tok, diag::err_omp_unexpected_clause)
3218 << getOpenMPClauseName(CKind)
3219 << getOpenMPDirectiveName(DKind, OMPVersion);
3221 WrongDirective =
true;
3226 case OMPC_num_threads:
3232 case OMPC_grainsize:
3233 case OMPC_num_tasks:
3235 case OMPC_allocator:
3238 case OMPC_novariants:
3239 case OMPC_nocontext:
3244 case OMPC_ompx_dyn_cgroup_mem:
3245 case OMPC_dyn_groupprivate:
3246 case OMPC_transparent:
3275 Diag(Tok, diag::err_omp_more_one_clause)
3276 << getOpenMPDirectiveName(DKind, OMPVersion)
3277 << getOpenMPClauseName(CKind) << 0;
3281 if (CKind == OMPC_transparent && PP.LookAhead(0).isNot(tok::l_paren)) {
3283 SourceLocation LLoc = Tok.getLocation();
3284 Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(
nullptr, LLoc,
3288 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3289 PP.LookAhead(0).isNot(tok::l_paren))
3290 Clause = ParseOpenMPClause(CKind, WrongDirective);
3291 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3292 CKind == OMPC_num_threads || CKind == OMPC_dyn_groupprivate)
3293 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3295 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3297 case OMPC_threadset:
3299 case OMPC_proc_bind:
3300 case OMPC_atomic_default_mem_order:
3318 Diag(Tok, diag::err_omp_more_one_clause)
3319 << getOpenMPDirectiveName(DKind, OMPVersion)
3320 << getOpenMPClauseName(CKind) << 0;
3324 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3328 case OMPC_dist_schedule:
3329 case OMPC_defaultmap:
3340 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3341 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3342 Diag(Tok, diag::err_omp_more_one_clause)
3343 << getOpenMPDirectiveName(DKind, OMPVersion)
3344 << getOpenMPClauseName(CKind) << 0;
3349 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3352 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3356 case OMPC_mergeable:
3370 case OMPC_unified_address:
3371 case OMPC_unified_shared_memory:
3372 case OMPC_reverse_offload:
3373 case OMPC_dynamic_allocators:
3382 Diag(Tok, diag::err_omp_more_one_clause)
3383 << getOpenMPDirectiveName(DKind, OMPVersion)
3384 << getOpenMPClauseName(CKind) << 0;
3388 if (CKind == OMPC_nowait && PP.LookAhead(0).is(tok::l_paren) &&
3390 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3392 Clause = ParseOpenMPClause(CKind, WrongDirective);
3394 case OMPC_self_maps:
3397 Diag(Tok, diag::err_omp_expected_clause)
3398 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3402 Diag(Tok, diag::err_omp_more_one_clause)
3403 << getOpenMPDirectiveName(DKind, OMPVersion)
3404 << getOpenMPClauseName(CKind) << 0;
3407 Clause = ParseOpenMPClause(CKind, WrongDirective);
3411 Diag(Tok, diag::err_omp_more_one_clause)
3412 << getOpenMPDirectiveName(DKind, OMPVersion)
3413 << getOpenMPClauseName(CKind) << 0;
3417 Clause = (DKind == OMPD_depobj)
3418 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3419 : ParseOpenMPClause(CKind, WrongDirective);
3421 case OMPC_num_teams:
3422 case OMPC_thread_limit:
3424 Diag(Tok, diag::err_omp_more_one_clause)
3425 << getOpenMPDirectiveName(DKind, OMPVersion)
3426 << getOpenMPClauseName(CKind) << 0;
3431 case OMPC_firstprivate:
3432 case OMPC_lastprivate:
3434 case OMPC_reduction:
3435 case OMPC_task_reduction:
3436 case OMPC_in_reduction:
3440 case OMPC_copyprivate:
3446 case OMPC_use_device_ptr:
3447 case OMPC_use_device_addr:
3448 case OMPC_is_device_ptr:
3449 case OMPC_has_device_addr:
3451 case OMPC_nontemporal:
3452 case OMPC_inclusive:
3453 case OMPC_exclusive:
3457 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
3458 CKind == OMPC_depend)
3459 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3460 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3464 Diag(Tok, diag::err_omp_more_one_clause)
3465 << getOpenMPDirectiveName(DKind, OMPVersion)
3466 << getOpenMPClauseName(CKind) << 0;
3470 Clause = ParseOpenMPSizesClause();
3472 case OMPC_permutation:
3474 Diag(Tok, diag::err_omp_more_one_clause)
3475 << getOpenMPDirectiveName(DKind, OMPVersion)
3476 << getOpenMPClauseName(CKind) << 0;
3479 Clause = ParseOpenMPPermutationClause();
3483 Diag(Tok, diag::err_omp_more_one_clause)
3484 << getOpenMPDirectiveName(DKind, OMPVersion)
3485 << getOpenMPClauseName(CKind) << 0;
3488 Clause = ParseOpenMPCountsClause();
3490 case OMPC_uses_allocators:
3491 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3494 if (DKind != OMPD_interop) {
3496 Diag(Tok, diag::err_omp_more_one_clause)
3497 << getOpenMPDirectiveName(DKind, OMPVersion)
3498 << getOpenMPClauseName(CKind) << 0;
3501 Clause = ParseOpenMPClause(CKind, WrongDirective);
3507 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3509 case OMPC_device_type:
3511 skipUntilPragmaOpenMPEnd(DKind);
3513 case OMPC_threadprivate:
3514 case OMPC_groupprivate:
3517 if (!WrongDirective)
3518 Diag(Tok, diag::err_omp_unexpected_clause)
3519 << getOpenMPClauseName(CKind)
3520 << getOpenMPDirectiveName(DKind, OMPVersion);
3524 case OMPC_contains: {
3526 SourceLocation LLoc = Tok.getLocation();
3527 SourceLocation RLoc;
3528 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3533 if (DK == OMPD_unknown) {
3534 skipUntilPragmaOpenMPEnd(OMPD_assume);
3535 Diag(Tok, diag::err_omp_unexpected_clause)
3536 << getOpenMPClauseName(CKind)
3537 << getOpenMPDirectiveName(DKind, OMPVersion);
3541 DKVec.push_back(DK);
3544 Diag(Tok, diag::err_omp_unexpected_clause)
3545 << getOpenMPClauseName(CKind)
3546 << getOpenMPDirectiveName(DKind, OMPVersion);
3549 RLoc = Tok.getLocation();
3551 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3552 CKind, DKVec, Loc, LLoc, RLoc);
3555 case OMPC_no_openmp:
3556 case OMPC_no_openmp_routines:
3557 case OMPC_no_openmp_constructs:
3558 case OMPC_no_parallelism: {
3560 Diag(Tok, diag::err_omp_more_one_clause)
3561 << getOpenMPDirectiveName(DKind, OMPVersion)
3562 << getOpenMPClauseName(CKind) << 0;
3566 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3567 CKind, Loc, Tok.getLocation());
3570 case OMPC_ompx_attribute:
3571 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3573 case OMPC_ompx_bare:
3574 if (DKind == llvm::omp::Directive::OMPD_target) {
3579 Diag(Tok, diag::err_omp_unexpected_clause)
3580 << getOpenMPClauseName(CKind)
3581 << getOpenMPDirectiveName(DKind, OMPVersion);
3583 WrongDirective =
true;
3586 Diag(Tok, diag::note_ompx_bare_clause)
3587 << getOpenMPClauseName(CKind) <<
"target teams";
3588 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3589 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3590 << getOpenMPClauseName(CKind)
3591 << getOpenMPDirectiveName(DKind, OMPVersion);
3594 Clause = ParseOpenMPClause(CKind, WrongDirective);
3596 case OMPC_looprange:
3597 Clause = ParseOpenMPLoopRangeClause();
3602 return ErrorFound ?
nullptr : Clause;
3610 bool IsAddressOfOperand) {
3612 if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3620 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3623 RLoc = Tok.getLocation();
3624 if (!T.consumeClose())
3625 RLoc = T.getCloseLocation();
3647bool Parser::ParseOpenMPIndirectClause(
3652 if (
Tok.isNot(tok::l_paren)) {
3671 if (
Ret.isInvalid())
3674 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3676 if (
Ret.isInvalid())
3687 bool HasError =
false;
3688 bool IsTarget =
false;
3689 bool IsTargetSync =
false;
3691 while (Tok.is(tok::identifier)) {
3693 bool PreferTypeAllowed =
Kind == OMPC_init &&
3696 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3701 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3704 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3706 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3707 IsTargetSync =
true;
3709 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3710 PreferTypeAllowed) {
3713 tok::annot_pragma_openmp_end);
3714 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3717 while (Tok.isNot(tok::r_paren)) {
3718 SourceLocation Loc = Tok.getLocation();
3721 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
3727 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3731 if (Tok.is(tok::comma))
3737 Diag(Tok, diag::err_omp_expected_interop_type);
3740 if (!Tok.is(tok::comma))
3745 if (!HasError && !IsTarget && !IsTargetSync) {
3746 Diag(Tok, diag::err_omp_expected_interop_type);
3750 if (Kind == OMPC_init) {
3751 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
3752 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3753 if (Tok.is(tok::colon))
3770 if (T.expectAndConsume(diag::err_expected_lparen_after,
3771 getOpenMPClauseName(Kind).data()))
3774 bool InteropError =
false;
3775 OMPInteropInfo InteropInfo;
3776 if (Kind == OMPC_init)
3777 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3780 SourceLocation VarLoc = Tok.getLocation();
3783 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3788 SourceLocation RLoc = Tok.getLocation();
3789 if (!T.consumeClose())
3790 RLoc = T.getCloseLocation();
3792 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3795 if (Kind == OMPC_init)
3796 return Actions.OpenMP().ActOnOpenMPInitClause(
3797 InteropVarExpr.
get(), InteropInfo, Loc, T.getOpenLocation(), VarLoc,
3799 if (Kind == OMPC_use)
3800 return Actions.OpenMP().ActOnOpenMPUseClause(
3801 InteropVarExpr.
get(), Loc, T.getOpenLocation(), VarLoc, RLoc);
3803 if (Kind == OMPC_destroy)
3804 return Actions.OpenMP().ActOnOpenMPDestroyClause(
3805 InteropVarExpr.
get(), Loc, T.getOpenLocation(), VarLoc, RLoc);
3807 llvm_unreachable(
"Unexpected interop variable clause.");
3810OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
3814 if (T.expectAndConsume(diag::err_expected_lparen_after,
3815 getOpenMPClauseName(OMPC_ompx_attribute).data()))
3818 ParsedAttributes ParsedAttrs(AttrFactory);
3819 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
3822 if (T.consumeClose())
3828 SmallVector<Attr *> Attrs;
3829 for (
const ParsedAttr &PA : ParsedAttrs) {
3830 switch (PA.getKind()) {
3831 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
3832 if (!PA.checkExactlyNumArgs(Actions, 2))
3834 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
3835 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
3838 case ParsedAttr::AT_AMDGPUWavesPerEU:
3839 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3840 !PA.checkAtMostNumArgs(Actions, 2))
3842 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
3843 PA, PA.getArgAsExpr(0),
3844 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
3847 case ParsedAttr::AT_CUDALaunchBounds:
3848 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3849 !PA.checkAtMostNumArgs(Actions, 3))
3851 if (
auto *A = Actions.CreateLaunchBoundsAttr(
3852 PA, PA.getArgAsExpr(0),
3853 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
3854 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr,
3859 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
3864 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
3865 Attrs, Loc, T.getOpenLocation(), T.getCloseLocation());
3871 if (!Val || ParseOnly)
3873 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3874 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
3875 static_cast<DefaultKind
>(Val->Type) ==
3876 OMP_DEFAULT_firstprivate)) {
3877 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
3878 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
3881 : OMPC_firstprivate)
3882 << getOpenMPClauseName(OMPC_default) <<
"5.1";
3885 return Actions.OpenMP().ActOnOpenMPSimpleClause(
3886 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
3890 SourceLocation Loc = Tok.getLocation();
3895 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3902 SourceLocation DelimLoc;
3905 if (T.expectAndConsume(diag::err_expected_lparen_after,
3906 getOpenMPClauseName(Kind).data()))
3910 SmallVector<unsigned, 4> Arg;
3911 SmallVector<SourceLocation, 4> KLoc;
3912 if (Kind == OMPC_schedule) {
3913 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3914 Arg.resize(NumberOfElements);
3915 KLoc.resize(NumberOfElements);
3920 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3923 Arg[Modifier1] = KindModifier;
3924 KLoc[Modifier1] = Tok.getLocation();
3925 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3926 Tok.isNot(tok::annot_pragma_openmp_end))
3928 if (Tok.is(tok::comma)) {
3932 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3936 KLoc[Modifier2] = Tok.getLocation();
3937 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3938 Tok.isNot(tok::annot_pragma_openmp_end))
3942 if (Tok.is(tok::colon))
3945 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
3947 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3949 Arg[ScheduleKind] = KindModifier;
3950 KLoc[ScheduleKind] = Tok.getLocation();
3951 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3952 Tok.isNot(tok::annot_pragma_openmp_end))
3954 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3955 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3956 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3959 }
else if (Kind == OMPC_dist_schedule) {
3961 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3962 KLoc.push_back(Tok.getLocation());
3963 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3964 Tok.isNot(tok::annot_pragma_openmp_end))
3966 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3968 }
else if (Kind == OMPC_default) {
3971 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3973 Arg.push_back(Modifier);
3974 KLoc.push_back(Tok.getLocation());
3975 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3976 Tok.isNot(tok::annot_pragma_openmp_end))
3979 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
3984 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3985 Arg.push_back(VariableCategory);
3986 KLoc.push_back(Tok.getLocation());
3987 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3988 Tok.isNot(tok::annot_pragma_openmp_end))
3991 Arg.push_back(OMPC_DEFAULT_VC_all);
3992 KLoc.push_back(SourceLocation());
3994 }
else if (Kind == OMPC_defaultmap) {
3997 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4003 Arg.push_back(Modifier);
4004 KLoc.push_back(Tok.getLocation());
4005 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4006 Tok.isNot(tok::annot_pragma_openmp_end))
4009 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
4010 if (Tok.is(tok::colon))
4013 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
4016 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4017 KLoc.push_back(Tok.getLocation());
4018 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4019 Tok.isNot(tok::annot_pragma_openmp_end))
4023 KLoc.push_back(SourceLocation());
4025 }
else if (Kind == OMPC_order) {
4026 enum { Modifier, OrderKind, NumberOfElements };
4027 Arg.resize(NumberOfElements);
4028 KLoc.resize(NumberOfElements);
4032 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4035 Arg[Modifier] = KindModifier;
4036 KLoc[Modifier] = Tok.getLocation();
4037 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4038 Tok.isNot(tok::annot_pragma_openmp_end))
4041 if (Tok.is(tok::colon))
4044 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
4046 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4048 Arg[OrderKind] = KindModifier;
4049 KLoc[OrderKind] = Tok.getLocation();
4050 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4051 Tok.isNot(tok::annot_pragma_openmp_end))
4053 }
else if (Kind == OMPC_device) {
4059 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4060 KLoc.push_back(Tok.getLocation());
4066 KLoc.emplace_back();
4068 }
else if (Kind == OMPC_grainsize) {
4072 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4076 Arg.push_back(Modifier);
4077 KLoc.push_back(Tok.getLocation());
4083 if (Modifier == OMPC_GRAINSIZE_strict) {
4084 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4089 KLoc.emplace_back();
4093 KLoc.emplace_back();
4095 }
else if (Kind == OMPC_dyn_groupprivate) {
4096 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4097 Arg.resize(NumberOfModifiers);
4098 KLoc.resize(NumberOfModifiers);
4102 auto ConsumeModifier = [&]() {
4103 unsigned Type = NumberOfModifiers;
4106 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4110 ParenT.consumeOpen();
4113 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4116 Diag(Tok.getLocation(), diag::err_expected)
4117 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4119 return std::make_tuple(
Type, Modifier, Loc);
4121 Type = ComplexModifier;
4122 Loc = Tok.getLocation();
4123 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4124 Tok.isNot(tok::annot_pragma_openmp_end))
4126 ParenT.consumeClose();
4129 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4131 Type = SimpleModifier;
4132 Loc = Tok.getLocation();
4133 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4134 Tok.isNot(tok::annot_pragma_openmp_end))
4138 return std::make_tuple(
Type, Modifier, Loc);
4141 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4142 SourceLocation Loc) {
4143 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4144 if (!KLoc[
Type].isValid()) {
4145 Arg[
Type] = Modifier;
4148 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4155 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4156 if (Type1 < NumberOfModifiers) {
4157 SaveModifier(Type1, Mod1, Loc1);
4158 if (Tok.is(tok::comma)) {
4161 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4162 if (Type2 < NumberOfModifiers)
4163 SaveModifier(Type2, Mod2, Loc2);
4166 if (Tok.is(tok::colon))
4169 Diag(Tok, diag::warn_pragma_expected_colon)
4170 <<
"dyn_groupprivate modifier";
4172 }
else if (Kind == OMPC_num_tasks) {
4176 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4180 Arg.push_back(Modifier);
4181 KLoc.push_back(Tok.getLocation());
4187 if (Modifier == OMPC_NUMTASKS_strict) {
4188 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4193 KLoc.emplace_back();
4197 KLoc.emplace_back();
4199 }
else if (Kind == OMPC_num_threads) {
4203 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4207 Arg.push_back(Modifier);
4208 KLoc.push_back(Tok.getLocation());
4214 if (Modifier == OMPC_NUMTHREADS_strict) {
4215 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4220 KLoc.emplace_back();
4224 KLoc.emplace_back();
4227 assert(Kind == OMPC_if);
4228 KLoc.push_back(Tok.getLocation());
4229 TentativeParsingAction TPA(*
this);
4231 Arg.push_back(
static_cast<unsigned>(DK));
4232 if (DK != OMPD_unknown) {
4234 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4239 Arg.back() = unsigned(OMPD_unknown);
4246 bool NeedAnExpression =
4248 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
Kind == OMPC_if ||
4249 Kind == OMPC_device ||
Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4250 Kind == OMPC_num_threads ||
Kind == OMPC_dyn_groupprivate;
4251 if (NeedAnExpression) {
4252 SourceLocation ELoc = Tok.getLocation();
4258 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4262 SourceLocation RLoc = Tok.getLocation();
4263 if (!T.consumeClose())
4264 RLoc = T.getCloseLocation();
4266 if (NeedAnExpression && Val.
isInvalid())
4269 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4270 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4271 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4272 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4273 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4276 : OMPC_firstprivate)
4277 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4283 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4284 Kind, Arg, Val.
get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4289 if (ReductionIdScopeSpec.
isEmpty()) {
4327 ReductionIdScopeSpec,
nullptr,
4331 false,
nullptr, ReductionId);
4338 if (!
Tok.is(tok::identifier))
4345 return TypeModifier;
4351 if (T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4352 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4358 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4362 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4363 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4364 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4368 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4370 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4373 return T.consumeClose();
4379 bool HasMapType =
false;
4381 StringRef PreMapName =
"";
4385 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4386 TypeModifier == OMPC_MAP_MODIFIER_close ||
4387 TypeModifier == OMPC_MAP_MODIFIER_present ||
4388 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4389 Data.MapTypeModifiers.push_back(TypeModifier);
4390 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4391 if (PP.LookAhead(0).isNot(tok::comma) &&
4392 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4393 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4394 <<
"map type modifier";
4396 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4397 Data.MapTypeModifiers.push_back(TypeModifier);
4398 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4402 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4404 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4405 <<
"map type modifier";
4410 Data.ExtraModifier = MapKind;
4412 PreMapLoc = Tok.getLocation();
4413 PreMapName = Tok.getIdentifierInfo()->getName();
4415 Diag(Tok, diag::err_omp_more_one_map_type);
4416 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4420 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4421 Data.MapTypeModifiers.push_back(TypeModifier);
4422 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4423 if (PP.LookAhead(0).isNot(tok::comma) &&
4424 PP.LookAhead(0).isNot(tok::colon))
4425 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4426 <<
"map type modifier";
4428 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4438 if (Tok.is(tok::comma)) {
4439 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4444 if (PP.LookAhead(0).is(tok::colon)) {
4452 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4463 if (!Tok.is(tok::colon)) {
4464 Diag(Tok, diag::err_omp_unknown_map_type);
4478 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4483 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4484 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4485 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4495 if (
Tok.is(tok::colon)) {
4496 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4501 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4505ExprResult Parser::ParseOpenMPIteratorsExpr() {
4506 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4507 "Expected 'iterator' token.");
4511 if (T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4514 SourceLocation LLoc = T.getOpenLocation();
4515 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4516 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4519 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4526 IteratorType = TR.
get();
4530 IdentifierInfo *II =
nullptr;
4531 SourceLocation IdLoc;
4532 if (Tok.is(tok::identifier)) {
4533 II = Tok.getIdentifierInfo();
4536 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4540 SourceLocation AssignLoc;
4541 if (Tok.is(tok::equal))
4544 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4549 SourceLocation Loc = Tok.getLocation();
4552 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4555 SourceLocation ColonLoc;
4556 if (Tok.is(tok::colon))
4560 Loc = Tok.getLocation();
4563 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4566 SourceLocation SecColonLoc;
4569 if (Tok.is(tok::colon)) {
4573 Loc = Tok.getLocation();
4576 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4581 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4582 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4583 if (Tok.is(tok::comma))
4586 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4589 D.
Type = IteratorType;
4599 SourceLocation RLoc = Tok.getLocation();
4600 if (!T.consumeClose())
4601 RLoc = T.getCloseLocation();
4603 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4612 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4615 if (Tok.is(tok::identifier) &&
4616 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4618 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4619 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4620 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4621 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4622 Data.ExtraModifier != OMPC_DEPEND_inout)
4623 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4625 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4626 ? OMPC_DEPEND_outallmemory
4627 : OMPC_DEPEND_inoutallmemory;
4643 Data.DepModOrTailExpr = Tail.
get();
4645 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4646 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4664 bool AllocatorSeen =
false;
4665 bool AlignSeen =
false;
4684 if (
Tok.is(tok::l_paren)) {
4685 switch (CurrentModifier) {
4686 case OMPC_ALLOCATE_allocator: {
4687 if (AllocatorSeen) {
4688 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4690 << getOpenMPClauseName(Kind);
4692 Data.AllocClauseModifiers.push_back(CurrentModifier);
4693 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4696 tok::annot_pragma_openmp_end);
4700 AllocatorSeen =
true;
4703 case OMPC_ALLOCATE_align: {
4705 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4707 << getOpenMPClauseName(Kind);
4709 Data.AllocClauseModifiers.push_back(CurrentModifier);
4710 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4714 Data.AllocateAlignment = Val.
get();
4719 llvm_unreachable(
"Unexpected allocate modifier");
4722 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4724 if (
Tok.isNot(tok::comma))
4727 CurrentModifierLoc =
Tok.getLocation();
4732 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4735 }
while (!AllocatorSeen || !AlignSeen);
4744 bool InvalidReductionId =
false;
4745 bool IsInvalidMapperModifier =
false;
4749 if (T.expectAndConsume(diag::err_expected_lparen_after,
4750 getOpenMPClauseName(Kind).data()))
4753 bool HasIterator =
false;
4754 bool InvalidIterator =
false;
4755 bool NeedRParenForLinear =
false;
4757 tok::annot_pragma_openmp_end);
4759 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4760 Kind == OMPC_in_reduction) {
4762 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4763 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4766 Data.ExtraModifier =
4768 Data.ExtraModifierLoc = Tok.getLocation();
4770 assert(Tok.is(tok::comma) &&
"Expected comma.");
4774 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4775 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4781 if (Tok.is(tok::kw_private)) {
4782 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4783 Data.OriginalSharingModifierLoc = Tok.getLocation();
4785 }
else if (Tok.is(tok::identifier) &&
4786 (PP.getSpelling(Tok) ==
"shared" ||
4787 PP.getSpelling(Tok) ==
"default")) {
4788 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4789 Data.OriginalSharingModifierLoc = Tok.getLocation();
4792 Diag(Tok.getLocation(), diag::err_expected)
4793 <<
"'private or shared or default'";
4798 if (!Tok.is(tok::comma)) {
4799 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4806 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4811 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4812 if (InvalidReductionId) {
4813 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4816 if (Tok.is(tok::colon))
4819 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4820 if (!InvalidReductionId)
4821 Data.ReductionOrMapperId =
4822 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4823 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4825 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4834 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4835 Data.DepModOrTailExpr = IteratorRes.
get();
4837 ExpectAndConsume(tok::comma);
4843 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4845 Data.ExtraModifierLoc = Tok.getLocation();
4847 (Kind == OMPC_doacross &&
4849 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4854 if (DKind == OMPD_ordered && Kind == OMPC_depend &&
4855 Data.ExtraModifier == OMPC_DEPEND_source) {
4861 if (Tok.is(tok::colon)) {
4863 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
4864 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4865 : diag::warn_pragma_expected_colon)
4866 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
4868 if (Kind == OMPC_doacross) {
4869 if (Tok.is(tok::identifier) &&
4870 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
4871 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
4872 ? OMPC_DOACROSS_source_omp_cur_iteration
4873 : OMPC_DOACROSS_sink_omp_cur_iteration;
4876 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
4877 if (Tok.isNot(tok::minus)) {
4878 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4879 << getOpenMPClauseName(Kind) << 0 << 0;
4886 if (Tok.isNot(tok::numeric_constant) ||
4887 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
4888 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
4889 << getOpenMPClauseName(Kind) << 0 << 0;
4895 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
4896 if (Tok.isNot(tok::r_paren)) {
4897 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4898 << getOpenMPClauseName(Kind) << 1 << 1;
4904 if (Kind == OMPC_doacross &&
4905 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
4906 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
4907 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
4913 }
else if (Kind == OMPC_linear) {
4915 Data.ExtraModifier = OMPC_LINEAR_val;
4916 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
4917 Data.ExtraModifier =
4921 NeedRParenForLinear =
true;
4923 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
4924 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
4925 <<
"linear(list: [linear-modifier,] step(step-size))";
4927 }
else if (Kind == OMPC_lastprivate) {
4934 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
4935 Data.ExtraModifier =
4937 Data.ExtraModifierLoc = Tok.getLocation();
4939 assert(Tok.is(tok::colon) &&
"Expected colon.");
4942 }
else if (Kind == OMPC_map) {
4944 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4947 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
4948 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4949 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4950 Data.IteratorExpr = IteratorRes.
get();
4952 ExpectAndConsume(tok::comma);
4954 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4957 InvalidIterator =
true;
4967 Data.ExtraModifierLoc = Tok.getLocation();
4970 TentativeParsingAction TPA(*
this);
4971 bool ColonPresent =
false;
4972 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4974 if (Tok.is(tok::colon))
4975 ColonPresent =
true;
4982 Diag(Tok, diag::err_omp_map_modifier_specification_list);
4984 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
4990 Data.ExtraModifier = OMPC_MAP_tofrom;
4992 if (DKind == OMPD_target_enter_data)
4993 Data.ExtraModifier = OMPC_MAP_to;
4994 else if (DKind == OMPD_target_exit_data)
4995 Data.ExtraModifier = OMPC_MAP_from;
4997 Data.IsMapTypeImplicit =
true;
5000 if (Tok.is(tok::colon))
5002 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
5003 while (Tok.is(tok::identifier)) {
5008 Data.MotionModifiers.push_back(Modifier);
5009 Data.MotionModifiersLoc.push_back(Tok.getLocation());
5010 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
5012 Tail = ParseOpenMPIteratorsExpr();
5013 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
5016 Data.IteratorExpr = Tail.
get();
5019 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
5021 if (IsInvalidMapperModifier)
5029 if (Tok.is(tok::comma))
5033 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
5034 if (!IsInvalidMapperModifier) {
5036 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
5038 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
5040 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5048 }
else if (Kind == OMPC_allocate ||
5049 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
5050 PP.getSpelling(Tok) ==
"iterator")) {
5054 TentativeParsingAction TPA(*
this);
5059 if (Kind == OMPC_allocate) {
5064 Tail = ParseOpenMPIteratorsExpr();
5066 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
5069 if (Tok.is(tok::colon)) {
5076 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5077 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5079 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5086 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5089 }
else if (Kind == OMPC_adjust_args) {
5093 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5095 Data.ExtraModifierLoc = Tok.getLocation();
5097 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5102 if (Tok.is(tok::colon))
5103 Data.ColonLoc = Tok.getLocation();
5107 if (Tok.is(tok::l_paren)) {
5110 if (Tok.is(tok::identifier)) {
5111 std::string Modifier = PP.getSpelling(Tok);
5112 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5113 Data.NeedDevicePtrModifier =
5114 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5115 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5117 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5118 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5123 if (Tok.is(tok::r_paren)) {
5124 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5127 Diag(Tok, diag::err_expected) << tok::r_paren;
5128 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5137 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5140 }
else if (Kind == OMPC_use_device_ptr) {
5144 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5148 Data.ExtraModifier = FallbackModifier;
5149 Data.ExtraModifierLoc = Tok.getLocation();
5151 if (Tok.is(tok::colon))
5154 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5158 if (Kind == OMPC_num_teams && !Tok.is(tok::r_paren) &&
5159 !Tok.is(tok::annot_pragma_openmp_end)) {
5163 Data.RLoc = Tok.getLocation();
5164 if (!T.consumeClose())
5165 Data.RLoc = T.getCloseLocation();
5169 if (Tok.is(tok::colon)) {
5175 Data.RLoc = Tok.getLocation();
5176 if (!T.consumeClose())
5177 Data.RLoc = T.getCloseLocation();
5180 Vars.push_back(FirstExpr.
get());
5181 Vars.push_back(UpperBound.
get());
5182 Data.RLoc = Tok.getLocation();
5183 if (!T.consumeClose())
5184 Data.RLoc = T.getCloseLocation();
5187 if (Tok.is(tok::comma)) {
5188 Vars.push_back(FirstExpr.
get());
5189 while (Tok.is(tok::comma)) {
5193 Vars.push_back(NextExpr.
get());
5195 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5200 Data.RLoc = Tok.getLocation();
5201 bool HadError = T.consumeClose();
5203 Data.RLoc = T.getCloseLocation();
5208 Vars.push_back(FirstExpr.
get());
5209 Data.RLoc = Tok.getLocation();
5210 if (!T.consumeClose())
5211 Data.RLoc = T.getCloseLocation();
5216 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5217 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5218 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5219 (Kind == OMPC_reduction && !InvalidReductionId) ||
5223 (Kind == OMPC_adjust_args &&
5225 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5226 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5227 Tok.isNot(tok::annot_pragma_openmp_end))) {
5234 Vars.push_back(VarExpr.
get());
5236 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5241 IsComma = Tok.is(tok::comma);
5244 else if (Tok.isNot(tok::r_paren) &&
5245 Tok.isNot(tok::annot_pragma_openmp_end) &&
5246 (!MayHaveTail || Tok.isNot(tok::colon))) {
5247 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
5248 Diag(Tok, diag::err_omp_expected_punc)
5249 << ((Kind == OMPC_flush)
5250 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5251 : getOpenMPClauseName(Kind))
5252 << (Kind == OMPC_flush);
5257 if (NeedRParenForLinear)
5261 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5262 bool StepFound =
false;
5263 bool ModifierFound =
false;
5265 Data.ColonLoc = Tok.getLocation();
5268 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5269 bool Malformed =
false;
5270 while (Tok.isNot(tok::r_paren)) {
5271 if (Tok.is(tok::identifier)) {
5276 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5279 if (LinKind == OMPC_LINEAR_step) {
5281 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5284 tok::annot_pragma_openmp_end);
5288 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5293 Data.StepModifierLoc = StepModifierLoc;
5297 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5299 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5301 Data.ExtraModifier = LinKind;
5303 ModifierFound =
true;
5308 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5317 if (Tok.is(tok::comma))
5319 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5322 if (!Malformed && !StepFound && !ModifierFound)
5323 Diag(ELoc, diag::err_expected_expression);
5327 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5330 Data.DepModOrTailExpr = Tail.
get();
5332 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5338 Data.RLoc = Tok.getLocation();
5339 if (!T.consumeClose())
5340 Data.RLoc = T.getCloseLocation();
5344 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5346 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5347 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5374 "Expected parsing to start at clause name");
5379 if (T.consumeOpen()) {
5380 Diag(
Tok, diag::err_expected) << tok::l_paren;
5393 Exprs.push_back(Val.
get());
5396 bool Result = T.consumeClose();
5397 OpenLoc = T.getOpenLocation();
5398 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.