diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc index cdbe9c5f76..1f908d1569 100644 --- a/src/tint/reader/wgsl/parser_impl.cc +++ b/src/tint/reader/wgsl/parser_impl.cc @@ -310,7 +310,7 @@ bool ParserImpl::Parse() { } // translation_unit -// : enable_directive* global_decl* EOF +// : global_directive* global_decl* EOF void ParserImpl::translation_unit() { bool after_global_decl = false; while (continue_parsing()) { @@ -319,17 +319,9 @@ void ParserImpl::translation_unit() { break; } - auto ed = enable_directive(); - if (ed.matched) { - if (after_global_decl) { - add_error(p, "enable directives must come before all global declarations"); - } - } else if (ed.errored) { - // Found a invalid enable directive. - continue; - } else { + auto ed = global_directive(after_global_decl); + if (!ed.matched && !ed.errored) { auto gd = global_decl(); - if (gd.matched) { after_global_decl = true; } @@ -347,6 +339,17 @@ void ParserImpl::translation_unit() { } } +// global_directive +// : enable_directive +Maybe ParserImpl::global_directive(bool have_parsed_decl) { + auto& p = peek(); + auto ed = enable_directive(); + if (ed.matched && have_parsed_decl) { + return add_error(p, "enable directives must come before all global declarations"); + } + return ed; +} + // enable_directive // : enable name SEMICLON Maybe ParserImpl::enable_directive() { diff --git a/src/tint/reader/wgsl/parser_impl.h b/src/tint/reader/wgsl/parser_impl.h index ce0090e582..6dfc13f401 100644 --- a/src/tint/reader/wgsl/parser_impl.h +++ b/src/tint/reader/wgsl/parser_impl.h @@ -385,6 +385,10 @@ class ParserImpl { void deprecated(const Source& source, const std::string& msg); /// Parses the `translation_unit` grammar element void translation_unit(); + /// Parses the `global_directive` grammar element, erroring on parse failure. + /// @param has_parsed_decl flag indicating if the parser has consumed a global declaration. + /// @return true on parse success, otherwise an error or no-match. + Maybe global_directive(bool has_parsed_decl); /// Parses the `enable_directive` grammar element, erroring on parse failure. /// @return true on parse success, otherwise an error or no-match. Maybe enable_directive();