@@ -64,6 +64,34 @@ constexpr auto operator>=(PA checker, PB parser) {
6464 return lookAhead(checker) >> parser;
6565}
6666
67+ // This parser succeeds if the given parser succeeds, and the result
68+ // satisfies the given condition. Specifically, it succeeds if:
69+ // 1. The parser given as the argument succeeds, and
70+ // 2. The condition function (called with PA::resultType) returns true
71+ // for the result.
72+ template <typename PA, typename CF> struct PredicatedParser {
73+ using resultType = typename PA::resultType;
74+
75+ constexpr PredicatedParser(PA parser, CF condition)
76+ : parser_(parser), condition_(condition) {}
77+
78+ std::optional<resultType> Parse(ParseState &state) const {
79+ if (auto result{parser_.Parse(state)}; result && condition_(*result)) {
80+ return result;
81+ }
82+ return std::nullopt;
83+ }
84+
85+ private:
86+ const PA parser_;
87+ const CF condition_;
88+ };
89+
90+ template <typename PA, typename CF>
91+ constexpr auto predicated(PA parser, CF condition) {
92+ return PredicatedParser(parser, condition);
93+ }
94+
6795/// Parse OpenMP directive name (this includes compound directives).
6896struct OmpDirectiveNameParser {
6997 using resultType = OmpDirectiveName;
@@ -1027,6 +1055,8 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(
10271055
10281056// --- Parsers for directives and constructs --------------------------
10291057
1058+ TYPE_PARSER(sourced(construct<OmpDirectiveName>(OmpDirectiveNameParser{})))
1059+
10301060OmpDirectiveSpecification static makeFlushFromOldSyntax1(Verbatim &&text,
10311061 std::optional<OmpClauseList> &&clauses,
10321062 std::optional<std::list<OmpArgument>> &&args,
@@ -1198,24 +1228,32 @@ TYPE_PARSER(sourced( //
11981228 verbatim("FLUSH"_tok), maybe(parenthesized(Parser<OmpObjectList>{})),
11991229 Parser<OmpClauseList>{}, pure(/*TrailingClauses=*/true))))
12001230
1201- // Simple Standalone Directives
1202- TYPE_PARSER(sourced(construct<OmpSimpleStandaloneDirective>(first(
1203- "BARRIER" >> pure(llvm::omp::Directive::OMPD_barrier),
1204- "ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered),
1205- "SCAN" >> pure(llvm::omp::Directive::OMPD_scan),
1206- "TARGET ENTER DATA" >> pure(llvm::omp::Directive::OMPD_target_enter_data),
1207- "TARGET EXIT DATA" >> pure(llvm::omp::Directive::OMPD_target_exit_data),
1208- "TARGET UPDATE" >> pure(llvm::omp::Directive::OMPD_target_update),
1209- "TASKWAIT" >> pure(llvm::omp::Directive::OMPD_taskwait),
1210- "TASKYIELD" >> pure(llvm::omp::Directive::OMPD_taskyield)))))
1231+ static bool IsSimpleStandalone(const OmpDirectiveName &name) {
1232+ switch (name.v) {
1233+ case llvm::omp::Directive::OMPD_barrier:
1234+ case llvm::omp::Directive::OMPD_ordered:
1235+ case llvm::omp::Directive::OMPD_scan:
1236+ case llvm::omp::Directive::OMPD_target_enter_data:
1237+ case llvm::omp::Directive::OMPD_target_exit_data:
1238+ case llvm::omp::Directive::OMPD_target_update:
1239+ case llvm::omp::Directive::OMPD_taskwait:
1240+ case llvm::omp::Directive::OMPD_taskyield:
1241+ return true;
1242+ default:
1243+ return false;
1244+ }
1245+ }
12111246
1212- TYPE_PARSER(sourced(construct<OpenMPSimpleStandaloneConstruct>(
1213- Parser<OmpSimpleStandaloneDirective>{}, Parser<OmpClauseList>{})))
1247+ TYPE_PARSER(sourced( //
1248+ construct<OpenMPSimpleStandaloneConstruct>(
1249+ predicated(OmpDirectiveNameParser{}, IsSimpleStandalone) >=
1250+ Parser<OmpDirectiveSpecification>{})))
12141251
12151252// Standalone Constructs
12161253TYPE_PARSER(
1217- sourced(construct<OpenMPStandaloneConstruct>(
1218- Parser<OpenMPSimpleStandaloneConstruct>{}) ||
1254+ sourced( //
1255+ construct<OpenMPStandaloneConstruct>(
1256+ Parser<OpenMPSimpleStandaloneConstruct>{}) ||
12191257 construct<OpenMPStandaloneConstruct>(Parser<OpenMPFlushConstruct>{}) ||
12201258 // Try CANCELLATION POINT before CANCEL.
12211259 construct<OpenMPStandaloneConstruct>(
0 commit comments