diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index e923e2199bff9..f727525a759e6 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3424,7 +3424,20 @@ struct AssignedGotoStmt { WRAPPER_CLASS(PauseStmt, std::optional); -// Parse tree nodes for OpenMP 5.2 directives and clauses +// Parse tree nodes for OpenMP directives and clauses + +// --- Common definitions + +// 2.1 Directives or clauses may accept a list or extended-list. +// A list item is a variable, array section or common block name (enclosed +// in slashes). An extended list item is a list item or a procedure Name. +// variable-name | / common-block / | array-sections +struct OmpObject { + UNION_CLASS_BOILERPLATE(OmpObject); + std::variant u; +}; + +WRAPPER_CLASS(OmpObjectList, std::list); // [5.0] 2.1.6 iterator-specifier -> type-declaration-stmt = subscript-triple // iterator-modifier -> iterator-specifier-list @@ -3436,50 +3449,54 @@ struct OmpIteratorSpecifier { WRAPPER_CLASS(OmpIteratorModifier, std::list); -// 2.5 proc-bind-clause -> PROC_BIND (MASTER | CLOSE | SPREAD) -struct OmpProcBindClause { - ENUM_CLASS(Type, Close, Master, Spread, Primary) - WRAPPER_CLASS_BOILERPLATE(OmpProcBindClause, Type); +// 2.15.3.6 reduction-identifier -> + | - | * | .AND. | .OR. | .EQV. | .NEQV. | +// MAX | MIN | IAND | IOR | IEOR +struct OmpReductionOperator { + UNION_CLASS_BOILERPLATE(OmpReductionOperator); + std::variant u; }; -// 2.15.3.1 default-clause -> DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE) -struct OmpDefaultClause { - ENUM_CLASS(Type, Private, Firstprivate, Shared, None) - WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, Type); -}; +// --- Clauses -// 2.1 Directives or clauses may accept a list or extended-list. -// A list item is a variable, array section or common block name (enclosed -// in slashes). An extended list item is a list item or a procedure Name. -// variable-name | / common-block / | array-sections -struct OmpObject { - UNION_CLASS_BOILERPLATE(OmpObject); - std::variant u; +// 2.8.1 aligned-clause -> ALIGNED (variable-name-list[ : scalar-constant]) +struct OmpAlignedClause { + TUPLE_CLASS_BOILERPLATE(OmpAlignedClause); + CharBlock source; + std::tuple> t; }; -WRAPPER_CLASS(OmpObjectList, std::list); +// OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list) +// OMP 5.2 2.13.4 allocate-clause -> ALLOCATE ([allocate-modifier [, +// allocate-modifier] :] +// variable-name-list) +// allocate-modifier -> allocator | align +struct OmpAllocateClause { + struct AllocateModifier { + WRAPPER_CLASS(Allocator, ScalarIntExpr); + WRAPPER_CLASS(Align, ScalarIntExpr); + struct ComplexModifier { + TUPLE_CLASS_BOILERPLATE(ComplexModifier); + std::tuple t; + }; + UNION_CLASS_BOILERPLATE(AllocateModifier); + std::variant u; + }; + TUPLE_CLASS_BOILERPLATE(OmpAllocateClause); + std::tuple, OmpObjectList> t; +}; -// 2.15.5.1 map -> -// MAP ([[map-type-modifier-list [,]] [iterator-modifier [,]] map-type : ] -// variable-name-list) -// map-type-modifier-list -> map-type-modifier [,] [...] -// map-type-modifier -> ALWAYS | CLOSE | PRESENT | OMPX_HOLD -// map-type -> TO | FROM | TOFROM | ALLOC | RELEASE | DELETE -struct OmpMapClause { - ENUM_CLASS(TypeModifier, Always, Close, Present, Ompx_Hold); - ENUM_CLASS(Type, To, From, Tofrom, Alloc, Release, Delete) - TUPLE_CLASS_BOILERPLATE(OmpMapClause); +// OMP 5.0 2.4 atomic-default-mem-order-clause -> +// ATOMIC_DEFAULT_MEM_ORDER (SEQ_CST | ACQ_REL | +// RELAXED) +struct OmpAtomicDefaultMemOrderClause { + WRAPPER_CLASS_BOILERPLATE( + OmpAtomicDefaultMemOrderClause, common::OmpAtomicDefaultMemOrderType); +}; - // All modifiers are parsed into optional lists, even if they are unique. - // The checks for satisfying those constraints are deferred to semantics. - // In OpenMP 5.2 the non-comma syntax has been deprecated: keep the - // information about separator presence to emit a diagnostic if needed. - std::tuple>, - std::optional>, // unique - std::optional>, // unique - OmpObjectList, - bool> // were the modifiers comma-separated? - t; +// 2.15.3.1 default-clause -> DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE) +struct OmpDefaultClause { + ENUM_CLASS(Type, Private, Firstprivate, Shared, None) + WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, Type); }; // 2.15.5.2 defaultmap -> DEFAULTMAP (implicit-behavior[:variable-category]) @@ -3491,29 +3508,6 @@ struct OmpDefaultmapClause { std::tuple> t; }; -// 2.7.1 sched-modifier -> MONOTONIC | NONMONOTONIC | SIMD -struct OmpScheduleModifierType { - ENUM_CLASS(ModType, Monotonic, Nonmonotonic, Simd) - WRAPPER_CLASS_BOILERPLATE(OmpScheduleModifierType, ModType); -}; - -struct OmpScheduleModifier { - TUPLE_CLASS_BOILERPLATE(OmpScheduleModifier); - WRAPPER_CLASS(Modifier1, OmpScheduleModifierType); - WRAPPER_CLASS(Modifier2, OmpScheduleModifierType); - std::tuple> t; -}; - -// 2.7.1 schedule-clause -> SCHEDULE ([sched-modifier1] [, sched-modifier2]:] -// kind[, chunk_size]) -struct OmpScheduleClause { - TUPLE_CLASS_BOILERPLATE(OmpScheduleClause); - ENUM_CLASS(ScheduleType, Static, Dynamic, Guided, Auto, Runtime) - std::tuple, ScheduleType, - std::optional> - t; -}; - // device([ device-modifier :] scalar-integer-expression) struct OmpDeviceClause { TUPLE_CLASS_BOILERPLATE(OmpDeviceClause); @@ -3527,6 +3521,37 @@ struct OmpDeviceTypeClause { WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, Type); }; +// 2.13.9 depend-vec-length -> +/- non-negative-constant +struct OmpDependSinkVecLength { + TUPLE_CLASS_BOILERPLATE(OmpDependSinkVecLength); + std::tuple t; +}; + +// 2.13.9 depend-vec -> iterator [+/- depend-vec-length],...,iterator[...] +struct OmpDependSinkVec { + TUPLE_CLASS_BOILERPLATE(OmpDependSinkVec); + std::tuple> t; +}; + +// 2.13.9 depend-type -> IN | OUT | INOUT | SOURCE | SINK +struct OmpDependenceType { + ENUM_CLASS(Type, In, Out, Inout, Source, Sink) + WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Type); +}; + +// 2.13.9 depend-clause -> DEPEND (((IN | OUT | INOUT) : variable-name-list) | +// SOURCE | SINK : depend-vec) +struct OmpDependClause { + UNION_CLASS_BOILERPLATE(OmpDependClause); + EMPTY_CLASS(Source); + WRAPPER_CLASS(Sink, std::list); + struct InOut { + TUPLE_CLASS_BOILERPLATE(InOut); + std::tuple> t; + }; + std::variant u; +}; + // 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr) struct OmpIfClause { TUPLE_CLASS_BOILERPLATE(OmpIfClause); @@ -3535,24 +3560,20 @@ struct OmpIfClause { std::tuple, ScalarLogicalExpr> t; }; -// 2.8.1 aligned-clause -> ALIGNED (variable-name-list[ : scalar-constant]) -struct OmpAlignedClause { - TUPLE_CLASS_BOILERPLATE(OmpAlignedClause); - CharBlock source; - std::tuple> t; -}; - -// 2.9.5 order-clause -> ORDER ([order-modifier :]concurrent) -struct OmpOrderModifier { - UNION_CLASS_BOILERPLATE(OmpOrderModifier); - ENUM_CLASS(Kind, Reproducible, Unconstrained) - std::variant u; +// OMP 5.0 2.19.5.6 in_reduction-clause -> IN_REDUCTION (reduction-identifier: +// variable-name-list) +struct OmpInReductionClause { + TUPLE_CLASS_BOILERPLATE(OmpInReductionClause); + std::tuple t; }; -struct OmpOrderClause { - TUPLE_CLASS_BOILERPLATE(OmpOrderClause); - ENUM_CLASS(Type, Concurrent) - std::tuple, Type> t; +// OMP 5.0 2.19.4.5 lastprivate-clause -> +// LASTPRIVATE ([lastprivate-modifier :] list) +// lastprivate-modifier -> CONDITIONAL +struct OmpLastprivateClause { + TUPLE_CLASS_BOILERPLATE(OmpLastprivateClause); + ENUM_CLASS(LastprivateModifier, Conditional); + std::tuple, OmpObjectList> t; }; // 2.15.3.7 linear-modifier -> REF | VAL | UVAL @@ -3585,96 +3606,79 @@ struct OmpLinearClause { std::variant u; }; -// 2.15.3.6 reduction-identifier -> + | - | * | .AND. | .OR. | .EQV. | .NEQV. | -// MAX | MIN | IAND | IOR | IEOR -struct OmpReductionOperator { - UNION_CLASS_BOILERPLATE(OmpReductionOperator); - std::variant u; -}; +// 2.15.5.1 map -> +// MAP ([[map-type-modifier-list [,]] [iterator-modifier [,]] map-type : ] +// variable-name-list) +// map-type-modifier-list -> map-type-modifier [,] [...] +// map-type-modifier -> ALWAYS | CLOSE | PRESENT | OMPX_HOLD +// map-type -> TO | FROM | TOFROM | ALLOC | RELEASE | DELETE +struct OmpMapClause { + ENUM_CLASS(TypeModifier, Always, Close, Present, Ompx_Hold); + ENUM_CLASS(Type, To, From, Tofrom, Alloc, Release, Delete) + TUPLE_CLASS_BOILERPLATE(OmpMapClause); -// 2.15.3.6 reduction-clause -> REDUCTION (reduction-identifier: -// variable-name-list) -struct OmpReductionClause { - TUPLE_CLASS_BOILERPLATE(OmpReductionClause); - ENUM_CLASS(ReductionModifier, Inscan, Task, Default) - std::tuple, OmpReductionOperator, - OmpObjectList> + // All modifiers are parsed into optional lists, even if they are unique. + // The checks for satisfying those constraints are deferred to semantics. + // In OpenMP 5.2 the non-comma syntax has been deprecated: keep the + // information about separator presence to emit a diagnostic if needed. + std::tuple>, + std::optional>, // unique + std::optional>, // unique + OmpObjectList, + bool> // were the modifiers comma-separated? t; }; -// OMP 5.0 2.19.5.6 in_reduction-clause -> IN_REDUCTION (reduction-identifier: -// variable-name-list) -struct OmpInReductionClause { - TUPLE_CLASS_BOILERPLATE(OmpInReductionClause); - std::tuple t; -}; - -// OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list) -// OMP 5.2 2.13.4 allocate-clause -> ALLOCATE ([allocate-modifier [, -// allocate-modifier] :] -// variable-name-list) -// allocate-modifier -> allocator | align -struct OmpAllocateClause { - struct AllocateModifier { - WRAPPER_CLASS(Allocator, ScalarIntExpr); - WRAPPER_CLASS(Align, ScalarIntExpr); - struct ComplexModifier { - TUPLE_CLASS_BOILERPLATE(ComplexModifier); - std::tuple t; - }; - UNION_CLASS_BOILERPLATE(AllocateModifier); - std::variant u; - }; - TUPLE_CLASS_BOILERPLATE(OmpAllocateClause); - std::tuple, OmpObjectList> t; +// 2.9.5 order-clause -> ORDER ([order-modifier :]concurrent) +struct OmpOrderModifier { + UNION_CLASS_BOILERPLATE(OmpOrderModifier); + ENUM_CLASS(Kind, Reproducible, Unconstrained) + std::variant u; }; -// 2.13.9 depend-vec-length -> +/- non-negative-constant -struct OmpDependSinkVecLength { - TUPLE_CLASS_BOILERPLATE(OmpDependSinkVecLength); - std::tuple t; +struct OmpOrderClause { + TUPLE_CLASS_BOILERPLATE(OmpOrderClause); + ENUM_CLASS(Type, Concurrent) + std::tuple, Type> t; }; -// 2.13.9 depend-vec -> iterator [+/- depend-vec-length],...,iterator[...] -struct OmpDependSinkVec { - TUPLE_CLASS_BOILERPLATE(OmpDependSinkVec); - std::tuple> t; +// 2.5 proc-bind-clause -> PROC_BIND (MASTER | CLOSE | SPREAD) +struct OmpProcBindClause { + ENUM_CLASS(Type, Close, Master, Spread, Primary) + WRAPPER_CLASS_BOILERPLATE(OmpProcBindClause, Type); }; -// 2.13.9 depend-type -> IN | OUT | INOUT | SOURCE | SINK -struct OmpDependenceType { - ENUM_CLASS(Type, In, Out, Inout, Source, Sink) - WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Type); +// 2.15.3.6 reduction-clause -> REDUCTION (reduction-identifier: +// variable-name-list) +struct OmpReductionClause { + TUPLE_CLASS_BOILERPLATE(OmpReductionClause); + ENUM_CLASS(ReductionModifier, Inscan, Task, Default) + std::tuple, OmpReductionOperator, + OmpObjectList> + t; }; -// 2.13.9 depend-clause -> DEPEND (((IN | OUT | INOUT) : variable-name-list) | -// SOURCE | SINK : depend-vec) -struct OmpDependClause { - UNION_CLASS_BOILERPLATE(OmpDependClause); - EMPTY_CLASS(Source); - WRAPPER_CLASS(Sink, std::list); - struct InOut { - TUPLE_CLASS_BOILERPLATE(InOut); - std::tuple> t; - }; - std::variant u; +// 2.7.1 sched-modifier -> MONOTONIC | NONMONOTONIC | SIMD +struct OmpScheduleModifierType { + ENUM_CLASS(ModType, Monotonic, Nonmonotonic, Simd) + WRAPPER_CLASS_BOILERPLATE(OmpScheduleModifierType, ModType); }; -// OMP 5.0 2.4 atomic-default-mem-order-clause -> -// ATOMIC_DEFAULT_MEM_ORDER (SEQ_CST | ACQ_REL | -// RELAXED) -struct OmpAtomicDefaultMemOrderClause { - WRAPPER_CLASS_BOILERPLATE( - OmpAtomicDefaultMemOrderClause, common::OmpAtomicDefaultMemOrderType); +struct OmpScheduleModifier { + TUPLE_CLASS_BOILERPLATE(OmpScheduleModifier); + WRAPPER_CLASS(Modifier1, OmpScheduleModifierType); + WRAPPER_CLASS(Modifier2, OmpScheduleModifierType); + std::tuple> t; }; -// OMP 5.0 2.19.4.5 lastprivate-clause -> -// LASTPRIVATE ([lastprivate-modifier :] list) -// lastprivate-modifier -> CONDITIONAL -struct OmpLastprivateClause { - TUPLE_CLASS_BOILERPLATE(OmpLastprivateClause); - ENUM_CLASS(LastprivateModifier, Conditional); - std::tuple, OmpObjectList> t; +// 2.7.1 schedule-clause -> SCHEDULE ([sched-modifier1] [, sched-modifier2]:] +// kind[, chunk_size]) +struct OmpScheduleClause { + TUPLE_CLASS_BOILERPLATE(OmpScheduleClause); + ENUM_CLASS(ScheduleType, Static, Dynamic, Guided, Auto, Runtime) + std::tuple, ScheduleType, + std::optional> + t; }; // OpenMP Clauses @@ -3699,6 +3703,8 @@ struct OmpClauseList { CharBlock source; }; +// --- Directives and constructs + // 2.7.2 SECTIONS // 2.11.2 PARALLEL SECTIONS struct OmpSectionsDirective {