[wgsl][writer] Emit requires directives
Bug: tint:2088
Change-Id: Iff78857539e1e2bab68aa2db1df6463196cb8f64
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/158629
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/wgsl/writer/ast_printer/BUILD.bazel b/src/tint/lang/wgsl/writer/ast_printer/BUILD.bazel
index 16f6447..320ea14 100644
--- a/src/tint/lang/wgsl/writer/ast_printer/BUILD.bazel
+++ b/src/tint/lang/wgsl/writer/ast_printer/BUILD.bazel
@@ -99,6 +99,7 @@
"literal_test.cc",
"loop_test.cc",
"member_accessor_test.cc",
+ "requires_test.cc",
"return_test.cc",
"switch_test.cc",
"type_test.cc",
diff --git a/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake b/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake
index b65e2a0..50487ec 100644
--- a/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake
+++ b/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake
@@ -102,6 +102,7 @@
lang/wgsl/writer/ast_printer/literal_test.cc
lang/wgsl/writer/ast_printer/loop_test.cc
lang/wgsl/writer/ast_printer/member_accessor_test.cc
+ lang/wgsl/writer/ast_printer/requires_test.cc
lang/wgsl/writer/ast_printer/return_test.cc
lang/wgsl/writer/ast_printer/switch_test.cc
lang/wgsl/writer/ast_printer/type_test.cc
diff --git a/src/tint/lang/wgsl/writer/ast_printer/BUILD.gn b/src/tint/lang/wgsl/writer/ast_printer/BUILD.gn
index 0f53128..940f468 100644
--- a/src/tint/lang/wgsl/writer/ast_printer/BUILD.gn
+++ b/src/tint/lang/wgsl/writer/ast_printer/BUILD.gn
@@ -101,6 +101,7 @@
"literal_test.cc",
"loop_test.cc",
"member_accessor_test.cc",
+ "requires_test.cc",
"return_test.cc",
"switch_test.cc",
"type_test.cc",
diff --git a/src/tint/lang/wgsl/writer/ast_printer/ast_printer.cc b/src/tint/lang/wgsl/writer/ast_printer/ast_printer.cc
index 7ff0c0d..ec38e3d 100644
--- a/src/tint/lang/wgsl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/wgsl/writer/ast_printer/ast_printer.cc
@@ -102,6 +102,10 @@
EmitEnable(enable);
has_directives = true;
}
+ for (auto req : program_.AST().Requires()) {
+ EmitRequires(req);
+ has_directives = true;
+ }
for (auto diagnostic : program_.AST().DiagnosticDirectives()) {
auto out = Line();
EmitDiagnosticControl(out, diagnostic->control);
@@ -113,7 +117,7 @@
}
// Generate global declarations in the order they appear in the module.
for (auto* decl : program_.AST().GlobalDeclarations()) {
- if (decl->IsAnyOf<ast::DiagnosticDirective, ast::Enable>()) {
+ if (decl->IsAnyOf<ast::DiagnosticDirective, ast::Enable, ast::Requires>()) {
continue;
}
Switch(
@@ -148,6 +152,20 @@
out << ";";
}
+void ASTPrinter::EmitRequires(const ast::Requires* req) {
+ auto out = Line();
+ out << "requires ";
+ bool first = true;
+ for (auto feature : req->features) {
+ if (!first) {
+ out << ", ";
+ }
+ out << feature;
+ first = false;
+ }
+ out << ";";
+}
+
void ASTPrinter::EmitTypeDecl(const ast::TypeDecl* ty) {
Switch(
ty, //
diff --git a/src/tint/lang/wgsl/writer/ast_printer/ast_printer.h b/src/tint/lang/wgsl/writer/ast_printer/ast_printer.h
index 9fe6ca3..71bb09a 100644
--- a/src/tint/lang/wgsl/writer/ast_printer/ast_printer.h
+++ b/src/tint/lang/wgsl/writer/ast_printer/ast_printer.h
@@ -67,6 +67,7 @@
class LiteralExpression;
class LoopStatement;
class MemberAccessorExpression;
+class Requires;
class ReturnStatement;
class Statement;
class Statement;
@@ -104,6 +105,9 @@
/// Handles generating an enable directive
/// @param enable the enable node
void EmitEnable(const ast::Enable* enable);
+ /// Handles generating a requires directive
+ /// @param req the requires node
+ void EmitRequires(const ast::Requires* req);
/// Handles generating a declared type
/// @param ty the declared type to generate
void EmitTypeDecl(const ast::TypeDecl* ty);
diff --git a/src/tint/lang/wgsl/writer/ast_printer/requires_test.cc b/src/tint/lang/wgsl/writer/ast_printer/requires_test.cc
new file mode 100644
index 0000000..1526fbb
--- /dev/null
+++ b/src/tint/lang/wgsl/writer/ast_printer/requires_test.cc
@@ -0,0 +1,66 @@
+// Copyright 2023 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/wgsl/writer/ast_printer/helper_test.h"
+
+#include "gmock/gmock.h"
+
+namespace tint::wgsl::writer {
+namespace {
+
+using WgslASTPrinterTest = TestHelper;
+
+TEST_F(WgslASTPrinterTest, Emit_Requires) {
+ auto* req = Require(wgsl::LanguageFeature::kReadonlyAndReadwriteStorageTextures);
+
+ ASTPrinter& gen = Build();
+
+ gen.EmitRequires(req);
+ EXPECT_THAT(gen.Diagnostics(), testing::IsEmpty());
+ EXPECT_EQ(gen.Result(), R"(requires readonly_and_readwrite_storage_textures;
+)");
+}
+
+// TODO(jrprice): Enable this once we have multiple language features.
+TEST_F(WgslASTPrinterTest, DISABLED_Emit_Requires_Multiple) {
+ auto* req = create<ast::Requires>(
+ wgsl::LanguageFeatures({wgsl::LanguageFeature::kReadonlyAndReadwriteStorageTextures,
+ wgsl::LanguageFeature::kReadonlyAndReadwriteStorageTextures}));
+ AST().AddRequires(req);
+
+ ASTPrinter& gen = Build();
+
+ gen.EmitRequires(req);
+ EXPECT_THAT(gen.Diagnostics(), testing::IsEmpty());
+ EXPECT_EQ(
+ gen.Result(),
+ R"(requires readonly_and_readwrite_storage_textures, readonly_and_readwrite_storage_textures;
+)");
+}
+
+} // namespace
+} // namespace tint::wgsl::writer