[tint][wgsl] Add `Requires` AST node
This corresponds to the `requires` directive.
Bug: tint:2088
Change-Id: Ied437b6131b9e85eee7daed83d3d958cc063a36e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/158625
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/lang/wgsl/ast/BUILD.bazel b/src/tint/lang/wgsl/ast/BUILD.bazel
index eabb9ca..bc6462d 100644
--- a/src/tint/lang/wgsl/ast/BUILD.bazel
+++ b/src/tint/lang/wgsl/ast/BUILD.bazel
@@ -97,6 +97,7 @@
"parameter.cc",
"phony_expression.cc",
"pipeline_stage.cc",
+ "requires.cc",
"return_statement.cc",
"stage_attribute.cc",
"statement.cc",
@@ -177,6 +178,7 @@
"parameter.h",
"phony_expression.h",
"pipeline_stage.h",
+ "requires.h",
"return_statement.h",
"stage_attribute.h",
"statement.h",
@@ -271,6 +273,7 @@
"member_accessor_expression_test.cc",
"module_test.cc",
"phony_expression_test.cc",
+ "requires_test.cc",
"return_statement_test.cc",
"stage_attribute_test.cc",
"stride_attribute_test.cc",
diff --git a/src/tint/lang/wgsl/ast/BUILD.cmake b/src/tint/lang/wgsl/ast/BUILD.cmake
index e72ea46..e35a8b1 100644
--- a/src/tint/lang/wgsl/ast/BUILD.cmake
+++ b/src/tint/lang/wgsl/ast/BUILD.cmake
@@ -158,6 +158,8 @@
lang/wgsl/ast/phony_expression.h
lang/wgsl/ast/pipeline_stage.cc
lang/wgsl/ast/pipeline_stage.h
+ lang/wgsl/ast/requires.cc
+ lang/wgsl/ast/requires.h
lang/wgsl/ast/return_statement.cc
lang/wgsl/ast/return_statement.h
lang/wgsl/ast/stage_attribute.cc
@@ -271,6 +273,7 @@
lang/wgsl/ast/member_accessor_expression_test.cc
lang/wgsl/ast/module_test.cc
lang/wgsl/ast/phony_expression_test.cc
+ lang/wgsl/ast/requires_test.cc
lang/wgsl/ast/return_statement_test.cc
lang/wgsl/ast/stage_attribute_test.cc
lang/wgsl/ast/stride_attribute_test.cc
diff --git a/src/tint/lang/wgsl/ast/BUILD.gn b/src/tint/lang/wgsl/ast/BUILD.gn
index e440921..9c36fd0 100644
--- a/src/tint/lang/wgsl/ast/BUILD.gn
+++ b/src/tint/lang/wgsl/ast/BUILD.gn
@@ -161,6 +161,8 @@
"phony_expression.h",
"pipeline_stage.cc",
"pipeline_stage.h",
+ "requires.cc",
+ "requires.h",
"return_statement.cc",
"return_statement.h",
"stage_attribute.cc",
@@ -271,6 +273,7 @@
"member_accessor_expression_test.cc",
"module_test.cc",
"phony_expression_test.cc",
+ "requires_test.cc",
"return_statement_test.cc",
"stage_attribute_test.cc",
"stride_attribute_test.cc",
diff --git a/src/tint/lang/wgsl/ast/builder.h b/src/tint/lang/wgsl/ast/builder.h
index bab8fb9..1cbdfba 100644
--- a/src/tint/lang/wgsl/ast/builder.h
+++ b/src/tint/lang/wgsl/ast/builder.h
@@ -97,6 +97,7 @@
#include "src/tint/lang/wgsl/ast/override.h"
#include "src/tint/lang/wgsl/ast/parameter.h"
#include "src/tint/lang/wgsl/ast/phony_expression.h"
+#include "src/tint/lang/wgsl/ast/requires.h"
#include "src/tint/lang/wgsl/ast/return_statement.h"
#include "src/tint/lang/wgsl/ast/stage_attribute.h"
#include "src/tint/lang/wgsl/ast/stride_attribute.h"
@@ -1617,6 +1618,25 @@
return enable;
}
+ /// Adds the language feature to the list of requires directives at the top of the module.
+ /// @param feature the feature to require
+ /// @return a `ast::Requires` requiring the given language feature.
+ const ast::Requires* Require(wgsl::LanguageFeature feature) {
+ auto* req = create<ast::Requires>(wgsl::LanguageFeatures({feature}));
+ AST().AddRequires(req);
+ return req;
+ }
+
+ /// Adds the language feature to the list of requires directives at the top of the module.
+ /// @param source the requires source
+ /// @param feature the feature to require
+ /// @return a `ast::Requires` requiring the given language feature.
+ const ast::Requires* Require(const Source& source, wgsl::LanguageFeature feature) {
+ auto* req = create<ast::Requires>(source, wgsl::LanguageFeatures({feature}));
+ AST().AddRequires(req);
+ return req;
+ }
+
/// @param name the variable name
/// @param options the extra options passed to the ast::Var initializer
/// Can be any of the following, in any order:
diff --git a/src/tint/lang/wgsl/ast/module.cc b/src/tint/lang/wgsl/ast/module.cc
index 3ee8cfd..974abad 100644
--- a/src/tint/lang/wgsl/ast/module.cc
+++ b/src/tint/lang/wgsl/ast/module.cc
@@ -89,6 +89,10 @@
TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(enable, generation_id);
enables_.Push(enable);
},
+ [&](const ast::Requires* req) {
+ TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(req, generation_id);
+ requires_.Push(req);
+ },
[&](const ConstAssert* assertion) {
TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(assertion, generation_id);
const_asserts_.Push(assertion);
@@ -110,6 +114,13 @@
enables_.Push(enable);
}
+void Module::AddRequires(const ast::Requires* req) {
+ TINT_ASSERT(req);
+ TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(req, generation_id);
+ global_declarations_.Push(req);
+ requires_.Push(req);
+}
+
void Module::AddGlobalVariable(const Variable* var) {
TINT_ASSERT(var);
TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(var, generation_id);
diff --git a/src/tint/lang/wgsl/ast/module.h b/src/tint/lang/wgsl/ast/module.h
index 7214aec..8513348 100644
--- a/src/tint/lang/wgsl/ast/module.h
+++ b/src/tint/lang/wgsl/ast/module.h
@@ -34,6 +34,7 @@
#include "src/tint/lang/wgsl/ast/diagnostic_directive.h"
#include "src/tint/lang/wgsl/ast/enable.h"
#include "src/tint/lang/wgsl/ast/function.h"
+#include "src/tint/lang/wgsl/ast/requires.h"
#include "src/tint/utils/containers/vector.h"
namespace tint::ast {
@@ -110,12 +111,19 @@
/// @param ext the enable directive to add
void AddEnable(const Enable* ext);
+ /// Add a requires directive to the module
+ /// @param req the requires directive to add
+ void AddRequires(const Requires* req);
+
/// @returns the diagnostic directives for the module
const auto& DiagnosticDirectives() const { return diagnostic_directives_; }
/// @returns the extension set for the module
const auto& Enables() const { return enables_; }
+ /// @returns the requires directives for the module
+ const auto& Requires() const { return requires_; }
+
/// Add a global const assertion to the module
/// @param assertion the const assert to add
void AddConstAssert(const ConstAssert* assertion);
@@ -168,6 +176,7 @@
tint::Vector<const Variable*, 32> global_variables_;
tint::Vector<const DiagnosticDirective*, 8> diagnostic_directives_;
tint::Vector<const Enable*, 8> enables_;
+ tint::Vector<const ast::Requires*, 8> requires_;
tint::Vector<const ConstAssert*, 8> const_asserts_;
};
diff --git a/src/tint/lang/wgsl/ast/requires.cc b/src/tint/lang/wgsl/ast/requires.cc
new file mode 100644
index 0000000..059c35f
--- /dev/null
+++ b/src/tint/lang/wgsl/ast/requires.cc
@@ -0,0 +1,47 @@
+// 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/ast/requires.h"
+
+#include "src/tint/lang/wgsl/ast/builder.h"
+#include "src/tint/lang/wgsl/ast/clone_context.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::ast::Requires);
+
+namespace tint::ast {
+
+Requires::Requires(GenerationID pid, NodeID nid, const Source& src, wgsl::LanguageFeatures feats)
+ : Base(pid, nid, src), features(std::move(feats)) {}
+
+Requires::~Requires() = default;
+
+const Requires* Requires::Clone(CloneContext& ctx) const {
+ auto src = ctx.Clone(source);
+ return ctx.dst->create<Requires>(src, features);
+}
+
+} // namespace tint::ast
diff --git a/src/tint/lang/wgsl/ast/requires.h b/src/tint/lang/wgsl/ast/requires.h
new file mode 100644
index 0000000..c94d6b0
--- /dev/null
+++ b/src/tint/lang/wgsl/ast/requires.h
@@ -0,0 +1,68 @@
+// 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.
+
+#ifndef SRC_TINT_LANG_WGSL_AST_REQUIRES_H_
+#define SRC_TINT_LANG_WGSL_AST_REQUIRES_H_
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "src/tint/lang/wgsl/ast/node.h"
+#include "src/tint/lang/wgsl/language_feature.h"
+
+namespace tint::ast {
+
+/// A "requires" directive. Example:
+/// ```
+/// // Require a language feature named "foo"
+/// requires foo;
+/// ```
+class Requires final : public Castable<Requires, Node> {
+ public:
+ /// Create a requires directive
+ /// @param pid the identifier of the program that owns this node
+ /// @param nid the unique node identifier
+ /// @param src the source of this node
+ /// @param feats the language features being required by this directive
+ Requires(GenerationID pid, NodeID nid, const Source& src, wgsl::LanguageFeatures feats);
+
+ /// Destructor
+ ~Requires() override;
+
+ /// Clones this node and all transitive child nodes using the `CloneContext` `ctx`.
+ /// @param ctx the clone context
+ /// @return the newly cloned node
+ const Requires* Clone(CloneContext& ctx) const override;
+
+ /// The features being required by this directive.
+ const wgsl::LanguageFeatures features;
+};
+
+} // namespace tint::ast
+
+#endif // SRC_TINT_LANG_WGSL_AST_REQUIRES_H_
diff --git a/src/tint/lang/wgsl/ast/requires_test.cc b/src/tint/lang/wgsl/ast/requires_test.cc
new file mode 100644
index 0000000..8650f3f
--- /dev/null
+++ b/src/tint/lang/wgsl/ast/requires_test.cc
@@ -0,0 +1,51 @@
+// 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/ast/requires.h"
+
+#include "src/tint/lang/wgsl/ast/helper_test.h"
+
+namespace tint::ast {
+namespace {
+
+using RequiresTest = TestHelper;
+
+TEST_F(RequiresTest, Creation) {
+ auto* req = Require(Source{{{20, 2}, {20, 5}}},
+ wgsl::LanguageFeature::kReadonlyAndReadwriteStorageTextures);
+ EXPECT_EQ(req->source.range.begin.line, 20u);
+ EXPECT_EQ(req->source.range.begin.column, 2u);
+ EXPECT_EQ(req->source.range.end.line, 20u);
+ EXPECT_EQ(req->source.range.end.column, 5u);
+ ASSERT_EQ(req->features.Length(), 1u);
+ EXPECT_EQ(req->features[0], wgsl::LanguageFeature::kReadonlyAndReadwriteStorageTextures);
+ ASSERT_EQ(AST().Requires().Length(), 1u);
+ EXPECT_EQ(AST().Requires()[0], req);
+}
+
+} // namespace
+} // namespace tint::ast