@@ -122,6 +122,40 @@ template <typename Separator> struct MapModifiers {
122122 const Separator sep_;
123123};
124124
125+ // This is almost exactly the same thing as MapModifiers. It has the same
126+ // issue (it expects modifiers in a specific order), and the fix for that
127+ // will change how modifiers are parsed. Instead of making this code more
128+ // generic, make it simple, and generalize after the fix is in place.
129+ template <typename Separator> struct MotionModifiers {
130+ constexpr MotionModifiers (Separator sep) : sep_(sep) {}
131+ constexpr MotionModifiers (const MotionModifiers &) = default;
132+ constexpr MotionModifiers (MotionModifiers &&) = default;
133+
134+ // Parsing of mappers if not implemented yet.
135+ using ExpParser = Parser<OmpFromClause::Expectation>;
136+ using IterParser = Parser<OmpIteratorModifier>;
137+ using ModParser = ConcatSeparated<Separator, ExpParser, IterParser>;
138+
139+ using resultType = typename ModParser::resultType;
140+
141+ std::optional<resultType> Parse (ParseState &state) const {
142+ auto mp{ModParser (sep_, ExpParser{}, IterParser{})};
143+ auto mods{mp.Parse (state)};
144+ // The ModParser always "succeeds", i.e. even if the input is junk, it
145+ // will return a tuple filled with nullopts. If any of the components
146+ // is not a nullopt, expect a ":".
147+ if (std::apply ([](auto &&...opts ) { return (... || !!opts); }, *mods)) {
148+ if (!attempt (" :" _tok).Parse (state)) {
149+ return std::nullopt ;
150+ }
151+ }
152+ return std::move (mods);
153+ }
154+
155+ private:
156+ const Separator sep_;
157+ };
158+
125159// OpenMP Clauses
126160
127161// [5.0] 2.1.6 iterator-specifier -> type-declaration-stmt = subscript-triple |
@@ -382,6 +416,31 @@ TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
382416 maybe (Parser<OmpIteratorModifier>{} / " ," _tok),
383417 Parser<OmpTaskDependenceType>{} / " :" , Parser<OmpObjectList>{})))
384418
419+ TYPE_PARSER(construct<OmpFromClause::Expectation>(
420+ " PRESENT" >> pure (OmpFromClause::Expectation::Present)))
421+
422+ template <typename MotionClause, bool CommasEverywhere>
423+ static inline MotionClause makeMotionClause(
424+ std::tuple<std::optional<std::list<typename MotionClause::Expectation>>,
425+ std::optional<std::list<OmpIteratorModifier>>> &&mods,
426+ OmpObjectList &&objs) {
427+ auto &&[exp, iter] = std::move (mods);
428+ return MotionClause (
429+ std::move (exp), std::move (iter), std::move (objs), CommasEverywhere);
430+ }
431+
432+ TYPE_PARSER (construct<OmpFromClause>(
433+ applyFunction<OmpFromClause>(makeMotionClause<OmpFromClause, true >,
434+ MotionModifiers (" ," _tok), Parser<OmpObjectList>{}) ||
435+ applyFunction<OmpFromClause>(makeMotionClause<OmpFromClause, false >,
436+ MotionModifiers (maybe(" ," _tok)), Parser<OmpObjectList>{})))
437+
438+ TYPE_PARSER(construct<OmpToClause>(
439+ applyFunction<OmpToClause>(makeMotionClause<OmpToClause, true >,
440+ MotionModifiers (" ," _tok), Parser<OmpObjectList>{}) ||
441+ applyFunction<OmpToClause>(makeMotionClause<OmpToClause, false >,
442+ MotionModifiers (maybe(" ," _tok)), Parser<OmpObjectList>{})))
443+
385444// 2.15.3.7 LINEAR (linear-list: linear-step)
386445// linear-list -> list | modifier(list)
387446// linear-modifier -> REF | VAL | UVAL
@@ -478,11 +537,11 @@ TYPE_PARSER(
478537 parenthesized (scalarIntExpr))) ||
479538 "FINAL" >> construct<OmpClause>(construct<OmpClause::Final>(
480539 parenthesized (scalarLogicalExpr))) ||
481- "FULL" >> construct<OmpClause>(construct<OmpClause::Full>()) ||
482540 "FIRSTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Firstprivate>(
483541 parenthesized (Parser<OmpObjectList>{}))) ||
484542 "FROM" >> construct<OmpClause>(construct<OmpClause::From>(
485- parenthesized (Parser<OmpObjectList>{}))) ||
543+ parenthesized (Parser<OmpFromClause>{}))) ||
544+ "FULL" >> construct<OmpClause>(construct<OmpClause::Full>()) ||
486545 "GRAINSIZE" >> construct<OmpClause>(construct<OmpClause::Grainsize>(
487546 parenthesized (Parser<OmpGrainsizeClause>{}))) ||
488547 "HAS_DEVICE_ADDR" >>
@@ -559,7 +618,7 @@ TYPE_PARSER(
559618 "THREAD_LIMIT" >> construct<OmpClause>(construct<OmpClause::ThreadLimit>(
560619 parenthesized (scalarIntExpr))) ||
561620 "TO" >> construct<OmpClause>(construct<OmpClause::To>(
562- parenthesized (Parser<OmpObjectList >{}))) ||
621+ parenthesized (Parser<OmpToClause >{}))) ||
563622 "USE_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::UseDevicePtr>(
564623 parenthesized (Parser<OmpObjectList>{}))) ||
565624 "USE_DEVICE_ADDR" >>
0 commit comments