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, 2))
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))
3858 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
3863 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
3864 Attrs, Loc, T.getOpenLocation(), T.getCloseLocation());
3870 if (!Val || ParseOnly)
3872 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3873 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
3874 static_cast<DefaultKind
>(Val->Type) ==
3875 OMP_DEFAULT_firstprivate)) {
3876 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
3877 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
3880 : OMPC_firstprivate)
3881 << getOpenMPClauseName(OMPC_default) <<
"5.1";
3884 return Actions.OpenMP().ActOnOpenMPSimpleClause(
3885 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
3889 SourceLocation Loc = Tok.getLocation();
3894 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3901 SourceLocation DelimLoc;
3904 if (T.expectAndConsume(diag::err_expected_lparen_after,
3905 getOpenMPClauseName(Kind).data()))
3909 SmallVector<unsigned, 4> Arg;
3910 SmallVector<SourceLocation, 4> KLoc;
3911 if (Kind == OMPC_schedule) {
3912 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3913 Arg.resize(NumberOfElements);
3914 KLoc.resize(NumberOfElements);
3919 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3922 Arg[Modifier1] = KindModifier;
3923 KLoc[Modifier1] = Tok.getLocation();
3924 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3925 Tok.isNot(tok::annot_pragma_openmp_end))
3927 if (Tok.is(tok::comma)) {
3931 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3935 KLoc[Modifier2] = Tok.getLocation();
3936 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3937 Tok.isNot(tok::annot_pragma_openmp_end))
3941 if (Tok.is(tok::colon))
3944 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
3946 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3948 Arg[ScheduleKind] = KindModifier;
3949 KLoc[ScheduleKind] = Tok.getLocation();
3950 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3951 Tok.isNot(tok::annot_pragma_openmp_end))
3953 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3954 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3955 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3958 }
else if (Kind == OMPC_dist_schedule) {
3960 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3961 KLoc.push_back(Tok.getLocation());
3962 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3963 Tok.isNot(tok::annot_pragma_openmp_end))
3965 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3967 }
else if (Kind == OMPC_default) {
3970 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3972 Arg.push_back(Modifier);
3973 KLoc.push_back(Tok.getLocation());
3974 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3975 Tok.isNot(tok::annot_pragma_openmp_end))
3978 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
3983 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3984 Arg.push_back(VariableCategory);
3985 KLoc.push_back(Tok.getLocation());
3986 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3987 Tok.isNot(tok::annot_pragma_openmp_end))
3990 Arg.push_back(OMPC_DEFAULT_VC_all);
3991 KLoc.push_back(SourceLocation());
3993 }
else if (Kind == OMPC_defaultmap) {
3996 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4002 Arg.push_back(Modifier);
4003 KLoc.push_back(Tok.getLocation());
4004 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4005 Tok.isNot(tok::annot_pragma_openmp_end))
4008 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
4009 if (Tok.is(tok::colon))
4012 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
4015 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4016 KLoc.push_back(Tok.getLocation());
4017 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4018 Tok.isNot(tok::annot_pragma_openmp_end))
4022 KLoc.push_back(SourceLocation());
4024 }
else if (Kind == OMPC_order) {
4025 enum { Modifier, OrderKind, NumberOfElements };
4026 Arg.resize(NumberOfElements);
4027 KLoc.resize(NumberOfElements);
4031 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4034 Arg[Modifier] = KindModifier;
4035 KLoc[Modifier] = Tok.getLocation();
4036 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4037 Tok.isNot(tok::annot_pragma_openmp_end))
4040 if (Tok.is(tok::colon))
4043 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
4045 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4047 Arg[OrderKind] = KindModifier;
4048 KLoc[OrderKind] = Tok.getLocation();
4049 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4050 Tok.isNot(tok::annot_pragma_openmp_end))
4052 }
else if (Kind == OMPC_device) {
4058 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4059 KLoc.push_back(Tok.getLocation());
4065 KLoc.emplace_back();
4067 }
else if (Kind == OMPC_grainsize) {
4071 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4075 Arg.push_back(Modifier);
4076 KLoc.push_back(Tok.getLocation());
4082 if (Modifier == OMPC_GRAINSIZE_strict) {
4083 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4088 KLoc.emplace_back();
4092 KLoc.emplace_back();
4094 }
else if (Kind == OMPC_dyn_groupprivate) {
4095 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4096 Arg.resize(NumberOfModifiers);
4097 KLoc.resize(NumberOfModifiers);
4101 auto ConsumeModifier = [&]() {
4102 unsigned Type = NumberOfModifiers;
4105 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4109 ParenT.consumeOpen();
4112 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4115 Diag(Tok.getLocation(), diag::err_expected)
4116 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4118 return std::make_tuple(
Type, Modifier, Loc);
4120 Type = ComplexModifier;
4121 Loc = Tok.getLocation();
4122 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4123 Tok.isNot(tok::annot_pragma_openmp_end))
4125 ParenT.consumeClose();
4128 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4130 Type = SimpleModifier;
4131 Loc = Tok.getLocation();
4132 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4133 Tok.isNot(tok::annot_pragma_openmp_end))
4137 return std::make_tuple(
Type, Modifier, Loc);
4140 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4141 SourceLocation Loc) {
4142 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4143 if (!KLoc[
Type].isValid()) {
4144 Arg[
Type] = Modifier;
4147 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4154 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4155 if (Type1 < NumberOfModifiers) {
4156 SaveModifier(Type1, Mod1, Loc1);
4157 if (Tok.is(tok::comma)) {
4160 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4161 if (Type2 < NumberOfModifiers)
4162 SaveModifier(Type2, Mod2, Loc2);
4165 if (Tok.is(tok::colon))
4168 Diag(Tok, diag::warn_pragma_expected_colon)
4169 <<
"dyn_groupprivate modifier";
4171 }
else if (Kind == OMPC_num_tasks) {
4175 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4179 Arg.push_back(Modifier);
4180 KLoc.push_back(Tok.getLocation());
4186 if (Modifier == OMPC_NUMTASKS_strict) {
4187 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4192 KLoc.emplace_back();
4196 KLoc.emplace_back();
4198 }
else if (Kind == OMPC_num_threads) {
4202 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4206 Arg.push_back(Modifier);
4207 KLoc.push_back(Tok.getLocation());
4213 if (Modifier == OMPC_NUMTHREADS_strict) {
4214 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4219 KLoc.emplace_back();
4223 KLoc.emplace_back();
4226 assert(Kind == OMPC_if);
4227 KLoc.push_back(Tok.getLocation());
4228 TentativeParsingAction TPA(*
this);
4230 Arg.push_back(
static_cast<unsigned>(DK));
4231 if (DK != OMPD_unknown) {
4233 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4238 Arg.back() = unsigned(OMPD_unknown);
4245 bool NeedAnExpression =
4247 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
Kind == OMPC_if ||
4248 Kind == OMPC_device ||
Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4249 Kind == OMPC_num_threads ||
Kind == OMPC_dyn_groupprivate;
4250 if (NeedAnExpression) {
4251 SourceLocation ELoc = Tok.getLocation();
4257 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4261 SourceLocation RLoc = Tok.getLocation();
4262 if (!T.consumeClose())
4263 RLoc = T.getCloseLocation();
4265 if (NeedAnExpression && Val.
isInvalid())
4268 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4269 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4270 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4271 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4272 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4275 : OMPC_firstprivate)
4276 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4282 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4283 Kind, Arg, Val.
get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4288 if (ReductionIdScopeSpec.
isEmpty()) {
4326 ReductionIdScopeSpec,
nullptr,
4330 false,
nullptr, ReductionId);
4337 if (!
Tok.is(tok::identifier))
4344 return TypeModifier;
4350 if (T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4351 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4357 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4361 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4362 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4363 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4367 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4369 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4372 return T.consumeClose();
4378 bool HasMapType =
false;
4380 StringRef PreMapName =
"";
4384 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4385 TypeModifier == OMPC_MAP_MODIFIER_close ||
4386 TypeModifier == OMPC_MAP_MODIFIER_present ||
4387 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4388 Data.MapTypeModifiers.push_back(TypeModifier);
4389 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4390 if (PP.LookAhead(0).isNot(tok::comma) &&
4391 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4392 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4393 <<
"map type modifier";
4395 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4396 Data.MapTypeModifiers.push_back(TypeModifier);
4397 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4401 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4403 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4404 <<
"map type modifier";
4409 Data.ExtraModifier = MapKind;
4411 PreMapLoc = Tok.getLocation();
4412 PreMapName = Tok.getIdentifierInfo()->getName();
4414 Diag(Tok, diag::err_omp_more_one_map_type);
4415 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4419 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4420 Data.MapTypeModifiers.push_back(TypeModifier);
4421 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4422 if (PP.LookAhead(0).isNot(tok::comma) &&
4423 PP.LookAhead(0).isNot(tok::colon))
4424 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4425 <<
"map type modifier";
4427 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4437 if (Tok.is(tok::comma)) {
4438 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4443 if (PP.LookAhead(0).is(tok::colon)) {
4451 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4462 if (!Tok.is(tok::colon)) {
4463 Diag(Tok, diag::err_omp_unknown_map_type);
4477 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4482 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4483 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4484 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4494 if (
Tok.is(tok::colon)) {
4495 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4500 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4504ExprResult Parser::ParseOpenMPIteratorsExpr() {
4505 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4506 "Expected 'iterator' token.");
4510 if (T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4513 SourceLocation LLoc = T.getOpenLocation();
4514 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4515 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4518 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4525 IteratorType = TR.
get();
4529 IdentifierInfo *II =
nullptr;
4530 SourceLocation IdLoc;
4531 if (Tok.is(tok::identifier)) {
4532 II = Tok.getIdentifierInfo();
4535 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4539 SourceLocation AssignLoc;
4540 if (Tok.is(tok::equal))
4543 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4548 SourceLocation Loc = Tok.getLocation();
4551 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4554 SourceLocation ColonLoc;
4555 if (Tok.is(tok::colon))
4559 Loc = Tok.getLocation();
4562 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4565 SourceLocation SecColonLoc;
4568 if (Tok.is(tok::colon)) {
4572 Loc = Tok.getLocation();
4575 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4580 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4581 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4582 if (Tok.is(tok::comma))
4585 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4588 D.
Type = IteratorType;
4598 SourceLocation RLoc = Tok.getLocation();
4599 if (!T.consumeClose())
4600 RLoc = T.getCloseLocation();
4602 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4611 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4614 if (Tok.is(tok::identifier) &&
4615 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4617 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4618 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4619 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4620 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4621 Data.ExtraModifier != OMPC_DEPEND_inout)
4622 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4624 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4625 ? OMPC_DEPEND_outallmemory
4626 : OMPC_DEPEND_inoutallmemory;
4642 Data.DepModOrTailExpr = Tail.
get();
4644 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4645 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4663 bool AllocatorSeen =
false;
4664 bool AlignSeen =
false;
4683 if (
Tok.is(tok::l_paren)) {
4684 switch (CurrentModifier) {
4685 case OMPC_ALLOCATE_allocator: {
4686 if (AllocatorSeen) {
4687 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4689 << getOpenMPClauseName(Kind);
4691 Data.AllocClauseModifiers.push_back(CurrentModifier);
4692 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4695 tok::annot_pragma_openmp_end);
4699 AllocatorSeen =
true;
4702 case OMPC_ALLOCATE_align: {
4704 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4706 << getOpenMPClauseName(Kind);
4708 Data.AllocClauseModifiers.push_back(CurrentModifier);
4709 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4713 Data.AllocateAlignment = Val.
get();
4718 llvm_unreachable(
"Unexpected allocate modifier");
4721 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4723 if (
Tok.isNot(tok::comma))
4726 CurrentModifierLoc =
Tok.getLocation();
4731 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4734 }
while (!AllocatorSeen || !AlignSeen);
4743 bool InvalidReductionId =
false;
4744 bool IsInvalidMapperModifier =
false;
4748 if (T.expectAndConsume(diag::err_expected_lparen_after,
4749 getOpenMPClauseName(Kind).data()))
4752 bool HasIterator =
false;
4753 bool InvalidIterator =
false;
4754 bool NeedRParenForLinear =
false;
4756 tok::annot_pragma_openmp_end);
4758 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4759 Kind == OMPC_in_reduction) {
4761 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4762 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4765 Data.ExtraModifier =
4767 Data.ExtraModifierLoc = Tok.getLocation();
4769 assert(Tok.is(tok::comma) &&
"Expected comma.");
4773 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4774 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4780 if (Tok.is(tok::kw_private)) {
4781 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4782 Data.OriginalSharingModifierLoc = Tok.getLocation();
4784 }
else if (Tok.is(tok::identifier) &&
4785 (PP.getSpelling(Tok) ==
"shared" ||
4786 PP.getSpelling(Tok) ==
"default")) {
4787 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4788 Data.OriginalSharingModifierLoc = Tok.getLocation();
4791 Diag(Tok.getLocation(), diag::err_expected)
4792 <<
"'private or shared or default'";
4797 if (!Tok.is(tok::comma)) {
4798 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4805 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4810 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4811 if (InvalidReductionId) {
4812 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4815 if (Tok.is(tok::colon))
4818 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4819 if (!InvalidReductionId)
4820 Data.ReductionOrMapperId =
4821 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4822 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4824 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4833 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4834 Data.DepModOrTailExpr = IteratorRes.
get();
4836 ExpectAndConsume(tok::comma);
4842 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4844 Data.ExtraModifierLoc = Tok.getLocation();
4846 (Kind == OMPC_doacross &&
4848 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4853 if (DKind == OMPD_ordered && Kind == OMPC_depend &&
4854 Data.ExtraModifier == OMPC_DEPEND_source) {
4860 if (Tok.is(tok::colon)) {
4862 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
4863 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4864 : diag::warn_pragma_expected_colon)
4865 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
4867 if (Kind == OMPC_doacross) {
4868 if (Tok.is(tok::identifier) &&
4869 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
4870 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
4871 ? OMPC_DOACROSS_source_omp_cur_iteration
4872 : OMPC_DOACROSS_sink_omp_cur_iteration;
4875 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
4876 if (Tok.isNot(tok::minus)) {
4877 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4878 << getOpenMPClauseName(Kind) << 0 << 0;
4885 if (Tok.isNot(tok::numeric_constant) ||
4886 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
4887 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
4888 << getOpenMPClauseName(Kind) << 0 << 0;
4894 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
4895 if (Tok.isNot(tok::r_paren)) {
4896 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4897 << getOpenMPClauseName(Kind) << 1 << 1;
4903 if (Kind == OMPC_doacross &&
4904 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
4905 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
4906 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
4912 }
else if (Kind == OMPC_linear) {
4914 Data.ExtraModifier = OMPC_LINEAR_val;
4915 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
4916 Data.ExtraModifier =
4920 NeedRParenForLinear =
true;
4922 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
4923 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
4924 <<
"linear(list: [linear-modifier,] step(step-size))";
4926 }
else if (Kind == OMPC_lastprivate) {
4933 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
4934 Data.ExtraModifier =
4936 Data.ExtraModifierLoc = Tok.getLocation();
4938 assert(Tok.is(tok::colon) &&
"Expected colon.");
4941 }
else if (Kind == OMPC_map) {
4943 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4946 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
4947 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4948 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4949 Data.IteratorExpr = IteratorRes.
get();
4951 ExpectAndConsume(tok::comma);
4953 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4956 InvalidIterator =
true;
4966 Data.ExtraModifierLoc = Tok.getLocation();
4969 TentativeParsingAction TPA(*
this);
4970 bool ColonPresent =
false;
4971 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4973 if (Tok.is(tok::colon))
4974 ColonPresent =
true;
4981 Diag(Tok, diag::err_omp_map_modifier_specification_list);
4983 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
4989 Data.ExtraModifier = OMPC_MAP_tofrom;
4991 if (DKind == OMPD_target_enter_data)
4992 Data.ExtraModifier = OMPC_MAP_to;
4993 else if (DKind == OMPD_target_exit_data)
4994 Data.ExtraModifier = OMPC_MAP_from;
4996 Data.IsMapTypeImplicit =
true;
4999 if (Tok.is(tok::colon))
5001 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
5002 while (Tok.is(tok::identifier)) {
5007 Data.MotionModifiers.push_back(Modifier);
5008 Data.MotionModifiersLoc.push_back(Tok.getLocation());
5009 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
5011 Tail = ParseOpenMPIteratorsExpr();
5012 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
5015 Data.IteratorExpr = Tail.
get();
5018 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
5020 if (IsInvalidMapperModifier)
5028 if (Tok.is(tok::comma))
5032 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
5033 if (!IsInvalidMapperModifier) {
5035 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
5037 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
5039 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
5047 }
else if (Kind == OMPC_allocate ||
5048 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
5049 PP.getSpelling(Tok) ==
"iterator")) {
5053 TentativeParsingAction TPA(*
this);
5058 if (Kind == OMPC_allocate) {
5063 Tail = ParseOpenMPIteratorsExpr();
5065 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
5068 if (Tok.is(tok::colon)) {
5075 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5076 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5078 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5085 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5088 }
else if (Kind == OMPC_adjust_args) {
5092 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5094 Data.ExtraModifierLoc = Tok.getLocation();
5096 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5101 if (Tok.is(tok::colon))
5102 Data.ColonLoc = Tok.getLocation();
5106 if (Tok.is(tok::l_paren)) {
5109 if (Tok.is(tok::identifier)) {
5110 std::string Modifier = PP.getSpelling(Tok);
5111 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5112 Data.NeedDevicePtrModifier =
5113 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5114 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5116 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5117 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5122 if (Tok.is(tok::r_paren)) {
5123 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5126 Diag(Tok, diag::err_expected) << tok::r_paren;
5127 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5136 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5139 }
else if (Kind == OMPC_use_device_ptr) {
5143 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5147 Data.ExtraModifier = FallbackModifier;
5148 Data.ExtraModifierLoc = Tok.getLocation();
5150 if (Tok.is(tok::colon))
5153 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5157 if (Kind == OMPC_num_teams && !Tok.is(tok::r_paren) &&
5158 !Tok.is(tok::annot_pragma_openmp_end)) {
5162 Data.RLoc = Tok.getLocation();
5163 if (!T.consumeClose())
5164 Data.RLoc = T.getCloseLocation();
5168 if (Tok.is(tok::colon)) {
5174 Data.RLoc = Tok.getLocation();
5175 if (!T.consumeClose())
5176 Data.RLoc = T.getCloseLocation();
5179 Vars.push_back(FirstExpr.
get());
5180 Vars.push_back(UpperBound.
get());
5181 Data.RLoc = Tok.getLocation();
5182 if (!T.consumeClose())
5183 Data.RLoc = T.getCloseLocation();
5186 if (Tok.is(tok::comma)) {
5187 Vars.push_back(FirstExpr.
get());
5188 while (Tok.is(tok::comma)) {
5192 Vars.push_back(NextExpr.
get());
5194 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5199 Data.RLoc = Tok.getLocation();
5200 bool HadError = T.consumeClose();
5202 Data.RLoc = T.getCloseLocation();
5207 Vars.push_back(FirstExpr.
get());
5208 Data.RLoc = Tok.getLocation();
5209 if (!T.consumeClose())
5210 Data.RLoc = T.getCloseLocation();
5215 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5216 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5217 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5218 (Kind == OMPC_reduction && !InvalidReductionId) ||
5222 (Kind == OMPC_adjust_args &&
5224 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5225 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5226 Tok.isNot(tok::annot_pragma_openmp_end))) {
5233 Vars.push_back(VarExpr.
get());
5235 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5240 IsComma = Tok.is(tok::comma);
5243 else if (Tok.isNot(tok::r_paren) &&
5244 Tok.isNot(tok::annot_pragma_openmp_end) &&
5245 (!MayHaveTail || Tok.isNot(tok::colon))) {
5246 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
5247 Diag(Tok, diag::err_omp_expected_punc)
5248 << ((Kind == OMPC_flush)
5249 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5250 : getOpenMPClauseName(Kind))
5251 << (Kind == OMPC_flush);
5256 if (NeedRParenForLinear)
5260 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5261 bool StepFound =
false;
5262 bool ModifierFound =
false;
5264 Data.ColonLoc = Tok.getLocation();
5267 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5268 bool Malformed =
false;
5269 while (Tok.isNot(tok::r_paren)) {
5270 if (Tok.is(tok::identifier)) {
5275 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5278 if (LinKind == OMPC_LINEAR_step) {
5280 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5283 tok::annot_pragma_openmp_end);
5287 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5292 Data.StepModifierLoc = StepModifierLoc;
5296 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5298 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5300 Data.ExtraModifier = LinKind;
5302 ModifierFound =
true;
5307 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5316 if (Tok.is(tok::comma))
5318 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5321 if (!Malformed && !StepFound && !ModifierFound)
5322 Diag(ELoc, diag::err_expected_expression);
5326 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5329 Data.DepModOrTailExpr = Tail.
get();
5331 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5337 Data.RLoc = Tok.getLocation();
5338 if (!T.consumeClose())
5339 Data.RLoc = T.getCloseLocation();
5343 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5345 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5346 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5373 "Expected parsing to start at clause name");
5378 if (T.consumeOpen()) {
5379 Diag(
Tok, diag::err_expected) << tok::l_paren;
5392 Exprs.push_back(Val.
get());
5395 bool Result = T.consumeClose();
5396 OpenLoc = T.getOpenLocation();
5397 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.