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"
34using namespace llvm::omp;
41class DeclDirectiveListParserHelper final {
42 SmallVector<Expr *, 4> Identifiers;
49 void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
50 ExprResult Res = P->getActions().OpenMP().ActOnOpenMPIdExpression(
51 P->getCurScope(), SS, NameInfo, Kind);
53 Identifiers.push_back(Res.
get());
55 llvm::ArrayRef<Expr *> getIdentifiers()
const {
return Identifiers; }
64 auto [D, VR] = getOpenMPDirectiveKindAndVersions(Name);
65 assert(D == Kind &&
"Directive kind mismatch");
68 if (
static_cast<int>(Version) < VR.Min)
69 P.
Diag(Loc, diag::warn_omp_future_directive_spelling) << Name;
75 static const DirectiveNameParser DirParser;
77 const DirectiveNameParser::State *S = DirParser.initial();
80 if (
Tok.isAnnotation())
86 S = DirParser.consume(S, Concat);
90 while (!
Tok.isAnnotation()) {
93 if (!
Tok.isAnnotation()) {
95 S = DirParser.consume(S, TS);
103 assert(S &&
"Should have exited early");
112 bool WithOperator =
false;
113 if (
Tok.is(tok::kw_operator)) {
118 switch (
Tok.getKind()) {
143 case tok::identifier:
148 P.
Diag(
Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
149 P.
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
155 return OOK ==
OO_None ? DeclNames.getIdentifier(
Tok.getIdentifierInfo())
156 : DeclNames.getCXXOperatorName(OOK);
161 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
164 if (T.expectAndConsume(
165 diag::err_expected_lparen_after,
166 getOpenMPDirectiveName(OMPD_declare_reduction, OMPVersion).data())) {
172 if (Name.
isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
176 bool IsCorrect = !ExpectAndConsume(tok::colon);
178 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
181 IsCorrect = IsCorrect && !Name.
isEmpty();
183 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
184 Diag(Tok.getLocation(), diag::err_expected_type);
188 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
191 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
198 QualType ReductionType = Actions.OpenMP().ActOnOpenMPDeclareReductionType(
199 Range.getBegin(), TR);
200 if (!ReductionType.
isNull()) {
201 ReductionTypes.push_back(
202 std::make_pair(ReductionType,
Range.getBegin()));
205 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
209 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
213 if (ExpectAndConsume(tok::comma)) {
215 if (Tok.is(tok::annot_pragma_openmp_end)) {
216 Diag(Tok.getLocation(), diag::err_expected_type);
220 }
while (Tok.isNot(tok::annot_pragma_openmp_end));
222 if (ReductionTypes.empty()) {
227 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
231 if (ExpectAndConsume(tok::colon))
234 if (Tok.is(tok::annot_pragma_openmp_end)) {
235 Diag(Tok.getLocation(), diag::err_expected_expression);
240 Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveStart(
241 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes,
246 unsigned I = 0, E = ReductionTypes.size();
247 for (Decl *D : DRD.get()) {
248 TentativeParsingAction TPA(*
this);
253 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerStart(
getCurScope(), D);
254 ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
256 Actions.OpenMP().ActOnOpenMPDeclareReductionCombinerEnd(
257 D, CombinerResult.
get());
259 if (CombinerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
260 Tok.isNot(tok::annot_pragma_openmp_end)) {
265 IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.
isUsable();
267 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
269 if (Tok.is(tok::identifier) &&
270 Tok.getIdentifierInfo()->isStr(
"initializer")) {
273 Diag(Tok.getLocation(), diag::err_expected) <<
"'initializer'";
280 tok::annot_pragma_openmp_end);
282 !T.expectAndConsume(diag::err_expected_lparen_after,
"initializer") &&
284 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
289 VarDecl *OmpPrivParm =
290 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerStart(
293 if (Tok.is(tok::identifier) &&
294 Tok.getIdentifierInfo()->isStr(
"omp_priv")) {
296 ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
298 InitializerResult = Actions.ActOnFinishFullExpr(
302 Actions.OpenMP().ActOnOpenMPDeclareReductionInitializerEnd(
303 D, InitializerResult.
get(), OmpPrivParm);
304 if (InitializerResult.
isInvalid() && Tok.isNot(tok::r_paren) &&
305 Tok.isNot(tok::annot_pragma_openmp_end)) {
311 !T.consumeClose() && IsCorrect && !InitializerResult.
isInvalid();
323 return Actions.OpenMP().ActOnOpenMPDeclareReductionDirectiveEnd(
327void Parser::ParseOpenMPReductionInitializerForDecl(
VarDecl *OmpPrivParm) {
330 if (isTokenEqualOrEqualTypo()) {
333 if (Tok.is(tok::code_completion)) {
335 Actions.CodeCompletion().CodeCompleteInitializer(
getCurScope(),
337 Actions.FinalizeDeclaration(OmpPrivParm);
341 PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
344 if (
Init.isInvalid()) {
346 Actions.ActOnInitializerError(OmpPrivParm);
348 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
351 }
else if (Tok.is(tok::l_paren)) {
358 SourceLocation LParLoc = T.getOpenLocation();
359 auto RunSignatureHelp = [
this, OmpPrivParm, LParLoc, &Exprs]() {
360 QualType PreferredType =
361 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
363 OmpPrivParm->
getLocation(), Exprs, LParLoc,
false);
364 CalledSignatureHelp =
true;
365 return PreferredType;
367 if (ParseExpressionList(Exprs, [&] {
368 PreferredType.enterFunctionArgument(Tok.getLocation(),
371 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
373 Actions.ActOnInitializerError(OmpPrivParm);
377 SourceLocation RLoc = Tok.getLocation();
378 if (!T.consumeClose())
379 RLoc = T.getCloseLocation();
382 Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
383 Actions.AddInitializerToDecl(OmpPrivParm,
Initializer.get(),
388 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
392 if (
Init.isInvalid()) {
393 Actions.ActOnInitializerError(OmpPrivParm);
395 Actions.AddInitializerToDecl(OmpPrivParm,
Init.get(),
399 Actions.ActOnUninitializedDecl(OmpPrivParm);
405 bool IsCorrect =
true;
406 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
409 if (T.expectAndConsume(
410 diag::err_expected_lparen_after,
411 getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion).data())) {
417 auto &DeclNames = Actions.getASTContext().DeclarationNames;
418 DeclarationName MapperId;
419 if (PP.LookAhead(0).is(tok::colon)) {
420 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
421 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
424 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
428 ExpectAndConsume(tok::colon);
432 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get(
"default"));
435 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
439 DeclarationName VName;
444 MapperType = Actions.OpenMP().ActOnOpenMPDeclareMapperType(
Range.getBegin(),
454 IsCorrect &= !T.consumeClose();
462 DeclarationNameInfo DirName;
463 SourceLocation Loc = Tok.getLocation();
466 ParseScope OMPDirectiveScope(
this, ScopeFlags);
467 Actions.OpenMP().StartOpenMPDSABlock(OMPD_declare_mapper, DirName,
472 Actions.OpenMP().ActOnOpenMPDeclareMapperDirectiveVarDecl(
476 SmallVector<OMPClause *, 6> Clauses;
477 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
480 : getOpenMPClauseKind(PP.getSpelling(Tok));
481 Actions.OpenMP().StartOpenMPClause(CKind);
483 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
485 Clauses.push_back(Clause);
489 if (Tok.is(tok::comma))
491 Actions.OpenMP().EndOpenMPClause();
493 if (Clauses.empty()) {
494 Diag(Tok, diag::err_omp_expected_clause)
495 << getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion);
504 DeclGroupPtrTy DG = Actions.OpenMP().ActOnOpenMPDeclareMapperDirective(
505 OuterScope, Actions.getCurLexicalContext(), MapperId, MapperType,
506 Range.getBegin(), VName, AS, MapperVarRef.
get(), Clauses);
508 Actions.OpenMP().EndOpenMPDSABlock(
nullptr);
509 OMPDirectiveScope.Exit();
520 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
521 DeclSpec DS(AttrFactory);
522 ParseSpecifierQualifierList(DS, AS, DSC);
527 ParseDeclarator(DeclaratorInfo);
528 Range = DeclaratorInfo.getSourceRange();
529 if (DeclaratorInfo.getIdentifier() ==
nullptr) {
530 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
533 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
535 return Actions.OpenMP().ActOnOpenMPDeclareMapperVarDecl(
getCurScope(),
547 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
550 if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
554 (void)ConsumeAnnotationToken();
559 skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
563 VariantMatchInfo VMI;
567 Loc](StringRef ISATrait) {
570 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
573 ASTCtx, std::move(DiagUnknownTrait),
576 Actions.OpenMP().getOpenMPDeviceNum());
578 if (isVariantApplicableInContext(VMI, OMPCtx,
580 Actions.OpenMP().ActOnOpenMPBeginDeclareVariant(Loc, TI);
585 unsigned Nesting = 1;
589 DKLoc = Tok.getLocation();
591 if (DK == OMPD_end_declare_variant)
593 else if (DK == OMPD_begin_declare_variant)
595 if (!Nesting || isEofOrEom())
600 parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant, DK,
611class FNContextRAII final {
615 bool HasFunScope =
false;
616 FNContextRAII() =
delete;
617 FNContextRAII(
const FNContextRAII &) =
delete;
618 FNContextRAII &operator=(
const FNContextRAII &) =
delete;
665 bool IsError =
false;
666 while (
Tok.isNot(tok::annot_pragma_openmp_end)) {
667 if (
Tok.isNot(tok::identifier))
669 OMPDeclareSimdDeclAttr::BranchStateTy Out;
671 StringRef ClauseName = II->
getName();
673 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
674 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
675 P.
Diag(
Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
677 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
683 }
else if (ClauseName ==
"simdlen") {
686 P.
Diag(
Tok, diag::err_omp_more_one_clause)
687 << getOpenMPDirectiveName(OMPD_declare_simd, OMPVersion)
698 if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
699 CKind == OMPC_linear) {
702 if (CKind == OMPC_aligned) {
704 }
else if (CKind == OMPC_linear) {
705 Data.ExtraModifier = OMPC_LINEAR_val;
711 getOpenMPClauseKind(ClauseName), *Vars,
Data))
713 if (CKind == OMPC_aligned) {
714 Alignments.append(Aligneds.size() - Alignments.size(),
715 Data.DepModOrTailExpr);
716 }
else if (CKind == OMPC_linear) {
717 assert(0 <=
Data.ExtraModifier &&
719 "Unexpected linear modifier.");
722 Data.ExtraModifierLoc))
723 Data.ExtraModifier = OMPC_LINEAR_val;
724 LinModifiers.append(Linears.size() - LinModifiers.size(),
726 Steps.append(Linears.size() - Steps.size(),
Data.DepModOrTailExpr);
733 if (
Tok.is(tok::comma))
742 PP.EnterToken(Tok,
true);
743 PP.EnterTokenStream(Toks,
true,
749 FNContextRAII FnContext(*
this, Ptr);
750 OMPDeclareSimdDeclAttr::BranchStateTy BS =
751 OMPDeclareSimdDeclAttr::BS_Undefined;
753 SmallVector<Expr *, 4> Uniforms;
754 SmallVector<Expr *, 4> Aligneds;
755 SmallVector<Expr *, 4> Alignments;
756 SmallVector<Expr *, 4> Linears;
757 SmallVector<unsigned, 4> LinModifiers;
758 SmallVector<Expr *, 4> Steps;
761 Alignments, Linears, LinModifiers, Steps);
762 skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
764 SourceLocation EndLoc = ConsumeAnnotationToken();
767 return Actions.OpenMP().ActOnOpenMPDeclareSimdDirective(
768 Ptr, BS, Simdlen.
get(), Uniforms, Aligneds, Alignments, Linears,
769 LinModifiers, Steps, SourceRange(Loc, EndLoc));
776 CONTEXT_SELECTOR_SET_LVL = 0,
777 CONTEXT_SELECTOR_LVL = 1,
778 CONTEXT_TRAIT_LVL = 2,
781static StringRef stringLiteralParser(
Parser &P) {
788 if (
Tok.
is(tok::identifier) ||
Tok.
is(tok::kw_for)) {
796 return stringLiteralParser(P);
799 diag::warn_omp_declare_variant_string_literal_or_identifier)
804static bool checkForDuplicates(
Parser &P, StringRef Name,
806 llvm::StringMap<SourceLocation> &Seen,
808 auto Res = Seen.try_emplace(Name, NameLoc);
814 P.
Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
816 P.
Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
822void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
823 llvm::omp::TraitSet
Set,
825 llvm::StringMap<SourceLocation> &Seen) {
826 TIProperty.
Kind = TraitProperty::invalid;
828 SourceLocation NameLoc = Tok.getLocation();
830 if (Selector == llvm::omp::TraitSelector::target_device_device_num) {
832 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
834 if (DeviceNumExprResult.
isUsable()) {
835 Expr *DeviceNumExpr = DeviceNumExprResult.
get();
836 Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr);
840 Name = getNameFromIdOrString(*
this, Tok, CONTEXT_TRAIT_LVL);
842 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
843 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
848 TIProperty.
Kind = getOpenMPContextTraitPropertyKind(
Set, Selector, Name);
849 if (TIProperty.
Kind != TraitProperty::invalid) {
850 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
851 TIProperty.
Kind = TraitProperty::invalid;
857 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
858 << Name << getOpenMPContextTraitSelectorName(Selector)
859 << getOpenMPContextTraitSetName(
Set);
861 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
862 if (SetForName != TraitSet::invalid) {
863 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
864 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
865 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
866 << Name <<
"<selector-name>"
867 <<
"(<property-name>)";
870 TraitSelector SelectorForName =
871 getOpenMPContextTraitSelectorKind(Name, SetForName);
872 if (SelectorForName != TraitSelector::invalid) {
873 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
874 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
875 bool AllowsTraitScore =
false;
876 bool RequiresProperty =
false;
877 isValidTraitSelectorForTraitSet(
878 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
879 AllowsTraitScore, RequiresProperty);
880 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
881 << getOpenMPContextTraitSetName(
882 getOpenMPContextTraitSetForSelector(SelectorForName))
883 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
886 for (
const auto &PotentialSet :
887 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
888 TraitSet::device, TraitSet::target_device}) {
889 TraitProperty PropertyForName =
890 getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
891 if (PropertyForName == TraitProperty::invalid)
893 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
894 << getOpenMPContextTraitSetName(
895 getOpenMPContextTraitSetForProperty(PropertyForName))
896 << getOpenMPContextTraitSelectorName(
897 getOpenMPContextTraitSelectorForProperty(PropertyForName))
898 << (
"(" + Name +
")").str();
901 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
902 << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(
Set, Selector);
908 llvm::StringMap<SourceLocation> &Seen) {
909 assert(TISelector.
Kind ==
910 llvm::omp::TraitSelector::implementation_extension &&
911 "Only for extension properties, e.g., "
912 "`implementation={extension(PROPERTY)}`");
913 if (TIProperty.
Kind == TraitProperty::invalid)
916 if (TIProperty.
Kind ==
917 TraitProperty::implementation_extension_disable_implicit_base)
920 if (TIProperty.
Kind ==
921 TraitProperty::implementation_extension_allow_templates)
924 if (TIProperty.
Kind ==
925 TraitProperty::implementation_extension_bind_to_declaration)
930 llvm::omp::TraitProperty::implementation_extension_match_all ||
932 llvm::omp::TraitProperty::implementation_extension_match_any ||
934 llvm::omp::TraitProperty::implementation_extension_match_none);
937 if (IsMatchExtension(TIProperty)) {
939 if (IsMatchExtension(SeenProp)) {
940 P.
Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
941 StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
944 P.
Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
945 << CONTEXT_TRAIT_LVL << SeenName;
951 llvm_unreachable(
"Unknown extension property!");
954void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
955 llvm::omp::TraitSet
Set,
956 llvm::StringMap<SourceLocation> &Seen) {
957 assert(TISelector.
Kind != TraitSelector::user_condition &&
958 "User conditions are special properties not handled here!");
960 SourceLocation PropertyLoc = Tok.getLocation();
961 OMPTraitProperty TIProperty;
962 parseOMPTraitPropertyKind(TIProperty,
Set, TISelector.
Kind, Seen);
964 if (TISelector.
Kind == llvm::omp::TraitSelector::implementation_extension)
967 TIProperty.
Kind = TraitProperty::invalid;
970 if (TIProperty.
Kind == TraitProperty::invalid) {
971 if (PropertyLoc != Tok.getLocation())
972 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
973 << CONTEXT_TRAIT_LVL;
977 if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.
Kind,
986 Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
987 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
989 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
990 << getOpenMPContextTraitSetName(
Set);
991 Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
992 << getOpenMPContextTraitPropertyName(TIProperty.
Kind,
994 << getOpenMPContextTraitSelectorName(
995 getOpenMPContextTraitSelectorForProperty(TIProperty.
Kind))
996 << getOpenMPContextTraitSetName(
997 getOpenMPContextTraitSetForProperty(TIProperty.
Kind));
998 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
999 << CONTEXT_TRAIT_LVL;
1002void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
1003 llvm::omp::TraitSet
Set,
1004 llvm::StringMap<SourceLocation> &Seen) {
1005 TISelector.
Kind = TraitSelector::invalid;
1007 SourceLocation NameLoc = Tok.getLocation();
1008 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_LVL);
1010 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1011 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1015 TISelector.
Kind = getOpenMPContextTraitSelectorKind(Name,
Set);
1016 if (TISelector.
Kind != TraitSelector::invalid) {
1017 if (checkForDuplicates(*
this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1018 TISelector.
Kind = TraitSelector::invalid;
1023 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1024 << Name << getOpenMPContextTraitSetName(
Set);
1026 TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1027 if (SetForName != TraitSet::invalid) {
1028 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1029 << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1030 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1031 << Name <<
"<selector-name>"
1032 <<
"<property-name>";
1035 for (
const auto &PotentialSet :
1036 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1037 TraitSet::device, TraitSet::target_device}) {
1038 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1039 PotentialSet, TraitSelector::invalid, Name);
1040 if (PropertyForName == TraitProperty::invalid)
1042 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1043 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1044 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1045 << getOpenMPContextTraitSetName(
1046 getOpenMPContextTraitSetForProperty(PropertyForName))
1047 << getOpenMPContextTraitSelectorName(
1048 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1049 << (
"(" + Name +
")").str();
1052 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1053 << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(
Set);
1060 StringRef SelectorName =
1062 if (SelectorName !=
"score")
1073 <<
"score expression";
1077void Parser::parseOMPContextSelector(
1078 OMPTraitSelector &TISelector, llvm::omp::TraitSet
Set,
1079 llvm::StringMap<SourceLocation> &SeenSelectors) {
1080 unsigned short OuterPC = ParenCount;
1085 auto FinishSelector = [OuterPC,
this]() ->
void {
1088 while (!
SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1089 tok::annot_pragma_openmp_end},
1092 if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1093 (void)ConsumeParen();
1094 if (OuterPC <= ParenCount) {
1098 if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1104 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1105 << CONTEXT_SELECTOR_LVL;
1108 SourceLocation SelectorLoc = Tok.getLocation();
1109 parseOMPTraitSelectorKind(TISelector,
Set, SeenSelectors);
1110 if (TISelector.
Kind == TraitSelector::invalid)
1111 return FinishSelector();
1113 bool AllowsTraitScore =
false;
1114 bool RequiresProperty =
false;
1115 if (!isValidTraitSelectorForTraitSet(TISelector.
Kind,
Set, AllowsTraitScore,
1116 RequiresProperty)) {
1117 Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1118 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1119 << getOpenMPContextTraitSetName(
Set);
1120 Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1121 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1122 << getOpenMPContextTraitSetName(
1123 getOpenMPContextTraitSetForSelector(TISelector.
Kind))
1124 << RequiresProperty;
1125 return FinishSelector();
1128 if (!RequiresProperty) {
1130 {getOpenMPContextTraitPropertyForSelector(TISelector.
Kind),
1131 getOpenMPContextTraitSelectorName(TISelector.
Kind)});
1135 if (!Tok.is(tok::l_paren)) {
1136 Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1137 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1138 << getOpenMPContextTraitSetName(
Set);
1139 return FinishSelector();
1142 if (TISelector.
Kind == TraitSelector::user_condition) {
1143 SourceLocation RLoc;
1146 return FinishSelector();
1149 {TraitProperty::user_condition_unknown,
"<condition>"});
1154 tok::annot_pragma_openmp_end);
1156 (void)BDT.consumeOpen();
1158 SourceLocation ScoreLoc = Tok.getLocation();
1161 if (!AllowsTraitScore && !Score.
isUnset()) {
1163 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1164 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1165 << getOpenMPContextTraitSetName(
Set) << Score.
get();
1167 Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1168 << getOpenMPContextTraitSelectorName(TISelector.
Kind)
1169 << getOpenMPContextTraitSetName(
Set) <<
"<invalid>";
1177 llvm::StringMap<SourceLocation> SeenProperties;
1179 parseOMPContextProperty(TISelector,
Set, SeenProperties);
1186void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1187 llvm::StringMap<SourceLocation> &Seen) {
1188 TISet.
Kind = TraitSet::invalid;
1190 SourceLocation NameLoc = Tok.getLocation();
1191 StringRef Name = getNameFromIdOrString(*
this, Tok, CONTEXT_SELECTOR_SET_LVL);
1193 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1194 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1198 TISet.
Kind = getOpenMPContextTraitSetKind(Name);
1199 if (TISet.
Kind != TraitSet::invalid) {
1200 if (checkForDuplicates(*
this, Name, NameLoc, Seen,
1201 CONTEXT_SELECTOR_SET_LVL))
1202 TISet.
Kind = TraitSet::invalid;
1207 Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1209 TraitSelector SelectorForName =
1210 getOpenMPContextTraitSelectorKind(Name, TISet.
Kind);
1211 if (SelectorForName != TraitSelector::invalid) {
1212 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1213 << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1214 bool AllowsTraitScore =
false;
1215 bool RequiresProperty =
false;
1216 isValidTraitSelectorForTraitSet(
1217 SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1218 AllowsTraitScore, RequiresProperty);
1219 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1220 << getOpenMPContextTraitSetName(
1221 getOpenMPContextTraitSetForSelector(SelectorForName))
1222 << Name << (RequiresProperty ?
"(<property-name>)" :
"");
1225 for (
const auto &PotentialSet :
1226 {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1227 TraitSet::device, TraitSet::target_device}) {
1228 TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1229 PotentialSet, TraitSelector::invalid, Name);
1230 if (PropertyForName == TraitProperty::invalid)
1232 Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1233 << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1234 Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1235 << getOpenMPContextTraitSetName(
1236 getOpenMPContextTraitSetForProperty(PropertyForName))
1237 << getOpenMPContextTraitSelectorName(
1238 getOpenMPContextTraitSelectorForProperty(PropertyForName))
1239 << (
"(" + Name +
")").str();
1242 Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1243 << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1246void Parser::parseOMPContextSelectorSet(
1247 OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1248 auto OuterBC = BraceCount;
1253 auto FinishSelectorSet = [
this, OuterBC]() ->
void {
1256 while (!
SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1257 tok::annot_pragma_openmp_end},
1260 if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1261 (void)ConsumeBrace();
1262 if (OuterBC <= BraceCount) {
1266 if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1272 Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1273 << CONTEXT_SELECTOR_SET_LVL;
1276 parseOMPTraitSetKind(TISet, SeenSets);
1277 if (TISet.
Kind == TraitSet::invalid)
1278 return FinishSelectorSet();
1282 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1284 << (
"context set name \"" + getOpenMPContextTraitSetName(TISet.
Kind) +
1289 if (Tok.is(tok::l_brace)) {
1290 (void)ConsumeBrace();
1292 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1294 << (
"'=' that follows the context set name \"" +
1295 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1299 llvm::StringMap<SourceLocation> SeenSelectors;
1301 OMPTraitSelector TISelector;
1302 parseOMPContextSelector(TISelector, TISet.
Kind, SeenSelectors);
1303 if (TISelector.
Kind != TraitSelector::invalid &&
1309 if (Tok.is(tok::r_brace)) {
1310 (void)ConsumeBrace();
1312 Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1314 << (
"context selectors for the context set \"" +
1315 getOpenMPContextTraitSetName(TISet.
Kind) +
"\"")
1320bool Parser::parseOMPContextSelectors(
SourceLocation Loc, OMPTraitInfo &TI) {
1321 llvm::StringMap<SourceLocation> SeenSets;
1324 parseOMPContextSelectorSet(TISet, SeenSets);
1325 if (TISet.
Kind != TraitSet::invalid && !TISet.
Selectors.empty())
1326 TI.
Sets.push_back(TISet);
1335 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1336 PP.EnterToken(Tok,
true);
1337 PP.EnterTokenStream(Toks,
true,
1343 FNContextRAII FnContext(*
this, Ptr);
1345 SourceLocation RLoc;
1355 getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion), RLoc,
1358 if (!AssociatedFunction.
isUsable()) {
1359 if (!Tok.is(tok::annot_pragma_openmp_end))
1363 (void)ConsumeAnnotationToken();
1367 OMPTraitInfo *ParentTI =
1368 Actions.OpenMP().getOMPTraitInfoForSurroundingScope();
1369 ASTContext &ASTCtx = Actions.getASTContext();
1371 SmallVector<Expr *, 6> AdjustNothing;
1372 SmallVector<Expr *, 6> AdjustNeedDevicePtr;
1373 SmallVector<Expr *, 6> AdjustNeedDeviceAddr;
1374 SmallVector<OMPInteropInfo, 3> AppendArgs;
1375 SourceLocation AdjustArgsLoc, AppendArgsLoc;
1378 if (Tok.is(tok::annot_pragma_openmp_end)) {
1379 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1383 bool IsError =
false;
1384 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1387 : getOpenMPClauseKind(PP.getSpelling(Tok));
1388 if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1390 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1397 IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1399 case OMPC_adjust_args: {
1400 AdjustArgsLoc = Tok.getLocation();
1402 SemaOpenMP::OpenMPVarListDataTy
Data;
1403 SmallVector<Expr *> Vars;
1407 switch (
Data.ExtraModifier) {
1408 case OMPC_ADJUST_ARGS_nothing:
1409 llvm::append_range(AdjustNothing, Vars);
1411 case OMPC_ADJUST_ARGS_need_device_ptr:
1412 llvm::append_range(AdjustNeedDevicePtr, Vars);
1414 case OMPC_ADJUST_ARGS_need_device_addr:
1415 llvm::append_range(AdjustNeedDeviceAddr, Vars);
1418 llvm_unreachable(
"Unexpected 'adjust_args' clause modifier.");
1423 case OMPC_append_args:
1424 if (!AppendArgs.empty()) {
1425 Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1426 << getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion)
1427 << getOpenMPClauseName(CKind) << 0;
1431 AppendArgsLoc = Tok.getLocation();
1433 IsError = parseOpenMPAppendArgs(AppendArgs);
1437 llvm_unreachable(
"Unexpected clause for declare variant.");
1444 (void)ConsumeAnnotationToken();
1448 if (Tok.is(tok::comma))
1452 std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1453 Actions.OpenMP().checkOpenMPDeclareVariantFunction(
1454 Ptr, AssociatedFunction.
get(), TI, AppendArgs.size(),
1455 SourceRange(Loc, Tok.getLocation()));
1457 if (DeclVarData && !TI.
Sets.empty())
1458 Actions.OpenMP().ActOnOpenMPDeclareVariantDirective(
1459 DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1460 AdjustNeedDevicePtr, AdjustNeedDeviceAddr, AppendArgs, AdjustArgsLoc,
1461 AppendArgsLoc, SourceRange(Loc, Tok.getLocation()));
1464 (void)ConsumeAnnotationToken();
1467bool Parser::parseOpenMPAppendArgs(
1469 bool HasError =
false;
1472 if (T.expectAndConsume(diag::err_expected_lparen_after,
1473 getOpenMPClauseName(OMPC_append_args).data()))
1478 while (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr(
"interop")) {
1481 tok::annot_pragma_openmp_end);
1482 if (IT.expectAndConsume(diag::err_expected_lparen_after,
"interop"))
1485 OMPInteropInfo InteropInfo;
1486 if (ParseOMPInteropInfo(InteropInfo, OMPC_append_args))
1489 InteropInfos.push_back(InteropInfo);
1492 if (Tok.is(tok::comma))
1495 if (!HasError && InteropInfos.empty()) {
1497 Diag(Tok.getLocation(), diag::err_omp_unexpected_append_op);
1498 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1501 HasError = T.consumeClose() || HasError;
1505bool Parser::parseOMPDeclareVariantMatchClause(
SourceLocation Loc,
1507 OMPTraitInfo *ParentTI) {
1511 : getOpenMPClauseKind(PP.getSpelling(Tok));
1512 if (CKind != OMPC_match) {
1513 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1520 if (T.expectAndConsume(diag::err_expected_lparen_after,
1521 getOpenMPClauseName(OMPC_match).data()))
1525 parseOMPContextSelectors(Loc, TI);
1528 (void)T.consumeClose();
1538 for (
const OMPTraitSet &ParentSet : ParentTI->
Sets) {
1539 bool MergedSet =
false;
1540 for (OMPTraitSet &
Set : TI.
Sets) {
1541 if (
Set.Kind != ParentSet.
Kind)
1544 for (
const OMPTraitSelector &ParentSelector : ParentSet.
Selectors) {
1545 bool MergedSelector =
false;
1546 for (OMPTraitSelector &Selector :
Set.Selectors) {
1547 if (Selector.
Kind != ParentSelector.
Kind)
1549 MergedSelector =
true;
1550 for (
const OMPTraitProperty &ParentProperty :
1552 bool MergedProperty =
false;
1566 if (Selector.
Kind == llvm::omp::TraitSelector::user_condition) {
1567 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1570 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1571 << getOpenMPContextTraitPropertyName(
1573 << getOpenMPContextTraitSelectorName(ParentSelector.
Kind)
1574 << getOpenMPContextTraitSetName(ParentSet.
Kind);
1577 if (!MergedProperty)
1578 Selector.
Properties.push_back(ParentProperty);
1581 if (!MergedSelector)
1582 Set.Selectors.push_back(ParentSelector);
1586 TI.
Sets.push_back(ParentSet);
1595 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
1596 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1599 : getOpenMPClauseKind(PP.getSpelling(Tok));
1600 Actions.OpenMP().StartOpenMPClause(CKind);
1602 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
1603 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1605 SeenClauses[unsigned(CKind)] =
true;
1606 if (Clause !=
nullptr)
1607 Clauses.push_back(Clause);
1608 if (Tok.is(tok::annot_pragma_openmp_end)) {
1609 Actions.OpenMP().EndOpenMPClause();
1613 if (Tok.is(tok::comma))
1615 Actions.OpenMP().EndOpenMPClause();
1621 SmallVector<std::string, 4> Assumptions;
1622 bool SkippedClauses =
false;
1624 auto SkipBraces = [&](llvm::StringRef Spelling,
bool IssueNote) {
1626 tok::annot_pragma_openmp_end);
1627 if (T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1630 if (IssueNote && T.getCloseLocation().isValid())
1631 Diag(T.getCloseLocation(),
1632 diag::note_omp_assumption_clause_continue_here);
1638 auto MatchACMClause = [&](StringRef RawString) {
1639 llvm::StringSwitch<int> SS(RawString);
1640 unsigned ACMIdx = 0;
1641 for (
const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1642 if (ACMI.StartsWith)
1643 SS.StartsWith(ACMI.Identifier, ACMIdx++);
1645 SS.Case(ACMI.Identifier, ACMIdx++);
1647 return SS.Default(-1);
1650 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1651 IdentifierInfo *II =
nullptr;
1652 SourceLocation StartLoc = Tok.getLocation();
1654 if (Tok.isAnyIdentifier()) {
1655 II = Tok.getIdentifierInfo();
1656 Idx = MatchACMClause(II->
getName());
1660 bool NextIsLPar = Tok.is(tok::l_paren);
1663 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1664 Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1665 << llvm::omp::getOpenMPDirectiveName(DKind, OMPVersion)
1666 << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1668 SkipBraces(II ? II->
getName() :
"",
true);
1669 SkippedClauses =
true;
1672 const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1673 if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1676 SkippedClauses =
true;
1677 SkipBraces(II->
getName(),
false);
1682 Diag(Tok.getLocation(),
1683 diag::warn_omp_unknown_assumption_clause_without_args)
1685 SkipBraces(II->
getName(),
true);
1688 assert(II &&
"Expected an identifier clause!");
1689 std::string Assumption = II->
getName().str();
1690 if (ACMI.StartsWith)
1691 Assumption =
"ompx_" + Assumption.substr(ACMI.Identifier.size());
1693 Assumption =
"omp_" + Assumption;
1694 Assumptions.push_back(Assumption);
1697 Actions.OpenMP().ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions,
1702 if (Actions.OpenMP().isInOpenMPAssumeScope())
1703 Actions.OpenMP().ActOnOpenMPEndAssumesDirective();
1705 Diag(Loc, diag::err_expected_begin_assumes);
1719struct SimpleClauseData {
1722 SourceLocation LOpen;
1723 SourceLocation TypeLoc;
1724 SourceLocation RLoc;
1725 SimpleClauseData(
unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1726 SourceLocation TypeLoc, SourceLocation RLoc)
1727 :
Type(
Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1731static std::optional<SimpleClauseData>
1738 if (T.expectAndConsume(diag::err_expected_lparen_after,
1739 getOpenMPClauseName(Kind).data()))
1740 return std::nullopt;
1746 if (
Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::comma) &&
1747 Tok.isNot(tok::annot_pragma_openmp_end))
1752 if (!T.consumeClose())
1753 RLoc = T.getCloseLocation();
1755 return SimpleClauseData(
Type, Loc, LOpen,
TypeLoc, RLoc);
1758void Parser::ParseOMPDeclareTargetClauses(
1760 SourceLocation DeviceTypeLoc;
1761 bool RequiresToOrLinkOrIndirectClause =
false;
1762 bool HasToOrLinkOrIndirectClause =
false;
1763 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1764 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1765 bool HasIdentifier = Tok.is(tok::identifier);
1766 if (HasIdentifier) {
1768 RequiresToOrLinkOrIndirectClause =
true;
1769 IdentifierInfo *II = Tok.getIdentifierInfo();
1770 StringRef ClauseName = II->
getName();
1771 bool IsDeviceTypeClause =
1773 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1775 bool IsIndirectClause =
getLangOpts().OpenMP >= 51 &&
1776 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1777 if (DTCI.
Indirect && IsIndirectClause) {
1778 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1779 Diag(Tok, diag::err_omp_more_one_clause)
1780 << getOpenMPDirectiveName(OMPD_declare_target, OMPVersion)
1781 << getOpenMPClauseName(OMPC_indirect) << 0;
1784 bool IsToEnterOrLinkClause =
1785 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1786 assert((!IsDeviceTypeClause || !IsToEnterOrLinkClause) &&
1791 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1792 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1795 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1796 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1800 if (!IsDeviceTypeClause && !IsIndirectClause &&
1801 DTCI.
Kind == OMPD_begin_declare_target) {
1802 Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1803 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1806 if (!IsDeviceTypeClause && !IsToEnterOrLinkClause && !IsIndirectClause) {
1808 ? diag::err_omp_declare_target_unexpected_clause_52
1809 : diag::err_omp_declare_target_unexpected_clause)
1817 if (IsToEnterOrLinkClause || IsIndirectClause)
1818 HasToOrLinkOrIndirectClause =
true;
1820 if (IsIndirectClause) {
1821 if (!ParseOpenMPIndirectClause(DTCI,
false))
1826 if (IsDeviceTypeClause) {
1827 std::optional<SimpleClauseData> DevTypeData =
1830 if (DeviceTypeLoc.
isValid()) {
1832 Diag(DevTypeData->Loc,
1833 diag::warn_omp_more_one_device_type_clause);
1837 case OMPC_DEVICE_TYPE_any:
1838 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Any;
1840 case OMPC_DEVICE_TYPE_host:
1841 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Host;
1843 case OMPC_DEVICE_TYPE_nohost:
1844 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1847 llvm_unreachable(
"Unexpected device_type");
1849 DeviceTypeLoc = DevTypeData->Loc;
1856 if (DTCI.
Kind == OMPD_declare_target || HasIdentifier) {
1857 auto &&Callback = [
this, MT, &DTCI](CXXScopeSpec &SS,
1858 DeclarationNameInfo NameInfo) {
1859 NamedDecl *ND = Actions.OpenMP().lookupOpenMPDeclareTargetName(
1863 SemaOpenMP::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.
getLoc()};
1866 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1869 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1874 if (Tok.is(tok::l_paren)) {
1876 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1879 if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1882 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1883 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1888 if (Tok.is(tok::comma))
1892 if (DTCI.
Indirect && DTCI.
DT != OMPDeclareTargetDeclAttr::DT_Any)
1893 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1896 if (DTCI.
Kind == OMPD_declare_target && RequiresToOrLinkOrIndirectClause &&
1897 !HasToOrLinkOrIndirectClause)
1900 ? diag::err_omp_declare_target_missing_enter_or_link_clause
1901 : diag::err_omp_declare_target_missing_to_or_link_clause)
1910 if (Tok.is(tok::annot_pragma_openmp_end))
1913 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1914 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1915 << getOpenMPDirectiveName(DKind, OMPVersion);
1916 while (Tok.isNot(tok::annot_pragma_openmp_end))
1925 bool SkipUntilOpenMPEnd) {
1926 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1928 if (FoundKind == ExpectedKind) {
1930 skipUntilPragmaOpenMPEnd(ExpectedKind);
1934 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1935 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1937 Diag(BeginLoc, diag::note_matching)
1938 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind, OMPVersion) +
"'")
1940 if (SkipUntilOpenMPEnd)
1947 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1951 if (Tok.is(tok::annot_pragma_openmp_end))
1952 ConsumeAnnotationToken();
1958 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
1959 "Not an OpenMP directive!");
1962 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1967 TentativeParsingAction TPA(*
this);
1968 Loc = ConsumeAnnotationToken();
1970 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1975 Toks.push_back(Tok);
1976 while (Cnt && Tok.isNot(tok::eof)) {
1978 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
1980 else if (Tok.is(tok::annot_pragma_openmp_end))
1982 Toks.push_back(Tok);
1987 auto *LP =
new LateParsedPragma(
this, AS);
1989 getCurrentClass().LateParsedDeclarations.push_back(LP);
1994 Loc = ConsumeAnnotationToken();
1999 case OMPD_threadprivate: {
2001 DeclDirectiveListParserHelper Helper(
this, DKind);
2002 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2004 skipUntilPragmaOpenMPEnd(DKind);
2006 ConsumeAnnotationToken();
2007 return Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2008 Loc, Helper.getIdentifiers());
2012 case OMPD_groupprivate: {
2014 DeclDirectiveListParserHelper Helper(
this, DKind);
2015 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2017 skipUntilPragmaOpenMPEnd(DKind);
2019 ConsumeAnnotationToken();
2020 return Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2021 Loc, Helper.getIdentifiers());
2025 case OMPD_allocate: {
2027 DeclDirectiveListParserHelper Helper(
this, DKind);
2028 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2030 SmallVector<OMPClause *, 1> Clauses;
2031 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2032 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
2033 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2035 Tok.isAnnotation() ? OMPC_unknown
2036 : getOpenMPClauseKind(PP.getSpelling(Tok));
2037 Actions.OpenMP().StartOpenMPClause(CKind);
2038 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2039 !SeenClauses[
unsigned(CKind)]);
2040 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2042 SeenClauses[unsigned(CKind)] =
true;
2043 if (Clause !=
nullptr)
2044 Clauses.push_back(Clause);
2045 if (Tok.is(tok::annot_pragma_openmp_end)) {
2046 Actions.OpenMP().EndOpenMPClause();
2050 if (Tok.is(tok::comma))
2052 Actions.OpenMP().EndOpenMPClause();
2054 skipUntilPragmaOpenMPEnd(DKind);
2057 ConsumeAnnotationToken();
2058 return Actions.OpenMP().ActOnOpenMPAllocateDirective(
2059 Loc, Helper.getIdentifiers(), Clauses);
2063 case OMPD_requires: {
2065 SmallVector<OMPClause *, 5> Clauses;
2066 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2067 if (Tok.is(tok::annot_pragma_openmp_end)) {
2068 Diag(Tok, diag::err_omp_expected_clause)
2069 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2072 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2075 : getOpenMPClauseKind(PP.getSpelling(Tok));
2076 Actions.OpenMP().StartOpenMPClause(CKind);
2077 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
2078 !SeenClauses[
unsigned(CKind)]);
2079 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2081 SeenClauses[unsigned(CKind)] =
true;
2082 if (Clause !=
nullptr)
2083 Clauses.push_back(Clause);
2084 if (Tok.is(tok::annot_pragma_openmp_end)) {
2085 Actions.OpenMP().EndOpenMPClause();
2089 if (Tok.is(tok::comma))
2091 Actions.OpenMP().EndOpenMPClause();
2094 if (Clauses.empty()) {
2095 Diag(Tok, diag::err_omp_expected_clause)
2096 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2097 ConsumeAnnotationToken();
2100 ConsumeAnnotationToken();
2101 return Actions.OpenMP().ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2104 SmallVector<OMPClause *, 1> Clauses;
2106 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2107 Actions.OpenMP().ActOnOpenMPErrorDirective(Clauses, StartLoc,
2113 case OMPD_begin_assumes:
2116 case OMPD_end_assumes:
2119 case OMPD_declare_reduction:
2121 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2122 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2124 ConsumeAnnotationToken();
2128 case OMPD_declare_mapper: {
2130 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2132 ConsumeAnnotationToken();
2137 case OMPD_begin_declare_variant: {
2142 ConsumeAnnotationToken();
2146 case OMPD_end_declare_variant: {
2148 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2149 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2151 Diag(Loc, diag::err_expected_begin_declare_variant);
2153 ConsumeAnnotationToken();
2156 case OMPD_declare_variant:
2157 case OMPD_declare_simd: {
2163 Toks.push_back(Tok);
2165 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2166 Toks.push_back(Tok);
2169 Toks.push_back(Tok);
2173 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2174 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2176 }
else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2180 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2181 MaybeParseCXX11Attributes(Attrs);
2182 ParsingDeclSpec PDS(*
this);
2183 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2186 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2190 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2191 << (DKind == OMPD_declare_simd ? 0 : 1);
2194 if (DKind == OMPD_declare_simd)
2195 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2196 assert(DKind == OMPD_declare_variant &&
2197 "Expected declare variant directive only");
2198 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2201 case OMPD_begin_declare_target:
2202 case OMPD_declare_target: {
2204 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2205 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2206 if (DKind == OMPD_declare_target && !HasClauses &&
2208 Diag(DTLoc, diag::warn_omp_deprecated_declare_target_delimited_form);
2210 ParseOMPDeclareTargetClauses(DTCI);
2211 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2218 if (HasImplicitMappings) {
2219 Actions.OpenMP().ActOnStartOpenMPDeclareTargetContext(DTCI);
2223 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2224 llvm::SmallVector<Decl *, 4> Decls;
2226 Decls.push_back(It.first);
2227 return Actions.BuildDeclaratorGroup(Decls);
2229 case OMPD_end_declare_target: {
2230 if (!Actions.OpenMP().isInOpenMPDeclareTargetContext()) {
2231 Diag(Tok, diag::err_omp_unexpected_directive)
2232 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2235 const SemaOpenMP::DeclareTargetContextInfo &DTCI =
2236 Actions.OpenMP().ActOnOpenMPEndDeclareTargetDirective();
2237 ParseOMPEndDeclareTargetDirective(DTCI.
Kind, DKind, DTCI.
Loc);
2241 Diag(Tok, diag::err_omp_unexpected_directive)
2242 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2246 Diag(Tok, diag::err_omp_unknown_directive);
2249 switch (getDirectiveCategory(DKind)) {
2250 case Category::Executable:
2251 case Category::Meta:
2252 case Category::Subsidiary:
2253 case Category::Utility:
2254 Diag(Tok, diag::err_omp_unexpected_directive)
2255 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2257 case Category::Declarative:
2258 case Category::Informational:
2262 while (Tok.isNot(tok::annot_pragma_openmp_end))
2268StmtResult Parser::ParseOpenMPExecutableDirective(
2270 bool ReadDirectiveWithinMetadirective) {
2272 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2274 bool HasAssociatedStatement =
true;
2275 Association Assoc = getDirectiveAssociation(DKind);
2281 if (DKind != OMPD_ordered && DKind != OMPD_section &&
2282 (Assoc == Association::None || Assoc == Association::Separating)) {
2283 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2284 ParsedStmtContext()) {
2285 Diag(Tok, diag::err_omp_immediate_directive)
2286 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2287 if (DKind == OMPD_error) {
2288 SkipUntil(tok::annot_pragma_openmp_end);
2292 HasAssociatedStatement =
false;
2295 SourceLocation EndLoc;
2296 SmallVector<OMPClause *, 5> Clauses;
2297 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2298 DeclarationNameInfo DirName;
2305 bool ImplicitClauseAllowed =
false;
2306 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2308 ImplicitClauseAllowed =
true;
2312 if (DKind == OMPD_critical) {
2314 tok::annot_pragma_openmp_end);
2315 if (!T.consumeOpen()) {
2316 if (Tok.isAnyIdentifier()) {
2318 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2321 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2325 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2327 if (Tok.isNot(tok::annot_pragma_openmp_end))
2335 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2336 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2339 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2342 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2343 while (Tok.isNot(tok::annot_pragma_openmp_end))
2347 bool HasImplicitClause =
false;
2348 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2349 HasImplicitClause =
true;
2352 PP.EnterToken(Tok,
true);
2353 PP.EnterToken(ImplicitTok,
true);
2358 : getOpenMPClauseKind(PP.getSpelling(Tok));
2359 if (HasImplicitClause) {
2360 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2361 if (DKind == OMPD_flush) {
2364 assert(DKind == OMPD_depobj &&
"Expected flush or depobj directives.");
2365 CKind = OMPC_depobj;
2369 ImplicitClauseAllowed =
false;
2370 Actions.OpenMP().StartOpenMPClause(CKind);
2371 HasImplicitClause =
false;
2373 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2374 SeenClauses[unsigned(CKind)] =
true;
2376 Clauses.push_back(Clause);
2379 if (Tok.is(tok::comma))
2381 Actions.OpenMP().EndOpenMPClause();
2384 EndLoc = Tok.getLocation();
2386 ConsumeAnnotationToken();
2388 if (DKind == OMPD_ordered) {
2391 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2392 if (SeenClauses[
unsigned(CK)]) {
2393 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2394 ParsedStmtContext()) {
2395 Diag(Loc, diag::err_omp_immediate_directive)
2396 << getOpenMPDirectiveName(DKind, OMPVersion) << 1
2397 << getOpenMPClauseName(CK);
2399 HasAssociatedStatement =
false;
2404 if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
2405 !SeenClauses[
unsigned(OMPC_sizes)]) {
2406 Diag(Loc, diag::err_omp_required_clause)
2407 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"sizes";
2411 if (HasAssociatedStatement) {
2413 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2419 Sema::CompoundScopeRAII Scope(Actions);
2420 AssociatedStmt = ParseStatement();
2425 Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
2428 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2429 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2430 DKind == OMPD_target_exit_data) {
2431 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2432 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2433 Actions.ActOnCompoundStmt(Loc, Loc, {},
2436 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2440 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2443 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2444 OMPDirectiveScope.Exit();
2449StmtResult Parser::ParseOpenMPInformationalDirective(
2451 bool ReadDirectiveWithinMetadirective) {
2453 "Unexpected directive category");
2455 bool HasAssociatedStatement =
true;
2457 SmallVector<OMPClause *, 5> Clauses;
2458 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2459 DeclarationNameInfo DirName;
2462 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2464 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2467 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2468 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2469 while (Tok.isNot(tok::annot_pragma_openmp_end))
2476 : getOpenMPClauseKind(PP.getSpelling(Tok));
2477 Actions.OpenMP().StartOpenMPClause(CKind);
2479 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2480 SeenClauses[unsigned(CKind)] =
true;
2482 Clauses.push_back(Clause);
2484 if (Tok.is(tok::comma))
2486 Actions.OpenMP().EndOpenMPClause();
2489 SourceLocation EndLoc = Tok.getLocation();
2490 ConsumeAnnotationToken();
2493 if (HasAssociatedStatement) {
2494 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2497 Sema::CompoundScopeRAII Scope(Actions);
2498 AssociatedStmt = ParseStatement();
2501 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2505 DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2507 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2508 OMPDirectiveScope.Exit();
2513StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2514 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2515 if (!ReadDirectiveWithinMetadirective)
2516 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2517 "Not an OpenMP directive!");
2520 SourceLocation Loc = ReadDirectiveWithinMetadirective
2522 : ConsumeAnnotationToken();
2523 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2525 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2526 Diag(Tok, diag::err_omp_unknown_directive);
2532 bool IsExecutable = [&]() {
2533 if (DKind == OMPD_error)
2535 auto Res = getDirectiveCategory(DKind);
2536 return Res == Category::Executable || Res == Category::Subsidiary;
2540 Directive = ParseOpenMPExecutableDirective(
2541 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2542 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2551 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
2552 while (Tok.isNot(tok::annot_pragma_openmp_end))
2555 skipUntilPragmaOpenMPEnd(DKind);
2556 if (Tok.is(tok::annot_pragma_openmp_end))
2557 ConsumeAnnotationToken();
2560 case OMPD_metadirective: {
2562 SmallVector<VariantMatchInfo, 4> VMIs;
2567 TentativeParsingAction TPA(*
this);
2568 ASTContext &ASTContext = Actions.getASTContext();
2571 tok::annot_pragma_openmp_end);
2572 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2575 : getOpenMPClauseKind(PP.getSpelling(Tok));
2577 if (CKind == OMPC_unknown) {
2578 Diag(Tok, diag::err_omp_expected_clause) <<
"metadirective";
2580 SkipUntil(tok::annot_pragma_openmp_end);
2583 if (
getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
2584 Diag(Tok, diag::err_omp_unexpected_clause)
2585 << getOpenMPClauseName(CKind) <<
"metadirective";
2586 if (CKind == OMPC_default &&
getLangOpts().OpenMP >= 52)
2587 Diag(Tok, diag::warn_omp_default_deprecated);
2592 if (T.expectAndConsume(diag::err_expected_lparen_after,
2593 getOpenMPClauseName(CKind).data())) {
2595 SkipUntil(tok::annot_pragma_openmp_end);
2599 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2600 if (CKind == OMPC_when) {
2602 parseOMPContextSelectors(Loc, TI);
2603 if (TI.
Sets.size() == 0) {
2604 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2610 if (Tok.is(tok::colon))
2613 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2621 while (Tok.isNot(tok::r_paren) || paren != 0) {
2622 if (Tok.is(tok::l_paren))
2624 if (Tok.is(tok::r_paren))
2626 if (Tok.is(tok::annot_pragma_openmp_end)) {
2627 Diag(Tok, diag::err_omp_expected_punc)
2628 << getOpenMPClauseName(CKind) << 0;
2635 if (Tok.is(tok::r_paren))
2638 VariantMatchInfo VMI;
2641 VMIs.push_back(VMI);
2648 [
this, Loc](StringRef ISATrait) {
2651 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2653 TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2655 ArrayRef<llvm::omp::TraitProperty>(),
2656 Actions.OpenMP().getOpenMPDeviceNum());
2659 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2666 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2668 if (Idx++ != BestIdx) {
2673 while (Tok.isNot(tok::r_paren) || paren != 0) {
2674 if (Tok.is(tok::l_paren))
2676 if (Tok.is(tok::r_paren))
2681 if (Tok.is(tok::r_paren))
2688 : getOpenMPClauseKind(PP.getSpelling(Tok));
2695 if (CKind == OMPC_when) {
2696 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2698 parseOMPContextSelectors(Loc, TI);
2706 if (Tok.is(tok::r_paren)) {
2707 SkipUntil(tok::annot_pragma_openmp_end);
2712 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2720 if (BestIdx == -1 && Idx > 0) {
2721 assert(Tok.is(tok::annot_pragma_openmp_end) &&
2722 "Expecting the end of the pragma here");
2723 ConsumeAnnotationToken();
2728 case OMPD_threadprivate: {
2730 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2731 ParsedStmtContext()) {
2732 Diag(Tok, diag::err_omp_immediate_directive)
2733 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2736 DeclDirectiveListParserHelper Helper(
this, DKind);
2737 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2739 skipUntilPragmaOpenMPEnd(DKind);
2740 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2741 Loc, Helper.getIdentifiers());
2742 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2744 SkipUntil(tok::annot_pragma_openmp_end);
2747 case OMPD_groupprivate: {
2748 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2749 ParsedStmtContext()) {
2750 Diag(Tok, diag::err_omp_immediate_directive)
2751 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2754 DeclDirectiveListParserHelper Helper(
this, DKind);
2755 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2757 skipUntilPragmaOpenMPEnd(DKind);
2758 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2759 Loc, Helper.getIdentifiers());
2760 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2762 SkipUntil(tok::annot_pragma_openmp_end);
2765 case OMPD_allocate: {
2767 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2768 ParsedStmtContext()) {
2769 Diag(Tok, diag::err_omp_immediate_directive)
2770 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2773 DeclDirectiveListParserHelper Helper(
this, DKind);
2774 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2776 SmallVector<OMPClause *, 1> Clauses;
2777 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2778 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2779 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2781 Tok.isAnnotation() ? OMPC_unknown
2782 : getOpenMPClauseKind(PP.getSpelling(Tok));
2783 Actions.OpenMP().StartOpenMPClause(CKind);
2784 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2785 !SeenClauses[
unsigned(CKind)]);
2786 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2788 SeenClauses[unsigned(CKind)] =
true;
2789 if (Clause !=
nullptr)
2790 Clauses.push_back(Clause);
2791 if (Tok.is(tok::annot_pragma_openmp_end)) {
2792 Actions.OpenMP().EndOpenMPClause();
2796 if (Tok.is(tok::comma))
2798 Actions.OpenMP().EndOpenMPClause();
2800 skipUntilPragmaOpenMPEnd(DKind);
2802 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPAllocateDirective(
2803 Loc, Helper.getIdentifiers(), Clauses);
2804 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2806 SkipUntil(tok::annot_pragma_openmp_end);
2809 case OMPD_declare_reduction:
2812 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2813 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2815 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2817 SkipUntil(tok::annot_pragma_openmp_end);
2820 case OMPD_declare_mapper: {
2823 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2825 ConsumeAnnotationToken();
2826 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2828 SkipUntil(tok::annot_pragma_openmp_end);
2832 case OMPD_declare_target: {
2834 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2835 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2837 ParseOMPDeclareTargetClauses(DTCI);
2838 bool HasImplicitMappings =
2841 if (HasImplicitMappings) {
2842 Diag(Tok, diag::err_omp_unexpected_directive)
2843 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2844 SkipUntil(tok::annot_pragma_openmp_end);
2851 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2854 case OMPD_begin_declare_variant: {
2859 ConsumeAnnotationToken();
2863 case OMPD_end_declare_variant: {
2865 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2866 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2868 Diag(Loc, diag::err_expected_begin_declare_variant);
2869 ConsumeAnnotationToken();
2872 case OMPD_declare_simd:
2873 case OMPD_begin_declare_target:
2874 case OMPD_end_declare_target:
2876 case OMPD_declare_variant:
2877 Diag(Tok, diag::err_omp_unexpected_directive)
2878 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2879 SkipUntil(tok::annot_pragma_openmp_end);
2883 Directive = ParseOpenMPInformationalDirective(
2884 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2886 "Informational directive remains unprocessed");
2891 Diag(Tok, diag::err_omp_unknown_directive);
2892 SkipUntil(tok::annot_pragma_openmp_end);
2898bool Parser::ParseOpenMPSimpleVarList(
2902 bool AllowScopeSpecifier) {
2903 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2906 if (T.expectAndConsume(diag::err_expected_lparen_after,
2907 getOpenMPDirectiveName(Kind, OMPVersion).data()))
2909 bool IsCorrect =
true;
2910 bool NoIdentIsFound =
true;
2913 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2917 Token PrevTok = Tok;
2918 NoIdentIsFound =
false;
2921 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2924 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2927 false,
false,
false,
2928 false,
false,
nullptr, Name)) {
2930 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2932 }
else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2933 Tok.isNot(tok::annot_pragma_openmp_end)) {
2935 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2939 << SourceRange(PrevTok.
getLocation(), PrevTokLocation);
2941 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2944 if (Tok.is(tok::comma)) {
2949 if (NoIdentIsFound) {
2950 Diag(Tok, diag::err_expected) << tok::identifier;
2955 IsCorrect = !T.consumeClose() && IsCorrect;
2960OMPClause *Parser::ParseOpenMPSizesClause() {
2961 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
2962 SmallVector<Expr *, 4> ValExprs;
2963 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
2967 return Actions.OpenMP().ActOnOpenMPSizesClause(ValExprs, ClauseNameLoc,
2971OMPClause *Parser::ParseOpenMPLoopRangeClause() {
2973 SourceLocation FirstLoc, CountLoc;
2976 if (T.consumeOpen()) {
2977 Diag(Tok, diag::err_expected) << tok::l_paren;
2981 FirstLoc = Tok.getLocation();
2988 ExpectAndConsume(tok::comma);
2990 CountLoc = Tok.getLocation();
2999 return Actions.OpenMP().ActOnOpenMPLoopRangeClause(
3000 FirstVal.
get(), CountVal.
get(), ClauseNameLoc, T.getOpenLocation(),
3001 FirstLoc, CountLoc, T.getCloseLocation());
3004OMPClause *Parser::ParseOpenMPPermutationClause() {
3005 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3006 SmallVector<Expr *> ArgExprs;
3007 if (ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,
3012 return Actions.OpenMP().ActOnOpenMPPermutationClause(ArgExprs, ClauseNameLoc,
3017 SourceLocation Loc = Tok.getLocation();
3022 if (T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3024 SmallVector<SemaOpenMP::UsesAllocatorsData, 4>
Data;
3027 if (
getLangOpts().OpenMP >= 52 && Tok.is(tok::identifier) &&
3028 Tok.getIdentifierInfo()->getName() ==
"traits") {
3030 SemaOpenMP::UsesAllocatorsData &D =
Data.emplace_back();
3036 tok::annot_pragma_openmp_end);
3037 TraitParens.consumeOpen();
3040 TraitParens.consumeClose();
3044 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3050 if (Tok.isNot(tok::colon)) {
3051 Diag(Tok, diag::err_expected) << tok::colon;
3053 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3063 ? ParseCXXIdExpression()
3064 : tryParseCXXIdExpression(SS,
false,
3069 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3076 D.
LParenLoc = TraitParens.getOpenLocation();
3077 D.
RParenLoc = TraitParens.getCloseLocation();
3080 if (Tok.is(tok::comma)) {
3082 Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3085 }
else if (Tok.is(tok::semi)) {
3096 getLangOpts().CPlusPlus
3097 ? ParseCXXIdExpression()
3098 : tryParseCXXIdExpression(SS,
false,
3101 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3108 BalancedDelimiterTracker T(*this, tok::l_paren,
3109 tok::annot_pragma_openmp_end);
3111 ExprResult AllocatorTraits =
3112 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3114 if (AllocatorTraits.isInvalid()) {
3115 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3124 if (getLangOpts().OpenMP >= 52) {
3125 Diag(Loc, diag::err_omp_deprecate_old_syntax)
3126 <<
"allocator(expr)"
3127 <<
"uses_allocators"
3128 <<
"traits(expr): alloc";
3132 Diag(
Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3134 if (
Tok.
is(tok::comma))
3136 }
while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end));
3139 Loc, T.getOpenLocation(), T.getCloseLocation(),
Data);
3144 OMPClauseKind = CKind;
3145 OMPClause *Clause =
nullptr;
3146 bool ErrorFound =
false;
3147 bool WrongDirective =
false;
3148 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
3151 if (CKind != OMPC_unknown &&
3152 !isAllowedClauseForDirective(DKind, CKind,
getLangOpts().OpenMP)) {
3153 Diag(Tok, diag::err_omp_unexpected_clause)
3154 << getOpenMPClauseName(CKind)
3155 << getOpenMPDirectiveName(DKind, OMPVersion);
3157 WrongDirective =
true;
3162 case OMPC_num_threads:
3168 case OMPC_grainsize:
3169 case OMPC_num_tasks:
3171 case OMPC_allocator:
3174 case OMPC_novariants:
3175 case OMPC_nocontext:
3180 case OMPC_ompx_dyn_cgroup_mem:
3181 case OMPC_dyn_groupprivate:
3182 case OMPC_transparent:
3211 Diag(Tok, diag::err_omp_more_one_clause)
3212 << getOpenMPDirectiveName(DKind, OMPVersion)
3213 << getOpenMPClauseName(CKind) << 0;
3217 if (CKind == OMPC_transparent && PP.LookAhead(0).isNot(tok::l_paren)) {
3219 SourceLocation LLoc = Tok.getLocation();
3220 Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(
nullptr, LLoc,
3224 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3225 PP.LookAhead(0).isNot(tok::l_paren))
3226 Clause = ParseOpenMPClause(CKind, WrongDirective);
3227 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3228 CKind == OMPC_num_threads || CKind == OMPC_dyn_groupprivate)
3229 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3231 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3233 case OMPC_threadset:
3235 case OMPC_proc_bind:
3236 case OMPC_atomic_default_mem_order:
3254 Diag(Tok, diag::err_omp_more_one_clause)
3255 << getOpenMPDirectiveName(DKind, OMPVersion)
3256 << getOpenMPClauseName(CKind) << 0;
3260 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3264 case OMPC_dist_schedule:
3265 case OMPC_defaultmap:
3276 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3277 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3278 Diag(Tok, diag::err_omp_more_one_clause)
3279 << getOpenMPDirectiveName(DKind, OMPVersion)
3280 << getOpenMPClauseName(CKind) << 0;
3285 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3288 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3292 case OMPC_mergeable:
3306 case OMPC_unified_address:
3307 case OMPC_unified_shared_memory:
3308 case OMPC_reverse_offload:
3309 case OMPC_dynamic_allocators:
3318 Diag(Tok, diag::err_omp_more_one_clause)
3319 << getOpenMPDirectiveName(DKind, OMPVersion)
3320 << getOpenMPClauseName(CKind) << 0;
3324 if (CKind == OMPC_nowait && PP.LookAhead(0).is(tok::l_paren) &&
3326 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3328 Clause = ParseOpenMPClause(CKind, WrongDirective);
3330 case OMPC_self_maps:
3333 Diag(Tok, diag::err_omp_expected_clause)
3334 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3338 Diag(Tok, diag::err_omp_more_one_clause)
3339 << getOpenMPDirectiveName(DKind, OMPVersion)
3340 << getOpenMPClauseName(CKind) << 0;
3343 Clause = ParseOpenMPClause(CKind, WrongDirective);
3347 Diag(Tok, diag::err_omp_more_one_clause)
3348 << getOpenMPDirectiveName(DKind, OMPVersion)
3349 << getOpenMPClauseName(CKind) << 0;
3353 Clause = (DKind == OMPD_depobj)
3354 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3355 : ParseOpenMPClause(CKind, WrongDirective);
3357 case OMPC_num_teams:
3358 case OMPC_thread_limit:
3360 Diag(Tok, diag::err_omp_more_one_clause)
3361 << getOpenMPDirectiveName(DKind, OMPVersion)
3362 << getOpenMPClauseName(CKind) << 0;
3367 case OMPC_firstprivate:
3368 case OMPC_lastprivate:
3370 case OMPC_reduction:
3371 case OMPC_task_reduction:
3372 case OMPC_in_reduction:
3376 case OMPC_copyprivate:
3382 case OMPC_use_device_ptr:
3383 case OMPC_use_device_addr:
3384 case OMPC_is_device_ptr:
3385 case OMPC_has_device_addr:
3387 case OMPC_nontemporal:
3388 case OMPC_inclusive:
3389 case OMPC_exclusive:
3393 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
3394 CKind == OMPC_depend)
3395 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3396 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3400 Diag(Tok, diag::err_omp_more_one_clause)
3401 << getOpenMPDirectiveName(DKind, OMPVersion)
3402 << getOpenMPClauseName(CKind) << 0;
3406 Clause = ParseOpenMPSizesClause();
3408 case OMPC_permutation:
3410 Diag(Tok, diag::err_omp_more_one_clause)
3411 << getOpenMPDirectiveName(DKind, OMPVersion)
3412 << getOpenMPClauseName(CKind) << 0;
3415 Clause = ParseOpenMPPermutationClause();
3417 case OMPC_uses_allocators:
3418 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3421 if (DKind != OMPD_interop) {
3423 Diag(Tok, diag::err_omp_more_one_clause)
3424 << getOpenMPDirectiveName(DKind, OMPVersion)
3425 << getOpenMPClauseName(CKind) << 0;
3428 Clause = ParseOpenMPClause(CKind, WrongDirective);
3434 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3436 case OMPC_device_type:
3438 skipUntilPragmaOpenMPEnd(DKind);
3440 case OMPC_threadprivate:
3441 case OMPC_groupprivate:
3444 if (!WrongDirective)
3445 Diag(Tok, diag::err_omp_unexpected_clause)
3446 << getOpenMPClauseName(CKind)
3447 << getOpenMPDirectiveName(DKind, OMPVersion);
3451 case OMPC_contains: {
3453 SourceLocation LLoc = Tok.getLocation();
3454 SourceLocation RLoc;
3455 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3460 if (DK == OMPD_unknown) {
3461 skipUntilPragmaOpenMPEnd(OMPD_assume);
3462 Diag(Tok, diag::err_omp_unexpected_clause)
3463 << getOpenMPClauseName(CKind)
3464 << getOpenMPDirectiveName(DKind, OMPVersion);
3468 DKVec.push_back(DK);
3471 Diag(Tok, diag::err_omp_unexpected_clause)
3472 << getOpenMPClauseName(CKind)
3473 << getOpenMPDirectiveName(DKind, OMPVersion);
3476 RLoc = Tok.getLocation();
3478 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3479 CKind, DKVec, Loc, LLoc, RLoc);
3482 case OMPC_no_openmp:
3483 case OMPC_no_openmp_routines:
3484 case OMPC_no_openmp_constructs:
3485 case OMPC_no_parallelism: {
3487 Diag(Tok, diag::err_omp_more_one_clause)
3488 << getOpenMPDirectiveName(DKind, OMPVersion)
3489 << getOpenMPClauseName(CKind) << 0;
3493 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3494 CKind, Loc, Tok.getLocation());
3497 case OMPC_ompx_attribute:
3498 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3500 case OMPC_ompx_bare:
3501 if (DKind == llvm::omp::Directive::OMPD_target) {
3506 Diag(Tok, diag::err_omp_unexpected_clause)
3507 << getOpenMPClauseName(CKind)
3508 << getOpenMPDirectiveName(DKind, OMPVersion);
3510 WrongDirective =
true;
3513 Diag(Tok, diag::note_ompx_bare_clause)
3514 << getOpenMPClauseName(CKind) <<
"target teams";
3515 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3516 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3517 << getOpenMPClauseName(CKind)
3518 << getOpenMPDirectiveName(DKind, OMPVersion);
3521 Clause = ParseOpenMPClause(CKind, WrongDirective);
3523 case OMPC_looprange:
3524 Clause = ParseOpenMPLoopRangeClause();
3529 return ErrorFound ?
nullptr : Clause;
3537 bool IsAddressOfOperand) {
3539 if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3547 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3550 RLoc = Tok.getLocation();
3551 if (!T.consumeClose())
3552 RLoc = T.getCloseLocation();
3574bool Parser::ParseOpenMPIndirectClause(
3579 if (
Tok.isNot(tok::l_paren)) {
3598 if (
Ret.isInvalid())
3601 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3603 if (
Ret.isInvalid())
3614 bool HasError =
false;
3615 bool IsTarget =
false;
3616 bool IsTargetSync =
false;
3618 while (Tok.is(tok::identifier)) {
3620 bool PreferTypeAllowed =
Kind == OMPC_init &&
3623 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3628 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3631 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3633 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3634 IsTargetSync =
true;
3636 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3637 PreferTypeAllowed) {
3640 tok::annot_pragma_openmp_end);
3641 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3644 while (Tok.isNot(tok::r_paren)) {
3645 SourceLocation Loc = Tok.getLocation();
3648 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
3654 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3658 if (Tok.is(tok::comma))
3664 Diag(Tok, diag::err_omp_expected_interop_type);
3667 if (!Tok.is(tok::comma))
3672 if (!HasError && !IsTarget && !IsTargetSync) {
3673 Diag(Tok, diag::err_omp_expected_interop_type);
3677 if (Kind == OMPC_init) {
3678 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
3679 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3680 if (Tok.is(tok::colon))
3697 if (T.expectAndConsume(diag::err_expected_lparen_after,
3698 getOpenMPClauseName(Kind).data()))
3701 bool InteropError =
false;
3702 OMPInteropInfo InteropInfo;
3703 if (Kind == OMPC_init)
3704 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3707 SourceLocation VarLoc = Tok.getLocation();
3710 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3715 SourceLocation RLoc = Tok.getLocation();
3716 if (!T.consumeClose())
3717 RLoc = T.getCloseLocation();
3719 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3722 if (Kind == OMPC_init)
3723 return Actions.OpenMP().ActOnOpenMPInitClause(
3724 InteropVarExpr.
get(), InteropInfo, Loc, T.getOpenLocation(), VarLoc,
3726 if (Kind == OMPC_use)
3727 return Actions.OpenMP().ActOnOpenMPUseClause(
3728 InteropVarExpr.
get(), Loc, T.getOpenLocation(), VarLoc, RLoc);
3730 if (Kind == OMPC_destroy)
3731 return Actions.OpenMP().ActOnOpenMPDestroyClause(
3732 InteropVarExpr.
get(), Loc, T.getOpenLocation(), VarLoc, RLoc);
3734 llvm_unreachable(
"Unexpected interop variable clause.");
3737OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
3741 if (T.expectAndConsume(diag::err_expected_lparen_after,
3742 getOpenMPClauseName(OMPC_ompx_attribute).data()))
3745 ParsedAttributes ParsedAttrs(AttrFactory);
3746 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
3749 if (T.consumeClose())
3755 SmallVector<Attr *> Attrs;
3756 for (
const ParsedAttr &PA : ParsedAttrs) {
3757 switch (PA.getKind()) {
3758 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
3759 if (!PA.checkExactlyNumArgs(Actions, 2))
3761 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
3762 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
3765 case ParsedAttr::AT_AMDGPUWavesPerEU:
3766 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3767 !PA.checkAtMostNumArgs(Actions, 2))
3769 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
3770 PA, PA.getArgAsExpr(0),
3771 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
3774 case ParsedAttr::AT_CUDALaunchBounds:
3775 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3776 !PA.checkAtMostNumArgs(Actions, 2))
3778 if (
auto *A = Actions.CreateLaunchBoundsAttr(
3779 PA, PA.getArgAsExpr(0),
3780 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
3781 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr))
3785 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
3790 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
3791 Attrs, Loc, T.getOpenLocation(), T.getCloseLocation());
3797 if (!Val || ParseOnly)
3799 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3800 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
3801 static_cast<DefaultKind
>(Val->Type) ==
3802 OMP_DEFAULT_firstprivate)) {
3803 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
3804 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
3807 : OMPC_firstprivate)
3808 << getOpenMPClauseName(OMPC_default) <<
"5.1";
3811 return Actions.OpenMP().ActOnOpenMPSimpleClause(
3812 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
3816 SourceLocation Loc = Tok.getLocation();
3821 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3828 SourceLocation DelimLoc;
3831 if (T.expectAndConsume(diag::err_expected_lparen_after,
3832 getOpenMPClauseName(Kind).data()))
3836 SmallVector<unsigned, 4> Arg;
3837 SmallVector<SourceLocation, 4> KLoc;
3838 if (Kind == OMPC_schedule) {
3839 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3840 Arg.resize(NumberOfElements);
3841 KLoc.resize(NumberOfElements);
3846 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3849 Arg[Modifier1] = KindModifier;
3850 KLoc[Modifier1] = Tok.getLocation();
3851 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3852 Tok.isNot(tok::annot_pragma_openmp_end))
3854 if (Tok.is(tok::comma)) {
3858 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3862 KLoc[Modifier2] = Tok.getLocation();
3863 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3864 Tok.isNot(tok::annot_pragma_openmp_end))
3868 if (Tok.is(tok::colon))
3871 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
3873 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3875 Arg[ScheduleKind] = KindModifier;
3876 KLoc[ScheduleKind] = Tok.getLocation();
3877 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3878 Tok.isNot(tok::annot_pragma_openmp_end))
3880 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3881 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3882 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3885 }
else if (Kind == OMPC_dist_schedule) {
3887 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3888 KLoc.push_back(Tok.getLocation());
3889 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3890 Tok.isNot(tok::annot_pragma_openmp_end))
3892 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3894 }
else if (Kind == OMPC_default) {
3897 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3899 Arg.push_back(Modifier);
3900 KLoc.push_back(Tok.getLocation());
3901 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3902 Tok.isNot(tok::annot_pragma_openmp_end))
3905 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
3910 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3911 Arg.push_back(VariableCategory);
3912 KLoc.push_back(Tok.getLocation());
3913 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3914 Tok.isNot(tok::annot_pragma_openmp_end))
3917 Arg.push_back(OMPC_DEFAULT_VC_all);
3918 KLoc.push_back(SourceLocation());
3920 }
else if (Kind == OMPC_defaultmap) {
3923 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3929 Arg.push_back(Modifier);
3930 KLoc.push_back(Tok.getLocation());
3931 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3932 Tok.isNot(tok::annot_pragma_openmp_end))
3935 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
3936 if (Tok.is(tok::colon))
3939 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
3942 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3943 KLoc.push_back(Tok.getLocation());
3944 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3945 Tok.isNot(tok::annot_pragma_openmp_end))
3949 KLoc.push_back(SourceLocation());
3951 }
else if (Kind == OMPC_order) {
3952 enum { Modifier, OrderKind, NumberOfElements };
3953 Arg.resize(NumberOfElements);
3954 KLoc.resize(NumberOfElements);
3958 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3961 Arg[Modifier] = KindModifier;
3962 KLoc[Modifier] = Tok.getLocation();
3963 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3964 Tok.isNot(tok::annot_pragma_openmp_end))
3967 if (Tok.is(tok::colon))
3970 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
3972 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3974 Arg[OrderKind] = KindModifier;
3975 KLoc[OrderKind] = Tok.getLocation();
3976 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3977 Tok.isNot(tok::annot_pragma_openmp_end))
3979 }
else if (Kind == OMPC_device) {
3985 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3986 KLoc.push_back(Tok.getLocation());
3992 KLoc.emplace_back();
3994 }
else if (Kind == OMPC_grainsize) {
3998 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4002 Arg.push_back(Modifier);
4003 KLoc.push_back(Tok.getLocation());
4009 if (Modifier == OMPC_GRAINSIZE_strict) {
4010 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4015 KLoc.emplace_back();
4019 KLoc.emplace_back();
4021 }
else if (Kind == OMPC_dyn_groupprivate) {
4022 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4023 Arg.resize(NumberOfModifiers);
4024 KLoc.resize(NumberOfModifiers);
4028 auto ConsumeModifier = [&]() {
4029 unsigned Type = NumberOfModifiers;
4032 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4036 ParenT.consumeOpen();
4039 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4042 Diag(Tok.getLocation(), diag::err_expected)
4043 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4045 return std::make_tuple(
Type, Modifier, Loc);
4047 Type = ComplexModifier;
4048 Loc = Tok.getLocation();
4049 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4050 Tok.isNot(tok::annot_pragma_openmp_end))
4052 ParenT.consumeClose();
4055 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4057 Type = SimpleModifier;
4058 Loc = Tok.getLocation();
4059 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4060 Tok.isNot(tok::annot_pragma_openmp_end))
4064 return std::make_tuple(
Type, Modifier, Loc);
4067 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4068 SourceLocation Loc) {
4069 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4070 if (!KLoc[
Type].isValid()) {
4071 Arg[
Type] = Modifier;
4074 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4081 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4082 if (Type1 < NumberOfModifiers) {
4083 SaveModifier(Type1, Mod1, Loc1);
4084 if (Tok.is(tok::comma)) {
4087 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4088 if (Type2 < NumberOfModifiers)
4089 SaveModifier(Type2, Mod2, Loc2);
4092 if (Tok.is(tok::colon))
4095 Diag(Tok, diag::warn_pragma_expected_colon)
4096 <<
"dyn_groupprivate modifier";
4098 }
else if (Kind == OMPC_num_tasks) {
4102 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4106 Arg.push_back(Modifier);
4107 KLoc.push_back(Tok.getLocation());
4113 if (Modifier == OMPC_NUMTASKS_strict) {
4114 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4119 KLoc.emplace_back();
4123 KLoc.emplace_back();
4125 }
else if (Kind == OMPC_num_threads) {
4129 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4133 Arg.push_back(Modifier);
4134 KLoc.push_back(Tok.getLocation());
4140 if (Modifier == OMPC_NUMTHREADS_strict) {
4141 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4146 KLoc.emplace_back();
4150 KLoc.emplace_back();
4153 assert(Kind == OMPC_if);
4154 KLoc.push_back(Tok.getLocation());
4155 TentativeParsingAction TPA(*
this);
4157 Arg.push_back(
static_cast<unsigned>(DK));
4158 if (DK != OMPD_unknown) {
4160 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4165 Arg.back() = unsigned(OMPD_unknown);
4172 bool NeedAnExpression =
4174 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
Kind == OMPC_if ||
4175 Kind == OMPC_device ||
Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4176 Kind == OMPC_num_threads ||
Kind == OMPC_dyn_groupprivate;
4177 if (NeedAnExpression) {
4178 SourceLocation ELoc = Tok.getLocation();
4184 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4188 SourceLocation RLoc = Tok.getLocation();
4189 if (!T.consumeClose())
4190 RLoc = T.getCloseLocation();
4192 if (NeedAnExpression && Val.
isInvalid())
4195 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4196 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4197 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4198 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4199 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4202 : OMPC_firstprivate)
4203 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4209 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4210 Kind, Arg, Val.
get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4215 if (ReductionIdScopeSpec.
isEmpty()) {
4253 ReductionIdScopeSpec,
nullptr,
4257 false,
nullptr, ReductionId);
4264 if (!
Tok.is(tok::identifier))
4271 return TypeModifier;
4277 if (T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4278 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4284 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4288 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4289 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4290 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4294 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4296 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4299 return T.consumeClose();
4305 bool HasMapType =
false;
4307 StringRef PreMapName =
"";
4311 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4312 TypeModifier == OMPC_MAP_MODIFIER_close ||
4313 TypeModifier == OMPC_MAP_MODIFIER_present ||
4314 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4315 Data.MapTypeModifiers.push_back(TypeModifier);
4316 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4317 if (PP.LookAhead(0).isNot(tok::comma) &&
4318 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4319 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4320 <<
"map type modifier";
4322 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4323 Data.MapTypeModifiers.push_back(TypeModifier);
4324 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4328 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4330 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4331 <<
"map type modifier";
4336 Data.ExtraModifier = MapKind;
4338 PreMapLoc = Tok.getLocation();
4339 PreMapName = Tok.getIdentifierInfo()->getName();
4341 Diag(Tok, diag::err_omp_more_one_map_type);
4342 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4346 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4347 Data.MapTypeModifiers.push_back(TypeModifier);
4348 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4349 if (PP.LookAhead(0).isNot(tok::comma) &&
4350 PP.LookAhead(0).isNot(tok::colon))
4351 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4352 <<
"map type modifier";
4354 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4364 if (Tok.is(tok::comma)) {
4365 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4370 if (PP.LookAhead(0).is(tok::colon)) {
4378 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4389 if (!Tok.is(tok::colon)) {
4390 Diag(Tok, diag::err_omp_unknown_map_type);
4404 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4409 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4410 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4411 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4421 if (
Tok.is(tok::colon)) {
4422 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4427 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4431ExprResult Parser::ParseOpenMPIteratorsExpr() {
4432 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4433 "Expected 'iterator' token.");
4437 if (T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4440 SourceLocation LLoc = T.getOpenLocation();
4441 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4442 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4445 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4452 IteratorType = TR.
get();
4456 IdentifierInfo *II =
nullptr;
4457 SourceLocation IdLoc;
4458 if (Tok.is(tok::identifier)) {
4459 II = Tok.getIdentifierInfo();
4462 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4466 SourceLocation AssignLoc;
4467 if (Tok.is(tok::equal))
4470 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4475 SourceLocation Loc = Tok.getLocation();
4478 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4481 SourceLocation ColonLoc;
4482 if (Tok.is(tok::colon))
4486 Loc = Tok.getLocation();
4489 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4492 SourceLocation SecColonLoc;
4495 if (Tok.is(tok::colon)) {
4499 Loc = Tok.getLocation();
4502 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4507 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4508 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4509 if (Tok.is(tok::comma))
4512 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4515 D.
Type = IteratorType;
4525 SourceLocation RLoc = Tok.getLocation();
4526 if (!T.consumeClose())
4527 RLoc = T.getCloseLocation();
4529 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4538 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4541 if (Tok.is(tok::identifier) &&
4542 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4544 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4545 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4546 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4547 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4548 Data.ExtraModifier != OMPC_DEPEND_inout)
4549 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4551 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4552 ? OMPC_DEPEND_outallmemory
4553 : OMPC_DEPEND_inoutallmemory;
4569 Data.DepModOrTailExpr = Tail.
get();
4571 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4572 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4590 bool AllocatorSeen =
false;
4591 bool AlignSeen =
false;
4610 if (
Tok.is(tok::l_paren)) {
4611 switch (CurrentModifier) {
4612 case OMPC_ALLOCATE_allocator: {
4613 if (AllocatorSeen) {
4614 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4616 << getOpenMPClauseName(Kind);
4618 Data.AllocClauseModifiers.push_back(CurrentModifier);
4619 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4622 tok::annot_pragma_openmp_end);
4626 AllocatorSeen =
true;
4629 case OMPC_ALLOCATE_align: {
4631 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4633 << getOpenMPClauseName(Kind);
4635 Data.AllocClauseModifiers.push_back(CurrentModifier);
4636 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4640 Data.AllocateAlignment = Val.
get();
4645 llvm_unreachable(
"Unexpected allocate modifier");
4648 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4650 if (
Tok.isNot(tok::comma))
4653 CurrentModifierLoc =
Tok.getLocation();
4658 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4661 }
while (!AllocatorSeen || !AlignSeen);
4670 bool InvalidReductionId =
false;
4671 bool IsInvalidMapperModifier =
false;
4675 if (T.expectAndConsume(diag::err_expected_lparen_after,
4676 getOpenMPClauseName(Kind).data()))
4679 bool HasIterator =
false;
4680 bool InvalidIterator =
false;
4681 bool NeedRParenForLinear =
false;
4683 tok::annot_pragma_openmp_end);
4685 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4686 Kind == OMPC_in_reduction) {
4688 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4689 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4692 Data.ExtraModifier =
4694 Data.ExtraModifierLoc = Tok.getLocation();
4696 assert(Tok.is(tok::comma) &&
"Expected comma.");
4700 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4701 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4707 if (Tok.is(tok::kw_private)) {
4708 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4709 Data.OriginalSharingModifierLoc = Tok.getLocation();
4711 }
else if (Tok.is(tok::identifier) &&
4712 (PP.getSpelling(Tok) ==
"shared" ||
4713 PP.getSpelling(Tok) ==
"default")) {
4714 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4715 Data.OriginalSharingModifierLoc = Tok.getLocation();
4718 Diag(Tok.getLocation(), diag::err_expected)
4719 <<
"'private or shared or default'";
4724 if (!Tok.is(tok::comma)) {
4725 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4732 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4737 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4738 if (InvalidReductionId) {
4739 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4742 if (Tok.is(tok::colon))
4745 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4746 if (!InvalidReductionId)
4747 Data.ReductionOrMapperId =
4748 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4749 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4751 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4760 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4761 Data.DepModOrTailExpr = IteratorRes.
get();
4763 ExpectAndConsume(tok::comma);
4769 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4771 Data.ExtraModifierLoc = Tok.getLocation();
4773 (Kind == OMPC_doacross &&
4775 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4780 if (DKind == OMPD_ordered && Kind == OMPC_depend &&
4781 Data.ExtraModifier == OMPC_DEPEND_source) {
4787 if (Tok.is(tok::colon)) {
4789 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
4790 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4791 : diag::warn_pragma_expected_colon)
4792 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
4794 if (Kind == OMPC_doacross) {
4795 if (Tok.is(tok::identifier) &&
4796 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
4797 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
4798 ? OMPC_DOACROSS_source_omp_cur_iteration
4799 : OMPC_DOACROSS_sink_omp_cur_iteration;
4802 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
4803 if (Tok.isNot(tok::minus)) {
4804 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4805 << getOpenMPClauseName(Kind) << 0 << 0;
4812 if (Tok.isNot(tok::numeric_constant) ||
4813 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
4814 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
4815 << getOpenMPClauseName(Kind) << 0 << 0;
4821 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
4822 if (Tok.isNot(tok::r_paren)) {
4823 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4824 << getOpenMPClauseName(Kind) << 1 << 1;
4830 if (Kind == OMPC_doacross &&
4831 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
4832 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
4833 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
4839 }
else if (Kind == OMPC_linear) {
4841 Data.ExtraModifier = OMPC_LINEAR_val;
4842 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
4843 Data.ExtraModifier =
4847 NeedRParenForLinear =
true;
4849 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
4850 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
4851 <<
"linear(list: [linear-modifier,] step(step-size))";
4853 }
else if (Kind == OMPC_lastprivate) {
4860 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
4861 Data.ExtraModifier =
4863 Data.ExtraModifierLoc = Tok.getLocation();
4865 assert(Tok.is(tok::colon) &&
"Expected colon.");
4868 }
else if (Kind == OMPC_map) {
4870 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4873 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
4874 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4875 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4876 Data.IteratorExpr = IteratorRes.
get();
4878 ExpectAndConsume(tok::comma);
4880 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4883 InvalidIterator =
true;
4893 Data.ExtraModifierLoc = Tok.getLocation();
4896 TentativeParsingAction TPA(*
this);
4897 bool ColonPresent =
false;
4898 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4900 if (Tok.is(tok::colon))
4901 ColonPresent =
true;
4908 Diag(Tok, diag::err_omp_map_modifier_specification_list);
4910 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
4916 Data.ExtraModifier = OMPC_MAP_tofrom;
4918 if (DKind == OMPD_target_enter_data)
4919 Data.ExtraModifier = OMPC_MAP_to;
4920 else if (DKind == OMPD_target_exit_data)
4921 Data.ExtraModifier = OMPC_MAP_from;
4923 Data.IsMapTypeImplicit =
true;
4926 if (Tok.is(tok::colon))
4928 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
4929 while (Tok.is(tok::identifier)) {
4934 Data.MotionModifiers.push_back(Modifier);
4935 Data.MotionModifiersLoc.push_back(Tok.getLocation());
4936 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
4938 Tail = ParseOpenMPIteratorsExpr();
4939 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
4942 Data.IteratorExpr = Tail.
get();
4945 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
4947 if (IsInvalidMapperModifier)
4955 if (Tok.is(tok::comma))
4959 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
4960 if (!IsInvalidMapperModifier) {
4962 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
4964 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
4966 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4974 }
else if (Kind == OMPC_allocate ||
4975 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
4976 PP.getSpelling(Tok) ==
"iterator")) {
4980 TentativeParsingAction TPA(*
this);
4985 if (Kind == OMPC_allocate) {
4990 Tail = ParseOpenMPIteratorsExpr();
4992 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
4995 if (Tok.is(tok::colon)) {
5002 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5003 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5005 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5012 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5015 }
else if (Kind == OMPC_adjust_args) {
5019 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5021 Data.ExtraModifierLoc = Tok.getLocation();
5023 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5028 if (Tok.is(tok::colon))
5029 Data.ColonLoc = Tok.getLocation();
5033 if (Tok.is(tok::l_paren)) {
5036 if (Tok.is(tok::identifier)) {
5037 std::string Modifier = PP.getSpelling(Tok);
5038 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5039 Data.NeedDevicePtrModifier =
5040 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5041 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5043 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5044 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5049 if (Tok.is(tok::r_paren)) {
5050 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5053 Diag(Tok, diag::err_expected) << tok::r_paren;
5054 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5063 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5066 }
else if (Kind == OMPC_use_device_ptr) {
5070 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5074 Data.ExtraModifier = FallbackModifier;
5075 Data.ExtraModifierLoc = Tok.getLocation();
5077 if (Tok.is(tok::colon))
5080 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5084 if (Kind == OMPC_num_teams && !Tok.is(tok::r_paren) &&
5085 !Tok.is(tok::annot_pragma_openmp_end)) {
5089 Data.RLoc = Tok.getLocation();
5090 if (!T.consumeClose())
5091 Data.RLoc = T.getCloseLocation();
5095 if (Tok.is(tok::colon)) {
5101 Data.RLoc = Tok.getLocation();
5102 if (!T.consumeClose())
5103 Data.RLoc = T.getCloseLocation();
5106 Vars.push_back(FirstExpr.
get());
5107 Vars.push_back(UpperBound.
get());
5108 Data.RLoc = Tok.getLocation();
5109 if (!T.consumeClose())
5110 Data.RLoc = T.getCloseLocation();
5113 if (Tok.is(tok::comma)) {
5114 Vars.push_back(FirstExpr.
get());
5115 while (Tok.is(tok::comma)) {
5119 Vars.push_back(NextExpr.
get());
5121 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5126 Data.RLoc = Tok.getLocation();
5127 bool HadError = T.consumeClose();
5129 Data.RLoc = T.getCloseLocation();
5134 Vars.push_back(FirstExpr.
get());
5135 Data.RLoc = Tok.getLocation();
5136 if (!T.consumeClose())
5137 Data.RLoc = T.getCloseLocation();
5142 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5143 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5144 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5145 (Kind == OMPC_reduction && !InvalidReductionId) ||
5149 (Kind == OMPC_adjust_args &&
5151 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5152 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5153 Tok.isNot(tok::annot_pragma_openmp_end))) {
5160 Vars.push_back(VarExpr.
get());
5162 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5167 IsComma = Tok.is(tok::comma);
5170 else if (Tok.isNot(tok::r_paren) &&
5171 Tok.isNot(tok::annot_pragma_openmp_end) &&
5172 (!MayHaveTail || Tok.isNot(tok::colon))) {
5173 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
5174 Diag(Tok, diag::err_omp_expected_punc)
5175 << ((Kind == OMPC_flush)
5176 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5177 : getOpenMPClauseName(Kind))
5178 << (Kind == OMPC_flush);
5183 if (NeedRParenForLinear)
5187 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5188 bool StepFound =
false;
5189 bool ModifierFound =
false;
5191 Data.ColonLoc = Tok.getLocation();
5194 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5195 bool Malformed =
false;
5196 while (Tok.isNot(tok::r_paren)) {
5197 if (Tok.is(tok::identifier)) {
5202 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5205 if (LinKind == OMPC_LINEAR_step) {
5207 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5210 tok::annot_pragma_openmp_end);
5214 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5219 Data.StepModifierLoc = StepModifierLoc;
5223 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5225 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5227 Data.ExtraModifier = LinKind;
5229 ModifierFound =
true;
5234 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5243 if (Tok.is(tok::comma))
5245 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5248 if (!Malformed && !StepFound && !ModifierFound)
5249 Diag(ELoc, diag::err_expected_expression);
5253 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5256 Data.DepModOrTailExpr = Tail.
get();
5258 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5264 Data.RLoc = Tok.getLocation();
5265 if (!T.consumeClose())
5266 Data.RLoc = T.getCloseLocation();
5270 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5272 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5273 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5300 "Expected parsing to start at clause name");
5305 if (T.consumeOpen()) {
5306 Diag(
Tok, diag::err_expected) << tok::l_paren;
5319 Exprs.push_back(Val.
get());
5322 bool Result = T.consumeClose();
5323 OpenLoc = T.getOpenLocation();
5324 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.
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.