diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index d647879c0dc92..6a21d5d8c79d7 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4292,14 +4292,16 @@ struct OmpPrescriptiveness { WRAPPER_CLASS_BOILERPLATE(OmpPrescriptiveness, Value); }; -// Ref: [4.5:216-219], [5.0:315-324], [5.1:347-355], [5.2:150-158], -// [6.0:279-288] +// Ref: [5.1:205-210], [6.0:279-288] // // present-modifier -> -// PRESENT // since 5.1 +// PRESENT // since 5.1, until 5.1 +// // since 6.0 // -// Until 5.2, it was a part of map-type-modifier. Since 6.0 the -// map-type-modifier has been split into individual modifiers. +// In 5.1 it was a part of "motion-modifier" (on FROM and TO clauses), which +// should really be modeled as a modifier-group. In 5.2 it was replaced by +// "expectation". It was restored in 6.0 when map-type-modifier was broken up +// into individual modifiers. struct OmpPresentModifier { ENUM_CLASS(Value, Present) WRAPPER_CLASS_BOILERPLATE(OmpPresentModifier, Value); @@ -4711,17 +4713,24 @@ struct OmpFailClause { WRAPPER_CLASS_BOILERPLATE(OmpFailClause, MemoryOrder); }; -// Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168] +// Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168], +// [6.0:298-299] // // from-clause -> -// FROM(locator-list) | -// FROM(mapper-modifier: locator-list) | // since 5.0 -// FROM(motion-modifier[,] ...: locator-list) // since 5.1 +// FROM(locator-list) | // since 4.5 +// FROM(modifier[,] ...: locator-list) | // since 5.0 +// modifier -> +// mapper | // since 5.2 +// motion-modifier | // since 5.1, until 5.1 +// expectation | mapper | iterator // since 5.2, until 5.2 +// present-modifier | mapper | iterator | // since 6.0 +// directive-name-modifier // since 6.0 // motion-modifier -> // PRESENT | mapper-modifier | iterator-modifier struct OmpFromClause { TUPLE_CLASS_BOILERPLATE(OmpFromClause); - MODIFIER_BOILERPLATE(OmpExpectation, OmpIterator, OmpMapper); + MODIFIER_BOILERPLATE( + OmpExpectation, OmpPresentModifier, OmpIterator, OmpMapper); std::tuple t; }; @@ -5070,18 +5079,25 @@ struct OmpThreadsetClause { }; // Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168] +// [6.0:297-298] // // to-clause (in DECLARE TARGET) -> -// TO(extended-list) | // until 5.1 +// TO(extended-list) | // since 4.5, until 5.1 // to-clause (in TARGET UPDATE) -> -// TO(locator-list) | -// TO(mapper-modifier: locator-list) | // since 5.0 -// TO(motion-modifier[,] ...: locator-list) // since 5.1 -// motion-modifier -> +// TO(locator-list) | // since 4.5 +// TO(modifier[,] ...: locator-list) | // since 5.0 +// modifier -> +// mapper | // since 5.2 +// motion-modifier | // since 5.1, until 5.1 +// expectation | mapper | iterator // since 5.2, until 5.2 +// present-modifier | mapper | iterator | // since 6.0 +// directive-name-modifier // since 6.0 +// motion-modifier -> // PRESENT | mapper-modifier | iterator-modifier struct OmpToClause { TUPLE_CLASS_BOILERPLATE(OmpToClause); - MODIFIER_BOILERPLATE(OmpExpectation, OmpIterator, OmpMapper); + MODIFIER_BOILERPLATE( + OmpExpectation, OmpPresentModifier, OmpIterator, OmpMapper); std::tuple t; }; diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 1b9ce1401118e..0d315c218770a 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -974,7 +974,13 @@ From make(const parser::OmpClause::From &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpFromClause CLAUSET_ENUM_CONVERT( // - convert, parser::OmpExpectation::Value, From::Expectation, + convertExp, parser::OmpExpectation::Value, From::Expectation, + // clang-format off + MS(Present, Present) + // clang-format on + ); + CLAUSET_ENUM_CONVERT( // + convertPre, parser::OmpPresentModifier::Value, From::Expectation, // clang-format off MS(Present, Present) // clang-format on @@ -982,26 +988,32 @@ From make(const parser::OmpClause::From &inp, auto &mods = semantics::OmpGetModifiers(inp.v); auto *t0 = semantics::OmpGetUniqueModifier(mods); - auto *t1 = semantics::OmpGetUniqueModifier(mods); - auto *t2 = semantics::OmpGetUniqueModifier(mods); - auto &t3 = std::get(inp.v.t); + auto *t1 = semantics::OmpGetUniqueModifier(mods); + auto *t2 = semantics::OmpGetUniqueModifier(mods); + auto *t3 = semantics::OmpGetUniqueModifier(mods); + auto &t4 = std::get(inp.v.t); + + std::optional maybeExp = // + t0 ? maybeApplyToV(convertExp, t0) + : t1 ? maybeApplyToV(convertPre, t1) + : std::optional{}; auto mappers = [&]() -> std::optional> { - if (t1) - return List{Mapper{makeObject(t1->v, semaCtx)}}; + if (t2) + return List{Mapper{makeObject(t2->v, semaCtx)}}; return std::nullopt; }(); auto iterator = [&]() -> std::optional { - if (t2) - return makeIterator(*t2, semaCtx); + if (t3) + return makeIterator(*t3, semaCtx); return std::nullopt; }(); - return From{{/*Expectation=*/maybeApplyToV(convert, t0), + return From{{/*Expectation=*/maybeExp, /*Mappers=*/std::move(mappers), /*Iterator=*/std::move(iterator), - /*LocatorList=*/makeObjects(t3, semaCtx)}}; + /*LocatorList=*/makeObjects(t4, semaCtx)}}; } // Full: empty @@ -1694,7 +1706,13 @@ To make(const parser::OmpClause::To &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpToClause CLAUSET_ENUM_CONVERT( // - convert, parser::OmpExpectation::Value, To::Expectation, + convertExp, parser::OmpExpectation::Value, To::Expectation, + // clang-format off + MS(Present, Present) + // clang-format on + ); + CLAUSET_ENUM_CONVERT( // + convertPre, parser::OmpPresentModifier::Value, To::Expectation, // clang-format off MS(Present, Present) // clang-format on @@ -1702,26 +1720,32 @@ To make(const parser::OmpClause::To &inp, auto &mods = semantics::OmpGetModifiers(inp.v); auto *t0 = semantics::OmpGetUniqueModifier(mods); - auto *t1 = semantics::OmpGetUniqueModifier(mods); - auto *t2 = semantics::OmpGetUniqueModifier(mods); - auto &t3 = std::get(inp.v.t); + auto *t1 = semantics::OmpGetUniqueModifier(mods); + auto *t2 = semantics::OmpGetUniqueModifier(mods); + auto *t3 = semantics::OmpGetUniqueModifier(mods); + auto &t4 = std::get(inp.v.t); + + std::optional maybeExp = // + t0 ? maybeApplyToV(convertExp, t0) + : t1 ? maybeApplyToV(convertPre, t1) + : std::optional{}; auto mappers = [&]() -> std::optional> { - if (t1) - return List{Mapper{makeObject(t1->v, semaCtx)}}; + if (t2) + return List{Mapper{makeObject(t2->v, semaCtx)}}; return std::nullopt; }(); auto iterator = [&]() -> std::optional { - if (t2) - return makeIterator(*t2, semaCtx); + if (t3) + return makeIterator(*t3, semaCtx); return std::nullopt; }(); - return To{{/*Expectation=*/maybeApplyToV(convert, t0), + return To{{/*Expectation=*/maybeExp, /*Mappers=*/{std::move(mappers)}, /*Iterator=*/std::move(iterator), - /*LocatorList=*/makeObjects(t3, semaCtx)}}; + /*LocatorList=*/makeObjects(t4, semaCtx)}}; } UnifiedAddress make(const parser::OmpClause::UnifiedAddress &inp, diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index ad74cb84aa8bf..7c4e49a673bb0 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1088,10 +1088,27 @@ TYPE_PARSER( TYPE_PARSER( sourced(construct(Parser{}))) -TYPE_PARSER(sourced(construct( - sourced(construct(Parser{}) || - construct(Parser{}) || - construct(Parser{}))))) +template struct OmpMotionClauseModifierParser { + using resultType = typename MotionClause::Modifier; + + std::optional Parse(ParseState &state) const { + unsigned version{state.userState()->langOptions().OpenMPVersion}; + if (version == 52) { + auto expect{sourced(construct(Parser{}))}; + if (auto &&result{attempt(expect).Parse(state)}) { + return std::move(result); + } + } + auto parser{sourced( // + construct(Parser{}) || + construct(Parser{}) || + construct(Parser{}))}; + return parser.Parse(state); + } +}; + +TYPE_PARSER(OmpMotionClauseModifierParser{}) +TYPE_PARSER(OmpMotionClauseModifierParser{}) TYPE_PARSER(sourced( construct(Parser{}))) @@ -1176,11 +1193,6 @@ TYPE_PARSER(sourced(construct( TYPE_PARSER(sourced( construct(Parser{}))) -TYPE_PARSER(sourced(construct( - sourced(construct(Parser{}) || - construct(Parser{}) || - construct(Parser{}))))) - TYPE_PARSER(sourced(construct( // Parser{}))) diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp index 972788aff1247..293136d3649ad 100644 --- a/flang/lib/Semantics/openmp-modifiers.cpp +++ b/flang/lib/Semantics/openmp-modifiers.cpp @@ -361,11 +361,12 @@ const OmpModifierDescriptor &OmpGetDescriptor() { /*name=*/"expectation", /*props=*/ { - {51, {OmpProperty::Unique}}, + {52, {OmpProperty::Unique}}, }, /*clauses=*/ { - {51, {Clause::OMPC_from, Clause::OMPC_to}}, + {52, {Clause::OMPC_from, Clause::OMPC_to}}, + {60, {}}, }, }; return desc; @@ -629,7 +630,9 @@ const OmpModifierDescriptor &OmpGetDescriptor() { }, /*clauses=*/ { - {51, {Clause::OMPC_map}}, + {51, {Clause::OMPC_from, Clause::OMPC_to}}, + {52, {}}, + {60, {Clause::OMPC_from, Clause::OMPC_map, Clause::OMPC_to}}, }, }; return desc; diff --git a/flang/test/Semantics/OpenMP/from-clause-v45.f90 b/flang/test/Semantics/OpenMP/from-clause-v45.f90 index 654af4b7dd9b7..284511acfdd59 100644 --- a/flang/test/Semantics/OpenMP/from-clause-v45.f90 +++ b/flang/test/Semantics/OpenMP/from-clause-v45.f90 @@ -14,16 +14,16 @@ subroutine f01(x) subroutine f02(x) integer :: x(10) -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 !WARNING: 'iterator' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 !$omp target update from(present, iterator(i = 1:5): x(i)) end subroutine f03(x) integer :: x(10) -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 -!ERROR: 'expectation' modifier cannot occur multiple times +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!ERROR: 'present-modifier' modifier cannot occur multiple times !$omp target update from(present, present: x) end diff --git a/flang/test/Semantics/OpenMP/from-clause-v51.f90 b/flang/test/Semantics/OpenMP/from-clause-v51.f90 index 8771f519fec03..60252a8a1745c 100644 --- a/flang/test/Semantics/OpenMP/from-clause-v51.f90 +++ b/flang/test/Semantics/OpenMP/from-clause-v51.f90 @@ -8,7 +8,7 @@ subroutine f01(x) subroutine f03(x) integer :: x(10) -!ERROR: 'expectation' modifier cannot occur multiple times +!ERROR: 'present-modifier' modifier cannot occur multiple times !$omp target update from(present, present: x) end diff --git a/flang/test/Semantics/OpenMP/to-clause-v45.f90 b/flang/test/Semantics/OpenMP/to-clause-v45.f90 index 7e56817e1ff7c..2fff681d621b1 100644 --- a/flang/test/Semantics/OpenMP/to-clause-v45.f90 +++ b/flang/test/Semantics/OpenMP/to-clause-v45.f90 @@ -14,16 +14,16 @@ subroutine f01(x) subroutine f02(x) integer :: x(10) -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 !WARNING: 'iterator' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 !$omp target update to(present, iterator(i = 1:5): x(i)) end subroutine f03(x) integer :: x(10) -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 -!ERROR: 'expectation' modifier cannot occur multiple times +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!ERROR: 'present-modifier' modifier cannot occur multiple times !$omp target update to(present, present: x) end diff --git a/flang/test/Semantics/OpenMP/to-clause-v51.f90 b/flang/test/Semantics/OpenMP/to-clause-v51.f90 index 0db292a22238b..15e742c1ece22 100644 --- a/flang/test/Semantics/OpenMP/to-clause-v51.f90 +++ b/flang/test/Semantics/OpenMP/to-clause-v51.f90 @@ -8,7 +8,7 @@ subroutine f01(x) subroutine f03(x) integer :: x(10) -!ERROR: 'expectation' modifier cannot occur multiple times +!ERROR: 'present-modifier' modifier cannot occur multiple times !$omp target update to(present, present: x) end