@@ -64,6 +64,29 @@ constexpr auto operator>=(PA checker, PB parser) {
6464 return lookAhead(checker) >> parser;
6565}
6666
67+ template <typename PA, typename CF> struct PredicatedParser {
68+ using resultType = typename PA::resultType;
69+
70+ constexpr PredicatedParser(PA parser, CF condition)
71+ : parser_(parser), condition_(condition) {}
72+
73+ std::optional<resultType> Parse(ParseState &state) const {
74+ if (auto result{parser_.Parse(state)}; result && condition_(*result)) {
75+ return result;
76+ }
77+ return std::nullopt;
78+ }
79+
80+ private:
81+ const PA parser_;
82+ const CF condition_;
83+ };
84+
85+ template <typename PA, typename CF>
86+ constexpr auto predicated(PA parser, CF condition) {
87+ return PredicatedParser(parser, condition);
88+ }
89+
6790/// Parse OpenMP directive name (this includes compound directives).
6891struct OmpDirectiveNameParser {
6992 using resultType = OmpDirectiveName;
@@ -1027,6 +1050,8 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(
10271050
10281051// --- Parsers for directives and constructs --------------------------
10291052
1053+ TYPE_PARSER(sourced(construct<OmpDirectiveName>(OmpDirectiveNameParser{})))
1054+
10301055OmpDirectiveSpecification static makeFlushFromOldSyntax1(Verbatim &&text,
10311056 std::optional<OmpClauseList> &&clauses,
10321057 std::optional<std::list<OmpArgument>> &&args,
@@ -1198,24 +1223,32 @@ TYPE_PARSER(sourced( //
11981223 verbatim("FLUSH"_tok), maybe(parenthesized(Parser<OmpObjectList>{})),
11991224 Parser<OmpClauseList>{}, pure(/*TrailingClauses=*/true))))
12001225
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)))))
1226+ static bool IsSimpleStandalone(const OmpDirectiveName &name) {
1227+ switch (name.v) {
1228+ case llvm::omp::Directive::OMPD_barrier:
1229+ case llvm::omp::Directive::OMPD_ordered:
1230+ case llvm::omp::Directive::OMPD_scan:
1231+ case llvm::omp::Directive::OMPD_target_enter_data:
1232+ case llvm::omp::Directive::OMPD_target_exit_data:
1233+ case llvm::omp::Directive::OMPD_target_update:
1234+ case llvm::omp::Directive::OMPD_taskwait:
1235+ case llvm::omp::Directive::OMPD_taskyield:
1236+ return true;
1237+ default:
1238+ return false;
1239+ }
1240+ }
12111241
1212- TYPE_PARSER(sourced(construct<OpenMPSimpleStandaloneConstruct>(
1213- Parser<OmpSimpleStandaloneDirective>{}, Parser<OmpClauseList>{})))
1242+ TYPE_PARSER(sourced( //
1243+ construct<OpenMPSimpleStandaloneConstruct>(
1244+ predicated(OmpDirectiveNameParser{}, IsSimpleStandalone) >=
1245+ Parser<OmpDirectiveSpecification>{})))
12141246
12151247// Standalone Constructs
12161248TYPE_PARSER(
1217- sourced(construct<OpenMPStandaloneConstruct>(
1218- Parser<OpenMPSimpleStandaloneConstruct>{}) ||
1249+ sourced( //
1250+ construct<OpenMPStandaloneConstruct>(
1251+ Parser<OpenMPSimpleStandaloneConstruct>{}) ||
12191252 construct<OpenMPStandaloneConstruct>(Parser<OpenMPFlushConstruct>{}) ||
12201253 // Try CANCELLATION POINT before CANCEL.
12211254 construct<OpenMPStandaloneConstruct>(
0 commit comments