diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn index 92565b2500..8b32d9359e 100644 --- a/src/tint/BUILD.gn +++ b/src/tint/BUILD.gn @@ -1594,6 +1594,7 @@ if (tint_build_unittests) { "reader/wgsl/parser_impl_continuing_stmt_test.cc", "reader/wgsl/parser_impl_core_lhs_expression_test.cc", "reader/wgsl/parser_impl_depth_texture_test.cc", + "reader/wgsl/parser_impl_diagnostic_attribute_test.cc", "reader/wgsl/parser_impl_diagnostic_control_test.cc", "reader/wgsl/parser_impl_diagnostic_directive_test.cc", "reader/wgsl/parser_impl_element_count_expression_test.cc", diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt index 6c2a8e48a6..845ed65220 100644 --- a/src/tint/CMakeLists.txt +++ b/src/tint/CMakeLists.txt @@ -1097,6 +1097,7 @@ if(TINT_BUILD_TESTS) reader/wgsl/parser_impl_continuing_stmt_test.cc reader/wgsl/parser_impl_core_lhs_expression_test.cc reader/wgsl/parser_impl_depth_texture_test.cc + reader/wgsl/parser_impl_diagnostic_attribute_test.cc reader/wgsl/parser_impl_diagnostic_control_test.cc reader/wgsl/parser_impl_diagnostic_directive_test.cc reader/wgsl/parser_impl_element_count_expression_test.cc diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc index e8653bbaa9..37c3ac3d99 100644 --- a/src/tint/reader/wgsl/parser_impl.cc +++ b/src/tint/reader/wgsl/parser_impl.cc @@ -3503,6 +3503,7 @@ Expect ParserImpl::expect_attribute() { // | ATTR 'binding' PAREN_LEFT expression COMMA? PAREN_RIGHT // | ATTR 'builtin' PAREN_LEFT builtin_value_name COMMA? PAREN_RIGHT // | ATTR 'const' +// | ATTR 'diagnostic' diagnostic_control // | ATTR 'group' PAREN_LEFT expression COMMA? PAREN_RIGHT // | ATTR 'id' PAREN_LEFT expression COMMA? PAREN_RIGHT // | ATTR 'interpolate' PAREN_LEFT interpolation_type_name COMMA? PAREN_RIGHT @@ -3522,7 +3523,7 @@ Maybe ParserImpl::attribute() { using Result = Maybe; auto& t = next(); - if (!t.IsIdentifier()) { + if (!t.IsIdentifier() && !(t.Is(Token::Type::kDiagnostic))) { return Failure::kNoMatch; } @@ -3576,6 +3577,14 @@ Maybe ParserImpl::attribute() { // Note, `const` is not valid in a WGSL source file, it's internal only + if (t.Is(Token::Type::kDiagnostic)) { + auto control = expect_diagnostic_control(); + if (control.errored) { + return Failure::kErrored; + } + return create(t.source(), control.value); + } + if (t == "fragment") { return create(t.source(), ast::PipelineStage::kFragment); } diff --git a/src/tint/reader/wgsl/parser_impl_diagnostic_attribute_test.cc b/src/tint/reader/wgsl/parser_impl_diagnostic_attribute_test.cc new file mode 100644 index 0000000000..aebd1a0d3d --- /dev/null +++ b/src/tint/reader/wgsl/parser_impl_diagnostic_attribute_test.cc @@ -0,0 +1,36 @@ +// Copyright 2023 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/tint/reader/wgsl/parser_impl_test_helper.h" + +#include "src/tint/ast/diagnostic_control.h" + +namespace tint::reader::wgsl { +namespace { + +TEST_F(ParserImplTest, DiagnosticAttribute_Valid) { + auto p = parser("diagnostic(off, foo)"); + auto a = p->attribute(); + EXPECT_FALSE(p->has_error()) << p->error(); + EXPECT_TRUE(a.matched); + auto* d = a.value->As(); + ASSERT_NE(d, nullptr); + EXPECT_EQ(d->control->severity, ast::DiagnosticSeverity::kOff); + auto* r = As(d->control->rule_name); + ASSERT_NE(r, nullptr); + EXPECT_EQ(p->builder().Symbols().NameFor(r->symbol), "foo"); +} + +} // namespace +} // namespace tint::reader::wgsl