diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-18 20:30:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-06 20:11:55 +0000 |
commit | 5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch) | |
tree | 1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp | |
parent | 3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff) | |
parent | 312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp | 205 |
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', |