aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-18 20:30:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-06 20:11:55 +0000
commit5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch)
tree1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp
parent3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff)
parent312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp205
1 files changed, 186 insertions, 19 deletions
diff --git a/contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp b/contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp
index 96d2e2cede62..da5f6605c6ff 100644
--- a/contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp
+++ b/contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp
@@ -2418,6 +2418,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
case OMPD_distribute_simd:
case OMPD_target_parallel_for_simd:
case OMPD_target_simd:
+ case OMPD_scope:
case OMPD_teams_distribute:
case OMPD_teams_distribute_simd:
case OMPD_teams_distribute_parallel_for_simd:
@@ -2517,15 +2518,18 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
switch (DKind) {
case OMPD_nothing:
- if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
- ParsedStmtContext())
- Diag(Tok, diag::err_omp_immediate_directive)
- << getOpenMPDirectiveName(DKind) << 0;
ConsumeToken();
- skipUntilPragmaOpenMPEnd(DKind);
+ // If we are parsing the directive within a metadirective, the directive
+ // ends with a ')'.
+ if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren))
+ while (Tok.isNot(tok::annot_pragma_openmp_end))
+ ConsumeAnyToken();
+ else
+ skipUntilPragmaOpenMPEnd(DKind);
if (Tok.is(tok::annot_pragma_openmp_end))
ConsumeAnnotationToken();
- break;
+ // return an empty statement
+ return StmtEmpty();
case OMPD_metadirective: {
ConsumeToken();
SmallVector<VariantMatchInfo, 4> VMIs;
@@ -2669,7 +2673,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
}
case OMPD_threadprivate: {
// FIXME: Should this be permitted in C++?
- if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
+ if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
ParsedStmtContext()) {
Diag(Tok, diag::err_omp_immediate_directive)
<< getOpenMPDirectiveName(DKind) << 0;
@@ -2688,7 +2692,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
}
case OMPD_allocate: {
// FIXME: Should this be permitted in C++?
- if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
+ if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
ParsedStmtContext()) {
Diag(Tok, diag::err_omp_immediate_directive)
<< getOpenMPDirectiveName(DKind) << 0;
@@ -2810,6 +2814,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
case OMPD_target_teams_loop:
case OMPD_parallel_loop:
case OMPD_target_parallel_loop:
+ case OMPD_scope:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_master_taskloop:
@@ -3246,6 +3251,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
else
Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
break;
+ case OMPC_fail:
case OMPC_default:
case OMPC_proc_bind:
case OMPC_atomic_default_mem_order:
@@ -3367,6 +3373,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_exclusive:
case OMPC_affinity:
case OMPC_doacross:
+ case OMPC_enter:
if (getLangOpts().OpenMP >= 52 && DKind == OMPD_ordered &&
CKind == OMPC_depend)
Diag(Tok, diag::warn_omp_depend_in_ordered_deprecated);
@@ -3411,6 +3418,20 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
break;
+ case OMPC_ompx_attribute:
+ Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
+ break;
+ case OMPC_ompx_bare:
+ if (WrongDirective)
+ Diag(Tok, diag::note_ompx_bare_clause)
+ << getOpenMPClauseName(CKind) << "target teams";
+ if (!ErrorFound && !getLangOpts().OpenMPExtensions) {
+ Diag(Tok, diag::err_omp_unexpected_clause_extension_only)
+ << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
+ ErrorFound = true;
+ }
+ Clause = ParseOpenMPClause(CKind, WrongDirective);
+ break;
default:
break;
}
@@ -3691,6 +3712,63 @@ OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
llvm_unreachable("Unexpected interop variable clause.");
}
+OMPClause *Parser::ParseOpenMPOMPXAttributesClause(bool ParseOnly) {
+ SourceLocation Loc = ConsumeToken();
+ // Parse '('.
+ BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
+ if (T.expectAndConsume(diag::err_expected_lparen_after,
+ getOpenMPClauseName(OMPC_ompx_attribute).data()))
+ return nullptr;
+
+ ParsedAttributes ParsedAttrs(AttrFactory);
+ ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
+
+ // Parse ')'.
+ if (T.consumeClose())
+ return nullptr;
+
+ if (ParseOnly)
+ return nullptr;
+
+ SmallVector<Attr *> Attrs;
+ for (const ParsedAttr &PA : ParsedAttrs) {
+ switch (PA.getKind()) {
+ case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
+ if (!PA.checkExactlyNumArgs(Actions, 2))
+ continue;
+ if (auto *A = Actions.CreateAMDGPUFlatWorkGroupSizeAttr(
+ PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
+ Attrs.push_back(A);
+ continue;
+ case ParsedAttr::AT_AMDGPUWavesPerEU:
+ if (!PA.checkAtLeastNumArgs(Actions, 1) ||
+ !PA.checkAtMostNumArgs(Actions, 2))
+ continue;
+ if (auto *A = Actions.CreateAMDGPUWavesPerEUAttr(
+ PA, PA.getArgAsExpr(0),
+ PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) : nullptr))
+ Attrs.push_back(A);
+ continue;
+ case ParsedAttr::AT_CUDALaunchBounds:
+ if (!PA.checkAtLeastNumArgs(Actions, 1) ||
+ !PA.checkAtMostNumArgs(Actions, 2))
+ continue;
+ if (auto *A = Actions.CreateLaunchBoundsAttr(
+ PA, PA.getArgAsExpr(0),
+ PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) : nullptr,
+ PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) : nullptr))
+ Attrs.push_back(A);
+ continue;
+ default:
+ Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
+ continue;
+ };
+ }
+
+ return Actions.ActOnOpenMPXAttributeClause(Attrs, Loc, T.getOpenLocation(),
+ T.getCloseLocation());
+}
+
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
///
/// default-clause:
@@ -4125,6 +4203,10 @@ bool Parser::parseMapTypeModifiers(Sema::OpenMPVarListDataTy &Data) {
TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
Data.MapTypeModifiers.push_back(TypeModifier);
Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
+ if (PP.LookAhead(0).isNot(tok::comma) &&
+ PP.LookAhead(0).isNot(tok::colon) && getLangOpts().OpenMP >= 52)
+ Diag(Tok.getLocation(), diag::err_omp_missing_comma)
+ << "map type modifier";
ConsumeToken();
} else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
Data.MapTypeModifiers.push_back(TypeModifier);
@@ -4132,6 +4214,11 @@ bool Parser::parseMapTypeModifiers(Sema::OpenMPVarListDataTy &Data) {
ConsumeToken();
if (parseMapperModifier(Data))
return true;
+ if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
+ getLangOpts().OpenMP >= 52)
+ Diag(Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
+ << "map type modifier";
+
} else {
// For the case of unknown map-type-modifier or a map-type.
// Map-type is followed by a colon; the function returns when it
@@ -4319,6 +4406,25 @@ bool Parser::ParseOpenMPReservedLocator(OpenMPClauseKind Kind,
return false;
}
+/// Parse step size expression. Returns true if parsing is successfull,
+/// otherwise returns false.
+static bool parseStepSize(Parser &P, Sema::OpenMPVarListDataTy &Data,
+ OpenMPClauseKind CKind, SourceLocation ELoc) {
+ ExprResult Tail = P.ParseAssignmentExpression();
+ Sema &Actions = P.getActions();
+ Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc,
+ /*DiscardedValue*/ false);
+ if (Tail.isUsable()) {
+ Data.DepModOrTailExpr = Tail.get();
+ Token CurTok = P.getCurToken();
+ if (CurTok.isNot(tok::r_paren) && CurTok.isNot(tok::comma)) {
+ P.Diag(CurTok, diag::err_expected_punc) << "step expression";
+ }
+ return true;
+ }
+ return false;
+}
+
/// Parses clauses with list.
bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
OpenMPClauseKind Kind,
@@ -4472,6 +4578,10 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
Data.ExtraModifierLoc = ConsumeToken();
LinearT.consumeOpen();
NeedRParenForLinear = true;
+ if (getLangOpts().OpenMP >= 52)
+ Diag(Data.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)
+ << "linear-modifier(list)" << getOpenMPClauseName(Kind)
+ << "linear(list: [linear-modifier,] step(step-size))";
}
} else if (Kind == OMPC_lastprivate) {
// Try to parse modifier if any.
@@ -4681,19 +4791,76 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
if (NeedRParenForLinear)
LinearT.consumeClose();
- // Parse ':' linear-step (or ':' alignment).
+ // Parse ':' linear modifiers (val, uval, ref or step(step-size))
+ // or parse ':' alignment.
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
+ bool StepFound = false;
+ bool ModifierFound = false;
if (MustHaveTail) {
Data.ColonLoc = Tok.getLocation();
SourceLocation ELoc = ConsumeToken();
- ExprResult Tail = ParseAssignmentExpression();
- Tail =
- Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
- if (Tail.isUsable())
- Data.DepModOrTailExpr = Tail.get();
- else
- SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
- StopBeforeMatch);
+
+ if (getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
+ while (Tok.isNot(tok::r_paren)) {
+ if (Tok.is(tok::identifier)) {
+ // identifier could be a linear kind (val, uval, ref) or step
+ // modifier or step size
+ OpenMPLinearClauseKind LinKind =
+ static_cast<OpenMPLinearClauseKind>(getOpenMPSimpleClauseType(
+ Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
+ getLangOpts()));
+
+ if (LinKind == OMPC_LINEAR_step) {
+ if (StepFound)
+ Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
+
+ BalancedDelimiterTracker StepT(*this, tok::l_paren,
+ tok::annot_pragma_openmp_end);
+ SourceLocation StepModifierLoc = ConsumeToken();
+ // parse '('
+ if (StepT.consumeOpen())
+ Diag(StepModifierLoc, diag::err_expected_lparen_after) << "step";
+
+ // parse step size expression
+ StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation());
+ if (StepFound)
+ Data.StepModifierLoc = StepModifierLoc;
+
+ // parse ')'
+ StepT.consumeClose();
+ } else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
+ if (ModifierFound)
+ Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
+
+ Data.ExtraModifier = LinKind;
+ Data.ExtraModifierLoc = ConsumeToken();
+ ModifierFound = true;
+ } else {
+ StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation());
+ }
+ } else {
+ // parse an integer expression as step size
+ StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation());
+ }
+
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
+ break;
+ }
+ if (!StepFound && !ModifierFound)
+ Diag(ELoc, diag::err_expected_expression);
+ } else {
+ // for OMPC_aligned and OMPC_linear (with OpenMP <= 5.1)
+ ExprResult Tail = ParseAssignmentExpression();
+ Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc,
+ /*DiscardedValue*/ false);
+ if (Tail.isUsable())
+ Data.DepModOrTailExpr = Tail.get();
+ else
+ SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
+ }
}
// Parse ')'.
@@ -4705,8 +4872,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
ExitScope();
return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
Vars.empty()) ||
- (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId ||
- IsInvalidMapperModifier || InvalidIterator;
+ (MustHaveTail && !Data.DepModOrTailExpr && StepFound) ||
+ InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
}
/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',