@@ -27,15 +27,40 @@ namespace Fortran::parser {
2727constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok;
2828constexpr auto endOmpLine = space >> endOfLine;
2929
30+ // Given a parser P for a wrapper class, invoke P, and if it succeeds return
31+ // the wrapped object.
32+ template <typename Parser> struct UnwrapParser {
33+ static_assert(
34+ Parser::resultType::WrapperTrait::value && "Wrapper class required");
35+ using resultType = decltype(Parser::resultType::v);
36+ constexpr UnwrapParser(Parser p) : parser_(p) {}
37+
38+ std::optional<resultType> Parse(ParseState &state) const {
39+ if (auto result{parser_.Parse(state)}) {
40+ return result->v;
41+ }
42+ return std::nullopt;
43+ }
44+
45+ private:
46+ const Parser parser_;
47+ };
48+
49+ template <typename Parser> constexpr auto unwrap(const Parser &p) {
50+ return UnwrapParser<Parser>(p);
51+ }
52+
3053/// Parse OpenMP directive name (this includes compound directives).
3154struct OmpDirectiveNameParser {
32- using resultType = llvm::omp::Directive ;
55+ using resultType = OmpDirectiveName ;
3356 using Token = TokenStringMatch<false, false>;
3457
3558 std::optional<resultType> Parse(ParseState &state) const {
3659 for (const NameWithId &nid : directives()) {
3760 if (attempt(Token(nid.first.data())).Parse(state)) {
38- return nid.second;
61+ OmpDirectiveName n;
62+ n.v = nid.second;
63+ return n;
3964 }
4065 }
4166 return std::nullopt;
@@ -218,7 +243,7 @@ TYPE_PARSER(construct<OmpTraitSelectorName::Value>(
218243TYPE_PARSER(sourced(construct<OmpTraitSelectorName>(
219244 // Parse predefined names first (because of SIMD).
220245 construct<OmpTraitSelectorName>(Parser<OmpTraitSelectorName::Value>{}) ||
221- construct<OmpTraitSelectorName>(OmpDirectiveNameParser{}) ||
246+ construct<OmpTraitSelectorName>(unwrap( OmpDirectiveNameParser{}) ) ||
222247 // identifier-or-string for extensions
223248 construct<OmpTraitSelectorName>(
224249 applyFunction(nameToString, Parser<Name>{})) ||
@@ -775,9 +800,9 @@ TYPE_PARSER(construct<OmpMessageClause>(expr))
775800
776801TYPE_PARSER(construct<OmpHoldsClause>(indirect(expr)))
777802TYPE_PARSER(construct<OmpAbsentClause>(many(maybe(","_tok) >>
778- construct<llvm::omp::Directive>(OmpDirectiveNameParser{}))))
803+ construct<llvm::omp::Directive>(unwrap( OmpDirectiveNameParser{}) ))))
779804TYPE_PARSER(construct<OmpContainsClause>(many(maybe(","_tok) >>
780- construct<llvm::omp::Directive>(OmpDirectiveNameParser{}))))
805+ construct<llvm::omp::Directive>(unwrap( OmpDirectiveNameParser{}) ))))
781806
782807TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
783808 parenthesized(Parser<OmpAbsentClause>{}))) ||
@@ -972,7 +997,7 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(
972997// --- Parsers for directives and constructs --------------------------
973998
974999TYPE_PARSER(sourced(construct<OmpDirectiveSpecification>( //
975- OmpDirectiveNameParser{},
1000+ sourced( OmpDirectiveNameParser{}) ,
9761001 maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
9771002 maybe(Parser<OmpClauseList>{}))))
9781003
0 commit comments