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 RequiresToLinkLocalOrIndirectClause =
false;
1762 bool HasToLinkLocalOrIndirectClause =
false;
1763 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1764 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1765 bool HasIdentifier = Tok.is(tok::identifier);
1766 if (HasIdentifier) {
1768 RequiresToLinkLocalOrIndirectClause =
true;
1769 IdentifierInfo *II = Tok.getIdentifierInfo();
1770 StringRef ClauseName = II->
getName();
1771 bool IsDeviceTypeClause =
1773 getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1775 bool IsIndirectClause =
getLangOpts().OpenMP >= 51 &&
1776 getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1778 if (DTCI.
Indirect && IsIndirectClause) {
1779 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1780 Diag(Tok, diag::err_omp_more_one_clause)
1781 << getOpenMPDirectiveName(OMPD_declare_target, OMPVersion)
1782 << getOpenMPClauseName(OMPC_indirect) << 0;
1785 bool IsToEnterLinkOrLocalClause =
1786 OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1787 assert((!IsDeviceTypeClause || !IsToEnterLinkOrLocalClause) &&
1792 if (
getLangOpts().OpenMP >= 52 && ClauseName ==
"to") {
1793 Diag(Tok, diag::err_omp_declare_target_unexpected_to_clause);
1796 if (
getLangOpts().OpenMP <= 51 && ClauseName ==
"enter") {
1797 Diag(Tok, diag::err_omp_declare_target_unexpected_enter_clause);
1802 if (
getLangOpts().OpenMP < 60 && ClauseName ==
"local") {
1804 ? diag::err_omp_declare_target_unexpected_clause_52
1805 : diag::err_omp_declare_target_unexpected_clause)
1813 if (!IsDeviceTypeClause && !IsIndirectClause &&
1814 DTCI.
Kind == OMPD_begin_declare_target) {
1816 ? diag::err_omp_declare_target_unexpected_clause_52
1817 : diag::err_omp_declare_target_unexpected_clause)
1818 << ClauseName << (
getLangOpts().OpenMP >= 51 ? 3 : 0);
1822 if (!IsDeviceTypeClause && !IsToEnterLinkOrLocalClause &&
1823 !IsIndirectClause) {
1825 ? diag::err_omp_declare_target_unexpected_clause_52
1826 : diag::err_omp_declare_target_unexpected_clause)
1835 if (IsToEnterLinkOrLocalClause || IsIndirectClause)
1836 HasToLinkLocalOrIndirectClause =
true;
1838 if (IsIndirectClause) {
1839 if (!ParseOpenMPIndirectClause(DTCI,
false))
1844 if (IsDeviceTypeClause) {
1845 std::optional<SimpleClauseData> DevTypeData =
1848 if (DeviceTypeLoc.
isValid()) {
1850 Diag(DevTypeData->Loc,
1851 diag::warn_omp_more_one_device_type_clause);
1855 case OMPC_DEVICE_TYPE_any:
1856 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Any;
1858 case OMPC_DEVICE_TYPE_host:
1859 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_Host;
1861 case OMPC_DEVICE_TYPE_nohost:
1862 DTCI.
DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1865 llvm_unreachable(
"Unexpected device_type");
1867 DeviceTypeLoc = DevTypeData->Loc;
1874 if (DTCI.
Kind == OMPD_declare_target || HasIdentifier) {
1875 auto &&Callback = [
this, MT, &DTCI](CXXScopeSpec &SS,
1876 DeclarationNameInfo NameInfo) {
1877 NamedDecl *ND = Actions.OpenMP().lookupOpenMPDeclareTargetName(
1881 SemaOpenMP::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.
getLoc()};
1884 Diag(NameInfo.
getLoc(), diag::err_omp_declare_target_multiple)
1887 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1892 if (Tok.is(tok::l_paren)) {
1894 diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1897 if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1900 ? diag::err_omp_declare_target_wrong_clause_after_implicit_enter
1901 : diag::err_omp_declare_target_wrong_clause_after_implicit_to);
1906 if (Tok.is(tok::comma))
1910 if (DTCI.
Indirect && DTCI.
DT != OMPDeclareTargetDeclAttr::DT_Any)
1911 Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1914 if (DTCI.
Kind == OMPD_declare_target && RequiresToLinkLocalOrIndirectClause &&
1915 !HasToLinkLocalOrIndirectClause)
1916 Diag(DTCI.
Loc, diag::err_omp_declare_target_missing_required_clause)
1928 if (Tok.is(tok::annot_pragma_openmp_end))
1931 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1932 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1933 << getOpenMPDirectiveName(DKind, OMPVersion);
1934 while (Tok.isNot(tok::annot_pragma_openmp_end))
1943 bool SkipUntilOpenMPEnd) {
1944 int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1946 if (FoundKind == ExpectedKind) {
1948 skipUntilPragmaOpenMPEnd(ExpectedKind);
1952 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1953 Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1955 Diag(BeginLoc, diag::note_matching)
1956 << (
"'#pragma omp " + getOpenMPDirectiveName(BeginKind, OMPVersion) +
"'")
1958 if (SkipUntilOpenMPEnd)
1965 parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1969 if (Tok.is(tok::annot_pragma_openmp_end))
1970 ConsumeAnnotationToken();
1976 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
1977 "Not an OpenMP directive!");
1980 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
1985 TentativeParsingAction TPA(*
this);
1986 Loc = ConsumeAnnotationToken();
1988 if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1993 Toks.push_back(Tok);
1994 while (Cnt && Tok.isNot(tok::eof)) {
1996 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
1998 else if (Tok.is(tok::annot_pragma_openmp_end))
2000 Toks.push_back(Tok);
2005 auto *LP =
new LateParsedPragma(
this, AS);
2007 getCurrentClass().LateParsedDeclarations.push_back(LP);
2012 Loc = ConsumeAnnotationToken();
2017 case OMPD_threadprivate: {
2019 DeclDirectiveListParserHelper Helper(
this, DKind);
2020 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2022 skipUntilPragmaOpenMPEnd(DKind);
2024 ConsumeAnnotationToken();
2025 return Actions.OpenMP().ActOnOpenMPThreadprivateDirective(
2026 Loc, Helper.getIdentifiers());
2030 case OMPD_groupprivate: {
2032 DeclDirectiveListParserHelper Helper(
this, DKind);
2033 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2035 skipUntilPragmaOpenMPEnd(DKind);
2037 ConsumeAnnotationToken();
2038 return Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2039 Loc, Helper.getIdentifiers());
2043 case OMPD_allocate: {
2045 DeclDirectiveListParserHelper Helper(
this, DKind);
2046 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2048 SmallVector<OMPClause *, 1> Clauses;
2049 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2050 std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
2051 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2053 Tok.isAnnotation() ? OMPC_unknown
2054 : getOpenMPClauseKind(PP.getSpelling(Tok));
2055 Actions.OpenMP().StartOpenMPClause(CKind);
2056 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2057 !SeenClauses[
unsigned(CKind)]);
2058 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2060 SeenClauses[unsigned(CKind)] =
true;
2061 if (Clause !=
nullptr)
2062 Clauses.push_back(Clause);
2063 if (Tok.is(tok::annot_pragma_openmp_end)) {
2064 Actions.OpenMP().EndOpenMPClause();
2068 if (Tok.is(tok::comma))
2070 Actions.OpenMP().EndOpenMPClause();
2072 skipUntilPragmaOpenMPEnd(DKind);
2075 ConsumeAnnotationToken();
2076 return Actions.OpenMP().ActOnOpenMPAllocateDirective(
2077 Loc, Helper.getIdentifiers(), Clauses);
2081 case OMPD_requires: {
2083 SmallVector<OMPClause *, 5> Clauses;
2084 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2085 if (Tok.is(tok::annot_pragma_openmp_end)) {
2086 Diag(Tok, diag::err_omp_expected_clause)
2087 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2090 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2093 : getOpenMPClauseKind(PP.getSpelling(Tok));
2094 Actions.OpenMP().StartOpenMPClause(CKind);
2095 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
2096 !SeenClauses[
unsigned(CKind)]);
2097 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2099 SeenClauses[unsigned(CKind)] =
true;
2100 if (Clause !=
nullptr)
2101 Clauses.push_back(Clause);
2102 if (Tok.is(tok::annot_pragma_openmp_end)) {
2103 Actions.OpenMP().EndOpenMPClause();
2107 if (Tok.is(tok::comma))
2109 Actions.OpenMP().EndOpenMPClause();
2112 if (Clauses.empty()) {
2113 Diag(Tok, diag::err_omp_expected_clause)
2114 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
2115 ConsumeAnnotationToken();
2118 ConsumeAnnotationToken();
2119 return Actions.OpenMP().ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2122 SmallVector<OMPClause *, 1> Clauses;
2124 ParseOpenMPClauses(DKind, Clauses, StartLoc);
2125 Actions.OpenMP().ActOnOpenMPErrorDirective(Clauses, StartLoc,
2131 case OMPD_begin_assumes:
2134 case OMPD_end_assumes:
2137 case OMPD_declare_reduction:
2139 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2140 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2142 ConsumeAnnotationToken();
2146 case OMPD_declare_mapper: {
2148 if (
DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2150 ConsumeAnnotationToken();
2155 case OMPD_begin_declare_variant: {
2160 ConsumeAnnotationToken();
2164 case OMPD_end_declare_variant: {
2166 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2167 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2169 Diag(Loc, diag::err_expected_begin_declare_variant);
2171 ConsumeAnnotationToken();
2174 case OMPD_declare_variant:
2175 case OMPD_declare_simd: {
2181 Toks.push_back(Tok);
2183 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2184 Toks.push_back(Tok);
2187 Toks.push_back(Tok);
2191 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2192 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2194 }
else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2198 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2199 MaybeParseCXX11Attributes(Attrs);
2200 ParsingDeclSpec PDS(*
this);
2201 Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
2204 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2208 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2209 << (DKind == OMPD_declare_simd ? 0 : 1);
2212 if (DKind == OMPD_declare_simd)
2213 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2214 assert(DKind == OMPD_declare_variant &&
2215 "Expected declare variant directive only");
2216 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2219 case OMPD_begin_declare_target:
2220 case OMPD_declare_target: {
2222 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2223 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2224 if (DKind == OMPD_declare_target && !HasClauses &&
2226 Diag(DTLoc, diag::warn_omp_deprecated_declare_target_delimited_form);
2228 ParseOMPDeclareTargetClauses(DTCI);
2229 bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2236 if (HasImplicitMappings) {
2237 Actions.OpenMP().ActOnStartOpenMPDeclareTargetContext(DTCI);
2241 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2242 llvm::SmallVector<Decl *, 4> Decls;
2244 Decls.push_back(It.first);
2245 return Actions.BuildDeclaratorGroup(Decls);
2247 case OMPD_end_declare_target: {
2248 if (!Actions.OpenMP().isInOpenMPDeclareTargetContext()) {
2249 Diag(Tok, diag::err_omp_unexpected_directive)
2250 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2253 const SemaOpenMP::DeclareTargetContextInfo &DTCI =
2254 Actions.OpenMP().ActOnOpenMPEndDeclareTargetDirective();
2255 ParseOMPEndDeclareTargetDirective(DTCI.
Kind, DKind, DTCI.
Loc);
2259 Diag(Tok, diag::err_omp_unexpected_directive)
2260 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2264 Diag(Tok, diag::err_omp_unknown_directive);
2267 switch (getDirectiveCategory(DKind)) {
2268 case Category::Executable:
2269 case Category::Meta:
2270 case Category::Subsidiary:
2271 case Category::Utility:
2272 Diag(Tok, diag::err_omp_unexpected_directive)
2273 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2275 case Category::Declarative:
2276 case Category::Informational:
2280 while (Tok.isNot(tok::annot_pragma_openmp_end))
2286StmtResult Parser::ParseOpenMPExecutableDirective(
2288 bool ReadDirectiveWithinMetadirective) {
2290 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2292 bool HasAssociatedStatement =
true;
2293 Association Assoc = getDirectiveAssociation(DKind);
2299 if (DKind != OMPD_ordered && DKind != OMPD_section &&
2300 (Assoc == Association::None || Assoc == Association::Separating)) {
2301 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2302 ParsedStmtContext()) {
2303 Diag(Tok, diag::err_omp_immediate_directive)
2304 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2305 if (DKind == OMPD_error) {
2306 SkipUntil(tok::annot_pragma_openmp_end);
2310 HasAssociatedStatement =
false;
2313 SourceLocation EndLoc;
2314 SmallVector<OMPClause *, 5> Clauses;
2315 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2316 DeclarationNameInfo DirName;
2323 bool ImplicitClauseAllowed =
false;
2324 if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2326 ImplicitClauseAllowed =
true;
2330 if (DKind == OMPD_critical) {
2332 tok::annot_pragma_openmp_end);
2333 if (!T.consumeOpen()) {
2334 if (Tok.isAnyIdentifier()) {
2336 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2339 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2343 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2345 if (Tok.isNot(tok::annot_pragma_openmp_end))
2353 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2354 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2357 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2360 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2361 while (Tok.isNot(tok::annot_pragma_openmp_end))
2365 bool HasImplicitClause =
false;
2366 if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2367 HasImplicitClause =
true;
2370 PP.EnterToken(Tok,
true);
2371 PP.EnterToken(ImplicitTok,
true);
2376 : getOpenMPClauseKind(PP.getSpelling(Tok));
2377 if (HasImplicitClause) {
2378 assert(CKind == OMPC_unknown &&
"Must be unknown implicit clause.");
2379 if (DKind == OMPD_flush) {
2382 assert(DKind == OMPD_depobj &&
"Expected flush or depobj directives.");
2383 CKind = OMPC_depobj;
2387 ImplicitClauseAllowed =
false;
2388 Actions.OpenMP().StartOpenMPClause(CKind);
2389 HasImplicitClause =
false;
2391 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2392 SeenClauses[unsigned(CKind)] =
true;
2394 Clauses.push_back(Clause);
2397 if (Tok.is(tok::comma))
2399 Actions.OpenMP().EndOpenMPClause();
2402 EndLoc = Tok.getLocation();
2404 ConsumeAnnotationToken();
2406 if (DKind == OMPD_ordered) {
2409 for (
auto CK : {OMPC_depend, OMPC_doacross}) {
2410 if (SeenClauses[
unsigned(CK)]) {
2411 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2412 ParsedStmtContext()) {
2413 Diag(Loc, diag::err_omp_immediate_directive)
2414 << getOpenMPDirectiveName(DKind, OMPVersion) << 1
2415 << getOpenMPClauseName(CK);
2417 HasAssociatedStatement =
false;
2422 if ((DKind == OMPD_tile || DKind == OMPD_stripe) &&
2423 !SeenClauses[
unsigned(OMPC_sizes)]) {
2424 Diag(Loc, diag::err_omp_required_clause)
2425 << getOpenMPDirectiveName(DKind, OMPVersion) <<
"sizes";
2429 if (HasAssociatedStatement) {
2431 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2437 Sema::CompoundScopeRAII Scope(Actions);
2438 AssociatedStmt = ParseStatement();
2443 Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
2446 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2447 }
else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2448 DKind == OMPD_target_exit_data) {
2449 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2450 AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2451 Actions.ActOnCompoundStmt(Loc, Loc, {},
2454 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2458 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2461 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2462 OMPDirectiveScope.Exit();
2467StmtResult Parser::ParseOpenMPInformationalDirective(
2469 bool ReadDirectiveWithinMetadirective) {
2471 "Unexpected directive category");
2473 bool HasAssociatedStatement =
true;
2475 SmallVector<OMPClause *, 5> Clauses;
2476 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2477 DeclarationNameInfo DirName;
2480 ParseScope OMPDirectiveScope(
this, ScopeFlags);
2482 Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
2485 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2486 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2487 while (Tok.isNot(tok::annot_pragma_openmp_end))
2494 : getOpenMPClauseKind(PP.getSpelling(Tok));
2495 Actions.OpenMP().StartOpenMPClause(CKind);
2497 ParseOpenMPClause(DKind, CKind, !SeenClauses[
unsigned(CKind)]);
2498 SeenClauses[unsigned(CKind)] =
true;
2500 Clauses.push_back(Clause);
2502 if (Tok.is(tok::comma))
2504 Actions.OpenMP().EndOpenMPClause();
2507 SourceLocation EndLoc = Tok.getLocation();
2508 ConsumeAnnotationToken();
2511 if (HasAssociatedStatement) {
2512 Actions.OpenMP().ActOnOpenMPRegionStart(DKind,
getCurScope());
2515 Sema::CompoundScopeRAII Scope(Actions);
2516 AssociatedStmt = ParseStatement();
2519 Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2523 DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
2525 Actions.OpenMP().EndOpenMPDSABlock(
Directive.get());
2526 OMPDirectiveScope.Exit();
2531StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2532 ParsedStmtContext StmtCtx,
bool ReadDirectiveWithinMetadirective) {
2533 if (!ReadDirectiveWithinMetadirective)
2534 assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2535 "Not an OpenMP directive!");
2538 SourceLocation Loc = ReadDirectiveWithinMetadirective
2540 : ConsumeAnnotationToken();
2541 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2543 if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2544 Diag(Tok, diag::err_omp_unknown_directive);
2550 bool IsExecutable = [&]() {
2551 if (DKind == OMPD_error)
2553 auto Res = getDirectiveCategory(DKind);
2554 return Res == Category::Executable || Res == Category::Subsidiary;
2558 Directive = ParseOpenMPExecutableDirective(
2559 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2560 assert(!
Directive.isUnset() &&
"Executable directive remained unprocessed");
2569 if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
2570 while (Tok.isNot(tok::annot_pragma_openmp_end))
2573 skipUntilPragmaOpenMPEnd(DKind);
2574 if (Tok.is(tok::annot_pragma_openmp_end))
2575 ConsumeAnnotationToken();
2578 case OMPD_metadirective: {
2580 SmallVector<VariantMatchInfo, 4> VMIs;
2585 TentativeParsingAction TPA(*
this);
2586 ASTContext &ASTContext = Actions.getASTContext();
2589 tok::annot_pragma_openmp_end);
2590 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2593 : getOpenMPClauseKind(PP.getSpelling(Tok));
2595 if (CKind == OMPC_unknown) {
2596 Diag(Tok, diag::err_omp_expected_clause) <<
"metadirective";
2598 SkipUntil(tok::annot_pragma_openmp_end);
2601 if (
getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
2602 Diag(Tok, diag::err_omp_unexpected_clause)
2603 << getOpenMPClauseName(CKind) <<
"metadirective";
2604 if (CKind == OMPC_default &&
getLangOpts().OpenMP >= 52)
2605 Diag(Tok, diag::warn_omp_default_deprecated);
2610 if (T.expectAndConsume(diag::err_expected_lparen_after,
2611 getOpenMPClauseName(CKind).data())) {
2613 SkipUntil(tok::annot_pragma_openmp_end);
2617 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2618 if (CKind == OMPC_when) {
2620 parseOMPContextSelectors(Loc, TI);
2621 if (TI.
Sets.size() == 0) {
2622 Diag(Tok, diag::err_omp_expected_context_selector) <<
"when clause";
2628 if (Tok.is(tok::colon))
2631 Diag(Tok, diag::err_omp_expected_colon) <<
"when clause";
2639 while (Tok.isNot(tok::r_paren) || paren != 0) {
2640 if (Tok.is(tok::l_paren))
2642 if (Tok.is(tok::r_paren))
2644 if (Tok.is(tok::annot_pragma_openmp_end)) {
2645 Diag(Tok, diag::err_omp_expected_punc)
2646 << getOpenMPClauseName(CKind) << 0;
2653 if (Tok.is(tok::r_paren))
2656 VariantMatchInfo VMI;
2659 VMIs.push_back(VMI);
2666 [
this, Loc](StringRef ISATrait) {
2669 Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2671 TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2673 ArrayRef<llvm::omp::TraitProperty>(),
2674 Actions.OpenMP().getOpenMPDeviceNum());
2677 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2684 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2686 if (Idx++ != BestIdx) {
2691 while (Tok.isNot(tok::r_paren) || paren != 0) {
2692 if (Tok.is(tok::l_paren))
2694 if (Tok.is(tok::r_paren))
2699 if (Tok.is(tok::r_paren))
2706 : getOpenMPClauseKind(PP.getSpelling(Tok));
2713 if (CKind == OMPC_when) {
2714 OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2716 parseOMPContextSelectors(Loc, TI);
2724 if (Tok.is(tok::r_paren)) {
2725 SkipUntil(tok::annot_pragma_openmp_end);
2730 Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2738 if (BestIdx == -1 && Idx > 0) {
2739 assert(Tok.is(tok::annot_pragma_openmp_end) &&
2740 "Expecting the end of the pragma here");
2741 ConsumeAnnotationToken();
2746 case OMPD_threadprivate: {
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().ActOnOpenMPThreadprivateDirective(
2759 Loc, Helper.getIdentifiers());
2760 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2762 SkipUntil(tok::annot_pragma_openmp_end);
2765 case OMPD_groupprivate: {
2766 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2767 ParsedStmtContext()) {
2768 Diag(Tok, diag::err_omp_immediate_directive)
2769 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2772 DeclDirectiveListParserHelper Helper(
this, DKind);
2773 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2775 skipUntilPragmaOpenMPEnd(DKind);
2776 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPGroupPrivateDirective(
2777 Loc, Helper.getIdentifiers());
2778 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2780 SkipUntil(tok::annot_pragma_openmp_end);
2783 case OMPD_allocate: {
2785 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2786 ParsedStmtContext()) {
2787 Diag(Tok, diag::err_omp_immediate_directive)
2788 << getOpenMPDirectiveName(DKind, OMPVersion) << 0;
2791 DeclDirectiveListParserHelper Helper(
this, DKind);
2792 if (!ParseOpenMPSimpleVarList(DKind, Helper,
2794 SmallVector<OMPClause *, 1> Clauses;
2795 if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2796 llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
2797 while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2799 Tok.isAnnotation() ? OMPC_unknown
2800 : getOpenMPClauseKind(PP.getSpelling(Tok));
2801 Actions.OpenMP().StartOpenMPClause(CKind);
2802 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
2803 !SeenClauses[
unsigned(CKind)]);
2804 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2806 SeenClauses[unsigned(CKind)] =
true;
2807 if (Clause !=
nullptr)
2808 Clauses.push_back(Clause);
2809 if (Tok.is(tok::annot_pragma_openmp_end)) {
2810 Actions.OpenMP().EndOpenMPClause();
2814 if (Tok.is(tok::comma))
2816 Actions.OpenMP().EndOpenMPClause();
2818 skipUntilPragmaOpenMPEnd(DKind);
2820 DeclGroupPtrTy Res = Actions.OpenMP().ActOnOpenMPAllocateDirective(
2821 Loc, Helper.getIdentifiers(), Clauses);
2822 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2824 SkipUntil(tok::annot_pragma_openmp_end);
2827 case OMPD_declare_reduction:
2830 ParseOpenMPDeclareReductionDirective(
AS_none)) {
2831 skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2833 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2835 SkipUntil(tok::annot_pragma_openmp_end);
2838 case OMPD_declare_mapper: {
2841 ParseOpenMPDeclareMapperDirective(
AS_none)) {
2843 ConsumeAnnotationToken();
2844 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2846 SkipUntil(tok::annot_pragma_openmp_end);
2850 case OMPD_declare_target: {
2852 bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2853 SemaOpenMP::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2855 ParseOMPDeclareTargetClauses(DTCI);
2856 bool HasImplicitMappings =
2859 if (HasImplicitMappings) {
2860 Diag(Tok, diag::err_omp_unexpected_directive)
2861 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2862 SkipUntil(tok::annot_pragma_openmp_end);
2869 Actions.OpenMP().ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2872 case OMPD_begin_declare_variant: {
2877 ConsumeAnnotationToken();
2881 case OMPD_end_declare_variant: {
2883 if (Actions.OpenMP().isInOpenMPDeclareVariantScope())
2884 Actions.OpenMP().ActOnOpenMPEndDeclareVariant();
2886 Diag(Loc, diag::err_expected_begin_declare_variant);
2887 ConsumeAnnotationToken();
2890 case OMPD_declare_simd:
2891 case OMPD_begin_declare_target:
2892 case OMPD_end_declare_target:
2894 case OMPD_declare_variant:
2895 Diag(Tok, diag::err_omp_unexpected_directive)
2896 << 1 << getOpenMPDirectiveName(DKind, OMPVersion);
2897 SkipUntil(tok::annot_pragma_openmp_end);
2901 Directive = ParseOpenMPInformationalDirective(
2902 StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
2904 "Informational directive remains unprocessed");
2909 Diag(Tok, diag::err_omp_unknown_directive);
2910 SkipUntil(tok::annot_pragma_openmp_end);
2916bool Parser::ParseOpenMPSimpleVarList(
2920 bool AllowScopeSpecifier) {
2921 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
2924 if (T.expectAndConsume(diag::err_expected_lparen_after,
2925 getOpenMPDirectiveName(Kind, OMPVersion).data()))
2927 bool IsCorrect =
true;
2928 bool NoIdentIsFound =
true;
2931 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2935 Token PrevTok = Tok;
2936 NoIdentIsFound =
false;
2939 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2942 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2945 false,
false,
false,
2946 false,
false,
nullptr, Name)) {
2948 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2950 }
else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2951 Tok.isNot(tok::annot_pragma_openmp_end)) {
2953 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2957 << SourceRange(PrevTok.
getLocation(), PrevTokLocation);
2959 Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2962 if (Tok.is(tok::comma)) {
2967 if (NoIdentIsFound) {
2968 Diag(Tok, diag::err_expected) << tok::identifier;
2973 IsCorrect = !T.consumeClose() && IsCorrect;
2978OMPClause *Parser::ParseOpenMPSizesClause() {
2979 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
2980 SmallVector<Expr *, 4> ValExprs;
2981 if (ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,
2985 return Actions.OpenMP().ActOnOpenMPSizesClause(ValExprs, ClauseNameLoc,
2989OMPClause *Parser::ParseOpenMPLoopRangeClause() {
2991 SourceLocation FirstLoc, CountLoc;
2994 if (T.consumeOpen()) {
2995 Diag(Tok, diag::err_expected) << tok::l_paren;
2999 FirstLoc = Tok.getLocation();
3006 ExpectAndConsume(tok::comma);
3008 CountLoc = Tok.getLocation();
3017 return Actions.OpenMP().ActOnOpenMPLoopRangeClause(
3018 FirstVal.
get(), CountVal.
get(), ClauseNameLoc, T.getOpenLocation(),
3019 FirstLoc, CountLoc, T.getCloseLocation());
3022OMPClause *Parser::ParseOpenMPPermutationClause() {
3023 SourceLocation ClauseNameLoc, OpenLoc, CloseLoc;
3024 SmallVector<Expr *> ArgExprs;
3025 if (ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,
3030 return Actions.OpenMP().ActOnOpenMPPermutationClause(ArgExprs, ClauseNameLoc,
3035 SourceLocation Loc = Tok.getLocation();
3040 if (T.expectAndConsume(diag::err_expected_lparen_after,
"uses_allocator"))
3042 SmallVector<SemaOpenMP::UsesAllocatorsData, 4>
Data;
3045 if (
getLangOpts().OpenMP >= 52 && Tok.is(tok::identifier) &&
3046 Tok.getIdentifierInfo()->getName() ==
"traits") {
3048 SemaOpenMP::UsesAllocatorsData &D =
Data.emplace_back();
3054 tok::annot_pragma_openmp_end);
3055 TraitParens.consumeOpen();
3058 TraitParens.consumeClose();
3062 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3068 if (Tok.isNot(tok::colon)) {
3069 Diag(Tok, diag::err_expected) << tok::colon;
3071 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3081 ? ParseCXXIdExpression()
3082 : tryParseCXXIdExpression(SS,
false,
3087 {tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3094 D.
LParenLoc = TraitParens.getOpenLocation();
3095 D.
RParenLoc = TraitParens.getCloseLocation();
3098 if (Tok.is(tok::comma)) {
3100 Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3103 }
else if (Tok.is(tok::semi)) {
3114 getLangOpts().CPlusPlus
3115 ? ParseCXXIdExpression()
3116 : tryParseCXXIdExpression(SS,
false,
3119 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3126 BalancedDelimiterTracker T(*this, tok::l_paren,
3127 tok::annot_pragma_openmp_end);
3129 ExprResult AllocatorTraits =
3130 getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3132 if (AllocatorTraits.isInvalid()) {
3133 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3142 if (getLangOpts().OpenMP >= 52) {
3143 Diag(Loc, diag::err_omp_deprecate_old_syntax)
3144 <<
"allocator(expr)"
3145 <<
"uses_allocators"
3146 <<
"traits(expr): alloc";
3150 Diag(
Tok, diag::err_omp_expected_punc) <<
"uses_allocators" << 0;
3152 if (
Tok.
is(tok::comma))
3154 }
while (
Tok.
isNot(tok::r_paren) &&
Tok.
isNot(tok::annot_pragma_openmp_end));
3157 Loc, T.getOpenLocation(), T.getCloseLocation(),
Data);
3162 OMPClauseKind = CKind;
3163 OMPClause *Clause =
nullptr;
3164 bool ErrorFound =
false;
3165 bool WrongDirective =
false;
3166 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
3169 if (CKind != OMPC_unknown &&
3170 !isAllowedClauseForDirective(DKind, CKind,
getLangOpts().OpenMP)) {
3171 Diag(Tok, diag::err_omp_unexpected_clause)
3172 << getOpenMPClauseName(CKind)
3173 << getOpenMPDirectiveName(DKind, OMPVersion);
3175 WrongDirective =
true;
3180 case OMPC_num_threads:
3186 case OMPC_grainsize:
3187 case OMPC_num_tasks:
3189 case OMPC_allocator:
3192 case OMPC_novariants:
3193 case OMPC_nocontext:
3198 case OMPC_ompx_dyn_cgroup_mem:
3199 case OMPC_dyn_groupprivate:
3200 case OMPC_transparent:
3229 Diag(Tok, diag::err_omp_more_one_clause)
3230 << getOpenMPDirectiveName(DKind, OMPVersion)
3231 << getOpenMPClauseName(CKind) << 0;
3235 if (CKind == OMPC_transparent && PP.LookAhead(0).isNot(tok::l_paren)) {
3237 SourceLocation LLoc = Tok.getLocation();
3238 Clause = Actions.OpenMP().ActOnOpenMPTransparentClause(
nullptr, LLoc,
3242 if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3243 PP.LookAhead(0).isNot(tok::l_paren))
3244 Clause = ParseOpenMPClause(CKind, WrongDirective);
3245 else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks ||
3246 CKind == OMPC_num_threads || CKind == OMPC_dyn_groupprivate)
3247 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3249 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3251 case OMPC_threadset:
3253 case OMPC_proc_bind:
3254 case OMPC_atomic_default_mem_order:
3272 Diag(Tok, diag::err_omp_more_one_clause)
3273 << getOpenMPDirectiveName(DKind, OMPVersion)
3274 << getOpenMPClauseName(CKind) << 0;
3278 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3282 case OMPC_dist_schedule:
3283 case OMPC_defaultmap:
3294 if ((
getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3295 (CKind != OMPC_order ||
getLangOpts().OpenMP >= 51) && !FirstClause) {
3296 Diag(Tok, diag::err_omp_more_one_clause)
3297 << getOpenMPDirectiveName(DKind, OMPVersion)
3298 << getOpenMPClauseName(CKind) << 0;
3303 Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3306 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3310 case OMPC_mergeable:
3324 case OMPC_unified_address:
3325 case OMPC_unified_shared_memory:
3326 case OMPC_reverse_offload:
3327 case OMPC_dynamic_allocators:
3336 Diag(Tok, diag::err_omp_more_one_clause)
3337 << getOpenMPDirectiveName(DKind, OMPVersion)
3338 << getOpenMPClauseName(CKind) << 0;
3342 if (CKind == OMPC_nowait && PP.LookAhead(0).is(tok::l_paren) &&
3344 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3346 Clause = ParseOpenMPClause(CKind, WrongDirective);
3348 case OMPC_self_maps:
3351 Diag(Tok, diag::err_omp_expected_clause)
3352 << getOpenMPDirectiveName(OMPD_requires, OMPVersion);
3356 Diag(Tok, diag::err_omp_more_one_clause)
3357 << getOpenMPDirectiveName(DKind, OMPVersion)
3358 << getOpenMPClauseName(CKind) << 0;
3361 Clause = ParseOpenMPClause(CKind, WrongDirective);
3365 Diag(Tok, diag::err_omp_more_one_clause)
3366 << getOpenMPDirectiveName(DKind, OMPVersion)
3367 << getOpenMPClauseName(CKind) << 0;
3371 Clause = (DKind == OMPD_depobj)
3372 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3373 : ParseOpenMPClause(CKind, WrongDirective);
3375 case OMPC_num_teams:
3376 case OMPC_thread_limit:
3378 Diag(Tok, diag::err_omp_more_one_clause)
3379 << getOpenMPDirectiveName(DKind, OMPVersion)
3380 << getOpenMPClauseName(CKind) << 0;
3385 case OMPC_firstprivate:
3386 case OMPC_lastprivate:
3388 case OMPC_reduction:
3389 case OMPC_task_reduction:
3390 case OMPC_in_reduction:
3394 case OMPC_copyprivate:
3400 case OMPC_use_device_ptr:
3401 case OMPC_use_device_addr:
3402 case OMPC_is_device_ptr:
3403 case OMPC_has_device_addr:
3405 case OMPC_nontemporal:
3406 case OMPC_inclusive:
3407 case OMPC_exclusive:
3411 if (
getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
3412 CKind == OMPC_depend)
3413 Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
3414 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3418 Diag(Tok, diag::err_omp_more_one_clause)
3419 << getOpenMPDirectiveName(DKind, OMPVersion)
3420 << getOpenMPClauseName(CKind) << 0;
3424 Clause = ParseOpenMPSizesClause();
3426 case OMPC_permutation:
3428 Diag(Tok, diag::err_omp_more_one_clause)
3429 << getOpenMPDirectiveName(DKind, OMPVersion)
3430 << getOpenMPClauseName(CKind) << 0;
3433 Clause = ParseOpenMPPermutationClause();
3435 case OMPC_uses_allocators:
3436 Clause = ParseOpenMPUsesAllocatorClause(DKind);
3439 if (DKind != OMPD_interop) {
3441 Diag(Tok, diag::err_omp_more_one_clause)
3442 << getOpenMPDirectiveName(DKind, OMPVersion)
3443 << getOpenMPClauseName(CKind) << 0;
3446 Clause = ParseOpenMPClause(CKind, WrongDirective);
3452 Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3454 case OMPC_device_type:
3456 skipUntilPragmaOpenMPEnd(DKind);
3458 case OMPC_threadprivate:
3459 case OMPC_groupprivate:
3462 if (!WrongDirective)
3463 Diag(Tok, diag::err_omp_unexpected_clause)
3464 << getOpenMPClauseName(CKind)
3465 << getOpenMPDirectiveName(DKind, OMPVersion);
3469 case OMPC_contains: {
3471 SourceLocation LLoc = Tok.getLocation();
3472 SourceLocation RLoc;
3473 llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
3478 if (DK == OMPD_unknown) {
3479 skipUntilPragmaOpenMPEnd(OMPD_assume);
3480 Diag(Tok, diag::err_omp_unexpected_clause)
3481 << getOpenMPClauseName(CKind)
3482 << getOpenMPDirectiveName(DKind, OMPVersion);
3486 DKVec.push_back(DK);
3489 Diag(Tok, diag::err_omp_unexpected_clause)
3490 << getOpenMPClauseName(CKind)
3491 << getOpenMPDirectiveName(DKind, OMPVersion);
3494 RLoc = Tok.getLocation();
3496 Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
3497 CKind, DKVec, Loc, LLoc, RLoc);
3500 case OMPC_no_openmp:
3501 case OMPC_no_openmp_routines:
3502 case OMPC_no_openmp_constructs:
3503 case OMPC_no_parallelism: {
3505 Diag(Tok, diag::err_omp_more_one_clause)
3506 << getOpenMPDirectiveName(DKind, OMPVersion)
3507 << getOpenMPClauseName(CKind) << 0;
3511 Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
3512 CKind, Loc, Tok.getLocation());
3515 case OMPC_ompx_attribute:
3516 Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
3518 case OMPC_ompx_bare:
3519 if (DKind == llvm::omp::Directive::OMPD_target) {
3524 Diag(Tok, diag::err_omp_unexpected_clause)
3525 << getOpenMPClauseName(CKind)
3526 << getOpenMPDirectiveName(DKind, OMPVersion);
3528 WrongDirective =
true;
3531 Diag(Tok, diag::note_ompx_bare_clause)
3532 << getOpenMPClauseName(CKind) <<
"target teams";
3533 if (!ErrorFound && !
getLangOpts().OpenMPExtensions) {
3534 Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
3535 << getOpenMPClauseName(CKind)
3536 << getOpenMPDirectiveName(DKind, OMPVersion);
3539 Clause = ParseOpenMPClause(CKind, WrongDirective);
3541 case OMPC_looprange:
3542 Clause = ParseOpenMPLoopRangeClause();
3547 return ErrorFound ?
nullptr : Clause;
3555 bool IsAddressOfOperand) {
3557 if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3565 Val = Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
3568 RLoc = Tok.getLocation();
3569 if (!T.consumeClose())
3570 RLoc = T.getCloseLocation();
3592bool Parser::ParseOpenMPIndirectClause(
3597 if (
Tok.isNot(tok::l_paren)) {
3616 if (
Ret.isInvalid())
3619 Ret = Actions.VerifyIntegerConstantExpression(Val.
get(), &
Result,
3621 if (
Ret.isInvalid())
3632 bool HasError =
false;
3633 bool IsTarget =
false;
3634 bool IsTargetSync =
false;
3636 while (Tok.is(tok::identifier)) {
3638 bool PreferTypeAllowed =
Kind == OMPC_init &&
3641 if (Tok.getIdentifierInfo()->isStr(
"target")) {
3646 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"target";
3649 }
else if (Tok.getIdentifierInfo()->isStr(
"targetsync")) {
3651 Diag(Tok, diag::warn_omp_more_one_interop_type) <<
"targetsync";
3652 IsTargetSync =
true;
3654 }
else if (Tok.getIdentifierInfo()->isStr(
"prefer_type") &&
3655 PreferTypeAllowed) {
3658 tok::annot_pragma_openmp_end);
3659 if (PT.expectAndConsume(diag::err_expected_lparen_after,
"prefer_type"))
3662 while (Tok.isNot(tok::r_paren)) {
3663 SourceLocation Loc = Tok.getLocation();
3666 PTExpr = Actions.ActOnFinishFullExpr(PTExpr.
get(), Loc,
3672 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3676 if (Tok.is(tok::comma))
3682 Diag(Tok, diag::err_omp_expected_interop_type);
3685 if (!Tok.is(tok::comma))
3690 if (!HasError && !IsTarget && !IsTargetSync) {
3691 Diag(Tok, diag::err_omp_expected_interop_type);
3695 if (Kind == OMPC_init) {
3696 if (Tok.isNot(tok::colon) && (IsTarget || IsTargetSync))
3697 Diag(Tok, diag::warn_pragma_expected_colon) <<
"interop types";
3698 if (Tok.is(tok::colon))
3715 if (T.expectAndConsume(diag::err_expected_lparen_after,
3716 getOpenMPClauseName(Kind).data()))
3719 bool InteropError =
false;
3720 OMPInteropInfo InteropInfo;
3721 if (Kind == OMPC_init)
3722 InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);
3725 SourceLocation VarLoc = Tok.getLocation();
3728 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3733 SourceLocation RLoc = Tok.getLocation();
3734 if (!T.consumeClose())
3735 RLoc = T.getCloseLocation();
3737 if (ParseOnly || !InteropVarExpr.
isUsable() || InteropError)
3740 if (Kind == OMPC_init)
3741 return Actions.OpenMP().ActOnOpenMPInitClause(
3742 InteropVarExpr.
get(), InteropInfo, Loc, T.getOpenLocation(), VarLoc,
3744 if (Kind == OMPC_use)
3745 return Actions.OpenMP().ActOnOpenMPUseClause(
3746 InteropVarExpr.
get(), Loc, T.getOpenLocation(), VarLoc, RLoc);
3748 if (Kind == OMPC_destroy)
3749 return Actions.OpenMP().ActOnOpenMPDestroyClause(
3750 InteropVarExpr.
get(), Loc, T.getOpenLocation(), VarLoc, RLoc);
3752 llvm_unreachable(
"Unexpected interop variable clause.");
3755OMPClause *Parser::ParseOpenMPOMPXAttributesClause(
bool ParseOnly) {
3759 if (T.expectAndConsume(diag::err_expected_lparen_after,
3760 getOpenMPClauseName(OMPC_ompx_attribute).data()))
3763 ParsedAttributes ParsedAttrs(AttrFactory);
3764 ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
3767 if (T.consumeClose())
3773 SmallVector<Attr *> Attrs;
3774 for (
const ParsedAttr &PA : ParsedAttrs) {
3775 switch (PA.getKind()) {
3776 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
3777 if (!PA.checkExactlyNumArgs(Actions, 2))
3779 if (
auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr(
3780 PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
3783 case ParsedAttr::AT_AMDGPUWavesPerEU:
3784 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3785 !PA.checkAtMostNumArgs(Actions, 2))
3787 if (
auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr(
3788 PA, PA.getArgAsExpr(0),
3789 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr))
3792 case ParsedAttr::AT_CUDALaunchBounds:
3793 if (!PA.checkAtLeastNumArgs(Actions, 1) ||
3794 !PA.checkAtMostNumArgs(Actions, 2))
3796 if (
auto *A = Actions.CreateLaunchBoundsAttr(
3797 PA, PA.getArgAsExpr(0),
3798 PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :
nullptr,
3799 PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :
nullptr))
3803 Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
3808 return Actions.OpenMP().ActOnOpenMPXAttributeClause(
3809 Attrs, Loc, T.getOpenLocation(), T.getCloseLocation());
3815 if (!Val || ParseOnly)
3817 if (
getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3818 (
static_cast<DefaultKind
>(Val->Type) == OMP_DEFAULT_private ||
3819 static_cast<DefaultKind
>(Val->Type) ==
3820 OMP_DEFAULT_firstprivate)) {
3821 Diag(Val->LOpen, diag::err_omp_invalid_dsa)
3822 << getOpenMPClauseName(
static_cast<DefaultKind
>(Val->Type) ==
3825 : OMPC_firstprivate)
3826 << getOpenMPClauseName(OMPC_default) <<
"5.1";
3829 return Actions.OpenMP().ActOnOpenMPSimpleClause(
3830 Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
3834 SourceLocation Loc = Tok.getLocation();
3839 return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3846 SourceLocation DelimLoc;
3849 if (T.expectAndConsume(diag::err_expected_lparen_after,
3850 getOpenMPClauseName(Kind).data()))
3854 SmallVector<unsigned, 4> Arg;
3855 SmallVector<SourceLocation, 4> KLoc;
3856 if (Kind == OMPC_schedule) {
3857 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3858 Arg.resize(NumberOfElements);
3859 KLoc.resize(NumberOfElements);
3864 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3867 Arg[Modifier1] = KindModifier;
3868 KLoc[Modifier1] = Tok.getLocation();
3869 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3870 Tok.isNot(tok::annot_pragma_openmp_end))
3872 if (Tok.is(tok::comma)) {
3876 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3880 KLoc[Modifier2] = Tok.getLocation();
3881 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3882 Tok.isNot(tok::annot_pragma_openmp_end))
3886 if (Tok.is(tok::colon))
3889 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
3891 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3893 Arg[ScheduleKind] = KindModifier;
3894 KLoc[ScheduleKind] = Tok.getLocation();
3895 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3896 Tok.isNot(tok::annot_pragma_openmp_end))
3898 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3899 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3900 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3903 }
else if (Kind == OMPC_dist_schedule) {
3905 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3906 KLoc.push_back(Tok.getLocation());
3907 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3908 Tok.isNot(tok::annot_pragma_openmp_end))
3910 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3912 }
else if (Kind == OMPC_default) {
3915 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3917 Arg.push_back(Modifier);
3918 KLoc.push_back(Tok.getLocation());
3919 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3920 Tok.isNot(tok::annot_pragma_openmp_end))
3923 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP >= 60) {
3928 Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3929 Arg.push_back(VariableCategory);
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 Arg.push_back(OMPC_DEFAULT_VC_all);
3936 KLoc.push_back(SourceLocation());
3938 }
else if (Kind == OMPC_defaultmap) {
3941 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3947 Arg.push_back(Modifier);
3948 KLoc.push_back(Tok.getLocation());
3949 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3950 Tok.isNot(tok::annot_pragma_openmp_end))
3953 if (Tok.is(tok::colon) ||
getLangOpts().OpenMP < 50) {
3954 if (Tok.is(tok::colon))
3957 Diag(Tok, diag::warn_pragma_expected_colon) <<
"defaultmap modifier";
3960 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
3961 KLoc.push_back(Tok.getLocation());
3962 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3963 Tok.isNot(tok::annot_pragma_openmp_end))
3967 KLoc.push_back(SourceLocation());
3969 }
else if (Kind == OMPC_order) {
3970 enum { Modifier, OrderKind, NumberOfElements };
3971 Arg.resize(NumberOfElements);
3972 KLoc.resize(NumberOfElements);
3976 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3979 Arg[Modifier] = KindModifier;
3980 KLoc[Modifier] = Tok.getLocation();
3981 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3982 Tok.isNot(tok::annot_pragma_openmp_end))
3985 if (Tok.is(tok::colon))
3988 Diag(Tok, diag::warn_pragma_expected_colon) <<
"order modifier";
3990 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
3992 Arg[OrderKind] = KindModifier;
3993 KLoc[OrderKind] = Tok.getLocation();
3994 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3995 Tok.isNot(tok::annot_pragma_openmp_end))
3997 }
else if (Kind == OMPC_device) {
4003 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts()));
4004 KLoc.push_back(Tok.getLocation());
4010 KLoc.emplace_back();
4012 }
else if (Kind == OMPC_grainsize) {
4016 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4020 Arg.push_back(Modifier);
4021 KLoc.push_back(Tok.getLocation());
4027 if (Modifier == OMPC_GRAINSIZE_strict) {
4028 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4033 KLoc.emplace_back();
4037 KLoc.emplace_back();
4039 }
else if (Kind == OMPC_dyn_groupprivate) {
4040 enum { SimpleModifier, ComplexModifier, NumberOfModifiers };
4041 Arg.resize(NumberOfModifiers);
4042 KLoc.resize(NumberOfModifiers);
4046 auto ConsumeModifier = [&]() {
4047 unsigned Type = NumberOfModifiers;
4050 if (!Tok.isAnnotation() && PP.getSpelling(Tok) ==
"fallback" &&
4054 ParenT.consumeOpen();
4057 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4060 Diag(Tok.getLocation(), diag::err_expected)
4061 <<
"'abort', 'null' or 'default_mem' in fallback modifier";
4063 return std::make_tuple(
Type, Modifier, Loc);
4065 Type = ComplexModifier;
4066 Loc = Tok.getLocation();
4067 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4068 Tok.isNot(tok::annot_pragma_openmp_end))
4070 ParenT.consumeClose();
4073 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
getLangOpts());
4075 Type = SimpleModifier;
4076 Loc = Tok.getLocation();
4077 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
4078 Tok.isNot(tok::annot_pragma_openmp_end))
4082 return std::make_tuple(
Type, Modifier, Loc);
4085 auto SaveModifier = [&](
unsigned Type,
unsigned Modifier,
4086 SourceLocation Loc) {
4087 assert(
Type < NumberOfModifiers &&
"Unexpected modifier type");
4088 if (!KLoc[
Type].isValid()) {
4089 Arg[
Type] = Modifier;
4092 Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier)
4099 auto [Type1, Mod1, Loc1] = ConsumeModifier();
4100 if (Type1 < NumberOfModifiers) {
4101 SaveModifier(Type1, Mod1, Loc1);
4102 if (Tok.is(tok::comma)) {
4105 auto [Type2, Mod2, Loc2] = ConsumeModifier();
4106 if (Type2 < NumberOfModifiers)
4107 SaveModifier(Type2, Mod2, Loc2);
4110 if (Tok.is(tok::colon))
4113 Diag(Tok, diag::warn_pragma_expected_colon)
4114 <<
"dyn_groupprivate modifier";
4116 }
else if (Kind == OMPC_num_tasks) {
4120 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4124 Arg.push_back(Modifier);
4125 KLoc.push_back(Tok.getLocation());
4131 if (Modifier == OMPC_NUMTASKS_strict) {
4132 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4137 KLoc.emplace_back();
4141 KLoc.emplace_back();
4143 }
else if (Kind == OMPC_num_threads) {
4147 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
4151 Arg.push_back(Modifier);
4152 KLoc.push_back(Tok.getLocation());
4158 if (Modifier == OMPC_NUMTHREADS_strict) {
4159 Diag(Tok, diag::err_modifier_expected_colon) <<
"strict";
4164 KLoc.emplace_back();
4168 KLoc.emplace_back();
4171 assert(Kind == OMPC_if);
4172 KLoc.push_back(Tok.getLocation());
4173 TentativeParsingAction TPA(*
this);
4175 Arg.push_back(
static_cast<unsigned>(DK));
4176 if (DK != OMPD_unknown) {
4178 if (Tok.is(tok::colon) &&
getLangOpts().OpenMP > 40) {
4183 Arg.back() = unsigned(OMPD_unknown);
4190 bool NeedAnExpression =
4192 (
Kind == OMPC_dist_schedule && DelimLoc.
isValid()) ||
Kind == OMPC_if ||
4193 Kind == OMPC_device ||
Kind == OMPC_grainsize ||
Kind == OMPC_num_tasks ||
4194 Kind == OMPC_num_threads ||
Kind == OMPC_dyn_groupprivate;
4195 if (NeedAnExpression) {
4196 SourceLocation ELoc = Tok.getLocation();
4202 Actions.ActOnFinishFullExpr(Val.
get(), ELoc,
false);
4206 SourceLocation RLoc = Tok.getLocation();
4207 if (!T.consumeClose())
4208 RLoc = T.getCloseLocation();
4210 if (NeedAnExpression && Val.
isInvalid())
4213 if (Kind == OMPC_default &&
getLangOpts().OpenMP < 51 && Arg[0] &&
4214 (
static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_private ||
4215 static_cast<DefaultKind
>(Arg[0]) == OMP_DEFAULT_firstprivate)) {
4216 Diag(KLoc[0], diag::err_omp_invalid_dsa)
4217 << getOpenMPClauseName(
static_cast<DefaultKind
>(Arg[0]) ==
4220 : OMPC_firstprivate)
4221 << getOpenMPClauseName(OMPC_default) <<
"5.1";
4227 return Actions.OpenMP().ActOnOpenMPSingleExprWithArgClause(
4228 Kind, Arg, Val.
get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
4233 if (ReductionIdScopeSpec.
isEmpty()) {
4271 ReductionIdScopeSpec,
nullptr,
4275 false,
nullptr, ReductionId);
4282 if (!
Tok.is(tok::identifier))
4289 return TypeModifier;
4295 if (T.expectAndConsume(diag::err_expected_lparen_after,
"mapper")) {
4296 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4302 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4306 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
4307 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
4308 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4312 auto &DeclNames = Actions.getASTContext().DeclarationNames;
4314 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
4317 return T.consumeClose();
4323 bool HasMapType =
false;
4325 StringRef PreMapName =
"";
4329 if (TypeModifier == OMPC_MAP_MODIFIER_always ||
4330 TypeModifier == OMPC_MAP_MODIFIER_close ||
4331 TypeModifier == OMPC_MAP_MODIFIER_present ||
4332 TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
4333 Data.MapTypeModifiers.push_back(TypeModifier);
4334 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4335 if (PP.LookAhead(0).isNot(tok::comma) &&
4336 PP.LookAhead(0).isNot(tok::colon) &&
getLangOpts().OpenMP >= 52)
4337 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4338 <<
"map type modifier";
4340 }
else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
4341 Data.MapTypeModifiers.push_back(TypeModifier);
4342 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4346 if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
4348 Diag(
Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
4349 <<
"map type modifier";
4354 Data.ExtraModifier = MapKind;
4356 PreMapLoc = Tok.getLocation();
4357 PreMapName = Tok.getIdentifierInfo()->getName();
4359 Diag(Tok, diag::err_omp_more_one_map_type);
4360 Diag(PreMapLoc, diag::note_previous_map_type_specified_here)
4364 }
else if (TypeModifier == OMPC_MAP_MODIFIER_self) {
4365 Data.MapTypeModifiers.push_back(TypeModifier);
4366 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4367 if (PP.LookAhead(0).isNot(tok::comma) &&
4368 PP.LookAhead(0).isNot(tok::colon))
4369 Diag(Tok.getLocation(), diag::err_omp_missing_comma)
4370 <<
"map type modifier";
4372 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4382 if (Tok.is(tok::comma)) {
4383 Diag(Tok, diag::err_omp_map_type_modifier_missing);
4388 if (PP.LookAhead(0).is(tok::colon)) {
4396 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4407 if (!Tok.is(tok::colon)) {
4408 Diag(Tok, diag::err_omp_unknown_map_type);
4422 if (!
Tok.isOneOf(tok::identifier, tok::kw_delete))
4427 if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
4428 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||
4429 MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)
4439 if (
Tok.is(tok::colon)) {
4440 P.
Diag(
Tok, diag::err_omp_map_type_missing);
4445 P.
Diag(
Tok, diag::err_omp_unknown_map_type);
4449ExprResult Parser::ParseOpenMPIteratorsExpr() {
4450 assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator" &&
4451 "Expected 'iterator' token.");
4455 if (T.expectAndConsume(diag::err_expected_lparen_after,
"iterator"))
4458 SourceLocation LLoc = T.getOpenLocation();
4459 SmallVector<SemaOpenMP::OMPIteratorData, 4>
Data;
4460 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
4463 if (Tok.isNot(tok::identifier) ||
NextToken().
isNot(tok::equal)) {
4470 IteratorType = TR.
get();
4474 IdentifierInfo *II =
nullptr;
4475 SourceLocation IdLoc;
4476 if (Tok.is(tok::identifier)) {
4477 II = Tok.getIdentifierInfo();
4480 Diag(Tok, diag::err_expected_unqualified_id) << 0;
4484 SourceLocation AssignLoc;
4485 if (Tok.is(tok::equal))
4488 Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4493 SourceLocation Loc = Tok.getLocation();
4496 Begin = Actions.ActOnFinishFullExpr(Begin.
get(), Loc,
4499 SourceLocation ColonLoc;
4500 if (Tok.is(tok::colon))
4504 Loc = Tok.getLocation();
4507 End = Actions.ActOnFinishFullExpr(End.
get(), Loc,
4510 SourceLocation SecColonLoc;
4513 if (Tok.is(tok::colon)) {
4517 Loc = Tok.getLocation();
4520 Step = Actions.ActOnFinishFullExpr(Step.
get(), Loc,
4525 if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4526 Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4527 if (Tok.is(tok::comma))
4530 SemaOpenMP::OMPIteratorData &D =
Data.emplace_back();
4533 D.
Type = IteratorType;
4543 SourceLocation RLoc = Tok.getLocation();
4544 if (!T.consumeClose())
4545 RLoc = T.getCloseLocation();
4547 return Actions.OpenMP().ActOnOMPIteratorExpr(
getCurScope(), IteratorKwLoc,
4556 if (Kind != OMPC_depend || LangOpts.OpenMP < 51)
4559 if (Tok.is(tok::identifier) &&
4560 Tok.getIdentifierInfo()->isStr(
"omp_all_memory")) {
4562 if (
Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4563 Data.ExtraModifier == OMPC_DEPEND_inoutallmemory)
4564 Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4565 else if (
Data.ExtraModifier != OMPC_DEPEND_out &&
4566 Data.ExtraModifier != OMPC_DEPEND_inout)
4567 Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4569 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DEPEND_out
4570 ? OMPC_DEPEND_outallmemory
4571 : OMPC_DEPEND_inoutallmemory;
4587 Data.DepModOrTailExpr = Tail.
get();
4589 if (CurTok.
isNot(tok::r_paren) && CurTok.
isNot(tok::comma)) {
4590 P.
Diag(CurTok, diag::err_expected_punc) <<
"step expression";
4608 bool AllocatorSeen =
false;
4609 bool AlignSeen =
false;
4628 if (
Tok.is(tok::l_paren)) {
4629 switch (CurrentModifier) {
4630 case OMPC_ALLOCATE_allocator: {
4631 if (AllocatorSeen) {
4632 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4634 << getOpenMPClauseName(Kind);
4636 Data.AllocClauseModifiers.push_back(CurrentModifier);
4637 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4640 tok::annot_pragma_openmp_end);
4644 AllocatorSeen =
true;
4647 case OMPC_ALLOCATE_align: {
4649 P.
Diag(
Tok, diag::err_omp_duplicate_modifier)
4651 << getOpenMPClauseName(Kind);
4653 Data.AllocClauseModifiers.push_back(CurrentModifier);
4654 Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);
4658 Data.AllocateAlignment = Val.
get();
4663 llvm_unreachable(
"Unexpected allocate modifier");
4666 P.
Diag(
Tok, diag::err_expected) << tok::l_paren;
4668 if (
Tok.isNot(tok::comma))
4671 CurrentModifierLoc =
Tok.getLocation();
4676 P.
Diag(
Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);
4679 }
while (!AllocatorSeen || !AlignSeen);
4688 bool InvalidReductionId =
false;
4689 bool IsInvalidMapperModifier =
false;
4693 if (T.expectAndConsume(diag::err_expected_lparen_after,
4694 getOpenMPClauseName(Kind).data()))
4697 bool HasIterator =
false;
4698 bool InvalidIterator =
false;
4699 bool NeedRParenForLinear =
false;
4701 tok::annot_pragma_openmp_end);
4703 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4704 Kind == OMPC_in_reduction) {
4706 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 50 &&
4707 (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4710 Data.ExtraModifier =
4712 Data.ExtraModifierLoc = Tok.getLocation();
4714 assert(Tok.is(tok::comma) &&
"Expected comma.");
4718 if (Kind == OMPC_reduction &&
getLangOpts().OpenMP >= 60 &&
4719 Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"original" &&
4725 if (Tok.is(tok::kw_private)) {
4726 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
4727 Data.OriginalSharingModifierLoc = Tok.getLocation();
4729 }
else if (Tok.is(tok::identifier) &&
4730 (PP.getSpelling(Tok) ==
"shared" ||
4731 PP.getSpelling(Tok) ==
"default")) {
4732 Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
4733 Data.OriginalSharingModifierLoc = Tok.getLocation();
4736 Diag(Tok.getLocation(), diag::err_expected)
4737 <<
"'private or shared or default'";
4742 if (!Tok.is(tok::comma)) {
4743 Diag(Tok.getLocation(), diag::err_expected) <<
"',' (comma)";
4750 ParseOptionalCXXScopeSpecifier(
Data.ReductionOrMapperIdScopeSpec,
4755 *
this,
Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4756 if (InvalidReductionId) {
4757 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4760 if (Tok.is(tok::colon))
4763 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
4764 if (!InvalidReductionId)
4765 Data.ReductionOrMapperId =
4766 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4767 }
else if (Kind == OMPC_depend || Kind == OMPC_doacross) {
4769 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4778 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4779 Data.DepModOrTailExpr = IteratorRes.
get();
4781 ExpectAndConsume(tok::comma);
4787 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
4789 Data.ExtraModifierLoc = Tok.getLocation();
4791 (Kind == OMPC_doacross &&
4793 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4798 if (DKind == OMPD_ordered && Kind == OMPC_depend &&
4799 Data.ExtraModifier == OMPC_DEPEND_source) {
4805 if (Tok.is(tok::colon)) {
4807 }
else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
4808 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4809 : diag::warn_pragma_expected_colon)
4810 << (Kind == OMPC_depend ?
"dependency type" :
"dependence-type");
4812 if (Kind == OMPC_doacross) {
4813 if (Tok.is(tok::identifier) &&
4814 Tok.getIdentifierInfo()->isStr(
"omp_cur_iteration")) {
4815 Data.ExtraModifier =
Data.ExtraModifier == OMPC_DOACROSS_source
4816 ? OMPC_DOACROSS_source_omp_cur_iteration
4817 : OMPC_DOACROSS_sink_omp_cur_iteration;
4820 if (
Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
4821 if (Tok.isNot(tok::minus)) {
4822 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4823 << getOpenMPClauseName(Kind) << 0 << 0;
4830 if (Tok.isNot(tok::numeric_constant) ||
4831 (PP.parseSimpleIntegerLiteral(Tok,
Value) &&
Value != 1)) {
4832 Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
4833 << getOpenMPClauseName(Kind) << 0 << 0;
4839 if (
Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
4840 if (Tok.isNot(tok::r_paren)) {
4841 Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
4842 << getOpenMPClauseName(Kind) << 1 << 1;
4848 if (Kind == OMPC_doacross &&
4849 (
Data.ExtraModifier == OMPC_DOACROSS_source ||
4850 Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
4851 Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
4857 }
else if (Kind == OMPC_linear) {
4859 Data.ExtraModifier = OMPC_LINEAR_val;
4860 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
4861 Data.ExtraModifier =
4865 NeedRParenForLinear =
true;
4867 Diag(
Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
4868 <<
"linear-modifier(list)" << getOpenMPClauseName(Kind)
4869 <<
"linear(list: [linear-modifier,] step(step-size))";
4871 }
else if (Kind == OMPC_lastprivate) {
4878 Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
4879 Data.ExtraModifier =
4881 Data.ExtraModifierLoc = Tok.getLocation();
4883 assert(Tok.is(tok::colon) &&
"Expected colon.");
4886 }
else if (Kind == OMPC_map) {
4888 if (Tok.is(tok::identifier) && PP.getSpelling(Tok) ==
"iterator") {
4891 Data.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);
4892 Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
4893 ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4894 Data.IteratorExpr = IteratorRes.
get();
4896 ExpectAndConsume(tok::comma);
4898 Diag(Tok, diag::err_omp_unknown_map_type_modifier)
4901 InvalidIterator =
true;
4911 Data.ExtraModifierLoc = Tok.getLocation();
4914 TentativeParsingAction TPA(*
this);
4915 bool ColonPresent =
false;
4916 if (
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4918 if (Tok.is(tok::colon))
4919 ColonPresent =
true;
4926 Diag(Tok, diag::err_omp_map_modifier_specification_list);
4928 if (
getLangOpts().OpenMP < 60 && !IsInvalidMapperModifier)
4934 Data.ExtraModifier = OMPC_MAP_tofrom;
4936 if (DKind == OMPD_target_enter_data)
4937 Data.ExtraModifier = OMPC_MAP_to;
4938 else if (DKind == OMPD_target_exit_data)
4939 Data.ExtraModifier = OMPC_MAP_from;
4941 Data.IsMapTypeImplicit =
true;
4944 if (Tok.is(tok::colon))
4946 }
else if (Kind == OMPC_to || Kind == OMPC_from) {
4947 while (Tok.is(tok::identifier)) {
4952 Data.MotionModifiers.push_back(Modifier);
4953 Data.MotionModifiersLoc.push_back(Tok.getLocation());
4954 if (PP.getSpelling(Tok) ==
"iterator" &&
getLangOpts().OpenMP >= 51) {
4956 Tail = ParseOpenMPIteratorsExpr();
4957 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
4960 Data.IteratorExpr = Tail.
get();
4963 if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
4965 if (IsInvalidMapperModifier)
4973 if (Tok.is(tok::comma))
4977 if (!
Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
4978 if (!IsInvalidMapperModifier) {
4980 Diag(Tok, diag::warn_pragma_expected_colon) <<
")";
4982 Diag(Tok, diag::warn_pragma_expected_colon) <<
"motion modifier";
4984 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4992 }
else if (Kind == OMPC_allocate ||
4993 (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
4994 PP.getSpelling(Tok) ==
"iterator")) {
4998 TentativeParsingAction TPA(*
this);
5003 if (Kind == OMPC_allocate) {
5008 Tail = ParseOpenMPIteratorsExpr();
5010 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), T.getOpenLocation(),
5013 if (Tok.is(tok::colon)) {
5020 if (Kind == OMPC_allocate &&
Data.AllocClauseModifiers.size()) {
5021 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5023 Diag(Tok, diag::err_modifier_expected_colon) <<
"allocate clause";
5030 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5033 }
else if (Kind == OMPC_adjust_args) {
5037 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) :
"",
5039 Data.ExtraModifierLoc = Tok.getLocation();
5041 Diag(Tok, diag::err_omp_unknown_adjust_args_op)
5046 if (Tok.is(tok::colon))
5047 Data.ColonLoc = Tok.getLocation();
5051 if (Tok.is(tok::l_paren)) {
5054 if (Tok.is(tok::identifier)) {
5055 std::string Modifier = PP.getSpelling(Tok);
5056 if (Modifier ==
"fb_nullify" || Modifier ==
"fb_preserve") {
5057 Data.NeedDevicePtrModifier =
5058 Modifier ==
"fb_nullify" ? OMPC_NEED_DEVICE_PTR_fb_nullify
5059 : OMPC_NEED_DEVICE_PTR_fb_preserve;
5061 Diag(Tok, diag::err_omp_unknown_need_device_ptr_kind);
5062 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5067 if (Tok.is(tok::r_paren)) {
5068 Data.NeedDevicePtrModifierLoc = Tok.getLocation();
5071 Diag(Tok, diag::err_expected) << tok::r_paren;
5072 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
5081 ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
5084 }
else if (Kind == OMPC_use_device_ptr) {
5088 if (
getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
5092 Data.ExtraModifier = FallbackModifier;
5093 Data.ExtraModifierLoc = Tok.getLocation();
5095 if (Tok.is(tok::colon))
5098 Diag(Tok, diag::err_modifier_expected_colon) <<
"fallback";
5102 if (Kind == OMPC_num_teams && !Tok.is(tok::r_paren) &&
5103 !Tok.is(tok::annot_pragma_openmp_end)) {
5107 Data.RLoc = Tok.getLocation();
5108 if (!T.consumeClose())
5109 Data.RLoc = T.getCloseLocation();
5113 if (Tok.is(tok::colon)) {
5119 Data.RLoc = Tok.getLocation();
5120 if (!T.consumeClose())
5121 Data.RLoc = T.getCloseLocation();
5124 Vars.push_back(FirstExpr.
get());
5125 Vars.push_back(UpperBound.
get());
5126 Data.RLoc = Tok.getLocation();
5127 if (!T.consumeClose())
5128 Data.RLoc = T.getCloseLocation();
5131 if (Tok.is(tok::comma)) {
5132 Vars.push_back(FirstExpr.
get());
5133 while (Tok.is(tok::comma)) {
5137 Vars.push_back(NextExpr.
get());
5139 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5144 Data.RLoc = Tok.getLocation();
5145 bool HadError = T.consumeClose();
5147 Data.RLoc = T.getCloseLocation();
5152 Vars.push_back(FirstExpr.
get());
5153 Data.RLoc = Tok.getLocation();
5154 if (!T.consumeClose())
5155 Data.RLoc = T.getCloseLocation();
5160 (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
5161 Kind != OMPC_in_reduction && Kind != OMPC_depend &&
5162 Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||
5163 (Kind == OMPC_reduction && !InvalidReductionId) ||
5167 (Kind == OMPC_adjust_args &&
5169 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
5170 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
5171 Tok.isNot(tok::annot_pragma_openmp_end))) {
5178 Vars.push_back(VarExpr.
get());
5180 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5185 IsComma = Tok.is(tok::comma);
5188 else if (Tok.isNot(tok::r_paren) &&
5189 Tok.isNot(tok::annot_pragma_openmp_end) &&
5190 (!MayHaveTail || Tok.isNot(tok::colon))) {
5191 unsigned OMPVersion = Actions.getLangOpts().OpenMP;
5192 Diag(Tok, diag::err_omp_expected_punc)
5193 << ((Kind == OMPC_flush)
5194 ? getOpenMPDirectiveName(OMPD_flush, OMPVersion)
5195 : getOpenMPClauseName(Kind))
5196 << (Kind == OMPC_flush);
5201 if (NeedRParenForLinear)
5205 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
5206 bool StepFound =
false;
5207 bool ModifierFound =
false;
5209 Data.ColonLoc = Tok.getLocation();
5212 if (
getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
5213 bool Malformed =
false;
5214 while (Tok.isNot(tok::r_paren)) {
5215 if (Tok.is(tok::identifier)) {
5220 Kind, Tok.isAnnotation() ?
"" : PP.getSpelling(Tok),
5223 if (LinKind == OMPC_LINEAR_step) {
5225 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
5228 tok::annot_pragma_openmp_end);
5232 Diag(StepModifierLoc, diag::err_expected_lparen_after) <<
"step";
5237 Data.StepModifierLoc = StepModifierLoc;
5241 }
else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
5243 Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
5245 Data.ExtraModifier = LinKind;
5247 ModifierFound =
true;
5252 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5261 if (Tok.is(tok::comma))
5263 if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
5266 if (!Malformed && !StepFound && !ModifierFound)
5267 Diag(ELoc, diag::err_expected_expression);
5271 Tail = Actions.ActOnFinishFullExpr(Tail.
get(), ELoc,
5274 Data.DepModOrTailExpr = Tail.
get();
5276 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
5282 Data.RLoc = Tok.getLocation();
5283 if (!T.consumeClose())
5284 Data.RLoc = T.getCloseLocation();
5288 return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
5290 (MustHaveTail && !
Data.DepModOrTailExpr && StepFound) ||
5291 InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
5318 "Expected parsing to start at clause name");
5323 if (T.consumeOpen()) {
5324 Diag(
Tok, diag::err_expected) << tok::l_paren;
5337 Exprs.push_back(Val.
get());
5340 bool Result = T.consumeClose();
5341 OpenLoc = T.getOpenLocation();
5342 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.