diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index 2e90f19dc2e62..c5cb8c8fdf40b 100644 --- a/flang/examples/FeatureList/FeatureList.cpp +++ b/flang/examples/FeatureList/FeatureList.cpp @@ -488,7 +488,9 @@ struct NodeVisitor { READ_FEATURE(OmpEndLoopDirective) READ_FEATURE(OmpEndSectionsDirective) READ_FEATURE(OmpGrainsizeClause) - READ_FEATURE(OmpGrainsizeClause::Prescriptiveness) + READ_FEATURE(OmpGrainsizeClause::Modifier) + READ_FEATURE(OmpPrescriptiveness) + READ_FEATURE(OmpPrescriptiveness::Value) READ_FEATURE(OmpIfClause) READ_FEATURE(OmpIfClause::DirectiveNameModifier) READ_FEATURE(OmpLinearClause) @@ -500,7 +502,7 @@ struct NodeVisitor { READ_FEATURE(OmpMapClause) READ_FEATURE(OmpMapClause::Modifier) READ_FEATURE(OmpNumTasksClause) - READ_FEATURE(OmpNumTasksClause::Prescriptiveness) + READ_FEATURE(OmpNumTasksClause::Modifier) READ_FEATURE(OmpObject) READ_FEATURE(OmpObjectList) READ_FEATURE(OmpOrderClause) diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 958793d62338a..1144a6b946c70 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -536,6 +536,7 @@ class ParseTreeDumper { NODE(OmpDoacross, Source) NODE(parser, OmpDependClause) NODE(OmpDependClause, TaskDep) + NODE(OmpDependClause::TaskDep, Modifier) NODE(parser, OmpDetachClause) NODE(parser, OmpDoacrossClause) NODE(parser, OmpDestroyClause) @@ -574,9 +575,11 @@ class ParseTreeDumper { NODE(parser, OmpOrderModifier) NODE_ENUM(OmpOrderModifier, Value) NODE(parser, OmpGrainsizeClause) - NODE_ENUM(OmpGrainsizeClause, Prescriptiveness) + NODE(OmpGrainsizeClause, Modifier) + NODE(parser, OmpPrescriptiveness) + NODE_ENUM(OmpPrescriptiveness, Value) NODE(parser, OmpNumTasksClause) - NODE_ENUM(OmpNumTasksClause, Prescriptiveness) + NODE(OmpNumTasksClause, Modifier) NODE(parser, OmpBindClause) NODE_ENUM(OmpBindClause, Binding) NODE(parser, OmpProcBindClause) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 844f34c8780a0..9f5af4b366313 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3627,6 +3627,15 @@ struct OmpOrderModifier { WRAPPER_CLASS_BOILERPLATE(OmpOrderModifier, Value); }; +// Ref: [5.1:166-171], [5.2:269-270] +// +// prescriptiveness -> +// STRICT // since 5.1 +struct OmpPrescriptiveness { + ENUM_CLASS(Value, Strict) + WRAPPER_CLASS_BOILERPLATE(OmpPrescriptiveness, Value); +}; + // Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124] // // reduction-identifier -> @@ -3816,8 +3825,8 @@ struct OmpDependClause { struct TaskDep { OmpTaskDependenceType::Value GetTaskDepType() const; TUPLE_CLASS_BOILERPLATE(TaskDep); - std::tuple, OmpTaskDependenceType, OmpObjectList> - t; + MODIFIER_BOILERPLATE(OmpIterator, OmpTaskDependenceType); + std::tuple t; }; std::variant u; }; @@ -3878,11 +3887,15 @@ struct OmpFromClause { std::tuple t; }; -// OMP 5.2 12.6.1 grainsize-clause -> grainsize ([prescriptiveness :] value) +// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:269] +// +// grainsize-clause -> +// GRAINSIZE(grain-size) | // since 4.5 +// GRAINSIZE([prescriptiveness:] grain-size) // since 5.1 struct OmpGrainsizeClause { TUPLE_CLASS_BOILERPLATE(OmpGrainsizeClause); - ENUM_CLASS(Prescriptiveness, Strict); - std::tuple, ScalarIntExpr> t; + MODIFIER_BOILERPLATE(OmpPrescriptiveness); + std::tuple t; }; // 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr) @@ -3948,6 +3961,17 @@ struct OmpMapClause { std::tuple t; }; +// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270] +// +// num-tasks-clause -> +// NUM_TASKS(num-tasks) | // since 4.5 +// NUM_TASKS([prescriptiveness:] num-tasks) // since 5.1 +struct OmpNumTasksClause { + TUPLE_CLASS_BOILERPLATE(OmpNumTasksClause); + MODIFIER_BOILERPLATE(OmpPrescriptiveness); + std::tuple t; +}; + // Ref: [5.0:101-109], [5.1:126-134], [5.2:233-234] // // order-clause -> @@ -4015,13 +4039,6 @@ struct OmpToClause { std::tuple t; }; -// OMP 5.2 12.6.2 num_tasks-clause -> num_tasks ([prescriptiveness :] value) -struct OmpNumTasksClause { - TUPLE_CLASS_BOILERPLATE(OmpNumTasksClause); - ENUM_CLASS(Prescriptiveness, Strict); - std::tuple, ScalarIntExpr> t; -}; - // Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322] // // update-clause -> @@ -4030,6 +4047,7 @@ struct OmpNumTasksClause { // UPDATE(task-dependence-type) // since 5.2 struct OmpUpdateClause { UNION_CLASS_BOILERPLATE(OmpUpdateClause); + // The dependence type is an argument here, not a modifier. std::variant u; }; diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h index fab4b38090b04..dbc554198df21 100644 --- a/flang/include/flang/Semantics/openmp-modifiers.h +++ b/flang/include/flang/Semantics/openmp-modifiers.h @@ -82,6 +82,7 @@ DECLARE_DESCRIPTOR(parser::OmpMapType); DECLARE_DESCRIPTOR(parser::OmpMapTypeModifier); DECLARE_DESCRIPTOR(parser::OmpOrderModifier); DECLARE_DESCRIPTOR(parser::OmpOrderingModifier); +DECLARE_DESCRIPTOR(parser::OmpPrescriptiveness); DECLARE_DESCRIPTOR(parser::OmpReductionIdentifier); DECLARE_DESCRIPTOR(parser::OmpReductionModifier); DECLARE_DESCRIPTOR(parser::OmpTaskDependenceType); diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 2792232253879..ff2667983d436 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -369,6 +369,15 @@ clause::DependenceType makeDepType(const parser::OmpTaskDependenceType &inp) { llvm_unreachable("Unexpected task dependence type"); } +clause::Prescriptiveness +makePrescriptiveness(parser::OmpPrescriptiveness::Value v) { + switch (v) { + case parser::OmpPrescriptiveness::Value::Strict: + return clause::Prescriptiveness::Strict; + } + llvm_unreachable("Unexpected prescriptiveness"); +} + // -------------------------------------------------------------------- // Actual clauses. Each T (where tomp::T exists in ClauseT) has its "make". @@ -615,15 +624,18 @@ Depend make(const parser::OmpClause::Depend &inp, using Variant = decltype(Depend::u); auto visitTaskDep = [&](const wrapped::TaskDep &s) -> Variant { - auto &t0 = std::get>(s.t); - auto &t1 = std::get(s.t); - auto &t2 = std::get(s.t); + auto &mods = semantics::OmpGetModifiers(s); + auto *m0 = semantics::OmpGetUniqueModifier(mods); + auto *m1 = + semantics::OmpGetUniqueModifier(mods); + auto &t1 = std::get(s.t); + assert(m1 && "expecting task dependence type"); auto &&maybeIter = - maybeApply([&](auto &&s) { return makeIterator(s, semaCtx); }, t0); - return Depend::TaskDep{{/*DependenceType=*/makeDepType(t1), + m0 ? makeIterator(*m0, semaCtx) : std::optional{}; + return Depend::TaskDep{{/*DependenceType=*/makeDepType(*m1), /*Iterator=*/std::move(maybeIter), - /*LocatorList=*/makeObjects(t2, semaCtx)}}; + /*LocatorList=*/makeObjects(t1, semaCtx)}}; }; return Depend{common::visit( // @@ -785,19 +797,12 @@ From make(const parser::OmpClause::From &inp, Grainsize make(const parser::OmpClause::Grainsize &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpGrainsizeClause - using wrapped = parser::OmpGrainsizeClause; - - CLAUSET_ENUM_CONVERT( // - convert, parser::OmpGrainsizeClause::Prescriptiveness, - Grainsize::Prescriptiveness, - // clang-format off - MS(Strict, Strict) - // clang-format on - ); - auto &t0 = std::get>(inp.v.t); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *m0 = semantics::OmpGetUniqueModifier(mods); auto &t1 = std::get(inp.v.t); - return Grainsize{{/*Prescriptiveness=*/maybeApply(convert, t0), - /*Grainsize=*/makeExpr(t1, semaCtx)}}; + return Grainsize{ + {/*Prescriptiveness=*/maybeApplyToV(makePrescriptiveness, m0), + /*Grainsize=*/makeExpr(t1, semaCtx)}}; } HasDeviceAddr make(const parser::OmpClause::HasDeviceAddr &inp, @@ -1047,18 +1052,10 @@ Novariants make(const parser::OmpClause::Novariants &inp, NumTasks make(const parser::OmpClause::NumTasks &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpNumTasksClause - using wrapped = parser::OmpNumTasksClause; - - CLAUSET_ENUM_CONVERT( // - convert, parser::OmpNumTasksClause::Prescriptiveness, - NumTasks::Prescriptiveness, - // clang-format off - MS(Strict, Strict) - // clang-format on - ); - auto &t0 = std::get>(inp.v.t); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *m0 = semantics::OmpGetUniqueModifier(mods); auto &t1 = std::get(inp.v.t); - return NumTasks{{/*Prescriptiveness=*/maybeApply(convert, t0), + return NumTasks{{/*Prescriptiveness=*/maybeApplyToV(makePrescriptiveness, m0), /*NumTasks=*/makeExpr(t1, semaCtx)}}; } diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h index 562685e43c13b..65282d243d87a 100644 --- a/flang/lib/Lower/OpenMP/Clauses.h +++ b/flang/lib/Lower/OpenMP/Clauses.h @@ -176,6 +176,7 @@ using DefinedOperator = tomp::type::DefinedOperatorT; using ProcedureDesignator = tomp::type::ProcedureDesignatorT; using ReductionOperator = tomp::type::ReductionIdentifierT; using DependenceType = tomp::type::DependenceType; +using Prescriptiveness = tomp::type::Prescriptiveness; // "Requires" clauses are handled early on, and the aggregated information // is stored in the Symbol details of modules, programs, and subprograms. diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 686f1c5d69c2e..023cbb31fb9b6 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -176,6 +176,9 @@ TYPE_PARSER(construct( "NONMONOTONIC" >> pure(OmpOrderingModifier::Value::Nonmonotonic) || "SIMD" >> pure(OmpOrderingModifier::Value::Simd))) +TYPE_PARSER(construct( + "STRICT" >> pure(OmpPrescriptiveness::Value::Strict))) + TYPE_PARSER(construct( "INSCAN" >> pure(OmpReductionModifier::Value::Inscan) || "TASK" >> pure(OmpReductionModifier::Value::Task) || @@ -213,6 +216,11 @@ TYPE_PARSER(sourced(construct(sourced( TYPE_PARSER(sourced( construct(Parser{}))) +TYPE_PARSER(sourced(construct(sourced( + construct(Parser{}) || + construct( + Parser{}))))) + TYPE_PARSER( sourced(construct(Parser{}))) @@ -221,6 +229,9 @@ TYPE_PARSER(sourced(construct( construct(Parser{}) || construct(Parser{}))))) +TYPE_PARSER(sourced( + construct(Parser{}))) + TYPE_PARSER(sourced(construct( sourced(construct(Parser{}) || construct(Parser{}) || @@ -230,6 +241,9 @@ TYPE_PARSER(sourced(construct( TYPE_PARSER( sourced(construct(Parser{}))) +TYPE_PARSER(sourced( + construct(Parser{}))) + TYPE_PARSER(sourced(construct(sourced( construct(Parser{}) || construct( @@ -382,10 +396,16 @@ TYPE_PARSER(construct( TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US, construct( + // Try to parse OmpDoacross first, because TaskDep will succeed on + // "sink: xxx", interpreting it to not have any modifiers, and "sink" + // being an OmpObject. Parsing of the TaskDep variant will stop right + // after the "sink", leaving the ": xxx" unvisited. + construct(Parser{}) || + // Parse TaskDep after Doacross. construct(construct( - maybe(Parser{} / ","_tok), - Parser{} / ":", Parser{})) || - construct(Parser{}))) + maybe(nonemptyList(Parser{}) / + ": "), + Parser{})))) TYPE_CONTEXT_PARSER("Omp Doacross clause"_en_US, construct(Parser{})) @@ -427,12 +447,12 @@ TYPE_PARSER(construct( // OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression) TYPE_PARSER(construct( - maybe("STRICT" >> pure(OmpGrainsizeClause::Prescriptiveness::Strict) / ":"), + maybe(nonemptyList(Parser{}) / ":"), scalarIntExpr)) // OMP 5.2 12.6.2 num_tasks([ prescriptiveness :] scalar-integer-expression) TYPE_PARSER(construct( - maybe("STRICT" >> pure(OmpNumTasksClause::Prescriptiveness::Strict) / ":"), + maybe(nonemptyList(Parser{}) / ":"), scalarIntExpr)) TYPE_PARSER( diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp index 24b2902f286f4..a414f226058e3 100644 --- a/flang/lib/Parser/parse-tree.cpp +++ b/flang/lib/Parser/parse-tree.cpp @@ -267,7 +267,18 @@ OmpDependenceType::Value OmpDoacross::GetDepType() const { } OmpTaskDependenceType::Value OmpDependClause::TaskDep::GetTaskDepType() const { - return std::get(t).v; + using Modifier = OmpDependClause::TaskDep::Modifier; + auto &modifiers{std::get>>(t)}; + if (modifiers) { + for (auto &m : *modifiers) { + if (auto *dep{std::get_if(&m.u)}) { + return dep->v; + } + } + llvm_unreachable("expecting OmpTaskDependenceType in TaskDep"); + } else { + llvm_unreachable("expecting modifiers on OmpDependClause::TaskDep"); + } } } // namespace Fortran::parser diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index eee1420500ce2..bde0e18d1d4c0 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2171,13 +2171,13 @@ class UnparseVisitor { Walk(std::get(x.t)); } void Unparse(const OmpGrainsizeClause &x) { - Walk(std::get>(x.t), - ":"); + using Modifier = OmpGrainsizeClause::Modifier; + Walk(std::get>>(x.t), ": "); Walk(std::get(x.t)); } void Unparse(const OmpNumTasksClause &x) { - Walk( - std::get>(x.t), ":"); + using Modifier = OmpNumTasksClause::Modifier; + Walk(std::get>>(x.t), ": "); Walk(std::get(x.t)); } void Unparse(const OmpDoacross::Sink &x) { @@ -2186,8 +2186,8 @@ class UnparseVisitor { } void Unparse(const OmpDoacross::Source &) { Word("SOURCE"); } void Unparse(const OmpDependClause::TaskDep &x) { - Walk(std::get(x.t)); - Put(":"); + using Modifier = OmpDependClause::TaskDep::Modifier; + Walk(std::get>>(x.t), ": "); Walk(std::get(x.t)); } void Unparse(const OmpDefaultmapClause &x) { @@ -2853,9 +2853,7 @@ class UnparseVisitor { WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type WALK_NESTED_ENUM(OmpOrderClause, Ordering) // OMP ordering WALK_NESTED_ENUM(OmpOrderModifier, Value) // OMP order-modifier - WALK_NESTED_ENUM( - OmpGrainsizeClause, Prescriptiveness) // OMP grainsize-modifier - WALK_NESTED_ENUM(OmpNumTasksClause, Prescriptiveness) // OMP numtasks-modifier + WALK_NESTED_ENUM(OmpPrescriptiveness, Value) // OMP prescriptiveness WALK_NESTED_ENUM(OmpMapType, Value) // OMP map-type WALK_NESTED_ENUM(OmpMapTypeModifier, Value) // OMP map-type-modifier #undef WALK_NESTED_ENUM diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 4f42971031866..e1c37bffc9750 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -3725,18 +3725,13 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) { } } } - if (std::get>(taskDep->t)) { - unsigned allowedInVersion{50}; - if (version < allowedInVersion) { - context_.Say(GetContext().clauseSource, - "Iterator modifiers are not supported in %s, %s"_warn_en_US, - ThisVersion(version), TryVersion(allowedInVersion)); - } else { + if (OmpVerifyModifiers(*taskDep, llvm::omp::OMPC_depend, + GetContext().clauseSource, context_)) { + auto &modifiers{OmpGetModifiers(*taskDep)}; + if (OmpGetUniqueModifier(modifiers)) { if (dir == llvm::omp::OMPD_depobj) { context_.Say(GetContext().clauseSource, - "An iterator-modifier may specify multiple locators, " - "a DEPEND clause on a DEPOBJ construct must only specify " - "one locator"_warn_en_US); + "An iterator-modifier may specify multiple locators, a DEPEND clause on a DEPOBJ construct must only specify one locator"_warn_en_US); } } } diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp index 97227bfef0ea5..e384b0270e6ea 100644 --- a/flang/lib/Semantics/openmp-modifiers.cpp +++ b/flang/lib/Semantics/openmp-modifiers.cpp @@ -321,6 +321,22 @@ const OmpModifierDescriptor &OmpGetDescriptor() { return desc; } +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"prescriptiveness", + /*props=*/ + { + {51, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {51, {Clause::OMPC_grainsize, Clause::OMPC_num_tasks}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor & OmpGetDescriptor() { @@ -363,11 +379,12 @@ const OmpModifierDescriptor &OmpGetDescriptor() { /*name=*/"task-dependence-type", /*props=*/ { - {52, {OmpProperty::Required, OmpProperty::Ultimate}}, + {45, {OmpProperty::Required, OmpProperty::Ultimate}}, }, /*clauses=*/ { - {52, {Clause::OMPC_depend, Clause::OMPC_update}}, + {45, {Clause::OMPC_depend}}, + {51, {Clause::OMPC_depend, Clause::OMPC_update}}, }, }; return desc; diff --git a/flang/test/Parser/OpenMP/depobj-construct.f90 b/flang/test/Parser/OpenMP/depobj-construct.f90 index 51726a5adf99e..f186c82a2ccc3 100644 --- a/flang/test/Parser/OpenMP/depobj-construct.f90 +++ b/flang/test/Parser/OpenMP/depobj-construct.f90 @@ -8,14 +8,14 @@ subroutine f00 !UNPARSE: SUBROUTINE f00 !UNPARSE: INTEGER x, y -!UNPARSE: !$OMP DEPOBJ(x) DEPEND(IN:y) +!UNPARSE: !$OMP DEPOBJ(x) DEPEND(IN: y) !UNPARSE: END SUBROUTINE !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPDepobjConstruct !PARSE-TREE: | Verbatim !PARSE-TREE: | OmpObject -> Designator -> DataRef -> Name = 'x' !PARSE-TREE: | OmpClause -> Depend -> OmpDependClause -> TaskDep -!PARSE-TREE: | | OmpTaskDependenceType -> Value = In +!PARSE-TREE: | | Modifier -> OmpTaskDependenceType -> Value = In !PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'y' subroutine f01 diff --git a/flang/test/Parser/OpenMP/taskloop.f90 b/flang/test/Parser/OpenMP/taskloop.f90 index a9c361046bd5f..f053aa7f0cff3 100644 --- a/flang/test/Parser/OpenMP/taskloop.f90 +++ b/flang/test/Parser/OpenMP/taskloop.f90 @@ -4,11 +4,11 @@ subroutine parallel_work integer :: i -!CHECK: !$OMP TASKLOOP GRAINSIZE(STRICT:500_4) +!CHECK: !$OMP TASKLOOP GRAINSIZE(STRICT: 500_4) !PARSE-TREE: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Grainsize -> OmpGrainsizeClause -!PARSE-TREE-NEXT: Prescriptiveness = Strict +!PARSE-TREE-NEXT: Modifier -> OmpPrescriptiveness -> Value = Strict !PARSE-TREE-NEXT: Scalar -> Integer -> Expr = '500_4' !$omp taskloop grainsize(strict: 500) do i=1,10000 @@ -27,11 +27,11 @@ subroutine parallel_work end do !$omp end taskloop -!CHECK: !$OMP TASKLOOP NUM_TASKS(STRICT:500_4) +!CHECK: !$OMP TASKLOOP NUM_TASKS(STRICT: 500_4) !PARSE-TREE: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> NumTasks -> OmpNumTasksClause -!PARSE-TREE-NEXT: Prescriptiveness = Strict +!PARSE-TREE-NEXT: Modifier -> OmpPrescriptiveness -> Value = Strict !PARSE-TREE-NEXT: Scalar -> Integer -> Expr = '500_4' !$omp taskloop num_tasks(strict: 500) do i=1,10000 diff --git a/flang/test/Semantics/OpenMP/depend05.f90 b/flang/test/Semantics/OpenMP/depend05.f90 index 53fd82bd08a9e..3ca091ef3187d 100644 --- a/flang/test/Semantics/OpenMP/depend05.f90 +++ b/flang/test/Semantics/OpenMP/depend05.f90 @@ -2,7 +2,7 @@ subroutine f00(x) integer :: x(10) -!WARNING: Iterator modifiers are not supported in OpenMP v4.5, try -fopenmp-version=50 +!WARNING: 'iterator' modifier is not supported in OpenMP v4.5, try -fopenmp-version=50 !$omp task depend(iterator(i = 1:10), in: x(i)) x = 0 !$omp end task diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h index 07efd6fd4e9da..67632fb79f8aa 100644 --- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h +++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h @@ -242,6 +242,7 @@ ENUM(MotionExpectation, Present); // V5.2: [15.9.1] `task-dependence-type` modifier ENUM(DependenceType, Depobj, In, Inout, Inoutset, Mutexinoutset, Out, Sink, Source); +ENUM(Prescriptiveness, Strict); template // struct LoopIterationT { @@ -643,7 +644,7 @@ struct FullT { // V5.2: [12.6.1] `grainsize` clause template // struct GrainsizeT { - ENUM(Prescriptiveness, Strict); + using Prescriptiveness = type::Prescriptiveness; using GrainSize = E; using TupleTrait = std::true_type; std::tuple t; @@ -876,8 +877,8 @@ struct NowaitT { // V5.2: [12.6.2] `num_tasks` clause template // struct NumTasksT { + using Prescriptiveness = type::Prescriptiveness; using NumTasks = E; - ENUM(Prescriptiveness, Strict); using TupleTrait = std::true_type; std::tuple t; };