Import Tint changes from Dawn
Changes:
- 2de4deea1f4de5bae44be624e0ec88060e8aae60 tint: Fix implicit conversion of vector-scalar of abstrac... by Antonio Maiorano <amaiorano@google.com>
- fa4a7291f2f6083b72a09cb4d944e68c109f8e2b tint: add [[nodiscard]] on utils::Result class by Antonio Maiorano <amaiorano@google.com>
- cc937971c9ff16d905f59f9c23ae38f7bcb0c94f tint: natvis: add utils::Slice, utils::Vector, and utils:... by Antonio Maiorano <amaiorano@google.com>
- 735e4b4fa1ef359f2db9308522f5715a3130debd Emit deprecation for fallthrough. by dan sinclair <dsinclair@chromium.org>
- 4acf608cf2268dc894480bc8d125098e944e553c Include 'libfuzzer_exports.h' in fuzzers that are missing... by Ryan Harrison <rharrison@chromium.org>
- 3abad2c1257df4d7499914241acf70d03fc2141e When emitting a MSL struct initializer emit the struct na... by dan sinclair <dsinclair@chromium.org>
- a58d8c9facbf55291dfa90edaf21a7c67cd7cc6e tint: fix builtin calls and binary ops with abstract args... by Antonio Maiorano <amaiorano@google.com>
- 90d5eb612895d143791aa3527832fcefa57a2b99 tint: Add RemovePhonies transform to spir-v backend by Antonio Maiorano <amaiorano@google.com>
- b91d7e1b31be193bdeb3a240cd1ae9f09782b290 Spit `expect_variable_ident_decl` into helper and calling... by dan sinclair <dsinclair@chromium.org>
- 7058a17bda91e64f3c46b8330466776ee585af91 tint: refactor ConstEval API to accept vector of constant... by Antonio Maiorano <amaiorano@google.com>
- a8e9a6ef2bd6391bce2460d0b544847f4b70eae2 tint: Fix Resolver erroneously materializing matrices of ... by Antonio Maiorano <amaiorano@google.com>
- 50bc60359ee103f8096e04aa3a6d09c28d481fe5 tint: Add unit test for HasSideEffects for builtins by Antonio Maiorano <amaiorano@google.com>
- f7e2de797145279ca568f7eed514ba20584756be tint: make RemovePhonies remove call statements to builti... by Antonio Maiorano <amaiorano@google.com>
- e62fbbc75cfd0e131dd2ed5979290b1dd4863590 Syncing WGSL grammar to Tint. by dan sinclair <dsinclair@chromium.org>
- 6d5542d7036730f268bf1deb2d566ba815436caf Fix compilation error in delete_statement.cc by Corentin Wallez <cwallez@chromium.org>
- 1884c964d7e64ff97f69c8e1240d1073dace1ad7 tint: Fix utils::Vector<T, 0>::Push segfaulting by Antonio Maiorano <amaiorano@google.com>
- 953d610aa2244604a271be3bddd7c609337241df AST fuzzer: mutation that deletes statements by Shiyu Liu <jamessliu2020@gmail.com>
- 20cddbf04ca6bbca806bd24ef201d1e714d88448 tint: Implement modf and frexp built-ins for f16 types by Zhaoming Jiang <zhaoming.jiang@intel.com>
- 1cd4706f850edefc7f12c82b041621daf94b21fa Sync the `statement` grammar element. by dan sinclair <dsinclair@chromium.org>
- 7d8307122e6cdc6c66b3da8e6d7eaa52a2cb54f1 Cleanup some strings; Reorder `attribute` rule. by dan sinclair <dsinclair@chromium.org>
- 69a9415084dabdf140aa6efafe88deda784e2b66 Extract interpolation sample and type name parsing by dan sinclair <dsinclair@chromium.org>
- 737fd8223ebab063da09281295ede8bad02db378 Add `expression` into the WGSL parser. by dan sinclair <dsinclair@chromium.org>
- 7e9f571814c720b887f63870628c03e5e3102757 tint: const eval of binary add by Antonio Maiorano <amaiorano@google.com>
- b8893b4c2f8a7f018fa55bc8cddeceb4c10d8e7c Sync the `global_decl` grammar rule by dan sinclair <dsinclair@chromium.org>
- c2a052eaa4453eeb9c797b6f576143bdcf3b26a8 tint: Allow ConstEval functions to fail by Antonio Maiorano <amaiorano@google.com>
- 50bddbffca5e50e82741d2b203f74a94c009a17c tint: Fix dxc on Linux by Antonio Maiorano <amaiorano@google.com>
- 50940aeef1da1feccff97b94c9c800f3fafcaf36 tint: add CheckedAdd AFloat overload by Antonio Maiorano <amaiorano@google.com>
- f3015a81cc35f06226545f4de59164531997b92f tint/reader: Parse static_assert by Ben Clayton <bclayton@google.com>
- 7d7976d590fe95a0e500e235d3cb78c5997a2f53 tint: Add end-to-end tests for expressions using f16 types by Zhaoming Jiang <zhaoming.jiang@intel.com>
- 7d04cedce3f197109d076cddbccf8db90d3a1f98 tint/resolver: Pre-allocate containers by Ben Clayton <bclayton@google.com>
- 6d6692105303da31ac0df301f621ecae834863f7 tint/resolver: Reduce small-vector sizes by Ben Clayton <bclayton@google.com>
- b4744ac3599ae1691e1f8be9f4feb162b6e5de21 tint/writer: Handle static_asserts by Ben Clayton <bclayton@google.com>
- 759ac33cd177a74b4f82ace7ead6f02a70dd65ed tint/resolver: Optimize intrinsic lookups by Ben Clayton <bclayton@google.com>
- 6f8d945dd6ce5d786530c1b2b8bdb2140616cbed Sync reserved token list to WGSL spec. by dan sinclair <dsinclair@chromium.org>
- 02791e95f3ae8f0536d7b5067704ad3332387251 tint/resolver: Resolve static_assert by Ben Clayton <bclayton@google.com>
- bfd1a81364f0718f806ab01b2eaa673e1b2cc642 tint/ast: Add StaticAssert node by Ben Clayton <bclayton@google.com>
- ce6246502c4d4e43b158bd161859179ba606bf75 Add `global_directive` rule to the WGSL parser. by dan sinclair <dsinclair@chromium.org>
- ab5fc1c4dcdc0f5ac69b463bf18d15112c2326ee Fixup utils::Vector merge conflicts. by dan sinclair <dsinclair@chromium.org>
- 73778d3b0bd7cb49d3cc9c165c8f4bf7c3017b9d Add support for >>= and <<=. by dan sinclair <dsinclair@chromium.org>
- 783b169bf47b9fe7a0af7e86381bb4c1b95b3128 tint/ast: Migrate to utils::Vector by Ben Clayton <bclayton@google.com>
- 34d46731bbc4270086e585186a8cda9e5ed9e02f tint: Replace VectorRef with ConstVectorRef. by Ben Clayton <bclayton@google.com>
- 4abf28e29b515cbdadba2c83949059bf94f879b5 tint: Add basic support for chromium_experimental_push_co... by dan sinclair <dsinclair@chromium.org>
- 24d36b022747fddcd345eeecd0767ac68bcaf204 AST fuzzer: fix change unary operator mutation by Alastair F. Donaldson <alastair.donaldson@imperial.ac.uk>
GitOrigin-RevId: 2de4deea1f4de5bae44be624e0ec88060e8aae60
Change-Id: If080953641c8de4363964e89fb685210d6a9c57d
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/98063
Commit-Queue: Copybara Prod <copybara-worker-blackhole@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index bb017a1..cf3ebae 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -310,6 +310,8 @@
"ast/stage_attribute.h",
"ast/statement.cc",
"ast/statement.h",
+ "ast/static_assert.cc",
+ "ast/static_assert.h",
"ast/storage_class.cc",
"ast/storage_class.h",
"ast/storage_texture.cc",
@@ -1046,6 +1048,7 @@
"ast/sampled_texture_test.cc",
"ast/sampler_test.cc",
"ast/stage_attribute_test.cc",
+ "ast/static_assert_test.cc",
"ast/storage_class_test.cc",
"ast/storage_texture_test.cc",
"ast/stride_attribute_test.cc",
@@ -1110,6 +1113,7 @@
"resolver/function_validation_test.cc",
"resolver/host_shareable_validation_test.cc",
"resolver/increment_decrement_validation_test.cc",
+ "resolver/inferred_type_test.cc",
"resolver/intrinsic_table_test.cc",
"resolver/is_host_shareable_test.cc",
"resolver/is_storeable_test.cc",
@@ -1123,6 +1127,7 @@
"resolver/resolver_test_helper.h",
"resolver/side_effects_test.cc",
"resolver/source_variable_test.cc",
+ "resolver/static_assert_test.cc",
"resolver/storage_class_layout_validation_test.cc",
"resolver/storage_class_validation_test.cc",
"resolver/struct_layout_test.cc",
@@ -1317,6 +1322,7 @@
"writer/spirv/builder_literal_test.cc",
"writer/spirv/builder_loop_test.cc",
"writer/spirv/builder_return_test.cc",
+ "writer/spirv/builder_static_assert_test.cc",
"writer/spirv/builder_switch_test.cc",
"writer/spirv/builder_test.cc",
"writer/spirv/builder_type_test.cc",
@@ -1343,11 +1349,11 @@
"reader/wgsl/parser_impl_and_expression_test.cc",
"reader/wgsl/parser_impl_argument_expression_list_test.cc",
"reader/wgsl/parser_impl_assignment_stmt_test.cc",
- "reader/wgsl/parser_impl_body_stmt_test.cc",
"reader/wgsl/parser_impl_break_stmt_test.cc",
"reader/wgsl/parser_impl_bug_cases_test.cc",
"reader/wgsl/parser_impl_call_stmt_test.cc",
"reader/wgsl/parser_impl_case_body_test.cc",
+ "reader/wgsl/parser_impl_compound_stmt_test.cc",
"reader/wgsl/parser_impl_const_literal_test.cc",
"reader/wgsl/parser_impl_continue_stmt_test.cc",
"reader/wgsl/parser_impl_continuing_stmt_test.cc",
@@ -1442,6 +1448,7 @@
"writer/wgsl/generator_impl_loop_test.cc",
"writer/wgsl/generator_impl_member_accessor_test.cc",
"writer/wgsl/generator_impl_return_test.cc",
+ "writer/wgsl/generator_impl_static_assert_test.cc",
"writer/wgsl/generator_impl_switch_test.cc",
"writer/wgsl/generator_impl_test.cc",
"writer/wgsl/generator_impl_type_test.cc",
@@ -1482,6 +1489,7 @@
"writer/msl/generator_impl_module_constant_test.cc",
"writer/msl/generator_impl_return_test.cc",
"writer/msl/generator_impl_sanitizer_test.cc",
+ "writer/msl/generator_impl_static_assert_test.cc",
"writer/msl/generator_impl_switch_test.cc",
"writer/msl/generator_impl_test.cc",
"writer/msl/generator_impl_type_test.cc",
@@ -1521,6 +1529,7 @@
"writer/hlsl/generator_impl_module_constant_test.cc",
"writer/hlsl/generator_impl_return_test.cc",
"writer/hlsl/generator_impl_sanitizer_test.cc",
+ "writer/hlsl/generator_impl_static_assert_test.cc",
"writer/hlsl/generator_impl_switch_test.cc",
"writer/hlsl/generator_impl_test.cc",
"writer/hlsl/generator_impl_type_test.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index b5c32d7..2d25330 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -180,6 +180,8 @@
ast/stage_attribute.h
ast/statement.cc
ast/statement.h
+ ast/static_assert.cc
+ ast/static_assert.h
ast/storage_class.cc
ast/storage_class.h
ast/storage_texture.cc
@@ -742,6 +744,7 @@
ast/sampled_texture_test.cc
ast/sampler_test.cc
ast/stage_attribute_test.cc
+ ast/static_assert_test.cc
ast/storage_class_test.cc
ast/storage_texture_test.cc
ast/stride_attribute_test.cc
@@ -806,6 +809,7 @@
resolver/resolver_test_helper.h
resolver/resolver_test.cc
resolver/side_effects_test.cc
+ resolver/static_assert_test.cc
resolver/source_variable_test.cc
resolver/storage_class_layout_validation_test.cc
resolver/storage_class_validation_test.cc
@@ -940,11 +944,11 @@
reader/wgsl/parser_impl_and_expression_test.cc
reader/wgsl/parser_impl_argument_expression_list_test.cc
reader/wgsl/parser_impl_assignment_stmt_test.cc
- reader/wgsl/parser_impl_body_stmt_test.cc
reader/wgsl/parser_impl_break_stmt_test.cc
reader/wgsl/parser_impl_bug_cases_test.cc
reader/wgsl/parser_impl_call_stmt_test.cc
reader/wgsl/parser_impl_case_body_test.cc
+ reader/wgsl/parser_impl_compound_stmt_test.cc
reader/wgsl/parser_impl_const_literal_test.cc
reader/wgsl/parser_impl_continue_stmt_test.cc
reader/wgsl/parser_impl_continuing_stmt_test.cc
@@ -1035,6 +1039,7 @@
writer/spirv/builder_literal_test.cc
writer/spirv/builder_loop_test.cc
writer/spirv/builder_return_test.cc
+ writer/spirv/builder_static_assert_test.cc
writer/spirv/builder_switch_test.cc
writer/spirv/builder_test.cc
writer/spirv/builder_type_test.cc
@@ -1074,6 +1079,7 @@
writer/wgsl/generator_impl_literal_test.cc
writer/wgsl/generator_impl_member_accessor_test.cc
writer/wgsl/generator_impl_return_test.cc
+ writer/wgsl/generator_impl_static_assert_test.cc
writer/wgsl/generator_impl_switch_test.cc
writer/wgsl/generator_impl_type_test.cc
writer/wgsl/generator_impl_unary_op_test.cc
@@ -1156,6 +1162,7 @@
writer/msl/generator_impl_module_constant_test.cc
writer/msl/generator_impl_return_test.cc
writer/msl/generator_impl_sanitizer_test.cc
+ writer/msl/generator_impl_static_assert_test.cc
writer/msl/generator_impl_switch_test.cc
writer/msl/generator_impl_test.cc
writer/msl/generator_impl_type_test.cc
@@ -1227,6 +1234,7 @@
writer/hlsl/generator_impl_module_constant_test.cc
writer/hlsl/generator_impl_return_test.cc
writer/hlsl/generator_impl_sanitizer_test.cc
+ writer/hlsl/generator_impl_static_assert_test.cc
writer/hlsl/generator_impl_switch_test.cc
writer/hlsl/generator_impl_test.cc
writer/hlsl/generator_impl_type_test.cc
diff --git a/src/tint/ast/array.cc b/src/tint/ast/array.cc
index 988dfaf..6a898f4 100644
--- a/src/tint/ast/array.cc
+++ b/src/tint/ast/array.cc
@@ -15,6 +15,7 @@
#include "src/tint/ast/array.h"
#include <cmath>
+#include <utility>
#include "src/tint/program_builder.h"
@@ -42,8 +43,8 @@
const Source& src,
const Type* subtype,
const Expression* cnt,
- AttributeList attrs)
- : Base(pid, nid, src), type(subtype), count(cnt), attributes(attrs) {}
+ utils::VectorRef<const Attribute*> attrs)
+ : Base(pid, nid, src), type(subtype), count(cnt), attributes(std::move(attrs)) {}
Array::Array(Array&&) = default;
@@ -73,7 +74,7 @@
auto* ty = ctx->Clone(type);
auto* cnt = ctx->Clone(count);
auto attrs = ctx->Clone(attributes);
- return ctx->dst->create<Array>(src, ty, cnt, attrs);
+ return ctx->dst->create<Array>(src, ty, cnt, std::move(attrs));
}
} // namespace tint::ast
diff --git a/src/tint/ast/array.h b/src/tint/ast/array.h
index 6ad1cbc..19e806e 100644
--- a/src/tint/ast/array.h
+++ b/src/tint/ast/array.h
@@ -43,7 +43,7 @@
const Source& src,
const Type* subtype,
const Expression* count,
- AttributeList attributes);
+ utils::VectorRef<const Attribute*> attributes);
/// Move constructor
Array(Array&&);
~Array() override;
@@ -69,7 +69,7 @@
const Expression* const count;
/// the array attributes
- const AttributeList attributes;
+ const utils::Vector<const Attribute*, 1> attributes;
};
} // namespace tint::ast
diff --git a/src/tint/ast/array_test.cc b/src/tint/ast/array_test.cc
index f8d469b..e2ce77b 100644
--- a/src/tint/ast/array_test.cc
+++ b/src/tint/ast/array_test.cc
@@ -26,7 +26,7 @@
TEST_F(AstArrayTest, CreateSizedArray) {
auto* u32 = create<U32>();
auto* count = Expr(3_u);
- auto* arr = create<Array>(u32, count, AttributeList{});
+ auto* arr = create<Array>(u32, count, utils::Empty);
EXPECT_EQ(arr->type, u32);
EXPECT_EQ(arr->count, count);
EXPECT_TRUE(arr->Is<Array>());
@@ -35,7 +35,7 @@
TEST_F(AstArrayTest, CreateRuntimeArray) {
auto* u32 = create<U32>();
- auto* arr = create<Array>(u32, nullptr, AttributeList{});
+ auto* arr = create<Array>(u32, nullptr, utils::Empty);
EXPECT_EQ(arr->type, u32);
EXPECT_EQ(arr->count, nullptr);
EXPECT_TRUE(arr->Is<Array>());
@@ -43,7 +43,7 @@
}
TEST_F(AstArrayTest, CreateInferredTypeArray) {
- auto* arr = create<Array>(nullptr, nullptr, AttributeList{});
+ auto* arr = create<Array>(nullptr, nullptr, utils::Empty);
EXPECT_EQ(arr->type, nullptr);
EXPECT_EQ(arr->count, nullptr);
EXPECT_TRUE(arr->Is<Array>());
@@ -52,35 +52,35 @@
TEST_F(AstArrayTest, FriendlyName_RuntimeSized) {
auto* i32 = create<I32>();
- auto* arr = create<Array>(i32, nullptr, AttributeList{});
+ auto* arr = create<Array>(i32, nullptr, utils::Empty);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
}
TEST_F(AstArrayTest, FriendlyName_LiteralSized) {
auto* i32 = create<I32>();
- auto* arr = create<Array>(i32, Expr(5_u), AttributeList{});
+ auto* arr = create<Array>(i32, Expr(5_u), utils::Empty);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
}
TEST_F(AstArrayTest, FriendlyName_ConstantSized) {
auto* i32 = create<I32>();
- auto* arr = create<Array>(i32, Expr("size"), AttributeList{});
+ auto* arr = create<Array>(i32, Expr("size"), utils::Empty);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, size>");
}
TEST_F(AstArrayTest, FriendlyName_WithStride) {
auto* i32 = create<I32>();
- auto* arr = create<Array>(i32, Expr(5_u), AttributeList{create<StrideAttribute>(32u)});
+ auto* arr = create<Array>(i32, Expr(5_u), utils::Vector{create<StrideAttribute>(32u)});
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array<i32, 5>");
}
TEST_F(AstArrayTest, FriendlyName_InferredTypeAndCount) {
- auto* arr = create<Array>(nullptr, nullptr, AttributeList{});
+ auto* arr = create<Array>(nullptr, nullptr, utils::Empty);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array");
}
TEST_F(AstArrayTest, FriendlyName_InferredTypeAndCount_WithStrize) {
- auto* arr = create<Array>(nullptr, nullptr, AttributeList{create<StrideAttribute>(32u)});
+ auto* arr = create<Array>(nullptr, nullptr, utils::Vector{create<StrideAttribute>(32u)});
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array");
}
diff --git a/src/tint/ast/attribute.h b/src/tint/ast/attribute.h
index 03d80c6..1809782 100644
--- a/src/tint/ast/attribute.h
+++ b/src/tint/ast/attribute.h
@@ -38,13 +38,10 @@
Attribute(ProgramID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
};
-/// A list of attributes
-using AttributeList = std::vector<const Attribute*>;
-
/// @param attributes the list of attributes to search
/// @returns true if `attributes` includes a attribute of type `T`
template <typename... Ts>
-bool HasAttribute(const AttributeList& attributes) {
+bool HasAttribute(utils::VectorRef<const Attribute*> attributes) {
for (auto* attr : attributes) {
if (attr->IsAnyOf<Ts...>()) {
return true;
@@ -56,7 +53,7 @@
/// @param attributes the list of attributes to search
/// @returns a pointer to `T` from `attributes` if found, otherwise nullptr.
template <typename T>
-const T* GetAttribute(const AttributeList& attributes) {
+const T* GetAttribute(utils::VectorRef<const Attribute*> attributes) {
for (auto* attr : attributes) {
if (attr->Is<T>()) {
return attr->As<T>();
diff --git a/src/tint/ast/block_statement.cc b/src/tint/ast/block_statement.cc
index 4b39121..430dbba 100644
--- a/src/tint/ast/block_statement.cc
+++ b/src/tint/ast/block_statement.cc
@@ -23,7 +23,7 @@
BlockStatement::BlockStatement(ProgramID pid,
NodeID nid,
const Source& src,
- const StatementList& stmts)
+ utils::VectorRef<const Statement*> stmts)
: Base(pid, nid, src), statements(std::move(stmts)) {
for (auto* stmt : statements) {
TINT_ASSERT(AST, stmt);
@@ -39,7 +39,7 @@
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto stmts = ctx->Clone(statements);
- return ctx->dst->create<BlockStatement>(src, stmts);
+ return ctx->dst->create<BlockStatement>(src, std::move(stmts));
}
} // namespace tint::ast
diff --git a/src/tint/ast/block_statement.h b/src/tint/ast/block_statement.h
index c67ecd0..22d0a65 100644
--- a/src/tint/ast/block_statement.h
+++ b/src/tint/ast/block_statement.h
@@ -32,16 +32,16 @@
BlockStatement(ProgramID pid,
NodeID nid,
const Source& source,
- const StatementList& statements);
+ utils::VectorRef<const Statement*> statements);
/// Move constructor
BlockStatement(BlockStatement&&);
~BlockStatement() override;
/// @returns true if the block has no statements
- bool Empty() const { return statements.empty(); }
+ bool Empty() const { return statements.IsEmpty(); }
/// @returns the last statement in the block or nullptr if block empty
- const Statement* Last() const { return statements.empty() ? nullptr : statements.back(); }
+ const Statement* Last() const { return statements.IsEmpty() ? nullptr : statements.Back(); }
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
@@ -50,7 +50,7 @@
const BlockStatement* Clone(CloneContext* ctx) const override;
/// the statement list
- const StatementList statements;
+ const utils::Vector<const Statement*, 8> statements;
};
} // namespace tint::ast
diff --git a/src/tint/ast/block_statement_test.cc b/src/tint/ast/block_statement_test.cc
index 4097b20..ec92c3f 100644
--- a/src/tint/ast/block_statement_test.cc
+++ b/src/tint/ast/block_statement_test.cc
@@ -26,21 +26,21 @@
auto* d = create<DiscardStatement>();
auto* ptr = d;
- auto* b = create<BlockStatement>(StatementList{d});
+ auto* b = create<BlockStatement>(utils::Vector{d});
- ASSERT_EQ(b->statements.size(), 1u);
+ ASSERT_EQ(b->statements.Length(), 1u);
EXPECT_EQ(b->statements[0], ptr);
}
TEST_F(BlockStatementTest, Creation_WithSource) {
- auto* b = create<BlockStatement>(Source{Source::Location{20, 2}}, ast::StatementList{});
+ auto* b = create<BlockStatement>(Source{Source::Location{20, 2}}, utils::Empty);
auto src = b->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(BlockStatementTest, IsBlock) {
- auto* b = create<BlockStatement>(ast::StatementList{});
+ auto* b = create<BlockStatement>(utils::Empty);
EXPECT_TRUE(b->Is<BlockStatement>());
}
@@ -48,7 +48,7 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- b.create<BlockStatement>(ast::StatementList{nullptr});
+ b.create<BlockStatement>(utils::Vector<const ast::Statement*, 1>{nullptr});
},
"internal compiler error");
}
@@ -58,7 +58,7 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<BlockStatement>(ast::StatementList{b2.create<DiscardStatement>()});
+ b1.create<BlockStatement>(utils::Vector{b2.create<DiscardStatement>()});
},
"internal compiler error");
}
diff --git a/src/tint/ast/builtin_texture_helper_test.cc b/src/tint/ast/builtin_texture_helper_test.cc
index ad42267..882c0bb 100644
--- a/src/tint/ast/builtin_texture_helper_test.cc
+++ b/src/tint/ast/builtin_texture_helper_test.cc
@@ -29,7 +29,7 @@
ast::TextureDimension dims,
TextureDataType datatype,
const char* f,
- std::function<ExpressionList(ProgramBuilder*)> a)
+ std::function<Args(ProgramBuilder*)> a)
: overload(o),
description(desc),
texture_kind(tk),
@@ -44,7 +44,7 @@
ast::TextureDimension dims,
TextureDataType datatype,
const char* f,
- std::function<ExpressionList(ProgramBuilder*)> a)
+ std::function<Args(ProgramBuilder*)> a)
: overload(o),
description(desc),
texture_kind(tk),
@@ -59,7 +59,7 @@
ast::TextureDimension dims,
TextureDataType datatype,
const char* f,
- std::function<ExpressionList(ProgramBuilder*)> a)
+ std::function<Args(ProgramBuilder*)> a)
: overload(o),
description(d),
texture_kind(TextureKind::kStorage),
@@ -141,7 +141,7 @@
}
const ast::Variable* TextureOverloadCase::BuildTextureVariable(ProgramBuilder* b) const {
- AttributeList attrs = {
+ utils::Vector attrs{
b->create<ast::GroupAttribute>(0u),
b->create<ast::BindingAttribute>(0u),
};
@@ -175,7 +175,7 @@
}
const ast::Variable* TextureOverloadCase::BuildSamplerVariable(ProgramBuilder* b) const {
- AttributeList attrs = {
+ utils::Vector attrs = {
b->create<ast::GroupAttribute>(0u),
b->create<ast::BindingAttribute>(1u),
};
diff --git a/src/tint/ast/builtin_texture_helper_test.h b/src/tint/ast/builtin_texture_helper_test.h
index 1616a86..bb61875 100644
--- a/src/tint/ast/builtin_texture_helper_test.h
+++ b/src/tint/ast/builtin_texture_helper_test.h
@@ -177,6 +177,9 @@
/// Describes a texture builtin overload
struct TextureOverloadCase {
+ /// Args is a list of ast::Expression used as arguments to the texture overload case.
+ using Args = utils::Vector<const ast::Expression*, 8>;
+
/// Constructor for textureSample...() functions
TextureOverloadCase(ValidTextureOverload,
const char*,
@@ -185,7 +188,7 @@
ast::TextureDimension,
TextureDataType,
const char*,
- std::function<ExpressionList(ProgramBuilder*)>);
+ std::function<Args(ProgramBuilder*)>);
/// Constructor for textureLoad() functions with non-storage textures
TextureOverloadCase(ValidTextureOverload,
const char*,
@@ -193,7 +196,7 @@
ast::TextureDimension,
TextureDataType,
const char*,
- std::function<ExpressionList(ProgramBuilder*)>);
+ std::function<Args(ProgramBuilder*)>);
/// Constructor for textureLoad() with storage textures
TextureOverloadCase(ValidTextureOverload,
const char*,
@@ -202,7 +205,7 @@
ast::TextureDimension,
TextureDataType,
const char*,
- std::function<ExpressionList(ProgramBuilder*)>);
+ std::function<Args(ProgramBuilder*)>);
/// Copy constructor
TextureOverloadCase(const TextureOverloadCase&);
/// Destructor
@@ -246,7 +249,7 @@
/// Name of the function. e.g. `textureSample`, `textureSampleGrad`, etc
const char* const function;
/// A function that builds the AST arguments for the overload
- std::function<ExpressionList(ProgramBuilder*)> const args;
+ std::function<Args(ProgramBuilder*)> const args;
};
std::ostream& operator<<(std::ostream& out, const TextureOverloadCase& data);
diff --git a/src/tint/ast/call_expression.cc b/src/tint/ast/call_expression.cc
index 03eecf5..5a8aa96 100644
--- a/src/tint/ast/call_expression.cc
+++ b/src/tint/ast/call_expression.cc
@@ -14,6 +14,8 @@
#include "src/tint/ast/call_expression.h"
+#include <utility>
+
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::CallExpression);
@@ -37,8 +39,8 @@
NodeID nid,
const Source& src,
const IdentifierExpression* name,
- ExpressionList a)
- : Base(pid, nid, src), target(ToTarget(name)), args(a) {
+ utils::VectorRef<const Expression*> a)
+ : Base(pid, nid, src), target(ToTarget(name)), args(std::move(a)) {
TINT_ASSERT(AST, name);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, name, program_id);
for (auto* arg : args) {
@@ -51,8 +53,8 @@
NodeID nid,
const Source& src,
const Type* type,
- ExpressionList a)
- : Base(pid, nid, src), target(ToTarget(type)), args(a) {
+ utils::VectorRef<const Expression*> a)
+ : Base(pid, nid, src), target(ToTarget(type)), args(std::move(a)) {
TINT_ASSERT(AST, type);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
for (auto* arg : args) {
@@ -69,8 +71,9 @@
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto p = ctx->Clone(args);
- return target.name ? ctx->dst->create<CallExpression>(src, ctx->Clone(target.name), p)
- : ctx->dst->create<CallExpression>(src, ctx->Clone(target.type), p);
+ return target.name
+ ? ctx->dst->create<CallExpression>(src, ctx->Clone(target.name), std::move(p))
+ : ctx->dst->create<CallExpression>(src, ctx->Clone(target.type), std::move(p));
}
} // namespace tint::ast
diff --git a/src/tint/ast/call_expression.h b/src/tint/ast/call_expression.h
index e020429..587a88f 100644
--- a/src/tint/ast/call_expression.h
+++ b/src/tint/ast/call_expression.h
@@ -42,7 +42,7 @@
NodeID nid,
const Source& source,
const IdentifierExpression* name,
- ExpressionList args);
+ utils::VectorRef<const Expression*> args);
/// Constructor
/// @param pid the identifier of the program that owns this node
@@ -54,7 +54,7 @@
NodeID nid,
const Source& source,
const Type* type,
- ExpressionList args);
+ utils::VectorRef<const Expression*> args);
/// Move constructor
CallExpression(CallExpression&&);
@@ -80,7 +80,7 @@
const Target target;
/// The arguments
- const ExpressionList args;
+ const utils::Vector<const Expression*, 8> args;
};
} // namespace tint::ast
diff --git a/src/tint/ast/call_expression_test.cc b/src/tint/ast/call_expression_test.cc
index 5cb31cb..8b5b6a9 100644
--- a/src/tint/ast/call_expression_test.cc
+++ b/src/tint/ast/call_expression_test.cc
@@ -22,23 +22,24 @@
TEST_F(CallExpressionTest, CreationIdentifier) {
auto* func = Expr("func");
- ExpressionList params;
- params.push_back(Expr("param1"));
- params.push_back(Expr("param2"));
+ utils::Vector params{
+ Expr("param1"),
+ Expr("param2"),
+ };
auto* stmt = create<CallExpression>(func, params);
EXPECT_EQ(stmt->target.name, func);
EXPECT_EQ(stmt->target.type, nullptr);
const auto& vec = stmt->args;
- ASSERT_EQ(vec.size(), 2u);
+ ASSERT_EQ(vec.Length(), 2u);
EXPECT_EQ(vec[0], params[0]);
EXPECT_EQ(vec[1], params[1]);
}
TEST_F(CallExpressionTest, CreationIdentifier_WithSource) {
auto* func = Expr("func");
- auto* stmt = create<CallExpression>(Source{{20, 2}}, func, ExpressionList{});
+ auto* stmt = create<CallExpression>(Source{{20, 2}}, func, utils::Empty);
EXPECT_EQ(stmt->target.name, func);
EXPECT_EQ(stmt->target.type, nullptr);
@@ -49,23 +50,24 @@
TEST_F(CallExpressionTest, CreationType) {
auto* type = ty.f32();
- ExpressionList params;
- params.push_back(Expr("param1"));
- params.push_back(Expr("param2"));
+ utils::Vector params{
+ Expr("param1"),
+ Expr("param2"),
+ };
auto* stmt = create<CallExpression>(type, params);
EXPECT_EQ(stmt->target.name, nullptr);
EXPECT_EQ(stmt->target.type, type);
const auto& vec = stmt->args;
- ASSERT_EQ(vec.size(), 2u);
+ ASSERT_EQ(vec.Length(), 2u);
EXPECT_EQ(vec[0], params[0]);
EXPECT_EQ(vec[1], params[1]);
}
TEST_F(CallExpressionTest, CreationType_WithSource) {
auto* type = ty.f32();
- auto* stmt = create<CallExpression>(Source{{20, 2}}, type, ExpressionList{});
+ auto* stmt = create<CallExpression>(Source{{20, 2}}, type, utils::Empty);
EXPECT_EQ(stmt->target.name, nullptr);
EXPECT_EQ(stmt->target.type, type);
@@ -76,7 +78,7 @@
TEST_F(CallExpressionTest, IsCall) {
auto* func = Expr("func");
- auto* stmt = create<CallExpression>(func, ExpressionList{});
+ auto* stmt = create<CallExpression>(func, utils::Empty);
EXPECT_TRUE(stmt->Is<CallExpression>());
}
@@ -84,7 +86,7 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- b.create<CallExpression>(static_cast<IdentifierExpression*>(nullptr), ExpressionList{});
+ b.create<CallExpression>(static_cast<IdentifierExpression*>(nullptr), utils::Empty);
},
"internal compiler error");
}
@@ -93,7 +95,7 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- b.create<CallExpression>(static_cast<Type*>(nullptr), ExpressionList{});
+ b.create<CallExpression>(static_cast<Type*>(nullptr), utils::Empty);
},
"internal compiler error");
}
@@ -102,11 +104,11 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- ExpressionList params;
- params.push_back(b.Expr("param1"));
- params.push_back(nullptr);
- params.push_back(b.Expr("param2"));
- b.create<CallExpression>(b.Expr("func"), params);
+ b.create<CallExpression>(b.Expr("func"), utils::Vector{
+ b.Expr("param1"),
+ nullptr,
+ b.Expr("param2"),
+ });
},
"internal compiler error");
}
@@ -116,7 +118,7 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<CallExpression>(b2.Expr("func"), ExpressionList{});
+ b1.create<CallExpression>(b2.Expr("func"), utils::Empty);
},
"internal compiler error");
}
@@ -126,7 +128,7 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<CallExpression>(b2.ty.f32(), ExpressionList{});
+ b1.create<CallExpression>(b2.ty.f32(), utils::Empty);
},
"internal compiler error");
}
@@ -136,7 +138,7 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<CallExpression>(b1.Expr("func"), ExpressionList{b2.Expr("param1")});
+ b1.create<CallExpression>(b1.Expr("func"), utils::Vector{b2.Expr("param1")});
},
"internal compiler error");
}
diff --git a/src/tint/ast/call_statement_test.cc b/src/tint/ast/call_statement_test.cc
index 3426597..84d2b41 100644
--- a/src/tint/ast/call_statement_test.cc
+++ b/src/tint/ast/call_statement_test.cc
@@ -23,7 +23,7 @@
using CallStatementTest = TestHelper;
TEST_F(CallStatementTest, Creation) {
- auto* expr = create<CallExpression>(Expr("func"), ExpressionList{});
+ auto* expr = create<CallExpression>(Expr("func"), utils::Empty);
auto* c = create<CallStatement>(expr);
EXPECT_EQ(c->expr, expr);
@@ -48,7 +48,7 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<CallStatement>(b2.create<CallExpression>(b2.Expr("func"), ExpressionList{}));
+ b1.create<CallStatement>(b2.create<CallExpression>(b2.Expr("func"), utils::Empty));
},
"internal compiler error");
}
diff --git a/src/tint/ast/case_statement.cc b/src/tint/ast/case_statement.cc
index 55be8e3..9f1c20e 100644
--- a/src/tint/ast/case_statement.cc
+++ b/src/tint/ast/case_statement.cc
@@ -14,6 +14,8 @@
#include "src/tint/ast/case_statement.h"
+#include <utility>
+
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::CaseStatement);
@@ -23,9 +25,9 @@
CaseStatement::CaseStatement(ProgramID pid,
NodeID nid,
const Source& src,
- CaseSelectorList s,
+ utils::VectorRef<const IntLiteralExpression*> s,
const BlockStatement* b)
- : Base(pid, nid, src), selectors(s), body(b) {
+ : Base(pid, nid, src), selectors(std::move(s)), body(b) {
TINT_ASSERT(AST, body);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
for (auto* selector : selectors) {
@@ -43,7 +45,7 @@
auto src = ctx->Clone(source);
auto sel = ctx->Clone(selectors);
auto* b = ctx->Clone(body);
- return ctx->dst->create<CaseStatement>(src, sel, b);
+ return ctx->dst->create<CaseStatement>(src, std::move(sel), b);
}
} // namespace tint::ast
diff --git a/src/tint/ast/case_statement.h b/src/tint/ast/case_statement.h
index 613b721..47d2097 100644
--- a/src/tint/ast/case_statement.h
+++ b/src/tint/ast/case_statement.h
@@ -22,9 +22,6 @@
namespace tint::ast {
-/// A list of case literals
-using CaseSelectorList = std::vector<const IntLiteralExpression*>;
-
/// A case statement
class CaseStatement final : public Castable<CaseStatement, Statement> {
public:
@@ -37,14 +34,14 @@
CaseStatement(ProgramID pid,
NodeID nid,
const Source& src,
- CaseSelectorList selectors,
+ utils::VectorRef<const IntLiteralExpression*> selectors,
const BlockStatement* body);
/// Move constructor
CaseStatement(CaseStatement&&);
~CaseStatement() override;
/// @returns true if this is a default statement
- bool IsDefault() const { return selectors.empty(); }
+ bool IsDefault() const { return selectors.IsEmpty(); }
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
@@ -53,15 +50,12 @@
const CaseStatement* Clone(CloneContext* ctx) const override;
/// The case selectors, empty if none set
- const CaseSelectorList selectors;
+ const utils::Vector<const IntLiteralExpression*, 4> selectors;
/// The case body
const BlockStatement* const body;
};
-/// A list of case statements
-using CaseStatementList = std::vector<const CaseStatement*>;
-
} // namespace tint::ast
#endif // SRC_TINT_AST_CASE_STATEMENT_H_
diff --git a/src/tint/ast/case_statement_test.cc b/src/tint/ast/case_statement_test.cc
index 12fcbda..dc3c88a 100644
--- a/src/tint/ast/case_statement_test.cc
+++ b/src/tint/ast/case_statement_test.cc
@@ -27,40 +27,37 @@
using CaseStatementTest = TestHelper;
TEST_F(CaseStatementTest, Creation_i32) {
- CaseSelectorList b;
auto* selector = Expr(2_i);
- b.push_back(selector);
+ utils::Vector b{selector};
auto* discard = create<DiscardStatement>();
- auto* body = create<BlockStatement>(StatementList{discard});
+ auto* body = create<BlockStatement>(utils::Vector{discard});
auto* c = create<CaseStatement>(b, body);
- ASSERT_EQ(c->selectors.size(), 1u);
+ ASSERT_EQ(c->selectors.Length(), 1u);
EXPECT_EQ(c->selectors[0], selector);
- ASSERT_EQ(c->body->statements.size(), 1u);
+ ASSERT_EQ(c->body->statements.Length(), 1u);
EXPECT_EQ(c->body->statements[0], discard);
}
TEST_F(CaseStatementTest, Creation_u32) {
- CaseSelectorList b;
auto* selector = Expr(2_u);
- b.push_back(selector);
+ utils::Vector b{selector};
auto* discard = create<DiscardStatement>();
- auto* body = create<BlockStatement>(StatementList{discard});
+ auto* body = create<BlockStatement>(utils::Vector{discard});
auto* c = create<CaseStatement>(b, body);
- ASSERT_EQ(c->selectors.size(), 1u);
+ ASSERT_EQ(c->selectors.Length(), 1u);
EXPECT_EQ(c->selectors[0], selector);
- ASSERT_EQ(c->body->statements.size(), 1u);
+ ASSERT_EQ(c->body->statements.Length(), 1u);
EXPECT_EQ(c->body->statements[0], discard);
}
TEST_F(CaseStatementTest, Creation_WithSource) {
- CaseSelectorList b;
- b.push_back(Expr(2_i));
+ utils::Vector b{Expr(2_i)};
- auto* body = create<BlockStatement>(StatementList{
+ auto* body = create<BlockStatement>(utils::Vector{
create<DiscardStatement>(),
});
auto* c = create<CaseStatement>(Source{Source::Location{20, 2}}, b, body);
@@ -70,23 +67,21 @@
}
TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) {
- auto* body = create<BlockStatement>(StatementList{
+ auto* body = create<BlockStatement>(utils::Vector{
create<DiscardStatement>(),
});
- auto* c = create<CaseStatement>(CaseSelectorList{}, body);
+ auto* c = create<CaseStatement>(utils::Empty, body);
EXPECT_TRUE(c->IsDefault());
}
TEST_F(CaseStatementTest, IsDefault_WithSelectors) {
- CaseSelectorList b;
- b.push_back(Expr(2_i));
-
- auto* c = create<CaseStatement>(b, create<BlockStatement>(StatementList{}));
+ utils::Vector b{Expr(2_i)};
+ auto* c = create<CaseStatement>(b, create<BlockStatement>(utils::Empty));
EXPECT_FALSE(c->IsDefault());
}
TEST_F(CaseStatementTest, IsCase) {
- auto* c = create<CaseStatement>(CaseSelectorList{}, create<BlockStatement>(StatementList{}));
+ auto* c = create<CaseStatement>(utils::Empty, create<BlockStatement>(utils::Empty));
EXPECT_TRUE(c->Is<CaseStatement>());
}
@@ -94,7 +89,7 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- b.create<CaseStatement>(CaseSelectorList{}, nullptr);
+ b.create<CaseStatement>(utils::Empty, nullptr);
},
"internal compiler error");
}
@@ -103,8 +98,8 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- b.create<CaseStatement>(CaseSelectorList{nullptr},
- b.create<BlockStatement>(StatementList{}));
+ b.create<CaseStatement>(utils::Vector<const ast::IntLiteralExpression*, 1>{nullptr},
+ b.create<BlockStatement>(utils::Empty));
},
"internal compiler error");
}
@@ -114,8 +109,7 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<CaseStatement>(CaseSelectorList{},
- b2.create<BlockStatement>(StatementList{}));
+ b1.create<CaseStatement>(utils::Empty, b2.create<BlockStatement>(utils::Empty));
},
"internal compiler error");
}
@@ -125,8 +119,8 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<CaseStatement>(CaseSelectorList{b2.Expr(2_i)},
- b1.create<BlockStatement>(StatementList{}));
+ b1.create<CaseStatement>(utils::Vector{b2.Expr(2_i)},
+ b1.create<BlockStatement>(utils::Empty));
},
"internal compiler error");
}
diff --git a/src/tint/ast/const.cc b/src/tint/ast/const.cc
index 4dbbb86..fbc8469 100644
--- a/src/tint/ast/const.cc
+++ b/src/tint/ast/const.cc
@@ -14,6 +14,8 @@
#include "src/tint/ast/const.h"
+#include <utility>
+
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Const);
@@ -26,8 +28,8 @@
const Symbol& sym,
const ast::Type* ty,
const Expression* ctor,
- AttributeList attrs)
- : Base(pid, nid, src, sym, ty, ctor, attrs) {
+ utils::VectorRef<const Attribute*> attrs)
+ : Base(pid, nid, src, sym, ty, ctor, std::move(attrs)) {
TINT_ASSERT(AST, ctor != nullptr);
}
@@ -45,7 +47,7 @@
auto* ty = ctx->Clone(type);
auto* ctor = ctx->Clone(constructor);
auto attrs = ctx->Clone(attributes);
- return ctx->dst->create<Const>(src, sym, ty, ctor, attrs);
+ return ctx->dst->create<Const>(src, sym, ty, ctor, std::move(attrs));
}
} // namespace tint::ast
diff --git a/src/tint/ast/const.h b/src/tint/ast/const.h
index 48cbab8..c37458f 100644
--- a/src/tint/ast/const.h
+++ b/src/tint/ast/const.h
@@ -46,7 +46,7 @@
const Symbol& sym,
const ast::Type* type,
const Expression* constructor,
- AttributeList attributes);
+ utils::VectorRef<const Attribute*> attributes);
/// Move constructor
Const(Const&&);
diff --git a/src/tint/ast/enable.h b/src/tint/ast/enable.h
index df8c5e9..4c27113 100644
--- a/src/tint/ast/enable.h
+++ b/src/tint/ast/enable.h
@@ -52,9 +52,6 @@
const Extension extension;
};
-/// A list of enables
-using EnableList = std::vector<const Enable*>;
-
} // namespace tint::ast
#endif // SRC_TINT_AST_ENABLE_H_
diff --git a/src/tint/ast/expression.h b/src/tint/ast/expression.h
index 2690b93..8e0718b 100644
--- a/src/tint/ast/expression.h
+++ b/src/tint/ast/expression.h
@@ -38,9 +38,6 @@
Expression(Expression&&);
};
-/// A list of expressions
-using ExpressionList = std::vector<const Expression*>;
-
} // namespace tint::ast
#endif // SRC_TINT_AST_EXPRESSION_H_
diff --git a/src/tint/ast/extension.cc b/src/tint/ast/extension.cc
index 4283df1..e57b248 100644
--- a/src/tint/ast/extension.cc
+++ b/src/tint/ast/extension.cc
@@ -37,6 +37,9 @@
if (str == "chromium_disable_uniformity_analysis") {
return Extension::kChromiumDisableUniformityAnalysis;
}
+ if (str == "chromium_experimental_push_constant") {
+ return Extension::kChromiumExperimentalPushConstant;
+ }
return Extension::kInvalid;
}
@@ -50,6 +53,8 @@
return out << "chromium_experimental_dp4a";
case Extension::kChromiumDisableUniformityAnalysis:
return out << "chromium_disable_uniformity_analysis";
+ case Extension::kChromiumExperimentalPushConstant:
+ return out << "chromium_experimental_push_constant";
}
return out << "<unknown>";
}
diff --git a/src/tint/ast/extension.h b/src/tint/ast/extension.h
index 32bf507..ce3d48a 100644
--- a/src/tint/ast/extension.h
+++ b/src/tint/ast/extension.h
@@ -36,6 +36,7 @@
kF16,
kChromiumExperimentalDp4A,
kChromiumDisableUniformityAnalysis,
+ kChromiumExperimentalPushConstant,
};
/// @param out the std::ostream to write to
diff --git a/src/tint/ast/extension_bench.cc b/src/tint/ast/extension_bench.cc
index 47787e3..8fc9d1c 100644
--- a/src/tint/ast/extension_bench.cc
+++ b/src/tint/ast/extension_bench.cc
@@ -52,6 +52,13 @@
"chromiuE_disable_uniformity_analysis",
"chromium_disable_uniTTormity_aPPalsis",
"ddhromium_disabexxuniformity_analysis",
+ "c44romium_experimental_push_constant",
+ "chromium_experimental_pSSsVV_constant",
+ "chrom22Rm_experimental_pushRonstant",
+ "chromium_experimental_push_constant",
+ "chromium_exp9rimFntal_ush_constant",
+ "chrmium_experimental_push_constant",
+ "cOOromium_experiVeHtal_puh_conRRtant",
};
for (auto _ : state) {
for (auto& str : kStrings) {
diff --git a/src/tint/ast/extension_test.cc b/src/tint/ast/extension_test.cc
index 8c75613..283088d 100644
--- a/src/tint/ast/extension_test.cc
+++ b/src/tint/ast/extension_test.cc
@@ -45,6 +45,7 @@
{"f16", Extension::kF16},
{"chromium_experimental_dp4a", Extension::kChromiumExperimentalDp4A},
{"chromium_disable_uniformity_analysis", Extension::kChromiumDisableUniformityAnalysis},
+ {"chromium_experimental_push_constant", Extension::kChromiumExperimentalPushConstant},
};
static constexpr Case kInvalidCases[] = {
@@ -57,6 +58,9 @@
{"chromiumppdisableqquniformity_aalysHHs", Extension::kInvalid},
{"chromiu_disable_unifovmitc_analyi", Extension::kInvalid},
{"chromium_diable_uGbformity_analysis", Extension::kInvalid},
+ {"chvomium_experimental_push_constiint", Extension::kInvalid},
+ {"chromiu8WWexperimental_push_constant", Extension::kInvalid},
+ {"chromium_experiMental_push_costanxx", Extension::kInvalid},
};
using ExtensionParseTest = testing::TestWithParam<Case>;
diff --git a/src/tint/ast/function.cc b/src/tint/ast/function.cc
index 49bfb9b..1cb0339 100644
--- a/src/tint/ast/function.cc
+++ b/src/tint/ast/function.cc
@@ -26,11 +26,11 @@
NodeID nid,
const Source& src,
Symbol sym,
- ParameterList parameters,
+ utils::VectorRef<const Parameter*> parameters,
const Type* return_ty,
const BlockStatement* b,
- AttributeList attrs,
- AttributeList return_type_attrs)
+ utils::VectorRef<const Attribute*> attrs,
+ utils::VectorRef<const Attribute*> return_type_attrs)
: Base(pid, nid, src),
symbol(sym),
params(std::move(parameters)),
diff --git a/src/tint/ast/function.h b/src/tint/ast/function.h
index ed7f5b2..61771bb 100644
--- a/src/tint/ast/function.h
+++ b/src/tint/ast/function.h
@@ -48,11 +48,11 @@
NodeID nid,
const Source& source,
Symbol symbol,
- ParameterList params,
+ utils::VectorRef<const Parameter*> params,
const Type* return_type,
const BlockStatement* body,
- AttributeList attributes,
- AttributeList return_type_attributes);
+ utils::VectorRef<const Attribute*> attributes,
+ utils::VectorRef<const Attribute*> return_type_attributes);
/// Move constructor
Function(Function&&);
@@ -74,7 +74,7 @@
const Symbol symbol;
/// The function params
- const ParameterList params;
+ const utils::Vector<const Parameter*, 8> params;
/// The function return type
const Type* const return_type;
@@ -83,18 +83,18 @@
const BlockStatement* const body;
/// The attributes attached to this function
- const AttributeList attributes;
+ const utils::Vector<const Attribute*, 2> attributes;
/// The attributes attached to the function return type.
- const AttributeList return_type_attributes;
+ const utils::Vector<const Attribute*, 2> return_type_attributes;
};
/// A list of functions
-class FunctionList : public std::vector<const Function*> {
+class FunctionList : public utils::Vector<const Function*, 8> {
public:
/// Appends f to the end of the list
/// @param f the function to append to this list
- void Add(const Function* f) { this->emplace_back(f); }
+ void Add(const Function* f) { this->Push(f); }
/// Returns the function with the given name
/// @param sym the function symbol to search for
diff --git a/src/tint/ast/function_test.cc b/src/tint/ast/function_test.cc
index f1de639..b95af26 100644
--- a/src/tint/ast/function_test.cc
+++ b/src/tint/ast/function_test.cc
@@ -26,20 +26,20 @@
using FunctionTest = TestHelper;
TEST_F(FunctionTest, Creation) {
- ParameterList params{Param("var", ty.i32())};
+ utils::Vector params{Param("var", ty.i32())};
auto* var = params[0];
- auto* f = Func("func", params, ty.void_(), {});
+ auto* f = Func("func", params, ty.void_(), utils::Empty);
EXPECT_EQ(f->symbol, Symbols().Get("func"));
- ASSERT_EQ(f->params.size(), 1u);
+ ASSERT_EQ(f->params.Length(), 1u);
EXPECT_TRUE(f->return_type->Is<ast::Void>());
EXPECT_EQ(f->params[0], var);
}
TEST_F(FunctionTest, Creation_WithSource) {
- ParameterList params{Param("var", ty.i32())};
+ utils::Vector params{Param("var", ty.i32())};
- auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(), {});
+ auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(), utils::Empty);
auto src = f->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
@@ -49,7 +49,7 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- b.Func("", {}, b.ty.void_(), {});
+ b.Func("", utils::Empty, b.ty.void_(), utils::Empty);
},
"internal compiler error");
}
@@ -58,20 +58,20 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- b.Func("f", {}, nullptr, {});
+ b.Func("f", utils::Empty, nullptr, utils::Empty);
},
"internal compiler error");
}
TEST_F(FunctionTest, Assert_Null_Param) {
+ using ParamList = utils::Vector<const ast::Parameter*, 2>;
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- ParameterList params;
- params.push_back(b.Param("var", b.ty.i32()));
- params.push_back(nullptr);
-
- b.Func("f", params, b.ty.void_(), {});
+ ParamList params;
+ params.Push(b.Param("var", b.ty.i32()));
+ params.Push(nullptr);
+ b.Func("f", params, b.ty.void_(), utils::Empty);
},
"internal compiler error");
}
@@ -81,7 +81,7 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.Func(b2.Sym("func"), {}, b1.ty.void_(), {});
+ b1.Func(b2.Sym("func"), utils::Empty, b1.ty.void_(), utils::Empty);
},
"internal compiler error");
}
@@ -91,7 +91,11 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.Func("func", {b2.Param("var", b2.ty.i32())}, b1.ty.void_(), {});
+ b1.Func("func",
+ utils::Vector{
+ b2.Param("var", b2.ty.i32()),
+ },
+ b1.ty.void_(), utils::Empty);
},
"internal compiler error");
}
@@ -101,8 +105,8 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.Func("func", {}, b1.ty.void_(), {},
- {
+ b1.Func("func", utils::Empty, b1.ty.void_(), utils::Empty,
+ utils::Vector{
b2.WorkgroupSize(2_i, 4_i, 6_i),
});
},
@@ -114,8 +118,8 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.Func("func", {}, b1.ty.void_(), {}, {},
- {
+ b1.Func("func", utils::Empty, b1.ty.void_(), utils::Empty, utils::Empty,
+ utils::Vector{
b2.WorkgroupSize(2_i, 4_i, 6_i),
});
},
@@ -125,7 +129,7 @@
using FunctionListTest = TestHelper;
TEST_F(FunctionListTest, FindSymbol) {
- auto* func = Func("main", {}, ty.f32(), {});
+ auto* func = Func("main", utils::Empty, ty.f32(), utils::Empty);
FunctionList list;
list.Add(func);
EXPECT_EQ(func, list.Find(Symbols().Register("main")));
@@ -137,12 +141,12 @@
}
TEST_F(FunctionListTest, FindSymbolStage) {
- auto* fs = Func("main", {}, ty.f32(), {},
- {
+ auto* fs = Func("main", utils::Empty, ty.f32(), utils::Empty,
+ utils::Vector{
Stage(PipelineStage::kFragment),
});
- auto* vs = Func("main", {}, ty.f32(), {},
- {
+ auto* vs = Func("main", utils::Empty, ty.f32(), utils::Empty,
+ utils::Vector{
Stage(PipelineStage::kVertex),
});
FunctionList list;
@@ -154,8 +158,8 @@
TEST_F(FunctionListTest, FindSymbolStageMissing) {
FunctionList list;
- list.Add(Func("main", {}, ty.f32(), {},
- {
+ list.Add(Func("main", utils::Empty, ty.f32(), utils::Empty,
+ utils::Vector{
Stage(PipelineStage::kFragment),
}));
EXPECT_EQ(nullptr, list.Find(Symbols().Register("main"), PipelineStage::kVertex));
@@ -163,8 +167,8 @@
TEST_F(FunctionListTest, HasStage) {
FunctionList list;
- list.Add(Func("main", {}, ty.f32(), {},
- {
+ list.Add(Func("main", utils::Empty, ty.f32(), utils::Empty,
+ utils::Vector{
Stage(PipelineStage::kFragment),
}));
EXPECT_TRUE(list.HasStage(PipelineStage::kFragment));
diff --git a/src/tint/ast/let.cc b/src/tint/ast/let.cc
index b42e6e6..0248234 100644
--- a/src/tint/ast/let.cc
+++ b/src/tint/ast/let.cc
@@ -14,6 +14,8 @@
#include "src/tint/ast/let.h"
+#include <utility>
+
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Let);
@@ -26,8 +28,8 @@
const Symbol& sym,
const ast::Type* ty,
const Expression* ctor,
- AttributeList attrs)
- : Base(pid, nid, src, sym, ty, ctor, attrs) {
+ utils::VectorRef<const Attribute*> attrs)
+ : Base(pid, nid, src, sym, ty, ctor, std::move(attrs)) {
TINT_ASSERT(AST, ctor != nullptr);
}
@@ -45,7 +47,7 @@
auto* ty = ctx->Clone(type);
auto* ctor = ctx->Clone(constructor);
auto attrs = ctx->Clone(attributes);
- return ctx->dst->create<Let>(src, sym, ty, ctor, attrs);
+ return ctx->dst->create<Let>(src, sym, ty, ctor, std::move(attrs));
}
} // namespace tint::ast
diff --git a/src/tint/ast/let.h b/src/tint/ast/let.h
index 0f71da2..fa0c8be 100644
--- a/src/tint/ast/let.h
+++ b/src/tint/ast/let.h
@@ -43,7 +43,7 @@
const Symbol& sym,
const ast::Type* type,
const Expression* constructor,
- AttributeList attributes);
+ utils::VectorRef<const Attribute*> attributes);
/// Move constructor
Let(Let&&);
diff --git a/src/tint/ast/loop_statement_test.cc b/src/tint/ast/loop_statement_test.cc
index c28665b..caa995d 100644
--- a/src/tint/ast/loop_statement_test.cc
+++ b/src/tint/ast/loop_statement_test.cc
@@ -31,9 +31,9 @@
auto* continuing = Block(create<DiscardStatement>());
auto* l = create<LoopStatement>(body, continuing);
- ASSERT_EQ(l->body->statements.size(), 1u);
+ ASSERT_EQ(l->body->statements.Length(), 1u);
EXPECT_EQ(l->body->statements[0], b);
- ASSERT_EQ(l->continuing->statements.size(), 1u);
+ ASSERT_EQ(l->continuing->statements.Length(), 1u);
EXPECT_EQ(l->continuing->statements[0], continuing->Last());
}
diff --git a/src/tint/ast/module.cc b/src/tint/ast/module.cc
index 7cf9282..3faab6c 100644
--- a/src/tint/ast/module.cc
+++ b/src/tint/ast/module.cc
@@ -28,7 +28,7 @@
Module::Module(ProgramID pid,
NodeID nid,
const Source& src,
- std::vector<const ast::Node*> global_decls)
+ utils::VectorRef<const ast::Node*> global_decls)
: Base(pid, nid, src), global_declarations_(std::move(global_decls)) {
for (auto* decl : global_declarations_) {
if (decl == nullptr) {
@@ -53,7 +53,7 @@
void Module::AddGlobalDeclaration(const tint::ast::Node* decl) {
diag::List diags;
BinGlobalDeclaration(decl, diags);
- global_declarations_.emplace_back(decl);
+ global_declarations_.Push(decl);
}
void Module::BinGlobalDeclaration(const tint::ast::Node* decl, diag::List& diags) {
@@ -61,19 +61,23 @@
decl, //
[&](const ast::TypeDecl* type) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
- type_decls_.push_back(type);
+ type_decls_.Push(type);
},
[&](const Function* func) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id);
- functions_.push_back(func);
+ functions_.Push(func);
},
[&](const Variable* var) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
- global_variables_.push_back(var);
+ global_variables_.Push(var);
},
[&](const Enable* enable) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
- enables_.push_back(enable);
+ enables_.Push(enable);
+ },
+ [&](const StaticAssert* assertion) {
+ TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, assertion, program_id);
+ static_asserts_.Push(assertion);
},
[&](Default) { TINT_ICE(AST, diags) << "Unknown global declaration type"; });
}
@@ -81,29 +85,36 @@
void Module::AddEnable(const ast::Enable* enable) {
TINT_ASSERT(AST, enable);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
- global_declarations_.push_back(enable);
- enables_.push_back(enable);
+ global_declarations_.Push(enable);
+ enables_.Push(enable);
}
void Module::AddGlobalVariable(const ast::Variable* var) {
TINT_ASSERT(AST, var);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
- global_variables_.push_back(var);
- global_declarations_.push_back(var);
+ global_variables_.Push(var);
+ global_declarations_.Push(var);
+}
+
+void Module::AddStaticAssert(const StaticAssert* assertion) {
+ TINT_ASSERT(AST, assertion);
+ TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, assertion, program_id);
+ static_asserts_.Push(assertion);
+ global_declarations_.Push(assertion);
}
void Module::AddTypeDecl(const ast::TypeDecl* type) {
TINT_ASSERT(AST, type);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
- type_decls_.push_back(type);
- global_declarations_.push_back(type);
+ type_decls_.Push(type);
+ global_declarations_.Push(type);
}
void Module::AddFunction(const ast::Function* func) {
TINT_ASSERT(AST, func);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id);
- functions_.push_back(func);
- global_declarations_.push_back(func);
+ functions_.Push(func);
+ global_declarations_.Push(func);
}
const Module* Module::Clone(CloneContext* ctx) const {
@@ -117,10 +128,10 @@
// During the clone, declarations may have been placed into the module.
// Clear everything out, as we're about to re-bin the declarations.
- type_decls_.clear();
- functions_.clear();
- global_variables_.clear();
- enables_.clear();
+ type_decls_.Clear();
+ functions_.Clear();
+ global_variables_.Clear();
+ enables_.Clear();
for (auto* decl : global_declarations_) {
if (!decl) {
diff --git a/src/tint/ast/module.h b/src/tint/ast/module.h
index 27c62dc..2818cb8 100644
--- a/src/tint/ast/module.h
+++ b/src/tint/ast/module.h
@@ -16,11 +16,12 @@
#define SRC_TINT_AST_MODULE_H_
#include <string>
-#include <vector>
#include "src/tint/ast/enable.h"
#include "src/tint/ast/function.h"
+#include "src/tint/ast/static_assert.h"
#include "src/tint/ast/type.h"
+#include "src/tint/utils/vector.h"
namespace tint::ast {
@@ -42,19 +43,18 @@
/// @param src the source of this node
/// @param global_decls the list of global types, functions, and variables, in
/// the order they were declared in the source program
- Module(ProgramID pid, NodeID nid, const Source& src, std::vector<const Node*> global_decls);
+ Module(ProgramID pid,
+ NodeID nid,
+ const Source& src,
+ utils::VectorRef<const ast::Node*> global_decls);
/// Destructor
~Module() override;
/// @returns the declaration-ordered global declarations for the module
- const std::vector<const Node*>& GlobalDeclarations() const { return global_declarations_; }
+ const auto& GlobalDeclarations() const { return global_declarations_; }
- /// Add a enable directive to the Builder
- /// @param ext the enable directive to add
- void AddEnable(const Enable* ext);
-
- /// Add a global variable to the Builder
+ /// Add a global variable to the module
/// @param var the variable to add
void AddGlobalVariable(const Variable* var);
@@ -69,33 +69,44 @@
return false;
}
- /// Adds a global declaration to the Builder.
+ /// Adds a global declaration to the module.
/// @param decl the declaration to add
void AddGlobalDeclaration(const tint::ast::Node* decl);
/// @returns the global variables for the module
- const VariableList& GlobalVariables() const { return global_variables_; }
+ const auto& GlobalVariables() const { return global_variables_; }
/// @returns the global variables for the module
- VariableList& GlobalVariables() { return global_variables_; }
+ auto& GlobalVariables() { return global_variables_; }
/// @returns the global variable declarations of kind 'T' for the module
template <typename T, typename = traits::EnableIfIsType<T, ast::Variable>>
- std::vector<const T*> Globals() const {
- std::vector<const T*> out;
- out.reserve(global_variables_.size());
+ auto Globals() const {
+ utils::Vector<const T*, 32> out;
+ out.Reserve(global_variables_.Length());
for (auto* global : global_variables_) {
if (auto* var = global->As<T>()) {
- out.emplace_back(var);
+ out.Push(var);
}
}
return out;
}
- /// @returns the extension set for the module
- const EnableList& Enables() const { return enables_; }
+ /// Add a enable directive to the module
+ /// @param ext the enable directive to add
+ void AddEnable(const Enable* ext);
- /// Adds a type declaration to the Builder.
+ /// @returns the extension set for the module
+ const auto& Enables() const { return enables_; }
+
+ /// Add a global static assertion to the module
+ /// @param assertion the static assert to add
+ void AddStaticAssert(const StaticAssert* assertion);
+
+ /// @returns the list of global static assertions
+ const auto& StaticAsserts() const { return static_asserts_; }
+
+ /// Adds a type declaration to the module
/// @param decl the type declaration to add
void AddTypeDecl(const TypeDecl* decl);
@@ -104,9 +115,9 @@
const TypeDecl* LookupType(Symbol name) const;
/// @returns the declared types in the module
- const std::vector<const TypeDecl*>& TypeDecls() const { return type_decls_; }
+ const auto& TypeDecls() const { return type_decls_; }
- /// Add a function to the Builder
+ /// Add a function to the module
/// @param func the function to add
void AddFunction(const Function* func);
@@ -131,11 +142,12 @@
/// * #functions_
void BinGlobalDeclaration(const tint::ast::Node* decl, diag::List& diags);
- std::vector<const Node*> global_declarations_;
- std::vector<const TypeDecl*> type_decls_;
+ utils::Vector<const Node*, 64> global_declarations_;
+ utils::Vector<const TypeDecl*, 16> type_decls_;
FunctionList functions_;
- VariableList global_variables_;
- EnableList enables_;
+ utils::Vector<const Variable*, 32> global_variables_;
+ utils::Vector<const Enable*, 8> enables_;
+ utils::Vector<const StaticAssert*, 8> static_asserts_;
};
} // namespace tint::ast
diff --git a/src/tint/ast/module_test.cc b/src/tint/ast/module_test.cc
index 7096769..3093a16 100644
--- a/src/tint/ast/module_test.cc
+++ b/src/tint/ast/module_test.cc
@@ -22,7 +22,7 @@
using ModuleTest = TestHelper;
TEST_F(ModuleTest, Creation) {
- EXPECT_EQ(Program(std::move(*this)).AST().Functions().size(), 0u);
+ EXPECT_EQ(Program(std::move(*this)).AST().Functions().Length(), 0u);
}
TEST_F(ModuleTest, LookupFunction) {
@@ -61,8 +61,8 @@
ProgramBuilder b1;
ProgramBuilder b2;
b1.AST().AddFunction(b2.create<ast::Function>(b2.Symbols().Register("func"),
- ParameterList{}, b2.ty.f32(), b2.Block(),
- AttributeList{}, AttributeList{}));
+ utils::Empty, b2.ty.f32(), b2.Block(),
+ utils::Empty, utils::Empty));
},
"internal compiler error");
}
@@ -116,7 +116,7 @@
ctx.Clone();
auto& decls = cloned.AST().GlobalDeclarations();
- ASSERT_EQ(decls.size(), 6u);
+ ASSERT_EQ(decls.Length(), 6u);
EXPECT_TRUE(decls[1]->Is<ast::Function>());
EXPECT_TRUE(decls[3]->Is<ast::Alias>());
EXPECT_TRUE(decls[5]->Is<ast::Variable>());
diff --git a/src/tint/ast/override.cc b/src/tint/ast/override.cc
index 2876920..3a0a3a9 100644
--- a/src/tint/ast/override.cc
+++ b/src/tint/ast/override.cc
@@ -14,6 +14,8 @@
#include "src/tint/ast/override.h"
+#include <utility>
+
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Override);
@@ -26,8 +28,8 @@
const Symbol& sym,
const ast::Type* ty,
const Expression* ctor,
- AttributeList attrs)
- : Base(pid, nid, src, sym, ty, ctor, attrs) {}
+ utils::VectorRef<const Attribute*> attrs)
+ : Base(pid, nid, src, sym, ty, ctor, std::move(attrs)) {}
Override::Override(Override&&) = default;
@@ -43,7 +45,7 @@
auto* ty = ctx->Clone(type);
auto* ctor = ctx->Clone(constructor);
auto attrs = ctx->Clone(attributes);
- return ctx->dst->create<Override>(src, sym, ty, ctor, attrs);
+ return ctx->dst->create<Override>(src, sym, ty, ctor, std::move(attrs));
}
std::string Override::Identifier(const SymbolTable& symbols) const {
diff --git a/src/tint/ast/override.h b/src/tint/ast/override.h
index 00c36fc..7d01d13 100644
--- a/src/tint/ast/override.h
+++ b/src/tint/ast/override.h
@@ -46,7 +46,7 @@
const Symbol& sym,
const ast::Type* type,
const Expression* constructor,
- AttributeList attributes);
+ utils::VectorRef<const Attribute*> attributes);
/// Move constructor
Override(Override&&);
diff --git a/src/tint/ast/override_test.cc b/src/tint/ast/override_test.cc
index b4179e5..9e7af83 100644
--- a/src/tint/ast/override_test.cc
+++ b/src/tint/ast/override_test.cc
@@ -27,7 +27,7 @@
}
TEST_F(OverrideTest, Identifier_WithId) {
- auto* o = Override("o", nullptr, Expr(f32(1.0)), {Id(4u)});
+ auto* o = Override("o", nullptr, Expr(f32(1.0)), utils::Vector{Id(4u)});
EXPECT_EQ(std::string("4"), o->Identifier(Symbols()));
}
diff --git a/src/tint/ast/parameter.cc b/src/tint/ast/parameter.cc
index bab2729..01ee3aa 100644
--- a/src/tint/ast/parameter.cc
+++ b/src/tint/ast/parameter.cc
@@ -14,6 +14,8 @@
#include "src/tint/ast/parameter.h"
+#include <utility>
+
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::Parameter);
@@ -25,8 +27,8 @@
const Source& src,
const Symbol& sym,
const ast::Type* ty,
- AttributeList attrs)
- : Base(pid, nid, src, sym, ty, nullptr, attrs) {}
+ utils::VectorRef<const Attribute*> attrs)
+ : Base(pid, nid, src, sym, ty, nullptr, std::move(attrs)) {}
Parameter::Parameter(Parameter&&) = default;
@@ -41,7 +43,7 @@
auto sym = ctx->Clone(symbol);
auto* ty = ctx->Clone(type);
auto attrs = ctx->Clone(attributes);
- return ctx->dst->create<Parameter>(src, sym, ty, attrs);
+ return ctx->dst->create<Parameter>(src, sym, ty, std::move(attrs));
}
} // namespace tint::ast
diff --git a/src/tint/ast/parameter.h b/src/tint/ast/parameter.h
index 4a9bb93..e9d9f62 100644
--- a/src/tint/ast/parameter.h
+++ b/src/tint/ast/parameter.h
@@ -45,7 +45,7 @@
const Source& source,
const Symbol& sym,
const ast::Type* type,
- AttributeList attributes);
+ utils::VectorRef<const Attribute*> attributes);
/// Move constructor
Parameter(Parameter&&);
@@ -63,9 +63,6 @@
const Parameter* Clone(CloneContext* ctx) const override;
};
-/// A list of parameters
-using ParameterList = std::vector<const Parameter*>;
-
} // namespace tint::ast
#endif // SRC_TINT_AST_PARAMETER_H_
diff --git a/src/tint/ast/statement.h b/src/tint/ast/statement.h
index e3a96d1..616e348 100644
--- a/src/tint/ast/statement.h
+++ b/src/tint/ast/statement.h
@@ -39,9 +39,6 @@
Statement(Statement&&);
};
-/// A list of statements
-using StatementList = std::vector<const Statement*>;
-
} // namespace tint::ast
#endif // SRC_TINT_AST_STATEMENT_H_
diff --git a/src/tint/ast/static_assert.cc b/src/tint/ast/static_assert.cc
new file mode 100644
index 0000000..0609194
--- /dev/null
+++ b/src/tint/ast/static_assert.cc
@@ -0,0 +1,40 @@
+// Copyright 2022 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/ast/static_assert.h"
+
+#include "src/tint/program_builder.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::ast::StaticAssert);
+
+namespace tint::ast {
+
+StaticAssert::StaticAssert(ProgramID pid, NodeID nid, const Source& src, const Expression* cond)
+ : Base(pid, nid, src), condition(cond) {
+ TINT_ASSERT(AST, cond);
+ TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, cond, program_id);
+}
+
+StaticAssert::StaticAssert(StaticAssert&&) = default;
+
+StaticAssert::~StaticAssert() = default;
+
+const StaticAssert* StaticAssert::Clone(CloneContext* ctx) const {
+ // Clone arguments outside of create() call to have deterministic ordering
+ auto src = ctx->Clone(source);
+ auto* cond = ctx->Clone(condition);
+ return ctx->dst->create<StaticAssert>(src, cond);
+}
+
+} // namespace tint::ast
diff --git a/src/tint/ast/static_assert.h b/src/tint/ast/static_assert.h
new file mode 100644
index 0000000..f42ad07
--- /dev/null
+++ b/src/tint/ast/static_assert.h
@@ -0,0 +1,50 @@
+// Copyright 2022 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.
+
+#ifndef SRC_TINT_AST_STATIC_ASSERT_H_
+#define SRC_TINT_AST_STATIC_ASSERT_H_
+
+#include "src/tint/ast/statement.h"
+#include "src/tint/ast/variable.h"
+
+namespace tint::ast {
+
+/// A `static_assert` statement
+class StaticAssert final : public Castable<StaticAssert, Statement> {
+ public:
+ /// Constructor
+ /// @param pid the identifier of the program that owns this node
+ /// @param nid the unique node identifier
+ /// @param source the variable statement source
+ /// @param condition the assertion condition
+ StaticAssert(ProgramID pid, NodeID nid, const Source& source, const Expression* condition);
+
+ /// Move constructor
+ StaticAssert(StaticAssert&&);
+
+ /// Destructor
+ ~StaticAssert() override;
+
+ /// Clones this node and all transitive child nodes using the `CloneContext` `ctx`.
+ /// @param ctx the clone context
+ /// @return the newly cloned node
+ const StaticAssert* Clone(CloneContext* ctx) const override;
+
+ /// The assertion condition
+ const Expression* const condition;
+};
+
+} // namespace tint::ast
+
+#endif // SRC_TINT_AST_STATIC_ASSERT_H_
diff --git a/src/tint/ast/static_assert_test.cc b/src/tint/ast/static_assert_test.cc
new file mode 100644
index 0000000..48bee48
--- /dev/null
+++ b/src/tint/ast/static_assert_test.cc
@@ -0,0 +1,66 @@
+// Copyright 2022 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/ast/static_assert.h"
+
+#include "gtest/gtest-spi.h"
+#include "src/tint/ast/test_helper.h"
+
+namespace tint::ast {
+namespace {
+
+using StaticAssertTest = TestHelper;
+
+TEST_F(StaticAssertTest, Creation) {
+ auto* cond = Expr(true);
+ auto* stmt = StaticAssert(cond);
+ EXPECT_EQ(stmt->condition, cond);
+}
+
+TEST_F(StaticAssertTest, Creation_WithSource) {
+ auto* cond = Expr(true);
+ auto* stmt = StaticAssert(Source{{20, 2}}, cond);
+ auto src = stmt->source;
+ EXPECT_EQ(src.range.begin.line, 20u);
+ EXPECT_EQ(src.range.begin.column, 2u);
+}
+
+TEST_F(StaticAssertTest, IsStaticAssert) {
+ auto* cond = Expr(true);
+
+ auto* stmt = StaticAssert(cond);
+ EXPECT_TRUE(stmt->Is<ast::StaticAssert>());
+}
+
+TEST_F(StaticAssertTest, Assert_Null_Condition) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.StaticAssert(nullptr);
+ },
+ "internal compiler error");
+}
+
+TEST_F(StaticAssertTest, Assert_DifferentProgramID_Condition) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b1;
+ ProgramBuilder b2;
+ b1.StaticAssert(b2.Expr(i32(123)));
+ },
+ "internal compiler error");
+}
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/storage_class.cc b/src/tint/ast/storage_class.cc
index 303c04e..450067b 100644
--- a/src/tint/ast/storage_class.cc
+++ b/src/tint/ast/storage_class.cc
@@ -43,6 +43,9 @@
if (str == "storage") {
return StorageClass::kStorage;
}
+ if (str == "push_constant") {
+ return StorageClass::kPushConstant;
+ }
return StorageClass::kInvalid;
}
@@ -62,6 +65,8 @@
return out << "uniform";
case StorageClass::kStorage:
return out << "storage";
+ case StorageClass::kPushConstant:
+ return out << "push_constant";
case StorageClass::kHandle:
return out << "handle";
case StorageClass::kIn:
diff --git a/src/tint/ast/storage_class.h b/src/tint/ast/storage_class.h
index 4da3db0..43e41e1 100644
--- a/src/tint/ast/storage_class.h
+++ b/src/tint/ast/storage_class.h
@@ -36,6 +36,7 @@
kWorkgroup,
kUniform,
kStorage,
+ kPushConstant,
kHandle, // Tint-internal enum entry - not parsed
kIn, // Tint-internal enum entry - not parsed
kOut, // Tint-internal enum entry - not parsed
@@ -55,7 +56,8 @@
/// @param sc the StorageClass
/// @see https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable
inline bool IsHostShareable(StorageClass sc) {
- return sc == ast::StorageClass::kUniform || sc == ast::StorageClass::kStorage;
+ return sc == ast::StorageClass::kUniform || sc == ast::StorageClass::kStorage ||
+ sc == ast::StorageClass::kPushConstant;
}
} // namespace tint::ast
diff --git a/src/tint/ast/storage_class.h.tmpl b/src/tint/ast/storage_class.h.tmpl
index d885c72..c21d6f6 100644
--- a/src/tint/ast/storage_class.h.tmpl
+++ b/src/tint/ast/storage_class.h.tmpl
@@ -28,7 +28,8 @@
/// @param sc the StorageClass
/// @see https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable
inline bool IsHostShareable(StorageClass sc) {
- return sc == ast::StorageClass::kUniform || sc == ast::StorageClass::kStorage;
+ return sc == ast::StorageClass::kUniform || sc == ast::StorageClass::kStorage ||
+ sc == ast::StorageClass::kPushConstant;
}
} // namespace tint::ast
diff --git a/src/tint/ast/storage_class_bench.cc b/src/tint/ast/storage_class_bench.cc
index d8e9ae9..00095c2 100644
--- a/src/tint/ast/storage_class_bench.cc
+++ b/src/tint/ast/storage_class_bench.cc
@@ -31,12 +31,48 @@
void StorageClassParser(::benchmark::State& state) {
std::array kStrings{
- "fccnctin", "ucti3", "functVon", "function", "1unction", "unJtqqon",
- "llun77tion", "ppqqivtHH", "prcv", "bivaGe", "private", "priviive",
- "8WWivate", "pxxvate", "wXkgrggup", "worXVup", "3orkgroup", "workgroup",
- "workgroEp", "woTTPkroup", "ddorkroxxp", "u44iform", "unSSfoVVm", "RniR22m",
- "uniform", "uFfo9m", "uniorm", "VOORRHrm", "straye", "llntrrr77ge",
- "stor4g00", "storage", "trooe", "zzrage", "siioppa1",
+ "fccnctin",
+ "ucti3",
+ "functVon",
+ "function",
+ "1unction",
+ "unJtqqon",
+ "llun77tion",
+ "ppqqivtHH",
+ "prcv",
+ "bivaGe",
+ "private",
+ "priviive",
+ "8WWivate",
+ "pxxvate",
+ "wXkgrggup",
+ "worXVup",
+ "3orkgroup",
+ "workgroup",
+ "workgroEp",
+ "woTTPkroup",
+ "ddorkroxxp",
+ "u44iform",
+ "unSSfoVVm",
+ "RniR22m",
+ "uniform",
+ "uFfo9m",
+ "uniorm",
+ "VOORRHrm",
+ "straye",
+ "llntrrr77ge",
+ "stor4g00",
+ "storage",
+ "trooe",
+ "zzrage",
+ "siioppa1",
+ "puXXh_constant",
+ "pusII9_nn55nstant",
+ "YusHH_coaastSSrnt",
+ "push_constant",
+ "pushonkkHan",
+ "jush_consgRt",
+ "puh_cobsant",
};
for (auto _ : state) {
for (auto& str : kStrings) {
diff --git a/src/tint/ast/storage_class_test.cc b/src/tint/ast/storage_class_test.cc
index 9688236..1d12d45 100644
--- a/src/tint/ast/storage_class_test.cc
+++ b/src/tint/ast/storage_class_test.cc
@@ -44,18 +44,19 @@
static constexpr Case kValidCases[] = {
{"function", StorageClass::kFunction}, {"private", StorageClass::kPrivate},
{"workgroup", StorageClass::kWorkgroup}, {"uniform", StorageClass::kUniform},
- {"storage", StorageClass::kStorage},
+ {"storage", StorageClass::kStorage}, {"push_constant", StorageClass::kPushConstant},
};
static constexpr Case kInvalidCases[] = {
- {"fccnctin", StorageClass::kInvalid}, {"ucti3", StorageClass::kInvalid},
- {"functVon", StorageClass::kInvalid}, {"priv1te", StorageClass::kInvalid},
- {"pqiJate", StorageClass::kInvalid}, {"privat7ll", StorageClass::kInvalid},
- {"workroppqHH", StorageClass::kInvalid}, {"workru", StorageClass::kInvalid},
- {"wbkgGoup", StorageClass::kInvalid}, {"unifiivm", StorageClass::kInvalid},
- {"8WWiform", StorageClass::kInvalid}, {"uxxform", StorageClass::kInvalid},
- {"sXraggg", StorageClass::kInvalid}, {"traXe", StorageClass::kInvalid},
- {"stor3ge", StorageClass::kInvalid},
+ {"fccnctin", StorageClass::kInvalid}, {"ucti3", StorageClass::kInvalid},
+ {"functVon", StorageClass::kInvalid}, {"priv1te", StorageClass::kInvalid},
+ {"pqiJate", StorageClass::kInvalid}, {"privat7ll", StorageClass::kInvalid},
+ {"workroppqHH", StorageClass::kInvalid}, {"workru", StorageClass::kInvalid},
+ {"wbkgGoup", StorageClass::kInvalid}, {"unifiivm", StorageClass::kInvalid},
+ {"8WWiform", StorageClass::kInvalid}, {"uxxform", StorageClass::kInvalid},
+ {"sXraggg", StorageClass::kInvalid}, {"traXe", StorageClass::kInvalid},
+ {"stor3ge", StorageClass::kInvalid}, {"push_constanE", StorageClass::kInvalid},
+ {"push_TTPnstant", StorageClass::kInvalid}, {"puxxdh_constan", StorageClass::kInvalid},
};
using StorageClassParseTest = testing::TestWithParam<Case>;
diff --git a/src/tint/ast/struct.cc b/src/tint/ast/struct.cc
index 326718a..c2d9002 100644
--- a/src/tint/ast/struct.cc
+++ b/src/tint/ast/struct.cc
@@ -26,8 +26,8 @@
NodeID nid,
const Source& src,
Symbol n,
- StructMemberList m,
- AttributeList attrs)
+ utils::VectorRef<const ast::StructMember*> m,
+ utils::VectorRef<const ast::Attribute*> attrs)
: Base(pid, nid, src, n), members(std::move(m)), attributes(std::move(attrs)) {
for (auto* mem : members) {
TINT_ASSERT(AST, mem);
@@ -49,7 +49,7 @@
auto n = ctx->Clone(name);
auto mem = ctx->Clone(members);
auto attrs = ctx->Clone(attributes);
- return ctx->dst->create<Struct>(src, n, mem, attrs);
+ return ctx->dst->create<Struct>(src, n, std::move(mem), std::move(attrs));
}
} // namespace tint::ast
diff --git a/src/tint/ast/struct.h b/src/tint/ast/struct.h
index 5d55b8c..3e3e5cf 100644
--- a/src/tint/ast/struct.h
+++ b/src/tint/ast/struct.h
@@ -21,6 +21,7 @@
#include "src/tint/ast/attribute.h"
#include "src/tint/ast/struct_member.h"
#include "src/tint/ast/type_decl.h"
+#include "src/tint/utils/vector.h"
namespace tint::ast {
@@ -38,8 +39,8 @@
NodeID nid,
const Source& src,
Symbol name,
- StructMemberList members,
- AttributeList attributes);
+ utils::VectorRef<const ast::StructMember*> members,
+ utils::VectorRef<const ast::Attribute*> attributes);
/// Move constructor
Struct(Struct&&);
@@ -52,10 +53,10 @@
const Struct* Clone(CloneContext* ctx) const override;
/// The members
- const StructMemberList members;
+ const utils::Vector<const ast::StructMember*, 8> members;
/// The struct attributes
- const AttributeList attributes;
+ const utils::Vector<const ast::Attribute*, 4> attributes;
};
} // namespace tint::ast
diff --git a/src/tint/ast/struct_member.cc b/src/tint/ast/struct_member.cc
index 72acd33..22de044 100644
--- a/src/tint/ast/struct_member.cc
+++ b/src/tint/ast/struct_member.cc
@@ -25,7 +25,7 @@
const Source& src,
const Symbol& sym,
const ast::Type* ty,
- AttributeList attrs)
+ utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src), symbol(sym), type(ty), attributes(std::move(attrs)) {
TINT_ASSERT(AST, type);
TINT_ASSERT(AST, symbol.IsValid());
@@ -46,7 +46,7 @@
auto sym = ctx->Clone(symbol);
auto* ty = ctx->Clone(type);
auto attrs = ctx->Clone(attributes);
- return ctx->dst->create<StructMember>(src, sym, ty, attrs);
+ return ctx->dst->create<StructMember>(src, sym, ty, std::move(attrs));
}
} // namespace tint::ast
diff --git a/src/tint/ast/struct_member.h b/src/tint/ast/struct_member.h
index 39c8532..fc616d7 100644
--- a/src/tint/ast/struct_member.h
+++ b/src/tint/ast/struct_member.h
@@ -16,7 +16,6 @@
#define SRC_TINT_AST_STRUCT_MEMBER_H_
#include <utility>
-#include <vector>
#include "src/tint/ast/attribute.h"
@@ -42,7 +41,7 @@
const Source& src,
const Symbol& sym,
const ast::Type* type,
- AttributeList attributes);
+ utils::VectorRef<const Attribute*> attributes);
/// Move constructor
StructMember(StructMember&&);
@@ -61,12 +60,9 @@
const ast::Type* const type;
/// The attributes
- const AttributeList attributes;
+ const utils::Vector<const Attribute*, 4> attributes;
};
-/// A list of struct members
-using StructMemberList = std::vector<const StructMember*>;
-
} // namespace tint::ast
#endif // SRC_TINT_AST_STRUCT_MEMBER_H_
diff --git a/src/tint/ast/struct_member_test.cc b/src/tint/ast/struct_member_test.cc
index cec82ae..69772f4 100644
--- a/src/tint/ast/struct_member_test.cc
+++ b/src/tint/ast/struct_member_test.cc
@@ -21,10 +21,10 @@
using StructMemberTest = TestHelper;
TEST_F(StructMemberTest, Creation) {
- auto* st = Member("a", ty.i32(), {MemberSize(4)});
+ auto* st = Member("a", ty.i32(), utils::Vector{MemberSize(4)});
EXPECT_EQ(st->symbol, Symbol(1, ID()));
EXPECT_TRUE(st->type->Is<ast::I32>());
- EXPECT_EQ(st->attributes.size(), 1u);
+ EXPECT_EQ(st->attributes.Length(), 1u);
EXPECT_TRUE(st->attributes[0]->Is<StructMemberSizeAttribute>());
EXPECT_EQ(st->source.range.begin.line, 0u);
EXPECT_EQ(st->source.range.begin.column, 0u);
@@ -37,7 +37,7 @@
ty.i32());
EXPECT_EQ(st->symbol, Symbol(1, ID()));
EXPECT_TRUE(st->type->Is<ast::I32>());
- EXPECT_EQ(st->attributes.size(), 0u);
+ EXPECT_EQ(st->attributes.Length(), 0u);
EXPECT_EQ(st->source.range.begin.line, 27u);
EXPECT_EQ(st->source.range.begin.column, 4u);
EXPECT_EQ(st->source.range.end.line, 27u);
@@ -66,7 +66,7 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- b.Member("a", b.ty.i32(), {b.MemberSize(4), nullptr});
+ b.Member("a", b.ty.i32(), utils::Vector{b.MemberSize(4), nullptr});
},
"internal compiler error");
}
@@ -76,7 +76,7 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.Member(b2.Sym("a"), b1.ty.i32(), {b1.MemberSize(4)});
+ b1.Member(b2.Sym("a"), b1.ty.i32(), utils::Vector{b1.MemberSize(4)});
},
"internal compiler error");
}
@@ -86,7 +86,7 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.Member("a", b1.ty.i32(), {b2.MemberSize(4)});
+ b1.Member("a", b1.ty.i32(), utils::Vector{b2.MemberSize(4)});
},
"internal compiler error");
}
diff --git a/src/tint/ast/struct_test.cc b/src/tint/ast/struct_test.cc
index a94ceb3..53ec9c8 100644
--- a/src/tint/ast/struct_test.cc
+++ b/src/tint/ast/struct_test.cc
@@ -36,10 +36,10 @@
TEST_F(AstStructTest, Creation) {
auto name = Sym("s");
- auto* s = create<Struct>(name, StructMemberList{Member("a", ty.i32())}, AttributeList{});
+ auto* s = create<Struct>(name, utils::Vector{Member("a", ty.i32())}, utils::Empty);
EXPECT_EQ(s->name, name);
- EXPECT_EQ(s->members.size(), 1u);
- EXPECT_TRUE(s->attributes.empty());
+ EXPECT_EQ(s->members.Length(), 1u);
+ EXPECT_TRUE(s->attributes.IsEmpty());
EXPECT_EQ(s->source.range.begin.line, 0u);
EXPECT_EQ(s->source.range.begin.column, 0u);
EXPECT_EQ(s->source.range.end.line, 0u);
@@ -48,13 +48,14 @@
TEST_F(AstStructTest, Creation_WithAttributes) {
auto name = Sym("s");
- AttributeList attrs;
- attrs.push_back(ASTNodes().Create<SpirvBlockAttribute>(ID(), AllocateNodeID()));
- auto* s = create<Struct>(name, StructMemberList{Member("a", ty.i32())}, attrs);
+ auto* s = create<Struct>(name, utils::Vector{Member("a", ty.i32())},
+ utils::Vector{
+ ASTNodes().Create<SpirvBlockAttribute>(ID(), AllocateNodeID()),
+ });
EXPECT_EQ(s->name, name);
- EXPECT_EQ(s->members.size(), 1u);
- ASSERT_EQ(s->attributes.size(), 1u);
+ EXPECT_EQ(s->members.Length(), 1u);
+ ASSERT_EQ(s->attributes.Length(), 1u);
EXPECT_TRUE(s->attributes[0]->Is<SpirvBlockAttribute>());
EXPECT_EQ(s->source.range.begin.line, 0u);
EXPECT_EQ(s->source.range.begin.column, 0u);
@@ -66,11 +67,11 @@
auto name = Sym("s");
auto* s = create<Struct>(
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}}, name,
- StructMemberList{Member("a", ty.i32())},
- AttributeList{ASTNodes().Create<SpirvBlockAttribute>(ID(), AllocateNodeID())});
+ utils::Vector{Member("a", ty.i32())},
+ utils::Vector{ASTNodes().Create<SpirvBlockAttribute>(ID(), AllocateNodeID())});
EXPECT_EQ(s->name, name);
- EXPECT_EQ(s->members.size(), 1u);
- ASSERT_EQ(s->attributes.size(), 1u);
+ EXPECT_EQ(s->members.Length(), 1u);
+ ASSERT_EQ(s->attributes.Length(), 1u);
EXPECT_TRUE(s->attributes[0]->Is<SpirvBlockAttribute>());
EXPECT_EQ(s->source.range.begin.line, 27u);
EXPECT_EQ(s->source.range.begin.column, 4u);
@@ -82,8 +83,8 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- b.create<Struct>(b.Sym("S"), StructMemberList{b.Member("a", b.ty.i32()), nullptr},
- AttributeList{});
+ b.create<Struct>(b.Sym("S"), utils::Vector{b.Member("a", b.ty.i32()), nullptr},
+ utils::Empty);
},
"internal compiler error");
}
@@ -92,8 +93,8 @@
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
- b.create<Struct>(b.Sym("S"), StructMemberList{b.Member("a", b.ty.i32())},
- AttributeList{nullptr});
+ b.create<Struct>(b.Sym("S"), utils::Vector{b.Member("a", b.ty.i32())},
+ utils::Vector<const ast::Attribute*, 1>{nullptr});
},
"internal compiler error");
}
@@ -103,8 +104,8 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<Struct>(b1.Sym("S"), StructMemberList{b2.Member("a", b2.ty.i32())},
- AttributeList{});
+ b1.create<Struct>(b1.Sym("S"), utils::Vector{b2.Member("a", b2.ty.i32())},
+ utils::Empty);
},
"internal compiler error");
}
@@ -114,8 +115,8 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<Struct>(b1.Sym("S"), StructMemberList{b1.Member("a", b1.ty.i32())},
- AttributeList{b2.ASTNodes().Create<SpirvBlockAttribute>(
+ b1.create<Struct>(b1.Sym("S"), utils::Vector{b1.Member("a", b1.ty.i32())},
+ utils::Vector{b2.ASTNodes().Create<SpirvBlockAttribute>(
b2.ID(), b2.AllocateNodeID())});
},
"internal compiler error");
diff --git a/src/tint/ast/switch_statement.cc b/src/tint/ast/switch_statement.cc
index 7abf0c0..1cdf8a4 100644
--- a/src/tint/ast/switch_statement.cc
+++ b/src/tint/ast/switch_statement.cc
@@ -14,6 +14,8 @@
#include "src/tint/ast/switch_statement.h"
+#include <utility>
+
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::SwitchStatement);
@@ -24,8 +26,8 @@
NodeID nid,
const Source& src,
const Expression* cond,
- CaseStatementList b)
- : Base(pid, nid, src), condition(cond), body(b) {
+ utils::VectorRef<const CaseStatement*> b)
+ : Base(pid, nid, src), condition(cond), body(std::move(b)) {
TINT_ASSERT(AST, condition);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, condition, program_id);
for (auto* stmt : body) {
@@ -43,7 +45,7 @@
auto src = ctx->Clone(source);
auto* cond = ctx->Clone(condition);
auto b = ctx->Clone(body);
- return ctx->dst->create<SwitchStatement>(src, cond, b);
+ return ctx->dst->create<SwitchStatement>(src, cond, std::move(b));
}
} // namespace tint::ast
diff --git a/src/tint/ast/switch_statement.h b/src/tint/ast/switch_statement.h
index c13ac88..82a9aa4 100644
--- a/src/tint/ast/switch_statement.h
+++ b/src/tint/ast/switch_statement.h
@@ -33,7 +33,7 @@
NodeID nid,
const Source& src,
const Expression* condition,
- CaseStatementList body);
+ utils::VectorRef<const CaseStatement*> body);
/// Move constructor
SwitchStatement(SwitchStatement&&);
~SwitchStatement() override;
@@ -51,7 +51,7 @@
const Expression* const condition;
/// The Switch body
- const CaseStatementList body;
+ const utils::Vector<const CaseStatement*, 4> body;
SwitchStatement(const SwitchStatement&) = delete;
};
diff --git a/src/tint/ast/switch_statement_test.cc b/src/tint/ast/switch_statement_test.cc
index 19d1cfb..0f66c61 100644
--- a/src/tint/ast/switch_statement_test.cc
+++ b/src/tint/ast/switch_statement_test.cc
@@ -25,54 +25,47 @@
using SwitchStatementTest = TestHelper;
TEST_F(SwitchStatementTest, Creation) {
- CaseSelectorList lit;
- lit.push_back(Expr(1_u));
-
+ auto* case_stmt = create<CaseStatement>(utils::Vector{Expr(1_u)}, Block());
auto* ident = Expr("ident");
- CaseStatementList body;
- auto* case_stmt = create<CaseStatement>(lit, Block());
- body.push_back(case_stmt);
+ utils::Vector body{case_stmt};
auto* stmt = create<SwitchStatement>(ident, body);
EXPECT_EQ(stmt->condition, ident);
- ASSERT_EQ(stmt->body.size(), 1u);
+ ASSERT_EQ(stmt->body.Length(), 1u);
EXPECT_EQ(stmt->body[0], case_stmt);
}
TEST_F(SwitchStatementTest, Creation_WithSource) {
auto* ident = Expr("ident");
-
- auto* stmt =
- create<SwitchStatement>(Source{Source::Location{20, 2}}, ident, CaseStatementList());
+ auto* stmt = create<SwitchStatement>(Source{Source::Location{20, 2}}, ident, utils::Empty);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(SwitchStatementTest, IsSwitch) {
- CaseSelectorList lit;
- lit.push_back(Expr(2_i));
-
+ utils::Vector lit{Expr(2_i)};
auto* ident = Expr("ident");
- CaseStatementList body;
- body.push_back(create<CaseStatement>(lit, Block()));
+ utils::Vector body{create<CaseStatement>(lit, Block())};
auto* stmt = create<SwitchStatement>(ident, body);
EXPECT_TRUE(stmt->Is<SwitchStatement>());
}
TEST_F(SwitchStatementTest, Assert_Null_Condition) {
+ using CaseStatementList = utils::Vector<const ast::CaseStatement*, 2>;
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
CaseStatementList cases;
- cases.push_back(b.create<CaseStatement>(CaseSelectorList{b.Expr(1_i)}, b.Block()));
+ cases.Push(b.create<CaseStatement>(utils::Vector{b.Expr(1_i)}, b.Block()));
b.create<SwitchStatement>(nullptr, cases);
},
"internal compiler error");
}
TEST_F(SwitchStatementTest, Assert_Null_CaseStatement) {
+ using CaseStatementList = utils::Vector<const ast::CaseStatement*, 2>;
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
@@ -86,9 +79,9 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<SwitchStatement>(b2.Expr(true), CaseStatementList{
+ b1.create<SwitchStatement>(b2.Expr(true), utils::Vector{
b1.create<CaseStatement>(
- CaseSelectorList{
+ utils::Vector{
b1.Expr(1_i),
},
b1.Block()),
@@ -102,9 +95,9 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.create<SwitchStatement>(b1.Expr(true), CaseStatementList{
+ b1.create<SwitchStatement>(b1.Expr(true), utils::Vector{
b2.create<CaseStatement>(
- CaseSelectorList{
+ utils::Vector{
b2.Expr(1_i),
},
b2.Block()),
diff --git a/src/tint/ast/traverse_expressions.h b/src/tint/ast/traverse_expressions.h
index 0974fd8..bcf0bfd 100644
--- a/src/tint/ast/traverse_expressions.h
+++ b/src/tint/ast/traverse_expressions.h
@@ -68,7 +68,7 @@
size_t depth;
};
- utils::Vector<Pending, 64> to_visit{{root, 0}};
+ utils::Vector<Pending, 32> to_visit{{root, 0}};
auto push_single = [&](const ast::Expression* expr, size_t depth) {
to_visit.Push({expr, depth});
@@ -82,7 +82,7 @@
to_visit.Push({right, depth});
}
};
- auto push_list = [&](const std::vector<const ast::Expression*>& exprs, size_t depth) {
+ auto push_list = [&](utils::VectorRef<const ast::Expression*> exprs, size_t depth) {
if (ORDER == TraverseOrder::LeftToRight) {
for (auto* expr : utils::Reverse(exprs)) {
to_visit.Push({expr, depth});
diff --git a/src/tint/ast/traverse_expressions_test.cc b/src/tint/ast/traverse_expressions_test.cc
index e79decb..a5a6dfd 100644
--- a/src/tint/ast/traverse_expressions_test.cc
+++ b/src/tint/ast/traverse_expressions_test.cc
@@ -97,19 +97,19 @@
auto* b2 = Bitcast<i32>(b1);
auto* root = Bitcast<i32>(b2);
{
- std::vector<const ast::Expression*> l2r;
+ utils::Vector<const ast::Expression*, 8> l2r;
TraverseExpressions<TraverseOrder::LeftToRight>(root, Diagnostics(),
[&](const ast::Expression* expr) {
- l2r.push_back(expr);
+ l2r.Push(expr);
return ast::TraverseAction::Descend;
});
EXPECT_THAT(l2r, ElementsAre(root, b2, b1, b0, e));
}
{
- std::vector<const ast::Expression*> r2l;
+ utils::Vector<const ast::Expression*, 8> r2l;
TraverseExpressions<TraverseOrder::RightToLeft>(root, Diagnostics(),
[&](const ast::Expression* expr) {
- r2l.push_back(expr);
+ r2l.Push(expr);
return ast::TraverseAction::Descend;
});
EXPECT_THAT(r2l, ElementsAre(root, b2, b1, b0, e));
@@ -117,23 +117,23 @@
}
TEST_F(TraverseExpressionsTest, DescendCallExpression) {
- std::vector<const ast::Expression*> e = {Expr(1_i), Expr(1_i), Expr(1_i), Expr(1_i)};
- std::vector<const ast::Expression*> c = {Call("a", e[0], e[1]), Call("b", e[2], e[3])};
+ utils::Vector e{Expr(1_i), Expr(1_i), Expr(1_i), Expr(1_i)};
+ utils::Vector c{Call("a", e[0], e[1]), Call("b", e[2], e[3])};
auto* root = Call("c", c[0], c[1]);
{
- std::vector<const ast::Expression*> l2r;
+ utils::Vector<const ast::Expression*, 8> l2r;
TraverseExpressions<TraverseOrder::LeftToRight>(root, Diagnostics(),
[&](const ast::Expression* expr) {
- l2r.push_back(expr);
+ l2r.Push(expr);
return ast::TraverseAction::Descend;
});
EXPECT_THAT(l2r, ElementsAre(root, c[0], e[0], e[1], c[1], e[2], e[3]));
}
{
- std::vector<const ast::Expression*> r2l;
+ utils::Vector<const ast::Expression*, 8> r2l;
TraverseExpressions<TraverseOrder::RightToLeft>(root, Diagnostics(),
[&](const ast::Expression* expr) {
- r2l.push_back(expr);
+ r2l.Push(expr);
return ast::TraverseAction::Descend;
});
EXPECT_THAT(r2l, ElementsAre(root, c[1], e[3], e[2], c[0], e[1], e[0]));
diff --git a/src/tint/ast/var.cc b/src/tint/ast/var.cc
index 763949f..474cff2 100644
--- a/src/tint/ast/var.cc
+++ b/src/tint/ast/var.cc
@@ -28,8 +28,8 @@
StorageClass storage_class,
Access access,
const Expression* ctor,
- AttributeList attrs)
- : Base(pid, nid, src, sym, ty, ctor, attrs),
+ utils::VectorRef<const Attribute*> attrs)
+ : Base(pid, nid, src, sym, ty, ctor, std::move(attrs)),
declared_storage_class(storage_class),
declared_access(access) {}
@@ -48,7 +48,7 @@
auto* ctor = ctx->Clone(constructor);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Var>(src, sym, ty, declared_storage_class, declared_access, ctor,
- attrs);
+ std::move(attrs));
}
} // namespace tint::ast
diff --git a/src/tint/ast/var.h b/src/tint/ast/var.h
index cd12ff4..908a9b3 100644
--- a/src/tint/ast/var.h
+++ b/src/tint/ast/var.h
@@ -59,7 +59,7 @@
StorageClass declared_storage_class,
Access declared_access,
const Expression* constructor,
- AttributeList attributes);
+ utils::VectorRef<const Attribute*> attributes);
/// Move constructor
Var(Var&&);
diff --git a/src/tint/ast/variable.cc b/src/tint/ast/variable.cc
index b16b2aa..ec87e54 100644
--- a/src/tint/ast/variable.cc
+++ b/src/tint/ast/variable.cc
@@ -26,7 +26,7 @@
const Symbol& sym,
const ast::Type* ty,
const Expression* ctor,
- AttributeList attrs)
+ utils::VectorRef<const Attribute*> attrs)
: Base(pid, nid, src), symbol(sym), type(ty), constructor(ctor), attributes(std::move(attrs)) {
TINT_ASSERT(AST, symbol.IsValid());
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
diff --git a/src/tint/ast/variable.h b/src/tint/ast/variable.h
index 3031318..1f5d77a 100644
--- a/src/tint/ast/variable.h
+++ b/src/tint/ast/variable.h
@@ -67,7 +67,7 @@
const Symbol& sym,
const ast::Type* type,
const Expression* constructor,
- AttributeList attributes);
+ utils::VectorRef<const Attribute*> attributes);
/// Move constructor
Variable(Variable&&);
@@ -95,12 +95,9 @@
const Expression* const constructor;
/// The attributes attached to this variable
- const AttributeList attributes;
+ const utils::Vector<const Attribute*, 2> attributes;
};
-/// A list of variables
-using VariableList = std::vector<const Variable*>;
-
} // namespace tint::ast
#endif // SRC_TINT_AST_VARIABLE_H_
diff --git a/src/tint/ast/variable_test.cc b/src/tint/ast/variable_test.cc
index a54e869..b226994 100644
--- a/src/tint/ast/variable_test.cc
+++ b/src/tint/ast/variable_test.cc
@@ -38,7 +38,7 @@
TEST_F(VariableTest, CreationWithSource) {
auto* v = Var(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}}, "i",
- ty.f32(), StorageClass::kPrivate, nullptr, AttributeList{});
+ ty.f32(), StorageClass::kPrivate, nullptr, utils::Empty);
EXPECT_EQ(v->symbol, Symbol(1, ID()));
EXPECT_EQ(v->declared_storage_class, StorageClass::kPrivate);
@@ -51,7 +51,7 @@
TEST_F(VariableTest, CreationEmpty) {
auto* v = Var(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}}, "a_var",
- ty.i32(), StorageClass::kWorkgroup, nullptr, AttributeList{});
+ ty.i32(), StorageClass::kWorkgroup, nullptr, utils::Empty);
EXPECT_EQ(v->symbol, Symbol(1, ID()));
EXPECT_EQ(v->declared_storage_class, StorageClass::kWorkgroup);
@@ -93,7 +93,7 @@
TEST_F(VariableTest, WithAttributes) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
- AttributeList{
+ utils::Vector{
create<LocationAttribute>(1u),
create<BuiltinAttribute>(BuiltinValue::kPosition),
create<IdAttribute>(1200u),
@@ -111,7 +111,7 @@
TEST_F(VariableTest, BindingPoint) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
- AttributeList{
+ utils::Vector{
create<BindingAttribute>(2u),
create<GroupAttribute>(1u),
});
@@ -123,7 +123,7 @@
}
TEST_F(VariableTest, BindingPointAttributes) {
- auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr, AttributeList{});
+ auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr, utils::Empty);
EXPECT_FALSE(var->BindingPoint());
EXPECT_EQ(var->BindingPoint().group, nullptr);
EXPECT_EQ(var->BindingPoint().binding, nullptr);
@@ -131,7 +131,7 @@
TEST_F(VariableTest, BindingPointMissingGroupAttribute) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
- AttributeList{
+ utils::Vector{
create<BindingAttribute>(2u),
});
EXPECT_FALSE(var->BindingPoint());
@@ -142,7 +142,7 @@
TEST_F(VariableTest, BindingPointMissingBindingAttribute) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
- AttributeList{create<GroupAttribute>(1u)});
+ utils::Vector{create<GroupAttribute>(1u)});
EXPECT_FALSE(var->BindingPoint());
ASSERT_NE(var->BindingPoint().group, nullptr);
EXPECT_EQ(var->BindingPoint().group->value, 1u);
diff --git a/src/tint/clone_context.cc b/src/tint/clone_context.cc
index 513c710..1225294 100644
--- a/src/tint/clone_context.cc
+++ b/src/tint/clone_context.cc
@@ -62,7 +62,7 @@
ast::FunctionList CloneContext::Clone(const ast::FunctionList& v) {
ast::FunctionList out;
- out.reserve(v.size());
+ out.Reserve(v.Length());
for (const ast::Function* el : v) {
out.Add(Clone(el));
}
diff --git a/src/tint/clone_context.h b/src/tint/clone_context.h
index e8e197f..e7e2d52 100644
--- a/src/tint/clone_context.h
+++ b/src/tint/clone_context.h
@@ -28,6 +28,7 @@
#include "src/tint/program_id.h"
#include "src/tint/symbol.h"
#include "src/tint/traits.h"
+#include "src/tint/utils/vector.h"
// Forward declarations
namespace tint {
@@ -163,12 +164,12 @@
///
/// @param v the vector to clone
/// @return the cloned vector
- template <typename T, typename A>
- std::vector<T> Clone(const std::vector<T, A>& v) {
- std::vector<T> out;
+ template <typename T, size_t N>
+ utils::Vector<T, N> Clone(const utils::Vector<T, N>& v) {
+ utils::Vector<T, N> out;
out.reserve(v.size());
for (auto& el : v) {
- out.emplace_back(Clone(el));
+ out.Push(Clone(el));
}
return out;
}
@@ -181,9 +182,9 @@
///
/// @param v the vector to clone
/// @return the cloned vector
- template <typename T, typename A>
- std::vector<T*, A> Clone(const std::vector<T*, A>& v) {
- std::vector<T*, A> out;
+ template <typename T, size_t N>
+ utils::Vector<T*, N> Clone(const utils::Vector<T*, N>& v) {
+ utils::Vector<T*, N> out;
Clone(out, v);
return out;
}
@@ -196,39 +197,39 @@
///
/// @param from the vector to clone
/// @param to the cloned result
- template <typename T, typename A>
- void Clone(std::vector<T*, A>& to, const std::vector<T*, A>& from) {
- to.reserve(from.size());
+ template <typename T, size_t N>
+ void Clone(utils::Vector<T*, N>& to, const utils::Vector<T*, N>& from) {
+ to.Reserve(from.Length());
auto list_transform_it = list_transforms_.find(&from);
if (list_transform_it != list_transforms_.end()) {
const auto& transforms = list_transform_it->second;
for (auto* o : transforms.insert_front_) {
- to.emplace_back(CheckedCast<T>(o));
+ to.Push(CheckedCast<T>(o));
}
for (auto& el : from) {
auto insert_before_it = transforms.insert_before_.find(el);
if (insert_before_it != transforms.insert_before_.end()) {
for (auto insert : insert_before_it->second) {
- to.emplace_back(CheckedCast<T>(insert));
+ to.Push(CheckedCast<T>(insert));
}
}
if (transforms.remove_.count(el) == 0) {
- to.emplace_back(Clone(el));
+ to.Push(Clone(el));
}
auto insert_after_it = transforms.insert_after_.find(el);
if (insert_after_it != transforms.insert_after_.end()) {
for (auto insert : insert_after_it->second) {
- to.emplace_back(CheckedCast<T>(insert));
+ to.Push(CheckedCast<T>(insert));
}
}
}
for (auto* o : transforms.insert_back_) {
- to.emplace_back(CheckedCast<T>(o));
+ to.Push(CheckedCast<T>(o));
}
} else {
for (auto& el : from) {
- to.emplace_back(Clone(el));
+ to.Push(Clone(el));
// Clone(el) may have inserted after
list_transform_it = list_transforms_.find(&from);
@@ -238,7 +239,7 @@
auto insert_after_it = transforms.insert_after_.find(el);
if (insert_after_it != transforms.insert_after_.end()) {
for (auto insert : insert_after_it->second) {
- to.emplace_back(CheckedCast<T>(insert));
+ to.Push(CheckedCast<T>(insert));
}
}
}
@@ -250,7 +251,7 @@
const auto& transforms = list_transform_it->second;
for (auto* o : transforms.insert_back_) {
- to.emplace_back(CheckedCast<T>(o));
+ to.Push(CheckedCast<T>(o));
}
}
}
@@ -318,7 +319,7 @@
CloneableTransform transform;
transform.typeinfo = &TypeInfo::Of<T>();
transform.function = [=](const Cloneable* in) { return replacer(in->As<T>()); };
- transforms_.emplace_back(std::move(transform));
+ transforms_.Push(std::move(transform));
return *this;
}
@@ -386,8 +387,8 @@
/// @param object a pointer to the object in #src that will be omitted from
/// the cloned vector.
/// @returns this CloneContext so calls can be chained
- template <typename T, typename A, typename OBJECT>
- CloneContext& Remove(const std::vector<T, A>& vector, OBJECT* object) {
+ template <typename T, size_t N, typename OBJECT>
+ CloneContext& Remove(const utils::Vector<T, N>& vector, OBJECT* object) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, object);
if (std::find(vector.begin(), vector.end(), object) == vector.end()) {
TINT_ICE(Clone, Diagnostics())
@@ -404,12 +405,12 @@
/// @param object a pointer to the object in #dst that will be inserted at the
/// front of the vector
/// @returns this CloneContext so calls can be chained
- template <typename T, typename A, typename OBJECT>
- CloneContext& InsertFront(const std::vector<T, A>& vector, OBJECT* object) {
+ template <typename T, size_t N, typename OBJECT>
+ CloneContext& InsertFront(const utils::Vector<T, N>& vector, OBJECT* object) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, object);
auto& transforms = list_transforms_[&vector];
auto& list = transforms.insert_front_;
- list.emplace_back(object);
+ list.Push(object);
return *this;
}
@@ -418,12 +419,12 @@
/// @param object a pointer to the object in #dst that will be inserted at the
/// end of the vector
/// @returns this CloneContext so calls can be chained
- template <typename T, typename A, typename OBJECT>
- CloneContext& InsertBack(const std::vector<T, A>& vector, OBJECT* object) {
+ template <typename T, size_t N, typename OBJECT>
+ CloneContext& InsertBack(const utils::Vector<T, N>& vector, OBJECT* object) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, object);
auto& transforms = list_transforms_[&vector];
auto& list = transforms.insert_back_;
- list.emplace_back(object);
+ list.Push(object);
return *this;
}
@@ -433,8 +434,8 @@
/// @param object a pointer to the object in #dst that will be inserted before
/// any occurrence of the clone of `before`
/// @returns this CloneContext so calls can be chained
- template <typename T, typename A, typename BEFORE, typename OBJECT>
- CloneContext& InsertBefore(const std::vector<T, A>& vector,
+ template <typename T, size_t N, typename BEFORE, typename OBJECT>
+ CloneContext& InsertBefore(const utils::Vector<T, N>& vector,
const BEFORE* before,
const OBJECT* object) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, before);
@@ -447,7 +448,7 @@
auto& transforms = list_transforms_[&vector];
auto& list = transforms.insert_before_[before];
- list.emplace_back(object);
+ list.Push(object);
return *this;
}
@@ -457,8 +458,8 @@
/// @param object a pointer to the object in #dst that will be inserted after
/// any occurrence of the clone of `after`
/// @returns this CloneContext so calls can be chained
- template <typename T, typename A, typename AFTER, typename OBJECT>
- CloneContext& InsertAfter(const std::vector<T, A>& vector,
+ template <typename T, size_t N, typename AFTER, typename OBJECT>
+ CloneContext& InsertAfter(const utils::Vector<T, N>& vector,
const AFTER* after,
const OBJECT* object) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, after);
@@ -471,7 +472,7 @@
auto& transforms = list_transforms_[&vector];
auto& list = transforms.insert_after_[after];
- list.emplace_back(object);
+ list.Push(object);
return *this;
}
@@ -530,7 +531,7 @@
diag::List& Diagnostics() const;
/// A vector of const Cloneable*
- using CloneableList = std::vector<const Cloneable*>;
+ using CloneableList = utils::Vector<const Cloneable*, 4>;
/// Transformations to be applied to a list (vector)
struct ListTransforms {
@@ -551,12 +552,12 @@
CloneableList insert_back_;
/// A map of object in #src to the list of cloned objects in #dst.
- /// Clone(const std::vector<T*>& v) will use this to insert the map-value
+ /// Clone(const utils::Vector<T*>& v) will use this to insert the map-value
/// list into the target vector before cloning and inserting the map-key.
std::unordered_map<const Cloneable*, CloneableList> insert_before_;
/// A map of object in #src to the list of cloned objects in #dst.
- /// Clone(const std::vector<T*>& v) will use this to insert the map-value
+ /// Clone(const utils::Vector<T*>& v) will use this to insert the map-value
/// list into the target vector after cloning and inserting the map-key.
std::unordered_map<const Cloneable*, CloneableList> insert_after_;
};
@@ -569,9 +570,9 @@
std::unordered_map<Symbol, Symbol> cloned_symbols_;
/// Cloneable transform functions registered with ReplaceAll()
- std::vector<CloneableTransform> transforms_;
+ utils::Vector<CloneableTransform, 8> transforms_;
- /// Map of std::vector pointer to transforms for that list
+ /// Map of utils::Vector pointer to transforms for that list
std::unordered_map<const void*, ListTransforms> list_transforms_;
/// Symbol transform registered with ReplaceAll()
diff --git a/src/tint/clone_context_test.cc b/src/tint/clone_context_test.cc
index 46cc720..c895151 100644
--- a/src/tint/clone_context_test.cc
+++ b/src/tint/clone_context_test.cc
@@ -37,12 +37,13 @@
const Node* node_b = nullptr,
const Node* node_c = nullptr)
: allocator(alloc), name(n), a(node_a), b(node_b), c(node_c) {}
+ Node(Node&&) = delete;
Allocator* const allocator;
Symbol name;
const Node* a = nullptr;
const Node* b = nullptr;
const Node* c = nullptr;
- std::vector<const Node*> vec;
+ utils::Vector<const Node*, 8> vec;
Node* Clone(CloneContext* ctx) const override {
auto* out = allocator->Create<Node>(ctx->Clone(name));
@@ -387,7 +388,7 @@
.Remove(original_root->vec, original_root->vec[1])
.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 2u);
+ EXPECT_EQ(cloned_root->vec.Length(), 2u);
EXPECT_NE(cloned_root->vec[0], cloned_root->a);
EXPECT_NE(cloned_root->vec[1], cloned_root->c);
@@ -416,7 +417,7 @@
.InsertFront(original_root->vec, insertion)
.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 4u);
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
EXPECT_NE(cloned_root->vec[0], cloned_root->a);
EXPECT_NE(cloned_root->vec[1], cloned_root->b);
@@ -434,7 +435,7 @@
ProgramBuilder builder;
auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
- original_root->vec = {};
+ original_root->vec.Clear();
Program original(std::move(builder));
ProgramBuilder cloned;
@@ -444,7 +445,7 @@
.InsertFront(original_root->vec, insertion)
.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 1u);
+ EXPECT_EQ(cloned_root->vec.Length(), 1u);
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion"));
@@ -469,7 +470,7 @@
.InsertBack(original_root->vec, insertion)
.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 4u);
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
@@ -483,7 +484,7 @@
ProgramBuilder builder;
auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
- original_root->vec = {};
+ original_root->vec.Clear();
Program original(std::move(builder));
ProgramBuilder cloned;
@@ -493,7 +494,7 @@
.InsertBack(original_root->vec, insertion)
.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 1u);
+ EXPECT_EQ(cloned_root->vec.Length(), 1u);
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion"));
@@ -504,7 +505,7 @@
ProgramBuilder builder;
auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
- original_root->vec = {};
+ original_root->vec.Clear();
Program original(std::move(builder));
ProgramBuilder cloned;
@@ -516,7 +517,7 @@
.InsertFront(original_root->vec, insertion_front)
.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 2u);
+ EXPECT_EQ(cloned_root->vec.Length(), 2u);
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion_front"));
@@ -542,7 +543,7 @@
.InsertBefore(original_root->vec, original_root->vec[1], insertion)
.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 4u);
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
@@ -570,7 +571,7 @@
.InsertAfter(original_root->vec, original_root->vec[1], insertion)
.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 4u);
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
@@ -602,7 +603,7 @@
auto* cloned_root = ctx.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 4u);
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
@@ -634,7 +635,7 @@
auto* cloned_root = ctx.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 4u);
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
@@ -666,7 +667,7 @@
.Remove(original_root->vec, original_root->vec[1])
.Clone(original_root);
- EXPECT_EQ(cloned_root->vec.size(), 4u);
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
diff --git a/src/tint/cmd/main.cc b/src/tint/cmd/main.cc
index c38e6f9..6f12348 100644
--- a/src/tint/cmd/main.cc
+++ b/src/tint/cmd/main.cc
@@ -32,6 +32,7 @@
#include "spirv-tools/libspirv.hpp"
#endif // TINT_BUILD_SPV_READER
+#include "src/tint/ast/module.h"
#include "src/tint/utils/io/command.h"
#include "src/tint/utils/string.h"
#include "src/tint/utils/transform.h"
@@ -820,7 +821,18 @@
tint::utils::Command::LookPath(options.dxc_path.empty() ? "dxc" : options.dxc_path);
if (dxc.Found()) {
dxc_found = true;
- dxc_res = tint::val::HlslUsingDXC(dxc.Path(), result.hlsl, result.entry_points);
+
+ auto enable_list = program->AST().Enables();
+ bool dxc_require_16bit_types = false;
+ for (auto enable : enable_list) {
+ if (enable->extension == tint::ast::Extension::kF16) {
+ dxc_require_16bit_types = true;
+ break;
+ }
+ }
+
+ dxc_res = tint::val::HlslUsingDXC(dxc.Path(), result.hlsl, result.entry_points,
+ dxc_require_16bit_types);
} else if (must_validate_dxc) {
// DXC was explicitly requested. Error if it could not be found.
dxc_res.failed = true;
diff --git a/src/tint/fuzzers/fuzzer_init.cc b/src/tint/fuzzers/fuzzer_init.cc
index 3d3f692..66f701a 100644
--- a/src/tint/fuzzers/fuzzer_init.cc
+++ b/src/tint/fuzzers/fuzzer_init.cc
@@ -12,8 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "src/tint/fuzzers/fuzzer_init.h"
+#include <cstddef>
+
#include "src/tint/fuzzers/cli.h"
+#include "src/tint/fuzzers/fuzzer_init.h"
+#include "testing/libfuzzer/libfuzzer_exports.h"
namespace tint::fuzzers {
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/BUILD.gn b/src/tint/fuzzers/tint_ast_fuzzer/BUILD.gn
index 69ef3fe..58a36ea 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/BUILD.gn
+++ b/src/tint/fuzzers/tint_ast_fuzzer/BUILD.gn
@@ -46,6 +46,8 @@
"expression_size.cc",
"expression_size.h",
"fuzzer.cc",
+ "jump_tracker.cc",
+ "jump_tracker.h",
"mutation.cc",
"mutation.h",
"mutation_finder.cc",
@@ -54,6 +56,8 @@
"mutation_finders/change_binary_operators.h",
"mutation_finders/change_unary_operators.cc",
"mutation_finders/change_unary_operators.h",
+ "mutation_finders/delete_statements.cc",
+ "mutation_finders/delete_statements.h",
"mutation_finders/replace_identifiers.cc",
"mutation_finders/replace_identifiers.h",
"mutation_finders/wrap_unary_operators.cc",
@@ -62,6 +66,8 @@
"mutations/change_binary_operator.h",
"mutations/change_unary_operator.cc",
"mutations/change_unary_operator.h",
+ "mutations/delete_statement.cc",
+ "mutations/delete_statement.h",
"mutations/replace_identifier.cc",
"mutations/replace_identifier.h",
"mutations/wrap_unary_operator.cc",
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/CMakeLists.txt b/src/tint/fuzzers/tint_ast_fuzzer/CMakeLists.txt
index 5bd8c50..0d1f5a2 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/CMakeLists.txt
+++ b/src/tint/fuzzers/tint_ast_fuzzer/CMakeLists.txt
@@ -39,14 +39,17 @@
../random_generator.h
../random_generator_engine.h
expression_size.h
+ jump_tracker.h
mutation.h
mutation_finder.h
mutation_finders/change_binary_operators.h
mutation_finders/change_unary_operators.h
+ mutation_finders/delete_statements.h
mutation_finders/replace_identifiers.h
mutation_finders/wrap_unary_operators.h
mutations/change_binary_operator.h
mutations/change_unary_operator.h
+ mutations/delete_statement.h
mutations/replace_identifier.h
mutations/wrap_unary_operator.h
mutator.h
@@ -61,14 +64,17 @@
../random_generator.cc
../random_generator_engine.cc
expression_size.cc
+ jump_tracker.cc
mutation.cc
mutation_finder.cc
mutation_finders/change_binary_operators.cc
mutation_finders/change_unary_operators.cc
+ mutation_finders/delete_statements.cc
mutation_finders/replace_identifiers.cc
mutation_finders/wrap_unary_operators.cc
mutations/change_binary_operator.cc
mutations/change_unary_operator.cc
+ mutations/delete_statement.cc
mutations/replace_identifier.cc
mutations/wrap_unary_operator.cc
mutator.cc
@@ -107,8 +113,10 @@
if (${TINT_BUILD_TESTS})
set(TEST_SOURCES
expression_size_test.cc
+ jump_tracker_test.cc
mutations/change_binary_operator_test.cc
mutations/change_unary_operator_test.cc
+ mutations/delete_statement_test.cc
mutations/replace_identifier_test.cc
mutations/wrap_unary_operator_test.cc)
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/fuzzer.cc b/src/tint/fuzzers/tint_ast_fuzzer/fuzzer.cc
index 20601df..383135d 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/fuzzer.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/fuzzer.cc
@@ -21,9 +21,9 @@
#include "src/tint/fuzzers/tint_ast_fuzzer/override_cli_params.h"
#include "src/tint/fuzzers/tint_common_fuzzer.h"
#include "src/tint/fuzzers/transform_builder.h"
-
#include "src/tint/reader/wgsl/parser.h"
#include "src/tint/writer/wgsl/generator.h"
+#include "testing/libfuzzer/libfuzzer_exports.h"
namespace tint::fuzzers::ast_fuzzer {
namespace {
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.cc b/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.cc
new file mode 100644
index 0000000..66bbaf7
--- /dev/null
+++ b/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.cc
@@ -0,0 +1,83 @@
+// Copyright 2022 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/fuzzers/tint_ast_fuzzer/jump_tracker.h"
+
+#include <cassert>
+#include <unordered_set>
+
+#include "src/tint/ast/break_statement.h"
+#include "src/tint/ast/discard_statement.h"
+#include "src/tint/ast/for_loop_statement.h"
+#include "src/tint/ast/loop_statement.h"
+#include "src/tint/ast/return_statement.h"
+#include "src/tint/ast/switch_statement.h"
+#include "src/tint/ast/while_statement.h"
+#include "src/tint/sem/statement.h"
+
+namespace tint::fuzzers::ast_fuzzer {
+
+JumpTracker::JumpTracker(const Program& program) {
+ // Consider every AST node, looking for break, return and discard statements.
+ for (auto* node : program.ASTNodes().Objects()) {
+ auto* stmt = node->As<ast::Statement>();
+ if (stmt == nullptr) {
+ continue;
+ }
+ if (stmt->As<ast::BreakStatement>()) {
+ // This break statement either exits a loop or a switch statement.
+ // Walk up the AST until either a loop or switch statement is found. In the former case,
+ // it is the innermost loop containing the break statement, and thus all the nodes
+ // encountered along the way are nodes that contain a break from the innermost loop.
+
+ // This records the statements encountered when walking up the AST from the break
+ // statement to the innermost enclosing loop or switch statement.
+ std::unordered_set<const ast::Statement*> candidate_statements;
+ for (const ast::Statement* current = stmt;;
+ current =
+ As<sem::Statement>(program.Sem().Get(current))->Parent()->Declaration()) {
+ if (current->Is<ast::ForLoopStatement>() || current->Is<ast::LoopStatement>() ||
+ current->Is<ast::WhileStatement>()) {
+ // A loop has been encountered, thus all that statements recorded until this
+ // point contain a break from their innermost loop.
+ for (auto* candidate : candidate_statements) {
+ contains_break_for_innermost_loop_.insert(candidate);
+ }
+ break;
+ }
+ if (current->Is<ast::SwitchStatement>()) {
+ // A switch statement has been encountered, so the break does not correspond to
+ // a loop break.
+ break;
+ }
+ candidate_statements.insert(current);
+ }
+ } else if (stmt->As<ast::ReturnStatement>() || stmt->As<ast::DiscardStatement>()) {
+ // Walk up the AST from the return or discard statement, recording that every node
+ // encountered along the way contains a return/discard.
+ auto& target_set = stmt->As<ast::ReturnStatement>() ? contains_return_
+ : contains_intraprocedural_discard_;
+ const ast::Statement* current = stmt;
+ while (true) {
+ target_set.insert(current);
+ auto* parent = program.Sem().Get(current)->Parent();
+ if (parent == nullptr) {
+ break;
+ }
+ current = parent->Declaration();
+ }
+ }
+ }
+}
+} // namespace tint::fuzzers::ast_fuzzer
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.h b/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.h
new file mode 100644
index 0000000..614ceb5
--- /dev/null
+++ b/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.h
@@ -0,0 +1,68 @@
+// Copyright 2022 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.
+
+#ifndef SRC_TINT_FUZZERS_TINT_AST_FUZZER_JUMP_TRACKER_H_
+#define SRC_TINT_FUZZERS_TINT_AST_FUZZER_JUMP_TRACKER_H_
+
+#include <unordered_set>
+
+#include "src/tint/ast/statement.h"
+#include "src/tint/program.h"
+
+namespace tint::fuzzers::ast_fuzzer {
+
+/// This class computes information on which statements contain loop breaks, returns and discards.
+/// It could be extended to handle other jumps, such as switch breaks and loop continues, should
+/// such information prove useful.
+class JumpTracker {
+ public:
+ /// Initializes jump tracking information for the given program.
+ /// @param program - the program for which jumps will be tracked;
+ /// must remain in scope as long as this instance exists.
+ explicit JumpTracker(const Program& program);
+
+ /// Indicates whether a statement contains a break statement for the innermost loop (if any).
+ /// @param statement - the statement of interest.
+ /// @return true if and only if the statement is, or contains, a break for the innermost
+ /// enclosing loop.
+ bool ContainsBreakForInnermostLoop(const ast::Statement& statement) const {
+ return contains_break_for_innermost_loop_.count(&statement) > 0;
+ }
+
+ /// Indicates whether a statement contains a return statement.
+ /// @param statement - the statement of interest.
+ /// @return true if and only if the statement is, or contains, a return statement.
+ bool ContainsReturn(const ast::Statement& statement) const {
+ return contains_return_.count(&statement) > 0;
+ }
+
+ /// Indicates whether a statement contains a discard statement.
+ /// @param statement - the statement of interest.
+ /// @return true if and only if the statement is, or contains, a discard statement. This is
+ /// determined in an intraprocedural fashion: the answer will be "false" if no discard occurs
+ /// inside the statement, even if the statement calls a function that may lead to a discard
+ /// being performed.
+ bool ContainsIntraproceduralDiscard(const ast::Statement& statement) const {
+ return contains_intraprocedural_discard_.count(&statement) > 0;
+ }
+
+ private:
+ std::unordered_set<const ast::Statement*> contains_break_for_innermost_loop_;
+ std::unordered_set<const ast::Statement*> contains_return_;
+ std::unordered_set<const ast::Statement*> contains_intraprocedural_discard_;
+};
+
+} // namespace tint::fuzzers::ast_fuzzer
+
+#endif // SRC_TINT_FUZZERS_TINT_AST_FUZZER_JUMP_TRACKER_H_
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker_test.cc
new file mode 100644
index 0000000..f83e639
--- /dev/null
+++ b/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker_test.cc
@@ -0,0 +1,332 @@
+// Copyright 2022 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/fuzzers/tint_ast_fuzzer/jump_tracker.h"
+
+#include <string>
+
+#include "gtest/gtest.h"
+
+#include "src/tint/ast/block_statement.h"
+#include "src/tint/ast/break_statement.h"
+#include "src/tint/ast/discard_statement.h"
+#include "src/tint/ast/for_loop_statement.h"
+#include "src/tint/ast/if_statement.h"
+#include "src/tint/ast/loop_statement.h"
+#include "src/tint/ast/module.h"
+#include "src/tint/ast/return_statement.h"
+#include "src/tint/ast/switch_statement.h"
+#include "src/tint/ast/while_statement.h"
+#include "src/tint/program.h"
+#include "src/tint/reader/wgsl/parser.h"
+
+namespace tint::fuzzers::ast_fuzzer {
+namespace {
+
+TEST(JumpTrackerTest, Breaks) {
+ std::string content = R"(
+fn main() {
+ var x : u32;
+ for (var i : i32 = 0; i < 100; i++) {
+ if (i == 40) {
+ {
+ break;
+ }
+ }
+ for (var j : i32 = 0; j < 10; j++) {
+ loop {
+ if (i > j) {
+ break;
+ }
+ continuing {
+ i++;
+ j-=2;
+ }
+ }
+ switch (j) {
+ case 0: {
+ if (i == j) {
+ break;
+ }
+ i = i + 1;
+ continue;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+}
+ )";
+ Source::File file("test.wgsl", content);
+ auto program = reader::wgsl::Parse(&file);
+ ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
+
+ JumpTracker jump_tracker(program);
+
+ const auto* outer_loop_body =
+ program.AST().Functions()[0]->body->statements[1]->As<ast::ForLoopStatement>()->body;
+ const auto* first_if = outer_loop_body->statements[0]->As<ast::IfStatement>();
+ const auto* first_if_body = first_if->body;
+ const auto* block_in_first_if = first_if_body->statements[0]->As<ast::BlockStatement>();
+ const auto* break_in_first_if = block_in_first_if->statements[0]->As<ast::BreakStatement>();
+
+ const auto* innermost_loop_body = outer_loop_body->statements[1]
+ ->As<ast::ForLoopStatement>()
+ ->body->statements[0]
+ ->As<ast::LoopStatement>()
+ ->body;
+ const auto* innermost_loop_if = innermost_loop_body->statements[0]->As<ast::IfStatement>();
+ const auto* innermost_loop_if_body = innermost_loop_if->body;
+ const auto* break_in_innermost_loop =
+ innermost_loop_if_body->statements[0]->As<ast::BreakStatement>();
+
+ std::unordered_set<const ast::Statement*> containing_loop_break = {
+ outer_loop_body, first_if,
+ first_if_body, block_in_first_if,
+ break_in_first_if, innermost_loop_body,
+ innermost_loop_if, innermost_loop_if_body,
+ break_in_innermost_loop};
+
+ for (auto* node : program.ASTNodes().Objects()) {
+ auto* stmt = node->As<ast::Statement>();
+ if (stmt == nullptr) {
+ continue;
+ }
+ if (containing_loop_break.count(stmt) > 0) {
+ ASSERT_TRUE(jump_tracker.ContainsBreakForInnermostLoop(*stmt));
+ } else {
+ ASSERT_FALSE(jump_tracker.ContainsBreakForInnermostLoop(*stmt));
+ }
+ }
+}
+
+TEST(JumpTrackerTest, Returns) {
+ std::string content = R"(
+fn main() {
+ var x : u32;
+ for (var i : i32 = 0; i < 100; i++) {
+ if (i == 40) {
+ {
+ return;
+ }
+ }
+ for (var j : i32 = 0; j < 10; j++) {
+ loop {
+ if (i > j) {
+ return;
+ }
+ continuing {
+ i++;
+ j-=2;
+ }
+ }
+ switch (j) {
+ case 0: {
+ if (i == j) {
+ break;
+ }
+ i = i + 1;
+ continue;
+ }
+ default: {
+ return;
+ }
+ }
+ }
+ }
+}
+ )";
+ Source::File file("test.wgsl", content);
+ auto program = reader::wgsl::Parse(&file);
+ ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
+
+ JumpTracker jump_tracker(program);
+
+ const auto* function_body = program.AST().Functions()[0]->body;
+ const auto* outer_loop = function_body->statements[1]->As<ast::ForLoopStatement>();
+ const auto* outer_loop_body = outer_loop->body;
+ const auto* first_if = outer_loop_body->statements[0]->As<ast::IfStatement>();
+ const auto* first_if_body = first_if->body;
+ const auto* block_in_first_if = first_if_body->statements[0]->As<ast::BlockStatement>();
+ const auto* return_in_first_if = block_in_first_if->statements[0]->As<ast::ReturnStatement>();
+ const auto* inner_for_loop = outer_loop_body->statements[1]->As<ast::ForLoopStatement>();
+ const auto* inner_for_loop_body = inner_for_loop->body;
+ const auto* innermost_loop = inner_for_loop_body->statements[0]->As<ast::LoopStatement>();
+ const auto* innermost_loop_body = innermost_loop->body;
+ const auto* innermost_loop_if = innermost_loop_body->statements[0]->As<ast::IfStatement>();
+ const auto* innermost_loop_if_body = innermost_loop_if->body;
+ const auto* return_in_innermost_loop =
+ innermost_loop_if_body->statements[0]->As<ast::ReturnStatement>();
+ const auto* switch_statement = inner_for_loop_body->statements[1]->As<ast::SwitchStatement>();
+ const auto* default_statement = switch_statement->body[1];
+ const auto* default_statement_body = default_statement->body;
+ const auto* return_in_default_statement =
+ default_statement_body->statements[0]->As<ast::ReturnStatement>();
+
+ std::unordered_set<const ast::Statement*> containing_return = {
+ function_body, outer_loop,
+ outer_loop_body, first_if,
+ first_if_body, block_in_first_if,
+ return_in_first_if, inner_for_loop,
+ inner_for_loop_body, innermost_loop,
+ innermost_loop_body, innermost_loop_if,
+ innermost_loop_if_body, return_in_innermost_loop,
+ switch_statement, default_statement,
+ default_statement_body, return_in_default_statement};
+
+ for (auto* node : program.ASTNodes().Objects()) {
+ auto* stmt = node->As<ast::Statement>();
+ if (stmt == nullptr) {
+ continue;
+ }
+ if (containing_return.count(stmt) > 0) {
+ ASSERT_TRUE(jump_tracker.ContainsReturn(*stmt));
+ } else {
+ ASSERT_FALSE(jump_tracker.ContainsReturn(*stmt));
+ }
+ }
+}
+
+TEST(JumpTrackerTest, Discards) {
+ std::string content = R"(
+fn main() {
+ var x : u32;
+ for (var i : i32 = 0; i < 100; i++) {
+ if (i == 40) {
+ {
+ discard;
+ }
+ }
+ for (var j : i32 = 0; j < 10; j++) {
+ loop {
+ if (i > j) {
+ discard;
+ }
+ continuing {
+ i++;
+ j-=2;
+ }
+ }
+ switch (j) {
+ case 0: {
+ if (i == j) {
+ break;
+ }
+ i = i + 1;
+ continue;
+ }
+ default: {
+ discard;
+ }
+ }
+ }
+ }
+}
+ )";
+ Source::File file("test.wgsl", content);
+ auto program = reader::wgsl::Parse(&file);
+ ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
+
+ JumpTracker jump_tracker(program);
+
+ const auto* function_body = program.AST().Functions()[0]->body;
+ const auto* outer_loop = function_body->statements[1]->As<ast::ForLoopStatement>();
+ const auto* outer_loop_body = outer_loop->body;
+ const auto* first_if = outer_loop_body->statements[0]->As<ast::IfStatement>();
+ const auto* first_if_body = first_if->body;
+ const auto* block_in_first_if = first_if_body->statements[0]->As<ast::BlockStatement>();
+ const auto* discard_in_first_if = block_in_first_if->statements[0]->As<ast::DiscardStatement>();
+ const auto* inner_for_loop = outer_loop_body->statements[1]->As<ast::ForLoopStatement>();
+ const auto* inner_for_loop_body = inner_for_loop->body;
+ const auto* innermost_loop = inner_for_loop_body->statements[0]->As<ast::LoopStatement>();
+ const auto* innermost_loop_body = innermost_loop->body;
+ const auto* innermost_loop_if = innermost_loop_body->statements[0]->As<ast::IfStatement>();
+ const auto* innermost_loop_if_body = innermost_loop_if->body;
+ const auto* discard_in_innermost_loop =
+ innermost_loop_if_body->statements[0]->As<ast::DiscardStatement>();
+ const auto* switch_statement = inner_for_loop_body->statements[1]->As<ast::SwitchStatement>();
+ const auto* default_statement = switch_statement->body[1];
+ const auto* default_statement_body = default_statement->body;
+ const auto* discard_in_default_statement =
+ default_statement_body->statements[0]->As<ast::DiscardStatement>();
+
+ std::unordered_set<const ast::Statement*> containing_discard = {
+ function_body, outer_loop,
+ outer_loop_body, first_if,
+ first_if_body, block_in_first_if,
+ discard_in_first_if, inner_for_loop,
+ inner_for_loop_body, innermost_loop,
+ innermost_loop_body, innermost_loop_if,
+ innermost_loop_if_body, discard_in_innermost_loop,
+ switch_statement, default_statement,
+ default_statement_body, discard_in_default_statement};
+
+ for (auto* node : program.ASTNodes().Objects()) {
+ auto* stmt = node->As<ast::Statement>();
+ if (stmt == nullptr) {
+ continue;
+ }
+ if (containing_discard.count(stmt) > 0) {
+ ASSERT_TRUE(jump_tracker.ContainsIntraproceduralDiscard(*stmt));
+ } else {
+ ASSERT_FALSE(jump_tracker.ContainsIntraproceduralDiscard(*stmt));
+ }
+ }
+}
+
+TEST(JumpTrackerTest, WhileLoop) {
+ std::string content = R"(
+fn main() {
+ var x : u32;
+ x = 0;
+ while (x < 100) {
+ if (x > 50) {
+ break;
+ }
+ x = x + 1;
+ }
+}
+ )";
+ Source::File file("test.wgsl", content);
+ auto program = reader::wgsl::Parse(&file);
+ ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
+
+ JumpTracker jump_tracker(program);
+
+ const auto* while_loop_body =
+ program.AST().Functions()[0]->body->statements[2]->As<ast::WhileStatement>()->body;
+ const auto* if_statement = while_loop_body->statements[0]->As<ast::IfStatement>();
+ const auto* if_statement_body = if_statement->body;
+ const auto* break_in_if = if_statement_body->statements[0]->As<ast::BreakStatement>();
+
+ std::unordered_set<const ast::Statement*> containing_loop_break = {
+ while_loop_body, if_statement, if_statement_body, break_in_if};
+
+ for (auto* node : program.ASTNodes().Objects()) {
+ auto* stmt = node->As<ast::Statement>();
+ if (stmt == nullptr) {
+ continue;
+ }
+ if (containing_loop_break.count(stmt) > 0) {
+ ASSERT_TRUE(jump_tracker.ContainsBreakForInnermostLoop(*stmt));
+ } else {
+ ASSERT_FALSE(jump_tracker.ContainsBreakForInnermostLoop(*stmt));
+ }
+ }
+}
+
+} // namespace
+} // namespace tint::fuzzers::ast_fuzzer
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutation.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutation.cc
index 6f60fc3..62c970b 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutation.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutation.cc
@@ -18,6 +18,7 @@
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/change_binary_operator.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.h"
@@ -33,6 +34,8 @@
return std::make_unique<MutationReplaceIdentifier>(message.replace_identifier());
case protobufs::Mutation::kChangeBinaryOperator:
return std::make_unique<MutationChangeBinaryOperator>(message.change_binary_operator());
+ case protobufs::Mutation::kDeleteStatement:
+ return std::make_unique<MutationDeleteStatement>(message.delete_statement());
case protobufs::Mutation::kWrapUnaryOperator:
return std::make_unique<MutationWrapUnaryOperator>(message.wrap_unary_operator());
case protobufs::Mutation::MUTATION_NOT_SET:
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_unary_operators.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_unary_operators.cc
index fb3fb96..c8dff2c 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_unary_operators.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_unary_operators.cc
@@ -50,6 +50,12 @@
continue;
}
+ // Only complement and negation operators can be swapped.
+ if (!(unary_expr->op == ast::UnaryOp::kComplement ||
+ unary_expr->op == ast::UnaryOp::kNegation)) {
+ continue;
+ }
+
result.push_back(std::make_unique<MutationChangeUnaryOperator>(
node_id_map->GetId(unary_expr),
MutationChangeUnaryOperator::ToggleOperator(unary_expr->op)));
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/delete_statements.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/delete_statements.cc
new file mode 100644
index 0000000..f1d7e4d
--- /dev/null
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/delete_statements.cc
@@ -0,0 +1,68 @@
+// Copyright 2021 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/fuzzers/tint_ast_fuzzer/mutation_finders/delete_statements.h"
+
+#include <memory>
+
+#include "src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/util.h"
+#include "src/tint/sem/expression.h"
+#include "src/tint/sem/statement.h"
+#include "src/tint/sem/variable.h"
+
+namespace tint::fuzzers::ast_fuzzer {
+
+MutationList MutationFinderDeleteStatements::FindMutations(const tint::Program& program,
+ NodeIdMap* node_id_map,
+ ProbabilityContext* /*unused*/) const {
+ MutationList result;
+
+ JumpTracker jump_tracker(program);
+
+ // Consider every statement node in the AST.
+ for (auto* node : program.ASTNodes().Objects()) {
+ auto* statement_node = tint::As<ast::Statement>(node);
+
+ if (!statement_node) {
+ continue;
+ }
+
+ const auto* statement_sem_node =
+ tint::As<sem::Statement>(program.Sem().Get(statement_node));
+
+ // Semantic information for the node is required in order to delete it.
+ if (!statement_sem_node) {
+ continue;
+ }
+
+ // Check that this kind of statement can be deleted.
+ if (!MutationDeleteStatement::CanBeDeleted(*statement_node, program, jump_tracker)) {
+ continue;
+ }
+
+ result.push_back(
+ std::make_unique<MutationDeleteStatement>(node_id_map->GetId(statement_node)));
+ }
+
+ return result;
+}
+
+uint32_t MutationFinderDeleteStatements::GetChanceOfApplyingMutation(
+ ProbabilityContext* probability_context) const {
+ return probability_context->GetChanceOfDeletingStatements();
+}
+
+} // namespace tint::fuzzers::ast_fuzzer
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/delete_statements.h b/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/delete_statements.h
new file mode 100644
index 0000000..97a4cbf
--- /dev/null
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/delete_statements.h
@@ -0,0 +1,36 @@
+// Copyright 2021 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.
+
+#ifndef SRC_TINT_FUZZERS_TINT_AST_FUZZER_MUTATION_FINDERS_DELETE_STATEMENTS_H_
+#define SRC_TINT_FUZZERS_TINT_AST_FUZZER_MUTATION_FINDERS_DELETE_STATEMENTS_H_
+
+#include "src/tint/fuzzers/tint_ast_fuzzer/mutation_finder.h"
+
+namespace tint::fuzzers::ast_fuzzer {
+
+/// Looks for opportunities to apply
+/// `MutationFinderDeleteStatements`.
+///
+/// Considers statements for deletion if their deletion would not make the module invalid.
+class MutationFinderDeleteStatements : public MutationFinder {
+ public:
+ MutationList FindMutations(const tint::Program& program,
+ NodeIdMap* node_id_map,
+ ProbabilityContext* probability_context) const override;
+ uint32_t GetChanceOfApplyingMutation(ProbabilityContext* probability_context) const override;
+};
+
+} // namespace tint::fuzzers::ast_fuzzer
+
+#endif // SRC_TINT_FUZZERS_TINT_AST_FUZZER_MUTATION_FINDERS_DELETE_STATEMENTS_H_
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement.cc
new file mode 100644
index 0000000..05435d0
--- /dev/null
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement.cc
@@ -0,0 +1,208 @@
+// Copyright 2021 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/fuzzers/tint_ast_fuzzer/mutations/delete_statement.h"
+
+#include <algorithm>
+#include <utility>
+#include <vector>
+
+#include "src/tint/ast/block_statement.h"
+#include "src/tint/ast/fallthrough_statement.h"
+#include "src/tint/ast/for_loop_statement.h"
+#include "src/tint/ast/if_statement.h"
+#include "src/tint/ast/loop_statement.h"
+#include "src/tint/ast/variable_decl_statement.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/util.h"
+#include "src/tint/program_builder.h"
+#include "src/tint/sem/for_loop_statement.h"
+#include "src/tint/sem/if_statement.h"
+#include "src/tint/sem/loop_statement.h"
+#include "src/tint/sem/statement.h"
+
+namespace tint::fuzzers::ast_fuzzer {
+
+MutationDeleteStatement::MutationDeleteStatement(protobufs::MutationDeleteStatement message)
+ : message_(std::move(message)) {}
+
+MutationDeleteStatement::MutationDeleteStatement(uint32_t statement_id) {
+ message_.set_statement_id(statement_id);
+}
+
+bool MutationDeleteStatement::IsApplicable(const tint::Program& program,
+ const NodeIdMap& node_id_map) const {
+ auto* statement_node = tint::As<ast::Statement>(node_id_map.GetNode(message_.statement_id()));
+
+ if (!statement_node) {
+ // The statement id is invalid or does not refer to a statement.
+ return false;
+ }
+
+ const auto* statement_sem_node = tint::As<sem::Statement>(program.Sem().Get(statement_node));
+
+ if (!statement_sem_node) {
+ // Semantic information for the statement is not available. This
+ // information is required in order to perform the deletion.
+ return false;
+ }
+
+ // Check whether it is OK to delete this statement.
+ if (!CanBeDeleted(*statement_node, program, JumpTracker(program))) {
+ return false;
+ }
+
+ return true;
+}
+
+void MutationDeleteStatement::Apply(const NodeIdMap& node_id_map,
+ tint::CloneContext* clone_context,
+ NodeIdMap* /* unused */) const {
+ const auto* statement_node =
+ tint::As<ast::Statement>(node_id_map.GetNode(message_.statement_id()));
+ const auto* statement_sem_node =
+ tint::As<sem::Statement>(clone_context->src->Sem().Get(statement_node));
+ const auto* sem_parent = statement_sem_node->Parent();
+
+ if (tint::Is<sem::IfStatement>(sem_parent) &&
+ tint::As<ast::IfStatement>(sem_parent->Declaration())->else_statement == statement_node) {
+ // Remove the "else" part of an if statement.
+ clone_context->Replace(statement_node, static_cast<const ast::Statement*>(nullptr));
+ } else if (tint::Is<sem::ForLoopStatement>(sem_parent) &&
+ tint::As<ast::ForLoopStatement>(sem_parent->Declaration())->initializer ==
+ statement_node) {
+ // Remove the initializer of a for loop.
+ clone_context->Replace(statement_node, static_cast<const ast::Statement*>(nullptr));
+ } else if (tint::Is<sem::ForLoopStatement>(sem_parent) &&
+ tint::As<ast::ForLoopStatement>(sem_parent->Declaration())->continuing ==
+ statement_node) {
+ // Remove the "continuing" statement of a for loop.
+ clone_context->Replace(statement_node, static_cast<const ast::Statement*>(nullptr));
+ } else if (tint::Is<sem::LoopContinuingBlockStatement>(statement_sem_node)) {
+ // Remove the "continuing" block of a loop.
+ clone_context->Replace(statement_node, static_cast<const ast::Statement*>(nullptr));
+ } else if (tint::Is<ast::CaseStatement>(statement_node)) {
+ // Remove a case statement from its enclosing switch statement.
+ const auto& case_statement_list =
+ &sem_parent->Declaration()->As<ast::SwitchStatement>()->body;
+ assert(std::find(case_statement_list->begin(), case_statement_list->end(),
+ statement_node) != case_statement_list->end() &&
+ "Statement not found.");
+ clone_context->Remove(*case_statement_list, statement_node);
+ } else if (tint::Is<ast::BlockStatement>(statement_node)) {
+ // Remove a block statement from the block that encloses it. A special case is required for
+ // this, since a sem::Block has itself as its associated sem::Block, so it is necessary to
+ // look at the parent to get the enclosing block.
+ const auto& statement_list =
+ sem_parent->Declaration()->As<ast::BlockStatement>()->statements;
+ assert(std::find(statement_list.begin(), statement_list.end(), statement_node) !=
+ statement_list.end() &&
+ "Statement not found.");
+ clone_context->Remove(statement_list, statement_node);
+ } else {
+ // Remove a non-block statement from the block that encloses it.
+ const auto& statement_list =
+ statement_sem_node->Block()->Declaration()->As<ast::BlockStatement>()->statements;
+ assert(std::find(statement_list.begin(), statement_list.end(), statement_node) !=
+ statement_list.end() &&
+ "Statement not found.");
+ clone_context->Remove(statement_list, statement_node);
+ }
+}
+
+protobufs::Mutation MutationDeleteStatement::ToMessage() const {
+ protobufs::Mutation mutation;
+ *mutation.mutable_delete_statement() = message_;
+ return mutation;
+}
+
+bool MutationDeleteStatement::CanBeDeleted(const ast::Statement& statement_node,
+ const Program& program,
+ const JumpTracker& jump_tracker) {
+ if (statement_node.Is<ast::VariableDeclStatement>()) {
+ // This is conservative. It would be possible to delete variable declarations if they are
+ // not used. Further analysis could allow that.
+ return false;
+ }
+
+ if (jump_tracker.ContainsReturn(statement_node) ||
+ jump_tracker.ContainsIntraproceduralDiscard(statement_node)) {
+ // This is conservative. It would be possible to delete a return/discard statement as long
+ // as there is still a return/discard on every control flow path.
+ return false;
+ }
+
+ if (jump_tracker.ContainsBreakForInnermostLoop(statement_node)) {
+ // This is conservative. Disallowing the removal of breaks ensures that loops cannot become
+ // statically infinite. However, a loop might in practice have multiple breaks, some of
+ // which can be removed.
+ return false;
+ }
+
+ if (auto* case_statement = statement_node.As<ast::CaseStatement>()) {
+ // It is not OK to delete the final case statement in a switch statement if the penultimate
+ // case statement falls through to the final case statement.
+ auto* switch_statement =
+ program.Sem().Get(case_statement)->Parent()->Declaration()->As<ast::SwitchStatement>();
+
+ if (switch_statement->body.Length() > 1 &&
+ switch_statement->body[switch_statement->body.Length() - 1] == case_statement) {
+ // There are at least two case statements, and this is the final case statement.
+ auto& penultimate_case_statement_body_statements =
+ switch_statement->body[switch_statement->body.Length() - 2]->body->statements;
+ if (penultimate_case_statement_body_statements.Length() > 0 &&
+ penultimate_case_statement_body_statements
+ [penultimate_case_statement_body_statements.Length() - 1]
+ ->Is<ast::FallthroughStatement>()) {
+ // The penultimate case statement falls through to the final case statement, thus
+ // the final case statement cannot be removed.
+ return false;
+ }
+ }
+ }
+
+ auto* parent_sem = program.Sem().Get(&statement_node)->Parent();
+ if (parent_sem == nullptr) {
+ // Semantic information for the parent node is required.
+ return false;
+ }
+
+ auto* parent_stmt = parent_sem->Declaration();
+
+ // It does not make sense to delete the entire body of a loop or if statement.
+ if (auto* for_loop = parent_stmt->As<ast::ForLoopStatement>()) {
+ if (for_loop->body == &statement_node) {
+ return false;
+ }
+ }
+ if (auto* loop = parent_stmt->As<ast::LoopStatement>()) {
+ if (loop->body == &statement_node) {
+ return false;
+ }
+ }
+ if (auto* while_loop = parent_stmt->As<ast::WhileStatement>()) {
+ if (while_loop->body == &statement_node) {
+ return false;
+ }
+ }
+ if (auto* if_statement = parent_stmt->As<ast::IfStatement>()) {
+ if (if_statement->body == &statement_node) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace tint::fuzzers::ast_fuzzer
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement.h b/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement.h
new file mode 100644
index 0000000..c7c0192
--- /dev/null
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement.h
@@ -0,0 +1,75 @@
+// Copyright 2021 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.
+
+#ifndef SRC_TINT_FUZZERS_TINT_AST_FUZZER_MUTATIONS_DELETE_STATEMENT_H_
+#define SRC_TINT_FUZZERS_TINT_AST_FUZZER_MUTATIONS_DELETE_STATEMENT_H_
+
+#include "src/tint/ast/statement.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/jump_tracker.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/mutation.h"
+
+namespace tint::fuzzers::ast_fuzzer {
+
+/// @see MutationDeleteStatement::Apply
+class MutationDeleteStatement : public Mutation {
+ public:
+ /// @brief Constructs an instance of this mutation from a protobuf message.
+ /// @param message - protobuf message
+ explicit MutationDeleteStatement(protobufs::MutationDeleteStatement message);
+
+ /// @brief Constructor.
+ /// @param statement_id - the id of the statement to delete.
+ explicit MutationDeleteStatement(uint32_t statement_id);
+
+ /// @copybrief Mutation::IsApplicable
+ ///
+ /// The mutation is applicable iff:
+ /// - `statement_id` corresponds to a statement in the AST.
+ /// - `statement_id` does not refer to a variable declaration, since the declared variables will
+ /// be inaccessible if the statement is deleted.
+ /// - `statement_id` is not a return statement, since removing return statements arbitrarily can
+ /// make the program invalid.
+ /// - `statement_id` is not a break statement, since removing break statements can lead to
+ /// syntactically infinite loops.
+ ///
+ /// @copydetails Mutation::IsApplicable
+ bool IsApplicable(const tint::Program& program, const NodeIdMap& node_id_map) const override;
+
+ /// @copybrief Mutation::Apply
+ ///
+ /// Delete the statement referenced by `statement_id`.
+ ///
+ /// @copydetails Mutation::Apply
+ void Apply(const NodeIdMap& node_id_map,
+ tint::CloneContext* clone_context,
+ NodeIdMap* new_node_id_map) const override;
+
+ protobufs::Mutation ToMessage() const override;
+
+ /// Return whether the given statement is suitable for deletion.
+ /// @param statement_node - the statement to be considered for deletion.
+ /// @param program - the program containing the statement.
+ /// @param jump_tracker - information about jump statements for the program.
+ /// @return true if and only if it is OK to delete the statement.
+ static bool CanBeDeleted(const ast::Statement& statement_node,
+ const Program& program,
+ const JumpTracker& jump_tracker);
+
+ private:
+ protobufs::MutationDeleteStatement message_;
+};
+
+} // namespace tint::fuzzers::ast_fuzzer
+
+#endif // SRC_TINT_FUZZERS_TINT_AST_FUZZER_MUTATIONS_DELETE_STATEMENT_H_
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement_test.cc
new file mode 100644
index 0000000..925ee80
--- /dev/null
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement_test.cc
@@ -0,0 +1,750 @@
+// Copyright 2021 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/fuzzers/tint_ast_fuzzer/mutations/delete_statement.h"
+
+#include <functional>
+#include <string>
+
+#include "gtest/gtest.h"
+
+#include "src/tint/ast/assignment_statement.h"
+#include "src/tint/ast/block_statement.h"
+#include "src/tint/ast/case_statement.h"
+#include "src/tint/ast/fallthrough_statement.h"
+#include "src/tint/ast/for_loop_statement.h"
+#include "src/tint/ast/if_statement.h"
+#include "src/tint/ast/switch_statement.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/mutator.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/node_id_map.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/probability_context.h"
+#include "src/tint/program_builder.h"
+#include "src/tint/reader/wgsl/parser.h"
+#include "src/tint/writer/wgsl/generator.h"
+
+namespace tint::fuzzers::ast_fuzzer {
+namespace {
+
+void CheckStatementDeletionWorks(
+ const std::string& original,
+ const std::string& expected,
+ const std::function<const ast::Statement*(const Program&)>& statement_finder) {
+ Source::File original_file("original.wgsl", original);
+ auto program = reader::wgsl::Parse(&original_file);
+
+ Source::File expected_file("expected.wgsl", expected);
+ auto expected_program = reader::wgsl::Parse(&expected_file);
+
+ ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
+ ASSERT_TRUE(expected_program.IsValid()) << expected_program.Diagnostics().str();
+
+ NodeIdMap node_id_map(program);
+ const auto* statement = statement_finder(program);
+ ASSERT_NE(statement, nullptr);
+ auto statement_id = node_id_map.GetId(statement);
+ ASSERT_NE(statement_id, 0);
+ ASSERT_TRUE(MaybeApplyMutation(program, MutationDeleteStatement(statement_id), node_id_map,
+ &program, &node_id_map, nullptr));
+ ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
+ writer::wgsl::Options options;
+ auto transformed_result = writer::wgsl::Generate(&program, options);
+ auto expected_result = writer::wgsl::Generate(&expected_program, options);
+ ASSERT_TRUE(transformed_result.success) << transformed_result.error;
+ ASSERT_TRUE(expected_result.success) << expected_result.error;
+ ASSERT_EQ(expected_result.wgsl, transformed_result.wgsl);
+}
+
+void CheckStatementDeletionNotAllowed(
+ const std::string& original,
+ const std::function<const ast::Statement*(const Program&)>& statement_finder) {
+ Source::File original_file("original.wgsl", original);
+ auto program = reader::wgsl::Parse(&original_file);
+
+ ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
+
+ NodeIdMap node_id_map(program);
+ const auto* statement = statement_finder(program);
+ ASSERT_NE(statement, nullptr);
+ auto statement_id = node_id_map.GetId(statement);
+ ASSERT_NE(statement_id, 0);
+ ASSERT_FALSE(MaybeApplyMutation(program, MutationDeleteStatement(statement_id), node_id_map,
+ &program, &node_id_map, nullptr));
+}
+
+TEST(DeleteStatementTest, DeleteAssignStatement) {
+ auto original = R"(
+ fn main() {
+ {
+ var a : i32 = 5;
+ a = 6;
+ }
+ })";
+ auto expected = R"(fn main() {
+ {
+ var a : i32 = 5;
+ }
+}
+)";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[0]
+ ->As<ast::BlockStatement>()
+ ->statements[1]
+ ->As<ast::AssignmentStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteForStatement) {
+ auto original =
+ R"(
+ fn main() {
+ for (var i : i32 = 0; i < 10; i++) {
+ }
+ }
+ )";
+ auto expected = "fn main() { }";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::ForLoopStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteIfStatement) {
+ auto original =
+ R"(
+ fn main() {
+ if (true) { } else { }
+ }
+ )";
+ auto expected = "fn main() { }";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::IfStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteBlockStatement) {
+ auto original = "fn main() { { } }";
+ auto expected = "fn main() { }";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::BlockStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteSwitchStatement) {
+ auto original = R"(
+fn main() {
+ switch(1) {
+ case 0, 1: {
+ }
+ default: {
+ fallthrough;
+ }
+ case 2: {
+ }
+ }
+})";
+ auto expected = R"(fn main() { })";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::SwitchStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteCaseStatement) {
+ auto original = R"(
+fn main() {
+ switch(1) {
+ case 0, 1: {
+ }
+ default: {
+ fallthrough;
+ }
+ case 2: {
+ }
+ }
+})";
+ auto expected = R"(
+fn main() {
+ switch(1) {
+ default: {
+ fallthrough;
+ }
+ case 2: {
+ }
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[0]
+ ->As<ast::SwitchStatement>()
+ ->body[0]
+ ->As<ast::CaseStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteFallthroughStatement) {
+ auto original = R"(
+fn main() {
+ switch(1) {
+ case 0, 1: {
+ }
+ default: {
+ fallthrough;
+ }
+ case 2: {
+ }
+ }
+})";
+ auto expected = R"(
+fn main() {
+ switch(1) {
+ case 0, 1: {
+ }
+ default: {
+ }
+ case 2: {
+ }
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[0]
+ ->As<ast::SwitchStatement>()
+ ->body[1]
+ ->As<ast::CaseStatement>()
+ ->body->statements[0]
+ ->As<ast::FallthroughStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteElse) {
+ auto original = R"(
+fn main() {
+ if (true) {
+ } else {
+ }
+})";
+ auto expected = R"(
+fn main() {
+ if (true) {
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[0]
+ ->As<ast::IfStatement>()
+ ->else_statement;
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteCall) {
+ auto original = R"(
+fn main() {
+ sin(1.0);
+})";
+ auto expected = R"(
+fn main() {
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::CallStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteCompoundAssign) {
+ auto original = R"(
+fn main() {
+ var x : i32 = 0;
+ x += 2;;
+})";
+ auto expected = R"(
+fn main() {
+ var x : i32 = 0;
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[1]
+ ->As<ast::CompoundAssignmentStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteLoop) {
+ auto original = R"(
+fn main() {
+ var x : i32 = 0;
+ loop {
+ if (x > 100) {
+ break;
+ }
+ continuing {
+ x++;
+ }
+ }
+})";
+ auto expected = R"(
+fn main() {
+ var x : i32 = 0;
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[1]->As<ast::LoopStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteContinuingBlock) {
+ auto original = R"(
+fn main() {
+ var x : i32 = 0;
+ loop {
+ if (x > 100) {
+ break;
+ }
+ continuing {
+ x++;
+ }
+ }
+})";
+ auto expected = R"(
+fn main() {
+ var x : i32 = 0;
+ loop {
+ if (x > 100) {
+ break;
+ }
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[1]
+ ->As<ast::LoopStatement>()
+ ->continuing;
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteContinue) {
+ auto original = R"(
+fn main() {
+ var x : i32 = 0;
+ loop {
+ if (x > 100) {
+ break;
+ }
+ continue;
+ continuing {
+ x++;
+ }
+ }
+})";
+ auto expected = R"(
+fn main() {
+ var x : i32 = 0;
+ loop {
+ if (x > 100) {
+ break;
+ }
+ continuing {
+ x++;
+ }
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[1]
+ ->As<ast::LoopStatement>()
+ ->body->statements[1]
+ ->As<ast::ContinueStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteIncrement) {
+ auto original = R"(
+fn main() {
+ var x : i32 = 0;
+ loop {
+ if (x > 100) {
+ break;
+ }
+ continuing {
+ x++;
+ }
+ }
+})";
+ auto expected = R"(
+fn main() {
+ var x : i32 = 0;
+ loop {
+ if (x > 100) {
+ break;
+ }
+ continuing {
+ }
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[1]
+ ->As<ast::LoopStatement>()
+ ->continuing->statements[0]
+ ->As<ast::IncrementDecrementStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteForLoopInitializer) {
+ auto original = R"(
+fn main() {
+ var x : i32;
+ for (x = 0; x < 100; x++) {
+ }
+})";
+ auto expected = R"(
+fn main() {
+ var x : i32;
+ for (; x < 100; x++) {
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[1]
+ ->As<ast::ForLoopStatement>()
+ ->initializer->As<ast::AssignmentStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DeleteForLoopContinuing) {
+ auto original = R"(
+fn main() {
+ var x : i32;
+ for (x = 0; x < 100; x++) {
+ }
+})";
+ auto expected = R"(
+fn main() {
+ var x : i32;
+ for (x = 0; x < 100;) {
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[1]
+ ->As<ast::ForLoopStatement>()
+ ->continuing->As<ast::IncrementDecrementStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, AllowDeletionOfInnerLoopWithBreak) {
+ auto original = R"(
+fn main() {
+ loop {
+ loop {
+ break;
+ }
+ break;
+ }
+})";
+ auto expected = R"(
+fn main() {
+ loop {
+ break;
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[0]
+ ->As<ast::LoopStatement>()
+ ->body->statements[0]
+ ->As<ast::LoopStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, AllowDeletionOfInnerCaseWithBreak) {
+ auto original = R"(
+fn main() {
+ loop {
+ switch(0) {
+ case 1: {
+ break;
+ }
+ default: {
+ }
+ }
+ break;
+ }
+})";
+ auto expected = R"(
+fn main() {
+ loop {
+ switch(0) {
+ default: {
+ }
+ }
+ break;
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[0]
+ ->As<ast::LoopStatement>()
+ ->body->statements[0]
+ ->As<ast::SwitchStatement>()
+ ->body[0];
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, AllowDeletionOfBreakFromSwitch) {
+ auto original = R"(
+fn main() {
+ switch(0) {
+ case 1: {
+ break;
+ }
+ default: {
+ }
+ }
+})";
+ auto expected = R"(
+fn main() {
+ switch(0) {
+ case 1: {
+ }
+ default: {
+ }
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[0]
+ ->As<ast::SwitchStatement>()
+ ->body[0]
+ ->body->statements[0]
+ ->As<ast::BreakStatement>();
+ };
+ CheckStatementDeletionWorks(original, expected, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotDeleteVariableDeclaration) {
+ auto original = R"(
+fn main() {
+ var x : i32;
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::VariableDeclStatement>();
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotDeleteCaseDueToFallthrough) {
+ auto original = R"(
+fn main() {
+ switch(1) {
+ default: {
+ fallthrough;
+ }
+ case 2: {
+ }
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[0]
+ ->As<ast::SwitchStatement>()
+ ->body[1]
+ ->As<ast::CaseStatement>();
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotMakeLoopInfinite1) {
+ auto original = R"(
+fn main() {
+ loop {
+ break;
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[0]
+ ->As<ast::LoopStatement>()
+ ->body->statements[0]
+ ->As<ast::BreakStatement>();
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotMakeLoopInfinite2) {
+ auto original = R"(
+fn main() {
+ loop {
+ if (true) {
+ break;
+ }
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST()
+ .Functions()[0]
+ ->body->statements[0]
+ ->As<ast::LoopStatement>()
+ ->body->statements[0]
+ ->As<ast::IfStatement>();
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotRemoveReturn) {
+ auto original = R"(
+fn main() {
+ return;
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::ReturnStatement>();
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotRemoveStatementContainingReturn) {
+ auto original = R"(
+fn foo() -> i32 {
+ if (true) {
+ return 1;
+ } else {
+ return 2;
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::IfStatement>();
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotRemoveDiscard) {
+ auto original = R"(
+fn main() {
+ discard;
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::DiscardStatement>();
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotRemoveStatementContainingDiscard) {
+ auto original = R"(
+fn foo() -> i32 {
+ if (true) {
+ discard;
+ } else {
+ discard;
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::IfStatement>();
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotRemoveLoopBody) {
+ auto original = R"(
+fn foo() {
+ discard;
+}
+fn main() {
+ loop {
+ foo();
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[1]->body->statements[0]->As<ast::LoopStatement>()->body;
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotRemoveForLoopBody) {
+ auto original = R"(
+fn main() {
+ for(var i : i32 = 0; i < 10; i++) {
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::ForLoopStatement>()->body;
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotRemoveWhileBody) {
+ auto original = R"(
+fn main() {
+ var i : i32 = 0;
+ while(i < 10) {
+ i++;
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[1]->As<ast::WhileStatement>()->body;
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotRemoveIfBody) {
+ auto original = R"(
+fn main() {
+ if(true) {
+ }
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body->statements[0]->As<ast::IfStatement>()->body;
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+TEST(DeleteStatementTest, DoNotRemoveFunctionBody) {
+ auto original = R"(
+fn main() {
+})";
+ auto statement_finder = [](const Program& program) -> const ast::Statement* {
+ return program.AST().Functions()[0]->body;
+ };
+ CheckStatementDeletionNotAllowed(original, statement_finder);
+}
+
+} // namespace
+} // namespace tint::fuzzers::ast_fuzzer
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutator.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutator.cc
index f70a947..7153f0c 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutator.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutator.cc
@@ -22,6 +22,7 @@
#include "src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_binary_operators.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_unary_operators.h"
+#include "src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/delete_statements.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/replace_identifiers.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/wrap_unary_operators.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/node_id_map.h"
@@ -48,6 +49,8 @@
probability_context, &result);
MaybeAddFinder<MutationFinderChangeUnaryOperators>(enable_all_mutations,
probability_context, &result);
+ MaybeAddFinder<MutationFinderDeleteStatements>(enable_all_mutations, probability_context,
+ &result);
MaybeAddFinder<MutationFinderReplaceIdentifiers>(enable_all_mutations, probability_context,
&result);
MaybeAddFinder<MutationFinderWrapUnaryOperators>(enable_all_mutations, probability_context,
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/probability_context.cc b/src/tint/fuzzers/tint_ast_fuzzer/probability_context.cc
index 639bd60..f2cb159 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/probability_context.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/probability_context.cc
@@ -21,6 +21,7 @@
const std::pair<uint32_t, uint32_t> kChanceOfChangingBinaryOperators = {30, 90};
const std::pair<uint32_t, uint32_t> kChanceOfChangingUnaryOperators = {30, 70};
+const std::pair<uint32_t, uint32_t> kChanceOfDeletingStatements = {30, 70};
const std::pair<uint32_t, uint32_t> kChanceOfReplacingIdentifiers = {30, 70};
const std::pair<uint32_t, uint32_t> kChanceOfWrappingUnaryOperators = {30, 70};
@@ -30,6 +31,7 @@
: generator_(generator),
chance_of_changing_binary_operators_(RandomFromRange(kChanceOfChangingBinaryOperators)),
chance_of_changing_unary_operators_(RandomFromRange(kChanceOfChangingUnaryOperators)),
+ chance_of_deleting_statements_(RandomFromRange(kChanceOfDeletingStatements)),
chance_of_replacing_identifiers_(RandomFromRange(kChanceOfReplacingIdentifiers)),
chance_of_wrapping_unary_operators_(RandomFromRange(kChanceOfWrappingUnaryOperators)) {
assert(generator != nullptr && "generator must not be nullptr");
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/probability_context.h b/src/tint/fuzzers/tint_ast_fuzzer/probability_context.h
index ce46738..410d7cf 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/probability_context.h
+++ b/src/tint/fuzzers/tint_ast_fuzzer/probability_context.h
@@ -61,6 +61,9 @@
return chance_of_changing_unary_operators_;
}
+ /// @return the probability of changing operator for a binary expression.
+ uint32_t GetChanceOfDeletingStatements() const { return chance_of_deleting_statements_; }
+
/// @return the probability of replacing some identifier with some other one.
uint32_t GetChanceOfReplacingIdentifiers() const { return chance_of_replacing_identifiers_; }
@@ -78,6 +81,7 @@
uint32_t chance_of_changing_binary_operators_;
uint32_t chance_of_changing_unary_operators_;
+ uint32_t chance_of_deleting_statements_;
uint32_t chance_of_replacing_identifiers_;
uint32_t chance_of_wrapping_unary_operators_;
};
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/protobufs/tint_ast_fuzzer.proto b/src/tint/fuzzers/tint_ast_fuzzer/protobufs/tint_ast_fuzzer.proto
index fd3cd81..b1fa5e3 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/protobufs/tint_ast_fuzzer.proto
+++ b/src/tint/fuzzers/tint_ast_fuzzer/protobufs/tint_ast_fuzzer.proto
@@ -22,6 +22,7 @@
MutationChangeBinaryOperator change_binary_operator = 2;
MutationWrapUnaryOperator wrap_unary_operator = 3;
MutationChangeUnaryOperator change_unary_operator = 4;
+ MutationDeleteStatement delete_statement = 5;
};
}
@@ -64,6 +65,14 @@
uint32 new_operator = 2;
}
+message MutationDeleteStatement {
+ // This transformation deletes a statement, as long as doing so does not
+ // invalidate the program.
+
+ // The id of a statement to be deleted.
+ uint32 statement_id = 1;
+}
+
message MutationReplaceIdentifier {
// This transformation replaces a use of one variable with another.
diff --git a/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc b/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc
index 9ffea24..f17987d 100644
--- a/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc
+++ b/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc
@@ -24,6 +24,7 @@
#include "src/tint/fuzzers/transform_builder.h"
#include "src/tint/reader/wgsl/parser.h"
#include "src/tint/writer/wgsl/generator.h"
+#include "testing/libfuzzer/libfuzzer_exports.h"
namespace tint::fuzzers::regex_fuzzer {
namespace {
diff --git a/src/tint/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc b/src/tint/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc
index c35e0ce..41e417b 100644
--- a/src/tint/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc
+++ b/src/tint/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc
@@ -27,6 +27,7 @@
#include "src/tint/fuzzers/tint_spirv_tools_fuzzer/spirv_opt_mutator.h"
#include "src/tint/fuzzers/tint_spirv_tools_fuzzer/spirv_reduce_mutator.h"
#include "src/tint/fuzzers/tint_spirv_tools_fuzzer/util.h"
+#include "testing/libfuzzer/libfuzzer_exports.h"
namespace tint::fuzzers::spvtools_fuzzer {
namespace {
diff --git a/src/tint/inspector/inspector.cc b/src/tint/inspector/inspector.cc
index ae56de5..e9c4d88 100644
--- a/src/tint/inspector/inspector.cc
+++ b/src/tint/inspector/inspector.cc
@@ -107,7 +107,7 @@
std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData(
const sem::Type* type,
- const ast::AttributeList& attributes) {
+ utils::VectorRef<const ast::Attribute*> attributes) {
auto* interpolation_attribute = ast::GetAttribute<ast::InterpolateAttribute>(attributes);
if (type->is_integer_scalar_or_vector()) {
return {InterpolationType::kFlat, InterpolationSampling::kNone};
@@ -608,7 +608,7 @@
void Inspector::AddEntryPointInOutVariables(std::string name,
const sem::Type* type,
- const ast::AttributeList& attributes,
+ utils::VectorRef<const ast::Attribute*> attributes,
std::vector<StageVariable>& variables) const {
// Skip builtins.
if (ast::HasAttribute<ast::BuiltinAttribute>(attributes)) {
@@ -647,7 +647,7 @@
bool Inspector::ContainsBuiltin(ast::BuiltinValue builtin,
const sem::Type* type,
- const ast::AttributeList& attributes) const {
+ utils::VectorRef<const ast::Attribute*> attributes) const {
auto* unwrapped_type = type->UnwrapRef();
if (auto* struct_ty = unwrapped_type->As<sem::Struct>()) {
diff --git a/src/tint/inspector/inspector.h b/src/tint/inspector/inspector.h
index 2690581..97707db 100644
--- a/src/tint/inspector/inspector.h
+++ b/src/tint/inspector/inspector.h
@@ -170,7 +170,7 @@
/// @param variables the list to add the variables to
void AddEntryPointInOutVariables(std::string name,
const sem::Type* type,
- const ast::AttributeList& attributes,
+ utils::VectorRef<const ast::Attribute*> attributes,
std::vector<StageVariable>& variables) const;
/// Recursively determine if the type contains builtin.
@@ -178,7 +178,7 @@
/// Otherwise, check `attributes` for the attribute.
bool ContainsBuiltin(ast::BuiltinValue builtin,
const sem::Type* type,
- const ast::AttributeList& attributes) const;
+ utils::VectorRef<const ast::Attribute*> attributes) const;
/// Gathers all the texture resource bindings of the given type for the given
/// entry point.
diff --git a/src/tint/inspector/inspector_test.cc b/src/tint/inspector/inspector_test.cc
index 2bb862d..543239c 100644
--- a/src/tint/inspector/inspector_test.cc
+++ b/src/tint/inspector/inspector_test.cc
@@ -154,7 +154,7 @@
}
TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
- MakeEmptyBodyFunction("foo", {
+ MakeEmptyBodyFunction("foo", utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -172,11 +172,11 @@
}
TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
- MakeEmptyBodyFunction("foo", {
+ MakeEmptyBodyFunction("foo", utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
- MakeEmptyBodyFunction("bar", {
+ MakeEmptyBodyFunction("bar", utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -198,16 +198,16 @@
}
TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
- MakeEmptyBodyFunction("func", {});
+ MakeEmptyBodyFunction("func", utils::Empty);
- MakeCallerBodyFunction("foo", {"func"},
- {
+ MakeCallerBodyFunction("foo", utils::Vector{std::string("func")},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
- MakeCallerBodyFunction("bar", {"func"},
- {
+ MakeCallerBodyFunction("bar", utils::Vector{std::string("func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -228,7 +228,7 @@
}
TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
- MakeEmptyBodyFunction("foo", {
+ MakeEmptyBodyFunction("foo", utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(8_i, 2_i, 1_i),
});
@@ -247,7 +247,7 @@
}
TEST_F(InspectorGetEntryPointTest, NonDefaultWorkgroupSize) {
- MakeEmptyBodyFunction("foo", {
+ MakeEmptyBodyFunction("foo", utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(8_i, 2_i, 1_i),
});
@@ -266,10 +266,10 @@
}
TEST_F(InspectorGetEntryPointTest, NoInOutVariables) {
- MakeEmptyBodyFunction("func", {});
+ MakeEmptyBodyFunction("func", utils::Empty);
- MakeCallerBodyFunction("foo", {"func"},
- {
+ MakeCallerBodyFunction("foo", utils::Vector{std::string("func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -289,15 +289,19 @@
std::tie(component, composition) = GetParam();
std::function<const ast::Type*()> tint_type = GetTypeFunction(component, composition);
- auto* in_var = Param("in_var", tint_type(), {Location(0u), Flat()});
- Func("foo", {in_var}, tint_type(),
- {
+ auto* in_var = Param("in_var", tint_type(),
+ utils::Vector{
+ Location(0u),
+ Flat(),
+ });
+ Func("foo", utils::Vector{in_var}, tint_type(),
+ utils::Vector{
Return("in_var"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0u),
});
Inspector& inspector = Build();
@@ -330,17 +334,29 @@
CompositionType::kVec4)));
TEST_F(InspectorGetEntryPointTest, MultipleInOutVariables) {
- auto* in_var0 = Param("in_var0", ty.u32(), {Location(0u), Flat()});
- auto* in_var1 = Param("in_var1", ty.u32(), {Location(1u), Flat()});
- auto* in_var4 = Param("in_var4", ty.u32(), {Location(4u), Flat()});
- Func("foo", {in_var0, in_var1, in_var4}, ty.u32(),
- {
+ auto* in_var0 = Param("in_var0", ty.u32(),
+ utils::Vector{
+ Location(0u),
+ Flat(),
+ });
+ auto* in_var1 = Param("in_var1", ty.u32(),
+ utils::Vector{
+ Location(1u),
+ Flat(),
+ });
+ auto* in_var4 = Param("in_var4", ty.u32(),
+ utils::Vector{
+ Location(4u),
+ Flat(),
+ });
+ Func("foo", utils::Vector{in_var0, in_var1, in_var4}, ty.u32(),
+ utils::Vector{
Return("in_var0"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0u),
});
Inspector& inspector = Build();
@@ -375,27 +391,35 @@
}
TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutVariables) {
- auto* in_var_foo = Param("in_var_foo", ty.u32(), {Location(0u), Flat()});
- Func("foo", {in_var_foo}, ty.u32(),
- {
+ auto* in_var_foo = Param("in_var_foo", ty.u32(),
+ utils::Vector{
+ Location(0u),
+ Flat(),
+ });
+ Func("foo", utils::Vector{in_var_foo}, ty.u32(),
+ utils::Vector{
Return("in_var_foo"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0u),
});
- auto* in_var_bar = Param("in_var_bar", ty.u32(), {Location(0u), Flat()});
- Func("bar", {in_var_bar}, ty.u32(),
- {
+ auto* in_var_bar = Param("in_var_bar", ty.u32(),
+ utils::Vector{
+ Location(0u),
+ Flat(),
+ });
+ Func("bar", utils::Vector{in_var_bar}, ty.u32(),
+ utils::Vector{
Return("in_var_bar"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(1u),
});
@@ -434,16 +458,22 @@
}
TEST_F(InspectorGetEntryPointTest, BuiltInsNotStageVariables) {
- auto* in_var0 = Param("in_var0", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)});
- auto* in_var1 = Param("in_var1", ty.f32(), {Location(0u)});
- Func("foo", {in_var0, in_var1}, ty.f32(),
- {
+ auto* in_var0 = Param("in_var0", ty.u32(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kSampleIndex),
+ });
+ auto* in_var1 = Param("in_var1", ty.f32(),
+ utils::Vector{
+ Location(0u),
+ });
+ Func("foo", utils::Vector{in_var0, in_var1}, ty.f32(),
+ utils::Vector{
Return("in_var1"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Builtin(ast::BuiltinValue::kFragDepth),
});
Inspector& inspector = Build();
@@ -463,16 +493,19 @@
}
TEST_F(InspectorGetEntryPointTest, InOutStruct) {
- auto* interface = MakeInOutStruct("interface", {{"a", 0u}, {"b", 1u}});
+ auto* interface = MakeInOutStruct("interface", utils::Vector{
+ InOutInfo{"a", 0u},
+ InOutInfo{"b", 1u},
+ });
Func("foo",
- {
+ utils::Vector{
Param("param", ty.Of(interface)),
},
ty.Of(interface),
- {
+ utils::Vector{
Return("param"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
Inspector& inspector = Build();
@@ -504,16 +537,19 @@
}
TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutSharedStruct) {
- auto* interface = MakeInOutStruct("interface", {{"a", 0u}, {"b", 1u}});
- Func("foo", {}, ty.Of(interface),
- {
+ auto* interface = MakeInOutStruct("interface", utils::Vector{
+ InOutInfo{"a", 0u},
+ InOutInfo{"b", 1u},
+ });
+ Func("foo", utils::Empty, ty.Of(interface),
+ utils::Vector{
Return(Construct(ty.Of(interface))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
- Func("bar", {Param("param", ty.Of(interface))}, ty.void_(), {},
- {
+ Func("bar", utils::Vector{Param("param", ty.Of(interface))}, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
Inspector& inspector = Build();
@@ -549,20 +585,25 @@
}
TEST_F(InspectorGetEntryPointTest, MixInOutVariablesAndStruct) {
- auto* struct_a = MakeInOutStruct("struct_a", {{"a", 0u}, {"b", 1u}});
- auto* struct_b = MakeInOutStruct("struct_b", {{"a", 2u}});
+ auto* struct_a = MakeInOutStruct("struct_a", utils::Vector{
+ InOutInfo{"a", 0u},
+ InOutInfo{"b", 1u},
+ });
+ auto* struct_b = MakeInOutStruct("struct_b", utils::Vector{
+ InOutInfo{"a", 2u},
+ });
Func("foo",
- {
+ utils::Vector{
Param("param_a", ty.Of(struct_a)),
Param("param_b", ty.Of(struct_b)),
- Param("param_c", ty.f32(), {Location(3u)}),
- Param("param_d", ty.f32(), {Location(4u)}),
+ Param("param_c", ty.f32(), utils::Vector{Location(3u)}),
+ Param("param_d", ty.f32(), utils::Vector{Location(4u)}),
},
ty.Of(struct_a),
- {
+ utils::Vector{
Return("param_a"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
Inspector& inspector = Build();
@@ -607,7 +648,7 @@
TEST_F(InspectorGetEntryPointTest, OverrideUnreferenced) {
Override("foo", ty.f32(), nullptr);
- MakeEmptyBodyFunction("ep_func", {
+ MakeEmptyBodyFunction("ep_func", utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -623,7 +664,7 @@
TEST_F(InspectorGetEntryPointTest, OverrideReferencedByEntryPoint) {
Override("foo", ty.f32(), nullptr);
MakePlainGlobalReferenceBodyFunction("ep_func", "foo", ty.f32(),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -639,9 +680,9 @@
TEST_F(InspectorGetEntryPointTest, OverrideReferencedByCallee) {
Override("foo", ty.f32(), nullptr);
- MakePlainGlobalReferenceBodyFunction("callee_func", "foo", ty.f32(), {});
- MakeCallerBodyFunction("ep_func", {"callee_func"},
- {
+ MakePlainGlobalReferenceBodyFunction("callee_func", "foo", ty.f32(), utils::Empty);
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("callee_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -656,11 +697,17 @@
}
TEST_F(InspectorGetEntryPointTest, OverrideSomeReferenced) {
- Override("foo", ty.f32(), nullptr, {Id(1)});
- Override("bar", ty.f32(), nullptr, {Id(2)});
- MakePlainGlobalReferenceBodyFunction("callee_func", "foo", ty.f32(), {});
- MakeCallerBodyFunction("ep_func", {"callee_func"},
- {
+ Override("foo", ty.f32(), nullptr,
+ utils::Vector{
+ Id(1),
+ });
+ Override("bar", ty.f32(), nullptr,
+ utils::Vector{
+ Id(2),
+ });
+ MakePlainGlobalReferenceBodyFunction("callee_func", "foo", ty.f32(), utils::Empty);
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("callee_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -681,16 +728,17 @@
Override("u32_var", ty.u32(), nullptr);
Override("i32_var", ty.i32(), nullptr);
- MakePlainGlobalReferenceBodyFunction("bool_func", "bool_var", ty.bool_(), {});
- MakePlainGlobalReferenceBodyFunction("float_func", "float_var", ty.f32(), {});
- MakePlainGlobalReferenceBodyFunction("u32_func", "u32_var", ty.u32(), {});
- MakePlainGlobalReferenceBodyFunction("i32_func", "i32_var", ty.i32(), {});
+ MakePlainGlobalReferenceBodyFunction("bool_func", "bool_var", ty.bool_(), utils::Empty);
+ MakePlainGlobalReferenceBodyFunction("float_func", "float_var", ty.f32(), utils::Empty);
+ MakePlainGlobalReferenceBodyFunction("u32_func", "u32_var", ty.u32(), utils::Empty);
+ MakePlainGlobalReferenceBodyFunction("i32_func", "i32_var", ty.i32(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"bool_func", "float_func", "u32_func", "i32_func"},
- {
- Stage(ast::PipelineStage::kCompute),
- WorkgroupSize(1_i),
- });
+ MakeCallerBodyFunction(
+ "ep_func", utils::Vector{std::string("bool_func"), "float_func", "u32_func", "i32_func"},
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(1_i),
+ });
Inspector& inspector = Build();
@@ -711,7 +759,7 @@
TEST_F(InspectorGetEntryPointTest, OverrideInitialized) {
Override("foo", ty.f32(), Expr(0_f));
MakePlainGlobalReferenceBodyFunction("ep_func", "foo", ty.f32(),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -729,7 +777,7 @@
TEST_F(InspectorGetEntryPointTest, OverrideUninitialized) {
Override("foo", ty.f32(), nullptr);
MakePlainGlobalReferenceBodyFunction("ep_func", "foo", ty.f32(),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -747,13 +795,16 @@
TEST_F(InspectorGetEntryPointTest, OverrideNumericIDSpecified) {
Override("foo_no_id", ty.f32(), nullptr);
- Override("foo_id", ty.f32(), nullptr, {Id(1234)});
+ Override("foo_id", ty.f32(), nullptr,
+ utils::Vector{
+ Id(1234),
+ });
- MakePlainGlobalReferenceBodyFunction("no_id_func", "foo_no_id", ty.f32(), {});
- MakePlainGlobalReferenceBodyFunction("id_func", "foo_id", ty.f32(), {});
+ MakePlainGlobalReferenceBodyFunction("no_id_func", "foo_no_id", ty.f32(), utils::Empty);
+ MakePlainGlobalReferenceBodyFunction("id_func", "foo_id", ty.f32(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"no_id_func", "id_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("no_id_func"), "id_func"},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -773,11 +824,16 @@
}
TEST_F(InspectorGetEntryPointTest, NonOverrideSkipped) {
- auto* foo_struct_type = MakeUniformBufferType("foo_type", {ty.i32()});
+ auto* foo_struct_type = MakeUniformBufferType("foo_type", utils::Vector{
+ ty.i32(),
+ });
AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);
- MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
- MakeCallerBodyFunction("ep_func", {"ub_func"},
- {
+ MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -790,7 +846,7 @@
}
TEST_F(InspectorGetEntryPointTest, BuiltinNotReferenced) {
- MakeEmptyBodyFunction("ep_func", {
+ MakeEmptyBodyFunction("ep_func", utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -808,12 +864,15 @@
}
TEST_F(InspectorGetEntryPointTest, InputSampleMaskSimpleReferenced) {
- auto* in_var = Param("in_var", ty.u32(), {Builtin(ast::BuiltinValue::kSampleMask)});
- Func("ep_func", {in_var}, ty.void_(),
- {
+ auto* in_var = Param("in_var", ty.u32(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kSampleMask),
+ });
+ Func("ep_func", utils::Vector{in_var}, ty.void_(),
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -826,20 +885,21 @@
}
TEST_F(InspectorGetEntryPointTest, InputSampleMaskStructReferenced) {
- ast::StructMemberList members;
- members.push_back(
- Member("inner_position", ty.u32(), {Builtin(ast::BuiltinValue::kSampleMask)}));
+ utils::Vector members{
+ Member("inner_position", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kSampleMask)}),
+ };
+
Structure("in_struct", members);
Func("ep_func",
- {
- Param("in_var", ty.type_name("in_struct"), {}),
+ utils::Vector{
+ Param("in_var", ty.type_name("in_struct"), utils::Empty),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -853,17 +913,19 @@
TEST_F(InspectorGetEntryPointTest, OutputSampleMaskSimpleReferenced) {
Func("ep_func",
- {
- Param("in_var", ty.u32(), {Builtin(ast::BuiltinValue::kSampleMask)}),
+ utils::Vector{
+ Param("in_var", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kSampleMask)}),
},
ty.u32(),
- {
+ utils::Vector{
Return("in_var"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {Builtin(ast::BuiltinValue::kSampleMask)});
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kSampleMask),
+ });
Inspector& inspector = Build();
@@ -874,17 +936,17 @@
}
TEST_F(InspectorGetEntryPointTest, OutputSampleMaskStructReferenced) {
- Structure("out_struct",
- {
- Member("inner_sample_mask", ty.u32(), {Builtin(ast::BuiltinValue::kSampleMask)}),
- });
+ Structure("out_struct", utils::Vector{
+ Member("inner_sample_mask", ty.u32(),
+ utils::Vector{Builtin(ast::BuiltinValue::kSampleMask)}),
+ });
- Func("ep_func", {}, ty.type_name("out_struct"),
- {
+ Func("ep_func", utils::Empty, ty.type_name("out_struct"),
+ utils::Vector{
Decl(Var("out_var", ty.type_name("out_struct"))),
Return("out_var"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -898,14 +960,14 @@
TEST_F(InspectorGetEntryPointTest, InputPositionSimpleReferenced) {
Func("ep_func",
- {
- Param("in_var", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)}),
+ utils::Vector{
+ Param("in_var", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -918,20 +980,20 @@
}
TEST_F(InspectorGetEntryPointTest, InputPositionStructReferenced) {
- Structure("in_struct",
- {
- Member("inner_position", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)}),
- });
+ Structure("in_struct", utils::Vector{
+ Member("inner_position", ty.vec4<f32>(),
+ utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
+ });
Func("ep_func",
- {
- Param("in_var", ty.type_name("in_struct"), {}),
+ utils::Vector{
+ Param("in_var", ty.type_name("in_struct"), utils::Empty),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -945,14 +1007,14 @@
TEST_F(InspectorGetEntryPointTest, FrontFacingSimpleReferenced) {
Func("ep_func",
- {
- Param("in_var", ty.bool_(), {Builtin(ast::BuiltinValue::kFrontFacing)}),
+ utils::Vector{
+ Param("in_var", ty.bool_(), utils::Vector{Builtin(ast::BuiltinValue::kFrontFacing)}),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -965,20 +1027,20 @@
}
TEST_F(InspectorGetEntryPointTest, FrontFacingStructReferenced) {
- Structure("in_struct",
- {
- Member("inner_position", ty.bool_(), {Builtin(ast::BuiltinValue::kFrontFacing)}),
- });
+ Structure("in_struct", utils::Vector{
+ Member("inner_position", ty.bool_(),
+ utils::Vector{Builtin(ast::BuiltinValue::kFrontFacing)}),
+ });
Func("ep_func",
- {
- Param("in_var", ty.type_name("in_struct"), {}),
+ utils::Vector{
+ Param("in_var", ty.type_name("in_struct"), utils::Empty),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -992,14 +1054,14 @@
TEST_F(InspectorGetEntryPointTest, SampleIndexSimpleReferenced) {
Func("ep_func",
- {
- Param("in_var", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)}),
+ utils::Vector{
+ Param("in_var", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kSampleIndex)}),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1012,20 +1074,20 @@
}
TEST_F(InspectorGetEntryPointTest, SampleIndexStructReferenced) {
- Structure("in_struct",
- {
- Member("inner_position", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)}),
- });
+ Structure("in_struct", utils::Vector{
+ Member("inner_position", ty.u32(),
+ utils::Vector{Builtin(ast::BuiltinValue::kSampleIndex)}),
+ });
Func("ep_func",
- {
- Param("in_var", ty.type_name("in_struct"), {}),
+ utils::Vector{
+ Param("in_var", ty.type_name("in_struct"), utils::Empty),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1039,14 +1101,15 @@
TEST_F(InspectorGetEntryPointTest, NumWorkgroupsSimpleReferenced) {
Func("ep_func",
- {
- Param("in_var", ty.vec3<u32>(), {Builtin(ast::BuiltinValue::kNumWorkgroups)}),
+ utils::Vector{
+ Param("in_var", ty.vec3<u32>(),
+ utils::Vector{Builtin(ast::BuiltinValue::kNumWorkgroups)}),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)}, {});
+ utils::Vector{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)}, utils::Empty);
Inspector& inspector = Build();
@@ -1057,20 +1120,20 @@
}
TEST_F(InspectorGetEntryPointTest, NumWorkgroupsStructReferenced) {
- Structure("in_struct", {
+ Structure("in_struct", utils::Vector{
Member("inner_position", ty.vec3<u32>(),
- {Builtin(ast::BuiltinValue::kNumWorkgroups)}),
+ utils::Vector{Builtin(ast::BuiltinValue::kNumWorkgroups)}),
});
Func("ep_func",
- {
- Param("in_var", ty.type_name("in_struct"), {}),
+ utils::Vector{
+ Param("in_var", ty.type_name("in_struct"), utils::Empty),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)}, {});
+ utils::Vector{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)}, utils::Empty);
Inspector& inspector = Build();
@@ -1081,19 +1144,19 @@
}
TEST_F(InspectorGetEntryPointTest, ImplicitInterpolate) {
- Structure("in_struct", {
- Member("struct_inner", ty.f32(), {Location(0)}),
+ Structure("in_struct", utils::Vector{
+ Member("struct_inner", ty.f32(), utils::Vector{Location(0)}),
});
Func("ep_func",
- {
- Param("in_var", ty.type_name("in_struct"), {}),
+ utils::Vector{
+ Param("in_var", ty.type_name("in_struct"), utils::Empty),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1109,21 +1172,22 @@
TEST_P(InspectorGetEntryPointInterpolateTest, Test) {
auto& params = GetParam();
- Structure("in_struct",
- {
- Member("struct_inner", ty.f32(),
- {Interpolate(params.in_type, params.in_sampling), Location(0)}),
- });
+ Structure(
+ "in_struct",
+ utils::Vector{
+ Member("struct_inner", ty.f32(),
+ utils::Vector{Interpolate(params.in_type, params.in_sampling), Location(0)}),
+ });
Func("ep_func",
- {
- Param("in_var", ty.type_name("in_struct"), {}),
+ utils::Vector{
+ Param("in_var", ty.type_name("in_struct"), utils::Empty),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1170,9 +1234,18 @@
InterpolationType::kFlat, InterpolationSampling::kNone}));
TEST_F(InspectorGetOverrideDefaultValuesTest, Bool) {
- Override("foo", ty.bool_(), nullptr, {Id(1)});
- Override("bar", ty.bool_(), Expr(true), {Id(20)});
- Override("baz", ty.bool_(), Expr(false), {Id(300)});
+ Override("foo", ty.bool_(), nullptr,
+ utils::Vector{
+ Id(1),
+ });
+ Override("bar", ty.bool_(), Expr(true),
+ utils::Vector{
+ Id(20),
+ });
+ Override("baz", ty.bool_(), Expr(false),
+ utils::Vector{
+ Id(300),
+ });
Inspector& inspector = Build();
@@ -1192,8 +1265,14 @@
}
TEST_F(InspectorGetOverrideDefaultValuesTest, U32) {
- Override("foo", ty.u32(), nullptr, {Id(1)});
- Override("bar", ty.u32(), Expr(42_u), {Id(20)});
+ Override("foo", ty.u32(), nullptr,
+ utils::Vector{
+ Id(1),
+ });
+ Override("bar", ty.u32(), Expr(42_u),
+ utils::Vector{
+ Id(20),
+ });
Inspector& inspector = Build();
@@ -1209,9 +1288,18 @@
}
TEST_F(InspectorGetOverrideDefaultValuesTest, I32) {
- Override("foo", ty.i32(), nullptr, {Id(1)});
- Override("bar", ty.i32(), Expr(-42_i), {Id(20)});
- Override("baz", ty.i32(), Expr(42_i), {Id(300)});
+ Override("foo", ty.i32(), nullptr,
+ utils::Vector{
+ Id(1),
+ });
+ Override("bar", ty.i32(), Expr(-42_i),
+ utils::Vector{
+ Id(20),
+ });
+ Override("baz", ty.i32(), Expr(42_i),
+ utils::Vector{
+ Id(300),
+ });
Inspector& inspector = Build();
@@ -1231,10 +1319,22 @@
}
TEST_F(InspectorGetOverrideDefaultValuesTest, Float) {
- Override("foo", ty.f32(), nullptr, {Id(1)});
- Override("bar", ty.f32(), Expr(0_f), {Id(20)});
- Override("baz", ty.f32(), Expr(-10_f), {Id(300)});
- Override("x", ty.f32(), Expr(15_f), {Id(4000)});
+ Override("foo", ty.f32(), nullptr,
+ utils::Vector{
+ Id(1),
+ });
+ Override("bar", ty.f32(), Expr(0_f),
+ utils::Vector{
+ Id(20),
+ });
+ Override("baz", ty.f32(), Expr(-10_f),
+ utils::Vector{
+ Id(300),
+ });
+ Override("x", ty.f32(), Expr(15_f),
+ utils::Vector{
+ Id(4000),
+ });
Inspector& inspector = Build();
@@ -1258,9 +1358,18 @@
}
TEST_F(InspectorGetConstantNameToIdMapTest, WithAndWithoutIds) {
- Override("v1", ty.f32(), nullptr, {Id(1)});
- Override("v20", ty.f32(), nullptr, {Id(20)});
- Override("v300", ty.f32(), nullptr, {Id(300)});
+ Override("v1", ty.f32(), nullptr,
+ utils::Vector{
+ Id(1),
+ });
+ Override("v20", ty.f32(), nullptr,
+ utils::Vector{
+ Id(20),
+ });
+ Override("v300", ty.f32(), nullptr,
+ utils::Vector{
+ Id(300),
+ });
auto* a = Override("a", ty.f32(), nullptr);
auto* b = Override("b", ty.f32(), nullptr);
auto* c = Override("c", ty.f32(), nullptr);
@@ -1293,7 +1402,7 @@
}
TEST_F(InspectorGetStorageSizeTest, Empty) {
- MakeEmptyBodyFunction("ep_func", {
+ MakeEmptyBodyFunction("ep_func", utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -1305,13 +1414,13 @@
AddUniformBuffer("ub_var", ty.i32(), 0, 0);
AddStorageBuffer("sb_var", ty.i32(), ast::Access::kReadWrite, 1, 0);
AddStorageBuffer("rosb_var", ty.i32(), ast::Access::kRead, 1, 1);
- Func("ep_func", {}, ty.void_(),
- {
+ Func("ep_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("ub", nullptr, Expr("ub_var"))),
Decl(Let("sb", nullptr, Expr("sb_var"))),
Decl(Let("rosb", nullptr, Expr("rosb_var"))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -1322,20 +1431,36 @@
}
TEST_F(InspectorGetStorageSizeTest, Simple_Struct) {
- auto* ub_struct_type = MakeUniformBufferType("ub_type", {ty.i32(), ty.i32()});
+ auto* ub_struct_type = MakeUniformBufferType("ub_type", utils::Vector{
+ ty.i32(),
+ ty.i32(),
+ });
AddUniformBuffer("ub_var", ty.Of(ub_struct_type), 0, 0);
- MakeStructVariableReferenceBodyFunction("ub_func", "ub_var", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("ub_func", "ub_var",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- auto sb = MakeStorageBufferTypes("sb_type", {ty.i32()});
+ auto sb = MakeStorageBufferTypes("sb_type", utils::Vector{
+ ty.i32(),
+ });
AddStorageBuffer("sb_var", sb(), ast::Access::kReadWrite, 1, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "sb_var", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "sb_var",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- auto ro_sb = MakeStorageBufferTypes("rosb_type", {ty.i32()});
+ auto ro_sb = MakeStorageBufferTypes("rosb_type", utils::Vector{
+ ty.i32(),
+ });
AddStorageBuffer("rosb_var", ro_sb(), ast::Access::kRead, 1, 1);
- MakeStructVariableReferenceBodyFunction("rosb_func", "rosb_var", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("rosb_func", "rosb_var",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"ub_func", "sb_func", "rosb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func"), "sb_func", "rosb_func"},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -1347,11 +1472,11 @@
TEST_F(InspectorGetStorageSizeTest, NonStructVec3) {
AddUniformBuffer("ub_var", ty.vec3<f32>(), 0, 0);
- Func("ep_func", {}, ty.void_(),
- {
+ Func("ep_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("ub", nullptr, Expr("ub_var"))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -1362,13 +1487,15 @@
}
TEST_F(InspectorGetStorageSizeTest, StructVec3) {
- auto* ub_struct_type = MakeUniformBufferType("ub_type", {ty.vec3<f32>()});
+ auto* ub_struct_type = MakeUniformBufferType("ub_type", utils::Vector{
+ ty.vec3<f32>(),
+ });
AddUniformBuffer("ub_var", ty.Of(ub_struct_type), 0, 0);
- Func("ep_func", {}, ty.void_(),
- {
+ Func("ep_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("ub", nullptr, Expr("ub_var"))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -1379,8 +1506,8 @@
}
TEST_F(InspectorGetResourceBindingsTest, Empty) {
- MakeCallerBodyFunction("ep_func", {},
- {
+ MakeCallerBodyFunction("ep_func", utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1392,23 +1519,39 @@
}
TEST_F(InspectorGetResourceBindingsTest, Simple) {
- auto* ub_struct_type = MakeUniformBufferType("ub_type", {ty.i32()});
+ auto* ub_struct_type = MakeUniformBufferType("ub_type", utils::Vector{
+ ty.i32(),
+ });
AddUniformBuffer("ub_var", ty.Of(ub_struct_type), 0, 0);
- MakeStructVariableReferenceBodyFunction("ub_func", "ub_var", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("ub_func", "ub_var",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- auto sb = MakeStorageBufferTypes("sb_type", {ty.i32()});
+ auto sb = MakeStorageBufferTypes("sb_type", utils::Vector{
+ ty.i32(),
+ });
AddStorageBuffer("sb_var", sb(), ast::Access::kReadWrite, 1, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "sb_var", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "sb_var",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- auto ro_sb = MakeStorageBufferTypes("rosb_type", {ty.i32()});
+ auto ro_sb = MakeStorageBufferTypes("rosb_type", utils::Vector{
+ ty.i32(),
+ });
AddStorageBuffer("rosb_var", ro_sb(), ast::Access::kRead, 1, 1);
- MakeStructVariableReferenceBodyFunction("rosb_func", "rosb_var", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("rosb_func", "rosb_var",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
auto* s_texture_type = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
AddResource("s_texture", s_texture_type, 2, 0);
AddSampler("s_var", 3, 0);
AddGlobalVariable("s_coords", ty.f32());
- MakeSamplerReferenceBodyFunction("s_func", "s_texture", "s_var", "s_coords", ty.f32(), {});
+ MakeSamplerReferenceBodyFunction("s_func", "s_texture", "s_var", "s_coords", ty.f32(),
+ utils::Empty);
auto* cs_depth_texture_type = ty.depth_texture(ast::TextureDimension::k2d);
AddResource("cs_texture", cs_depth_texture_type, 3, 1);
@@ -1416,22 +1559,32 @@
AddGlobalVariable("cs_coords", ty.vec2<f32>());
AddGlobalVariable("cs_depth", ty.f32());
MakeComparisonSamplerReferenceBodyFunction("cs_func", "cs_texture", "cs_var", "cs_coords",
- "cs_depth", ty.f32(), {});
+ "cs_depth", ty.f32(), utils::Empty);
auto* depth_ms_texture_type = ty.depth_multisampled_texture(ast::TextureDimension::k2d);
AddResource("depth_ms_texture", depth_ms_texture_type, 3, 3);
- Func("depth_ms_func", {}, ty.void_(), {Ignore("depth_ms_texture")});
+ Func("depth_ms_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Ignore("depth_ms_texture"),
+ });
auto* st_type = MakeStorageTextureTypes(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint);
AddStorageTexture("st_var", st_type, 4, 0);
- MakeStorageTextureBodyFunction("st_func", "st_var", ty.vec2<i32>(), {});
+ MakeStorageTextureBodyFunction("st_func", "st_var", ty.vec2<i32>(), utils::Empty);
- MakeCallerBodyFunction(
- "ep_func",
- {"ub_func", "sb_func", "rosb_func", "s_func", "cs_func", "depth_ms_func", "st_func"},
- {
- Stage(ast::PipelineStage::kFragment),
- });
+ MakeCallerBodyFunction("ep_func",
+ utils::Vector{
+ std::string("ub_func"),
+ std::string("sb_func"),
+ std::string("rosb_func"),
+ std::string("s_func"),
+ std::string("cs_func"),
+ std::string("depth_ms_func"),
+ std::string("st_func"),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
Inspector& inspector = Build();
@@ -1486,13 +1639,18 @@
}
TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonEntryPointFunc) {
- auto* foo_struct_type = MakeUniformBufferType("foo_type", {ty.i32()});
+ auto* foo_struct_type = MakeUniformBufferType("foo_type", utils::Vector{
+ ty.i32(),
+ });
AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);
- MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"ub_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1505,10 +1663,10 @@
TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple_NonStruct) {
AddUniformBuffer("foo_ub", ty.i32(), 0, 0);
- MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.i32(), {});
+ MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.i32(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"ub_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1526,13 +1684,18 @@
}
TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple_Struct) {
- auto* foo_struct_type = MakeUniformBufferType("foo_type", {ty.i32()});
+ auto* foo_struct_type = MakeUniformBufferType("foo_type", utils::Vector{
+ ty.i32(),
+ });
AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);
- MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"ub_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1550,14 +1713,22 @@
}
TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleMembers) {
- auto* foo_struct_type = MakeUniformBufferType("foo_type", {ty.i32(), ty.u32(), ty.f32()});
+ auto* foo_struct_type = MakeUniformBufferType("foo_type", utils::Vector{
+ ty.i32(),
+ ty.u32(),
+ ty.f32(),
+ });
AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
- {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ MemberInfo{1, ty.u32()},
+ MemberInfo{2, ty.f32()},
+ });
- MakeCallerBodyFunction("ep_func", {"ub_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1575,13 +1746,18 @@
}
TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingPadding) {
- auto* foo_struct_type = MakeUniformBufferType("foo_type", {ty.vec3<f32>()});
+ auto* foo_struct_type = MakeUniformBufferType("foo_type", utils::Vector{
+ ty.vec3<f32>(),
+ });
AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);
- MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.vec3<f32>()}});
+ MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
+ utils::Vector{
+ MemberInfo{0, ty.vec3<f32>()},
+ });
- MakeCallerBodyFunction("ep_func", {"ub_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1600,10 +1776,10 @@
TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonStructVec3) {
AddUniformBuffer("foo_ub", ty.vec3<f32>(), 0, 0);
- MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {});
+ MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"ub_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1621,14 +1797,22 @@
}
TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleUniformBuffers) {
- auto* ub_struct_type = MakeUniformBufferType("ub_type", {ty.i32(), ty.u32(), ty.f32()});
+ auto* ub_struct_type = MakeUniformBufferType("ub_type", utils::Vector{
+ ty.i32(),
+ ty.u32(),
+ ty.f32(),
+ });
AddUniformBuffer("ub_foo", ty.Of(ub_struct_type), 0, 0);
AddUniformBuffer("ub_bar", ty.Of(ub_struct_type), 0, 1);
AddUniformBuffer("ub_baz", ty.Of(ub_struct_type), 2, 0);
auto AddReferenceFunc = [this](const std::string& func_name, const std::string& var_name) {
MakeStructVariableReferenceBodyFunction(func_name, var_name,
- {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ MemberInfo{1, ty.u32()},
+ MemberInfo{2, ty.f32()},
+ });
};
AddReferenceFunc("ub_foo_func", "ub_foo");
AddReferenceFunc("ub_bar_func", "ub_bar");
@@ -1638,14 +1822,14 @@
return create<ast::CallStatement>(Call(callee));
};
- Func("ep_func", {}, ty.void_(),
- {
+ Func("ep_func", utils::Empty, ty.void_(),
+ utils::Vector{
FuncCall("ub_foo_func"),
FuncCall("ub_bar_func"),
FuncCall("ub_baz_func"),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1678,15 +1862,21 @@
// Manually create uniform buffer to make sure it had a valid layout (array
// with elem stride of 16, and that is 16-byte aligned within the struct)
auto* foo_struct_type = Structure(
- "foo_type", {Member("0i32", ty.i32()),
- Member("b", ty.array(ty.u32(), 4_u, /*stride*/ 16), {MemberAlign(16)})});
+ "foo_type",
+ utils::Vector{
+ Member("0i32", ty.i32()),
+ Member("b", ty.array(ty.u32(), 4_u, /*stride*/ 16), utils::Vector{MemberAlign(16)}),
+ });
AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);
- MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"ub_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1705,10 +1895,10 @@
TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple_NonStruct) {
AddStorageBuffer("foo_sb", ty.i32(), ast::Access::kReadWrite, 0, 0);
- MakePlainGlobalReferenceBodyFunction("sb_func", "foo_sb", ty.i32(), {});
+ MakePlainGlobalReferenceBodyFunction("sb_func", "foo_sb", ty.i32(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1726,13 +1916,18 @@
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple_Struct) {
- auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32()});
+ auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
+ ty.i32(),
+ });
AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1750,7 +1945,7 @@
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleMembers) {
- auto foo_struct_type = MakeStorageBufferTypes("foo_type", {
+ auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
ty.i32(),
ty.u32(),
ty.f32(),
@@ -1758,10 +1953,14 @@
AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
- {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ MemberInfo{1, ty.u32()},
+ MemberInfo{2, ty.f32()},
+ });
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1779,7 +1978,7 @@
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
- auto sb_struct_type = MakeStorageBufferTypes("sb_type", {
+ auto sb_struct_type = MakeStorageBufferTypes("sb_type", utils::Vector{
ty.i32(),
ty.u32(),
ty.f32(),
@@ -1790,7 +1989,11 @@
auto AddReferenceFunc = [this](const std::string& func_name, const std::string& var_name) {
MakeStructVariableReferenceBodyFunction(func_name, var_name,
- {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ MemberInfo{1, ty.u32()},
+ MemberInfo{2, ty.f32()},
+ });
};
AddReferenceFunc("sb_foo_func", "sb_foo");
AddReferenceFunc("sb_bar_func", "sb_bar");
@@ -1800,14 +2003,14 @@
return create<ast::CallStatement>(Call(callee));
};
- Func("ep_func", {}, ty.void_(),
- {
+ Func("ep_func", utils::Empty, ty.void_(),
+ utils::Vector{
FuncCall("sb_foo_func"),
FuncCall("sb_bar_func"),
FuncCall("sb_baz_func"),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1837,13 +2040,19 @@
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) {
- auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32(), ty.array<u32, 4>()});
+ auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
+ ty.i32(),
+ ty.array<u32, 4>(),
+ });
AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1861,16 +2070,19 @@
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
- auto foo_struct_type = MakeStorageBufferTypes("foo_type", {
+ auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
ty.i32(),
ty.array<u32>(),
});
AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1888,13 +2100,18 @@
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) {
- auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.vec3<f32>()});
+ auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
+ ty.vec3<f32>(),
+ });
AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.vec3<f32>()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+ utils::Vector{
+ MemberInfo{0, ty.vec3<f32>()},
+ });
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1913,10 +2130,10 @@
TEST_F(InspectorGetStorageBufferResourceBindingsTest, NonStructVec3) {
AddStorageBuffer("foo_ub", ty.vec3<f32>(), ast::Access::kReadWrite, 0, 0);
- MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), {});
+ MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"ub_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1934,13 +2151,18 @@
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) {
- auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32()});
+ auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
+ ty.i32(),
+ });
AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1952,13 +2174,18 @@
}
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) {
- auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32()});
+ auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
+ ty.i32(),
+ });
AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1976,7 +2203,7 @@
}
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
- auto sb_struct_type = MakeStorageBufferTypes("sb_type", {
+ auto sb_struct_type = MakeStorageBufferTypes("sb_type", utils::Vector{
ty.i32(),
ty.u32(),
ty.f32(),
@@ -1987,7 +2214,11 @@
auto AddReferenceFunc = [this](const std::string& func_name, const std::string& var_name) {
MakeStructVariableReferenceBodyFunction(func_name, var_name,
- {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ MemberInfo{1, ty.u32()},
+ MemberInfo{2, ty.f32()},
+ });
};
AddReferenceFunc("sb_foo_func", "sb_foo");
AddReferenceFunc("sb_bar_func", "sb_bar");
@@ -1997,14 +2228,14 @@
return create<ast::CallStatement>(Call(callee));
};
- Func("ep_func", {}, ty.void_(),
- {
+ Func("ep_func", utils::Empty, ty.void_(),
+ utils::Vector{
FuncCall("sb_foo_func"),
FuncCall("sb_bar_func"),
FuncCall("sb_baz_func"),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2034,16 +2265,19 @@
}
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
- auto foo_struct_type = MakeStorageBufferTypes("foo_type", {
+ auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
ty.i32(),
ty.array<u32, 4>(),
});
AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2061,16 +2295,19 @@
}
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
- auto foo_struct_type = MakeStorageBufferTypes("foo_type", {
+ auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
ty.i32(),
ty.array<u32>(),
});
AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2088,13 +2325,18 @@
}
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {
- auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32()});
+ auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
+ ty.i32(),
+ });
AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
- MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
- MakeCallerBodyFunction("ep_func", {"sb_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2112,7 +2354,7 @@
AddGlobalVariable("foo_coords", ty.f32());
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords", ty.f32(),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2128,7 +2370,7 @@
}
TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) {
- MakeEmptyBodyFunction("ep_func", {
+ MakeEmptyBodyFunction("ep_func", utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2147,10 +2389,10 @@
AddGlobalVariable("foo_coords", ty.f32());
MakeSamplerReferenceBodyFunction("foo_func", "foo_texture", "foo_sampler", "foo_coords",
- ty.f32(), {});
+ ty.f32(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"foo_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("foo_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2172,7 +2414,7 @@
AddGlobalVariable("foo_coords", ty.f32());
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords", ty.f32(),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2191,7 +2433,7 @@
MakeComparisonSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords",
"foo_depth", ty.f32(),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2212,7 +2454,7 @@
MakeComparisonSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords",
"foo_depth", ty.f32(),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2228,7 +2470,7 @@
}
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) {
- MakeEmptyBodyFunction("ep_func", {
+ MakeEmptyBodyFunction("ep_func", utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2248,10 +2490,10 @@
AddGlobalVariable("foo_depth", ty.f32());
MakeComparisonSamplerReferenceBodyFunction("foo_func", "foo_texture", "foo_sampler",
- "foo_coords", "foo_depth", ty.f32(), {});
+ "foo_coords", "foo_depth", ty.f32(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"foo_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("foo_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2275,7 +2517,7 @@
MakeComparisonSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords",
"foo_depth", ty.f32(),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2292,7 +2534,7 @@
AddGlobalVariable("foo_coords", ty.f32());
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords", ty.f32(),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2305,7 +2547,7 @@
}
TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) {
- MakeEmptyBodyFunction("foo", {
+ MakeEmptyBodyFunction("foo", utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2327,7 +2569,7 @@
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords",
GetBaseType(GetParam().sampled_kind),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2377,7 +2619,7 @@
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords",
"foo_array_index", GetBaseType(GetParam().sampled_kind),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2413,11 +2655,11 @@
AddGlobalVariable("foo_coords", coord_type);
AddGlobalVariable("foo_sample_index", ty.i32());
- Func("ep", {}, ty.void_(),
- {
+ Func("ep", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call("textureLoad", "foo_texture", "foo_coords", "foo_sample_index")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2455,7 +2697,7 @@
inspector::ResourceBinding::SampledKind::kUInt}));
TEST_F(InspectorGetMultisampledArrayTextureResourceBindingsTest, Empty) {
- MakeEmptyBodyFunction("foo", {
+ MakeEmptyBodyFunction("foo", utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2478,7 +2720,7 @@
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", "foo_coords",
"foo_array_index", GetBaseType(GetParam().sampled_kind),
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2510,7 +2752,7 @@
inspector::ResourceBinding::SampledKind::kUInt}));
TEST_F(InspectorGetStorageTextureResourceBindingsTest, Empty) {
- MakeEmptyBodyFunction("ep", {
+ MakeEmptyBodyFunction("ep", utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2557,7 +2799,7 @@
ASSERT_FALSE(dim_type == nullptr);
MakeStorageTextureBodyFunction("ep", "st_var", dim_type,
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2639,11 +2881,11 @@
auto* depth_texture_type = ty.depth_texture(GetParam().type_dim);
AddResource("dt", depth_texture_type, 0, 0);
- Func("ep", {}, ty.void_(),
- {
+ Func("ep", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call("textureDimensions", "dt")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2676,11 +2918,11 @@
auto* depth_ms_texture_type = ty.depth_multisampled_texture(ast::TextureDimension::k2d);
AddResource("tex", depth_ms_texture_type, 0, 0);
- Func("ep", {}, ty.void_(),
- {
+ Func("ep", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call("textureDimensions", "tex")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2700,11 +2942,11 @@
auto* external_texture_type = ty.external_texture();
AddResource("et", external_texture_type, 0, 0);
- Func("ep", {}, ty.void_(),
- {
+ Func("ep", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call("textureDimensions", "et")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -2980,7 +3222,7 @@
}
TEST_F(InspectorGetWorkgroupStorageSizeTest, Empty) {
- MakeEmptyBodyFunction("ep_func", {
+ MakeEmptyBodyFunction("ep_func", utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -2990,10 +3232,10 @@
TEST_F(InspectorGetWorkgroupStorageSizeTest, Simple) {
AddWorkgroupStorage("wg_f32", ty.f32());
- MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {});
+ MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"f32_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("f32_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -3005,17 +3247,22 @@
TEST_F(InspectorGetWorkgroupStorageSizeTest, CompoundTypes) {
// This struct should occupy 68 bytes. 4 from the i32 field, and another 64
// from the 4-element array with 16-byte stride.
- auto* wg_struct_type =
- MakeStructType("WgStruct", {ty.i32(), ty.array(ty.i32(), 4_u, /*stride=*/16)});
+ auto* wg_struct_type = MakeStructType("WgStruct", utils::Vector{
+ ty.i32(),
+ ty.array(ty.i32(), 4_u, /*stride=*/16),
+ });
AddWorkgroupStorage("wg_struct_var", ty.Of(wg_struct_type));
- MakeStructVariableReferenceBodyFunction("wg_struct_func", "wg_struct_var", {{0, ty.i32()}});
+ MakeStructVariableReferenceBodyFunction("wg_struct_func", "wg_struct_var",
+ utils::Vector{
+ MemberInfo{0, ty.i32()},
+ });
// Plus another 4 bytes from this other workgroup-class f32.
AddWorkgroupStorage("wg_f32", ty.f32());
- MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), {});
+ MakePlainGlobalReferenceBodyFunction("f32_func", "wg_f32", ty.f32(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"wg_struct_func", "f32_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("wg_struct_func"), "f32_func"},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -3028,10 +3275,10 @@
// vec3<f32> has an alignment of 16 but a size of 12. We leverage this to test
// that our padded size calculation for workgroup storage is accurate.
AddWorkgroupStorage("wg_vec3", ty.vec3<f32>());
- MakePlainGlobalReferenceBodyFunction("wg_func", "wg_vec3", ty.vec3<f32>(), {});
+ MakePlainGlobalReferenceBodyFunction("wg_func", "wg_vec3", ty.vec3<f32>(), utils::Empty);
- MakeCallerBodyFunction("ep_func", {"wg_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("wg_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -3046,13 +3293,19 @@
// here the struct is expected to occupy 1024 bytes of workgroup storage.
const auto* wg_struct_type = MakeStructTypeFromMembers(
"WgStruct",
- {MakeStructMember(0, ty.f32(), {create<ast::StructMemberAlignAttribute>(1024u)})});
+ utils::Vector{
+ MakeStructMember(0, ty.f32(),
+ utils::Vector{create<ast::StructMemberAlignAttribute>(1024u)}),
+ });
AddWorkgroupStorage("wg_struct_var", ty.Of(wg_struct_type));
- MakeStructVariableReferenceBodyFunction("wg_struct_func", "wg_struct_var", {{0, ty.f32()}});
+ MakeStructVariableReferenceBodyFunction("wg_struct_func", "wg_struct_var",
+ utils::Vector{
+ MemberInfo{0, ty.f32()},
+ });
- MakeCallerBodyFunction("ep_func", {"wg_struct_func"},
- {
+ MakeCallerBodyFunction("ep_func", utils::Vector{std::string("wg_struct_func")},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/inspector/test_inspector_builder.cc b/src/tint/inspector/test_inspector_builder.cc
index 23b473c..5b89d7c 100644
--- a/src/tint/inspector/test_inspector_builder.cc
+++ b/src/tint/inspector/test_inspector_builder.cc
@@ -27,32 +27,36 @@
InspectorBuilder::InspectorBuilder() = default;
InspectorBuilder::~InspectorBuilder() = default;
-void InspectorBuilder::MakeEmptyBodyFunction(std::string name, ast::AttributeList attributes) {
- Func(name, {}, ty.void_(), {Return()}, attributes);
+void InspectorBuilder::MakeEmptyBodyFunction(std::string name,
+ utils::VectorRef<const ast::Attribute*> attributes) {
+ Func(name, utils::Empty, ty.void_(), utils::Vector{Return()}, attributes);
}
void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
- std::vector<std::string> callees,
- ast::AttributeList attributes) {
- ast::StatementList body;
- body.reserve(callees.size() + 1);
+ utils::VectorRef<std::string> callees,
+ utils::VectorRef<const ast::Attribute*> attributes) {
+ utils::Vector<const ast::Statement*, 8> body;
+ body.Reserve(callees.Length() + 1);
for (auto callee : callees) {
- body.push_back(CallStmt(Call(callee)));
+ body.Push(CallStmt(Call(callee)));
}
- body.push_back(Return());
+ body.Push(Return());
- Func(caller, {}, ty.void_(), body, attributes);
+ Func(caller, utils::Empty, ty.void_(), body, attributes);
}
-const ast::Struct* InspectorBuilder::MakeInOutStruct(
- std::string name,
- std::vector<std::tuple<std::string, uint32_t>> inout_vars) {
- ast::StructMemberList members;
+const ast::Struct* InspectorBuilder::MakeInOutStruct(std::string name,
+ utils::VectorRef<InOutInfo> inout_vars) {
+ utils::Vector<const ast::StructMember*, 8> members;
for (auto var : inout_vars) {
std::string member_name;
uint32_t location;
std::tie(member_name, location) = var;
- members.push_back(Member(member_name, ty.u32(), {Location(location), Flat()}));
+ members.Push(Member(member_name, ty.u32(),
+ utils::Vector{
+ Location(location),
+ Flat(),
+ }));
}
return Structure(name, members);
}
@@ -61,17 +65,15 @@
std::string func,
std::string var,
const ast::Type* type,
- ast::AttributeList attributes) {
- ast::StatementList stmts;
- stmts.emplace_back(Decl(Var("local_" + var, type)));
- stmts.emplace_back(Assign("local_" + var, var));
- stmts.emplace_back(Return());
-
- return Func(func, {}, ty.void_(), stmts, attributes);
+ utils::VectorRef<const ast::Attribute*> attributes) {
+ utils::Vector<const ast::Statement*, 3> stmts;
+ stmts.Push(Decl(Var("local_" + var, type)));
+ stmts.Push(Assign("local_" + var, var));
+ stmts.Push(Return());
+ return Func(func, utils::Empty, ty.void_(), std::move(stmts), std::move(attributes));
}
-bool InspectorBuilder::ContainsName(const std::vector<StageVariable>& vec,
- const std::string& name) {
+bool InspectorBuilder::ContainsName(utils::VectorRef<StageVariable> vec, const std::string& name) {
for (auto& s : vec) {
if (s.name == name) {
return true;
@@ -84,35 +86,38 @@
return std::to_string(idx) + type->FriendlyName(Symbols());
}
-const ast::Struct* InspectorBuilder::MakeStructType(const std::string& name,
- std::vector<const ast::Type*> member_types) {
- ast::StructMemberList members;
+const ast::Struct* InspectorBuilder::MakeStructType(
+ const std::string& name,
+ utils::VectorRef<const ast::Type*> member_types) {
+ utils::Vector<const ast::StructMember*, 8> members;
for (auto* type : member_types) {
- members.push_back(MakeStructMember(members.size(), type, {}));
+ members.Push(MakeStructMember(members.Length(), type, {}));
}
return MakeStructTypeFromMembers(name, std::move(members));
}
-const ast::Struct* InspectorBuilder::MakeStructTypeFromMembers(const std::string& name,
- ast::StructMemberList members) {
+const ast::Struct* InspectorBuilder::MakeStructTypeFromMembers(
+ const std::string& name,
+ utils::VectorRef<const ast::StructMember*> members) {
return Structure(name, std::move(members));
}
-const ast::StructMember* InspectorBuilder::MakeStructMember(size_t index,
- const ast::Type* type,
- ast::AttributeList attributes) {
+const ast::StructMember* InspectorBuilder::MakeStructMember(
+ size_t index,
+ const ast::Type* type,
+ utils::VectorRef<const ast::Attribute*> attributes) {
return Member(StructMemberName(index, type), type, std::move(attributes));
}
const ast::Struct* InspectorBuilder::MakeUniformBufferType(
const std::string& name,
- std::vector<const ast::Type*> member_types) {
+ utils::VectorRef<const ast::Type*> member_types) {
return MakeStructType(name, member_types);
}
std::function<const ast::TypeName*()> InspectorBuilder::MakeStorageBufferTypes(
const std::string& name,
- std::vector<const ast::Type*> member_types) {
+ utils::VectorRef<const ast::Type*> member_types) {
MakeStructType(name, member_types);
return [this, name] { return ty.type_name(name); };
}
@@ -122,7 +127,7 @@
uint32_t group,
uint32_t binding) {
GlobalVar(name, type, ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(binding),
create<ast::GroupAttribute>(group),
});
@@ -138,7 +143,7 @@
uint32_t group,
uint32_t binding) {
GlobalVar(name, type, ast::StorageClass::kStorage, access,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(binding),
create<ast::GroupAttribute>(group),
});
@@ -147,15 +152,15 @@
void InspectorBuilder::MakeStructVariableReferenceBodyFunction(
std::string func_name,
std::string struct_name,
- std::vector<std::tuple<size_t, const ast::Type*>> members) {
- ast::StatementList stmts;
+ utils::VectorRef<std::tuple<size_t, const ast::Type*>> members) {
+ utils::Vector<const ast::Statement*, 8> stmts;
for (auto member : members) {
size_t member_idx;
const ast::Type* member_type;
std::tie(member_idx, member_type) = member;
std::string member_name = StructMemberName(member_idx, member_type);
- stmts.emplace_back(Decl(Var("local" + member_name, member_type)));
+ stmts.Push(Decl(Var("local" + member_name, member_type)));
}
for (auto member : members) {
@@ -164,17 +169,17 @@
std::tie(member_idx, member_type) = member;
std::string member_name = StructMemberName(member_idx, member_type);
- stmts.emplace_back(Assign("local" + member_name, MemberAccessor(struct_name, member_name)));
+ stmts.Push(Assign("local" + member_name, MemberAccessor(struct_name, member_name)));
}
- stmts.emplace_back(Return());
+ stmts.Push(Return());
- Func(func_name, {}, ty.void_(), stmts);
+ Func(func_name, utils::Empty, ty.void_(), stmts);
}
void InspectorBuilder::AddSampler(const std::string& name, uint32_t group, uint32_t binding) {
GlobalVar(name, sampler_type(),
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(binding),
create<ast::GroupAttribute>(group),
});
@@ -184,7 +189,7 @@
uint32_t group,
uint32_t binding) {
GlobalVar(name, comparison_sampler_type(),
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(binding),
create<ast::GroupAttribute>(group),
});
@@ -195,7 +200,7 @@
uint32_t group,
uint32_t binding) {
GlobalVar(name, type,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(binding),
create<ast::GroupAttribute>(group),
});
@@ -211,17 +216,15 @@
const std::string& sampler_name,
const std::string& coords_name,
const ast::Type* base_type,
- ast::AttributeList attributes) {
+ utils::VectorRef<const ast::Attribute*> attributes) {
std::string result_name = "sampler_result";
- ast::StatementList stmts;
- stmts.emplace_back(Decl(Var(result_name, ty.vec(base_type, 4))));
-
- stmts.emplace_back(
- Assign(result_name, Call("textureSample", texture_name, sampler_name, coords_name)));
- stmts.emplace_back(Return());
-
- return Func(func_name, {}, ty.void_(), stmts, attributes);
+ utils::Vector stmts{
+ Decl(Var(result_name, ty.vec(base_type, 4))),
+ Assign(result_name, Call("textureSample", texture_name, sampler_name, coords_name)),
+ Return(),
+ };
+ return Func(func_name, utils::Empty, ty.void_(), std::move(stmts), std::move(attributes));
}
const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
@@ -231,18 +234,16 @@
const std::string& coords_name,
const std::string& array_index,
const ast::Type* base_type,
- ast::AttributeList attributes) {
+ utils::VectorRef<const ast::Attribute*> attributes) {
std::string result_name = "sampler_result";
- ast::StatementList stmts;
-
- stmts.emplace_back(Decl(Var("sampler_result", ty.vec(base_type, 4))));
-
- stmts.emplace_back(Assign("sampler_result", Call("textureSample", texture_name, sampler_name,
- coords_name, array_index)));
- stmts.emplace_back(Return());
-
- return Func(func_name, {}, ty.void_(), stmts, attributes);
+ utils::Vector stmts{
+ Decl(Var("sampler_result", ty.vec(base_type, 4))),
+ Assign("sampler_result",
+ Call("textureSample", texture_name, sampler_name, coords_name, array_index)),
+ Return(),
+ };
+ return Func(func_name, utils::Empty, ty.void_(), std::move(stmts), std::move(attributes));
}
const ast::Function* InspectorBuilder::MakeComparisonSamplerReferenceBodyFunction(
@@ -252,17 +253,16 @@
const std::string& coords_name,
const std::string& depth_name,
const ast::Type* base_type,
- ast::AttributeList attributes) {
+ utils::VectorRef<const ast::Attribute*> attributes) {
std::string result_name = "sampler_result";
- ast::StatementList stmts;
-
- stmts.emplace_back(Decl(Var("sampler_result", base_type)));
- stmts.emplace_back(Assign("sampler_result", Call("textureSampleCompare", texture_name,
- sampler_name, coords_name, depth_name)));
- stmts.emplace_back(Return());
-
- return Func(func_name, {}, ty.void_(), stmts, attributes);
+ utils::Vector stmts{
+ Decl(Var("sampler_result", base_type)),
+ Assign("sampler_result",
+ Call("textureSampleCompare", texture_name, sampler_name, coords_name, depth_name)),
+ Return(),
+ };
+ return Func(func_name, utils::Empty, ty.void_(), std::move(stmts), std::move(attributes));
}
const ast::Type* InspectorBuilder::GetBaseType(ResourceBinding::SampledKind sampled_kind) {
@@ -306,7 +306,7 @@
uint32_t group,
uint32_t binding) {
GlobalVar(name, type,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(binding),
create<ast::GroupAttribute>(group),
});
@@ -316,14 +316,14 @@
const std::string& func_name,
const std::string& st_name,
const ast::Type* dim_type,
- ast::AttributeList attributes) {
- ast::StatementList stmts;
+ utils::VectorRef<const ast::Attribute*> attributes) {
+ utils::Vector stmts{
+ Decl(Var("dim", dim_type)),
+ Assign("dim", Call("textureDimensions", st_name)),
+ Return(),
+ };
- stmts.emplace_back(Decl(Var("dim", dim_type)));
- stmts.emplace_back(Assign("dim", Call("textureDimensions", st_name)));
- stmts.emplace_back(Return());
-
- return Func(func_name, {}, ty.void_(), stmts, attributes);
+ return Func(func_name, utils::Empty, ty.void_(), std::move(stmts), std::move(attributes));
}
std::function<const ast::Type*()> InspectorBuilder::GetTypeFunction(ComponentType component,
diff --git a/src/tint/inspector/test_inspector_builder.h b/src/tint/inspector/test_inspector_builder.h
index a3ccb13..fe43c69 100644
--- a/src/tint/inspector/test_inspector_builder.h
+++ b/src/tint/inspector/test_inspector_builder.h
@@ -44,28 +44,31 @@
/// Generates an empty function
/// @param name name of the function created
/// @param attributes the function attributes
- void MakeEmptyBodyFunction(std::string name, ast::AttributeList attributes);
+ void MakeEmptyBodyFunction(std::string name,
+ utils::VectorRef<const ast::Attribute*> attributes);
/// Generates a function that calls other functions
/// @param caller name of the function created
/// @param callees names of the functions to be called
/// @param attributes the function attributes
void MakeCallerBodyFunction(std::string caller,
- std::vector<std::string> callees,
- ast::AttributeList attributes);
+ utils::VectorRef<std::string> callees,
+ utils::VectorRef<const ast::Attribute*> attributes);
+
+ /// InOutInfo is a tuple of name and location for a structure member
+ using InOutInfo = std::tuple<std::string, uint32_t>;
/// Generates a struct that contains user-defined IO members
/// @param name the name of the generated struct
/// @param inout_vars tuples of {name, loc} that will be the struct members
/// @returns a structure object
- const ast::Struct* MakeInOutStruct(std::string name,
- std::vector<std::tuple<std::string, uint32_t>> inout_vars);
+ const ast::Struct* MakeInOutStruct(std::string name, utils::VectorRef<InOutInfo> inout_vars);
// TODO(crbug.com/tint/697): Remove this.
/// Add In/Out variables to the global variables
/// @param inout_vars tuples of {in, out} that will be added as entries to the
/// global variables
- void AddInOutVariables(std::vector<std::tuple<std::string, std::string>> inout_vars);
+ void AddInOutVariables(utils::VectorRef<std::tuple<std::string, std::string>> inout_vars);
// TODO(crbug.com/tint/697): Remove this.
/// Generates a function that references in/out variables
@@ -73,9 +76,10 @@
/// @param inout_vars tuples of {in, out} that will be converted into out = in
/// calls in the function body
/// @param attributes the function attributes
- void MakeInOutVariableBodyFunction(std::string name,
- std::vector<std::tuple<std::string, std::string>> inout_vars,
- ast::AttributeList attributes);
+ void MakeInOutVariableBodyFunction(
+ std::string name,
+ utils::VectorRef<std::tuple<std::string, std::string>> inout_vars,
+ utils::VectorRef<const ast::Attribute*> attributes);
// TODO(crbug.com/tint/697): Remove this.
/// Generates a function that references in/out variables and calls another
@@ -89,9 +93,8 @@
const ast::Function* MakeInOutVariableCallerBodyFunction(
std::string caller,
std::string callee,
- std::vector<std::tuple<std::string, std::string>> inout_vars,
- ast::AttributeList attributes);
-
+ utils::VectorRef<std::tuple<std::string, std::string>> inout_vars,
+ utils::VectorRef<const ast::Attribute*> attributes);
/// Generates a function that references module-scoped, plain-typed constant
/// or variable.
@@ -100,15 +103,16 @@
/// @param type type of the const being referenced
/// @param attributes the function attributes
/// @returns a function object
- const ast::Function* MakePlainGlobalReferenceBodyFunction(std::string func,
- std::string var,
- const ast::Type* type,
- ast::AttributeList attributes);
+ const ast::Function* MakePlainGlobalReferenceBodyFunction(
+ std::string func,
+ std::string var,
+ const ast::Type* type,
+ utils::VectorRef<const ast::Attribute*> attributes);
/// @param vec Vector of StageVariable to be searched
/// @param name Name to be searching for
/// @returns true if name is in vec, otherwise false
- bool ContainsName(const std::vector<StageVariable>& vec, const std::string& name);
+ bool ContainsName(utils::VectorRef<StageVariable> vec, const std::string& name);
/// Builds a string for accessing a member in a generated struct
/// @param idx index of member
@@ -121,14 +125,15 @@
/// @param member_types a vector of member types
/// @returns a struct type
const ast::Struct* MakeStructType(const std::string& name,
- std::vector<const ast::Type*> member_types);
+ utils::VectorRef<const ast::Type*> member_types);
/// Generates a struct type from a list of member nodes.
/// @param name name for the struct type
/// @param members a vector of members
/// @returns a struct type
- const ast::Struct* MakeStructTypeFromMembers(const std::string& name,
- ast::StructMemberList members);
+ const ast::Struct* MakeStructTypeFromMembers(
+ const std::string& name,
+ utils::VectorRef<const ast::StructMember*> members);
/// Generates a struct member with a specified index and type.
/// @param index index of the field within the struct
@@ -137,14 +142,14 @@
/// @returns a struct member
const ast::StructMember* MakeStructMember(size_t index,
const ast::Type* type,
- ast::AttributeList attributes);
+ utils::VectorRef<const ast::Attribute*> attributes);
/// Generates types appropriate for using in an uniform buffer
/// @param name name for the type
/// @param member_types a vector of member types
/// @returns a struct type that has the layout for an uniform buffer.
const ast::Struct* MakeUniformBufferType(const std::string& name,
- std::vector<const ast::Type*> member_types);
+ utils::VectorRef<const ast::Type*> member_types);
/// Generates types appropriate for using in a storage buffer
/// @param name name for the type
@@ -152,7 +157,7 @@
/// @returns a function that returns the created structure.
std::function<const ast::TypeName*()> MakeStorageBufferTypes(
const std::string& name,
- std::vector<const ast::Type*> member_types);
+ utils::VectorRef<const ast::Type*> member_types);
/// Adds an uniform buffer variable to the program
/// @param name the name of the variable
@@ -181,14 +186,16 @@
uint32_t group,
uint32_t binding);
+ /// MemberInfo is a tuple of member index and type.
+ using MemberInfo = std::tuple<size_t, const ast::Type*>;
+
/// Generates a function that references a specific struct variable
/// @param func_name name of the function created
/// @param struct_name name of the struct variabler to be accessed
/// @param members list of members to access, by index and type
- void MakeStructVariableReferenceBodyFunction(
- std::string func_name,
- std::string struct_name,
- std::vector<std::tuple<size_t, const ast::Type*>> members);
+ void MakeStructVariableReferenceBodyFunction(std::string func_name,
+ std::string struct_name,
+ utils::VectorRef<MemberInfo> members);
/// Adds a regular sampler variable to the program
/// @param name the name of the variable
@@ -225,12 +232,13 @@
/// @param base_type sampler base type
/// @param attributes the function attributes
/// @returns a function that references all of the values specified
- const ast::Function* MakeSamplerReferenceBodyFunction(const std::string& func_name,
- const std::string& texture_name,
- const std::string& sampler_name,
- const std::string& coords_name,
- const ast::Type* base_type,
- ast::AttributeList attributes);
+ const ast::Function* MakeSamplerReferenceBodyFunction(
+ const std::string& func_name,
+ const std::string& texture_name,
+ const std::string& sampler_name,
+ const std::string& coords_name,
+ const ast::Type* base_type,
+ utils::VectorRef<const ast::Attribute*> attributes);
/// Generates a function that references a specific sampler variable
/// @param func_name name of the function created
@@ -241,13 +249,14 @@
/// @param base_type sampler base type
/// @param attributes the function attributes
/// @returns a function that references all of the values specified
- const ast::Function* MakeSamplerReferenceBodyFunction(const std::string& func_name,
- const std::string& texture_name,
- const std::string& sampler_name,
- const std::string& coords_name,
- const std::string& array_index,
- const ast::Type* base_type,
- ast::AttributeList attributes);
+ const ast::Function* MakeSamplerReferenceBodyFunction(
+ const std::string& func_name,
+ const std::string& texture_name,
+ const std::string& sampler_name,
+ const std::string& coords_name,
+ const std::string& array_index,
+ const ast::Type* base_type,
+ utils::VectorRef<const ast::Attribute*> attributes);
/// Generates a function that references a specific comparison sampler
/// variable.
@@ -259,13 +268,14 @@
/// @param base_type sampler base type
/// @param attributes the function attributes
/// @returns a function that references all of the values specified
- const ast::Function* MakeComparisonSamplerReferenceBodyFunction(const std::string& func_name,
- const std::string& texture_name,
- const std::string& sampler_name,
- const std::string& coords_name,
- const std::string& depth_name,
- const ast::Type* base_type,
- ast::AttributeList attributes);
+ const ast::Function* MakeComparisonSamplerReferenceBodyFunction(
+ const std::string& func_name,
+ const std::string& texture_name,
+ const std::string& sampler_name,
+ const std::string& coords_name,
+ const std::string& depth_name,
+ const ast::Type* base_type,
+ utils::VectorRef<const ast::Attribute*> attributes);
/// Gets an appropriate type for the data in a given texture type.
/// @param sampled_kind type of in the texture
@@ -301,10 +311,11 @@
/// @param dim_type type expected by textureDimensons to return
/// @param attributes the function attributes
/// @returns a function that references all of the values specified
- const ast::Function* MakeStorageTextureBodyFunction(const std::string& func_name,
- const std::string& st_name,
- const ast::Type* dim_type,
- ast::AttributeList attributes);
+ const ast::Function* MakeStorageTextureBodyFunction(
+ const std::string& func_name,
+ const std::string& st_name,
+ const ast::Type* dim_type,
+ utils::VectorRef<const ast::Attribute*> attributes);
/// Get a generator function that returns a type appropriate for a stage
/// variable with the given combination of component and composition type.
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index 6e1d8fb..54db7f5 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -49,6 +49,8 @@
chromium_experimental_dp4a
// A Chromium-specific extension for disabling uniformity analysis.
chromium_disable_uniformity_analysis
+ // A Chromium-specific extension for push constants
+ chromium_experimental_push_constant
}
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
@@ -59,6 +61,7 @@
workgroup
uniform
storage
+ push_constant
@internal handle
@internal in
@internal out
@@ -145,10 +148,10 @@
type texture_storage_3d<F: texel_format, A: access>
type texture_external
-type __modf_result
-@display("__modf_result_vec{N}") type __modf_result_vec<N: num>
-type __frexp_result
-@display("__frexp_result_vec{N}") type __frexp_result_vec<N: num>
+@display("__modf_result_{T}") type __modf_result<T>
+@display("__modf_result_vec{N}_{T}") type __modf_result_vec<N: num, T>
+@display("__frexp_result_{T}") type __frexp_result<T>
+@display("__frexp_result_vec{N}_{T}") type __frexp_result_vec<N: num, T>
type __atomic_compare_exchange_result<T>
@@ -460,8 +463,8 @@
fn fma<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
fn fract<T: f32_f16>(T) -> T
fn fract<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
-fn frexp(f32) -> __frexp_result
-fn frexp<N: num>(vec<N, f32>) -> __frexp_result_vec<N>
+fn frexp<T: f32_f16>(T) -> __frexp_result<T>
+fn frexp<N: num, T: f32_f16>(vec<N, T>) -> __frexp_result_vec<N, T>
@stage("fragment") fn fwidth(f32) -> f32
@stage("fragment") fn fwidth<N: num>(vec<N, f32>) -> vec<N, f32>
@stage("fragment") fn fwidthCoarse(f32) -> f32
@@ -487,8 +490,8 @@
fn mix<T: f32_f16>(T, T, T) -> T
fn mix<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
fn mix<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T>
-fn modf(f32) -> __modf_result
-fn modf<N: num>(vec<N, f32>) -> __modf_result_vec<N>
+fn modf<T: f32_f16>(T) -> __modf_result<T>
+fn modf<N: num, T: f32_f16>(vec<N, T>) -> __modf_result_vec<N, T>
fn normalize<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
fn pack2x16float(vec2<f32>) -> u32
fn pack2x16snorm(vec2<f32>) -> u32
@@ -883,11 +886,11 @@
////////////////////////////////////////////////////////////////////////////////
// Binary Operators //
////////////////////////////////////////////////////////////////////////////////
-op + <T: fiu32_f16>(T, T) -> T
-op + <T: fiu32_f16, N: num> (vec<N, T>, vec<N, T>) -> vec<N, T>
-op + <T: fiu32_f16, N: num> (vec<N, T>, T) -> vec<N, T>
-op + <T: fiu32_f16, N: num> (T, vec<N, T>) -> vec<N, T>
-op + <T: f32_f16, N: num, M: num> (mat<N, M, T>, mat<N, M, T>) -> mat<N, M, T>
+@const op + <T: fia_fiu32_f16>(T, T) -> T
+@const op + <T: fia_fiu32_f16, N: num> (vec<N, T>, vec<N, T>) -> vec<N, T>
+@const op + <T: fia_fiu32_f16, N: num> (vec<N, T>, T) -> vec<N, T>
+@const op + <T: fia_fiu32_f16, N: num> (T, vec<N, T>) -> vec<N, T>
+@const op + <T: fa_f32_f16, N: num, M: num> (mat<N, M, T>, mat<N, M, T>) -> mat<N, M, T>
op - <T: fiu32_f16>(T, T) -> T
op - <T: fiu32_f16, N: num> (vec<N, T>, vec<N, T>) -> vec<N, T>
diff --git a/src/tint/number.h b/src/tint/number.h
index 13ba76c..3c8d5a0 100644
--- a/src/tint/number.h
+++ b/src/tint/number.h
@@ -363,6 +363,15 @@
return AInt(result);
}
+/// @returns a + b, or an empty optional if the resulting value overflowed the AFloat
+inline std::optional<AFloat> CheckedAdd(AFloat a, AFloat b) {
+ auto result = a.value + b.value;
+ if (!std::isfinite(result)) {
+ return {};
+ }
+ return AFloat{result};
+}
+
/// @returns a * b, or an empty optional if the resulting value overflowed the AInt
inline std::optional<AInt> CheckedMul(AInt a, AInt b) {
int64_t result;
diff --git a/src/tint/number_test.cc b/src/tint/number_test.cc
index 16925ed..c245fb4 100644
--- a/src/tint/number_test.cc
+++ b/src/tint/number_test.cc
@@ -356,24 +356,25 @@
/////////////////////////////////////
}));
-using BinaryCheckedCase = std::tuple<std::optional<AInt>, AInt, AInt>;
-
#undef OVERFLOW // corecrt_math.h :(
#define OVERFLOW \
{}
-using CheckedAddTest = testing::TestWithParam<BinaryCheckedCase>;
-TEST_P(CheckedAddTest, Test) {
+using BinaryCheckedCase_AInt = std::tuple<std::optional<AInt>, AInt, AInt>;
+using BinaryCheckedCase_AFloat = std::tuple<std::optional<AFloat>, AFloat, AFloat>;
+
+using CheckedAddTest_AInt = testing::TestWithParam<BinaryCheckedCase_AInt>;
+TEST_P(CheckedAddTest_AInt, Test) {
auto expect = std::get<0>(GetParam());
auto a = std::get<1>(GetParam());
auto b = std::get<2>(GetParam());
- EXPECT_EQ(CheckedAdd(a, b), expect) << std::hex << "0x" << a << " * 0x" << b;
- EXPECT_EQ(CheckedAdd(b, a), expect) << std::hex << "0x" << a << " * 0x" << b;
+ EXPECT_EQ(CheckedAdd(a, b), expect) << std::hex << "0x" << a << " + 0x" << b;
+ EXPECT_EQ(CheckedAdd(b, a), expect) << std::hex << "0x" << a << " + 0x" << b;
}
INSTANTIATE_TEST_SUITE_P(
- CheckedAddTest,
- CheckedAddTest,
- testing::ValuesIn(std::vector<BinaryCheckedCase>{
+ CheckedAddTest_AInt,
+ CheckedAddTest_AInt,
+ testing::ValuesIn(std::vector<BinaryCheckedCase_AInt>{
{AInt(0), AInt(0), AInt(0)},
{AInt(1), AInt(1), AInt(0)},
{AInt(2), AInt(1), AInt(1)},
@@ -398,8 +399,37 @@
////////////////////////////////////////////////////////////////////////
}));
-using CheckedMulTest = testing::TestWithParam<BinaryCheckedCase>;
-TEST_P(CheckedMulTest, Test) {
+using CheckedAddTest_AFloat = testing::TestWithParam<BinaryCheckedCase_AFloat>;
+TEST_P(CheckedAddTest_AFloat, Test) {
+ auto expect = std::get<0>(GetParam());
+ auto a = std::get<1>(GetParam());
+ auto b = std::get<2>(GetParam());
+ EXPECT_EQ(CheckedAdd(a, b), expect) << std::hex << "0x" << a << " + 0x" << b;
+ EXPECT_EQ(CheckedAdd(b, a), expect) << std::hex << "0x" << a << " + 0x" << b;
+}
+INSTANTIATE_TEST_SUITE_P(
+ CheckedAddTest_AFloat,
+ CheckedAddTest_AFloat,
+ testing::ValuesIn(std::vector<BinaryCheckedCase_AFloat>{
+ {AFloat(0), AFloat(0), AFloat(0)},
+ {AFloat(1), AFloat(1), AFloat(0)},
+ {AFloat(2), AFloat(1), AFloat(1)},
+ {AFloat(0), AFloat(-1), AFloat(1)},
+ {AFloat(3), AFloat(2), AFloat(1)},
+ {AFloat(-1), AFloat(-2), AFloat(1)},
+ {AFloat(0x300), AFloat(0x100), AFloat(0x200)},
+ {AFloat(0x100), AFloat(-0x100), AFloat(0x200)},
+ {AFloat::Highest(), AFloat(1), AFloat(AFloat::kHighestValue - 1)},
+ {AFloat::Lowest(), AFloat(-1), AFloat(AFloat::kLowestValue + 1)},
+ {AFloat::Highest(), AFloat::Highest(), AFloat(0)},
+ {AFloat::Lowest(), AFloat::Lowest(), AFloat(0)},
+ {OVERFLOW, AFloat::Highest(), AFloat::Highest()},
+ {OVERFLOW, AFloat::Lowest(), AFloat::Lowest()},
+ ////////////////////////////////////////////////////////////////////////
+ }));
+
+using CheckedMulTest_AInt = testing::TestWithParam<BinaryCheckedCase_AInt>;
+TEST_P(CheckedMulTest_AInt, Test) {
auto expect = std::get<0>(GetParam());
auto a = std::get<1>(GetParam());
auto b = std::get<2>(GetParam());
@@ -407,9 +437,9 @@
EXPECT_EQ(CheckedMul(b, a), expect) << std::hex << "0x" << a << " * 0x" << b;
}
INSTANTIATE_TEST_SUITE_P(
- CheckedMulTest,
- CheckedMulTest,
- testing::ValuesIn(std::vector<BinaryCheckedCase>{
+ CheckedMulTest_AInt,
+ CheckedMulTest_AInt,
+ testing::ValuesIn(std::vector<BinaryCheckedCase_AInt>{
{AInt(0), AInt(0), AInt(0)},
{AInt(0), AInt(1), AInt(0)},
{AInt(1), AInt(1), AInt(1)},
@@ -446,8 +476,8 @@
using TernaryCheckedCase = std::tuple<std::optional<AInt>, AInt, AInt, AInt>;
-using CheckedMaddTest = testing::TestWithParam<TernaryCheckedCase>;
-TEST_P(CheckedMaddTest, Test) {
+using CheckedMaddTest_AInt = testing::TestWithParam<TernaryCheckedCase>;
+TEST_P(CheckedMaddTest_AInt, Test) {
auto expect = std::get<0>(GetParam());
auto a = std::get<1>(GetParam());
auto b = std::get<2>(GetParam());
@@ -458,8 +488,8 @@
<< std::hex << "0x" << a << " * 0x" << b << " + 0x" << c;
}
INSTANTIATE_TEST_SUITE_P(
- CheckedMaddTest,
- CheckedMaddTest,
+ CheckedMaddTest_AInt,
+ CheckedMaddTest_AInt,
testing::ValuesIn(std::vector<TernaryCheckedCase>{
{AInt(0), AInt(0), AInt(0), AInt(0)},
{AInt(0), AInt(1), AInt(0), AInt(0)},
diff --git a/src/tint/program_builder.cc b/src/tint/program_builder.cc
index 19f20b4..1507cd3 100644
--- a/src/tint/program_builder.cc
+++ b/src/tint/program_builder.cc
@@ -129,9 +129,9 @@
return stmt;
}
-const ast::Function* ProgramBuilder::WrapInFunction(const ast::StatementList stmts) {
+const ast::Function* ProgramBuilder::WrapInFunction(utils::VectorRef<const ast::Statement*> stmts) {
return Func("test_function", {}, ty.void_(), std::move(stmts),
- {
+ utils::Vector{
create<ast::StageAttribute>(ast::PipelineStage::kCompute),
WorkgroupSize(1_i, 1_i, 1_i),
});
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index 1a3313b..25766e6 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -70,6 +70,7 @@
#include "src/tint/ast/sampled_texture.h"
#include "src/tint/ast/sampler.h"
#include "src/tint/ast/stage_attribute.h"
+#include "src/tint/ast/static_assert.h"
#include "src/tint/ast/storage_texture.h"
#include "src/tint/ast/stride_attribute.h"
#include "src/tint/ast/struct_member_align_attribute.h"
@@ -120,6 +121,30 @@
namespace tint {
+namespace detail {
+
+/// IsVectorLike<T>::value is true if T is a utils::Vector or utils::VectorRef.
+template <typename T>
+struct IsVectorLike {
+ /// Non-specialized form of IsVectorLike defaults to false
+ static constexpr bool value = false;
+};
+
+/// IsVectorLike specialization for utils::Vector
+template <typename T, size_t N>
+struct IsVectorLike<utils::Vector<T, N>> {
+ /// True for the IsVectorLike specialization of utils::Vector
+ static constexpr bool value = true;
+};
+
+/// IsVectorLike specialization for utils::VectorRef
+template <typename T>
+struct IsVectorLike<utils::VectorRef<T>> {
+ /// True for the IsVectorLike specialization of utils::VectorRef
+ static constexpr bool value = true;
+};
+} // namespace detail
+
/// ProgramBuilder is a mutable builder for a Program.
/// To construct a Program, populate the builder and then `std::move` it to a
/// Program.
@@ -131,6 +156,12 @@
using DisableIfSource =
traits::EnableIfIsNotType<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>, Source>;
+ /// A helper used to disable overloads if the first type in `TYPES` is a utils::Vector,
+ /// utils::VectorRef or utils::VectorRef.
+ template <typename... TYPES>
+ using DisableIfVectorLike = traits::EnableIf<
+ !detail::IsVectorLike<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>::value>;
+
/// VarOptionals is a helper for accepting a number of optional, extra
/// arguments for Var() and GlobalVar().
struct VarOptionals {
@@ -143,13 +174,13 @@
ast::StorageClass storage = ast::StorageClass::kNone;
ast::Access access = ast::Access::kUndefined;
const ast::Expression* constructor = nullptr;
- ast::AttributeList attributes = {};
+ utils::Vector<const ast::Attribute*, 4> attributes;
private:
void Set(ast::StorageClass sc) { storage = sc; }
void Set(ast::Access ac) { access = ac; }
void Set(const ast::Expression* c) { constructor = c; }
- void Set(const ast::AttributeList& l) { attributes = l; }
+ void Set(utils::VectorRef<const ast::Attribute*> l) { attributes = std::move(l); }
template <typename FIRST, typename... ARGS>
void Apply(FIRST&& first, ARGS&&... args) {
@@ -687,11 +718,12 @@
/// @param attrs the optional attributes for the array
/// @return the tint AST type for a array of size `n` of type `T`
template <typename EXPR = ast::Expression*>
- const ast::Array* array(const ast::Type* subtype,
- EXPR&& n = nullptr,
- ast::AttributeList attrs = {}) const {
+ const ast::Array* array(
+ const ast::Type* subtype,
+ EXPR&& n = nullptr,
+ utils::VectorRef<const ast::Attribute*> attrs = utils::Empty) const {
return builder->create<ast::Array>(subtype, builder->Expr(std::forward<EXPR>(n)),
- attrs);
+ std::move(attrs));
}
/// @param source the Source of the node
@@ -700,12 +732,13 @@
/// @param attrs the optional attributes for the array
/// @return the tint AST type for a array of size `n` of type `T`
template <typename EXPR = ast::Expression*>
- const ast::Array* array(const Source& source,
- const ast::Type* subtype,
- EXPR&& n = nullptr,
- ast::AttributeList attrs = {}) const {
- return builder->create<ast::Array>(source, subtype,
- builder->Expr(std::forward<EXPR>(n)), attrs);
+ const ast::Array* array(
+ const Source& source,
+ const ast::Type* subtype,
+ EXPR&& n = nullptr,
+ utils::VectorRef<const ast::Attribute*> attrs = utils::Empty) const {
+ return builder->create<ast::Array>(
+ source, subtype, builder->Expr(std::forward<EXPR>(n)), std::move(attrs));
}
/// @param subtype the array element type
@@ -714,9 +747,9 @@
/// @return the tint AST type for a array of size `n` of type `T`
template <typename EXPR>
const ast::Array* array(const ast::Type* subtype, EXPR&& n, uint32_t stride) const {
- ast::AttributeList attrs;
+ utils::Vector<const ast::Attribute*, 2> attrs;
if (stride) {
- attrs.emplace_back(builder->create<ast::StrideAttribute>(stride));
+ attrs.Push(builder->create<ast::StrideAttribute>(stride));
}
return array(subtype, std::forward<EXPR>(n), std::move(attrs));
}
@@ -731,9 +764,9 @@
const ast::Type* subtype,
EXPR&& n,
uint32_t stride) const {
- ast::AttributeList attrs;
+ utils::Vector<const ast::Attribute*, 2> attrs;
if (stride) {
- attrs.emplace_back(builder->create<ast::StrideAttribute>(stride));
+ attrs.Push(builder->create<ast::StrideAttribute>(stride));
}
return array(source, subtype, std::forward<EXPR>(n), std::move(attrs));
}
@@ -1182,9 +1215,9 @@
/// `list`.
/// @param list the list to append too
/// @param arg the arg to create
- template <typename ARG>
- void Append(ast::ExpressionList& list, ARG&& arg) {
- list.emplace_back(Expr(std::forward<ARG>(arg)));
+ template <size_t N, typename ARG>
+ void Append(utils::Vector<const ast::Expression*, N>& list, ARG&& arg) {
+ list.Push(Expr(std::forward<ARG>(arg)));
}
/// Converts `arg0` and `args` to `ast::Expression`s using `Expr()`,
@@ -1192,29 +1225,38 @@
/// @param list the list to append too
/// @param arg0 the first argument
/// @param args the rest of the arguments
- template <typename ARG0, typename... ARGS>
- void Append(ast::ExpressionList& list, ARG0&& arg0, ARGS&&... args) {
+ template <size_t N, typename ARG0, typename... ARGS>
+ void Append(utils::Vector<const ast::Expression*, N>& list, ARG0&& arg0, ARGS&&... args) {
Append(list, std::forward<ARG0>(arg0));
Append(list, std::forward<ARGS>(args)...);
}
- /// @return an empty list of expressions
- ast::ExpressionList ExprList() { return {}; }
+ /// @return utils::EmptyType
+ utils::EmptyType ExprList() { return utils::Empty; }
/// @param args the list of expressions
/// @return the list of expressions converted to `ast::Expression`s using
/// `Expr()`,
- template <typename... ARGS>
- ast::ExpressionList ExprList(ARGS&&... args) {
- ast::ExpressionList list;
- list.reserve(sizeof...(args));
+ template <typename... ARGS, typename = DisableIfVectorLike<ARGS...>>
+ auto ExprList(ARGS&&... args) {
+ utils::Vector<const ast::Expression*, sizeof...(ARGS)> list;
Append(list, std::forward<ARGS>(args)...);
return list;
}
/// @param list the list of expressions
/// @return `list`
- ast::ExpressionList ExprList(ast::ExpressionList list) { return list; }
+ template <typename T, size_t N>
+ utils::Vector<T, N> ExprList(utils::Vector<T, N>&& list) {
+ return std::move(list);
+ }
+
+ /// @param list the list of expressions
+ /// @return `list`
+ utils::VectorRef<const ast::Expression*> ExprList(
+ utils::VectorRef<const ast::Expression*> list) {
+ return list;
+ }
/// @param args the arguments for the type constructor
/// @return an `ast::CallExpression` of type `ty`, with the values
@@ -1589,7 +1631,7 @@
const ast::Const* Const(NAME&& name,
const ast::Type* type,
const ast::Expression* constructor,
- ast::AttributeList attributes = {}) {
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
return create<ast::Const>(Sym(std::forward<NAME>(name)), type, constructor, attributes);
}
@@ -1604,7 +1646,7 @@
NAME&& name,
const ast::Type* type,
const ast::Expression* constructor,
- ast::AttributeList attributes = {}) {
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
return create<ast::Const>(source, Sym(std::forward<NAME>(name)), type, constructor,
attributes);
}
@@ -1618,7 +1660,7 @@
const ast::Let* Let(NAME&& name,
const ast::Type* type,
const ast::Expression* constructor,
- ast::AttributeList attributes = {}) {
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
return create<ast::Let>(Sym(std::forward<NAME>(name)), type, constructor, attributes);
}
@@ -1633,7 +1675,7 @@
NAME&& name,
const ast::Type* type,
const ast::Expression* constructor,
- ast::AttributeList attributes = {}) {
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
return create<ast::Let>(source, Sym(std::forward<NAME>(name)), type, constructor,
attributes);
}
@@ -1645,7 +1687,7 @@
template <typename NAME>
const ast::Parameter* Param(NAME&& name,
const ast::Type* type,
- ast::AttributeList attributes = {}) {
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
return create<ast::Parameter>(Sym(std::forward<NAME>(name)), type, attributes);
}
@@ -1658,7 +1700,7 @@
const ast::Parameter* Param(const Source& source,
NAME&& name,
const ast::Type* type,
- ast::AttributeList attributes = {}) {
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
return create<ast::Parameter>(source, Sym(std::forward<NAME>(name)), type, attributes);
}
@@ -1712,10 +1754,11 @@
/// @returns an `ast::Const` constructed by calling Const() with the arguments of `args`, which
/// is automatically registered as a global variable with the ast::Module.
template <typename NAME>
- const ast::Const* GlobalConst(NAME&& name,
- const ast::Type* type,
- const ast::Expression* constructor,
- ast::AttributeList attributes = {}) {
+ const ast::Const* GlobalConst(
+ NAME&& name,
+ const ast::Type* type,
+ const ast::Expression* constructor,
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
auto* var = Const(std::forward<NAME>(name), type, constructor, std::move(attributes));
AST().AddGlobalVariable(var);
return var;
@@ -1730,11 +1773,12 @@
/// arguments of `args`, which is automatically registered as a global
/// variable with the ast::Module.
template <typename NAME>
- const ast::Const* GlobalConst(const Source& source,
- NAME&& name,
- const ast::Type* type,
- const ast::Expression* constructor,
- ast::AttributeList attributes = {}) {
+ const ast::Const* GlobalConst(
+ const Source& source,
+ NAME&& name,
+ const ast::Type* type,
+ const ast::Expression* constructor,
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
auto* var =
Const(source, std::forward<NAME>(name), type, constructor, std::move(attributes));
AST().AddGlobalVariable(var);
@@ -1748,10 +1792,11 @@
/// @returns an `ast::Override` which is automatically registered as a global variable with the
/// ast::Module.
template <typename NAME>
- const ast::Override* Override(NAME&& name,
- const ast::Type* type,
- const ast::Expression* constructor,
- ast::AttributeList attributes = {}) {
+ const ast::Override* Override(
+ NAME&& name,
+ const ast::Type* type,
+ const ast::Expression* constructor,
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
auto* var = create<ast::Override>(source_, Sym(std::forward<NAME>(name)), type, constructor,
std::move(attributes));
AST().AddGlobalVariable(var);
@@ -1766,11 +1811,12 @@
/// @returns an `ast::Override` constructed with the arguments of `args`, which is automatically
/// registered as a global variable with the ast::Module.
template <typename NAME>
- const ast::Override* Override(const Source& source,
- NAME&& name,
- const ast::Type* type,
- const ast::Expression* constructor,
- ast::AttributeList attributes = {}) {
+ const ast::Override* Override(
+ const Source& source,
+ NAME&& name,
+ const ast::Type* type,
+ const ast::Expression* constructor,
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
auto* var = create<ast::Override>(source, Sym(std::forward<NAME>(name)), type, constructor,
std::move(attributes));
AST().AddGlobalVariable(var);
@@ -1778,6 +1824,42 @@
}
/// @param source the source information
+ /// @param condition the assertion condition
+ /// @returns a new `ast::StaticAssert`, which is automatically registered as a global statement
+ /// with the ast::Module.
+ template <typename EXPR>
+ const ast::StaticAssert* GlobalStaticAssert(const Source& source, EXPR&& condition) {
+ auto* sa = StaticAssert(source, std::forward<EXPR>(condition));
+ AST().AddStaticAssert(sa);
+ return sa;
+ }
+
+ /// @param condition the assertion condition
+ /// @returns a new `ast::StaticAssert`, which is automatically registered as a global statement
+ /// with the ast::Module.
+ template <typename EXPR, typename = DisableIfSource<EXPR>>
+ const ast::StaticAssert* GlobalStaticAssert(EXPR&& condition) {
+ auto* sa = StaticAssert(std::forward<EXPR>(condition));
+ AST().AddStaticAssert(sa);
+ return sa;
+ }
+
+ /// @param source the source information
+ /// @param condition the assertion condition
+ /// @returns a new `ast::StaticAssert` with the given assertion condition
+ template <typename EXPR>
+ const ast::StaticAssert* StaticAssert(const Source& source, EXPR&& condition) {
+ return create<ast::StaticAssert>(source, Expr(std::forward<EXPR>(condition)));
+ }
+
+ /// @param condition the assertion condition
+ /// @returns a new `ast::StaticAssert` with the given assertion condition
+ template <typename EXPR, typename = DisableIfSource<EXPR>>
+ const ast::StaticAssert* StaticAssert(EXPR&& condition) {
+ return create<ast::StaticAssert>(Expr(std::forward<EXPR>(condition)));
+ }
+
+ /// @param source the source information
/// @param expr the expression to take the address of
/// @return an ast::UnaryOpExpression that takes the address of `expr`
template <typename EXPR>
@@ -1896,6 +1978,17 @@
Expr(std::forward<RHS>(rhs)));
}
+ /// @param source the source information
+ /// @param lhs the left hand argument to the addition operation
+ /// @param rhs the right hand argument to the addition operation
+ /// @returns a `ast::BinaryExpression` summing the arguments `lhs` and `rhs`
+ template <typename LHS, typename RHS>
+ const ast::BinaryExpression* Add(const Source& source, LHS&& lhs, RHS&& rhs) {
+ return create<ast::BinaryExpression>(source, ast::BinaryOp::kAdd,
+ Expr(std::forward<LHS>(lhs)),
+ Expr(std::forward<RHS>(rhs)));
+ }
+
/// @param lhs the left hand argument to the and operation
/// @param rhs the right hand argument to the and operation
/// @returns a `ast::BinaryExpression` bitwise anding `lhs` and `rhs`
@@ -2158,7 +2251,7 @@
/// @param group the group index
/// @param binding the binding index
/// @returns a attribute list with both the group and binding attributes
- ast::AttributeList GroupAndBinding(uint32_t group, uint32_t binding) {
+ utils::Vector<const ast::Attribute*, 2> GroupAndBinding(uint32_t group, uint32_t binding) {
return {Group(group), Binding(binding)};
}
@@ -2173,16 +2266,18 @@
/// attributes
/// @returns the function pointer
template <typename NAME>
- const ast::Function* Func(const Source& source,
- NAME&& name,
- ast::ParameterList params,
- const ast::Type* type,
- ast::StatementList body,
- ast::AttributeList attributes = {},
- ast::AttributeList return_type_attributes = {}) {
- auto* func = create<ast::Function>(source, Sym(std::forward<NAME>(name)), params, type,
- create<ast::BlockStatement>(body), attributes,
- return_type_attributes);
+ const ast::Function* Func(
+ const Source& source,
+ NAME&& name,
+ utils::VectorRef<const ast::Parameter*> params,
+ const ast::Type* type,
+ utils::VectorRef<const ast::Statement*> body,
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty,
+ utils::VectorRef<const ast::Attribute*> return_type_attributes = utils::Empty) {
+ auto* func =
+ create<ast::Function>(source, Sym(std::forward<NAME>(name)), std::move(params), type,
+ create<ast::BlockStatement>(std::move(body)),
+ std::move(attributes), std::move(return_type_attributes));
AST().AddFunction(func);
return func;
}
@@ -2197,15 +2292,17 @@
/// attributes
/// @returns the function pointer
template <typename NAME>
- const ast::Function* Func(NAME&& name,
- ast::ParameterList params,
- const ast::Type* type,
- ast::StatementList body,
- ast::AttributeList attributes = {},
- ast::AttributeList return_type_attributes = {}) {
- auto* func = create<ast::Function>(Sym(std::forward<NAME>(name)), params, type,
- create<ast::BlockStatement>(body), attributes,
- return_type_attributes);
+ const ast::Function* Func(
+ NAME&& name,
+ utils::VectorRef<const ast::Parameter*> params,
+ const ast::Type* type,
+ utils::VectorRef<const ast::Statement*> body,
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty,
+ utils::VectorRef<const ast::Attribute*> return_type_attributes = utils::Empty) {
+ auto* func =
+ create<ast::Function>(Sym(std::forward<NAME>(name)), std::move(params), type,
+ create<ast::BlockStatement>(std::move(body)),
+ std::move(attributes), std::move(return_type_attributes));
AST().AddFunction(func);
return func;
}
@@ -2300,9 +2397,11 @@
/// @param members the struct members
/// @returns the struct type
template <typename NAME>
- const ast::Struct* Structure(const Source& source, NAME&& name, ast::StructMemberList members) {
+ const ast::Struct* Structure(const Source& source,
+ NAME&& name,
+ utils::VectorRef<const ast::StructMember*> members) {
auto sym = Sym(std::forward<NAME>(name));
- auto* type = create<ast::Struct>(source, sym, std::move(members), ast::AttributeList{});
+ auto* type = create<ast::Struct>(source, sym, std::move(members), utils::Empty);
AST().AddTypeDecl(type);
return type;
}
@@ -2312,9 +2411,9 @@
/// @param members the struct members
/// @returns the struct type
template <typename NAME>
- const ast::Struct* Structure(NAME&& name, ast::StructMemberList members) {
+ const ast::Struct* Structure(NAME&& name, utils::VectorRef<const ast::StructMember*> members) {
auto sym = Sym(std::forward<NAME>(name));
- auto* type = create<ast::Struct>(sym, std::move(members), ast::AttributeList{});
+ auto* type = create<ast::Struct>(sym, std::move(members), utils::Empty);
AST().AddTypeDecl(type);
return type;
}
@@ -2326,10 +2425,11 @@
/// @param attributes the optional struct member attributes
/// @returns the struct member pointer
template <typename NAME>
- const ast::StructMember* Member(const Source& source,
- NAME&& name,
- const ast::Type* type,
- ast::AttributeList attributes = {}) {
+ const ast::StructMember* Member(
+ const Source& source,
+ NAME&& name,
+ const ast::Type* type,
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
return create<ast::StructMember>(source, Sym(std::forward<NAME>(name)), type,
std::move(attributes));
}
@@ -2340,22 +2440,23 @@
/// @param attributes the optional struct member attributes
/// @returns the struct member pointer
template <typename NAME>
- const ast::StructMember* Member(NAME&& name,
- const ast::Type* type,
- ast::AttributeList attributes = {}) {
+ const ast::StructMember* Member(
+ NAME&& name,
+ const ast::Type* type,
+ utils::VectorRef<const ast::Attribute*> attributes = utils::Empty) {
return create<ast::StructMember>(source_, Sym(std::forward<NAME>(name)), type,
std::move(attributes));
}
/// Creates a ast::StructMember with the given byte offset
- /// @param offset the offset to use in the StructMemberOffsetattribute
+ /// @param offset the offset to use in the StructMemberOffsetAttribute
/// @param name the struct member name
/// @param type the struct member type
/// @returns the struct member pointer
template <typename NAME>
const ast::StructMember* Member(uint32_t offset, NAME&& name, const ast::Type* type) {
return create<ast::StructMember>(source_, Sym(std::forward<NAME>(name)), type,
- ast::AttributeList{
+ utils::Vector<const ast::Attribute*, 1>{
create<ast::StructMemberOffsetAttribute>(offset),
});
}
@@ -2367,7 +2468,9 @@
template <typename... Statements>
const ast::BlockStatement* Block(const Source& source, Statements&&... statements) {
return create<ast::BlockStatement>(
- source, ast::StatementList{std::forward<Statements>(statements)...});
+ source, utils::Vector<const ast::Statement*, sizeof...(statements)>{
+ std::forward<Statements>(statements)...,
+ });
}
/// Creates a ast::BlockStatement with input statements
@@ -2376,7 +2479,9 @@
template <typename... STATEMENTS, typename = DisableIfSource<STATEMENTS...>>
const ast::BlockStatement* Block(STATEMENTS&&... statements) {
return create<ast::BlockStatement>(
- ast::StatementList{std::forward<STATEMENTS>(statements)...});
+ utils::Vector<const ast::Statement*, sizeof...(statements)>{
+ std::forward<STATEMENTS>(statements)...,
+ });
}
/// A wrapper type for the Else statement used to create If statements.
@@ -2618,8 +2723,10 @@
const ast::SwitchStatement* Switch(const Source& source,
ExpressionInit&& condition,
Cases&&... cases) {
- return create<ast::SwitchStatement>(source, Expr(std::forward<ExpressionInit>(condition)),
- ast::CaseStatementList{std::forward<Cases>(cases)...});
+ return create<ast::SwitchStatement>(
+ source, Expr(std::forward<ExpressionInit>(condition)),
+ utils::Vector<const ast::CaseStatement*, sizeof...(cases)>{
+ std::forward<Cases>(cases)...});
}
/// Creates a ast::SwitchStatement with input expression and cases
@@ -2630,8 +2737,10 @@
typename... Cases,
typename = DisableIfSource<ExpressionInit>>
const ast::SwitchStatement* Switch(ExpressionInit&& condition, Cases&&... cases) {
- return create<ast::SwitchStatement>(Expr(std::forward<ExpressionInit>(condition)),
- ast::CaseStatementList{std::forward<Cases>(cases)...});
+ return create<ast::SwitchStatement>(
+ Expr(std::forward<ExpressionInit>(condition)),
+ utils::Vector<const ast::CaseStatement*, sizeof...(cases)>{
+ std::forward<Cases>(cases)...});
}
/// Creates a ast::CaseStatement with input list of selectors, and body
@@ -2640,7 +2749,7 @@
/// @param body the case body
/// @returns the case statement pointer
const ast::CaseStatement* Case(const Source& source,
- ast::CaseSelectorList selectors,
+ utils::VectorRef<const ast::IntLiteralExpression*> selectors,
const ast::BlockStatement* body = nullptr) {
return create<ast::CaseStatement>(source, std::move(selectors), body ? body : Block());
}
@@ -2649,7 +2758,7 @@
/// @param selectors list of selectors
/// @param body the case body
/// @returns the case statement pointer
- const ast::CaseStatement* Case(ast::CaseSelectorList selectors,
+ const ast::CaseStatement* Case(utils::VectorRef<const ast::IntLiteralExpression*> selectors,
const ast::BlockStatement* body = nullptr) {
return create<ast::CaseStatement>(std::move(selectors), body ? body : Block());
}
@@ -2660,7 +2769,7 @@
/// @returns the case statement pointer
const ast::CaseStatement* Case(const ast::IntLiteralExpression* selector,
const ast::BlockStatement* body = nullptr) {
- return Case(ast::CaseSelectorList{selector}, body);
+ return Case(utils::Vector{selector}, body);
}
/// Convenience function that creates a 'default' ast::CaseStatement
@@ -2669,14 +2778,14 @@
/// @returns the case statement pointer
const ast::CaseStatement* DefaultCase(const Source& source,
const ast::BlockStatement* body = nullptr) {
- return Case(source, ast::CaseSelectorList{}, body);
+ return Case(source, utils::Empty, body);
}
/// Convenience function that creates a 'default' ast::CaseStatement
/// @param body the case body
/// @returns the case statement pointer
const ast::CaseStatement* DefaultCase(const ast::BlockStatement* body = nullptr) {
- return Case(ast::CaseSelectorList{}, body);
+ return Case(utils::Empty, body);
}
/// Creates an ast::FallthroughStatement
@@ -2957,13 +3066,15 @@
/// @returns the function
template <typename... ARGS>
const ast::Function* WrapInFunction(ARGS&&... args) {
- ast::StatementList stmts{WrapInStatement(std::forward<ARGS>(args))...};
- return WrapInFunction(std::move(stmts));
+ utils::Vector stmts{
+ WrapInStatement(std::forward<ARGS>(args))...,
+ };
+ return WrapInFunction(utils::VectorRef<const ast::Statement*>{std::move(stmts)});
}
/// @param stmts a list of ast::Statement that will be wrapped by a function,
/// so that each statement is reachable by the Resolver.
/// @returns the function
- const ast::Function* WrapInFunction(ast::StatementList stmts);
+ const ast::Function* WrapInFunction(utils::VectorRef<const ast::Statement*> stmts);
/// The builder types
TypesBuilder const ty{this};
diff --git a/src/tint/program_builder_test.cc b/src/tint/program_builder_test.cc
index dd7e7a8..24e7344 100644
--- a/src/tint/program_builder_test.cc
+++ b/src/tint/program_builder_test.cc
@@ -38,14 +38,14 @@
return builder;
}());
- ASSERT_EQ(inner.AST().Functions().size(), 1u);
+ ASSERT_EQ(inner.AST().Functions().Length(), 1u);
ASSERT_TRUE(inner.Symbols().Get("a").IsValid());
ASSERT_FALSE(inner.Symbols().Get("b").IsValid());
ProgramBuilder outer = ProgramBuilder::Wrap(&inner);
- ASSERT_EQ(inner.AST().Functions().size(), 1u);
- ASSERT_EQ(outer.AST().Functions().size(), 1u);
+ ASSERT_EQ(inner.AST().Functions().Length(), 1u);
+ ASSERT_EQ(outer.AST().Functions().Length(), 1u);
EXPECT_EQ(inner.AST().Functions()[0], outer.AST().Functions()[0]);
EXPECT_TRUE(inner.Symbols().Get("a").IsValid());
EXPECT_EQ(inner.Symbols().Get("a"), outer.Symbols().Get("a"));
@@ -57,8 +57,8 @@
auto* ty = outer.ty.f32();
outer.Func("b", {}, ty, {}, {});
- ASSERT_EQ(inner.AST().Functions().size(), 1u);
- ASSERT_EQ(outer.AST().Functions().size(), 2u);
+ ASSERT_EQ(inner.AST().Functions().Length(), 1u);
+ ASSERT_EQ(outer.AST().Functions().Length(), 2u);
EXPECT_EQ(inner.AST().Functions()[0], outer.AST().Functions()[0]);
EXPECT_EQ(outer.AST().Functions()[1]->symbol, outer.Symbols().Get("b"));
EXPECT_EQ(inner.Symbols().Get("a"), outer.Symbols().Get("a"));
diff --git a/src/tint/program_test.cc b/src/tint/program_test.cc
index ae6aabe..39d7c07 100644
--- a/src/tint/program_test.cc
+++ b/src/tint/program_test.cc
@@ -28,7 +28,7 @@
TEST_F(ProgramTest, Creation) {
Program program(std::move(*this));
- EXPECT_EQ(program.AST().Functions().size(), 0u);
+ EXPECT_EQ(program.AST().Functions().Length(), 0u);
}
TEST_F(ProgramTest, EmptyIsValid) {
diff --git a/src/tint/reader/spirv/construct.h b/src/tint/reader/spirv/construct.h
index de4e477..cd0804a 100644
--- a/src/tint/reader/spirv/construct.h
+++ b/src/tint/reader/spirv/construct.h
@@ -18,7 +18,8 @@
#include <memory>
#include <sstream>
#include <string>
-#include <vector>
+
+#include "src/tint/utils/vector.h"
namespace tint::reader::spirv {
@@ -146,7 +147,7 @@
};
/// ConstructList is a list of Construct unique pointers.
-using ConstructList = std::vector<std::unique_ptr<Construct>>;
+using ConstructList = utils::Vector<std::unique_ptr<Construct>, 8>;
/// Converts a construct kind to a string.
/// @param kind the construct kind to convert
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index 06f9ecb..4975387 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -622,7 +622,7 @@
// - a continue target always follows the associated loop construct, if any
// @returns the IDs of blocks in reverse structured post order
std::vector<uint32_t> ReverseStructuredPostOrder() {
- visit_order_.clear();
+ visit_order_.Clear();
visited_.clear();
VisitBackward(function_.entry()->id());
@@ -660,20 +660,20 @@
VisitBackward(terminator->GetSingleWordInOperand(0));
} else if (opcode == SpvOpSwitch) {
// TODO(dneto): Consider visiting the labels in literal-value order.
- std::vector<uint32_t> successors;
+ utils::Vector<uint32_t, 32> successors;
bb->ForEachSuccessorLabel(
- [&successors](const uint32_t succ_id) { successors.push_back(succ_id); });
+ [&successors](const uint32_t succ_id) { successors.Push(succ_id); });
for (auto succ_id : successors) {
VisitBackward(succ_id);
}
}
- visit_order_.push_back(id);
+ visit_order_.Push(id);
}
const spvtools::opt::Function& function_;
std::unordered_map<uint32_t, const spvtools::opt::BasicBlock*> id_to_block_;
- std::vector<uint32_t> visit_order_;
+ utils::Vector<uint32_t, 32> visit_order_;
std::unordered_set<uint32_t> visited_;
};
@@ -692,13 +692,14 @@
auto reversed_cases = cases;
std::reverse(reversed_cases.begin(), reversed_cases.end());
- return builder->create<ast::SwitchStatement>(Source{}, condition, reversed_cases);
+ return builder->create<ast::SwitchStatement>(Source{}, condition,
+ std::move(reversed_cases));
}
/// Switch statement condition
const ast::Expression* const condition;
/// Switch statement cases
- ast::CaseStatementList cases;
+ utils::Vector<ast::CaseStatement*, 4> cases;
};
/// A StatementBuilder for ast::IfStatement
@@ -744,7 +745,7 @@
/// @param decos a list of parsed decorations
/// @returns true if the decorations include a SampleMask builtin
-bool HasBuiltinSampleMask(const ast::AttributeList& decos) {
+bool HasBuiltinSampleMask(utils::VectorRef<const ast::Attribute*> decos) {
if (auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(decos)) {
return builtin->builtin == ast::BuiltinValue::kSampleMask;
}
@@ -808,7 +809,7 @@
sample_mask_in_id(other.sample_mask_out_id),
sample_mask_out_id(other.sample_mask_in_id),
ep_info_(other.ep_info_) {
- other.statements_stack_.clear();
+ other.statements_stack_.Clear();
PushNewStatementBlock(nullptr, 0, nullptr);
}
@@ -826,7 +827,7 @@
void FunctionEmitter::StatementBlock::Finalize(ProgramBuilder* pb) {
TINT_ASSERT(Reader, !finalized_ /* Finalize() must only be called once */);
- for (size_t i = 0; i < statements_.size(); i++) {
+ for (size_t i = 0; i < statements_.Length(); i++) {
if (auto* sb = statements_[i]->As<StatementBuilder>()) {
statements_[i] = sb->Build(pb);
}
@@ -841,64 +842,64 @@
void FunctionEmitter::StatementBlock::Add(const ast::Statement* statement) {
TINT_ASSERT(Reader, !finalized_ /* Add() must not be called after Finalize() */);
- statements_.emplace_back(statement);
+ statements_.Push(statement);
}
void FunctionEmitter::PushNewStatementBlock(const Construct* construct,
uint32_t end_id,
CompletionAction action) {
- statements_stack_.emplace_back(StatementBlock{construct, end_id, action});
+ statements_stack_.Push(StatementBlock{construct, end_id, action});
}
void FunctionEmitter::PushGuard(const std::string& guard_name, uint32_t end_id) {
- TINT_ASSERT(Reader, !statements_stack_.empty());
+ TINT_ASSERT(Reader, !statements_stack_.IsEmpty());
TINT_ASSERT(Reader, !guard_name.empty());
// Guard control flow by the guard variable. Introduce a new
// if-selection with a then-clause ending at the same block
// as the statement block at the top of the stack.
- const auto& top = statements_stack_.back();
+ const auto& top = statements_stack_.Back();
auto* cond =
create<ast::IdentifierExpression>(Source{}, builder_.Symbols().Register(guard_name));
auto* builder = AddStatementBuilder<IfStatementBuilder>(cond);
- PushNewStatementBlock(top.GetConstruct(), end_id, [=](const ast::StatementList& stmts) {
+ PushNewStatementBlock(top.GetConstruct(), end_id, [=](const StatementList& stmts) {
builder->body = create<ast::BlockStatement>(Source{}, stmts);
});
}
void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
- TINT_ASSERT(Reader, !statements_stack_.empty());
- const auto& top = statements_stack_.back();
+ TINT_ASSERT(Reader, !statements_stack_.IsEmpty());
+ const auto& top = statements_stack_.Back();
auto* cond = MakeTrue(Source{});
auto* builder = AddStatementBuilder<IfStatementBuilder>(cond);
- PushNewStatementBlock(top.GetConstruct(), end_id, [=](const ast::StatementList& stmts) {
+ PushNewStatementBlock(top.GetConstruct(), end_id, [=](const StatementList& stmts) {
builder->body = create<ast::BlockStatement>(Source{}, stmts);
});
}
-const ast::StatementList FunctionEmitter::ast_body() {
- TINT_ASSERT(Reader, !statements_stack_.empty());
+FunctionEmitter::StatementList FunctionEmitter::ast_body() {
+ TINT_ASSERT(Reader, !statements_stack_.IsEmpty());
auto& entry = statements_stack_[0];
entry.Finalize(&builder_);
return entry.GetStatements();
}
const ast::Statement* FunctionEmitter::AddStatement(const ast::Statement* statement) {
- TINT_ASSERT(Reader, !statements_stack_.empty());
+ TINT_ASSERT(Reader, !statements_stack_.IsEmpty());
if (statement != nullptr) {
- statements_stack_.back().Add(statement);
+ statements_stack_.Back().Add(statement);
}
return statement;
}
const ast::Statement* FunctionEmitter::LastStatement() {
- TINT_ASSERT(Reader, !statements_stack_.empty());
- auto& statement_list = statements_stack_.back().GetStatements();
- TINT_ASSERT(Reader, !statement_list.empty());
- return statement_list.back();
+ TINT_ASSERT(Reader, !statements_stack_.IsEmpty());
+ auto& statement_list = statements_stack_.Back().GetStatements();
+ TINT_ASSERT(Reader, !statement_list.IsEmpty());
+ return statement_list.Back();
}
bool FunctionEmitter::Emit() {
@@ -937,10 +938,9 @@
return false;
}
- builder_.AST().AddFunction(
- create<ast::Function>(decl.source, builder_.Symbols().Register(decl.name),
- std::move(decl.params), decl.return_type->Build(builder_), body,
- std::move(decl.attributes), ast::AttributeList{}));
+ builder_.AST().AddFunction(create<ast::Function>(
+ decl.source, builder_.Symbols().Register(decl.name), std::move(decl.params),
+ decl.return_type->Build(builder_), body, std::move(decl.attributes), utils::Empty));
}
if (ep_info_ && !ep_info_->inner_name.empty()) {
@@ -951,17 +951,17 @@
}
const ast::BlockStatement* FunctionEmitter::MakeFunctionBody() {
- TINT_ASSERT(Reader, statements_stack_.size() == 1);
+ TINT_ASSERT(Reader, statements_stack_.Length() == 1);
if (!EmitBody()) {
return nullptr;
}
// Set the body of the AST function node.
- if (statements_stack_.size() != 1) {
+ if (statements_stack_.Length() != 1) {
Fail() << "internal error: statement-list stack should have 1 "
"element but has "
- << statements_stack_.size();
+ << statements_stack_.Length();
return nullptr;
}
@@ -970,7 +970,7 @@
auto* body = create<ast::BlockStatement>(Source{}, statements);
// Maintain the invariant by repopulating the one and only element.
- statements_stack_.clear();
+ statements_stack_.Clear();
PushNewStatementBlock(constructs_[0].get(), 0, nullptr);
return body;
@@ -978,12 +978,12 @@
bool FunctionEmitter::EmitPipelineInput(std::string var_name,
const Type* var_type,
- ast::AttributeList* attrs,
- std::vector<int> index_prefix,
+ AttributeList* attrs,
+ utils::Vector<int, 8> index_prefix,
const Type* tip_type,
const Type* forced_param_type,
- ast::ParameterList* params,
- ast::StatementList* statements) {
+ ParameterList* params,
+ StatementList* statements) {
// TODO(dneto): Handle structs where the locations are annotated on members.
tip_type = tip_type->UnwrapAlias();
if (auto* ref_type = tip_type->As<Reference>()) {
@@ -994,11 +994,11 @@
return Switch(
tip_type,
[&](const Matrix* matrix_type) -> bool {
- index_prefix.push_back(0);
+ index_prefix.Push(0);
const auto num_columns = static_cast<int>(matrix_type->columns);
const Type* vec_ty = ty_.Vector(matrix_type->type, matrix_type->rows);
for (int col = 0; col < num_columns; col++) {
- index_prefix.back() = col;
+ index_prefix.Back() = col;
if (!EmitPipelineInput(var_name, var_type, attrs, index_prefix, vec_ty,
forced_param_type, params, statements)) {
return false;
@@ -1010,10 +1010,10 @@
if (array_type->size == 0) {
return Fail() << "runtime-size array not allowed on pipeline IO";
}
- index_prefix.push_back(0);
+ index_prefix.Push(0);
const Type* elem_ty = array_type->type;
for (int i = 0; i < static_cast<int>(array_type->size); i++) {
- index_prefix.back() = i;
+ index_prefix.Back() = i;
if (!EmitPipelineInput(var_name, var_type, attrs, index_prefix, elem_ty,
forced_param_type, params, statements)) {
return false;
@@ -1023,10 +1023,10 @@
},
[&](const Struct* struct_type) -> bool {
const auto& members = struct_type->members;
- index_prefix.push_back(0);
+ index_prefix.Push(0);
for (size_t i = 0; i < members.size(); ++i) {
- index_prefix.back() = static_cast<int>(i);
- ast::AttributeList member_attrs(*attrs);
+ index_prefix.Back() = static_cast<int>(i);
+ AttributeList member_attrs(*attrs);
if (!parser_impl_.ConvertPipelineDecorations(
struct_type,
parser_impl_.GetMemberPipelineDecorations(*struct_type,
@@ -1039,7 +1039,8 @@
return false;
}
// Copy the location as updated by nested expansion of the member.
- parser_impl_.SetLocation(attrs, GetLocation(member_attrs));
+ parser_impl_.SetLocation(attrs,
+ ast::GetAttribute<ast::LocationAttribute>(member_attrs));
}
return success();
},
@@ -1056,7 +1057,7 @@
// disallowed but currently the SPIR-V reader will make duplicates when
// the entire AST is cloned at the top level of the SPIR-V reader flow.
// Consider rewriting this to avoid this node-sharing.
- params->push_back(builder_.Param(param_name, param_type->Build(builder_), *attrs));
+ params->Push(builder_.Param(param_name, param_type->Build(builder_), *attrs));
// Add a body statement to copy the parameter to the corresponding
// private variable.
@@ -1091,7 +1092,7 @@
create<ast::BitcastExpression>(tip_type->Build(builder_), param_value);
}
- statements->push_back(builder_.Assign(store_dest, param_value));
+ statements->Push(builder_.Assign(store_dest, param_value));
// Increment the location attribute, in case more parameters will
// follow.
@@ -1101,7 +1102,7 @@
});
}
-void FunctionEmitter::IncrementLocation(ast::AttributeList* attributes) {
+void FunctionEmitter::IncrementLocation(AttributeList* attributes) {
for (auto*& attr : *attributes) {
if (auto* loc_attr = attr->As<ast::LocationAttribute>()) {
// Replace this location attribute with a new one with one higher index.
@@ -1112,23 +1113,14 @@
}
}
-const ast::Attribute* FunctionEmitter::GetLocation(const ast::AttributeList& attributes) {
- for (auto* const& attr : attributes) {
- if (attr->Is<ast::LocationAttribute>()) {
- return attr;
- }
- }
- return nullptr;
-}
-
bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
const Type* var_type,
- ast::AttributeList* decos,
- std::vector<int> index_prefix,
+ AttributeList* decos,
+ utils::Vector<int, 8> index_prefix,
const Type* tip_type,
const Type* forced_member_type,
- ast::StructMemberList* return_members,
- ast::ExpressionList* return_exprs) {
+ StructMemberList* return_members,
+ ExpressionList* return_exprs) {
tip_type = tip_type->UnwrapAlias();
if (auto* ref_type = tip_type->As<Reference>()) {
tip_type = ref_type->type;
@@ -1138,12 +1130,12 @@
return Switch(
tip_type,
[&](const Matrix* matrix_type) {
- index_prefix.push_back(0);
+ index_prefix.Push(0);
const auto num_columns = static_cast<int>(matrix_type->columns);
const Type* vec_ty = ty_.Vector(matrix_type->type, matrix_type->rows);
for (int col = 0; col < num_columns; col++) {
- index_prefix.back() = col;
- if (!EmitPipelineOutput(var_name, var_type, decos, index_prefix, vec_ty,
+ index_prefix.Back() = col;
+ if (!EmitPipelineOutput(var_name, var_type, std::move(decos), index_prefix, vec_ty,
forced_member_type, return_members, return_exprs)) {
return false;
}
@@ -1154,11 +1146,11 @@
if (array_type->size == 0) {
return Fail() << "runtime-size array not allowed on pipeline IO";
}
- index_prefix.push_back(0);
+ index_prefix.Push(0);
const Type* elem_ty = array_type->type;
for (int i = 0; i < static_cast<int>(array_type->size); i++) {
- index_prefix.back() = i;
- if (!EmitPipelineOutput(var_name, var_type, decos, index_prefix, elem_ty,
+ index_prefix.Back() = i;
+ if (!EmitPipelineOutput(var_name, var_type, std::move(decos), index_prefix, elem_ty,
forced_member_type, return_members, return_exprs)) {
return false;
}
@@ -1167,10 +1159,10 @@
},
[&](const Struct* struct_type) -> bool {
const auto& members = struct_type->members;
- index_prefix.push_back(0);
+ index_prefix.Push(0);
for (int i = 0; i < static_cast<int>(members.size()); ++i) {
- index_prefix.back() = i;
- ast::AttributeList member_attrs(*decos);
+ index_prefix.Back() = i;
+ AttributeList member_attrs(*decos);
if (!parser_impl_.ConvertPipelineDecorations(
struct_type, parser_impl_.GetMemberPipelineDecorations(*struct_type, i),
&member_attrs)) {
@@ -1182,7 +1174,8 @@
return false;
}
// Copy the location as updated by nested expansion of the member.
- parser_impl_.SetLocation(decos, GetLocation(member_attrs));
+ parser_impl_.SetLocation(decos,
+ ast::GetAttribute<ast::LocationAttribute>(member_attrs));
}
return success();
},
@@ -1200,7 +1193,7 @@
// disallowed but currently the SPIR-V reader will make duplicates when
// the entire AST is cloned at the top level of the SPIR-V reader flow.
// Consider rewriting this to avoid this node-sharing.
- return_members->push_back(
+ return_members->Push(
builder_.Member(member_name, member_type->Build(builder_), *decos));
// Create an expression to evaluate the part of the variable indexed by
@@ -1236,7 +1229,7 @@
load_source = create<ast::BitcastExpression>(forced_member_type->Build(builder_),
load_source);
}
- return_exprs->push_back(load_source);
+ return_exprs->Push(load_source);
// Increment the location attribute, in case more parameters will
// follow.
@@ -1250,7 +1243,7 @@
Source source;
// The statements in the body.
- ast::StatementList stmts;
+ utils::Vector<const ast::Statement*, 8> stmts;
FunctionDeclaration decl;
decl.source = source;
@@ -1266,7 +1259,7 @@
TINT_ASSERT(Reader, var->opcode() == SpvOpVariable);
auto* store_type = GetVariableStoreType(*var);
auto* forced_param_type = store_type;
- ast::AttributeList param_decos;
+ AttributeList param_decos;
if (!parser_impl_.ConvertDecorationsForVariable(var_id, &forced_param_type, ¶m_decos,
true)) {
// This occurs, and is not an error, for the PointSize builtin.
@@ -1302,12 +1295,12 @@
}
// Call the inner function. It has no parameters.
- stmts.push_back(create<ast::CallStatement>(
+ stmts.Push(create<ast::CallStatement>(
source,
create<ast::CallExpression>(source,
create<ast::IdentifierExpression>(
source, builder_.Symbols().Register(ep_info_->inner_name)),
- ast::ExpressionList{})));
+ utils::Empty)));
// Pipeline outputs are mapped to the return value.
if (ep_info_->outputs.empty()) {
@@ -1321,8 +1314,8 @@
const auto return_struct_sym = builder_.Symbols().Register(return_struct_name);
// Define the structure.
- std::vector<const ast::StructMember*> return_members;
- ast::ExpressionList return_exprs;
+ StructMemberList return_members;
+ ExpressionList return_exprs;
const auto& builtin_position_info = parser_impl_.GetBuiltInPositionInfo();
@@ -1331,13 +1324,13 @@
// The SPIR-V gl_PerVertex variable has already been remapped to
// a gl_Position variable. Substitute the type.
const Type* param_type = ty_.Vector(ty_.F32(), 4);
- ast::AttributeList out_decos{
+ AttributeList out_decos{
create<ast::BuiltinAttribute>(source, ast::BuiltinValue::kPosition)};
const auto var_name = namer_.GetName(var_id);
- return_members.push_back(
+ return_members.Push(
builder_.Member(var_name, param_type->Build(builder_), out_decos));
- return_exprs.push_back(builder_.Expr(var_name));
+ return_exprs.Push(builder_.Expr(var_name));
} else {
const auto* var = def_use_mgr_->GetDef(var_id);
@@ -1345,7 +1338,7 @@
TINT_ASSERT(Reader, var->opcode() == SpvOpVariable);
const Type* store_type = GetVariableStoreType(*var);
const Type* forced_member_type = store_type;
- ast::AttributeList out_decos;
+ AttributeList out_decos;
if (!parser_impl_.ConvertDecorationsForVariable(var_id, &forced_member_type,
&out_decos, true)) {
// This occurs, and is not an error, for the PointSize builtin.
@@ -1378,26 +1371,26 @@
}
}
- if (return_members.empty()) {
+ if (return_members.IsEmpty()) {
// This can occur if only the PointSize member is accessed, because we
// never emit it.
return_type = ty_.Void()->Build(builder_);
} else {
// Create and register the result type.
- auto* str = create<ast::Struct>(Source{}, return_struct_sym, return_members,
- ast::AttributeList{});
+ auto* str =
+ create<ast::Struct>(Source{}, return_struct_sym, return_members, AttributeList{});
parser_impl_.AddTypeDecl(return_struct_sym, str);
return_type = builder_.ty.Of(str);
// Add the return-value statement.
- stmts.push_back(create<ast::ReturnStatement>(
+ stmts.Push(create<ast::ReturnStatement>(
source, builder_.Construct(source, return_type, std::move(return_exprs))));
}
}
auto* body = create<ast::BlockStatement>(source, stmts);
- ast::AttributeList fn_attrs;
- fn_attrs.emplace_back(create<ast::StageAttribute>(source, ep_info_->stage));
+ AttributeList fn_attrs;
+ fn_attrs.Push(create<ast::StageAttribute>(source, ep_info_->stage));
if (ep_info_->stage == ast::PipelineStage::kCompute) {
auto& size = ep_info_->workgroup_size;
@@ -1405,13 +1398,13 @@
const ast::Expression* x = builder_.Expr(i32(size.x));
const ast::Expression* y = size.y ? builder_.Expr(i32(size.y)) : nullptr;
const ast::Expression* z = size.z ? builder_.Expr(i32(size.z)) : nullptr;
- fn_attrs.emplace_back(create<ast::WorkgroupAttribute>(Source{}, x, y, z));
+ fn_attrs.Push(create<ast::WorkgroupAttribute>(Source{}, x, y, z));
}
}
builder_.AST().AddFunction(create<ast::Function>(
source, builder_.Symbols().Register(ep_info_->name), std::move(decl.params), return_type,
- body, std::move(fn_attrs), ast::AttributeList{}));
+ body, std::move(fn_attrs), AttributeList{}));
return true;
}
@@ -1435,14 +1428,13 @@
<< function_.result_id();
}
- ast::ParameterList ast_params;
+ ParameterList ast_params;
function_.ForEachParam([this, &ast_params](const spvtools::opt::Instruction* param) {
auto* type = parser_impl_.ConvertType(param->type_id());
if (type != nullptr) {
- auto* ast_param =
- parser_impl_.MakeParameter(param->result_id(), type, ast::AttributeList{});
+ auto* ast_param = parser_impl_.MakeParameter(param->result_id(), type, AttributeList{});
// Parameters are treated as const declarations.
- ast_params.emplace_back(ast_param);
+ ast_params.Push(ast_param);
// The value is accessible by name.
identifier_types_.emplace(param->result_id(), type);
} else {
@@ -1456,7 +1448,7 @@
decl->name = name;
decl->params = std::move(ast_params);
decl->return_type = ret_ty;
- decl->attributes.clear();
+ decl->attributes.Clear();
return success();
}
@@ -1765,11 +1757,11 @@
// haven't reached the backedge block.
TINT_ASSERT(Reader, block_order_.size() > 0);
- constructs_.clear();
+ constructs_.Clear();
const auto entry_id = block_order_[0];
// The stack of enclosing constructs.
- std::vector<Construct*> enclosing;
+ utils::Vector<Construct*, 4> enclosing;
// Creates a control flow construct and pushes it onto the stack.
// Its parent is the top of the stack, or nullptr if the stack is empty.
@@ -1779,7 +1771,7 @@
const auto begin_pos = GetBlockInfo(begin_id)->pos;
const auto end_pos =
end_id == 0 ? uint32_t(block_order_.size()) : GetBlockInfo(end_id)->pos;
- const auto* parent = enclosing.empty() ? nullptr : enclosing.back();
+ const auto* parent = enclosing.IsEmpty() ? nullptr : enclosing.Back();
auto scope_end_pos = end_pos;
// A loop construct is added right after its associated continue construct.
// In that case, adjust the parent up.
@@ -1789,11 +1781,10 @@
scope_end_pos = parent->end_pos;
parent = parent->parent;
}
- constructs_.push_back(std::make_unique<Construct>(parent, static_cast<int>(depth), k,
- begin_id, end_id, begin_pos, end_pos,
- scope_end_pos));
- Construct* result = constructs_.back().get();
- enclosing.push_back(result);
+ constructs_.Push(std::make_unique<Construct>(parent, static_cast<int>(depth), k, begin_id,
+ end_id, begin_pos, end_pos, scope_end_pos));
+ Construct* result = constructs_.Back().get();
+ enclosing.Push(result);
return result;
};
@@ -1808,19 +1799,19 @@
auto* block_info = GetBlockInfo(block_id);
TINT_ASSERT(Reader, block_info);
- if (enclosing.empty()) {
+ if (enclosing.IsEmpty()) {
return Fail() << "internal error: too many merge blocks before block " << block_id;
}
- const Construct* top = enclosing.back();
+ const Construct* top = enclosing.Back();
while (block_id == top->end_id) {
// We've reached a predeclared end of the construct. Pop it off the
// stack.
- enclosing.pop_back();
- if (enclosing.empty()) {
+ enclosing.Pop();
+ if (enclosing.IsEmpty()) {
return Fail() << "internal error: too many merge blocks before block " << block_id;
}
- top = enclosing.back();
+ top = enclosing.Back();
}
const auto merge = block_info->merge_for_header;
@@ -1851,10 +1842,10 @@
// If the loop header branches to two different blocks inside the loop
// construct, then the loop body should be modeled as an if-selection
// construct
- std::vector<uint32_t> targets;
+ utils::Vector<uint32_t, 4> targets;
header_info->basic_block->ForEachSuccessorLabel(
- [&targets](const uint32_t target) { targets.push_back(target); });
- if ((targets.size() == 2u) && targets[0] != targets[1]) {
+ [&targets](const uint32_t target) { targets.Push(target); });
+ if ((targets.Length() == 2u) && targets[0] != targets[1]) {
const auto target0_pos = GetBlockInfo(targets[0])->pos;
const auto target1_pos = GetBlockInfo(targets[1])->pos;
if (top->ContainsPos(target0_pos) && top->ContainsPos(target1_pos)) {
@@ -1881,10 +1872,10 @@
// At the end of the block list, we should only have the kFunction construct
// left.
- if (enclosing.size() != 1) {
+ if (enclosing.Length() != 1) {
return Fail() << "internal error: unbalanced structured constructs when "
"labeling structured constructs: ended with "
- << enclosing.size() - 1 << " unterminated constructs";
+ << enclosing.Length() - 1 << " unterminated constructs";
}
const auto* top = enclosing[0];
if (top->kind != Construct::kFunction || top->depth != 0) {
@@ -1945,8 +1936,8 @@
default_block->default_is_merge = default_block->pos == construct->end_pos;
// Map a case target to the list of values selecting that case.
- std::unordered_map<uint32_t, std::vector<uint64_t>> block_to_values;
- std::vector<uint32_t> case_targets;
+ std::unordered_map<uint32_t, utils::Vector<uint64_t, 4>> block_to_values;
+ utils::Vector<uint32_t, 4> case_targets;
std::unordered_set<uint64_t> case_values;
// Process case targets.
@@ -1960,16 +1951,15 @@
}
case_values.insert(value);
if (block_to_values.count(case_target_id) == 0) {
- case_targets.push_back(case_target_id);
+ case_targets.Push(case_target_id);
}
- block_to_values[case_target_id].push_back(value);
+ block_to_values[case_target_id].Push(value);
}
for (uint32_t case_target_id : case_targets) {
auto* case_block = GetBlockInfo(case_target_id);
- case_block->case_values =
- std::make_unique<std::vector<uint64_t>>(std::move(block_to_values[case_target_id]));
+ case_block->case_values = std::move(block_to_values[case_target_id]);
// A case target can't be a back-edge.
if (construct->begin_pos >= case_block->pos) {
@@ -2085,13 +2075,13 @@
const auto& src_construct = *(src_info->construct);
// Compute the ordered list of unique successors.
- std::vector<uint32_t> successors;
+ utils::Vector<uint32_t, 4> successors;
{
std::unordered_set<uint32_t> visited;
src_info->basic_block->ForEachSuccessorLabel(
[&successors, &visited](const uint32_t succ) {
if (visited.count(succ) == 0) {
- successors.push_back(succ);
+ successors.Push(succ);
visited.insert(succ);
}
});
@@ -2105,10 +2095,10 @@
// to have a merge instruction. We also track kIfBreak edges
// because when used with normal forward edges, we'll need
// to generate a flow guard variable.
- std::vector<uint32_t> normal_forward_edges;
- std::vector<uint32_t> if_break_edges;
+ utils::Vector<uint32_t, 4> normal_forward_edges;
+ utils::Vector<uint32_t, 4> if_break_edges;
- if (successors.empty() && src_construct.enclosing_continue) {
+ if (successors.IsEmpty() && src_construct.enclosing_continue) {
// Kill and return are not allowed in a continue construct.
return Fail() << "Invalid function exit at block " << src
<< " from continue construct starting at "
@@ -2223,10 +2213,10 @@
if ((edge_kind == EdgeKind::kForward) ||
(edge_kind == EdgeKind::kCaseFallThrough)) {
- normal_forward_edges.push_back(dest);
+ normal_forward_edges.Push(dest);
}
if (edge_kind == EdgeKind::kIfBreak) {
- if_break_edges.push_back(dest);
+ if_break_edges.Push(dest);
}
if ((edge_kind == EdgeKind::kForward) ||
@@ -2288,13 +2278,13 @@
if (num_backedges > 1) {
return Fail() << "Block " << src << " has too many backedges: " << num_backedges;
}
- if ((normal_forward_edges.size() > 1) && (src_info->merge_for_header == 0)) {
+ if ((normal_forward_edges.Length() > 1) && (src_info->merge_for_header == 0)) {
return Fail() << "Control flow diverges at block " << src << " (to "
<< normal_forward_edges[0] << ", " << normal_forward_edges[1]
<< ") but it is not a structured header (it has no merge "
"instruction)";
}
- if ((normal_forward_edges.size() + if_break_edges.size() > 1) &&
+ if ((normal_forward_edges.Length() + if_break_edges.Length() > 1) &&
(src_info->merge_for_header == 0)) {
// There is a branch to the merge of an if-selection combined
// with an other normal forward branch. Control within the
@@ -2504,7 +2494,7 @@
}
}
auto* var = parser_impl_.MakeVar(inst.result_id(), ast::StorageClass::kNone, var_store_type,
- constructor, ast::AttributeList{});
+ constructor, AttributeList{});
auto* var_decl_stmt = create<ast::VariableDeclStatement>(Source{}, var);
AddStatement(var_decl_stmt);
auto* var_type = ty_.Reference(var_store_type, ast::StorageClass::kNone);
@@ -2627,7 +2617,7 @@
// Upon entry, the statement stack has one entry representing the whole
// function.
- TINT_ASSERT(Reader, !constructs_.empty());
+ TINT_ASSERT(Reader, !constructs_.IsEmpty());
Construct* function_construct = constructs_[0].get();
TINT_ASSERT(Reader, function_construct != nullptr);
TINT_ASSERT(Reader, function_construct->kind == Construct::kFunction);
@@ -2635,7 +2625,7 @@
// had not been computed at the time the entry was first created.
// TODO(dneto): refactor how the first construct is created vs.
// this statements stack entry is populated.
- TINT_ASSERT(Reader, statements_stack_.size() == 1);
+ TINT_ASSERT(Reader, statements_stack_.Length() == 1);
statements_stack_[0].SetConstruct(function_construct);
for (auto block_id : block_order()) {
@@ -2648,24 +2638,24 @@
bool FunctionEmitter::EmitBasicBlock(const BlockInfo& block_info) {
// Close off previous constructs.
- while (!statements_stack_.empty() && (statements_stack_.back().GetEndId() == block_info.id)) {
- statements_stack_.back().Finalize(&builder_);
- statements_stack_.pop_back();
+ while (!statements_stack_.IsEmpty() && (statements_stack_.Back().GetEndId() == block_info.id)) {
+ statements_stack_.Back().Finalize(&builder_);
+ statements_stack_.Pop();
}
- if (statements_stack_.empty()) {
+ if (statements_stack_.IsEmpty()) {
return Fail() << "internal error: statements stack empty at block " << block_info.id;
}
// Enter new constructs.
- std::vector<const Construct*> entering_constructs; // inner most comes first
+ utils::Vector<const Construct*, 4> entering_constructs; // inner most comes first
{
auto* here = block_info.construct;
- auto* const top_construct = statements_stack_.back().GetConstruct();
+ auto* const top_construct = statements_stack_.Back().GetConstruct();
while (here != top_construct) {
// Only enter a construct at its header block.
if (here->begin_id == block_info.id) {
- entering_constructs.push_back(here);
+ entering_constructs.Push(here);
}
here = here->parent;
}
@@ -2721,10 +2711,10 @@
// - We are entering 0 or 1 constructs, or
// - We are entering 2 constructs, with the outer one being a kContinue or
// kLoop, the inner one is not a continue.
- if (entering_constructs.size() > 2) {
+ if (entering_constructs.Length() > 2) {
return Fail() << "internal error: bad construct nesting found";
}
- if (entering_constructs.size() == 2) {
+ if (entering_constructs.Length() == 2) {
auto inner_kind = entering_constructs[0]->kind;
auto outer_kind = entering_constructs[1]->kind;
if (outer_kind != Construct::kContinue && outer_kind != Construct::kLoop) {
@@ -2896,9 +2886,9 @@
// But make sure we do it in the right order.
auto push_else = [this, builder, else_end, construct, false_is_break, false_is_continue]() {
// Push the else clause onto the stack first.
- PushNewStatementBlock(construct, else_end, [=](const ast::StatementList& stmts) {
+ PushNewStatementBlock(construct, else_end, [=](const StatementList& stmts) {
// Only set the else-clause if there are statements to fill it.
- if (!stmts.empty()) {
+ if (!stmts.IsEmpty()) {
// The "else" consists of the statement list from the top of
// statements stack, without an "else if" condition.
builder->else_stmt = create<ast::BlockStatement>(Source{}, stmts);
@@ -2947,7 +2937,7 @@
}
// Push the then clause onto the stack.
- PushNewStatementBlock(construct, then_end, [=](const ast::StatementList& stmts) {
+ PushNewStatementBlock(construct, then_end, [=](const StatementList& stmts) {
builder->body = create<ast::BlockStatement>(Source{}, stmts);
});
if (true_is_break) {
@@ -2984,17 +2974,17 @@
// We will push statement-blocks onto the stack to gather the statements in
// the default clause and cases clauses. Determine the list of blocks
// that start each clause.
- std::vector<const BlockInfo*> clause_heads;
+ utils::Vector<const BlockInfo*, 4> clause_heads;
// Collect the case clauses, even if they are just the merge block.
// First the default clause.
const auto default_id = branch->GetSingleWordInOperand(1);
const auto* default_info = GetBlockInfo(default_id);
- clause_heads.push_back(default_info);
+ clause_heads.Push(default_info);
// Now the case clauses.
for (uint32_t iarg = 2; iarg + 1 < branch->NumInOperands(); iarg += 2) {
const auto case_target_id = branch->GetSingleWordInOperand(iarg + 1);
- clause_heads.push_back(GetBlockInfo(case_target_id));
+ clause_heads.Push(GetBlockInfo(case_target_id));
}
std::stable_sort(
@@ -3005,37 +2995,36 @@
// Use read index r, and write index w.
// Invariant: w <= r;
size_t w = 0;
- for (size_t r = 0; r < clause_heads.size(); ++r) {
+ for (size_t r = 0; r < clause_heads.Length(); ++r) {
if (clause_heads[r] != clause_heads[w]) {
++w; // Advance the write cursor.
}
clause_heads[w] = clause_heads[r];
}
// We know it's not empty because it always has at least a default clause.
- TINT_ASSERT(Reader, !clause_heads.empty());
- clause_heads.resize(w + 1);
+ TINT_ASSERT(Reader, !clause_heads.IsEmpty());
+ clause_heads.Resize(w + 1);
}
// Push them on in reverse order.
- const auto last_clause_index = clause_heads.size() - 1;
+ const auto last_clause_index = clause_heads.Length() - 1;
for (size_t i = last_clause_index;; --i) {
// Create a list of integer literals for the selector values leading to
// this case clause.
- ast::CaseSelectorList selectors;
- const auto* values_ptr = clause_heads[i]->case_values.get();
- const bool has_selectors = (values_ptr && !values_ptr->empty());
+ utils::Vector<const ast::IntLiteralExpression*, 4> selectors;
+ const bool has_selectors = clause_heads[i]->case_values.has_value();
if (has_selectors) {
- std::vector<uint64_t> values(values_ptr->begin(), values_ptr->end());
+ auto values = clause_heads[i]->case_values.value();
std::stable_sort(values.begin(), values.end());
for (auto value : values) {
// The rest of this module can handle up to 64 bit switch values.
// The Tint AST handles 32-bit values.
const uint32_t value32 = uint32_t(value & 0xFFFFFFFF);
if (selector.type->IsUnsignedScalarOrVector()) {
- selectors.emplace_back(create<ast::IntLiteralExpression>(
+ selectors.Push(create<ast::IntLiteralExpression>(
Source{}, value32, ast::IntLiteralExpression::Suffix::kU));
} else {
- selectors.emplace_back(
+ selectors.Push(
create<ast::IntLiteralExpression>(Source{}, static_cast<int32_t>(value32),
ast::IntLiteralExpression::Suffix::kI));
}
@@ -3044,13 +3033,13 @@
// Where does this clause end?
const auto end_id =
- (i + 1 < clause_heads.size()) ? clause_heads[i + 1]->id : construct->end_id;
+ (i + 1 < clause_heads.Length()) ? clause_heads[i + 1]->id : construct->end_id;
// Reserve the case clause slot in swch->cases, push the new statement block
// for the case, and fill the case clause once the block is generated.
- auto case_idx = swch->cases.size();
- swch->cases.emplace_back(nullptr);
- PushNewStatementBlock(construct, end_id, [=](const ast::StatementList& stmts) {
+ auto case_idx = swch->cases.Length();
+ swch->cases.Push(nullptr);
+ PushNewStatementBlock(construct, end_id, [=](const StatementList& stmts) {
auto* body = create<ast::BlockStatement>(Source{}, stmts);
swch->cases[case_idx] = create<ast::CaseStatement>(Source{}, selectors, body);
});
@@ -3059,11 +3048,11 @@
construct->ContainsPos(default_info->pos)) {
// Generate a default clause with a just fallthrough.
auto* stmts = create<ast::BlockStatement>(
- Source{}, ast::StatementList{
+ Source{}, StatementList{
create<ast::FallthroughStatement>(Source{}),
});
- auto* case_stmt = create<ast::CaseStatement>(Source{}, ast::CaseSelectorList{}, stmts);
- swch->cases.emplace_back(case_stmt);
+ auto* case_stmt = create<ast::CaseStatement>(Source{}, utils::Empty, stmts);
+ swch->cases.Push(case_stmt);
}
if (i == 0) {
@@ -3076,7 +3065,7 @@
bool FunctionEmitter::EmitLoopStart(const Construct* construct) {
auto* builder = AddStatementBuilder<LoopStatementBuilder>();
- PushNewStatementBlock(construct, construct->end_id, [=](const ast::StatementList& stmts) {
+ PushNewStatementBlock(construct, construct->end_id, [=](const StatementList& stmts) {
builder->body = create<ast::BlockStatement>(Source{}, stmts);
});
return success();
@@ -3091,7 +3080,7 @@
return Fail() << "internal error: starting continue construct, "
"expected loop on top of stack";
}
- PushNewStatementBlock(construct, construct->end_id, [=](const ast::StatementList& stmts) {
+ PushNewStatementBlock(construct, construct->end_id, [=](const StatementList& stmts) {
loop->continuing = create<ast::BlockStatement>(Source{}, stmts);
});
@@ -3185,7 +3174,7 @@
AddStatement(MakeSimpleIf(cond, true_branch, false_branch));
if (!flow_guard.empty()) {
- PushGuard(flow_guard, statements_stack_.back().GetEndId());
+ PushGuard(flow_guard, statements_stack_.Back().GetEndId());
}
return true;
}
@@ -3285,15 +3274,15 @@
if ((then_stmt == nullptr) && (else_stmt == nullptr)) {
return nullptr;
}
- ast::StatementList if_stmts;
+ StatementList if_stmts;
if (then_stmt != nullptr) {
- if_stmts.emplace_back(then_stmt);
+ if_stmts.Push(then_stmt);
}
auto* if_block = create<ast::BlockStatement>(Source{}, if_stmts);
const ast::Statement* else_block = nullptr;
if (else_stmt) {
- else_block = create<ast::BlockStatement>(ast::StatementList{else_stmt});
+ else_block = create<ast::BlockStatement>(StatementList{else_stmt});
}
auto* if_stmt = create<ast::IfStatement>(Source{}, condition, if_block, else_block);
@@ -3347,7 +3336,7 @@
return true;
}
// Returns the given list of local definition IDs, sorted by their index.
- auto sorted_by_index = [this](const std::vector<uint32_t>& ids) {
+ auto sorted_by_index = [this](auto& ids) {
auto sorted = ids;
std::stable_sort(sorted.begin(), sorted.end(),
[this](const uint32_t lhs, const uint32_t rhs) {
@@ -3363,7 +3352,7 @@
auto* storage_type = RemapStorageClass(parser_impl_.ConvertType(def_inst->type_id()), id);
AddStatement(create<ast::VariableDeclStatement>(
Source{}, parser_impl_.MakeVar(id, ast::StorageClass::kNone, storage_type, nullptr,
- ast::AttributeList{})));
+ AttributeList{})));
auto* type = ty_.Reference(storage_type, ast::StorageClass::kNone);
identifier_types_.emplace(id, type);
}
@@ -3394,7 +3383,7 @@
// Emit assignments to carry values to phi nodes in potential destinations.
// Do it in index order.
- if (!block_info.phi_assignments.empty()) {
+ if (!block_info.phi_assignments.IsEmpty()) {
auto sorted = block_info.phi_assignments;
std::stable_sort(
sorted.begin(), sorted.end(),
@@ -3813,8 +3802,8 @@
const char* unary_builtin_name = GetUnaryBuiltInFunctionName(opcode);
if (unary_builtin_name != nullptr) {
- ast::ExpressionList params;
- params.emplace_back(MakeOperand(inst, 0).expr);
+ ExpressionList params;
+ params.Push(MakeOperand(inst, 0).expr);
return {ast_type, create<ast::CallExpression>(
Source{},
create<ast::IdentifierExpression>(
@@ -3892,9 +3881,9 @@
}
if (opcode == SpvOpCompositeConstruct) {
- ast::ExpressionList operands;
+ ExpressionList operands;
for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) {
- operands.emplace_back(MakeOperand(inst, iarg).expr);
+ operands.Push(MakeOperand(inst, iarg).expr);
}
return {ast_type,
builder_.Construct(Source{}, ast_type->Build(builder_), std::move(operands))};
@@ -3962,7 +3951,7 @@
auto e1 = MakeOperand(inst, 2);
auto e2 = ToSignedIfUnsigned(MakeOperand(inst, 3));
- return {e1.type, builder_.Call(Source{}, "ldexp", ast::ExpressionList{e1.expr, e2.expr})};
+ return {e1.type, builder_.Call(Source{}, "ldexp", utils::Vector{e1.expr, e2.expr})};
}
auto* result_type = parser_impl_.ConvertType(inst.type_id());
@@ -3988,16 +3977,19 @@
TINT_ASSERT(Reader, normal.type->Is<F32>());
TINT_ASSERT(Reader, incident.type->Is<F32>());
TINT_ASSERT(Reader, nref.type->Is<F32>());
- return {ty_.F32(),
- builder_.Call(
- Source{}, "select",
- ast::ExpressionList{create<ast::UnaryOpExpression>(
- Source{}, ast::UnaryOp::kNegation, normal.expr),
- normal.expr,
- create<ast::BinaryExpression>(
- Source{}, ast::BinaryOp::kLessThan,
- builder_.Mul({}, incident.expr, nref.expr),
- builder_.Expr(0_f))})};
+ return {
+ ty_.F32(),
+ builder_.Call(
+ Source{}, "select",
+ utils::Vector{
+ create<ast::UnaryOpExpression>(Source{}, ast::UnaryOp::kNegation,
+ normal.expr),
+ normal.expr,
+ create<ast::BinaryExpression>(
+ Source{}, ast::BinaryOp::kLessThan,
+ builder_.Mul({}, incident.expr, nref.expr), builder_.Expr(0_f)),
+ }),
+ };
}
case GLSLstd450Reflect: {
@@ -4028,13 +4020,17 @@
return {};
}
const Type* f32 = eta.type;
- return {f32, builder_.MemberAccessor(
- builder_.Call(
- Source{}, "refract",
- ast::ExpressionList{
- builder_.vec2<tint::f32>(incident.expr, 0_f),
- builder_.vec2<tint::f32>(normal.expr, 0_f), eta.expr}),
- "x")};
+ return {
+ f32,
+ builder_.MemberAccessor(
+ builder_.Call(Source{}, "refract",
+ utils::Vector{
+ builder_.vec2<tint::f32>(incident.expr, 0_f),
+ builder_.vec2<tint::f32>(normal.expr, 0_f),
+ eta.expr,
+ }),
+ "x"),
+ };
}
default:
break;
@@ -4048,7 +4044,7 @@
}
auto* func = create<ast::IdentifierExpression>(Source{}, builder_.Symbols().Register(name));
- ast::ExpressionList operands;
+ ExpressionList operands;
const Type* first_operand_type = nullptr;
// All parameters to GLSL.std.450 extended instructions are IDs.
for (uint32_t iarg = 2; iarg < inst.NumInOperands(); ++iarg) {
@@ -4056,7 +4052,7 @@
if (first_operand_type == nullptr) {
first_operand_type = operand.type;
}
- operands.emplace_back(operand.expr);
+ operands.Push(operand.expr);
}
auto* call = create<ast::CallExpression>(Source{}, func, std::move(operands));
TypedExpression call_expr{result_type, call};
@@ -4483,7 +4479,7 @@
// Assume the literal indices are valid, and there is a valid number of them.
auto source = GetSourceForInst(inst);
const Vector* result_type = As<Vector>(parser_impl_.ConvertType(inst.type_id()));
- ast::ExpressionList values;
+ ExpressionList values;
for (uint32_t i = 2; i < inst.NumInOperands(); ++i) {
const auto index = inst.GetSingleWordInOperand(i);
if (index < vec0_len) {
@@ -4491,8 +4487,7 @@
if (!expr) {
return {};
}
- values.emplace_back(
- create<ast::MemberAccessorExpression>(source, expr.expr, Swizzle(index)));
+ values.Push(create<ast::MemberAccessorExpression>(source, expr.expr, Swizzle(index)));
} else if (index < vec0_len + vec1_len) {
const auto sub_index = index - vec0_len;
TINT_ASSERT(Reader, sub_index < kMaxVectorLen);
@@ -4500,18 +4495,19 @@
if (!expr) {
return {};
}
- values.emplace_back(
+ values.Push(
create<ast::MemberAccessorExpression>(source, expr.expr, Swizzle(sub_index)));
} else if (index == 0xFFFFFFFF) {
// By rule, this maps to OpUndef. Instead, make it zero.
- values.emplace_back(parser_impl_.MakeNullValue(result_type->type));
+ values.Push(parser_impl_.MakeNullValue(result_type->type));
} else {
Fail() << "invalid vectorshuffle ID %" << inst.result_id()
<< ": index too large: " << index;
return {};
}
}
- return {result_type, builder_.Construct(source, result_type->Build(builder_), values)};
+ return {result_type,
+ builder_.Construct(source, result_type->Build(builder_), std::move(values))};
}
bool FunctionEmitter::RegisterSpecialBuiltInVariables() {
@@ -4732,7 +4728,7 @@
if (IsInBlockOrder(pred_block_info)) {
// Record the assignment that needs to occur at the end
// of the predecessor block.
- pred_block_info->phi_assignments.push_back({phi_id, value_id});
+ pred_block_info->phi_assignments.Push({phi_id, value_id});
first_pos = std::min(first_pos, pred_block_info->pos);
last_pos = std::max(last_pos, pred_block_info->pos);
}
@@ -4740,8 +4736,7 @@
// Schedule the declaration of the state variable.
const auto* enclosing_construct = GetEnclosingScope(first_pos, last_pos);
- GetBlockInfo(enclosing_construct->begin_id)
- ->phis_needing_state_vars.push_back(phi_id);
+ GetBlockInfo(enclosing_construct->begin_id)->phis_needing_state_vars.Push(phi_id);
}
}
}
@@ -4812,7 +4807,7 @@
// TODO(dneto): Handle non-storable types, particularly pointers.
def_info->requires_hoisted_def = true;
auto* hoist_to_block = GetBlockInfo(enclosing_construct->begin_id);
- hoist_to_block->hoisted_ids.push_back(def_id);
+ hoist_to_block->hoisted_ids.Push(def_id);
}
}
}
@@ -4874,8 +4869,8 @@
return {};
}
- ast::ExpressionList params;
- params.push_back(arg_expr.expr);
+ ExpressionList params;
+ params.Push(arg_expr.expr);
TypedExpression result{
expr_type,
builder_.Construct(GetSourceForInst(inst), expr_type->Build(builder_), std::move(params))};
@@ -4893,7 +4888,7 @@
auto name = namer_.Name(inst.GetSingleWordInOperand(0));
auto* function = create<ast::IdentifierExpression>(Source{}, builder_.Symbols().Register(name));
- ast::ExpressionList args;
+ ExpressionList args;
for (uint32_t iarg = 1; iarg < inst.NumInOperands(); ++iarg) {
auto expr = MakeOperand(inst, iarg);
if (!expr) {
@@ -4902,7 +4897,7 @@
// Functions cannot use references as parameters, so we need to pass by
// pointer if the operand is of pointer type.
expr = AddressOfIfNeeded(expr, def_use_mgr_->GetDef(inst.GetSingleWordInOperand(iarg)));
- args.emplace_back(expr.expr);
+ args.Push(expr.expr);
}
if (failed()) {
return false;
@@ -4969,14 +4964,14 @@
auto* name = sem::str(builtin);
auto* ident = create<ast::IdentifierExpression>(Source{}, builder_.Symbols().Register(name));
- ast::ExpressionList params;
+ ExpressionList params;
const Type* first_operand_type = nullptr;
for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) {
TypedExpression operand = MakeOperand(inst, iarg);
if (first_operand_type == nullptr) {
first_operand_type = operand.type;
}
- params.emplace_back(operand.expr);
+ params.Push(operand.expr);
}
auto* call_expr = create<ast::CallExpression>(Source{}, ident, std::move(params));
auto* result_type = parser_impl_.ConvertType(inst.type_id());
@@ -5001,11 +4996,11 @@
auto* op_ty = true_value.type;
if (op_ty->Is<Vector>() || op_ty->IsFloatScalar() || op_ty->IsIntegerScalar() ||
op_ty->Is<Bool>()) {
- ast::ExpressionList params;
- params.push_back(false_value.expr);
- params.push_back(true_value.expr);
+ ExpressionList params;
+ params.Push(false_value.expr);
+ params.Push(true_value.expr);
// The condition goes last.
- params.push_back(condition.expr);
+ params.Push(condition.expr);
return {op_ty,
create<ast::CallExpression>(Source{},
create<ast::IdentifierExpression>(
@@ -5080,7 +5075,7 @@
}
bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
- ast::ExpressionList args;
+ ExpressionList args;
const auto opcode = inst.opcode();
// Form the texture operand.
@@ -5088,13 +5083,13 @@
if (!image) {
return false;
}
- args.push_back(GetImageExpression(inst));
+ args.Push(GetImageExpression(inst));
// Form the sampler operand, if needed.
if (IsSampledImageAccess(opcode)) {
// Form the sampler operand.
if (auto* sampler = GetSamplerExpression(inst)) {
- args.push_back(sampler);
+ args.Push(sampler);
} else {
return false;
}
@@ -5116,10 +5111,12 @@
// Push the coordinates operands.
auto coords = MakeCoordinateOperandsForImageAccess(inst);
- if (coords.empty()) {
+ if (coords.IsEmpty()) {
return false;
}
- args.insert(args.end(), coords.begin(), coords.end());
+ for (auto* coord : coords) {
+ args.Push(coord);
+ }
// Skip the coordinates operand.
arg_index++;
@@ -5129,7 +5126,7 @@
// the parameter list. Issues a diagnostic and returns false on error.
auto consume_dref = [&]() -> bool {
if (arg_index < num_args) {
- args.push_back(MakeOperand(inst, arg_index).expr);
+ args.Push(MakeOperand(inst, arg_index).expr);
arg_index++;
} else {
return Fail() << "image depth-compare instruction is missing a Dref operand: "
@@ -5166,7 +5163,12 @@
builtin_name = "textureGather";
if (!texture_type->Is<DepthTexture>()) {
// The explicit component is the *first* argument in WGSL.
- args.insert(args.begin(), ToI32(MakeOperand(inst, arg_index)).expr);
+ ExpressionList gather_args;
+ gather_args.Push(ToI32(MakeOperand(inst, arg_index)).expr);
+ for (auto* arg : args) {
+ gather_args.Push(arg);
+ }
+ args = std::move(gather_args);
}
// Skip over the component operand, even for depth textures.
arg_index++;
@@ -5194,7 +5196,7 @@
return false;
}
- args.push_back(converted_texel);
+ args.Push(converted_texel);
arg_index++;
} else {
return Fail() << "image write is missing a Texel operand: " << inst.PrettyPrint();
@@ -5223,7 +5225,7 @@
<< inst.PrettyPrint();
}
builtin_name += "Bias";
- args.push_back(MakeOperand(inst, arg_index).expr);
+ args.Push(MakeOperand(inst, arg_index).expr);
image_operands_mask ^= SpvImageOperandsBiasMask;
arg_index++;
}
@@ -5250,7 +5252,7 @@
// Convert it to a signed integer type.
lod = ToI32(lod);
}
- args.push_back(lod.expr);
+ args.Push(lod.expr);
}
image_operands_mask ^= SpvImageOperandsLodMask;
@@ -5259,7 +5261,7 @@
!texture_type->IsAnyOf<DepthMultisampledTexture, MultisampledTexture>()) {
// textureLoad requires an explicit level-of-detail parameter for
// non-multisampled texture types.
- args.push_back(parser_impl_.MakeNullValue(ty_.I32()));
+ args.Push(parser_impl_.MakeNullValue(ty_.I32()));
}
if (arg_index + 1 < num_args && (image_operands_mask & SpvImageOperandsGradMask)) {
if (is_dref_sample) {
@@ -5273,8 +5275,8 @@
<< inst.PrettyPrint();
}
builtin_name += "Grad";
- args.push_back(MakeOperand(inst, arg_index).expr);
- args.push_back(MakeOperand(inst, arg_index + 1).expr);
+ args.Push(MakeOperand(inst, arg_index).expr);
+ args.Push(MakeOperand(inst, arg_index + 1).expr);
image_operands_mask ^= SpvImageOperandsGradMask;
arg_index += 2;
}
@@ -5295,13 +5297,13 @@
<< inst.PrettyPrint();
}
- args.push_back(ToSignedIfUnsigned(MakeOperand(inst, arg_index)).expr);
+ args.Push(ToSignedIfUnsigned(MakeOperand(inst, arg_index)).expr);
image_operands_mask ^= SpvImageOperandsConstOffsetMask;
arg_index++;
}
if (arg_index < num_args && (image_operands_mask & SpvImageOperandsSampleMask)) {
// TODO(dneto): only permitted with ImageFetch
- args.push_back(ToI32(MakeOperand(inst, arg_index)).expr);
+ args.Push(ToI32(MakeOperand(inst, arg_index)).expr);
image_operands_mask ^= SpvImageOperandsSampleMask;
arg_index++;
}
@@ -5343,12 +5345,14 @@
// first component.
if (texture_type->IsAnyOf<DepthTexture, DepthMultisampledTexture>()) {
if (is_non_dref_sample || (opcode == SpvOpImageFetch)) {
- value = builder_.Construct(
- Source{},
- result_type->Build(builder_), // a vec4
- ast::ExpressionList{value, parser_impl_.MakeNullValue(result_component_type),
- parser_impl_.MakeNullValue(result_component_type),
- parser_impl_.MakeNullValue(result_component_type)});
+ value = builder_.Construct(Source{},
+ result_type->Build(builder_), // a vec4
+ utils::Vector{
+ value,
+ parser_impl_.MakeNullValue(result_component_type),
+ parser_impl_.MakeNullValue(result_component_type),
+ parser_impl_.MakeNullValue(result_component_type),
+ });
}
}
@@ -5399,15 +5403,15 @@
switch (opcode) {
case SpvOpImageQuerySize:
case SpvOpImageQuerySizeLod: {
- ast::ExpressionList exprs;
+ ExpressionList exprs;
// Invoke textureDimensions.
// If the texture is arrayed, combine with the result from
// textureNumLayers.
auto* dims_ident = create<ast::IdentifierExpression>(
Source{}, builder_.Symbols().Register("textureDimensions"));
- ast::ExpressionList dims_args{GetImageExpression(inst)};
+ ExpressionList dims_args{GetImageExpression(inst)};
if (opcode == SpvOpImageQuerySizeLod) {
- dims_args.push_back(ToI32(MakeOperand(inst, 1)).expr);
+ dims_args.Push(ToI32(MakeOperand(inst, 1)).expr);
}
const ast::Expression* dims_call =
create<ast::CallExpression>(Source{}, dims_ident, dims_args);
@@ -5418,16 +5422,17 @@
dims_call =
create<ast::MemberAccessorExpression>(Source{}, dims_call, PrefixSwizzle(2));
}
- exprs.push_back(dims_call);
+ exprs.Push(dims_call);
if (ast::IsTextureArray(dims)) {
auto* layers_ident = create<ast::IdentifierExpression>(
Source{}, builder_.Symbols().Register("textureNumLayers"));
- exprs.push_back(create<ast::CallExpression>(
- Source{}, layers_ident, ast::ExpressionList{GetImageExpression(inst)}));
+ exprs.Push(create<ast::CallExpression>(Source{}, layers_ident,
+ utils::Vector{GetImageExpression(inst)}));
}
auto* result_type = parser_impl_.ConvertType(inst.type_id());
TypedExpression expr = {
- result_type, builder_.Construct(Source{}, result_type->Build(builder_), exprs)};
+ result_type,
+ builder_.Construct(Source{}, result_type->Build(builder_), std::move(exprs))};
return EmitConstDefOrWriteToHoistedVar(inst, expr);
}
case SpvOpImageQueryLod:
@@ -5441,13 +5446,13 @@
auto* levels_ident =
create<ast::IdentifierExpression>(Source{}, builder_.Symbols().Register(name));
const ast::Expression* ast_expr = create<ast::CallExpression>(
- Source{}, levels_ident, ast::ExpressionList{GetImageExpression(inst)});
+ Source{}, levels_ident, utils::Vector{GetImageExpression(inst)});
auto* result_type = parser_impl_.ConvertType(inst.type_id());
// The SPIR-V result type must be integer scalar. The WGSL bulitin
// returns i32. If they aren't the same then convert the result.
if (!result_type->Is<I32>()) {
ast_expr = builder_.Construct(Source{}, result_type->Build(builder_),
- ast::ExpressionList{ast_expr});
+ utils::Vector{ast_expr});
}
TypedExpression expr{result_type, ast_expr};
return EmitConstDefOrWriteToHoistedVar(inst, expr);
@@ -5461,14 +5466,14 @@
bool FunctionEmitter::EmitAtomicOp(const spvtools::opt::Instruction& inst) {
auto emit_atomic = [&](sem::BuiltinType builtin, std::initializer_list<TypedExpression> args) {
// Split args into params and expressions
- ast::ParameterList params;
- params.reserve(args.size());
- ast::ExpressionList exprs;
- exprs.reserve(args.size());
+ ParameterList params;
+ params.Reserve(args.size());
+ ExpressionList exprs;
+ exprs.Reserve(args.size());
size_t i = 0;
for (auto& a : args) {
- params.emplace_back(builder_.Param("p" + std::to_string(i++), a.type->Build(builder_)));
- exprs.emplace_back(a.expr);
+ params.Push(builder_.Param("p" + std::to_string(i++), a.type->Build(builder_)));
+ exprs.Push(a.expr);
}
// Function return type
@@ -5486,15 +5491,15 @@
auto* stub =
create<ast::Function>(Source{}, sym, std::move(params), ret_type,
/* body */ nullptr,
- ast::AttributeList{
+ AttributeList{
stub_deco,
builder_.Disable(ast::DisabledValidation::kFunctionHasNoBody),
},
- ast::AttributeList{});
+ AttributeList{});
builder_.AST().AddFunction(stub);
// Emit call to stub, will be replaced with call to atomic builtin by transform::SpirvAtomic
- auto* call = builder_.Call(Source{}, sym, exprs);
+ auto* call = builder_.Call(Source{}, sym, std::move(exprs));
if (inst.type_id() != 0) {
auto* result_type = parser_impl_.ConvertType(inst.type_id());
TypedExpression expr{result_type, call};
@@ -5567,7 +5572,7 @@
return Fail() << "unhandled atomic op: " << inst.PrettyPrint();
}
-ast::ExpressionList FunctionEmitter::MakeCoordinateOperandsForImageAccess(
+FunctionEmitter::ExpressionList FunctionEmitter::MakeCoordinateOperandsForImageAccess(
const spvtools::opt::Instruction& inst) {
if (!parser_impl_.success()) {
Fail();
@@ -5642,7 +5647,7 @@
return {};
}
- ast::ExpressionList result;
+ ExpressionList result;
// Generates the expression for the WGSL coordinates, when it is a prefix
// swizzle with num_axes. If the result would be unsigned, also converts
@@ -5669,7 +5674,7 @@
// The source must be a vector. It has at least one coordinate component
// and it must have an array component. Use a vector swizzle to get the
// first `num_axes` components.
- result.push_back(prefix_swizzle_expr());
+ result.Push(prefix_swizzle_expr());
// Now get the array index.
const ast::Expression* array_index =
@@ -5682,16 +5687,16 @@
array_index = builder_.Call("round", array_index);
}
// Convert it to a signed integer type, if needed.
- result.push_back(ToI32({component_type, array_index}).expr);
+ result.Push(ToI32({component_type, array_index}).expr);
} else {
if (num_coords_supplied == num_coords_required && !is_proj) {
// Pass the value through, with possible unsigned->signed conversion.
- result.push_back(ToSignedIfUnsigned(raw_coords).expr);
+ result.Push(ToSignedIfUnsigned(raw_coords).expr);
} else {
// There are more coordinates supplied than needed. So the source type
// is a vector. Use a vector swizzle to get the first `num_axes`
// components.
- result.push_back(prefix_swizzle_expr());
+ result.Push(prefix_swizzle_expr());
}
}
return result;
@@ -5752,10 +5757,10 @@
// Expand the texel to a 4 element vector.
auto* component_type = texel.type->IsScalar() ? texel.type : texel.type->As<Vector>()->type;
texel.type = ty_.Vector(component_type, dest_count);
- ast::ExpressionList exprs;
- exprs.push_back(texel.expr);
+ ExpressionList exprs;
+ exprs.Push(texel.expr);
for (auto i = src_count; i < dest_count; i++) {
- exprs.push_back(parser_impl_.MakeNullExpression(component_type).expr);
+ exprs.Push(parser_impl_.MakeNullExpression(component_type).expr);
}
texel.expr = builder_.Construct(Source{}, texel.type->Build(builder_), std::move(exprs));
}
@@ -5767,8 +5772,7 @@
if (!value || value.type->Is<I32>()) {
return value;
}
- return {ty_.I32(),
- builder_.Construct(Source{}, builder_.ty.i32(), ast::ExpressionList{value.expr})};
+ return {ty_.I32(), builder_.Construct(Source{}, builder_.ty.i32(), utils::Vector{value.expr})};
}
TypedExpression FunctionEmitter::ToSignedIfUnsigned(TypedExpression value) {
@@ -5777,8 +5781,7 @@
}
if (auto* vec_type = value.type->As<Vector>()) {
auto* new_type = ty_.Vector(ty_.I32(), vec_type->size);
- return {new_type,
- builder_.Construct(new_type->Build(builder_), ast::ExpressionList{value.expr})};
+ return {new_type, builder_.Construct(new_type->Build(builder_), utils::Vector{value.expr})};
}
return ToI32(value);
}
@@ -5841,20 +5844,22 @@
// | c.y * r.x c.y * r.y |
// | c.z * r.x c.z * r.y |
- ast::ExpressionList result_columns;
+ ExpressionList result_columns;
for (uint32_t icol = 0; icol < result_ty->columns; icol++) {
- ast::ExpressionList result_row;
+ ExpressionList result_row;
auto* row_factor = create<ast::MemberAccessorExpression>(Source{}, row.expr, Swizzle(icol));
for (uint32_t irow = 0; irow < result_ty->rows; irow++) {
auto* column_factor =
create<ast::MemberAccessorExpression>(Source{}, col.expr, Swizzle(irow));
auto* elem = create<ast::BinaryExpression>(Source{}, ast::BinaryOp::kMultiply,
row_factor, column_factor);
- result_row.push_back(elem);
+ result_row.Push(elem);
}
- result_columns.push_back(builder_.Construct(Source{}, col_ty->Build(builder_), result_row));
+ result_columns.Push(
+ builder_.Construct(Source{}, col_ty->Build(builder_), std::move(result_row)));
}
- return {result_ty, builder_.Construct(Source{}, result_ty->Build(builder_), result_columns)};
+ return {result_ty,
+ builder_.Construct(Source{}, result_ty->Build(builder_), std::move(result_columns))};
}
bool FunctionEmitter::MakeVectorInsertDynamic(const spvtools::opt::Instruction& inst) {
diff --git a/src/tint/reader/spirv/function.h b/src/tint/reader/spirv/function.h
index ae7a9a1..7a2a86b 100644
--- a/src/tint/reader/spirv/function.h
+++ b/src/tint/reader/spirv/function.h
@@ -16,6 +16,7 @@
#define SRC_TINT_READER_SPIRV_FUNCTION_H_
#include <memory>
+#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
@@ -125,7 +126,7 @@
/// switch?
bool default_is_merge = false;
/// The list of switch values that cause a branch to this block.
- std::unique_ptr<std::vector<uint64_t>> case_values;
+ std::optional<utils::Vector<uint64_t, 4>> case_values;
/// The following fields record relationships among blocks in a selection
/// construct for an OpBranchConditional instruction.
@@ -158,7 +159,7 @@
/// The result IDs that this block is responsible for declaring as a
/// hoisted variable.
/// @see DefInfo#requires_hoisted_def
- std::vector<uint32_t> hoisted_ids;
+ utils::Vector<uint32_t, 4> hoisted_ids;
/// A PhiAssignment represents the assignment of a value to the state
/// variable associated with an OpPhi in a successor block.
@@ -170,10 +171,10 @@
};
/// If this basic block branches to a visited basic block containing phis,
/// then this is the list of writes to the variables associated those phis.
- std::vector<PhiAssignment> phi_assignments;
+ utils::Vector<PhiAssignment, 4> phi_assignments;
/// The IDs of OpPhi instructions which require their associated state
/// variable to be declared in this basic block.
- std::vector<uint32_t> phis_needing_state_vars;
+ utils::Vector<uint32_t, 4> phis_needing_state_vars;
};
/// Writes the BlockInfo to the ostream
@@ -388,6 +389,12 @@
/// A FunctionEmitter emits a SPIR-V function onto a Tint AST module.
class FunctionEmitter {
+ using AttributeList = utils::Vector<const ast::Attribute*, 8>;
+ using StructMemberList = utils::Vector<const ast::StructMember*, 8>;
+ using ExpressionList = utils::Vector<const ast::Expression*, 8>;
+ using ParameterList = utils::Vector<const ast::Parameter*, 8>;
+ using StatementList = utils::Vector<const ast::Statement*, 8>;
+
public:
/// Creates a FunctionEmitter, and prepares to write to the AST module
/// in `pi`
@@ -420,7 +427,7 @@
/// Finalizes any StatementBuilders returns the body of the function.
/// Must only be called once, and to be used only for testing.
/// @returns the body of the function.
- const ast::StatementList ast_body();
+ StatementList ast_body();
/// Records failure.
/// @returns a FailStream on which to emit diagnostics.
@@ -455,12 +462,12 @@
/// @returns false if emission failed
bool EmitPipelineInput(std::string var_name,
const Type* var_type,
- ast::AttributeList* decos,
- std::vector<int> index_prefix,
+ AttributeList* decos,
+ utils::Vector<int, 8> index_prefix,
const Type* tip_type,
const Type* forced_param_type,
- ast::ParameterList* params,
- ast::StatementList* statements);
+ ParameterList* params,
+ StatementList* statements);
/// Creates one or more struct members from an output variable, and the
/// expressions that compute the value they contribute to the entry point
@@ -471,37 +478,30 @@
/// @param var_name The name of the variable
/// @param var_type The store type of the variable
/// @param decos The variable's decorations
- /// @param index_prefix Indices stepping into the variable, indicating
- /// what part of the variable to populate.
- /// @param tip_type The type of the component inside variable, after indexing
- /// with the indices in `index_prefix`.
- /// @param forced_member_type The type forced by WGSL, if the variable is a
- /// builtin, otherwise the same as var_type.
- /// @param return_members The struct member list where the new member is
- /// added.
- /// @param return_exprs The expression list where the return expression is
- /// added.
+ /// @param index_prefix Indices stepping into the variable, indicating what part of the variable
+ /// to populate.
+ /// @param tip_type The type of the component inside variable, after indexing with the indices
+ /// in `index_prefix`.
+ /// @param forced_member_type The type forced by WGSL, if the variable is a builtin, otherwise
+ /// the same as var_type.
+ /// @param return_members The struct member list where the new member is added.
+ /// @param return_exprs The expression list where the return expression is added.
/// @returns false if emission failed
bool EmitPipelineOutput(std::string var_name,
const Type* var_type,
- ast::AttributeList* decos,
- std::vector<int> index_prefix,
+ AttributeList* decos,
+ utils::Vector<int, 8> index_prefix,
const Type* tip_type,
const Type* forced_member_type,
- ast::StructMemberList* return_members,
- ast::ExpressionList* return_exprs);
+ StructMemberList* return_members,
+ ExpressionList* return_exprs);
/// Updates the attribute list, replacing an existing Location attribute
/// with another having one higher location value. Does nothing if no
/// location attribute exists.
/// Assumes the list contains at most one Location attribute.
/// @param attributes the attribute list to modify
- void IncrementLocation(ast::AttributeList* attributes);
-
- /// Returns the Location attribute, if it exists.
- /// @param attributes the list of attributes to search
- /// @returns the Location attribute, or nullptr if it doesn't exist
- const ast::Attribute* GetLocation(const ast::AttributeList& attributes);
+ void IncrementLocation(AttributeList* attributes);
/// Create an ast::BlockStatement representing the body of the function.
/// This creates the statement stack, which is non-empty for the lifetime
@@ -913,7 +913,7 @@
/// On failure, issues an error and returns an empty expression list.
/// @param image_access the image access instruction
/// @returns an ExpressionList of the coordinate and array index (if any)
- ast::ExpressionList MakeCoordinateOperandsForImageAccess(
+ ExpressionList MakeCoordinateOperandsForImageAccess(
const spvtools::opt::Instruction& image_access);
/// Returns the given value as an I32. If it's already an I32 then this
@@ -951,11 +951,11 @@
/// Function name
std::string name;
/// Function parameters
- ast::ParameterList params;
+ ParameterList params;
/// Function return type
const Type* return_type;
/// Function attributes
- ast::AttributeList attributes;
+ AttributeList attributes;
};
/// Parse the function declaration, which comprises the name, parameters, and
@@ -1117,8 +1117,8 @@
/// @return the built StatementBuilder
template <typename T, typename... ARGS>
T* AddStatementBuilder(ARGS&&... args) {
- TINT_ASSERT(Reader, !statements_stack_.empty());
- return statements_stack_.back().AddStatementBuilder<T>(std::forward<ARGS>(args)...);
+ TINT_ASSERT(Reader, !statements_stack_.IsEmpty());
+ return statements_stack_.Back().AddStatementBuilder<T>(std::forward<ARGS>(args)...);
}
/// Returns the source record for the given instruction.
@@ -1126,10 +1126,10 @@
/// @return the Source record, or a default one
Source GetSourceForInst(const spvtools::opt::Instruction& inst) const;
- /// @returns the last statetment in the top of the statement stack.
+ /// @returns the last statement in the top of the statement stack.
const ast::Statement* LastStatement();
- using CompletionAction = std::function<void(const ast::StatementList&)>;
+ using CompletionAction = std::function<void(const StatementList&)>;
// A StatementBlock represents a braced-list of statements while it is being
// constructed.
@@ -1181,7 +1181,7 @@
/// @return the list of statements being built, if this construct is not a
/// switch.
- const ast::StatementList& GetStatements() const { return statements_; }
+ const StatementList& GetStatements() const { return statements_; }
private:
/// The construct to which this construct constributes.
@@ -1193,7 +1193,7 @@
/// The completion action finishes processing this statement block.
FunctionEmitter::CompletionAction const completion_action_;
/// The list of statements being built, if this construct is not a switch.
- ast::StatementList statements_;
+ StatementList statements_;
/// Owned statement builders
std::vector<std::unique_ptr<StatementBuilder>> builders_;
@@ -1251,7 +1251,6 @@
return builder_.create<T>(std::forward<ARGS>(args)...);
}
- using StatementsStack = std::vector<StatementBlock>;
using PtrAs = ParserImpl::PtrAs;
ParserImpl& parser_impl_;
@@ -1275,7 +1274,7 @@
// for the entire function. This stack is never empty.
// The `construct` member for the 0th element is only valid during the
// lifetime of the EmitFunctionBodyStatements method.
- StatementsStack statements_stack_;
+ utils::Vector<StatementBlock, 8> statements_stack_;
// The map of IDs that have already had an identifier name generated for it,
// to their Type.
diff --git a/src/tint/reader/spirv/function_call_test.cc b/src/tint/reader/spirv/function_call_test.cc
index 584ad16..6b12ece 100644
--- a/src/tint/reader/spirv/function_call_test.cc
+++ b/src/tint/reader/spirv/function_call_test.cc
@@ -87,13 +87,13 @@
OpFunctionEnd
)"));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
- ast::StatementList f100;
+ utils::Vector<const ast::Statement*, 4> f100;
{
auto fe = p->function_emitter(100);
EXPECT_TRUE(fe.EmitBody()) << p->error();
f100 = fe.ast_body();
}
- ast::StatementList f50;
+ utils::Vector<const ast::Statement*, 4> f50;
{
auto fe = p->function_emitter(50);
EXPECT_TRUE(fe.EmitBody()) << p->error();
@@ -128,13 +128,13 @@
OpFunctionEnd
)"));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
- ast::StatementList f100;
+ utils::Vector<const ast::Statement*, 4> f100;
{
auto fe = p->function_emitter(100);
EXPECT_TRUE(fe.EmitBody()) << p->error();
f100 = fe.ast_body();
}
- ast::StatementList f50;
+ utils::Vector<const ast::Statement*, 4> f50;
{
auto fe = p->function_emitter(50);
EXPECT_TRUE(fe.EmitBody()) << p->error();
diff --git a/src/tint/reader/spirv/function_cfg_test.cc b/src/tint/reader/spirv/function_cfg_test.cc
index efeeee8..fb5aff7 100644
--- a/src/tint/reader/spirv/function_cfg_test.cc
+++ b/src/tint/reader/spirv/function_cfg_test.cc
@@ -2894,8 +2894,8 @@
fe.ComputeBlockOrderAndPositions();
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
- EXPECT_EQ(fe.constructs().size(), 1u);
- auto& c = fe.constructs().front();
+ EXPECT_EQ(fe.constructs().Length(), 1u);
+ auto& c = fe.constructs().Front();
EXPECT_THAT(ToString(c), Eq("Construct{ Function [0,1) begin_id:10 end_id:0 "
"depth:0 parent:null }"));
EXPECT_EQ(fe.GetBlockInfo(10)->construct, c.get());
@@ -2920,8 +2920,8 @@
fe.ComputeBlockOrderAndPositions();
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
- EXPECT_EQ(fe.constructs().size(), 1u);
- auto& c = fe.constructs().front();
+ EXPECT_EQ(fe.constructs().Length(), 1u);
+ auto& c = fe.constructs().Front();
EXPECT_THAT(ToString(c), Eq("Construct{ Function [0,2) begin_id:10 end_id:0 "
"depth:0 parent:null }"));
EXPECT_EQ(fe.GetBlockInfo(10)->construct, c.get());
@@ -2955,7 +2955,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 2u);
+ EXPECT_EQ(constructs.Length(), 2u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,4) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ IfSelection [0,3) begin_id:10 end_id:99 depth:1 parent:Function@10 }
@@ -3001,7 +3001,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 2u);
+ EXPECT_EQ(constructs.Length(), 2u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,6) begin_id:5 end_id:0 depth:0 parent:null }
Construct{ IfSelection [1,4) begin_id:10 end_id:99 depth:1 parent:Function@5 }
@@ -3045,7 +3045,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 2u);
+ EXPECT_EQ(constructs.Length(), 2u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,5) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ SwitchSelection [0,4) begin_id:10 end_id:99 depth:1 parent:Function@10 in-c-l-s:SwitchSelection@10 }
@@ -3082,7 +3082,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 2u);
+ EXPECT_EQ(constructs.Length(), 2u);
// A single-block loop consists *only* of a continue target with one block in
// it.
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
@@ -3188,7 +3188,7 @@
EXPECT_EQ(fe.GetBlockInfo(40)->construct, constructs[1].get());
EXPECT_EQ(fe.GetBlockInfo(50)->construct, constructs[1].get());
EXPECT_EQ(fe.GetBlockInfo(99)->construct, constructs[0].get());
-
+
// SPIR-V 1.6 Rev 2 made this invalid SPIR-V.
p->DeliberatelyInvalidSpirv();
}
@@ -3223,7 +3223,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 3u);
+ EXPECT_EQ(constructs.Length(), 3u);
// A single-block loop consists *only* of a continue target with one block in
// it.
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
@@ -3271,7 +3271,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 4u);
+ EXPECT_EQ(constructs.Length(), 4u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,5) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ IfSelection [0,2) begin_id:10 end_id:50 depth:1 parent:Function@10 }
@@ -3330,7 +3330,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 4u);
+ EXPECT_EQ(constructs.Length(), 4u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,9) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ IfSelection [0,8) begin_id:10 end_id:99 depth:1 parent:Function@10 }
@@ -3390,7 +3390,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 4u);
+ EXPECT_EQ(constructs.Length(), 4u);
// The ordering among siblings depends on the computed block order.
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,8) begin_id:10 end_id:0 depth:0 parent:null }
@@ -3440,7 +3440,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 3u);
+ EXPECT_EQ(constructs.Length(), 3u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,5) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ IfSelection [0,4) begin_id:10 end_id:99 depth:1 parent:Function@10 }
@@ -3494,7 +3494,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 4u);
+ EXPECT_EQ(constructs.Length(), 4u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,8) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ Continue [4,6) begin_id:50 end_id:89 depth:1 parent:Function@10 in-c:Continue@50 }
@@ -3549,7 +3549,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 4u);
+ EXPECT_EQ(constructs.Length(), 4u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,7) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ Continue [5,6) begin_id:80 end_id:99 depth:1 parent:Function@10 in-c:Continue@80 }
@@ -3600,7 +3600,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 4u);
+ EXPECT_EQ(constructs.Length(), 4u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,6) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ Continue [2,5) begin_id:30 end_id:99 depth:1 parent:Function@10 in-c:Continue@30 }
@@ -3644,7 +3644,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 3u);
+ EXPECT_EQ(constructs.Length(), 3u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,4) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ IfSelection [0,3) begin_id:10 end_id:99 depth:1 parent:Function@10 }
@@ -3693,7 +3693,7 @@
fe.RegisterMerges();
EXPECT_TRUE(fe.LabelControlFlowConstructs());
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 4u);
+ EXPECT_EQ(constructs.Length(), 4u);
EXPECT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,7) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ IfSelection [0,6) begin_id:10 end_id:99 depth:1 parent:Function@10 }
@@ -3743,7 +3743,7 @@
auto fe = p->function_emitter(100);
ASSERT_TRUE(FlowLabelControlFlowConstructs(&fe)) << p->error();
const auto& constructs = fe.constructs();
- EXPECT_EQ(constructs.size(), 4u);
+ EXPECT_EQ(constructs.Length(), 4u);
ASSERT_THAT(ToString(constructs), Eq(R"(ConstructList{
Construct{ Function [0,6) begin_id:10 end_id:0 depth:0 parent:null }
Construct{ Continue [4,5) begin_id:90 end_id:99 depth:1 parent:Function@10 in-c:Continue@90 }
@@ -4157,7 +4157,7 @@
EXPECT_EQ(bi10->case_head_for, nullptr);
EXPECT_EQ(bi10->default_head_for, nullptr);
EXPECT_FALSE(bi10->default_is_merge);
- EXPECT_EQ(bi10->case_values.get(), nullptr);
+ EXPECT_FALSE(bi10->case_values.has_value());
}
TEST_F(SpvParserCFGTest, FindSwitchCaseHeaders_DefaultIsMerge) {
@@ -4192,7 +4192,7 @@
ASSERT_NE(bi99->default_head_for, nullptr);
EXPECT_EQ(bi99->default_head_for->begin_id, 10u);
EXPECT_TRUE(bi99->default_is_merge);
- EXPECT_EQ(bi99->case_values.get(), nullptr);
+ EXPECT_FALSE(bi99->case_values.has_value());
}
TEST_F(SpvParserCFGTest, FindSwitchCaseHeaders_DefaultIsNotMerge) {
@@ -4230,7 +4230,7 @@
ASSERT_NE(bi30->default_head_for, nullptr);
EXPECT_EQ(bi30->default_head_for->begin_id, 10u);
EXPECT_FALSE(bi30->default_is_merge);
- EXPECT_EQ(bi30->case_values.get(), nullptr);
+ EXPECT_FALSE(bi30->case_values.has_value());
}
TEST_F(SpvParserCFGTest, FindSwitchCaseHeaders_CaseIsNotDefault) {
@@ -4268,7 +4268,7 @@
EXPECT_EQ(bi20->case_head_for->begin_id, 10u);
EXPECT_EQ(bi20->default_head_for, nullptr);
EXPECT_FALSE(bi20->default_is_merge);
- EXPECT_THAT(*(bi20->case_values.get()), UnorderedElementsAre(200));
+ EXPECT_THAT(bi20->case_values.value(), UnorderedElementsAre(200));
}
TEST_F(SpvParserCFGTest, FindSwitchCaseHeaders_CaseIsDefault) {
@@ -4303,7 +4303,7 @@
EXPECT_EQ(bi20->case_head_for->begin_id, 10u);
EXPECT_EQ(bi20->default_head_for, bi20->case_head_for);
EXPECT_FALSE(bi20->default_is_merge);
- EXPECT_THAT(*(bi20->case_values.get()), UnorderedElementsAre(200));
+ EXPECT_THAT(bi20->case_values.value(), UnorderedElementsAre(200));
}
TEST_F(SpvParserCFGTest, FindSwitchCaseHeaders_ManyCasesWithSameValue_IsError) {
@@ -4370,7 +4370,7 @@
EXPECT_EQ(bi20->case_head_for->begin_id, 10u);
EXPECT_EQ(bi20->default_head_for, nullptr);
EXPECT_FALSE(bi20->default_is_merge);
- EXPECT_THAT(*(bi20->case_values.get()), UnorderedElementsAre(200, 300));
+ EXPECT_THAT(bi20->case_values.value(), UnorderedElementsAre(200, 300));
}
TEST_F(SpvParserCFGTest, ClassifyCFGEdges_BranchEscapesIfConstruct) {
diff --git a/src/tint/reader/spirv/parser_impl.cc b/src/tint/reader/spirv/parser_impl.cc
index 18d5761..e1bff31 100644
--- a/src/tint/reader/spirv/parser_impl.cc
+++ b/src/tint/reader/spirv/parser_impl.cc
@@ -447,10 +447,10 @@
return "SPIR-V type " + std::to_string(type_id);
}
-ast::AttributeList ParserImpl::ConvertMemberDecoration(uint32_t struct_type_id,
- uint32_t member_index,
- const Type* member_ty,
- const Decoration& decoration) {
+ParserImpl::AttributeList ParserImpl::ConvertMemberDecoration(uint32_t struct_type_id,
+ uint32_t member_index,
+ const Type* member_ty,
+ const Decoration& decoration) {
if (decoration.empty()) {
Fail() << "malformed SPIR-V decoration: it's empty";
return {};
@@ -1067,7 +1067,7 @@
}
// Compute members
- ast::StructMemberList ast_members;
+ utils::Vector<const ast::StructMember*, 8> ast_members;
const auto members = struct_ty->element_types();
if (members.empty()) {
Fail() << "WGSL does not support empty structures. can't convert type: "
@@ -1123,7 +1123,7 @@
}
bool is_non_writable = false;
- ast::AttributeList ast_member_decorations;
+ AttributeList ast_member_decorations;
for (auto& decoration : GetDecorationsForMember(type_id, member_index)) {
if (IsPipelineDecoration(decoration)) {
// IO decorations are handled when emitting the entry point.
@@ -1137,7 +1137,7 @@
auto decos =
ConvertMemberDecoration(type_id, member_index, ast_member_ty, decoration);
for (auto* deco : decos) {
- ast_member_decorations.emplace_back(deco);
+ ast_member_decorations.Push(deco);
}
if (!success_) {
return nullptr;
@@ -1154,10 +1154,10 @@
auto* ast_struct_member = create<ast::StructMember>(
Source{}, builder_.Symbols().Register(member_name), ast_member_ty->Build(builder_),
std::move(ast_member_decorations));
- ast_members.push_back(ast_struct_member);
+ ast_members.Push(ast_struct_member);
}
- if (ast_members.empty()) {
+ if (ast_members.IsEmpty()) {
// All members were likely built-ins. Don't generate an empty AST structure.
return nullptr;
}
@@ -1168,8 +1168,7 @@
// Now make the struct.
auto sym = builder_.Symbols().Register(name);
- auto* ast_struct =
- create<ast::Struct>(Source{}, sym, std::move(ast_members), ast::AttributeList());
+ auto* ast_struct = create<ast::Struct>(Source{}, sym, std::move(ast_members), utils::Empty);
if (num_non_writable_members == members.size()) {
read_only_struct_types_.insert(ast_struct->name);
}
@@ -1358,7 +1357,7 @@
break;
}
if (ast_type && ast_expr) {
- ast::AttributeList spec_id_decos;
+ AttributeList spec_id_decos;
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
const uint32_t id = deco[1];
@@ -1368,7 +1367,7 @@
<< inst.result_id() << " has SpecId " << id;
}
auto* cid = create<ast::IdAttribute>(Source{}, id);
- spec_id_decos.push_back(cid);
+ spec_id_decos.Push(cid);
break;
}
}
@@ -1491,7 +1490,7 @@
ast_constructor = MakeConstantExpression(var.GetSingleWordInOperand(1)).expr;
}
auto* ast_var = MakeVar(var.result_id(), ast_storage_class, ast_store_type, ast_constructor,
- ast::AttributeList{});
+ utils::Empty);
// TODO(dneto): initializers (a.k.a. constructor expression)
if (ast_var) {
builder_.AST().AddGlobalVariable(ast_var);
@@ -1558,7 +1557,7 @@
ast::StorageClass sc,
const Type* storage_type,
const ast::Expression* constructor,
- ast::AttributeList decorations) {
+ AttributeList decorations) {
if (storage_type == nullptr) {
Fail() << "internal error: can't make ast::Variable for null type";
return nullptr;
@@ -1593,14 +1592,13 @@
ast::Let* ParserImpl::MakeLet(uint32_t id, const Type* type, const ast::Expression* constructor) {
auto sym = builder_.Symbols().Register(namer_.Name(id));
- return create<ast::Let>(Source{}, sym, type->Build(builder_), constructor,
- ast::AttributeList{});
+ return create<ast::Let>(Source{}, sym, type->Build(builder_), constructor, utils::Empty);
}
ast::Override* ParserImpl::MakeOverride(uint32_t id,
const Type* type,
const ast::Expression* constructor,
- ast::AttributeList decorations) {
+ AttributeList decorations) {
if (!ConvertDecorationsForVariable(id, &type, &decorations, false)) {
return nullptr;
}
@@ -1610,7 +1608,7 @@
ast::Parameter* ParserImpl::MakeParameter(uint32_t id,
const Type* type,
- ast::AttributeList decorations) {
+ AttributeList decorations) {
if (!ConvertDecorationsForVariable(id, &type, &decorations, false)) {
return nullptr;
}
@@ -1621,7 +1619,7 @@
bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
const Type** store_type,
- ast::AttributeList* decorations,
+ AttributeList* decorations,
bool transfer_pipeline_io) {
DecorationList non_builtin_pipeline_decorations;
for (auto& deco : GetDecorationsFor(id)) {
@@ -1681,7 +1679,7 @@
return false;
}
if (transfer_pipeline_io) {
- decorations->emplace_back(create<ast::BuiltinAttribute>(Source{}, ast_builtin));
+ decorations->Push(create<ast::BuiltinAttribute>(Source{}, ast_builtin));
}
}
if (transfer_pipeline_io && IsPipelineDecoration(deco)) {
@@ -1692,13 +1690,13 @@
return Fail() << "malformed DescriptorSet decoration on ID " << id
<< ": has no operand";
}
- decorations->emplace_back(create<ast::GroupAttribute>(Source{}, deco[1]));
+ decorations->Push(create<ast::GroupAttribute>(Source{}, deco[1]));
}
if (deco[0] == SpvDecorationBinding) {
if (deco.size() == 1) {
return Fail() << "malformed Binding decoration on ID " << id << ": has no operand";
}
- decorations->emplace_back(create<ast::BindingAttribute>(Source{}, deco[1]));
+ decorations->Push(create<ast::BindingAttribute>(Source{}, deco[1]));
}
}
@@ -1725,7 +1723,7 @@
return result;
}
-const ast::Attribute* ParserImpl::SetLocation(ast::AttributeList* attributes,
+const ast::Attribute* ParserImpl::SetLocation(AttributeList* attributes,
const ast::Attribute* replacement) {
if (!replacement) {
return nullptr;
@@ -1742,13 +1740,13 @@
}
}
// The list didn't have a location. Add it.
- attributes->push_back(replacement);
+ attributes->Push(replacement);
return nullptr;
}
bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
const DecorationList& decorations,
- ast::AttributeList* attributes) {
+ AttributeList* attributes) {
// Vulkan defaults to perspective-correct interpolation.
ast::InterpolationType type = ast::InterpolationType::kPerspective;
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
@@ -1809,7 +1807,7 @@
sampling == ast::InterpolationSampling::kNone) {
// This is the default. Don't add a decoration.
} else {
- attributes->emplace_back(create<ast::InterpolateAttribute>(type, sampling));
+ attributes->Push(create<ast::InterpolateAttribute>(type, sampling));
}
return success();
@@ -1842,7 +1840,7 @@
auto z = MakeConstantExpression(workgroup_size_builtin_.z_id);
auto* ast_type = ty_.Vector(x.type, 3);
return {ast_type, builder_.Construct(Source{}, ast_type->Build(builder_),
- ast::ExpressionList{x.expr, y.expr, z.expr})};
+ utils::Vector{x.expr, y.expr, z.expr})};
} else if (id == workgroup_size_builtin_.x_id) {
return MakeConstantExpressionForScalarSpirvConstant(
Source{}, ConvertType(workgroup_size_builtin_.component_type_id),
@@ -1898,14 +1896,14 @@
// Handle vector, matrix, array, and struct
// Generate a composite from explicit components.
- ast::ExpressionList ast_components;
+ ExpressionList ast_components;
if (!inst->WhileEachInId([&](const uint32_t* id_ref) -> bool {
auto component = MakeConstantExpression(*id_ref);
if (!component) {
this->Fail() << "invalid constant with ID " << *id_ref;
return false;
}
- ast_components.emplace_back(component.expr);
+ ast_components.Push(component.expr);
return true;
})) {
// We've already emitted a diagnostic.
@@ -1996,9 +1994,9 @@
[&](const Array*) { return builder_.Construct(Source{}, type->Build(builder_)); },
[&](const Bool*) { return create<ast::BoolLiteralExpression>(Source{}, false); },
[&](const Struct* struct_ty) {
- ast::ExpressionList ast_components;
+ ExpressionList ast_components;
for (auto* member : struct_ty->members) {
- ast_components.emplace_back(MakeNullValue(member));
+ ast_components.Push(MakeNullValue(member));
}
return builder_.Construct(Source{}, original_type->Build(builder_),
std::move(ast_components));
diff --git a/src/tint/reader/spirv/parser_impl.h b/src/tint/reader/spirv/parser_impl.h
index ce790d3..12d6226 100644
--- a/src/tint/reader/spirv/parser_impl.h
+++ b/src/tint/reader/spirv/parser_impl.h
@@ -123,6 +123,9 @@
/// Parser implementation for SPIR-V.
class ParserImpl : Reader {
+ using AttributeList = utils::Vector<const ast::Attribute*, 8>;
+ using ExpressionList = utils::Vector<const ast::Expression*, 8>;
+
public:
/// Creates a new parser
/// @param input the input data to parse
@@ -252,15 +255,14 @@
/// a diagnostic), or when the variable should not be emitted, e.g. for a
/// PointSize builtin.
/// @param id the ID of the SPIR-V variable
- /// @param store_type the WGSL store type for the variable, which should be
- /// prepopulatd
+ /// @param store_type the WGSL store type for the variable, which should be prepopulated
/// @param attributes the attribute list to populate
/// @param transfer_pipeline_io true if pipeline IO decorations (builtins,
/// or locations) will update the store type and the decorations list
/// @returns false when the variable should not be emitted as a variable
bool ConvertDecorationsForVariable(uint32_t id,
const Type** store_type,
- ast::AttributeList* attributes,
+ AttributeList* attributes,
bool transfer_pipeline_io);
/// Converts SPIR-V decorations for pipeline IO into AST decorations.
@@ -270,7 +272,7 @@
/// @returns false if conversion fails
bool ConvertPipelineDecorations(const Type* store_type,
const DecorationList& decorations,
- ast::AttributeList* attributes);
+ AttributeList* attributes);
/// Updates the attribute list, placing a non-null location decoration into
/// the list, replacing an existing one if it exists. Does nothing if the
@@ -280,7 +282,7 @@
/// @param replacement the location decoration to place into the list
/// @returns the location decoration that was replaced, if one was replaced,
/// or null otherwise.
- const ast::Attribute* SetLocation(ast::AttributeList* decos, const ast::Attribute* replacement);
+ const ast::Attribute* SetLocation(AttributeList* decos, const ast::Attribute* replacement);
/// Converts a SPIR-V struct member decoration into a number of AST
/// decorations. If the decoration is recognized but deliberately dropped,
@@ -291,10 +293,10 @@
/// @param member_ty the type of the member
/// @param decoration an encoded SPIR-V Decoration
/// @returns the AST decorations
- ast::AttributeList ConvertMemberDecoration(uint32_t struct_type_id,
- uint32_t member_index,
- const Type* member_ty,
- const Decoration& decoration);
+ AttributeList ConvertMemberDecoration(uint32_t struct_type_id,
+ uint32_t member_index,
+ const Type* member_ty,
+ const Decoration& decoration);
/// Returns a string for the given type. If the type ID is invalid,
/// then the resulting string only names the type ID.
@@ -434,7 +436,7 @@
ast::StorageClass sc,
const Type* storage_type,
const ast::Expression* constructor,
- ast::AttributeList decorations);
+ AttributeList decorations);
/// Creates an AST 'let' node for a SPIR-V ID, including any attached decorations,.
/// @param id the SPIR-V result ID
@@ -452,7 +454,7 @@
ast::Override* MakeOverride(uint32_t id,
const Type* type,
const ast::Expression* constructor,
- ast::AttributeList decorations);
+ AttributeList decorations);
/// Creates an AST parameter node for a SPIR-V ID, including any attached decorations, unless
/// it's an ignorable builtin variable.
@@ -460,7 +462,7 @@
/// @param type the type of the parameter
/// @param decorations the parameter decorations
/// @returns the AST parameter node
- ast::Parameter* MakeParameter(uint32_t id, const Type* type, ast::AttributeList decorations);
+ ast::Parameter* MakeParameter(uint32_t id, const Type* type, AttributeList decorations);
/// Returns true if a constant expression can be generated.
/// @param id the SPIR-V ID of the value
diff --git a/src/tint/reader/spirv/parser_impl_barrier_test.cc b/src/tint/reader/spirv/parser_impl_barrier_test.cc
index fdfa3bf..a594098 100644
--- a/src/tint/reader/spirv/parser_impl_barrier_test.cc
+++ b/src/tint/reader/spirv/parser_impl_barrier_test.cc
@@ -65,10 +65,10 @@
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
auto* helper = program.AST().Functions().Find(program.Symbols().Get("helper"));
ASSERT_NE(helper, nullptr);
- ASSERT_GT(helper->body->statements.size(), 0u);
+ ASSERT_GT(helper->body->statements.Length(), 0u);
auto* call = helper->body->statements[0]->As<ast::CallStatement>();
ASSERT_NE(call, nullptr);
- EXPECT_EQ(call->expr->args.size(), 0u);
+ EXPECT_EQ(call->expr->args.Length(), 0u);
auto* sem_call = program.Sem().Get<sem::Call>(call->expr);
ASSERT_NE(sem_call, nullptr);
auto* builtin = sem_call->Target()->As<sem::Builtin>();
@@ -98,10 +98,10 @@
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
auto* helper = program.AST().Functions().Find(program.Symbols().Get("helper"));
ASSERT_NE(helper, nullptr);
- ASSERT_GT(helper->body->statements.size(), 0u);
+ ASSERT_GT(helper->body->statements.Length(), 0u);
auto* call = helper->body->statements[0]->As<ast::CallStatement>();
ASSERT_NE(call, nullptr);
- EXPECT_EQ(call->expr->args.size(), 0u);
+ EXPECT_EQ(call->expr->args.Length(), 0u);
auto* sem_call = program.Sem().Get<sem::Call>(call->expr);
ASSERT_NE(sem_call, nullptr);
auto* builtin = sem_call->Target()->As<sem::Builtin>();
diff --git a/src/tint/reader/spirv/parser_impl_convert_member_decoration_test.cc b/src/tint/reader/spirv/parser_impl_convert_member_decoration_test.cc
index 3147ac1..cd3e7b5 100644
--- a/src/tint/reader/spirv/parser_impl_convert_member_decoration_test.cc
+++ b/src/tint/reader/spirv/parser_impl_convert_member_decoration_test.cc
@@ -20,11 +20,11 @@
using ::testing::Eq;
-TEST_F(SpvParserTest, ConvertMemberDecoration_Empty) {
+TEST_F(SpvParserTest, ConvertMemberDecoration_IsEmpty) {
auto p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(1, 1, nullptr, {});
- EXPECT_TRUE(result.empty());
+ EXPECT_TRUE(result.IsEmpty());
EXPECT_THAT(p->error(), Eq("malformed SPIR-V decoration: it's empty"));
}
@@ -32,7 +32,7 @@
auto p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(12, 13, nullptr, {SpvDecorationOffset});
- EXPECT_TRUE(result.empty());
+ EXPECT_TRUE(result.IsEmpty());
EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal "
"operand, has 0: member 13 of SPIR-V type 12"));
}
@@ -41,7 +41,7 @@
auto p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(12, 13, nullptr, {SpvDecorationOffset, 3, 4});
- EXPECT_TRUE(result.empty());
+ EXPECT_TRUE(result.IsEmpty());
EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal "
"operand, has 2: member 13 of SPIR-V type 12"));
}
@@ -50,7 +50,7 @@
auto p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(1, 1, nullptr, {SpvDecorationOffset, 8});
- ASSERT_FALSE(result.empty());
+ ASSERT_FALSE(result.IsEmpty());
EXPECT_TRUE(result[0]->Is<ast::StructMemberOffsetAttribute>());
auto* offset_deco = result[0]->As<ast::StructMemberOffsetAttribute>();
ASSERT_NE(offset_deco, nullptr);
@@ -64,7 +64,7 @@
spirv::F32 f32;
spirv::Matrix matrix(&f32, 2, 2);
auto result = p->ConvertMemberDecoration(1, 1, &matrix, {SpvDecorationMatrixStride, 8});
- EXPECT_TRUE(result.empty());
+ EXPECT_TRUE(result.IsEmpty());
EXPECT_TRUE(p->error().empty());
}
@@ -74,7 +74,7 @@
spirv::F32 f32;
spirv::Matrix matrix(&f32, 2, 2);
auto result = p->ConvertMemberDecoration(1, 1, &matrix, {SpvDecorationMatrixStride, 16});
- ASSERT_FALSE(result.empty());
+ ASSERT_FALSE(result.IsEmpty());
EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
auto* stride_deco = result[0]->As<ast::StrideAttribute>();
ASSERT_NE(stride_deco, nullptr);
@@ -88,7 +88,7 @@
spirv::F32 f32;
spirv::Matrix matrix(&f32, 2, 4);
auto result = p->ConvertMemberDecoration(1, 1, &matrix, {SpvDecorationMatrixStride, 16});
- EXPECT_TRUE(result.empty());
+ EXPECT_TRUE(result.IsEmpty());
EXPECT_TRUE(p->error().empty());
}
@@ -98,7 +98,7 @@
spirv::F32 f32;
spirv::Matrix matrix(&f32, 2, 4);
auto result = p->ConvertMemberDecoration(1, 1, &matrix, {SpvDecorationMatrixStride, 64});
- ASSERT_FALSE(result.empty());
+ ASSERT_FALSE(result.IsEmpty());
EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
auto* stride_deco = result[0]->As<ast::StrideAttribute>();
ASSERT_NE(stride_deco, nullptr);
@@ -112,7 +112,7 @@
spirv::F32 f32;
spirv::Matrix matrix(&f32, 2, 3);
auto result = p->ConvertMemberDecoration(1, 1, &matrix, {SpvDecorationMatrixStride, 32});
- ASSERT_FALSE(result.empty());
+ ASSERT_FALSE(result.IsEmpty());
EXPECT_TRUE(result[0]->Is<ast::StrideAttribute>());
auto* stride_deco = result[0]->As<ast::StrideAttribute>();
ASSERT_NE(stride_deco, nullptr);
@@ -127,7 +127,7 @@
auto p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(1, 1, nullptr, {SpvDecorationRelaxedPrecision});
- EXPECT_TRUE(result.empty());
+ EXPECT_TRUE(result.IsEmpty());
EXPECT_TRUE(p->error().empty());
}
@@ -135,7 +135,7 @@
auto p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(12, 13, nullptr, {12345678});
- EXPECT_TRUE(result.empty());
+ EXPECT_TRUE(result.IsEmpty());
EXPECT_THAT(p->error(), Eq("unhandled member decoration: 12345678 on member "
"13 of SPIR-V type 12"));
}
diff --git a/src/tint/reader/spirv/parser_impl_handle_test.cc b/src/tint/reader/spirv/parser_impl_handle_test.cc
index 84f3dcb..e1b4889 100644
--- a/src/tint/reader/spirv/parser_impl_handle_test.cc
+++ b/src/tint/reader/spirv/parser_impl_handle_test.cc
@@ -3076,7 +3076,7 @@
ASSERT_NE(anchor, nullptr);
const spvtools::opt::Instruction& image_access = *(anchor->PreviousNode());
- ast::ExpressionList result = fe.MakeCoordinateOperandsForImageAccess(image_access);
+ auto result = fe.MakeCoordinateOperandsForImageAccess(image_access);
if (GetParam().expected_error.empty()) {
EXPECT_TRUE(fe.success()) << p->error();
EXPECT_TRUE(p->error().empty());
@@ -3090,7 +3090,7 @@
} else {
EXPECT_FALSE(fe.success());
EXPECT_THAT(p->error(), Eq(GetParam().expected_error)) << assembly;
- EXPECT_TRUE(result.empty());
+ EXPECT_TRUE(result.IsEmpty());
}
}
diff --git a/src/tint/reader/spirv/parser_impl_test_helper.cc b/src/tint/reader/spirv/parser_impl_test_helper.cc
index 1e52d81..e6249849 100644
--- a/src/tint/reader/spirv/parser_impl_test_helper.cc
+++ b/src/tint/reader/spirv/parser_impl_test_helper.cc
@@ -39,7 +39,7 @@
return writer.result();
}
-std::string ToString(const Program& program, const ast::StatementList& stmts) {
+std::string ToString(const Program& program, utils::VectorRef<const ast::Statement*> stmts) {
writer::wgsl::GeneratorImpl writer(&program);
for (const auto* stmt : stmts) {
if (!writer.EmitStatement(stmt)) {
diff --git a/src/tint/reader/spirv/parser_impl_test_helper.h b/src/tint/reader/spirv/parser_impl_test_helper.h
index f2c2dfe..d1b0e35 100644
--- a/src/tint/reader/spirv/parser_impl_test_helper.h
+++ b/src/tint/reader/spirv/parser_impl_test_helper.h
@@ -195,10 +195,10 @@
/// @param member_ty the type of the member
/// @param decoration an encoded SPIR-V Decoration
/// @returns the AST decorations
- ast::AttributeList ConvertMemberDecoration(uint32_t struct_type_id,
- uint32_t member_index,
- const Type* member_ty,
- const Decoration& decoration) {
+ auto ConvertMemberDecoration(uint32_t struct_type_id,
+ uint32_t member_index,
+ const Type* member_ty,
+ const Decoration& decoration) {
return impl_.ConvertMemberDecoration(struct_type_id, member_index, member_ty, decoration);
}
@@ -275,7 +275,7 @@
/// @param program the Program
/// @param stmts the statement list
/// @returns the WGSL printed string of a statement list.
-std::string ToString(const Program& program, const ast::StatementList& stmts);
+std::string ToString(const Program& program, utils::VectorRef<const ast::Statement*> stmts);
/// Returns the WGSL printed string of an AST node.
/// @param program the Program
diff --git a/src/tint/reader/wgsl/lexer.cc b/src/tint/reader/wgsl/lexer.cc
index 778cb3f..0bc19ad 100644
--- a/src/tint/reader/wgsl/lexer.cc
+++ b/src/tint/reader/wgsl/lexer.cc
@@ -1025,8 +1025,13 @@
type = Token::Type::kGreaterThanEqual;
advance(2);
} else if (matches(pos() + 1, '>')) {
- type = Token::Type::kShiftRight;
- advance(2);
+ if (matches(pos() + 2, '=')) {
+ type = Token::Type::kShiftRightEqual;
+ advance(3);
+ } else {
+ type = Token::Type::kShiftRight;
+ advance(2);
+ }
} else {
type = Token::Type::kGreaterThan;
advance(1);
@@ -1036,8 +1041,13 @@
type = Token::Type::kLessThanEqual;
advance(2);
} else if (matches(pos() + 1, '<')) {
- type = Token::Type::kShiftLeft;
- advance(2);
+ if (matches(pos() + 2, '=')) {
+ type = Token::Type::kShiftLeftEqual;
+ advance(3);
+ } else {
+ type = Token::Type::kShiftLeft;
+ advance(2);
+ }
} else {
type = Token::Type::kLessThan;
advance(1);
@@ -1185,9 +1195,6 @@
if (str == "if") {
return {Token::Type::kIf, source, "if"};
}
- if (str == "import") {
- return {Token::Type::kImport, source, "import"};
- }
if (str == "let") {
return {Token::Type::kLet, source, "let"};
}
@@ -1236,6 +1243,9 @@
if (str == "sampler_comparison") {
return {Token::Type::kComparisonSampler, source, "sampler_comparison"};
}
+ if (str == "static_assert") {
+ return {Token::Type::kStaticAssert, source, "static_assert"};
+ }
if (str == "struct") {
return {Token::Type::kStruct, source, "struct"};
}
diff --git a/src/tint/reader/wgsl/lexer_test.cc b/src/tint/reader/wgsl/lexer_test.cc
index f82045a..6cac798 100644
--- a/src/tint/reader/wgsl/lexer_test.cc
+++ b/src/tint/reader/wgsl/lexer_test.cc
@@ -1049,7 +1049,9 @@
TokenData{"%=", Token::Type::kModuloEqual},
TokenData{"&=", Token::Type::kAndEqual},
TokenData{"|=", Token::Type::kOrEqual},
- TokenData{"^=", Token::Type::kXorEqual}));
+ TokenData{"^=", Token::Type::kXorEqual},
+ TokenData{">>=", Token::Type::kShiftRightEqual},
+ TokenData{"<<=", Token::Type::kShiftLeftEqual}));
using SplittablePunctuationTest = testing::TestWithParam<TokenData>;
TEST_P(SplittablePunctuationTest, Parses) {
@@ -1127,7 +1129,6 @@
TokenData{"for", Token::Type::kFor},
TokenData{"i32", Token::Type::kI32},
TokenData{"if", Token::Type::kIf},
- TokenData{"import", Token::Type::kImport},
TokenData{"let", Token::Type::kLet},
TokenData{"loop", Token::Type::kLoop},
TokenData{"mat2x2", Token::Type::kMat2x2},
@@ -1144,6 +1145,7 @@
TokenData{"return", Token::Type::kReturn},
TokenData{"sampler", Token::Type::kSampler},
TokenData{"sampler_comparison", Token::Type::kComparisonSampler},
+ TokenData{"static_assert", Token::Type::kStaticAssert},
TokenData{"struct", Token::Type::kStruct},
TokenData{"switch", Token::Type::kSwitch},
TokenData{"texture_1d", Token::Type::kTextureSampled1d},
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index 59f4fac..bf26f8e 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -62,32 +62,42 @@
/// parser on error.
constexpr size_t const kMaxResynchronizeLookahead = 32;
-const char kVertexStage[] = "vertex";
-const char kFragmentStage[] = "fragment";
-const char kComputeStage[] = "compute";
-
-const char kReadAccess[] = "read";
-const char kWriteAccess[] = "write";
-const char kReadWriteAccess[] = "read_write";
-
-const char kBindingAttribute[] = "binding";
-const char kBuiltinAttribute[] = "builtin";
-const char kGroupAttribute[] = "group";
-const char kIdAttribute[] = "id";
-const char kInterpolateAttribute[] = "interpolate";
-const char kInvariantAttribute[] = "invariant";
-const char kLocationAttribute[] = "location";
-const char kSizeAttribute[] = "size";
-const char kAlignAttribute[] = "align";
-const char kStageAttribute[] = "stage";
-const char kWorkgroupSizeAttribute[] = "workgroup_size";
-
// https://gpuweb.github.io/gpuweb/wgsl.html#reserved-keywords
bool is_reserved(const Token& t) {
- return t == "asm" || t == "bf16" || t == "do" || t == "enum" || t == "f64" || t == "handle" ||
- t == "i8" || t == "i16" || t == "i64" || t == "mat" || t == "premerge" ||
- t == "regardless" || t == "typedef" || t == "u8" || t == "u16" || t == "u64" ||
- t == "unless" || t == "using" || t == "vec" || t == "void" || t == "while";
+ return t == "CompileShader" || t == "ComputeShader" || t == "DomainShader" ||
+ t == "GeometryShader" || t == "Hullshader" || t == "NULL" || t == "Self" ||
+ t == "abstract" || t == "active" || t == "alignas" || t == "alignof" || t == "as" ||
+ t == "asm" || t == "asm_fragment" || t == "async" || t == "attribute" || t == "auto" ||
+ t == "await" || t == "become" || t == "binding_array" || t == "cast" || t == "catch" ||
+ t == "class" || t == "co_await" || t == "co_return" || t == "co_yield" ||
+ t == "coherent" || t == "column_major" || t == "common" || t == "compile" ||
+ t == "compile_fragment" || t == "concept" || t == "const_cast" || t == "consteval" ||
+ t == "constexpr" || t == "constinit" || t == "crate" || t == "debugger" ||
+ t == "decltype" || t == "delete" || t == "demote" || t == "demote_to_helper" ||
+ t == "do" || t == "dynamic_cast" || t == "enum" || t == "explicit" || t == "export" ||
+ t == "extends" || t == "extern" || t == "external" || t == "filter" || t == "final" ||
+ t == "finally" || t == "friend" || t == "from" || t == "fxgroup" || t == "get" ||
+ t == "goto" || t == "groupshared" || t == "handle" || t == "highp" || t == "impl" ||
+ t == "implements" || t == "import" || t == "inline" || t == "inout" ||
+ t == "instanceof" || t == "interface" || t == "invariant" || t == "layout" ||
+ t == "line" || t == "lineadj" || t == "lowp" || t == "macro" || t == "macro_rules" ||
+ t == "match" || t == "mediump" || t == "meta" || t == "mod" || t == "module" ||
+ t == "move" || t == "mut" || t == "mutable" || t == "namespace" || t == "new" ||
+ t == "nil" || t == "noexcept" || t == "noinline" || t == "nointerpolation" ||
+ t == "noperspective" || t == "null" || t == "nullptr" || t == "of" || t == "operator" ||
+ t == "package" || t == "packoffset" || t == "partition" || t == "pass" || t == "patch" ||
+ t == "pixelfragment" || t == "point" || t == "precise" || t == "precision" ||
+ t == "premerge" || t == "priv" || t == "protected" || t == "pub" || t == "public" ||
+ t == "readonly" || t == "ref" || t == "regardless" || t == "register" ||
+ t == "reinterpret_cast" || t == "requires" || t == "resource" || t == "restrict" ||
+ t == "self" || t == "set" || t == "shared" || t == "signed" || t == "sizeof" ||
+ t == "smooth" || t == "snorm" || t == "static" || t == "static_cast" || t == "std" ||
+ t == "subroutine" || t == "super" || t == "target" || t == "template" || t == "this" ||
+ t == "thread_local" || t == "throw" || t == "trait" || t == "try" || t == "typedef" ||
+ t == "typeid" || t == "typename" || t == "typeof" || t == "union" || t == "unless" ||
+ t == "unorm" || t == "unsafe" || t == "unsized" || t == "use" || t == "using" ||
+ t == "varying" || t == "virtual" || t == "volatile" || t == "wgsl" || t == "where" ||
+ t == "with" || t == "writeonly" || t == "yield";
}
/// Enter-exit counters for block token types.
@@ -170,9 +180,9 @@
ParserImpl::FunctionHeader::FunctionHeader(Source src,
std::string n,
- ast::ParameterList p,
+ utils::VectorRef<const ast::Parameter*> p,
const ast::Type* ret_ty,
- ast::AttributeList ret_attrs)
+ utils::VectorRef<const ast::Attribute*> ret_attrs)
: source(src),
name(n),
params(std::move(p)),
@@ -310,7 +320,7 @@
}
// 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 +329,9 @@
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 +349,17 @@
}
}
+// global_directive
+// : enable_directive
+Maybe<bool> 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<bool> ParserImpl::enable_directive() {
@@ -405,18 +418,18 @@
// global_decl
// : SEMICOLON
-// | global_variable_decl SEMICLON
+// | global_variable_decl SEMICOLON
// | global_constant_decl SEMICOLON
-// | type_alias SEMICOLON
+// | type_alias_decl SEMICOLON
// | struct_decl
// | function_decl
+// | static_assert_statement SEMICOLON
Maybe<bool> ParserImpl::global_decl() {
if (match(Token::Type::kSemicolon) || match(Token::Type::kEOF)) {
return true;
}
bool errored = false;
-
auto attrs = attribute_list();
if (attrs.errored) {
errored = true;
@@ -443,7 +456,6 @@
if (gc.errored) {
return Failure::kErrored;
}
-
if (gc.matched) {
// Avoid the cost of the string allocation for the common no-error case
if (!peek().Is(Token::Type::kSemicolon)) {
@@ -457,11 +469,10 @@
return true;
}
- auto ta = type_alias();
+ auto ta = type_alias_decl();
if (ta.errored) {
return Failure::kErrored;
}
-
if (ta.matched) {
if (!expect("type alias", Token::Type::kSemicolon)) {
return Failure::kErrored;
@@ -471,13 +482,15 @@
return true;
}
- auto str = struct_decl();
- if (str.errored) {
+ auto assertion = static_assert_statement();
+ if (assertion.errored) {
return Failure::kErrored;
}
-
- if (str.matched) {
- builder_.AST().AddTypeDecl(str.value);
+ if (assertion.matched) {
+ builder_.AST().AddStaticAssert(assertion.value);
+ if (!expect("static assertion declaration", Token::Type::kSemicolon)) {
+ return Failure::kErrored;
+ }
return true;
}
@@ -491,6 +504,15 @@
return expect_attributes_consumed(attrs.value);
}
+ auto str = struct_decl();
+ if (str.errored) {
+ errored = true;
+ }
+ if (str.matched) {
+ builder_.AST().AddTypeDecl(str.value);
+ return true;
+ }
+
auto func = function_decl(attrs.value);
if (func.errored) {
errored = true;
@@ -507,7 +529,7 @@
// Invalid syntax found - try and determine the best error message
// We have attributes parsed, but nothing to consume them?
- if (attrs.value.size() > 0) {
+ if (attrs.value.Length() > 0) {
return add_error(next(), "expected declaration after attributes");
}
@@ -538,9 +560,8 @@
}
// global_variable_decl
-// : variable_attribute_list* variable_decl
-// | variable_attribute_list* variable_decl EQUAL const_expr
-Maybe<const ast::Variable*> ParserImpl::global_variable_decl(ast::AttributeList& attrs) {
+// : variable_attribute_list* variable_decl (EQUAL expression)?
+Maybe<const ast::Variable*> ParserImpl::global_variable_decl(AttributeList& attrs) {
auto decl = variable_decl();
if (decl.errored) {
return Failure::kErrored;
@@ -549,24 +570,26 @@
return Failure::kNoMatch;
}
- const ast::Expression* initalizer = nullptr;
+ const ast::Expression* initializer = nullptr;
if (match(Token::Type::kEqual)) {
- auto expr = logical_or_expression();
+ auto expr = expression();
if (expr.errored) {
return Failure::kErrored;
}
if (!expr.matched) {
- return add_error(peek(), "missing initalizer for 'var' declaration");
+ return add_error(peek(), "missing initializer for 'var' declaration");
}
- initalizer = expr.value;
+ initializer = expr.value;
}
+ TINT_DEFER(attrs.Clear());
+
return create<ast::Var>(decl->source, // source
builder_.Symbols().Register(decl->name), // symbol
decl->type, // type
decl->storage_class, // storage class
decl->access, // access control
- initalizer, // initializer
+ initializer, // initializer
std::move(attrs)); // attributes
}
@@ -575,7 +598,7 @@
// | attribute* override (ident | variable_ident_decl) (equal expression)?
// global_const_initializer
// : EQUAL const_expr
-Maybe<const ast::Variable*> ParserImpl::global_constant_decl(ast::AttributeList& attrs) {
+Maybe<const ast::Variable*> ParserImpl::global_constant_decl(AttributeList& attrs) {
bool is_const = false;
bool is_overridable = false;
const char* use = nullptr;
@@ -592,7 +615,7 @@
return Failure::kNoMatch;
}
- auto decl = expect_variable_ident_decl(use, /* allow_inferred = */ true);
+ auto decl = expect_ident_or_variable_ident_decl(use);
if (decl.errored) {
return Failure::kErrored;
}
@@ -609,7 +632,7 @@
const ast::Expression* initializer = nullptr;
if (has_initializer) {
- auto expr = logical_or_expression();
+ auto expr = expression();
if (expr.errored) {
return Failure::kErrored;
}
@@ -619,6 +642,8 @@
initializer = std::move(expr.value);
}
+ TINT_DEFER(attrs.Clear());
+
if (is_const) {
return create<ast::Const>(decl->source, // source
builder_.Symbols().Register(decl->name), // symbol
@@ -641,7 +666,7 @@
}
// variable_decl
-// : VAR variable_qualifier? variable_ident_decl
+// : VAR variable_qualifier? (ident | variable_ident_decl)
Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl() {
Source source;
if (!match(Token::Type::kVar, &source)) {
@@ -657,8 +682,7 @@
vq = explicit_vq.value;
}
- auto decl = expect_variable_ident_decl("variable declaration",
- /*allow_inferred = */ true);
+ auto decl = expect_ident_or_variable_ident_decl("variable declaration");
if (decl.errored) {
return Failure::kErrored;
}
@@ -894,10 +918,9 @@
return fmt;
}
-// variable_ident_decl
-// : IDENT COLON type_decl
-Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(std::string_view use,
- bool allow_inferred) {
+Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_ident_or_variable_ident_decl_impl(
+ std::string_view use,
+ bool allow_inferred) {
auto ident = expect_ident(use);
if (ident.errored) {
return Failure::kErrored;
@@ -923,19 +946,35 @@
return TypedIdentifier{type.value, ident.value, ident.source};
}
+// (ident | variable_ident_decl)
+Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_ident_or_variable_ident_decl(
+ std::string_view use) {
+ return expect_ident_or_variable_ident_decl_impl(use, true);
+}
+
+// variable_ident_decl
+// : IDENT COLON type_decl
+Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(std::string_view use) {
+ return expect_ident_or_variable_ident_decl_impl(use, false);
+}
+
+// access_mode
+// : 'read'
+// | 'write'
+// | 'read_write'
Expect<ast::Access> ParserImpl::expect_access(std::string_view use) {
auto ident = expect_ident(use);
if (ident.errored) {
return Failure::kErrored;
}
- if (ident.value == kReadAccess) {
+ if (ident.value == "read") {
return {ast::Access::kRead, ident.source};
}
- if (ident.value == kWriteAccess) {
+ if (ident.value == "write") {
return {ast::Access::kWrite, ident.source};
}
- if (ident.value == kReadWriteAccess) {
+ if (ident.value == "read_write") {
return {ast::Access::kReadWrite, ident.source};
}
@@ -952,7 +991,7 @@
auto* use = "variable declaration";
auto vq = expect_lt_gt_block(use, [&]() -> Expect<VariableQualifier> {
auto source = make_source_range();
- auto sc = expect_storage_class(use);
+ auto sc = expect_address_space(use);
if (sc.errored) {
return Failure::kErrored;
}
@@ -974,9 +1013,9 @@
return vq;
}
-// type_alias
+// type_alias_decl
// : TYPE IDENT EQUAL type_decl
-Maybe<const ast::Alias*> ParserImpl::type_alias() {
+Maybe<const ast::Alias*> ParserImpl::type_alias_decl() {
if (!peek_is(Token::Type::kType)) {
return Failure::kNoMatch;
}
@@ -1014,10 +1053,8 @@
// | VEC3 LESS_THAN type_decl GREATER_THAN
// | VEC4 LESS_THAN type_decl GREATER_THAN
// | PTR LESS_THAN storage_class, type_decl (COMMA access_mode)? GREATER_THAN
-// | array_attribute_list* ARRAY LESS_THAN type_decl COMMA
-// INT_LITERAL GREATER_THAN
-// | array_attribute_list* ARRAY LESS_THAN type_decl
-// GREATER_THAN
+// | array_attribute_list* ARRAY LESS_THAN type_decl COMMA INT_LITERAL GREATER_THAN
+// | array_attribute_list* ARRAY LESS_THAN type_decl GREATER_THAN
// | MAT2x2 LESS_THAN type_decl GREATER_THAN
// | MAT2x3 LESS_THAN type_decl GREATER_THAN
// | MAT2x4 LESS_THAN type_decl GREATER_THAN
@@ -1106,7 +1143,7 @@
auto access = ast::Access::kUndefined;
auto subtype = expect_lt_gt_block(use, [&]() -> Expect<const ast::Type*> {
- auto sc = expect_storage_class(use);
+ auto sc = expect_address_space(use);
if (sc.errored) {
return Failure::kErrored;
}
@@ -1238,7 +1275,15 @@
return builder_.ty.mat(make_source_range_from(t.source()), subtype, columns, rows);
}
-Expect<ast::StorageClass> ParserImpl::expect_storage_class(std::string_view use) {
+// address_space
+// : 'function'
+// | 'private'
+// | 'workgroup'
+// | 'uniform'
+// | 'storage'
+//
+// Note, we also parse `push_constant` from the experimental extension
+Expect<ast::StorageClass> ParserImpl::expect_address_space(std::string_view use) {
auto& t = peek();
auto ident = expect_ident("storage class");
if (ident.errored) {
@@ -1273,14 +1318,14 @@
}
auto sym = builder_.Symbols().Register(name.value);
- return create<ast::Struct>(t.source(), sym, std::move(body.value), ast::AttributeList{});
+ return create<ast::Struct>(t.source(), sym, std::move(body.value), utils::Empty);
}
// struct_body_decl
// : BRACE_LEFT (struct_member COMMA)* struct_member COMMA? BRACE_RIGHT
-Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
- return expect_brace_block("struct declaration", [&]() -> Expect<ast::StructMemberList> {
- ast::StructMemberList members;
+Expect<ParserImpl::StructMemberList> ParserImpl::expect_struct_body_decl() {
+ return expect_brace_block("struct declaration", [&]() -> Expect<StructMemberList> {
+ StructMemberList members;
bool errored = false;
while (continue_parsing()) {
// Check for the end of the list.
@@ -1296,7 +1341,7 @@
return Failure::kErrored;
}
} else {
- members.push_back(member.value);
+ members.Push(member.value);
}
if (!match(Token::Type::kComma)) {
@@ -1318,8 +1363,7 @@
return Failure::kErrored;
}
- auto decl = expect_variable_ident_decl("struct member",
- /*allow_inferred = */ false);
+ auto decl = expect_variable_ident_decl("struct member");
if (decl.errored) {
return Failure::kErrored;
}
@@ -1328,9 +1372,29 @@
decl->type, std::move(attrs.value));
}
+// static_assert_statement
+// : STATIC_ASSERT expression
+Maybe<const ast::StaticAssert*> ParserImpl::static_assert_statement() {
+ Source start;
+ if (!match(Token::Type::kStaticAssert, &start)) {
+ return Failure::kNoMatch;
+ }
+
+ auto condition = expression();
+ if (condition.errored) {
+ return Failure::kErrored;
+ }
+ if (!condition.matched) {
+ return add_error(peek(), "unable to parse condition expression");
+ }
+
+ Source source = make_source_range_from(start);
+ return create<ast::StaticAssert>(source, condition.value);
+}
+
// function_decl
-// : function_header body_stmt
-Maybe<const ast::Function*> ParserImpl::function_decl(ast::AttributeList& attrs) {
+// : function_header compound_statement
+Maybe<const ast::Function*> ParserImpl::function_decl(AttributeList& attrs) {
auto header = function_header();
if (header.errored) {
if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) {
@@ -1340,7 +1404,7 @@
// function body. The AST isn't used as we've already errored, but this
// catches any errors inside the body, and can help keep the parser in
// sync.
- expect_body_stmt();
+ expect_compound_statement();
}
return Failure::kErrored;
}
@@ -1350,7 +1414,7 @@
bool errored = false;
- auto body = expect_body_stmt();
+ auto body = expect_compound_statement();
if (body.errored) {
errored = true;
}
@@ -1359,8 +1423,10 @@
return Failure::kErrored;
}
+ TINT_DEFER(attrs.Clear());
+
return create<ast::Function>(header->source, builder_.Symbols().Register(header->name),
- header->params, header->return_type, body.value, attrs,
+ header->params, header->return_type, body.value, std::move(attrs),
header->return_type_attributes);
}
@@ -1395,7 +1461,7 @@
}
const ast::Type* return_type = nullptr;
- ast::AttributeList return_attributes;
+ AttributeList return_attributes;
if (match(Token::Type::kArrow)) {
auto attrs = attribute_list();
@@ -1420,15 +1486,17 @@
return Failure::kErrored;
}
- return FunctionHeader{source, name.value, std::move(params.value), return_type,
- std::move(return_attributes)};
+ return FunctionHeader{
+ source, std::move(name.value), std::move(params.value),
+ return_type, std::move(return_attributes),
+ };
}
// param_list
// :
// | (param COMMA)* param COMMA?
-Expect<ast::ParameterList> ParserImpl::expect_param_list() {
- ast::ParameterList ret;
+Expect<ParserImpl::ParameterList> ParserImpl::expect_param_list() {
+ ParameterList ret;
while (continue_parsing()) {
// Check for the end of the list.
auto& t = peek();
@@ -1440,7 +1508,7 @@
if (param.errored) {
return Failure::kErrored;
}
- ret.push_back(param.value);
+ ret.Push(param.value);
if (!match(Token::Type::kComma)) {
break;
@@ -1455,8 +1523,7 @@
Expect<ast::Parameter*> ParserImpl::expect_param() {
auto attrs = attribute_list();
- auto decl = expect_variable_ident_decl("parameter",
- /*allow_inferred = */ false);
+ auto decl = expect_variable_ident_decl("parameter");
if (decl.errored) {
return Failure::kErrored;
}
@@ -1471,23 +1538,83 @@
// : VERTEX
// | FRAGMENT
// | COMPUTE
+//
+// TODO(crbug.com/tint/1503): Remove when deprecation period is over.
Expect<ast::PipelineStage> ParserImpl::expect_pipeline_stage() {
auto& t = peek();
- if (t == kVertexStage) {
+ if (t == "vertex") {
next(); // Consume the peek
return {ast::PipelineStage::kVertex, t.source()};
}
- if (t == kFragmentStage) {
+ if (t == "fragment") {
next(); // Consume the peek
return {ast::PipelineStage::kFragment, t.source()};
}
- if (t == kComputeStage) {
+ if (t == "compute") {
next(); // Consume the peek
return {ast::PipelineStage::kCompute, t.source()};
}
return add_error(peek(), "invalid value for stage attribute");
}
+// interpolation_sample_name
+// : 'center'
+// | 'centroid'
+// | 'sample'
+Expect<ast::InterpolationSampling> ParserImpl::expect_interpolation_sample_name() {
+ auto ident = expect_ident("interpolation sample name");
+ if (ident.errored) {
+ return Failure::kErrored;
+ }
+
+ if (ident.value == "center") {
+ return {ast::InterpolationSampling::kCenter, ident.source};
+ }
+ if (ident.value == "centroid") {
+ return {ast::InterpolationSampling::kCentroid, ident.source};
+ }
+ if (ident.value == "sample") {
+ return {ast::InterpolationSampling::kSample, ident.source};
+ }
+ return add_error(ident.source, "invalid interpolation sampling");
+}
+
+// interpolation_type_name
+// : 'perspective'
+// | 'linear'
+// | 'flat'
+Expect<ast::InterpolationType> ParserImpl::expect_interpolation_type_name() {
+ auto ident = expect_ident("interpolation type name");
+ if (ident.errored) {
+ return Failure::kErrored;
+ }
+
+ if (ident.value == "perspective") {
+ return {ast::InterpolationType::kPerspective, ident.source};
+ }
+ if (ident.value == "linear") {
+ return {ast::InterpolationType::kLinear, ident.source};
+ }
+ if (ident.value == "flat") {
+ return {ast::InterpolationType::kFlat, ident.source};
+ }
+
+ return add_error(ident.source, "invalid interpolation type");
+}
+
+// builtin_value_name
+// : 'vertex_index'
+// | 'instance_index'
+// | 'position'
+// | 'front_facing'
+// | 'frag_depth'
+// | 'local_invocation_id'
+// | 'local_invocation_index'
+// | 'global_invocation_id'
+// | 'workgroup_id'
+// | 'num_workgroups'
+// | 'sample_index'
+// | 'sample_mask'
Expect<ast::BuiltinValue> ParserImpl::expect_builtin() {
auto ident = expect_ident("builtin");
if (ident.errored) {
@@ -1502,9 +1629,9 @@
return {builtin, ident.source};
}
-// body_stmt
-// : BRACE_LEFT statements BRACE_RIGHT
-Expect<ast::BlockStatement*> ParserImpl::expect_body_stmt() {
+// compound_statement
+// : BRACE_LEFT statement* BRACE_RIGHT
+Expect<ast::BlockStatement*> ParserImpl::expect_compound_statement() {
return expect_brace_block("", [&]() -> Expect<ast::BlockStatement*> {
auto stmts = expect_statements();
if (stmts.errored) {
@@ -1515,10 +1642,10 @@
}
// paren_expression
-// : PAREN_LEFT logical_or_expression PAREN_RIGHT
+// : PAREN_LEFT expression PAREN_RIGHT
Expect<const ast::Expression*> ParserImpl::expect_paren_expression() {
return expect_paren_block("", [&]() -> Expect<const ast::Expression*> {
- auto expr = logical_or_expression();
+ auto expr = expression();
if (expr.errored) {
return Failure::kErrored;
}
@@ -1532,16 +1659,16 @@
// statements
// : statement*
-Expect<ast::StatementList> ParserImpl::expect_statements() {
+Expect<ParserImpl::StatementList> ParserImpl::expect_statements() {
bool errored = false;
- ast::StatementList stmts;
+ StatementList stmts;
while (continue_parsing()) {
auto stmt = statement();
if (stmt.errored) {
errored = true;
} else if (stmt.matched) {
- stmts.emplace_back(stmt.value);
+ stmts.Push(stmt.value);
} else {
break;
}
@@ -1556,30 +1683,20 @@
// statement
// : SEMICOLON
-// | body_stmt?
-// | if_stmt
-// | switch_stmt
-// | loop_stmt
-// | for_stmt
-// | while_stmt
-// | non_block_statement
-// : return_stmt SEMICOLON
-// | func_call_stmt SEMICOLON
-// | variable_stmt SEMICOLON
-// | break_stmt SEMICOLON
-// | continue_stmt SEMICOLON
-// | DISCARD SEMICOLON
-// | assignment_stmt SEMICOLON
-// | increment_stmt SEMICOLON
-// | decrement_stmt SEMICOLON
+// | if_statement
+// | switch_statement
+// | loop_statement
+// | for_statement
+// | while_statement
+// | compound_statement
+// | non_block_statement // Note, we inject an extra rule in here for simpler parsing
Maybe<const ast::Statement*> ParserImpl::statement() {
while (match(Token::Type::kSemicolon)) {
// Skip empty statements
}
- // Non-block statments that error can resynchronize on semicolon.
+ // Non-block statements that error can resynchronize on semicolon.
auto stmt = sync(Token::Type::kSemicolon, [&] { return non_block_statement(); });
-
if (stmt.errored) {
return Failure::kErrored;
}
@@ -1587,7 +1704,7 @@
return stmt;
}
- auto stmt_if = if_stmt();
+ auto stmt_if = if_statement();
if (stmt_if.errored) {
return Failure::kErrored;
}
@@ -1595,7 +1712,7 @@
return stmt_if.value;
}
- auto sw = switch_stmt();
+ auto sw = switch_statement();
if (sw.errored) {
return Failure::kErrored;
}
@@ -1603,7 +1720,7 @@
return sw.value;
}
- auto loop = loop_stmt();
+ auto loop = loop_statement();
if (loop.errored) {
return Failure::kErrored;
}
@@ -1611,7 +1728,7 @@
return loop.value;
}
- auto stmt_for = for_stmt();
+ auto stmt_for = for_statement();
if (stmt_for.errored) {
return Failure::kErrored;
}
@@ -1619,7 +1736,7 @@
return stmt_for.value;
}
- auto stmt_while = while_stmt();
+ auto stmt_while = while_statement();
if (stmt_while.errored) {
return Failure::kErrored;
}
@@ -1628,7 +1745,7 @@
}
if (peek_is(Token::Type::kBraceLeft)) {
- auto body = expect_body_stmt();
+ auto body = expect_compound_statement();
if (body.errored) {
return Failure::kErrored;
}
@@ -1638,19 +1755,20 @@
return Failure::kNoMatch;
}
-// statement (continued)
-// : return_stmt SEMICOLON
-// | func_call_stmt SEMICOLON
-// | variable_stmt SEMICOLON
-// | break_stmt SEMICOLON
-// | continue_stmt SEMICOLON
+// non_block_statement (continued)
+// : return_statement SEMICOLON
+// | func_call_statement SEMICOLON
+// | variable_statement SEMICOLON
+// | break_statement SEMICOLON
+// | continue_statement SEMICOLON
// | DISCARD SEMICOLON
-// | assignment_stmt SEMICOLON
-// | increment_stmt SEMICOLON
-// | decrement_stmt SEMICOLON
+// | assignment_statement SEMICOLON
+// | increment_statement SEMICOLON
+// | decrement_statement SEMICOLON
+// | static_assert_statement SEMICOLON
Maybe<const ast::Statement*> ParserImpl::non_block_statement() {
auto stmt = [&]() -> Maybe<const ast::Statement*> {
- auto ret_stmt = return_stmt();
+ auto ret_stmt = return_statement();
if (ret_stmt.errored) {
return Failure::kErrored;
}
@@ -1658,7 +1776,7 @@
return ret_stmt.value;
}
- auto func = func_call_stmt();
+ auto func = func_call_statement();
if (func.errored) {
return Failure::kErrored;
}
@@ -1666,7 +1784,7 @@
return func.value;
}
- auto var = variable_stmt();
+ auto var = variable_statement();
if (var.errored) {
return Failure::kErrored;
}
@@ -1674,7 +1792,7 @@
return var.value;
}
- auto b = break_stmt();
+ auto b = break_statement();
if (b.errored) {
return Failure::kErrored;
}
@@ -1682,7 +1800,7 @@
return b.value;
}
- auto cont = continue_stmt();
+ auto cont = continue_statement();
if (cont.errored) {
return Failure::kErrored;
}
@@ -1690,7 +1808,13 @@
return cont.value;
}
- auto assign = assignment_stmt();
+ Source source;
+ if (match(Token::Type::kDiscard, &source)) {
+ return create<ast::DiscardStatement>(source);
+ }
+
+ // Note, this covers assignment, increment and decrement
+ auto assign = assignment_statement();
if (assign.errored) {
return Failure::kErrored;
}
@@ -1698,9 +1822,12 @@
return assign.value;
}
- Source source;
- if (match(Token::Type::kDiscard, &source)) {
- return create<ast::DiscardStatement>(source);
+ auto stmt_static_assert = static_assert_statement();
+ if (stmt_static_assert.errored) {
+ return Failure::kErrored;
+ }
+ if (stmt_static_assert.matched) {
+ return stmt_static_assert.value;
}
return Failure::kNoMatch;
@@ -1709,13 +1836,12 @@
if (stmt.matched && !expect(stmt->Name(), Token::Type::kSemicolon)) {
return Failure::kErrored;
}
-
return stmt;
}
-// return_stmt
-// : RETURN logical_or_expression?
-Maybe<const ast::ReturnStatement*> ParserImpl::return_stmt() {
+// return_statement
+// : RETURN expression?
+Maybe<const ast::ReturnStatement*> ParserImpl::return_statement() {
Source source;
if (!match(Token::Type::kReturn, &source)) {
return Failure::kNoMatch;
@@ -1725,7 +1851,7 @@
return create<ast::ReturnStatement>(source, nullptr);
}
- auto expr = logical_or_expression();
+ auto expr = expression();
if (expr.errored) {
return Failure::kErrored;
}
@@ -1734,14 +1860,14 @@
return create<ast::ReturnStatement>(source, expr.value);
}
-// variable_stmt
+// variable_statement
// : variable_decl
-// | variable_decl EQUAL logical_or_expression
-// | CONST variable_ident_decl EQUAL logical_or_expression
-Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
+// | variable_decl EQUAL expression
+// | LET (ident | variable_ident_decl) EQUAL expression
+// | CONST (ident | variable_ident_decl) EQUAL expression
+Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_statement() {
if (match(Token::Type::kConst)) {
- auto decl = expect_variable_ident_decl("'const' declaration",
- /*allow_inferred = */ true);
+ auto decl = expect_ident_or_variable_ident_decl("'const' declaration");
if (decl.errored) {
return Failure::kErrored;
}
@@ -1750,7 +1876,7 @@
return Failure::kErrored;
}
- auto initializer = logical_or_expression();
+ auto initializer = expression();
if (initializer.errored) {
return Failure::kErrored;
}
@@ -1762,14 +1888,13 @@
builder_.Symbols().Register(decl->name), // symbol
decl->type, // type
initializer.value, // initializer
- ast::AttributeList{}); // attributes
+ utils::Empty); // attributes
return create<ast::VariableDeclStatement>(decl->source, const_);
}
if (match(Token::Type::kLet)) {
- auto decl = expect_variable_ident_decl("'let' declaration",
- /*allow_inferred = */ true);
+ auto decl = expect_ident_or_variable_ident_decl("'let' declaration");
if (decl.errored) {
return Failure::kErrored;
}
@@ -1778,7 +1903,7 @@
return Failure::kErrored;
}
- auto initializer = logical_or_expression();
+ auto initializer = expression();
if (initializer.errored) {
return Failure::kErrored;
}
@@ -1790,7 +1915,7 @@
builder_.Symbols().Register(decl->name), // symbol
decl->type, // type
initializer.value, // initializer
- ast::AttributeList{}); // attributes
+ utils::Empty); // attributes
return create<ast::VariableDeclStatement>(decl->source, let);
}
@@ -1805,7 +1930,7 @@
const ast::Expression* initializer = nullptr;
if (match(Token::Type::kEqual)) {
- auto initializer_expr = logical_or_expression();
+ auto initializer_expr = expression();
if (initializer_expr.errored) {
return Failure::kErrored;
}
@@ -1822,17 +1947,17 @@
decl->storage_class, // storage class
decl->access, // access control
initializer, // initializer
- ast::AttributeList{}); // attributes
+ utils::Empty); // attributes
return create<ast::VariableDeclStatement>(var->source, var);
}
-// if_stmt
+// if_statement
// : IF expression compound_stmt ( ELSE else_stmt ) ?
// else_stmt
-// : body_stmt
-// | if_stmt
-Maybe<const ast::IfStatement*> ParserImpl::if_stmt() {
+// : compound_statement
+// | if_statement
+Maybe<const ast::IfStatement*> ParserImpl::if_statement() {
// Parse if-else chains iteratively instead of recursively, to avoid
// stack-overflow for long chains of if-else statements.
@@ -1849,7 +1974,7 @@
return Failure::kNoMatch;
}
- auto condition = logical_or_expression();
+ auto condition = expression();
if (condition.errored) {
return Failure::kErrored;
}
@@ -1857,7 +1982,7 @@
return add_error(peek(), "unable to parse condition expression");
}
- auto body = expect_body_stmt();
+ auto body = expect_compound_statement();
if (body.errored) {
return Failure::kErrored;
}
@@ -1893,7 +2018,7 @@
}
// If it wasn't an "else if", it must just be an "else".
- auto else_body = expect_body_stmt();
+ auto else_body = expect_compound_statement();
if (else_body.errored) {
return Failure::kErrored;
}
@@ -1909,15 +2034,15 @@
return last_stmt->As<ast::IfStatement>();
}
-// switch_stmt
-// : SWITCH paren_expression BRACKET_LEFT switch_body+ BRACKET_RIGHT
-Maybe<const ast::SwitchStatement*> ParserImpl::switch_stmt() {
+// switch_statement
+// : SWITCH expression BRACKET_LEFT switch_body+ BRACKET_RIGHT
+Maybe<const ast::SwitchStatement*> ParserImpl::switch_statement() {
Source source;
if (!match(Token::Type::kSwitch, &source)) {
return Failure::kNoMatch;
}
- auto condition = logical_or_expression();
+ auto condition = expression();
if (condition.errored) {
return Failure::kErrored;
}
@@ -1925,9 +2050,9 @@
return add_error(peek(), "unable to parse selector expression");
}
- auto body = expect_brace_block("switch statement", [&]() -> Expect<ast::CaseStatementList> {
+ auto body = expect_brace_block("switch statement", [&]() -> Expect<CaseStatementList> {
bool errored = false;
- ast::CaseStatementList list;
+ CaseStatementList list;
while (continue_parsing()) {
auto stmt = switch_body();
if (stmt.errored) {
@@ -1937,7 +2062,7 @@
if (!stmt.matched) {
break;
}
- list.push_back(stmt.value);
+ list.Push(stmt.value);
}
if (errored) {
return Failure::kErrored;
@@ -1962,7 +2087,7 @@
auto& t = next();
- ast::CaseSelectorList selector_list;
+ CaseSelectorList selector_list;
if (t.Is(Token::Type::kCase)) {
auto selectors = expect_case_selectors();
if (selectors.errored) {
@@ -1990,8 +2115,8 @@
// case_selectors
// : const_literal (COMMA const_literal)* COMMA?
-Expect<ast::CaseSelectorList> ParserImpl::expect_case_selectors() {
- ast::CaseSelectorList selectors;
+Expect<ParserImpl::CaseSelectorList> ParserImpl::expect_case_selectors() {
+ CaseSelectorList selectors;
while (continue_parsing()) {
auto cond = const_literal();
@@ -2003,14 +2128,14 @@
return add_error(cond.value->source, "invalid case selector must be an integer value");
}
- selectors.push_back(cond.value->As<ast::IntLiteralExpression>());
+ selectors.Push(cond.value->As<ast::IntLiteralExpression>());
if (!match(Token::Type::kComma)) {
break;
}
}
- if (selectors.empty()) {
+ if (selectors.IsEmpty()) {
return add_error(peek(), "unable to parse case selectors");
}
@@ -2022,7 +2147,7 @@
// | statement case_body
// | FALLTHROUGH SEMICOLON
Maybe<const ast::BlockStatement*> ParserImpl::case_body() {
- ast::StatementList stmts;
+ StatementList stmts;
while (continue_parsing()) {
Source source;
if (match(Token::Type::kFallthrough, &source)) {
@@ -2030,7 +2155,12 @@
return Failure::kErrored;
}
- stmts.emplace_back(create<ast::FallthroughStatement>(source));
+ deprecated(source,
+ "fallthrough is set to be removed from WGSL. "
+ "Case can accept multiple selectors if the existing case bodies are empty. "
+ "default is not yet supported in a case selector list.");
+
+ stmts.Push(create<ast::FallthroughStatement>(source));
break;
}
@@ -2042,15 +2172,15 @@
break;
}
- stmts.emplace_back(stmt.value);
+ stmts.Push(stmt.value);
}
return create<ast::BlockStatement>(Source{}, stmts);
}
-// loop_stmt
-// : LOOP BRACKET_LEFT statements continuing_stmt? BRACKET_RIGHT
-Maybe<const ast::LoopStatement*> ParserImpl::loop_stmt() {
+// loop_statement
+// : LOOP BRACKET_LEFT statements continuing_statement? BRACKET_RIGHT
+Maybe<const ast::LoopStatement*> ParserImpl::loop_statement() {
Source source;
if (!match(Token::Type::kLoop, &source)) {
return Failure::kNoMatch;
@@ -2062,7 +2192,7 @@
return Failure::kErrored;
}
- auto continuing = continuing_stmt();
+ auto continuing = continuing_statement();
if (continuing.errored) {
return Failure::kErrored;
}
@@ -2079,10 +2209,10 @@
ForHeader::~ForHeader() = default;
-// (variable_stmt | increment_stmt | decrement_stmt | assignment_stmt |
-// func_call_stmt)?
+// (variable_statement | increment_statement | decrement_statement | assignment_statement |
+// func_call_statement)?
Maybe<const ast::Statement*> ParserImpl::for_header_initializer() {
- auto call = func_call_stmt();
+ auto call = func_call_statement();
if (call.errored) {
return Failure::kErrored;
}
@@ -2090,7 +2220,7 @@
return call.value;
}
- auto var = variable_stmt();
+ auto var = variable_statement();
if (var.errored) {
return Failure::kErrored;
}
@@ -2098,7 +2228,7 @@
return var.value;
}
- auto assign = assignment_stmt();
+ auto assign = assignment_statement();
if (assign.errored) {
return Failure::kErrored;
}
@@ -2109,9 +2239,9 @@
return Failure::kNoMatch;
}
-// (increment_stmt | decrement_stmt | assignment_stmt | func_call_stmt)?
+// (increment_statement | decrement_statement | assignment_statement | func_call_statement)?
Maybe<const ast::Statement*> ParserImpl::for_header_continuing() {
- auto call_stmt = func_call_stmt();
+ auto call_stmt = func_call_statement();
if (call_stmt.errored) {
return Failure::kErrored;
}
@@ -2119,7 +2249,7 @@
return call_stmt.value;
}
- auto assign = assignment_stmt();
+ auto assign = assignment_statement();
if (assign.errored) {
return Failure::kErrored;
}
@@ -2131,10 +2261,10 @@
}
// for_header
-// : (variable_stmt | assignment_stmt | func_call_stmt)?
+// : (variable_statement | assignment_statement | func_call_statement)?
// SEMICOLON
-// logical_or_expression? SEMICOLON
-// (assignment_stmt | func_call_stmt)?
+// expression? SEMICOLON
+// (assignment_statement | func_call_statement)?
Expect<std::unique_ptr<ForHeader>> ParserImpl::expect_for_header() {
auto initializer = for_header_initializer();
if (initializer.errored) {
@@ -2145,7 +2275,7 @@
return Failure::kErrored;
}
- auto condition = logical_or_expression();
+ auto condition = expression();
if (condition.errored) {
return Failure::kErrored;
}
@@ -2164,7 +2294,7 @@
// for_statement
// : FOR PAREN_LEFT for_header PAREN_RIGHT BRACE_LEFT statements BRACE_RIGHT
-Maybe<const ast::ForLoopStatement*> ParserImpl::for_stmt() {
+Maybe<const ast::ForLoopStatement*> ParserImpl::for_statement() {
Source source;
if (!match(Token::Type::kFor, &source)) {
return Failure::kNoMatch;
@@ -2187,13 +2317,13 @@
// while_statement
// : WHILE expression compound_statement
-Maybe<const ast::WhileStatement*> ParserImpl::while_stmt() {
+Maybe<const ast::WhileStatement*> ParserImpl::while_statement() {
Source source;
if (!match(Token::Type::kWhile, &source)) {
return Failure::kNoMatch;
}
- auto condition = logical_or_expression();
+ auto condition = expression();
if (condition.errored) {
return Failure::kErrored;
}
@@ -2201,7 +2331,7 @@
return add_error(peek(), "unable to parse while condition expression");
}
- auto body = expect_body_stmt();
+ auto body = expect_compound_statement();
if (body.errored) {
return Failure::kErrored;
}
@@ -2209,9 +2339,9 @@
return create<ast::WhileStatement>(source, condition.value, body.value);
}
-// func_call_stmt
+// func_call_statement
// : IDENT argument_expression_list
-Maybe<const ast::CallStatement*> ParserImpl::func_call_stmt() {
+Maybe<const ast::CallStatement*> ParserImpl::func_call_statement() {
auto& t = peek();
auto& t2 = peek(1);
if (!t.IsIdentifier() || !t2.Is(Token::Type::kParenLeft)) {
@@ -2233,9 +2363,9 @@
std::move(params.value)));
}
-// break_stmt
+// break_statement
// : BREAK
-Maybe<const ast::BreakStatement*> ParserImpl::break_stmt() {
+Maybe<const ast::BreakStatement*> ParserImpl::break_statement() {
Source source;
if (!match(Token::Type::kBreak, &source)) {
return Failure::kNoMatch;
@@ -2244,9 +2374,9 @@
return create<ast::BreakStatement>(source);
}
-// continue_stmt
+// continue_statement
// : CONTINUE
-Maybe<const ast::ContinueStatement*> ParserImpl::continue_stmt() {
+Maybe<const ast::ContinueStatement*> ParserImpl::continue_statement() {
Source source;
if (!match(Token::Type::kContinue, &source)) {
return Failure::kNoMatch;
@@ -2255,14 +2385,42 @@
return create<ast::ContinueStatement>(source);
}
-// continuing_stmt
-// : CONTINUING body_stmt
-Maybe<const ast::BlockStatement*> ParserImpl::continuing_stmt() {
+// break_if_statement:
+// 'break' 'if' expression semicolon
+Maybe<const ast::Statement*> ParserImpl::break_if_statement() {
+ // TODO(crbug.com/tint/1451): Add support for break-if
+ return Failure::kNoMatch;
+}
+
+// continuing_compound_statement:
+// brace_left statement* break_if_statement? brace_right
+Maybe<const ast::BlockStatement*> ParserImpl::continuing_compound_statement() {
+ return expect_brace_block("", [&]() -> Expect<ast::BlockStatement*> {
+ auto stmts = expect_statements();
+ if (stmts.errored) {
+ return Failure::kErrored;
+ }
+
+ auto break_if = break_if_statement();
+ if (break_if.errored) {
+ return Failure::kErrored;
+ }
+ if (break_if.matched) {
+ stmts.value.Push(break_if.value);
+ }
+
+ return create<ast::BlockStatement>(Source{}, stmts.value);
+ });
+}
+
+// continuing_statement
+// : CONTINUING continuing_compound_statement
+Maybe<const ast::BlockStatement*> ParserImpl::continuing_statement() {
if (!match(Token::Type::kContinuing)) {
- return create<ast::BlockStatement>(Source{}, ast::StatementList{});
+ return create<ast::BlockStatement>(Source{}, utils::Empty);
}
- return expect_body_stmt();
+ return continuing_compound_statement();
}
// primary_expression
@@ -2343,7 +2501,7 @@
// postfix_expression
// :
-// | BRACE_LEFT logical_or_expression BRACE_RIGHT postfix_expr
+// | BRACE_LEFT expression BRACE_RIGHT postfix_expr
// | PERIOD IDENTIFIER postfix_expr
Maybe<const ast::Expression*> ParserImpl::postfix_expression(const ast::Expression* prefix) {
Source source;
@@ -2351,7 +2509,7 @@
while (continue_parsing()) {
if (match(Token::Type::kBracketLeft, &source)) {
auto res = sync(Token::Type::kBracketRight, [&]() -> Maybe<const ast::Expression*> {
- auto param = logical_or_expression();
+ auto param = expression();
if (param.errored) {
return Failure::kErrored;
}
@@ -2407,19 +2565,19 @@
}
// argument_expression_list
-// : PAREN_LEFT ((logical_or_expression COMMA)* logical_or_expression COMMA?)?
-// PAREN_RIGHT
-Expect<ast::ExpressionList> ParserImpl::expect_argument_expression_list(std::string_view use) {
- return expect_paren_block(use, [&]() -> Expect<ast::ExpressionList> {
- ast::ExpressionList ret;
+// : PAREN_LEFT ((expression COMMA)* expression COMMA?)? PAREN_RIGHT
+Expect<ParserImpl::ExpressionList> ParserImpl::expect_argument_expression_list(
+ std::string_view use) {
+ return expect_paren_block(use, [&]() -> Expect<ExpressionList> {
+ ExpressionList ret;
while (continue_parsing()) {
- auto arg = logical_or_expression();
+ auto arg = expression();
if (arg.errored) {
return Failure::kErrored;
} else if (!arg.matched) {
break;
}
- ret.push_back(arg.value);
+ ret.Push(arg.value);
if (!match(Token::Type::kComma)) {
break;
@@ -2906,15 +3064,26 @@
return expect_logical_or_expr(lhs.value);
}
-// compound_assignment_operator:
-// | plus_equal
-// | minus_equal
-// | times_equal
-// | division_equal
-// | modulo_equal
-// | and_equal
-// | or_equal
-// | xor_equal
+// expression:
+// : relational_expression
+// | short_circuit_or_expression or_or relational_expression
+// | short_circuit_and_expression and_and relational_expression
+// | bitwise_expression
+Maybe<const ast::Expression*> ParserImpl::expression() {
+ return logical_or_expression();
+}
+
+// compound_assignment_operator
+// : plus_equal
+// | minus_equal
+// | times_equal
+// | division_equal
+// | modulo_equal
+// | and_equal
+// | or_equal
+// | xor_equal
+// | shift_right_equal
+// | shift_left_equal
Maybe<ast::BinaryOp> ParserImpl::compound_assignment_operator() {
ast::BinaryOp compound_op = ast::BinaryOp::kNone;
if (peek_is(Token::Type::kPlusEqual)) {
@@ -2933,6 +3102,10 @@
compound_op = ast::BinaryOp::kOr;
} else if (peek_is(Token::Type::kXorEqual)) {
compound_op = ast::BinaryOp::kXor;
+ } else if (peek_is(Token::Type::kShiftLeftEqual)) {
+ compound_op = ast::BinaryOp::kShiftLeft;
+ } else if (peek_is(Token::Type::kShiftRightEqual)) {
+ compound_op = ast::BinaryOp::kShiftRight;
}
if (compound_op != ast::BinaryOp::kNone) {
next();
@@ -2941,16 +3114,16 @@
return Failure::kNoMatch;
}
-// assignment_stmt
-// | lhs_expression ( equal | compound_assignment_operator ) expression
-// | underscore equal expression
+// assignment_statement
+// | lhs_expression ( EQUAL | compound_assignment_operator ) expression
+// | UNDERSCORE EQUAL expression
//
-// increment_stmt
+// increment_statement
// | lhs_expression PLUS_PLUS
//
-// decrement_stmt
+// decrement_statement
// | lhs_expression MINUS_MINUS
-Maybe<const ast::Statement*> ParserImpl::assignment_stmt() {
+Maybe<const ast::Statement*> ParserImpl::assignment_statement() {
auto& t = peek();
// tint:295 - Test for `ident COLON` - this is invalid grammar, and without
@@ -2992,7 +3165,7 @@
}
}
- auto rhs = logical_or_expression();
+ auto rhs = expression();
if (rhs.errored) {
return Failure::kErrored;
}
@@ -3011,6 +3184,9 @@
// const_literal
// : INT_LITERAL
// | FLOAT_LITERAL
+// | bool_literal
+//
+// bool_literal:
// | TRUE
// | FALSE
Maybe<const ast::LiteralExpression*> ParserImpl::const_literal() {
@@ -3051,16 +3227,16 @@
return Failure::kNoMatch;
}
-Maybe<ast::AttributeList> ParserImpl::attribute_list() {
+Maybe<ParserImpl::AttributeList> ParserImpl::attribute_list() {
bool errored = false;
- ast::AttributeList attrs;
+ AttributeList attrs;
while (continue_parsing()) {
if (match(Token::Type::kAttr)) {
if (auto attr = expect_attribute(); attr.errored) {
errored = true;
} else {
- attrs.emplace_back(attr.value);
+ attrs.Push(attr.value);
}
} else {
break;
@@ -3071,7 +3247,7 @@
return Failure::kErrored;
}
- if (attrs.empty()) {
+ if (attrs.IsEmpty()) {
return Failure::kNoMatch;
}
@@ -3090,6 +3266,29 @@
return add_error(t, "expected attribute");
}
+// attribute
+// : ATTR 'align' PAREN_LEFT expression attrib_end
+// | ATTR 'binding' PAREN_LEFT expression attrib_end
+// | ATTR 'builtin' PAREN_LEFT builtin_value_name attrib_end
+// | ATTR 'const'
+// | ATTR 'group' PAREN_LEFT expression attrib_end
+// | ATTR 'id' PAREN_LEFT expression attrib_end
+// | ATTR 'interpolate' PAREN_LEFT interpolation_type_name attrib_end
+// | ATTR 'interpolate' PAREN_LEFT interpolation_type_name COMMA
+// interpolation_sample_name attrib_end
+// | ATTR 'invariant'
+// | ATTR 'location' PAREN_LEFT expression attrib_end
+// | ATTR 'size' PAREN_LEFT expression attrib_end
+// | ATTR 'workgroup_size' PAREN_LEFT expression attrib_end
+// | ATTR 'workgroup_size' PAREN_LEFT expression COMMA expression attrib_end
+// | ATTR 'workgroup_size' PAREN_LEFT expression COMMA expression COMMA expression attrib_end
+// | ATTR 'vertex'
+// | ATTR 'fragment'
+// | ATTR 'compute'
+//
+// attrib_end
+// : COMMA? PAREN_RIGHT
+//
Maybe<const ast::Attribute*> ParserImpl::attribute() {
using Result = Maybe<const ast::Attribute*>;
auto& t = next();
@@ -3098,8 +3297,8 @@
return Failure::kNoMatch;
}
- if (t == kLocationAttribute) {
- const char* use = "location attribute";
+ if (t == "align") {
+ const char* use = "align attribute";
return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use);
if (val.errored) {
@@ -3107,11 +3306,11 @@
}
match(Token::Type::kComma);
- return create<ast::LocationAttribute>(t.source(), val.value);
+ return create<ast::StructMemberAlignAttribute>(t.source(), val.value);
});
}
- if (t == kBindingAttribute) {
+ if (t == "binding") {
const char* use = "binding attribute";
return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use);
@@ -3124,7 +3323,29 @@
});
}
- if (t == kGroupAttribute) {
+ if (t == "builtin") {
+ return expect_paren_block("builtin attribute", [&]() -> Result {
+ auto builtin = expect_builtin();
+ if (builtin.errored) {
+ return Failure::kErrored;
+ }
+ match(Token::Type::kComma);
+
+ return create<ast::BuiltinAttribute>(t.source(), builtin.value);
+ });
+ }
+
+ if (t == "compute") {
+ return create<ast::StageAttribute>(t.source(), ast::PipelineStage::kCompute);
+ }
+
+ // Note, `const` is not valid in a WGSL source file, it's internal only
+
+ if (t == "fragment") {
+ return create<ast::StageAttribute>(t.source(), ast::PipelineStage::kFragment);
+ }
+
+ if (t == "group") {
const char* use = "group attribute";
return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use);
@@ -3137,59 +3358,106 @@
});
}
- if (t == kInterpolateAttribute) {
- return expect_paren_block("interpolate attribute", [&]() -> Result {
- ast::InterpolationType type;
- ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
+ if (t == "id") {
+ const char* use = "id attribute";
+ return expect_paren_block(use, [&]() -> Result {
+ auto val = expect_positive_sint(use);
+ if (val.errored) {
+ return Failure::kErrored;
+ }
+ match(Token::Type::kComma);
- auto& type_tok = next();
- if (type_tok == "perspective") {
- type = ast::InterpolationType::kPerspective;
- } else if (type_tok == "linear") {
- type = ast::InterpolationType::kLinear;
- } else if (type_tok == "flat") {
- type = ast::InterpolationType::kFlat;
- } else {
- return add_error(type_tok, "invalid interpolation type");
+ return create<ast::IdAttribute>(t.source(), val.value);
+ });
+ }
+
+ if (t == "interpolate") {
+ return expect_paren_block("interpolate attribute", [&]() -> Result {
+ auto type = expect_interpolation_type_name();
+ if (type.errored) {
+ return Failure::kErrored;
}
+ ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
if (match(Token::Type::kComma)) {
if (!peek_is(Token::Type::kParenRight)) {
- auto& sampling_tok = next();
- if (sampling_tok == "center") {
- sampling = ast::InterpolationSampling::kCenter;
- } else if (sampling_tok == "centroid") {
- sampling = ast::InterpolationSampling::kCentroid;
- } else if (sampling_tok == "sample") {
- sampling = ast::InterpolationSampling::kSample;
- } else {
- return add_error(sampling_tok, "invalid interpolation sampling");
+ auto sample = expect_interpolation_sample_name();
+ if (sample.errored) {
+ return Failure::kErrored;
}
+
+ sampling = sample.value;
match(Token::Type::kComma);
}
}
- return create<ast::InterpolateAttribute>(t.source(), type, sampling);
+ return create<ast::InterpolateAttribute>(t.source(), type.value, sampling);
});
}
- if (t == kInvariantAttribute) {
+ if (t == "invariant") {
return create<ast::InvariantAttribute>(t.source());
}
- if (t == kBuiltinAttribute) {
- return expect_paren_block("builtin attribute", [&]() -> Result {
- auto builtin = expect_builtin();
- if (builtin.errored) {
+ if (t == "location") {
+ const char* use = "location attribute";
+ return expect_paren_block(use, [&]() -> Result {
+ auto val = expect_positive_sint(use);
+ if (val.errored) {
return Failure::kErrored;
}
-
match(Token::Type::kComma);
- return create<ast::BuiltinAttribute>(t.source(), builtin.value);
+
+ return create<ast::LocationAttribute>(t.source(), val.value);
});
}
- if (t == kWorkgroupSizeAttribute) {
+ if (t == "size") {
+ const char* use = "size attribute";
+ return expect_paren_block(use, [&]() -> Result {
+ auto val = expect_positive_sint(use);
+ if (val.errored) {
+ return Failure::kErrored;
+ }
+ match(Token::Type::kComma);
+
+ return create<ast::StructMemberSizeAttribute>(t.source(), val.value);
+ });
+ }
+
+ // TODO(crbug.com/tint/1503): Remove when deprecation period is over.
+ if (t == "stage") {
+ return expect_paren_block("stage attribute", [&]() -> Result {
+ auto stage = expect_pipeline_stage();
+ if (stage.errored) {
+ return Failure::kErrored;
+ }
+
+ std::string warning = "remove stage and use @";
+ switch (stage.value) {
+ case ast::PipelineStage::kVertex:
+ warning += "vertex";
+ break;
+ case ast::PipelineStage::kFragment:
+ warning += "fragment";
+ break;
+ case ast::PipelineStage::kCompute:
+ warning += "compute";
+ break;
+ case ast::PipelineStage::kNone:
+ break;
+ }
+ deprecated(t.source(), warning);
+
+ return create<ast::StageAttribute>(t.source(), stage.value);
+ });
+ }
+
+ if (t == "vertex") {
+ return create<ast::StageAttribute>(t.source(), ast::PipelineStage::kVertex);
+ }
+
+ if (t == "workgroup_size") {
return expect_paren_block("workgroup_size attribute", [&]() -> Result {
const ast::Expression* x = nullptr;
const ast::Expression* y = nullptr;
@@ -3232,88 +3500,11 @@
return create<ast::WorkgroupAttribute>(t.source(), x, y, z);
});
}
-
- // TODO(crbug.com/tint/1503): Remove when deprecation period is over.
- if (t == kStageAttribute) {
- return expect_paren_block("stage attribute", [&]() -> Result {
- auto stage = expect_pipeline_stage();
- if (stage.errored) {
- return Failure::kErrored;
- }
-
- std::string warning = "remove stage and use @";
- switch (stage.value) {
- case ast::PipelineStage::kVertex:
- warning += "vertex";
- break;
- case ast::PipelineStage::kFragment:
- warning += "fragment";
- break;
- case ast::PipelineStage::kCompute:
- warning += "compute";
- break;
- case ast::PipelineStage::kNone:
- break;
- }
- deprecated(t.source(), warning);
-
- return create<ast::StageAttribute>(t.source(), stage.value);
- });
- }
- if (t == kComputeStage) {
- return create<ast::StageAttribute>(t.source(), ast::PipelineStage::kCompute);
- }
- if (t == kVertexStage) {
- return create<ast::StageAttribute>(t.source(), ast::PipelineStage::kVertex);
- }
- if (t == kFragmentStage) {
- return create<ast::StageAttribute>(t.source(), ast::PipelineStage::kFragment);
- }
-
- if (t == kSizeAttribute) {
- const char* use = "size attribute";
- return expect_paren_block(use, [&]() -> Result {
- auto val = expect_positive_sint(use);
- if (val.errored) {
- return Failure::kErrored;
- }
- match(Token::Type::kComma);
-
- return create<ast::StructMemberSizeAttribute>(t.source(), val.value);
- });
- }
-
- if (t == kAlignAttribute) {
- const char* use = "align attribute";
- return expect_paren_block(use, [&]() -> Result {
- auto val = expect_positive_sint(use);
- if (val.errored) {
- return Failure::kErrored;
- }
- match(Token::Type::kComma);
-
- return create<ast::StructMemberAlignAttribute>(t.source(), val.value);
- });
- }
-
- if (t == kIdAttribute) {
- const char* use = "id attribute";
- return expect_paren_block(use, [&]() -> Result {
- auto val = expect_positive_sint(use);
- if (val.errored) {
- return Failure::kErrored;
- }
- match(Token::Type::kComma);
-
- return create<ast::IdAttribute>(t.source(), val.value);
- });
- }
-
return Failure::kNoMatch;
}
-bool ParserImpl::expect_attributes_consumed(ast::AttributeList& in) {
- if (in.empty()) {
+bool ParserImpl::expect_attributes_consumed(utils::VectorRef<const ast::Attribute*> in) {
+ if (in.IsEmpty()) {
return true;
}
add_error(in[0]->source, "unexpected attributes");
@@ -3423,7 +3614,7 @@
next();
if (is_reserved(t)) {
- return add_error(t.source(), "'" + t.to_str() + "' is a reserved keyword");
+ deprecated(t.source(), "'" + t.to_str() + "' is a reserved keyword");
}
return {t.to_str(), t.source()};
diff --git a/src/tint/reader/wgsl/parser_impl.h b/src/tint/reader/wgsl/parser_impl.h
index 3e378c7..14f86d5 100644
--- a/src/tint/reader/wgsl/parser_impl.h
+++ b/src/tint/reader/wgsl/parser_impl.h
@@ -71,6 +71,17 @@
};
public:
+ /// Pre-determined small vector sizes for AST pointers
+ //! @cond Doxygen_Suppress
+ using AttributeList = utils::Vector<const ast::Attribute*, 4>;
+ using CaseSelectorList = utils::Vector<const ast::IntLiteralExpression*, 4>;
+ using CaseStatementList = utils::Vector<const ast::CaseStatement*, 4>;
+ using ExpressionList = utils::Vector<const ast::Expression*, 8>;
+ using ParameterList = utils::Vector<const ast::Parameter*, 8>;
+ using StatementList = utils::Vector<const ast::Statement*, 8>;
+ using StructMemberList = utils::Vector<const ast::StructMember*, 8>;
+ //! @endcond
+
/// Expect is the return type of the parser methods that are expected to
/// return a parsed value of type T, unless there was an parse error.
/// In the case of a parse error the called method will have called
@@ -231,9 +242,9 @@
/// @param ret_attrs return type attributes
FunctionHeader(Source src,
std::string n,
- ast::ParameterList p,
+ utils::VectorRef<const ast::Parameter*> p,
const ast::Type* ret_ty,
- ast::AttributeList ret_attrs);
+ utils::VectorRef<const ast::Attribute*> ret_attrs);
/// Destructor
~FunctionHeader();
/// Assignment operator
@@ -246,11 +257,11 @@
/// Function name
std::string name;
/// Function parameters
- ast::ParameterList params;
+ utils::Vector<const ast::Parameter*, 8> params;
/// Function return type
const ast::Type* return_type = nullptr;
/// Function return type attributes
- ast::AttributeList return_type_attributes;
+ AttributeList return_type_attributes;
};
/// VarDeclInfo contains the parsed information for variable declaration.
@@ -374,6 +385,10 @@
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<bool> 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<bool> enable_directive();
@@ -383,50 +398,61 @@
/// Parses a `global_variable_decl` grammar element with the initial
/// `variable_attribute_list*` provided as `attrs`
/// @returns the variable parsed or nullptr
- /// @param attrs the list of attributes for the variable declaration.
- Maybe<const ast::Variable*> global_variable_decl(ast::AttributeList& attrs);
+ /// @param attrs the list of attributes for the variable declaration. If attributes are consumed
+ /// by the declaration, then this vector is cleared before returning.
+ Maybe<const ast::Variable*> global_variable_decl(AttributeList& attrs);
/// Parses a `global_constant_decl` grammar element with the initial
/// `variable_attribute_list*` provided as `attrs`
/// @returns the const object or nullptr
- /// @param attrs the list of attributes for the constant declaration.
- Maybe<const ast::Variable*> global_constant_decl(ast::AttributeList& attrs);
+ /// @param attrs the list of attributes for the constant declaration. If attributes are consumed
+ /// by the declaration, then this vector is cleared before returning.
+ Maybe<const ast::Variable*> global_constant_decl(AttributeList& attrs);
/// Parses a `variable_decl` grammar element
/// @returns the parsed variable declaration info
Maybe<VarDeclInfo> variable_decl();
- /// Parses a `variable_ident_decl` grammar element, erroring on parse
- /// failure.
+ /// Helper for parsing ident or variable_ident_decl. Should not be called directly,
+ /// use the specific version below.
/// @param use a description of what was being parsed if an error was raised.
- /// @param allow_inferred if true, do not fail if variable decl does not
- /// specify type
+ /// @param allow_inferred allow the identifier to be parsed without a type
+ /// @returns the parsed identifier, and possibly type, or empty otherwise
+ Expect<TypedIdentifier> expect_ident_or_variable_ident_decl_impl(std::string_view use,
+ bool allow_inferred);
+ /// Parses a `ident` or a `variable_ident_decl` grammar element, erroring on parse failure.
+ /// @param use a description of what was being parsed if an error was raised.
+ /// @returns the identifier or empty otherwise.
+ Expect<TypedIdentifier> expect_ident_or_variable_ident_decl(std::string_view use);
+ /// Parses a `variable_ident_decl` grammar element, erroring on parse failure.
+ /// @param use a description of what was being parsed if an error was raised.
/// @returns the identifier and type parsed or empty otherwise
- Expect<TypedIdentifier> expect_variable_ident_decl(std::string_view use, bool allow_inferred);
+ Expect<TypedIdentifier> expect_variable_ident_decl(std::string_view use);
/// Parses a `variable_qualifier` grammar element
/// @returns the variable qualifier information
Maybe<VariableQualifier> variable_qualifier();
- /// Parses a `type_alias` grammar element
+ /// Parses a `type_alias_decl` grammar element
/// @returns the type alias or nullptr on error
- Maybe<const ast::Alias*> type_alias();
+ Maybe<const ast::Alias*> type_alias_decl();
/// Parses a `type_decl` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<const ast::Type*> type_decl();
- /// Parses a `storage_class` grammar element, erroring on parse failure.
+ /// Parses an `address_space` grammar element, erroring on parse failure.
/// @param use a description of what was being parsed if an error was raised.
- /// @returns the storage class or StorageClass::kNone if none matched
- Expect<ast::StorageClass> expect_storage_class(std::string_view use);
+ /// @returns the address space or StorageClass::kNone if none matched
+ Expect<ast::StorageClass> expect_address_space(std::string_view use);
/// Parses a `struct_decl` grammar element.
/// @returns the struct type or nullptr on error
Maybe<const ast::Struct*> struct_decl();
/// Parses a `struct_body_decl` grammar element, erroring on parse failure.
/// @returns the struct members
- Expect<ast::StructMemberList> expect_struct_body_decl();
+ Expect<StructMemberList> expect_struct_body_decl();
/// Parses a `struct_member` grammar element, erroring on parse failure.
/// @returns the struct member or nullptr
Expect<ast::StructMember*> expect_struct_member();
/// Parses a `function_decl` grammar element with the initial
/// `function_attribute_decl*` provided as `attrs`.
- /// @param attrs the list of attributes for the function declaration.
+ /// @param attrs the list of attributes for the function declaration. If attributes are consumed
+ /// by the declaration, then this vector is cleared before returning.
/// @returns the parsed function, nullptr otherwise
- Maybe<const ast::Function*> function_decl(ast::AttributeList& attrs);
+ Maybe<const ast::Function*> function_decl(AttributeList& attrs);
/// Parses a `texture_samplers` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<const ast::Type*> texture_samplers();
@@ -454,12 +480,15 @@
/// @param use a description of what was being parsed if an error was raised
/// @returns returns the texel format or kNone if none matched.
Expect<ast::TexelFormat> expect_texel_format(std::string_view use);
+ /// Parses a `static_assert_statement` grammar element
+ /// @returns returns the static assert, if it matched.
+ Maybe<const ast::StaticAssert*> static_assert_statement();
/// Parses a `function_header` grammar element
/// @returns the parsed function header
Maybe<FunctionHeader> function_header();
/// Parses a `param_list` grammar element, erroring on parse failure.
/// @returns the parsed variables
- Expect<ast::ParameterList> expect_param_list();
+ Expect<ParameterList> expect_param_list();
/// Parses a `param` grammar element, erroring on parse failure.
/// @returns the parsed variable
Expect<ast::Parameter*> expect_param();
@@ -472,67 +501,81 @@
/// @param use a description of what was being parsed if an error was raised
/// @returns the parsed access control.
Expect<ast::Access> expect_access(std::string_view use);
+ /// Parses an interpolation sample name identifier, erroring if the next token does not match a
+ /// valid sample name.
+ /// @returns the parsed sample name.
+ Expect<ast::InterpolationSampling> expect_interpolation_sample_name();
+ /// Parses an interpolation type name identifier, erroring if the next token does not match a
+ /// value type name.
+ /// @returns the parsed type name
+ Expect<ast::InterpolationType> expect_interpolation_type_name();
/// Parses a builtin identifier, erroring if the next token does not match a
/// valid builtin name.
/// @returns the parsed builtin.
Expect<ast::BuiltinValue> expect_builtin();
- /// Parses a `body_stmt` grammar element, erroring on parse failure.
+ /// Parses a `compound_statement` grammar element, erroring on parse failure.
/// @returns the parsed statements
- Expect<ast::BlockStatement*> expect_body_stmt();
+ Expect<ast::BlockStatement*> expect_compound_statement();
/// Parses a `paren_expression` grammar element, erroring on parse failure.
/// @returns the parsed element or nullptr
Expect<const ast::Expression*> expect_paren_expression();
/// Parses a `statements` grammar element
/// @returns the statements parsed
- Expect<ast::StatementList> expect_statements();
+ Expect<StatementList> expect_statements();
/// Parses a `statement` grammar element
/// @returns the parsed statement or nullptr
Maybe<const ast::Statement*> statement();
- /// Parses a `break_stmt` grammar element
+ /// Parses a `break_statement` grammar element
/// @returns the parsed statement or nullptr
- Maybe<const ast::BreakStatement*> break_stmt();
- /// Parses a `return_stmt` grammar element
+ Maybe<const ast::BreakStatement*> break_statement();
+ /// Parses a `return_statement` grammar element
/// @returns the parsed statement or nullptr
- Maybe<const ast::ReturnStatement*> return_stmt();
- /// Parses a `continue_stmt` grammar element
+ Maybe<const ast::ReturnStatement*> return_statement();
+ /// Parses a `continue_statement` grammar element
/// @returns the parsed statement or nullptr
- Maybe<const ast::ContinueStatement*> continue_stmt();
- /// Parses a `variable_stmt` grammar element
+ Maybe<const ast::ContinueStatement*> continue_statement();
+ /// Parses a `variable_statement` grammar element
/// @returns the parsed variable or nullptr
- Maybe<const ast::VariableDeclStatement*> variable_stmt();
- /// Parses a `if_stmt` grammar element
+ Maybe<const ast::VariableDeclStatement*> variable_statement();
+ /// Parses a `if_statement` grammar element
/// @returns the parsed statement or nullptr
- Maybe<const ast::IfStatement*> if_stmt();
- /// Parses a `switch_stmt` grammar element
+ Maybe<const ast::IfStatement*> if_statement();
+ /// Parses a `switch_statement` grammar element
/// @returns the parsed statement or nullptr
- Maybe<const ast::SwitchStatement*> switch_stmt();
+ Maybe<const ast::SwitchStatement*> switch_statement();
/// Parses a `switch_body` grammar element
/// @returns the parsed statement or nullptr
Maybe<const ast::CaseStatement*> switch_body();
/// Parses a `case_selectors` grammar element
/// @returns the list of literals
- Expect<ast::CaseSelectorList> expect_case_selectors();
+ Expect<CaseSelectorList> expect_case_selectors();
/// Parses a `case_body` grammar element
/// @returns the parsed statements
Maybe<const ast::BlockStatement*> case_body();
- /// Parses a `func_call_stmt` grammar element
+ /// Parses a `func_call_statement` grammar element
/// @returns the parsed function call or nullptr
- Maybe<const ast::CallStatement*> func_call_stmt();
- /// Parses a `loop_stmt` grammar element
+ Maybe<const ast::CallStatement*> func_call_statement();
+ /// Parses a `loop_statement` grammar element
/// @returns the parsed loop or nullptr
- Maybe<const ast::LoopStatement*> loop_stmt();
+ Maybe<const ast::LoopStatement*> loop_statement();
/// Parses a `for_header` grammar element, erroring on parse failure.
/// @returns the parsed for header or nullptr
Expect<std::unique_ptr<ForHeader>> expect_for_header();
- /// Parses a `for_stmt` grammar element
+ /// Parses a `for_statement` grammar element
/// @returns the parsed for loop or nullptr
- Maybe<const ast::ForLoopStatement*> for_stmt();
- /// Parses a `while_stmt` grammar element
+ Maybe<const ast::ForLoopStatement*> for_statement();
+ /// Parses a `while_statement` grammar element
/// @returns the parsed while loop or nullptr
- Maybe<const ast::WhileStatement*> while_stmt();
- /// Parses a `continuing_stmt` grammar element
+ Maybe<const ast::WhileStatement*> while_statement();
+ /// Parses a `break_if_statement` grammar element
+ /// @returns the parsed statement or nullptr
+ Maybe<const ast::Statement*> break_if_statement();
+ /// Parses a `continuing_compound_statement` grammar element
/// @returns the parsed statements
- Maybe<const ast::BlockStatement*> continuing_stmt();
+ Maybe<const ast::BlockStatement*> continuing_compound_statement();
+ /// Parses a `continuing_statement` grammar element
+ /// @returns the parsed statements
+ Maybe<const ast::BlockStatement*> continuing_statement();
/// Parses a `const_literal` grammar element
/// @returns the const literal parsed or nullptr if none found
Maybe<const ast::LiteralExpression*> const_literal();
@@ -543,7 +586,7 @@
/// failure.
/// @param use a description of what was being parsed if an error was raised
/// @returns the list of arguments
- Expect<ast::ExpressionList> expect_argument_expression_list(std::string_view use);
+ Expect<ExpressionList> expect_argument_expression_list(std::string_view use);
/// Parses the recursive portion of the postfix_expression
/// @param prefix the left side of the expression
/// @returns the parsed expression or nullptr
@@ -634,15 +677,18 @@
/// Parses a `logical_or_expression` grammar element
/// @returns the parsed expression or nullptr
Maybe<const ast::Expression*> logical_or_expression();
+ /// Parses an `expression` grammar element
+ /// @returns the parsed expression or nullptr
+ Maybe<const ast::Expression*> expression();
/// Parses a `compound_assignment_operator` grammar element
/// @returns the parsed compound assignment operator
Maybe<ast::BinaryOp> compound_assignment_operator();
- /// Parses a `assignment_stmt` grammar element
+ /// Parses a `assignment_statement` grammar element
/// @returns the parsed assignment or nullptr
- Maybe<const ast::Statement*> assignment_stmt();
+ Maybe<const ast::Statement*> assignment_statement();
/// Parses one or more attribute lists.
/// @return the parsed attribute list, or an empty list on error.
- Maybe<ast::AttributeList> attribute_list();
+ Maybe<AttributeList> attribute_list();
/// Parses a single attribute of the following types:
/// * `struct_attribute`
/// * `struct_member_attribute`
@@ -813,7 +859,7 @@
/// Reports an error if the attribute list `list` is not empty.
/// Used to ensure that all attributes are consumed.
- bool expect_attributes_consumed(ast::AttributeList& list);
+ bool expect_attributes_consumed(utils::VectorRef<const ast::Attribute*> list);
Expect<const ast::Type*> expect_type_decl_pointer(const Token& t);
Expect<const ast::Type*> expect_type_decl_atomic(const Token& t);
diff --git a/src/tint/reader/wgsl/parser_impl_argument_expression_list_test.cc b/src/tint/reader/wgsl/parser_impl_argument_expression_list_test.cc
index 3042c20..7f1132c 100644
--- a/src/tint/reader/wgsl/parser_impl_argument_expression_list_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_argument_expression_list_test.cc
@@ -23,7 +23,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
- ASSERT_EQ(e.value.size(), 1u);
+ ASSERT_EQ(e.value.Length(), 1u);
ASSERT_TRUE(e.value[0]->Is<ast::IdentifierExpression>());
}
@@ -33,7 +33,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
- ASSERT_EQ(e.value.size(), 0u);
+ ASSERT_EQ(e.value.Length(), 0u);
}
TEST_F(ParserImplTest, ArgumentExpressionList_ParsesMultiple) {
@@ -42,7 +42,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
- ASSERT_EQ(e.value.size(), 3u);
+ ASSERT_EQ(e.value.Length(), 3u);
ASSERT_TRUE(e.value[0]->Is<ast::IdentifierExpression>());
ASSERT_TRUE(e.value[1]->Is<ast::LiteralExpression>());
ASSERT_TRUE(e.value[2]->Is<ast::BinaryExpression>());
@@ -54,7 +54,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
- ASSERT_EQ(e.value.size(), 2u);
+ ASSERT_EQ(e.value.Length(), 2u);
ASSERT_TRUE(e.value[0]->Is<ast::IdentifierExpression>());
ASSERT_TRUE(e.value[1]->Is<ast::LiteralExpression>());
}
diff --git a/src/tint/reader/wgsl/parser_impl_assignment_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_assignment_stmt_test.cc
index 4fd23ce..4581d98 100644
--- a/src/tint/reader/wgsl/parser_impl_assignment_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_assignment_stmt_test.cc
@@ -19,7 +19,7 @@
TEST_F(ParserImplTest, AssignmentStmt_Parses_ToVariable) {
auto p = parser("a = 123");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -42,7 +42,7 @@
TEST_F(ParserImplTest, AssignmentStmt_Parses_ToMember) {
auto p = parser("a.b.c[2].d = 123");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -92,7 +92,7 @@
TEST_F(ParserImplTest, AssignmentStmt_Parses_ToPhony) {
auto p = parser("_ = 123i");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -111,9 +111,15 @@
ASSERT_TRUE(a->lhs->Is<ast::PhonyExpression>());
}
-TEST_F(ParserImplTest, AssignmentStmt_Parses_CompoundOp) {
- auto p = parser("a += 123u");
- auto e = p->assignment_stmt();
+struct CompoundData {
+ std::string str;
+ ast::BinaryOp op;
+};
+using CompoundOpTest = ParserImplTestWithParam<CompoundData>;
+TEST_P(CompoundOpTest, CompoundOp) {
+ auto params = GetParam();
+ auto p = parser("a " + params.str + " 123u");
+ auto e = p->assignment_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -123,7 +129,7 @@
ASSERT_NE(a, nullptr);
ASSERT_NE(a->lhs, nullptr);
ASSERT_NE(a->rhs, nullptr);
- EXPECT_EQ(a->op, ast::BinaryOp::kAdd);
+ EXPECT_EQ(a->op, params.op);
ASSERT_TRUE(a->lhs->Is<ast::IdentifierExpression>());
auto* ident = a->lhs->As<ast::IdentifierExpression>();
@@ -134,10 +140,22 @@
EXPECT_EQ(a->rhs->As<ast::IntLiteralExpression>()->suffix,
ast::IntLiteralExpression::Suffix::kU);
}
+INSTANTIATE_TEST_SUITE_P(ParserImplTest,
+ CompoundOpTest,
+ testing::Values(CompoundData{"+=", ast::BinaryOp::kAdd},
+ CompoundData{"-=", ast::BinaryOp::kSubtract},
+ CompoundData{"*=", ast::BinaryOp::kMultiply},
+ CompoundData{"/=", ast::BinaryOp::kDivide},
+ CompoundData{"%=", ast::BinaryOp::kModulo},
+ CompoundData{"&=", ast::BinaryOp::kAnd},
+ CompoundData{"|=", ast::BinaryOp::kOr},
+ CompoundData{"^=", ast::BinaryOp::kXor},
+ CompoundData{">>=", ast::BinaryOp::kShiftRight},
+ CompoundData{"<<=", ast::BinaryOp::kShiftLeft}));
TEST_F(ParserImplTest, AssignmentStmt_MissingEqual) {
auto p = parser("a.b.c[2].d 123");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_TRUE(p->has_error());
@@ -147,7 +165,7 @@
TEST_F(ParserImplTest, AssignmentStmt_Compound_MissingEqual) {
auto p = parser("a + 123");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_TRUE(p->has_error());
@@ -157,7 +175,7 @@
TEST_F(ParserImplTest, AssignmentStmt_InvalidLHS) {
auto p = parser("if (true) {} = 123");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_FALSE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -166,7 +184,7 @@
TEST_F(ParserImplTest, AssignmentStmt_InvalidRHS) {
auto p = parser("a.b.c[2].d = if (true) {}");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -176,7 +194,7 @@
TEST_F(ParserImplTest, AssignmentStmt_InvalidCompoundOp) {
auto p = parser("a &&= true");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
diff --git a/src/tint/reader/wgsl/parser_impl_break_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_break_stmt_test.cc
index ca8802a..21c5267 100644
--- a/src/tint/reader/wgsl/parser_impl_break_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_break_stmt_test.cc
@@ -20,7 +20,7 @@
TEST_F(ParserImplTest, BreakStmt) {
auto p = parser("break");
- auto e = p->break_stmt();
+ auto e = p->break_statement();
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
diff --git a/src/tint/reader/wgsl/parser_impl_call_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_call_stmt_test.cc
index d044f8d..59aeb3c 100644
--- a/src/tint/reader/wgsl/parser_impl_call_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_call_stmt_test.cc
@@ -36,7 +36,7 @@
EXPECT_EQ(c->target.name->symbol, p->builder().Symbols().Get("a"));
- EXPECT_EQ(c->args.size(), 0u);
+ EXPECT_EQ(c->args.Length(), 0u);
}
TEST_F(ParserImplTest, Statement_Call_WithParams) {
@@ -52,7 +52,7 @@
EXPECT_EQ(c->target.name->symbol, p->builder().Symbols().Get("a"));
- EXPECT_EQ(c->args.size(), 3u);
+ EXPECT_EQ(c->args.Length(), 3u);
EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>());
EXPECT_TRUE(c->args[1]->Is<ast::IdentifierExpression>());
EXPECT_TRUE(c->args[2]->Is<ast::BinaryExpression>());
@@ -71,7 +71,7 @@
EXPECT_EQ(c->target.name->symbol, p->builder().Symbols().Get("a"));
- EXPECT_EQ(c->args.size(), 2u);
+ EXPECT_EQ(c->args.Length(), 2u);
EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>());
EXPECT_TRUE(c->args[1]->Is<ast::IdentifierExpression>());
}
diff --git a/src/tint/reader/wgsl/parser_impl_case_body_test.cc b/src/tint/reader/wgsl/parser_impl_case_body_test.cc
index f8c07a3..c162be3 100644
--- a/src/tint/reader/wgsl/parser_impl_case_body_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_case_body_test.cc
@@ -24,7 +24,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(e.errored);
EXPECT_TRUE(e.matched);
- EXPECT_EQ(e->statements.size(), 0u);
+ EXPECT_EQ(e->statements.Length(), 0u);
}
TEST_F(ParserImplTest, CaseBody_Statements) {
@@ -36,7 +36,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(e.errored);
EXPECT_TRUE(e.matched);
- ASSERT_EQ(e->statements.size(), 2u);
+ ASSERT_EQ(e->statements.Length(), 2u);
EXPECT_TRUE(e->statements[0]->Is<ast::VariableDeclStatement>());
EXPECT_TRUE(e->statements[1]->Is<ast::AssignmentStatement>());
}
@@ -56,7 +56,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(e.errored);
EXPECT_TRUE(e.matched);
- ASSERT_EQ(e->statements.size(), 1u);
+ ASSERT_EQ(e->statements.Length(), 1u);
EXPECT_TRUE(e->statements[0]->Is<ast::FallthroughStatement>());
}
diff --git a/src/tint/reader/wgsl/parser_impl_body_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_compound_stmt_test.cc
similarity index 76%
rename from src/tint/reader/wgsl/parser_impl_body_stmt_test.cc
rename to src/tint/reader/wgsl/parser_impl_compound_stmt_test.cc
index f84a5ba..947cb48 100644
--- a/src/tint/reader/wgsl/parser_impl_body_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_compound_stmt_test.cc
@@ -18,38 +18,38 @@
namespace tint::reader::wgsl {
namespace {
-TEST_F(ParserImplTest, BodyStmt) {
+TEST_F(ParserImplTest, CompoundStmt) {
auto p = parser(R"({
discard;
return 1 + b / 2;
})");
- auto e = p->expect_body_stmt();
+ auto e = p->expect_compound_statement();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
- ASSERT_EQ(e->statements.size(), 2u);
+ ASSERT_EQ(e->statements.Length(), 2u);
EXPECT_TRUE(e->statements[0]->Is<ast::DiscardStatement>());
EXPECT_TRUE(e->statements[1]->Is<ast::ReturnStatement>());
}
-TEST_F(ParserImplTest, BodyStmt_Empty) {
+TEST_F(ParserImplTest, CompoundStmt_Empty) {
auto p = parser("{}");
- auto e = p->expect_body_stmt();
+ auto e = p->expect_compound_statement();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
- EXPECT_EQ(e->statements.size(), 0u);
+ EXPECT_EQ(e->statements.Length(), 0u);
}
-TEST_F(ParserImplTest, BodyStmt_InvalidStmt) {
+TEST_F(ParserImplTest, CompoundStmt_InvalidStmt) {
auto p = parser("{fn main() {}}");
- auto e = p->expect_body_stmt();
+ auto e = p->expect_compound_statement();
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(e.errored);
EXPECT_EQ(p->error(), "1:2: expected '}'");
}
-TEST_F(ParserImplTest, BodyStmt_MissingRightParen) {
+TEST_F(ParserImplTest, CompoundStmt_MissingRightParen) {
auto p = parser("{return;");
- auto e = p->expect_body_stmt();
+ auto e = p->expect_compound_statement();
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(e.errored);
EXPECT_EQ(p->error(), "1:9: expected '}'");
diff --git a/src/tint/reader/wgsl/parser_impl_continue_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_continue_stmt_test.cc
index 002f638..349bf5e 100644
--- a/src/tint/reader/wgsl/parser_impl_continue_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_continue_stmt_test.cc
@@ -20,7 +20,7 @@
TEST_F(ParserImplTest, ContinueStmt) {
auto p = parser("continue");
- auto e = p->continue_stmt();
+ auto e = p->continue_statement();
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
diff --git a/src/tint/reader/wgsl/parser_impl_continuing_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_continuing_stmt_test.cc
index d7a5779..d2113af 100644
--- a/src/tint/reader/wgsl/parser_impl_continuing_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_continuing_stmt_test.cc
@@ -20,17 +20,17 @@
TEST_F(ParserImplTest, ContinuingStmt) {
auto p = parser("continuing { discard; }");
- auto e = p->continuing_stmt();
+ auto e = p->continuing_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
- ASSERT_EQ(e->statements.size(), 1u);
+ ASSERT_EQ(e->statements.Length(), 1u);
ASSERT_TRUE(e->statements[0]->Is<ast::DiscardStatement>());
}
TEST_F(ParserImplTest, ContinuingStmt_InvalidBody) {
auto p = parser("continuing { discard }");
- auto e = p->continuing_stmt();
+ auto e = p->continuing_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
diff --git a/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc b/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
index 240ab38..ed57be8 100644
--- a/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
@@ -28,10 +28,10 @@
EXPECT_FALSE(p->has_error()) << p->error();
auto program = p->program();
auto& ast = program.AST();
- ASSERT_EQ(ast.Enables().size(), 1u);
+ ASSERT_EQ(ast.Enables().Length(), 1u);
auto* enable = ast.Enables()[0];
EXPECT_EQ(enable->extension, ast::Extension::kF16);
- ASSERT_EQ(ast.GlobalDeclarations().size(), 1u);
+ ASSERT_EQ(ast.GlobalDeclarations().Length(), 1u);
EXPECT_EQ(ast.GlobalDeclarations()[0], enable);
}
@@ -45,12 +45,12 @@
EXPECT_FALSE(p->has_error()) << p->error();
auto program = p->program();
auto& ast = program.AST();
- ASSERT_EQ(ast.Enables().size(), 2u);
+ ASSERT_EQ(ast.Enables().Length(), 2u);
auto* enable_a = ast.Enables()[0];
auto* enable_b = ast.Enables()[1];
EXPECT_EQ(enable_a->extension, ast::Extension::kF16);
EXPECT_EQ(enable_b->extension, ast::Extension::kF16);
- ASSERT_EQ(ast.GlobalDeclarations().size(), 2u);
+ ASSERT_EQ(ast.GlobalDeclarations().Length(), 2u);
EXPECT_EQ(ast.GlobalDeclarations()[0], enable_a);
EXPECT_EQ(ast.GlobalDeclarations()[1], enable_b);
}
@@ -64,8 +64,8 @@
EXPECT_EQ(p->error(), "1:8: unsupported extension: 'NotAValidExtensionName'");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Enables().size(), 0u);
- EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
+ EXPECT_EQ(ast.Enables().Length(), 0u);
+ EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
}
// Test an enable directive missing ending semicolon.
@@ -76,8 +76,8 @@
EXPECT_EQ(p->error(), "1:11: expected ';' for enable directive");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Enables().size(), 0u);
- EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
+ EXPECT_EQ(ast.Enables().Length(), 0u);
+ EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
}
// Test the special error message when enable are used with parenthesis.
@@ -88,8 +88,8 @@
EXPECT_EQ(p->error(), "1:7: enable directives don't take parenthesis");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Enables().size(), 0u);
- EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
+ EXPECT_EQ(ast.Enables().Length(), 0u);
+ EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
}
// Test using invalid tokens in an enable directive.
@@ -101,8 +101,8 @@
EXPECT_EQ(p->error(), "1:11: expected ';' for enable directive");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Enables().size(), 0u);
- EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
+ EXPECT_EQ(ast.Enables().Length(), 0u);
+ EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
}
{
auto p = parser("enable <f16;");
@@ -111,8 +111,8 @@
EXPECT_EQ(p->error(), "1:8: invalid extension name");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Enables().size(), 0u);
- EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
+ EXPECT_EQ(ast.Enables().Length(), 0u);
+ EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
}
{
auto p = parser("enable =;");
@@ -121,8 +121,8 @@
EXPECT_EQ(p->error(), "1:8: invalid extension name");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Enables().size(), 0u);
- EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
+ EXPECT_EQ(ast.Enables().Length(), 0u);
+ EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
}
{
auto p = parser("enable vec4;");
@@ -131,8 +131,8 @@
EXPECT_EQ(p->error(), "1:8: invalid extension name");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Enables().size(), 0u);
- EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
+ EXPECT_EQ(ast.Enables().Length(), 0u);
+ EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
}
}
@@ -148,10 +148,10 @@
auto program = p->program();
auto& ast = program.AST();
// Accept the enable directive although it caused an error
- ASSERT_EQ(ast.Enables().size(), 1u);
+ ASSERT_EQ(ast.Enables().Length(), 1u);
auto* enable = ast.Enables()[0];
EXPECT_EQ(enable->extension, ast::Extension::kF16);
- ASSERT_EQ(ast.GlobalDeclarations().size(), 2u);
+ ASSERT_EQ(ast.GlobalDeclarations().Length(), 2u);
EXPECT_EQ(ast.GlobalDeclarations()[1], enable);
}
@@ -168,10 +168,10 @@
auto program = p->program();
auto& ast = program.AST();
// Accept the enable directive although it cause an error
- ASSERT_EQ(ast.Enables().size(), 1u);
+ ASSERT_EQ(ast.Enables().Length(), 1u);
auto* enable = ast.Enables()[0];
EXPECT_EQ(enable->extension, ast::Extension::kF16);
- ASSERT_EQ(ast.GlobalDeclarations().size(), 1u);
+ ASSERT_EQ(ast.GlobalDeclarations().Length(), 1u);
EXPECT_EQ(ast.GlobalDeclarations()[0], enable);
}
diff --git a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
index 81613b4..85e888d 100644
--- a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
@@ -306,6 +306,51 @@
)");
}
+TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingCondThenEOF) {
+ EXPECT("fn f() { static_assert }", R"(test.wgsl:1:24 error: unable to parse condition expression
+fn f() { static_assert }
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingCondThenSemicolon) {
+ EXPECT("fn f() { static_assert; }",
+ R"(test.wgsl:1:23 error: unable to parse condition expression
+fn f() { static_assert; }
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingCondThenLet) {
+ EXPECT("fn f() { static_assert\nlet x = 0; }",
+ R"(test.wgsl:2:1 error: unable to parse condition expression
+let x = 0; }
+^^^
+)");
+}
+
+TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingLParen) {
+ EXPECT("fn f() { static_assert true);", R"(test.wgsl:1:28 error: expected ';' for statement
+fn f() { static_assert true);
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingRParen) {
+ EXPECT("fn f() { static_assert (true;", R"(test.wgsl:1:29 error: expected ')'
+fn f() { static_assert (true;
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingSemicolon) {
+ EXPECT("fn f() { static_assert true }",
+ R"(test.wgsl:1:29 error: expected ';' for statement
+fn f() { static_assert true }
+ ^
+)");
+}
+
// TODO(crbug.com/tint/1503): Remove this when @stage is removed
TEST_F(ParserImplErrorTest, FunctionDeclStageMissingLParen) {
EXPECT("@stage vertex) fn f() {}",
@@ -697,6 +742,50 @@
)");
}
+TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingCondThenEOF) {
+ EXPECT("static_assert", R"(test.wgsl:1:14 error: unable to parse condition expression
+static_assert
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingCondThenSemicolon) {
+ EXPECT("static_assert;", R"(test.wgsl:1:14 error: unable to parse condition expression
+static_assert;
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingCondThenAlias) {
+ EXPECT("static_assert\ntype T = i32;",
+ R"(test.wgsl:2:1 error: unable to parse condition expression
+type T = i32;
+^^^^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingLParen) {
+ EXPECT("static_assert true);", R"(test.wgsl:1:19 error: expected ';' for static assertion declaration
+static_assert true);
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingRParen) {
+ EXPECT("static_assert (true;", R"(test.wgsl:1:20 error: expected ')'
+static_assert (true;
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingSemicolon) {
+ EXPECT("static_assert true static_assert true;",
+ R"(test.wgsl:1:20 error: expected ';' for static assertion declaration
+static_assert true static_assert true;
+ ^^^^^^^^^^^^^
+)");
+}
+
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingLessThan) {
EXPECT("var x : texture_storage_2d;",
R"(test.wgsl:1:27 error: expected '<' for storage texture type
diff --git a/src/tint/reader/wgsl/parser_impl_for_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_for_stmt_test.cc
index 4f6beb0..a8d7873 100644
--- a/src/tint/reader/wgsl/parser_impl_for_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_for_stmt_test.cc
@@ -24,7 +24,7 @@
// Test an empty for loop.
TEST_F(ForStmtTest, Empty) {
auto p = parser("for (;;) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -37,21 +37,21 @@
// Test a for loop with non-empty body.
TEST_F(ForStmtTest, Body) {
auto p = parser("for (;;) { discard; }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
EXPECT_EQ(fl->initializer, nullptr);
EXPECT_EQ(fl->condition, nullptr);
EXPECT_EQ(fl->continuing, nullptr);
- ASSERT_EQ(fl->body->statements.size(), 1u);
+ ASSERT_EQ(fl->body->statements.Length(), 1u);
EXPECT_TRUE(fl->body->statements[0]->Is<ast::DiscardStatement>());
}
// Test a for loop declaring a variable in the initializer statement.
TEST_F(ForStmtTest, InitializerStatementDecl) {
auto p = parser("for (var i: i32 ;;) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -68,7 +68,7 @@
// statement.
TEST_F(ForStmtTest, InitializerStatementDeclEqual) {
auto p = parser("for (var i: i32 = 0 ;;) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -84,7 +84,7 @@
// Test a for loop declaring a const variable in the initializer statement.
TEST_F(ForStmtTest, InitializerStatementConstDecl) {
auto p = parser("for (let i: i32 = 0 ;;) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -100,7 +100,7 @@
// Test a for loop assigning a variable in the initializer statement.
TEST_F(ForStmtTest, InitializerStatementAssignment) {
auto p = parser("for (i = 0 ;;) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -113,7 +113,7 @@
// Test a for loop incrementing a variable in the initializer statement.
TEST_F(ForStmtTest, InitializerStatementIncrement) {
auto p = parser("for (i++;;) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -126,7 +126,7 @@
// Test a for loop calling a function in the initializer statement.
TEST_F(ForStmtTest, InitializerStatementFuncCall) {
auto p = parser("for (a(b,c) ;;) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -139,7 +139,7 @@
// Test a for loop with a break condition
TEST_F(ForStmtTest, BreakCondition) {
auto p = parser("for (; 0 == 1;) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -152,7 +152,7 @@
// Test a for loop assigning a variable in the continuing statement.
TEST_F(ForStmtTest, ContinuingAssignment) {
auto p = parser("for (;; x = 2) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -165,7 +165,7 @@
// Test a for loop with an increment statement as the continuing statement.
TEST_F(ForStmtTest, ContinuingIncrement) {
auto p = parser("for (;; x++) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -178,7 +178,7 @@
// Test a for loop calling a function in the continuing statement.
TEST_F(ForStmtTest, ContinuingFuncCall) {
auto p = parser("for (;; a(b,c)) { }");
- auto fl = p->for_stmt();
+ auto fl = p->for_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(fl.errored);
ASSERT_TRUE(fl.matched);
@@ -192,7 +192,7 @@
public:
void TestForWithError(std::string for_str, std::string error_str) {
auto p_for = parser(for_str);
- auto e_for = p_for->for_stmt();
+ auto e_for = p_for->for_statement();
EXPECT_FALSE(e_for.matched);
EXPECT_TRUE(e_for.errored);
diff --git a/src/tint/reader/wgsl/parser_impl_function_attribute_list_test.cc b/src/tint/reader/wgsl/parser_impl_function_attribute_list_test.cc
index 0773ffd..28b84a9 100644
--- a/src/tint/reader/wgsl/parser_impl_function_attribute_list_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_function_attribute_list_test.cc
@@ -25,7 +25,7 @@
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
- ASSERT_EQ(attrs.value.size(), 2u);
+ ASSERT_EQ(attrs.value.Length(), 2u);
auto* attr_0 = attrs.value[0]->As<ast::Attribute>();
auto* attr_1 = attrs.value[1]->As<ast::Attribute>();
@@ -51,7 +51,7 @@
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
- ASSERT_EQ(attrs.value.size(), 2u);
+ ASSERT_EQ(attrs.value.Length(), 2u);
auto* attr_0 = attrs.value[0]->As<ast::Attribute>();
auto* attr_1 = attrs.value[1]->As<ast::Attribute>();
@@ -77,7 +77,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
- EXPECT_TRUE(attrs.value.empty());
+ EXPECT_TRUE(attrs.value.IsEmpty());
EXPECT_EQ(p->error(), "1:2: expected attribute");
}
diff --git a/src/tint/reader/wgsl/parser_impl_function_decl_test.cc b/src/tint/reader/wgsl/parser_impl_function_decl_test.cc
index 4d7857b..cba4a7d 100644
--- a/src/tint/reader/wgsl/parser_impl_function_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_function_decl_test.cc
@@ -35,7 +35,7 @@
ASSERT_NE(f->return_type, nullptr);
EXPECT_TRUE(f->return_type->Is<ast::Void>());
- ASSERT_EQ(f->params.size(), 2u);
+ ASSERT_EQ(f->params.Length(), 2u);
EXPECT_EQ(f->params[0]->symbol, p->builder().Symbols().Get("a"));
EXPECT_EQ(f->params[1]->symbol, p->builder().Symbols().Get("b"));
@@ -43,7 +43,7 @@
EXPECT_TRUE(f->return_type->Is<ast::Void>());
auto* body = f->body;
- ASSERT_EQ(body->statements.size(), 1u);
+ ASSERT_EQ(body->statements.Length(), 1u);
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
}
@@ -80,7 +80,7 @@
ASSERT_NE(f->return_type, nullptr);
EXPECT_TRUE(f->return_type->Is<ast::Void>());
- ASSERT_EQ(f->params.size(), 2u);
+ ASSERT_EQ(f->params.Length(), 2u);
EXPECT_EQ(f->params[0]->symbol, p->builder().Symbols().Get(param_a_ident));
EXPECT_EQ(f->params[1]->symbol, p->builder().Symbols().Get(param_b_ident));
@@ -88,7 +88,7 @@
EXPECT_TRUE(f->return_type->Is<ast::Void>());
auto* body = f->body;
- ASSERT_EQ(body->statements.size(), 1u);
+ ASSERT_EQ(body->statements.Length(), 1u);
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
}
@@ -107,10 +107,10 @@
EXPECT_EQ(f->symbol, p->builder().Symbols().Get("main"));
ASSERT_NE(f->return_type, nullptr);
EXPECT_TRUE(f->return_type->Is<ast::Void>());
- ASSERT_EQ(f->params.size(), 0u);
+ ASSERT_EQ(f->params.Length(), 0u);
auto& attributes = f->attributes;
- ASSERT_EQ(attributes.size(), 1u);
+ ASSERT_EQ(attributes.Length(), 1u);
ASSERT_TRUE(attributes[0]->Is<ast::WorkgroupAttribute>());
auto values = attributes[0]->As<ast::WorkgroupAttribute>()->Values();
@@ -131,7 +131,7 @@
ast::IntLiteralExpression::Suffix::kNone);
auto* body = f->body;
- ASSERT_EQ(body->statements.size(), 1u);
+ ASSERT_EQ(body->statements.Length(), 1u);
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
}
@@ -152,10 +152,10 @@
EXPECT_EQ(f->symbol, p->builder().Symbols().Get("main"));
ASSERT_NE(f->return_type, nullptr);
EXPECT_TRUE(f->return_type->Is<ast::Void>());
- ASSERT_EQ(f->params.size(), 0u);
+ ASSERT_EQ(f->params.Length(), 0u);
auto& attributes = f->attributes;
- ASSERT_EQ(attributes.size(), 2u);
+ ASSERT_EQ(attributes.Length(), 2u);
ASSERT_TRUE(attributes[0]->Is<ast::WorkgroupAttribute>());
auto values = attributes[0]->As<ast::WorkgroupAttribute>()->Values();
@@ -179,7 +179,7 @@
EXPECT_EQ(attributes[1]->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute);
auto* body = f->body;
- ASSERT_EQ(body->statements.size(), 1u);
+ ASSERT_EQ(body->statements.Length(), 1u);
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
}
@@ -201,10 +201,10 @@
EXPECT_EQ(f->symbol, p->builder().Symbols().Get("main"));
ASSERT_NE(f->return_type, nullptr);
EXPECT_TRUE(f->return_type->Is<ast::Void>());
- ASSERT_EQ(f->params.size(), 0u);
+ ASSERT_EQ(f->params.Length(), 0u);
auto& attrs = f->attributes;
- ASSERT_EQ(attrs.size(), 2u);
+ ASSERT_EQ(attrs.Length(), 2u);
ASSERT_TRUE(attrs[0]->Is<ast::WorkgroupAttribute>());
auto values = attrs[0]->As<ast::WorkgroupAttribute>()->Values();
@@ -228,7 +228,7 @@
EXPECT_EQ(attrs[1]->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute);
auto* body = f->body;
- ASSERT_EQ(body->statements.size(), 1u);
+ ASSERT_EQ(body->statements.Length(), 1u);
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
}
@@ -247,19 +247,19 @@
EXPECT_EQ(f->symbol, p->builder().Symbols().Get("main"));
ASSERT_NE(f->return_type, nullptr);
EXPECT_TRUE(f->return_type->Is<ast::F32>());
- ASSERT_EQ(f->params.size(), 0u);
+ ASSERT_EQ(f->params.Length(), 0u);
auto& attributes = f->attributes;
- EXPECT_EQ(attributes.size(), 0u);
+ EXPECT_EQ(attributes.Length(), 0u);
auto& ret_type_attributes = f->return_type_attributes;
- ASSERT_EQ(ret_type_attributes.size(), 1u);
+ ASSERT_EQ(ret_type_attributes.Length(), 1u);
auto* loc = ret_type_attributes[0]->As<ast::LocationAttribute>();
ASSERT_TRUE(loc != nullptr);
EXPECT_EQ(loc->value, 1u);
auto* body = f->body;
- ASSERT_EQ(body->statements.size(), 1u);
+ ASSERT_EQ(body->statements.Length(), 1u);
EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
}
diff --git a/src/tint/reader/wgsl/parser_impl_function_header_test.cc b/src/tint/reader/wgsl/parser_impl_function_header_test.cc
index 6f2e6cb..1a8704e 100644
--- a/src/tint/reader/wgsl/parser_impl_function_header_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_function_header_test.cc
@@ -25,7 +25,7 @@
EXPECT_FALSE(f.errored);
EXPECT_EQ(f->name, "main");
- ASSERT_EQ(f->params.size(), 2u);
+ ASSERT_EQ(f->params.Length(), 2u);
EXPECT_EQ(f->params[0]->symbol, p->builder().Symbols().Get("a"));
EXPECT_EQ(f->params[1]->symbol, p->builder().Symbols().Get("b"));
EXPECT_TRUE(f->return_type->Is<ast::Void>());
@@ -38,7 +38,7 @@
EXPECT_FALSE(f.errored);
EXPECT_EQ(f->name, "main");
- ASSERT_EQ(f->params.size(), 1u);
+ ASSERT_EQ(f->params.Length(), 1u);
EXPECT_EQ(f->params[0]->symbol, p->builder().Symbols().Get("a"));
EXPECT_TRUE(f->return_type->Is<ast::Void>());
}
@@ -51,9 +51,9 @@
EXPECT_FALSE(f.errored);
EXPECT_EQ(f->name, "main");
- EXPECT_EQ(f->params.size(), 0u);
+ EXPECT_EQ(f->params.Length(), 0u);
EXPECT_TRUE(f->return_type->Is<ast::F32>());
- ASSERT_EQ(f->return_type_attributes.size(), 1u);
+ ASSERT_EQ(f->return_type_attributes.Length(), 1u);
auto* loc = f->return_type_attributes[0]->As<ast::LocationAttribute>();
ASSERT_TRUE(loc != nullptr);
EXPECT_EQ(loc->value, 1u);
@@ -67,9 +67,9 @@
EXPECT_FALSE(f.errored);
EXPECT_EQ(f->name, "main");
- EXPECT_EQ(f->params.size(), 0u);
+ EXPECT_EQ(f->params.Length(), 0u);
EXPECT_TRUE(f->return_type->Is<ast::F32>());
- ASSERT_EQ(f->return_type_attributes.size(), 1u);
+ ASSERT_EQ(f->return_type_attributes.Length(), 1u);
EXPECT_TRUE(f->return_type_attributes[0]->Is<ast::InvariantAttribute>());
}
diff --git a/src/tint/reader/wgsl/parser_impl_global_decl_test.cc b/src/tint/reader/wgsl/parser_impl_global_decl_test.cc
index 5abe58f..d9001c5 100644
--- a/src/tint/reader/wgsl/parser_impl_global_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_global_decl_test.cc
@@ -29,7 +29,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
- ASSERT_EQ(program.AST().GlobalVariables().size(), 1u);
+ ASSERT_EQ(program.AST().GlobalVariables().Length(), 1u);
auto* v = program.AST().GlobalVariables()[0];
EXPECT_EQ(v->symbol, program.Symbols().Get("a"));
@@ -42,7 +42,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
- ASSERT_EQ(program.AST().GlobalVariables().size(), 1u);
+ ASSERT_EQ(program.AST().GlobalVariables().Length(), 1u);
auto* v = program.AST().GlobalVariables()[0];
EXPECT_EQ(v->symbol, program.Symbols().Get("a"));
@@ -62,7 +62,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
- ASSERT_EQ(program.AST().GlobalVariables().size(), 1u);
+ ASSERT_EQ(program.AST().GlobalVariables().Length(), 1u);
auto* v = program.AST().GlobalVariables()[0];
EXPECT_EQ(v->symbol, program.Symbols().Get("a"));
@@ -104,7 +104,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
- ASSERT_EQ(program.AST().GlobalVariables().size(), 1u);
+ ASSERT_EQ(program.AST().GlobalVariables().Length(), 1u);
auto* v = program.AST().GlobalVariables()[0];
EXPECT_EQ(v->symbol, program.Symbols().Get("a"));
@@ -137,7 +137,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
- ASSERT_EQ(program.AST().TypeDecls().size(), 1u);
+ ASSERT_EQ(program.AST().TypeDecls().Length(), 1u);
ASSERT_TRUE(program.AST().TypeDecls()[0]->Is<ast::Alias>());
EXPECT_EQ(program.Symbols().NameFor(program.AST().TypeDecls()[0]->As<ast::Alias>()->name), "A");
}
@@ -152,7 +152,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
- ASSERT_EQ(program.AST().TypeDecls().size(), 2u);
+ ASSERT_EQ(program.AST().TypeDecls().Length(), 2u);
ASSERT_TRUE(program.AST().TypeDecls()[0]->Is<ast::Struct>());
auto* str = program.AST().TypeDecls()[0]->As<ast::Struct>();
EXPECT_EQ(str->name, program.Symbols().Get("A"));
@@ -178,7 +178,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
- ASSERT_EQ(program.AST().Functions().size(), 1u);
+ ASSERT_EQ(program.AST().Functions().Length(), 1u);
EXPECT_EQ(program.Symbols().NameFor(program.AST().Functions()[0]->symbol), "main");
}
@@ -188,7 +188,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
- ASSERT_EQ(program.AST().Functions().size(), 1u);
+ ASSERT_EQ(program.AST().Functions().Length(), 1u);
EXPECT_EQ(program.Symbols().NameFor(program.AST().Functions()[0]->symbol), "main");
}
@@ -205,7 +205,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
- ASSERT_EQ(program.AST().TypeDecls().size(), 1u);
+ ASSERT_EQ(program.AST().TypeDecls().Length(), 1u);
auto* t = program.AST().TypeDecls()[0];
ASSERT_NE(t, nullptr);
@@ -213,7 +213,7 @@
auto* str = t->As<ast::Struct>();
EXPECT_EQ(str->name, program.Symbols().Get("A"));
- EXPECT_EQ(str->members.size(), 2u);
+ EXPECT_EQ(str->members.Length(), 2u);
}
TEST_F(ParserImplTest, GlobalDecl_Struct_Invalid) {
@@ -233,5 +233,47 @@
}
}
+TEST_F(ParserImplTest, GlobalDecl_StaticAssert_WithParen) {
+ auto p = parser("static_assert(true);");
+ p->global_decl();
+ ASSERT_FALSE(p->has_error()) << p->error();
+
+ auto program = p->program();
+ ASSERT_EQ(program.AST().StaticAsserts().Length(), 1u);
+ auto* sa = program.AST().StaticAsserts()[0];
+ EXPECT_EQ(sa->source.range.begin.line, 1u);
+ EXPECT_EQ(sa->source.range.begin.column, 1u);
+ EXPECT_EQ(sa->source.range.end.line, 1u);
+ EXPECT_EQ(sa->source.range.end.column, 20u);
+
+ EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
+ EXPECT_EQ(sa->condition->source.range.begin.line, 1u);
+ EXPECT_EQ(sa->condition->source.range.begin.column, 15u);
+ EXPECT_EQ(sa->condition->source.range.end.line, 1u);
+ EXPECT_EQ(sa->condition->source.range.end.column, 19u);
+}
+
+TEST_F(ParserImplTest, GlobalDecl_StaticAssert_WithoutParen) {
+ auto p = parser("static_assert true;");
+ p->global_decl();
+ ASSERT_FALSE(p->has_error()) << p->error();
+
+ auto program = p->program();
+ ASSERT_EQ(program.AST().StaticAsserts().Length(), 1u);
+ auto* sa = program.AST().StaticAsserts()[0];
+ EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
+
+ EXPECT_EQ(sa->source.range.begin.line, 1u);
+ EXPECT_EQ(sa->source.range.begin.column, 1u);
+ EXPECT_EQ(sa->source.range.end.line, 1u);
+ EXPECT_EQ(sa->source.range.end.column, 20u);
+
+ EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
+ EXPECT_EQ(sa->condition->source.range.begin.line, 1u);
+ EXPECT_EQ(sa->condition->source.range.begin.column, 16u);
+ EXPECT_EQ(sa->condition->source.range.end.line, 1u);
+ EXPECT_EQ(sa->condition->source.range.end.column, 20u);
+}
+
} // namespace
} // namespace tint::reader::wgsl
diff --git a/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc b/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
index f671042..85f4702 100644
--- a/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
@@ -91,7 +91,7 @@
ASSERT_EQ(var->constructor, nullptr);
auto& attributes = var->attributes;
- ASSERT_EQ(attributes.size(), 2u);
+ ASSERT_EQ(attributes.Length(), 2u);
ASSERT_TRUE(attributes[0]->Is<ast::BindingAttribute>());
ASSERT_TRUE(attributes[1]->Is<ast::GroupAttribute>());
}
@@ -122,7 +122,7 @@
ASSERT_EQ(var->constructor, nullptr);
auto& attributes = var->attributes;
- ASSERT_EQ(attributes.size(), 2u);
+ ASSERT_EQ(attributes.Length(), 2u);
ASSERT_TRUE(attributes[0]->Is<ast::BindingAttribute>());
ASSERT_TRUE(attributes[1]->Is<ast::GroupAttribute>());
}
@@ -152,7 +152,7 @@
EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:24: missing initalizer for 'var' declaration");
+ EXPECT_EQ(p->error(), "1:24: missing initializer for 'var' declaration");
}
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {
diff --git a/src/tint/reader/wgsl/parser_impl_if_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_if_stmt_test.cc
index b9e5566..59e5ad3 100644
--- a/src/tint/reader/wgsl/parser_impl_if_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_if_stmt_test.cc
@@ -19,7 +19,7 @@
TEST_F(ParserImplTest, IfStmt) {
auto p = parser("if a == 4 { a = b; c = d; }");
- auto e = p->if_stmt();
+ auto e = p->if_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -28,13 +28,13 @@
ASSERT_TRUE(e->Is<ast::IfStatement>());
ASSERT_NE(e->condition, nullptr);
ASSERT_TRUE(e->condition->Is<ast::BinaryExpression>());
- EXPECT_EQ(e->body->statements.size(), 2u);
+ EXPECT_EQ(e->body->statements.Length(), 2u);
EXPECT_EQ(e->else_statement, nullptr);
}
TEST_F(ParserImplTest, IfStmt_WithElse) {
auto p = parser("if a == 4 { a = b; c = d; } else if(c) { d = 2; } else {}");
- auto e = p->if_stmt();
+ auto e = p->if_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -43,21 +43,21 @@
ASSERT_TRUE(e->Is<ast::IfStatement>());
ASSERT_NE(e->condition, nullptr);
ASSERT_TRUE(e->condition->Is<ast::BinaryExpression>());
- EXPECT_EQ(e->body->statements.size(), 2u);
+ EXPECT_EQ(e->body->statements.Length(), 2u);
auto* elseif = As<ast::IfStatement>(e->else_statement);
ASSERT_NE(elseif, nullptr);
ASSERT_TRUE(elseif->condition->Is<ast::IdentifierExpression>());
- EXPECT_EQ(elseif->body->statements.size(), 1u);
+ EXPECT_EQ(elseif->body->statements.Length(), 1u);
auto* el = As<ast::BlockStatement>(elseif->else_statement);
ASSERT_NE(el, nullptr);
- EXPECT_EQ(el->statements.size(), 0u);
+ EXPECT_EQ(el->statements.Length(), 0u);
}
TEST_F(ParserImplTest, IfStmt_WithElse_WithParens) {
auto p = parser("if(a==4) { a = b; c = d; } else if(c) { d = 2; } else {}");
- auto e = p->if_stmt();
+ auto e = p->if_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -66,21 +66,21 @@
ASSERT_TRUE(e->Is<ast::IfStatement>());
ASSERT_NE(e->condition, nullptr);
ASSERT_TRUE(e->condition->Is<ast::BinaryExpression>());
- EXPECT_EQ(e->body->statements.size(), 2u);
+ EXPECT_EQ(e->body->statements.Length(), 2u);
auto* elseif = As<ast::IfStatement>(e->else_statement);
ASSERT_NE(elseif, nullptr);
ASSERT_TRUE(elseif->condition->Is<ast::IdentifierExpression>());
- EXPECT_EQ(elseif->body->statements.size(), 1u);
+ EXPECT_EQ(elseif->body->statements.Length(), 1u);
auto* el = As<ast::BlockStatement>(elseif->else_statement);
ASSERT_NE(el, nullptr);
- EXPECT_EQ(el->statements.size(), 0u);
+ EXPECT_EQ(el->statements.Length(), 0u);
}
TEST_F(ParserImplTest, IfStmt_InvalidCondition) {
auto p = parser("if a = 3 {}");
- auto e = p->if_stmt();
+ auto e = p->if_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -90,7 +90,7 @@
TEST_F(ParserImplTest, IfStmt_MissingCondition) {
auto p = parser("if {}");
- auto e = p->if_stmt();
+ auto e = p->if_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -100,7 +100,7 @@
TEST_F(ParserImplTest, IfStmt_InvalidBody) {
auto p = parser("if a { fn main() {}}");
- auto e = p->if_stmt();
+ auto e = p->if_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -110,7 +110,7 @@
TEST_F(ParserImplTest, IfStmt_MissingBody) {
auto p = parser("if a");
- auto e = p->if_stmt();
+ auto e = p->if_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -120,7 +120,7 @@
TEST_F(ParserImplTest, IfStmt_InvalidElseif) {
auto p = parser("if a {} else if a { fn main() -> a{}}");
- auto e = p->if_stmt();
+ auto e = p->if_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -130,7 +130,7 @@
TEST_F(ParserImplTest, IfStmt_InvalidElse) {
auto p = parser("if a {} else { fn main() -> a{}}");
- auto e = p->if_stmt();
+ auto e = p->if_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
diff --git a/src/tint/reader/wgsl/parser_impl_increment_decrement_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_increment_decrement_stmt_test.cc
index 8041735..d4e52b2 100644
--- a/src/tint/reader/wgsl/parser_impl_increment_decrement_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_increment_decrement_stmt_test.cc
@@ -19,7 +19,7 @@
TEST_F(ParserImplTest, IncrementDecrementStmt_Increment) {
auto p = parser("a++");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -38,7 +38,7 @@
TEST_F(ParserImplTest, IncrementDecrementStmt_Decrement) {
auto p = parser("a--");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -57,7 +57,7 @@
TEST_F(ParserImplTest, IncrementDecrementStmt_Parenthesized) {
auto p = parser("(a)++");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -76,7 +76,7 @@
TEST_F(ParserImplTest, IncrementDecrementStmt_ToMember) {
auto p = parser("a.b.c[2].d++");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -121,7 +121,7 @@
TEST_F(ParserImplTest, IncrementDecrementStmt_InvalidLHS) {
auto p = parser("{}++");
- auto e = p->assignment_stmt();
+ auto e = p->assignment_statement();
EXPECT_FALSE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
diff --git a/src/tint/reader/wgsl/parser_impl_loop_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_loop_stmt_test.cc
index 20cd4f6..a3e51b4 100644
--- a/src/tint/reader/wgsl/parser_impl_loop_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_loop_stmt_test.cc
@@ -20,59 +20,59 @@
TEST_F(ParserImplTest, LoopStmt_BodyNoContinuing) {
auto p = parser("loop { discard; }");
- auto e = p->loop_stmt();
+ auto e = p->loop_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
- ASSERT_EQ(e->body->statements.size(), 1u);
+ ASSERT_EQ(e->body->statements.Length(), 1u);
EXPECT_TRUE(e->body->statements[0]->Is<ast::DiscardStatement>());
- EXPECT_EQ(e->continuing->statements.size(), 0u);
+ EXPECT_EQ(e->continuing->statements.Length(), 0u);
}
TEST_F(ParserImplTest, LoopStmt_BodyWithContinuing) {
auto p = parser("loop { discard; continuing { discard; }}");
- auto e = p->loop_stmt();
+ auto e = p->loop_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
- ASSERT_EQ(e->body->statements.size(), 1u);
+ ASSERT_EQ(e->body->statements.Length(), 1u);
EXPECT_TRUE(e->body->statements[0]->Is<ast::DiscardStatement>());
- EXPECT_EQ(e->continuing->statements.size(), 1u);
+ EXPECT_EQ(e->continuing->statements.Length(), 1u);
EXPECT_TRUE(e->continuing->statements[0]->Is<ast::DiscardStatement>());
}
TEST_F(ParserImplTest, LoopStmt_NoBodyNoContinuing) {
auto p = parser("loop { }");
- auto e = p->loop_stmt();
+ auto e = p->loop_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
- ASSERT_EQ(e->body->statements.size(), 0u);
- ASSERT_EQ(e->continuing->statements.size(), 0u);
+ ASSERT_EQ(e->body->statements.Length(), 0u);
+ ASSERT_EQ(e->continuing->statements.Length(), 0u);
}
TEST_F(ParserImplTest, LoopStmt_NoBodyWithContinuing) {
auto p = parser("loop { continuing { discard; }}");
- auto e = p->loop_stmt();
+ auto e = p->loop_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
- ASSERT_EQ(e->body->statements.size(), 0u);
- ASSERT_EQ(e->continuing->statements.size(), 1u);
+ ASSERT_EQ(e->body->statements.Length(), 0u);
+ ASSERT_EQ(e->continuing->statements.Length(), 1u);
EXPECT_TRUE(e->continuing->statements[0]->Is<ast::DiscardStatement>());
}
TEST_F(ParserImplTest, LoopStmt_MissingBracketLeft) {
auto p = parser("loop discard; }");
- auto e = p->loop_stmt();
+ auto e = p->loop_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -82,7 +82,7 @@
TEST_F(ParserImplTest, LoopStmt_MissingBracketRight) {
auto p = parser("loop { discard; ");
- auto e = p->loop_stmt();
+ auto e = p->loop_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -92,7 +92,7 @@
TEST_F(ParserImplTest, LoopStmt_InvalidStatements) {
auto p = parser("loop { discard }");
- auto e = p->loop_stmt();
+ auto e = p->loop_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -102,7 +102,7 @@
TEST_F(ParserImplTest, LoopStmt_InvalidContinuing) {
auto p = parser("loop { continuing { discard }}");
- auto e = p->loop_stmt();
+ auto e = p->loop_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
diff --git a/src/tint/reader/wgsl/parser_impl_param_list_test.cc b/src/tint/reader/wgsl/parser_impl_param_list_test.cc
index 86a2f68..ce542e4 100644
--- a/src/tint/reader/wgsl/parser_impl_param_list_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_param_list_test.cc
@@ -23,7 +23,7 @@
auto e = p->expect_param_list();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
- EXPECT_EQ(e.value.size(), 1u);
+ EXPECT_EQ(e.value.Length(), 1u);
EXPECT_EQ(e.value[0]->symbol, p->builder().Symbols().Get("a"));
EXPECT_TRUE(e.value[0]->type->Is<ast::I32>());
@@ -41,7 +41,7 @@
auto e = p->expect_param_list();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
- EXPECT_EQ(e.value.size(), 3u);
+ EXPECT_EQ(e.value.Length(), 3u);
EXPECT_EQ(e.value[0]->symbol, p->builder().Symbols().Get("a"));
EXPECT_TRUE(e.value[0]->type->Is<ast::I32>());
@@ -78,7 +78,7 @@
auto e = p->expect_param_list();
ASSERT_FALSE(p->has_error());
ASSERT_FALSE(e.errored);
- EXPECT_EQ(e.value.size(), 0u);
+ EXPECT_EQ(e.value.Length(), 0u);
}
TEST_F(ParserImplTest, ParamList_TrailingComma) {
@@ -86,7 +86,7 @@
auto e = p->expect_param_list();
ASSERT_FALSE(p->has_error());
ASSERT_FALSE(e.errored);
- EXPECT_EQ(e.value.size(), 1u);
+ EXPECT_EQ(e.value.Length(), 1u);
}
TEST_F(ParserImplTest, ParamList_Attributes) {
@@ -95,7 +95,7 @@
auto e = p->expect_param_list();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
- ASSERT_EQ(e.value.size(), 2u);
+ ASSERT_EQ(e.value.Length(), 2u);
EXPECT_EQ(e.value[0]->symbol, p->builder().Symbols().Get("coord"));
ASSERT_TRUE(e.value[0]->type->Is<ast::Vector>());
@@ -103,7 +103,7 @@
EXPECT_EQ(e.value[0]->type->As<ast::Vector>()->width, 4u);
EXPECT_TRUE(e.value[0]->Is<ast::Parameter>());
auto attrs_0 = e.value[0]->attributes;
- ASSERT_EQ(attrs_0.size(), 1u);
+ ASSERT_EQ(attrs_0.Length(), 1u);
EXPECT_TRUE(attrs_0[0]->Is<ast::BuiltinAttribute>());
EXPECT_EQ(attrs_0[0]->As<ast::BuiltinAttribute>()->builtin, ast::BuiltinValue::kPosition);
@@ -116,7 +116,7 @@
EXPECT_TRUE(e.value[1]->type->Is<ast::F32>());
EXPECT_TRUE(e.value[1]->Is<ast::Parameter>());
auto attrs_1 = e.value[1]->attributes;
- ASSERT_EQ(attrs_1.size(), 1u);
+ ASSERT_EQ(attrs_1.Length(), 1u);
EXPECT_TRUE(attrs_1[0]->Is<ast::LocationAttribute>());
EXPECT_EQ(attrs_1[0]->As<ast::LocationAttribute>()->value, 1u);
diff --git a/src/tint/reader/wgsl/parser_impl_primary_expression_test.cc b/src/tint/reader/wgsl/parser_impl_primary_expression_test.cc
index 493ce87..82f64c3 100644
--- a/src/tint/reader/wgsl/parser_impl_primary_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_primary_expression_test.cc
@@ -42,7 +42,7 @@
EXPECT_NE(call->target.type, nullptr);
- ASSERT_EQ(call->args.size(), 4u);
+ ASSERT_EQ(call->args.Length(), 4u);
const auto& val = call->args;
ASSERT_TRUE(val[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(val[0]->As<ast::IntLiteralExpression>()->value, 1);
@@ -76,7 +76,7 @@
ASSERT_TRUE(e->Is<ast::CallExpression>());
auto* call = e->As<ast::CallExpression>();
- ASSERT_EQ(call->args.size(), 0u);
+ ASSERT_EQ(call->args.Length(), 0u);
}
TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_InvalidTypeDecl) {
@@ -140,7 +140,7 @@
ASSERT_NE(call->target.name, nullptr);
EXPECT_EQ(call->target.name->symbol, p->builder().Symbols().Get("S"));
- ASSERT_EQ(call->args.size(), 0u);
+ ASSERT_EQ(call->args.Length(), 0u);
}
TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_StructConstructor_NotEmpty) {
@@ -164,7 +164,7 @@
ASSERT_NE(call->target.name, nullptr);
EXPECT_EQ(call->target.name->symbol, p->builder().Symbols().Get("S"));
- ASSERT_EQ(call->args.size(), 2u);
+ ASSERT_EQ(call->args.Length(), 2u);
ASSERT_TRUE(call->args[0]->Is<ast::IntLiteralExpression>());
EXPECT_EQ(call->args[0]->As<ast::IntLiteralExpression>()->value, 1u);
@@ -239,7 +239,7 @@
auto* call = e->As<ast::CallExpression>();
ASSERT_TRUE(call->target.type->Is<ast::F32>());
- ASSERT_EQ(call->args.size(), 1u);
+ ASSERT_EQ(call->args.Length(), 1u);
ASSERT_TRUE(call->args[0]->Is<ast::IntLiteralExpression>());
}
diff --git a/src/tint/reader/wgsl/parser_impl_reserved_keyword_test.cc b/src/tint/reader/wgsl/parser_impl_reserved_keyword_test.cc
index cb61eed..0ad3cc1 100644
--- a/src/tint/reader/wgsl/parser_impl_reserved_keyword_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_reserved_keyword_test.cc
@@ -21,88 +21,232 @@
TEST_P(ParserImplReservedKeywordTest, Function) {
auto name = GetParam();
auto p = parser("fn " + name + "() {}");
- EXPECT_FALSE(p->Parse());
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:4: '" + name + "' is a reserved keyword");
+ EXPECT_TRUE(p->Parse());
+ EXPECT_FALSE(p->has_error());
+ EXPECT_EQ(p->error(),
+ "1:4: use of deprecated language feature: '" + name + "' is a reserved keyword");
}
TEST_P(ParserImplReservedKeywordTest, ModuleConst) {
auto name = GetParam();
auto p = parser("const " + name + " : i32 = 1;");
- EXPECT_FALSE(p->Parse());
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:7: '" + name + "' is a reserved keyword");
+ EXPECT_TRUE(p->Parse());
+ EXPECT_FALSE(p->has_error());
+ EXPECT_EQ(p->error(),
+ "1:7: use of deprecated language feature: '" + name + "' is a reserved keyword");
}
TEST_P(ParserImplReservedKeywordTest, ModuleVar) {
auto name = GetParam();
auto p = parser("var " + name + " : i32 = 1;");
- EXPECT_FALSE(p->Parse());
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:5: '" + name + "' is a reserved keyword");
+ EXPECT_TRUE(p->Parse());
+ EXPECT_FALSE(p->has_error());
+ EXPECT_EQ(p->error(),
+ "1:5: use of deprecated language feature: '" + name + "' is a reserved keyword");
}
TEST_P(ParserImplReservedKeywordTest, FunctionLet) {
auto name = GetParam();
auto p = parser("fn f() { let " + name + " : i32 = 1; }");
- EXPECT_FALSE(p->Parse());
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:14: '" + name + "' is a reserved keyword");
+ EXPECT_TRUE(p->Parse());
+ EXPECT_FALSE(p->has_error());
+ EXPECT_EQ(p->error(),
+ "1:14: use of deprecated language feature: '" + name + "' is a reserved keyword");
}
TEST_P(ParserImplReservedKeywordTest, FunctionVar) {
auto name = GetParam();
auto p = parser("fn f() { var " + name + " : i32 = 1; }");
- EXPECT_FALSE(p->Parse());
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:14: '" + name + "' is a reserved keyword");
+ EXPECT_TRUE(p->Parse());
+ EXPECT_FALSE(p->has_error());
+ EXPECT_EQ(p->error(),
+ "1:14: use of deprecated language feature: '" + name + "' is a reserved keyword");
}
TEST_P(ParserImplReservedKeywordTest, FunctionParam) {
auto name = GetParam();
auto p = parser("fn f(" + name + " : i32) {}");
- EXPECT_FALSE(p->Parse());
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:6: '" + name + "' is a reserved keyword");
+ EXPECT_TRUE(p->Parse());
+ EXPECT_FALSE(p->has_error());
+ EXPECT_EQ(p->error(),
+ "1:6: use of deprecated language feature: '" + name + "' is a reserved keyword");
}
TEST_P(ParserImplReservedKeywordTest, Struct) {
auto name = GetParam();
auto p = parser("struct " + name + " {};");
- EXPECT_FALSE(p->Parse());
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:8: '" + name + "' is a reserved keyword");
+ EXPECT_TRUE(p->Parse());
+ EXPECT_FALSE(p->has_error());
+ EXPECT_EQ(p->error(),
+ "1:8: use of deprecated language feature: '" + name + "' is a reserved keyword");
}
TEST_P(ParserImplReservedKeywordTest, StructMember) {
auto name = GetParam();
auto p = parser("struct S { " + name + " : i32, };");
- EXPECT_FALSE(p->Parse());
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:12: '" + name + "' is a reserved keyword");
+ EXPECT_TRUE(p->Parse());
+ EXPECT_FALSE(p->has_error());
+ EXPECT_EQ(p->error(),
+ "1:12: use of deprecated language feature: '" + name + "' is a reserved keyword");
}
TEST_P(ParserImplReservedKeywordTest, Alias) {
auto name = GetParam();
auto p = parser("type " + name + " = i32;");
- EXPECT_FALSE(p->Parse());
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:6: '" + name + "' is a reserved keyword");
+ EXPECT_TRUE(p->Parse());
+ EXPECT_FALSE(p->has_error());
+ EXPECT_EQ(p->error(),
+ "1:6: use of deprecated language feature: '" + name + "' is a reserved keyword");
}
INSTANTIATE_TEST_SUITE_P(ParserImplReservedKeywordTest,
ParserImplReservedKeywordTest,
- testing::Values("asm",
- "bf16",
+ testing::Values("ComputeShader",
+ "DomainShader",
+ "GeometryShader",
+ "Hullshader",
+ "NULL",
+ "Self",
+ "abstract",
+ "active",
+ "alignas",
+ "alignof",
+ "as",
+ "asm",
+ "asm_fragment",
+ "async",
+ "attribute",
+ "auto",
+ "await",
+ "become",
+ "binding_array",
+ "cast",
+ "catch",
+ "class",
+ "co_await",
+ "co_return",
+ "co_yield",
+ "coherent",
+ "column_major",
+ "common",
+ "compile",
+ "compile_fragment",
+ "concept",
+ "const_cast",
+ "consteval",
+ "constexpr",
+ "constinit",
+ "crate",
+ "debugger",
+ "decltype",
+ "delete",
+ "demote",
+ "demote_to_helper",
"do",
+ "dynamic_cast",
"enum",
- "f64",
+ "explicit",
+ "export",
+ "extends",
+ "extern",
+ "external",
+ "filter",
+ "final",
+ "finally",
+ "friend",
+ "from",
+ "fxgroup",
+ "get",
+ "goto",
+ "groupshared",
"handle",
- "i8",
- "i16",
- "i64",
- "mat",
+ "highp",
+ "impl",
+ "implements",
+ "import",
+ "inline",
+ "inout",
+ "instanceof",
+ "interface",
+ "invariant",
+ "layout",
+ "line",
+ "lineadj",
+ "lowp",
+ "macro",
+ "macro_rules",
+ "match",
+ "mediump",
+ "meta",
+ "mod",
+ "module",
+ "move",
+ "mut",
+ "mutable",
+ "namespace",
+ "new",
+ "nil",
+ "noexcept",
+ "noinline",
+ "nointerpolation",
+ "noperspective",
+ "null",
+ "nullptr",
+ "of",
+ "operator",
+ "package",
+ "packoffset",
+ "partition",
+ "pass",
+ "patch",
+ "pixelfragment",
+ "point",
+ "precise",
+ "precision",
"premerge",
+ "priv",
+ "protected",
+ "pub",
+ "public",
+ "readonly",
+ "ref",
"regardless",
+ "register",
+ "reinterpret_cast",
+ "requires",
+ "resource",
+ "restrict",
+ "self",
+ "set",
+ "shared",
+ "signed",
+ "sizeof",
+ "smooth",
+ "snorm",
+ "static",
+ "static_cast",
+ "std",
+ "subroutine",
+ "super",
+ "target",
+ "template",
+ "this",
+ "thread_local",
+ "throw",
+ "trait",
+ "try",
"typedef",
- "u8",
- "u16",
- "u64",
+ "typeid",
+ "typename",
+ "typeof",
+ "union",
"unless",
+ "unorm",
+ "unsafe",
+ "unsized",
+ "use",
"using",
- "vec",
- "void"));
+ "varying",
+ "virtual",
+ "volatile",
+ "wgsl",
+ "where",
+ "with",
+ "writeonly",
+ "yield"
+
+ ));
} // namespace
} // namespace tint::reader::wgsl
diff --git a/src/tint/reader/wgsl/parser_impl_singular_expression_test.cc b/src/tint/reader/wgsl/parser_impl_singular_expression_test.cc
index 4ab185b..a08b45a 100644
--- a/src/tint/reader/wgsl/parser_impl_singular_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_singular_expression_test.cc
@@ -99,7 +99,7 @@
EXPECT_EQ(c->target.name->symbol, p->builder().Symbols().Get("a"));
- EXPECT_EQ(c->args.size(), 0u);
+ EXPECT_EQ(c->args.Length(), 0u);
}
TEST_F(ParserImplTest, SingularExpression_Call_WithArgs) {
@@ -115,7 +115,7 @@
EXPECT_EQ(c->target.name->symbol, p->builder().Symbols().Get("test"));
- EXPECT_EQ(c->args.size(), 3u);
+ EXPECT_EQ(c->args.Length(), 3u);
EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>());
EXPECT_TRUE(c->args[1]->Is<ast::IdentifierExpression>());
EXPECT_TRUE(c->args[2]->Is<ast::BinaryExpression>());
@@ -130,7 +130,7 @@
ASSERT_TRUE(e->Is<ast::CallExpression>());
auto* c = e->As<ast::CallExpression>();
- EXPECT_EQ(c->args.size(), 1u);
+ EXPECT_EQ(c->args.Length(), 1u);
}
TEST_F(ParserImplTest, SingularExpression_Call_InvalidArg) {
diff --git a/src/tint/reader/wgsl/parser_impl_statement_test.cc b/src/tint/reader/wgsl/parser_impl_statement_test.cc
index 677daa0..7bb51d3 100644
--- a/src/tint/reader/wgsl/parser_impl_statement_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_statement_test.cc
@@ -272,5 +272,47 @@
EXPECT_EQ(p->error(), "1:3: expected '}'");
}
+TEST_F(ParserImplTest, Statement_StaticAssert_WithParen) {
+ auto p = parser("static_assert(true);");
+ auto e = p->statement();
+ ASSERT_FALSE(p->has_error()) << p->error();
+ EXPECT_TRUE(e.matched);
+ EXPECT_FALSE(e.errored);
+
+ auto* sa = As<ast::StaticAssert>(e.value);
+ ASSERT_NE(sa, nullptr);
+ EXPECT_EQ(sa->source.range.begin.line, 1u);
+ EXPECT_EQ(sa->source.range.begin.column, 1u);
+ EXPECT_EQ(sa->source.range.end.line, 1u);
+ EXPECT_EQ(sa->source.range.end.column, 20u);
+
+ EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
+ EXPECT_EQ(sa->condition->source.range.begin.line, 1u);
+ EXPECT_EQ(sa->condition->source.range.begin.column, 15u);
+ EXPECT_EQ(sa->condition->source.range.end.line, 1u);
+ EXPECT_EQ(sa->condition->source.range.end.column, 19u);
+}
+
+TEST_F(ParserImplTest, Statement_StaticAssert_WithoutParen) {
+ auto p = parser("static_assert true;");
+ auto e = p->statement();
+ ASSERT_FALSE(p->has_error()) << p->error();
+ EXPECT_TRUE(e.matched);
+ EXPECT_FALSE(e.errored);
+
+ auto* sa = As<ast::StaticAssert>(e.value);
+ ASSERT_NE(sa, nullptr);
+ EXPECT_EQ(sa->source.range.begin.line, 1u);
+ EXPECT_EQ(sa->source.range.begin.column, 1u);
+ EXPECT_EQ(sa->source.range.end.line, 1u);
+ EXPECT_EQ(sa->source.range.end.column, 20u);
+
+ EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
+ EXPECT_EQ(sa->condition->source.range.begin.line, 1u);
+ EXPECT_EQ(sa->condition->source.range.begin.column, 16u);
+ EXPECT_EQ(sa->condition->source.range.end.line, 1u);
+ EXPECT_EQ(sa->condition->source.range.end.column, 20u);
+}
+
} // namespace
} // namespace tint::reader::wgsl
diff --git a/src/tint/reader/wgsl/parser_impl_statements_test.cc b/src/tint/reader/wgsl/parser_impl_statements_test.cc
index b96a28a..c631f7a 100644
--- a/src/tint/reader/wgsl/parser_impl_statements_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_statements_test.cc
@@ -23,7 +23,7 @@
auto e = p->expect_statements();
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
- ASSERT_EQ(e->size(), 2u);
+ ASSERT_EQ(e->Length(), 2u);
EXPECT_TRUE(e.value[0]->Is<ast::DiscardStatement>());
EXPECT_TRUE(e.value[1]->Is<ast::ReturnStatement>());
}
@@ -33,7 +33,7 @@
auto e = p->expect_statements();
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
- ASSERT_EQ(e->size(), 0u);
+ ASSERT_EQ(e->Length(), 0u);
}
} // namespace
diff --git a/src/tint/reader/wgsl/parser_impl_storage_class_test.cc b/src/tint/reader/wgsl/parser_impl_storage_class_test.cc
index c40752a..c6ef7eb 100644
--- a/src/tint/reader/wgsl/parser_impl_storage_class_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_storage_class_test.cc
@@ -32,7 +32,7 @@
auto params = GetParam();
auto p = parser(params.input);
- auto sc = p->expect_storage_class("test");
+ auto sc = p->expect_address_space("test");
EXPECT_FALSE(sc.errored);
EXPECT_FALSE(p->has_error());
EXPECT_EQ(sc.value, params.result);
@@ -51,7 +51,7 @@
TEST_F(ParserImplTest, StorageClass_NoMatch) {
auto p = parser("not-a-storage-class");
- auto sc = p->expect_storage_class("test");
+ auto sc = p->expect_address_space("test");
EXPECT_EQ(sc.errored, true);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:1: invalid storage class for test");
diff --git a/src/tint/reader/wgsl/parser_impl_struct_attribute_decl_test.cc b/src/tint/reader/wgsl/parser_impl_struct_attribute_decl_test.cc
index a22abee..e015033 100644
--- a/src/tint/reader/wgsl/parser_impl_struct_attribute_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_struct_attribute_decl_test.cc
@@ -24,7 +24,7 @@
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
- ASSERT_EQ(attrs.value.size(), 1u);
+ ASSERT_EQ(attrs.value.Length(), 1u);
auto* invariant = attrs.value[0]->As<ast::Attribute>();
EXPECT_TRUE(invariant->Is<ast::InvariantAttribute>());
}
@@ -35,7 +35,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
- EXPECT_TRUE(attrs.value.empty());
+ EXPECT_TRUE(attrs.value.IsEmpty());
EXPECT_EQ(p->error(), "1:11: expected '(' for location attribute");
}
@@ -45,7 +45,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
- EXPECT_TRUE(attrs.value.empty());
+ EXPECT_TRUE(attrs.value.IsEmpty());
EXPECT_EQ(p->error(), "1:11: expected signed integer literal for location attribute");
}
@@ -55,7 +55,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
- EXPECT_TRUE(attrs.value.empty());
+ EXPECT_TRUE(attrs.value.IsEmpty());
EXPECT_EQ(p->error(), "1:12: expected ')' for location attribute");
}
@@ -65,7 +65,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
- EXPECT_TRUE(attrs.value.empty());
+ EXPECT_TRUE(attrs.value.IsEmpty());
}
} // namespace
diff --git a/src/tint/reader/wgsl/parser_impl_struct_body_decl_test.cc b/src/tint/reader/wgsl/parser_impl_struct_body_decl_test.cc
index b02fb5a..3499b5c 100644
--- a/src/tint/reader/wgsl/parser_impl_struct_body_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_struct_body_decl_test.cc
@@ -25,12 +25,12 @@
auto m = p->expect_struct_body_decl();
ASSERT_FALSE(p->has_error());
ASSERT_FALSE(m.errored);
- ASSERT_EQ(m.value.size(), 1u);
+ ASSERT_EQ(m.value.Length(), 1u);
const auto* mem = m.value[0];
EXPECT_EQ(mem->symbol, builder.Symbols().Get("a"));
EXPECT_TRUE(mem->type->Is<ast::I32>());
- EXPECT_EQ(mem->attributes.size(), 0u);
+ EXPECT_EQ(mem->attributes.Length(), 0u);
}
TEST_F(ParserImplTest, StructBodyDecl_Parses_TrailingComma) {
@@ -41,12 +41,12 @@
auto m = p->expect_struct_body_decl();
ASSERT_FALSE(p->has_error());
ASSERT_FALSE(m.errored);
- ASSERT_EQ(m.value.size(), 1u);
+ ASSERT_EQ(m.value.Length(), 1u);
const auto* mem = m.value[0];
EXPECT_EQ(mem->symbol, builder.Symbols().Get("a"));
EXPECT_TRUE(mem->type->Is<ast::I32>());
- EXPECT_EQ(mem->attributes.size(), 0u);
+ EXPECT_EQ(mem->attributes.Length(), 0u);
}
TEST_F(ParserImplTest, StructBodyDecl_ParsesEmpty) {
@@ -54,7 +54,7 @@
auto m = p->expect_struct_body_decl();
ASSERT_FALSE(p->has_error());
ASSERT_FALSE(m.errored);
- ASSERT_EQ(m.value.size(), 0u);
+ ASSERT_EQ(m.value.Length(), 0u);
}
TEST_F(ParserImplTest, StructBodyDecl_InvalidAlign) {
diff --git a/src/tint/reader/wgsl/parser_impl_struct_decl_test.cc b/src/tint/reader/wgsl/parser_impl_struct_decl_test.cc
index 1c6d6bc..dbb9ca6 100644
--- a/src/tint/reader/wgsl/parser_impl_struct_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_struct_decl_test.cc
@@ -30,7 +30,7 @@
EXPECT_TRUE(s.matched);
ASSERT_NE(s.value, nullptr);
ASSERT_EQ(s->name, p->builder().Symbols().Register("S"));
- ASSERT_EQ(s->members.size(), 2u);
+ ASSERT_EQ(s->members.Length(), 2u);
EXPECT_EQ(s->members[0]->symbol, p->builder().Symbols().Register("a"));
EXPECT_EQ(s->members[1]->symbol, p->builder().Symbols().Register("b"));
}
@@ -64,7 +64,7 @@
EXPECT_TRUE(s.matched);
ASSERT_NE(s.value, nullptr);
ASSERT_EQ(s->name, p->builder().Symbols().Register(struct_ident));
- ASSERT_EQ(s->members.size(), 2u);
+ ASSERT_EQ(s->members.Length(), 2u);
EXPECT_EQ(s->members[0]->symbol, p->builder().Symbols().Register(member_a_ident));
EXPECT_EQ(s->members[1]->symbol, p->builder().Symbols().Register(member_b_ident));
}
@@ -77,7 +77,7 @@
EXPECT_FALSE(s.errored);
EXPECT_TRUE(s.matched);
ASSERT_NE(s.value, nullptr);
- ASSERT_EQ(s->members.size(), 0u);
+ ASSERT_EQ(s->members.Length(), 0u);
}
TEST_F(ParserImplTest, StructDecl_MissingIdent) {
diff --git a/src/tint/reader/wgsl/parser_impl_struct_member_attribute_decl_test.cc b/src/tint/reader/wgsl/parser_impl_struct_member_attribute_decl_test.cc
index 2695074..09d5274 100644
--- a/src/tint/reader/wgsl/parser_impl_struct_member_attribute_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_struct_member_attribute_decl_test.cc
@@ -23,7 +23,7 @@
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(attrs.errored);
EXPECT_FALSE(attrs.matched);
- EXPECT_EQ(attrs.value.size(), 0u);
+ EXPECT_EQ(attrs.value.Length(), 0u);
}
TEST_F(ParserImplTest, AttributeDecl_Single) {
@@ -32,7 +32,7 @@
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
- ASSERT_EQ(attrs.value.size(), 1u);
+ ASSERT_EQ(attrs.value.Length(), 1u);
auto* attr = attrs.value[0]->As<ast::Attribute>();
ASSERT_NE(attr, nullptr);
EXPECT_TRUE(attr->Is<ast::StructMemberSizeAttribute>());
diff --git a/src/tint/reader/wgsl/parser_impl_struct_member_test.cc b/src/tint/reader/wgsl/parser_impl_struct_member_test.cc
index 3e8b60e..d2ab916 100644
--- a/src/tint/reader/wgsl/parser_impl_struct_member_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_struct_member_test.cc
@@ -29,7 +29,7 @@
EXPECT_EQ(m->symbol, builder.Symbols().Get("a"));
EXPECT_TRUE(m->type->Is<ast::I32>());
- EXPECT_EQ(m->attributes.size(), 0u);
+ EXPECT_EQ(m->attributes.Length(), 0u);
EXPECT_EQ(m->source.range, (Source::Range{{1u, 1u}, {1u, 2u}}));
EXPECT_EQ(m->type->source.range, (Source::Range{{1u, 5u}, {1u, 8u}}));
@@ -47,7 +47,7 @@
EXPECT_EQ(m->symbol, builder.Symbols().Get("a"));
EXPECT_TRUE(m->type->Is<ast::I32>());
- EXPECT_EQ(m->attributes.size(), 1u);
+ EXPECT_EQ(m->attributes.Length(), 1u);
EXPECT_TRUE(m->attributes[0]->Is<ast::StructMemberAlignAttribute>());
EXPECT_EQ(m->attributes[0]->As<ast::StructMemberAlignAttribute>()->align, 2u);
@@ -67,7 +67,7 @@
EXPECT_EQ(m->symbol, builder.Symbols().Get("a"));
EXPECT_TRUE(m->type->Is<ast::I32>());
- EXPECT_EQ(m->attributes.size(), 1u);
+ EXPECT_EQ(m->attributes.Length(), 1u);
EXPECT_TRUE(m->attributes[0]->Is<ast::StructMemberSizeAttribute>());
EXPECT_EQ(m->attributes[0]->As<ast::StructMemberSizeAttribute>()->size, 2u);
@@ -88,7 +88,7 @@
EXPECT_EQ(m->symbol, builder.Symbols().Get("a"));
EXPECT_TRUE(m->type->Is<ast::I32>());
- EXPECT_EQ(m->attributes.size(), 2u);
+ EXPECT_EQ(m->attributes.Length(), 2u);
EXPECT_TRUE(m->attributes[0]->Is<ast::StructMemberSizeAttribute>());
EXPECT_EQ(m->attributes[0]->As<ast::StructMemberSizeAttribute>()->size, 2u);
EXPECT_TRUE(m->attributes[1]->Is<ast::StructMemberAlignAttribute>());
diff --git a/src/tint/reader/wgsl/parser_impl_switch_body_test.cc b/src/tint/reader/wgsl/parser_impl_switch_body_test.cc
index 0f7384d..076b1c3 100644
--- a/src/tint/reader/wgsl/parser_impl_switch_body_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_switch_body_test.cc
@@ -27,10 +27,10 @@
ASSERT_TRUE(e->Is<ast::CaseStatement>());
EXPECT_FALSE(e->IsDefault());
auto* stmt = e->As<ast::CaseStatement>();
- ASSERT_EQ(stmt->selectors.size(), 1u);
+ ASSERT_EQ(stmt->selectors.Length(), 1u);
EXPECT_EQ(stmt->selectors[0]->value, 1);
EXPECT_EQ(stmt->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
- ASSERT_EQ(e->body->statements.size(), 1u);
+ ASSERT_EQ(e->body->statements.Length(), 1u);
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
}
@@ -44,10 +44,10 @@
ASSERT_TRUE(e->Is<ast::CaseStatement>());
EXPECT_FALSE(e->IsDefault());
auto* stmt = e->As<ast::CaseStatement>();
- ASSERT_EQ(stmt->selectors.size(), 1u);
+ ASSERT_EQ(stmt->selectors.Length(), 1u);
EXPECT_EQ(stmt->selectors[0]->value, 1);
EXPECT_EQ(stmt->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
- ASSERT_EQ(e->body->statements.size(), 1u);
+ ASSERT_EQ(e->body->statements.Length(), 1u);
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
}
@@ -61,7 +61,7 @@
ASSERT_TRUE(e->Is<ast::CaseStatement>());
EXPECT_FALSE(e->IsDefault());
auto* stmt = e->As<ast::CaseStatement>();
- ASSERT_EQ(stmt->selectors.size(), 2u);
+ ASSERT_EQ(stmt->selectors.Length(), 2u);
EXPECT_EQ(stmt->selectors[0]->value, 1);
EXPECT_EQ(stmt->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
EXPECT_EQ(stmt->selectors[1]->value, 2);
@@ -77,7 +77,7 @@
ASSERT_TRUE(e->Is<ast::CaseStatement>());
EXPECT_FALSE(e->IsDefault());
auto* stmt = e->As<ast::CaseStatement>();
- ASSERT_EQ(stmt->selectors.size(), 2u);
+ ASSERT_EQ(stmt->selectors.Length(), 2u);
EXPECT_EQ(stmt->selectors[0]->value, 1);
EXPECT_EQ(stmt->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
EXPECT_EQ(stmt->selectors[1]->value, 2);
@@ -162,8 +162,8 @@
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::CaseStatement>());
EXPECT_FALSE(e->IsDefault());
- ASSERT_EQ(e->body->statements.size(), 0u);
- ASSERT_EQ(e->selectors.size(), 2u);
+ ASSERT_EQ(e->body->statements.Length(), 0u);
+ ASSERT_EQ(e->selectors.Length(), 2u);
ASSERT_EQ(e->selectors[0]->value, 1);
EXPECT_EQ(e->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
ASSERT_EQ(e->selectors[1]->value, 2);
@@ -179,8 +179,8 @@
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::CaseStatement>());
EXPECT_FALSE(e->IsDefault());
- ASSERT_EQ(e->body->statements.size(), 0u);
- ASSERT_EQ(e->selectors.size(), 2u);
+ ASSERT_EQ(e->body->statements.Length(), 0u);
+ ASSERT_EQ(e->selectors.Length(), 2u);
ASSERT_EQ(e->selectors[0]->value, 1);
EXPECT_EQ(e->selectors[0]->suffix, ast::IntLiteralExpression::Suffix::kNone);
ASSERT_EQ(e->selectors[1]->value, 2);
@@ -216,7 +216,7 @@
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::CaseStatement>());
EXPECT_TRUE(e->IsDefault());
- ASSERT_EQ(e->body->statements.size(), 1u);
+ ASSERT_EQ(e->body->statements.Length(), 1u);
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
}
@@ -229,7 +229,7 @@
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::CaseStatement>());
EXPECT_TRUE(e->IsDefault());
- ASSERT_EQ(e->body->statements.size(), 1u);
+ ASSERT_EQ(e->body->statements.Length(), 1u);
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
}
diff --git a/src/tint/reader/wgsl/parser_impl_switch_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_switch_stmt_test.cc
index c898b12..014d850 100644
--- a/src/tint/reader/wgsl/parser_impl_switch_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_switch_stmt_test.cc
@@ -22,26 +22,26 @@
case 1: {}
case 2: {}
})");
- auto e = p->switch_stmt();
+ auto e = p->switch_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::SwitchStatement>());
- ASSERT_EQ(e->body.size(), 2u);
+ ASSERT_EQ(e->body.Length(), 2u);
EXPECT_FALSE(e->body[0]->IsDefault());
EXPECT_FALSE(e->body[1]->IsDefault());
}
TEST_F(ParserImplTest, SwitchStmt_Empty) {
auto p = parser("switch a { }");
- auto e = p->switch_stmt();
+ auto e = p->switch_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::SwitchStatement>());
- ASSERT_EQ(e->body.size(), 0u);
+ ASSERT_EQ(e->body.Length(), 0u);
}
TEST_F(ParserImplTest, SwitchStmt_DefaultInMiddle) {
@@ -50,14 +50,14 @@
default: {}
case 2: {}
})");
- auto e = p->switch_stmt();
+ auto e = p->switch_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::SwitchStatement>());
- ASSERT_EQ(e->body.size(), 3u);
+ ASSERT_EQ(e->body.Length(), 3u);
ASSERT_FALSE(e->body[0]->IsDefault());
ASSERT_TRUE(e->body[1]->IsDefault());
ASSERT_FALSE(e->body[2]->IsDefault());
@@ -65,18 +65,18 @@
TEST_F(ParserImplTest, SwitchStmt_WithParens) {
auto p = parser("switch(a+b) { }");
- auto e = p->switch_stmt();
+ auto e = p->switch_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::SwitchStatement>());
- ASSERT_EQ(e->body.size(), 0u);
+ ASSERT_EQ(e->body.Length(), 0u);
}
TEST_F(ParserImplTest, SwitchStmt_InvalidExpression) {
auto p = parser("switch a=b {}");
- auto e = p->switch_stmt();
+ auto e = p->switch_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -86,7 +86,7 @@
TEST_F(ParserImplTest, SwitchStmt_MissingExpression) {
auto p = parser("switch {}");
- auto e = p->switch_stmt();
+ auto e = p->switch_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -96,7 +96,7 @@
TEST_F(ParserImplTest, SwitchStmt_MissingBracketLeft) {
auto p = parser("switch a }");
- auto e = p->switch_stmt();
+ auto e = p->switch_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -106,7 +106,7 @@
TEST_F(ParserImplTest, SwitchStmt_MissingBracketRight) {
auto p = parser("switch a {");
- auto e = p->switch_stmt();
+ auto e = p->switch_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -118,7 +118,7 @@
auto p = parser(R"(switch a {
case: {}
})");
- auto e = p->switch_stmt();
+ auto e = p->switch_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
diff --git a/src/tint/reader/wgsl/parser_impl_test.cc b/src/tint/reader/wgsl/parser_impl_test.cc
index 99ca25d..c234811 100644
--- a/src/tint/reader/wgsl/parser_impl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_test.cc
@@ -32,7 +32,7 @@
ASSERT_TRUE(p->Parse()) << p->error();
Program program = p->program();
- ASSERT_EQ(1u, program.AST().Functions().size());
+ ASSERT_EQ(1u, program.AST().Functions().Length());
}
TEST_F(ParserImplTest, Parses_ExtraSemicolons) {
@@ -52,8 +52,8 @@
ASSERT_TRUE(p->Parse()) << p->error();
Program program = p->program();
- ASSERT_EQ(1u, program.AST().Functions().size());
- ASSERT_EQ(1u, program.AST().TypeDecls().size());
+ ASSERT_EQ(1u, program.AST().Functions().Length());
+ ASSERT_EQ(1u, program.AST().TypeDecls().Length());
}
TEST_F(ParserImplTest, HandlesError) {
@@ -121,7 +121,7 @@
}/* block comments are OK at EOF...*/)");
ASSERT_TRUE(p->Parse()) << p->error();
- ASSERT_EQ(1u, p->program().AST().Functions().size());
+ ASSERT_EQ(1u, p->program().AST().Functions().Length());
}
TEST_F(ParserImplTest, Comments_UnterminatedBlockComment) {
diff --git a/src/tint/reader/wgsl/parser_impl_type_alias_test.cc b/src/tint/reader/wgsl/parser_impl_type_alias_test.cc
index ea5cbe2..c9bb72c 100644
--- a/src/tint/reader/wgsl/parser_impl_type_alias_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_type_alias_test.cc
@@ -20,7 +20,7 @@
TEST_F(ParserImplTest, TypeDecl_ParsesType) {
auto p = parser("type a = i32");
- auto t = p->type_alias();
+ auto t = p->type_alias_decl();
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(t.errored);
EXPECT_TRUE(t.matched);
@@ -35,7 +35,7 @@
TEST_F(ParserImplTest, TypeDecl_Parses_Ident) {
auto p = parser("type a = B");
- auto t = p->type_alias();
+ auto t = p->type_alias_decl();
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(t.errored);
EXPECT_TRUE(t.matched);
@@ -54,7 +54,7 @@
auto p = parser("type " + ident + " = i32");
- auto t = p->type_alias();
+ auto t = p->type_alias_decl();
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(t.errored);
EXPECT_TRUE(t.matched);
@@ -68,7 +68,7 @@
TEST_F(ParserImplTest, TypeDecl_MissingIdent) {
auto p = parser("type = i32");
- auto t = p->type_alias();
+ auto t = p->type_alias_decl();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
EXPECT_TRUE(p->has_error());
@@ -78,7 +78,7 @@
TEST_F(ParserImplTest, TypeDecl_InvalidIdent) {
auto p = parser("type 123 = i32");
- auto t = p->type_alias();
+ auto t = p->type_alias_decl();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
EXPECT_TRUE(p->has_error());
@@ -88,7 +88,7 @@
TEST_F(ParserImplTest, TypeDecl_MissingEqual) {
auto p = parser("type a i32");
- auto t = p->type_alias();
+ auto t = p->type_alias_decl();
EXPECT_TRUE(t.errored);
EXPECT_FALSE(t.matched);
EXPECT_TRUE(p->has_error());
diff --git a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
index 880f87a..1cf66c0 100644
--- a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
@@ -399,7 +399,7 @@
auto* a = t.value->As<ast::Array>();
ASSERT_FALSE(a->IsRuntimeArray());
ASSERT_TRUE(a->type->Is<ast::F32>());
- EXPECT_EQ(a->attributes.size(), 0u);
+ EXPECT_EQ(a->attributes.Length(), 0u);
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 14u}}));
auto* size = a->count->As<ast::IntLiteralExpression>();
@@ -420,7 +420,7 @@
auto* a = t.value->As<ast::Array>();
ASSERT_FALSE(a->IsRuntimeArray());
ASSERT_TRUE(a->type->Is<ast::F32>());
- EXPECT_EQ(a->attributes.size(), 0u);
+ EXPECT_EQ(a->attributes.Length(), 0u);
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 15u}}));
auto* size = a->count->As<ast::IntLiteralExpression>();
@@ -441,7 +441,7 @@
auto* a = t.value->As<ast::Array>();
ASSERT_FALSE(a->IsRuntimeArray());
ASSERT_TRUE(a->type->Is<ast::F32>());
- EXPECT_EQ(a->attributes.size(), 0u);
+ EXPECT_EQ(a->attributes.Length(), 0u);
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 15u}}));
auto* size = a->count->As<ast::IntLiteralExpression>();
@@ -461,7 +461,7 @@
auto* a = t.value->As<ast::Array>();
ASSERT_FALSE(a->IsRuntimeArray());
ASSERT_TRUE(a->type->Is<ast::F32>());
- EXPECT_EQ(a->attributes.size(), 0u);
+ EXPECT_EQ(a->attributes.Length(), 0u);
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
auto* count_expr = a->count->As<ast::IdentifierExpression>();
diff --git a/src/tint/reader/wgsl/parser_impl_variable_attribute_list_test.cc b/src/tint/reader/wgsl/parser_impl_variable_attribute_list_test.cc
index e1da7b7..2745e5f 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_attribute_list_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_attribute_list_test.cc
@@ -23,7 +23,7 @@
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(attrs.errored);
ASSERT_TRUE(attrs.matched);
- ASSERT_EQ(attrs.value.size(), 2u);
+ ASSERT_EQ(attrs.value.Length(), 2u);
auto* attr_0 = attrs.value[0]->As<ast::Attribute>();
auto* attr_1 = attrs.value[1]->As<ast::Attribute>();
@@ -42,7 +42,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
- EXPECT_TRUE(attrs.value.empty());
+ EXPECT_TRUE(attrs.value.IsEmpty());
EXPECT_EQ(p->error(), R"(1:2: expected attribute)");
}
@@ -52,7 +52,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
- EXPECT_TRUE(attrs.value.empty());
+ EXPECT_TRUE(attrs.value.IsEmpty());
EXPECT_EQ(p->error(), "1:10: invalid value for builtin attribute");
}
diff --git a/src/tint/reader/wgsl/parser_impl_variable_attribute_test.cc b/src/tint/reader/wgsl/parser_impl_variable_attribute_test.cc
index f338f62..ef77891 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_attribute_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_attribute_test.cc
@@ -235,7 +235,7 @@
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:18: invalid interpolation sampling");
+ EXPECT_EQ(p->error(), "1:18: expected identifier for interpolation sample name");
}
TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Center) {
@@ -329,7 +329,7 @@
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:13: invalid interpolation type");
+ EXPECT_EQ(p->error(), "1:13: expected identifier for interpolation type name");
}
TEST_F(ParserImplTest, Attribute_Interpolate_InvalidFirstValue) {
diff --git a/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc b/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
index 3ed0948..2fee83c 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
@@ -88,6 +88,17 @@
EXPECT_EQ(v->source.range.end.column, 20u);
}
+TEST_F(ParserImplTest, VariableDecl_WithPushConstant) {
+ auto p = parser("var<push_constant> my_var : f32");
+ auto v = p->variable_decl();
+ EXPECT_TRUE(v.matched);
+ EXPECT_FALSE(v.errored);
+ EXPECT_FALSE(p->has_error());
+ EXPECT_EQ(v->name, "my_var");
+ EXPECT_TRUE(v->type->Is<ast::F32>());
+ EXPECT_EQ(v->storage_class, ast::StorageClass::kPushConstant);
+}
+
TEST_F(ParserImplTest, VariableDecl_InvalidStorageClass) {
auto p = parser("var<unknown> my_var : f32");
auto v = p->variable_decl();
diff --git a/src/tint/reader/wgsl/parser_impl_variable_ident_decl_test.cc b/src/tint/reader/wgsl/parser_impl_variable_ident_decl_test.cc
index a811a82..2679983 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_ident_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_ident_decl_test.cc
@@ -19,7 +19,7 @@
TEST_F(ParserImplTest, VariableIdentDecl_Parses) {
auto p = parser("my_var : f32");
- auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ false);
+ auto decl = p->expect_variable_ident_decl("test");
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var");
@@ -32,7 +32,7 @@
TEST_F(ParserImplTest, VariableIdentDecl_Parses_AllowInferredType) {
auto p = parser("my_var : f32");
- auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ true);
+ auto decl = p->expect_ident_or_variable_ident_decl("test");
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var");
@@ -45,14 +45,14 @@
TEST_F(ParserImplTest, VariableIdentDecl_Inferred_Parse_Failure) {
auto p = parser("my_var = 1.0");
- auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ false);
+ auto decl = p->expect_variable_ident_decl("test");
ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:8: expected ':' for test");
}
TEST_F(ParserImplTest, VariableIdentDecl_Inferred_Parses_AllowInferredType) {
auto p = parser("my_var = 1.0");
- auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ true);
+ auto decl = p->expect_ident_or_variable_ident_decl("test");
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var");
@@ -63,7 +63,7 @@
TEST_F(ParserImplTest, VariableIdentDecl_MissingIdent) {
auto p = parser(": f32");
- auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ false);
+ auto decl = p->expect_variable_ident_decl("test");
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:1: expected identifier for test");
@@ -71,7 +71,7 @@
TEST_F(ParserImplTest, VariableIdentDecl_MissingIdent_AllowInferredType) {
auto p = parser(": f32");
- auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ true);
+ auto decl = p->expect_ident_or_variable_ident_decl("test");
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:1: expected identifier for test");
@@ -79,7 +79,7 @@
TEST_F(ParserImplTest, VariableIdentDecl_MissingType) {
auto p = parser("my_var :");
- auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ false);
+ auto decl = p->expect_variable_ident_decl("test");
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:9: invalid type for test");
@@ -87,7 +87,7 @@
TEST_F(ParserImplTest, VariableIdentDecl_MissingType_AllowInferredType) {
auto p = parser("my_var :");
- auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ true);
+ auto decl = p->expect_ident_or_variable_ident_decl("test");
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:9: invalid type for test");
@@ -95,7 +95,7 @@
TEST_F(ParserImplTest, VariableIdentDecl_InvalidIdent) {
auto p = parser("123 : f32");
- auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ false);
+ auto decl = p->expect_variable_ident_decl("test");
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:1: expected identifier for test");
@@ -103,7 +103,7 @@
TEST_F(ParserImplTest, VariableIdentDecl_InvalidIdent_AllowInferredType) {
auto p = parser("123 : f32");
- auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ true);
+ auto decl = p->expect_ident_or_variable_ident_decl("test");
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:1: expected identifier for test");
diff --git a/src/tint/reader/wgsl/parser_impl_variable_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_variable_stmt_test.cc
index 21ab6a8..c370262 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_stmt_test.cc
@@ -19,7 +19,7 @@
TEST_F(ParserImplTest, VariableStmt_VariableDecl) {
auto p = parser("var a : i32;");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -38,7 +38,7 @@
TEST_F(ParserImplTest, VariableStmt_VariableDecl_WithInit) {
auto p = parser("var a : i32 = 1;");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -58,7 +58,7 @@
TEST_F(ParserImplTest, VariableStmt_VariableDecl_ConstructorInvalid) {
auto p = parser("var a : i32 = if(a) {}");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -68,7 +68,7 @@
TEST_F(ParserImplTest, VariableStmt_VariableDecl_ArrayInit) {
auto p = parser("var a : array<i32> = array<i32>();");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -86,7 +86,7 @@
TEST_F(ParserImplTest, VariableStmt_VariableDecl_ArrayInit_NoSpace) {
auto p = parser("var a : array<i32>=array<i32>();");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -104,7 +104,7 @@
TEST_F(ParserImplTest, VariableStmt_VariableDecl_VecInit) {
auto p = parser("var a : vec2<i32> = vec2<i32>();");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -122,7 +122,7 @@
TEST_F(ParserImplTest, VariableStmt_VariableDecl_VecInit_NoSpace) {
auto p = parser("var a : vec2<i32>=vec2<i32>();");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -140,7 +140,7 @@
TEST_F(ParserImplTest, VariableStmt_Let) {
auto p = parser("let a : i32 = 1");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@@ -155,7 +155,7 @@
TEST_F(ParserImplTest, VariableStmt_Let_MissingEqual) {
auto p = parser("let a : i32 1");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -165,7 +165,7 @@
TEST_F(ParserImplTest, VariableStmt_Let_MissingConstructor) {
auto p = parser("let a : i32 =");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@@ -175,7 +175,7 @@
TEST_F(ParserImplTest, VariableStmt_Let_InvalidConstructor) {
auto p = parser("let a : i32 = if (a) {}");
- auto e = p->variable_stmt();
+ auto e = p->variable_statement();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
diff --git a/src/tint/reader/wgsl/parser_impl_while_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_while_stmt_test.cc
index 45c4990..247f340 100644
--- a/src/tint/reader/wgsl/parser_impl_while_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_while_stmt_test.cc
@@ -24,7 +24,7 @@
// Test an empty while loop.
TEST_F(WhileStmtTest, Empty) {
auto p = parser("while (true) { }");
- auto wl = p->while_stmt();
+ auto wl = p->while_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(wl.errored);
ASSERT_TRUE(wl.matched);
@@ -35,19 +35,19 @@
// Test a while loop with non-empty body.
TEST_F(WhileStmtTest, Body) {
auto p = parser("while (true) { discard; }");
- auto wl = p->while_stmt();
+ auto wl = p->while_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(wl.errored);
ASSERT_TRUE(wl.matched);
EXPECT_TRUE(Is<ast::Expression>(wl->condition));
- ASSERT_EQ(wl->body->statements.size(), 1u);
+ ASSERT_EQ(wl->body->statements.Length(), 1u);
EXPECT_TRUE(wl->body->statements[0]->Is<ast::DiscardStatement>());
}
// Test a while loop with complex condition.
TEST_F(WhileStmtTest, ComplexCondition) {
auto p = parser("while ((a + 1 - 2) == 3) { }");
- auto wl = p->while_stmt();
+ auto wl = p->while_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(wl.errored);
ASSERT_TRUE(wl.matched);
@@ -58,7 +58,7 @@
// Test a while loop with no brackets.
TEST_F(WhileStmtTest, NoBrackets) {
auto p = parser("while (a + 1 - 2) == 3 { }");
- auto wl = p->while_stmt();
+ auto wl = p->while_statement();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(wl.errored);
ASSERT_TRUE(wl.matched);
@@ -70,7 +70,7 @@
public:
void TestForWithError(std::string for_str, std::string error_str) {
auto p_for = parser(for_str);
- auto e_for = p_for->while_stmt();
+ auto e_for = p_for->while_statement();
EXPECT_FALSE(e_for.matched);
EXPECT_TRUE(e_for.errored);
diff --git a/src/tint/reader/wgsl/parser_test.cc b/src/tint/reader/wgsl/parser_test.cc
index 1f0e206..860120c 100644
--- a/src/tint/reader/wgsl/parser_test.cc
+++ b/src/tint/reader/wgsl/parser_test.cc
@@ -41,7 +41,7 @@
auto errs = diag::Formatter().format(program.Diagnostics());
ASSERT_TRUE(program.IsValid()) << errs;
- ASSERT_EQ(1u, program.AST().Functions().size());
+ ASSERT_EQ(1u, program.AST().Functions().Length());
}
TEST_F(ParserTest, HandlesError) {
diff --git a/src/tint/reader/wgsl/token.cc b/src/tint/reader/wgsl/token.cc
index a7b437f..ac5eb08 100644
--- a/src/tint/reader/wgsl/token.cc
+++ b/src/tint/reader/wgsl/token.cc
@@ -130,6 +130,10 @@
return "|=";
case Token::Type::kXorEqual:
return "^=";
+ case Token::Type::kShiftLeftEqual:
+ return "<<=";
+ case Token::Type::kShiftRightEqual:
+ return ">>=";
case Token::Type::kArray:
return "array";
@@ -173,8 +177,6 @@
return "i32";
case Token::Type::kIf:
return "if";
- case Token::Type::kImport:
- return "import";
case Token::Type::kLet:
return "let";
case Token::Type::kLoop:
@@ -207,6 +209,8 @@
return "sampler";
case Token::Type::kComparisonSampler:
return "sampler_comparison";
+ case Token::Type::kStaticAssert:
+ return "static_assert";
case Token::Type::kStruct:
return "struct";
case Token::Type::kSwitch:
diff --git a/src/tint/reader/wgsl/token.h b/src/tint/reader/wgsl/token.h
index 352c18f..68cb6c6 100644
--- a/src/tint/reader/wgsl/token.h
+++ b/src/tint/reader/wgsl/token.h
@@ -140,6 +140,10 @@
kOrEqual,
/// A '^='
kXorEqual,
+ /// A '>>='
+ kShiftRightEqual,
+ /// A '<<='
+ kShiftLeftEqual,
/// A 'array'
kArray,
@@ -183,8 +187,6 @@
kI32,
/// A 'if'
kIf,
- /// A 'import'
- kImport,
/// A 'let'
kLet,
/// A 'loop'
@@ -217,6 +219,8 @@
kSampler,
/// A 'sampler_comparison'
kComparisonSampler,
+ /// A 'static_assert'
+ kStaticAssert,
/// A 'struct'
kStruct,
/// A 'switch'
diff --git a/src/tint/resolver/array_accessor_test.cc b/src/tint/resolver/array_accessor_test.cc
index 0f72cf8..a07f6df 100644
--- a/src/tint/resolver/array_accessor_test.cc
+++ b/src/tint/resolver/array_accessor_test.cc
@@ -282,8 +282,8 @@
auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
auto* acc = IndexAccessor("a", Expr(Source{{12, 34}}, idx));
auto* f = Var("f", ty.f32(), acc);
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(a),
Decl(idx),
Decl(f),
@@ -303,8 +303,8 @@
// var f : f32 = a[2.0f];
auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
auto* f = Var("a_2", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, 2_f)));
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(a),
Decl(f),
});
@@ -318,8 +318,8 @@
auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
auto* acc = IndexAccessor("a", 2_i);
auto* f = Var("a_2", ty.f32(), acc);
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(a),
Decl(f),
});
@@ -342,7 +342,7 @@
auto* star_p = Deref(p);
auto* acc = IndexAccessor(Source{{12, 34}}, star_p, idx);
auto* x = Var("x", ty.f32(), acc);
- Func("func", {p}, ty.f32(), {Decl(idx), Decl(x), Return(x)});
+ Func("func", utils::Vector{p}, ty.f32(), utils::Vector{Decl(idx), Decl(x), Return(x)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -363,7 +363,7 @@
auto* accessor_expr = IndexAccessor(Source{{12, 34}}, p, idx);
auto* star_p = Deref(accessor_expr);
auto* x = Var("x", ty.f32(), star_p);
- Func("func", {p}, ty.f32(), {Decl(idx), Decl(x), Return(x)});
+ Func("func", utils::Vector{p}, ty.f32(), utils::Vector{Decl(idx), Decl(x), Return(x)});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
diff --git a/src/tint/resolver/assignment_validation_test.cc b/src/tint/resolver/assignment_validation_test.cc
index e204a62..d6a7e5c 100644
--- a/src/tint/resolver/assignment_validation_test.cc
+++ b/src/tint/resolver/assignment_validation_test.cc
@@ -29,9 +29,11 @@
// struct S { m : i32 };
// @group(0) @binding(0)
// var<storage,read> a : S;
- auto* s = Structure("S", {Member("m", ty.i32())});
+ auto* s = Structure("S", utils::Vector{
+ Member("m", ty.i32()),
+ });
GlobalVar(Source{{12, 34}}, "a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -236,12 +238,12 @@
};
GlobalVar("a", make_type(), ast::StorageClass::kNone,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
GlobalVar("b", make_type(), ast::StorageClass::kNone,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(0u),
});
@@ -257,9 +259,11 @@
// @group(0) @binding(0) var<storage, read_write> v : S;
// v.a = v.a;
- auto* s = Structure("S", {Member("a", ty.atomic(ty.i32()))});
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.atomic(ty.i32())),
+ });
GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -275,9 +279,11 @@
// @group(0) @binding(0) var<storage, read_write> v : S;
// v.a = v.a;
- auto* s = Structure("S", {Member("a", ty.array(ty.f32()))});
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.array(ty.f32())),
+ });
GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -296,7 +302,9 @@
// fn f() {
// _ = s;
// }
- auto* s = Structure("S", {Member("arr", ty.array<i32>())});
+ auto* s = Structure("S", utils::Vector{
+ Member("arr", ty.array<i32>()),
+ });
GlobalVar("s", ty.Of(s), ast::StorageClass::kStorage, GroupAndBinding(0, 0));
WrapInFunction(Assign(Phony(), Expr(Source{{12, 34}}, "s")));
@@ -316,7 +324,9 @@
// fn f() {
// _ = s.arr;
// }
- auto* s = Structure("S", {Member("arr", ty.array<i32>())});
+ auto* s = Structure("S", utils::Vector{
+ Member("arr", ty.array<i32>()),
+ });
GlobalVar("s", ty.Of(s), ast::StorageClass::kStorage, GroupAndBinding(0, 0));
WrapInFunction(Assign(Phony(), MemberAccessor(Source{{12, 34}}, "s", "arr")));
@@ -360,11 +370,13 @@
// _ = wg;
// _ = wg[3i];
// }
- auto* S = Structure("S", {
+ auto* S = Structure("S", utils::Vector{
Member("i", ty.i32()),
Member("arr", ty.array<i32>()),
});
- auto* U = Structure("U", {Member("i", ty.i32())});
+ auto* U = Structure("U", utils::Vector{
+ Member("i", ty.i32()),
+ });
GlobalVar("tex", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
GroupAndBinding(0, 0));
GlobalVar("smp", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(0, 1));
diff --git a/src/tint/resolver/atomics_test.cc b/src/tint/resolver/atomics_test.cc
index 09ca0ba..d7b3824 100644
--- a/src/tint/resolver/atomics_test.cc
+++ b/src/tint/resolver/atomics_test.cc
@@ -45,9 +45,9 @@
}
TEST_F(ResolverAtomicTest, GlobalStorageStruct) {
- auto* s = Structure("s", {Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
+ auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
auto* g = GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
diff --git a/src/tint/resolver/atomics_validation_test.cc b/src/tint/resolver/atomics_validation_test.cc
index 5ec4e01..0961397 100644
--- a/src/tint/resolver/atomics_validation_test.cc
+++ b/src/tint/resolver/atomics_validation_test.cc
@@ -40,7 +40,7 @@
}
TEST_F(ResolverAtomicValidationTest, StorageClass_Storage_Struct) {
- auto* s = Structure("s", {Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
+ auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
GroupAndBinding(0, 0));
@@ -73,7 +73,7 @@
}
TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_Struct) {
- auto* s = Structure("s", {Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
+ auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
@@ -88,8 +88,9 @@
// struct Outer { m : array<Inner, 4>; };
// var<private> g : Outer;
- auto* Inner = Structure("Inner", {Member("m", ty.atomic(Source{{12, 34}}, ty.i32()))});
- auto* Outer = Structure("Outer", {Member("m", ty.Of(Inner))});
+ auto* Inner =
+ Structure("Inner", utils::Vector{Member("m", ty.atomic(Source{{12, 34}}, ty.i32()))});
+ auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
GlobalVar("g", ty.Of(Outer), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
@@ -104,8 +105,9 @@
// struct Outer { m : array<Inner, 4>; };
// var<private> g : Outer;
- auto* Inner = Structure("Inner", {Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
- auto* Outer = Structure("Outer", {Member("m", ty.Of(Inner))});
+ auto* Inner =
+ Structure("Inner", utils::Vector{Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
+ auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
GlobalVar("g", ty.Of(Outer), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
@@ -135,7 +137,7 @@
// };
// var<private> v: array<S, 5u>;
- auto* s = Structure("S", {Member("m", ty.atomic<u32>())});
+ auto* s = Structure("S", utils::Vector{Member("m", ty.atomic<u32>())});
GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
@@ -154,7 +156,7 @@
auto* atomic_array =
Alias(Source{{12, 34}}, "AtomicArray", ty.atomic(Source{{12, 34}}, ty.i32()));
- auto* s = Structure("S", {Member("m", ty.Of(atomic_array))});
+ auto* s = Structure("S", utils::Vector{Member("m", ty.Of(atomic_array))});
GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
@@ -185,17 +187,17 @@
auto* array_atomic_u32_8 = ty.array(ty.atomic(ty.u32()), 8_u);
auto* array_atomic_i32_4 = ty.array(ty.atomic(ty.i32()), 4_u);
- auto* s6 = Structure("S6", {Member("x", array_i32_4)});
- auto* s5 = Structure("S5", {Member("x", ty.Of(s6)), //
- Member("y", ty.Of(atomic_array)), //
- Member("z", array_atomic_u32_8)}); //
- auto* s4 = Structure("S4", {Member("x", ty.Of(s6)), //
- Member("y", ty.Of(s5)), //
- Member("z", array_atomic_i32_4)}); //
- auto* s3 = Structure("S3", {Member("x", ty.Of(s4))});
- auto* s2 = Structure("S2", {Member("x", ty.Of(s3))});
- auto* s1 = Structure("S1", {Member("x", ty.Of(s2))});
- auto* s0 = Structure("S0", {Member("x", ty.Of(s1))});
+ auto* s6 = Structure("S6", utils::Vector{Member("x", array_i32_4)});
+ auto* s5 = Structure("S5", utils::Vector{Member("x", ty.Of(s6)), //
+ Member("y", ty.Of(atomic_array)), //
+ Member("z", array_atomic_u32_8)}); //
+ auto* s4 = Structure("S4", utils::Vector{Member("x", ty.Of(s6)), //
+ Member("y", ty.Of(s5)), //
+ Member("z", array_atomic_i32_4)}); //
+ auto* s3 = Structure("S3", utils::Vector{Member("x", ty.Of(s4))});
+ auto* s2 = Structure("S2", utils::Vector{Member("x", ty.Of(s3))});
+ auto* s1 = Structure("S1", utils::Vector{Member("x", ty.Of(s2))});
+ auto* s0 = Structure("S0", utils::Vector{Member("x", ty.Of(s1))});
GlobalVar(Source{{56, 78}}, "g", ty.Of(s0), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
@@ -206,7 +208,7 @@
}
TEST_F(ResolverAtomicValidationTest, Struct_AccessMode_Read) {
- auto* s = Structure("s", {Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
+ auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
GroupAndBinding(0, 0));
@@ -218,7 +220,7 @@
}
TEST_F(ResolverAtomicValidationTest, InvalidAccessMode_Struct) {
- auto* s = Structure("s", {Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
+ auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
GroupAndBinding(0, 0));
@@ -234,8 +236,9 @@
// struct Outer { m : array<Inner, 4>; };
// var<storage, read> g : Outer;
- auto* Inner = Structure("Inner", {Member("m", ty.atomic(Source{{12, 34}}, ty.i32()))});
- auto* Outer = Structure("Outer", {Member("m", ty.Of(Inner))});
+ auto* Inner =
+ Structure("Inner", utils::Vector{Member("m", ty.atomic(Source{{12, 34}}, ty.i32()))});
+ auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::StorageClass::kStorage, ast::Access::kRead,
GroupAndBinding(0, 0));
@@ -251,8 +254,9 @@
// struct Outer { m : array<Inner, 4>; };
// var<storage, read> g : Outer;
- auto* Inner = Structure("Inner", {Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
- auto* Outer = Structure("Outer", {Member("m", ty.Of(Inner))});
+ auto* Inner =
+ Structure("Inner", utils::Vector{Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
+ auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::StorageClass::kStorage, ast::Access::kRead,
GroupAndBinding(0, 0));
@@ -284,17 +288,17 @@
auto* array_atomic_u32_8 = ty.array(ty.atomic(ty.u32()), 8_u);
auto* array_atomic_i32_4 = ty.array(ty.atomic(ty.i32()), 4_u);
- auto* s6 = Structure("S6", {Member("x", array_i32_4)});
- auto* s5 = Structure("S5", {Member("x", ty.Of(s6)), //
- Member("y", ty.Of(atomic_array)), //
- Member("z", array_atomic_u32_8)}); //
- auto* s4 = Structure("S4", {Member("x", ty.Of(s6)), //
- Member("y", ty.Of(s5)), //
- Member("z", array_atomic_i32_4)}); //
- auto* s3 = Structure("S3", {Member("x", ty.Of(s4))});
- auto* s2 = Structure("S2", {Member("x", ty.Of(s3))});
- auto* s1 = Structure("S1", {Member("x", ty.Of(s2))});
- auto* s0 = Structure("S0", {Member("x", ty.Of(s1))});
+ auto* s6 = Structure("S6", utils::Vector{Member("x", array_i32_4)});
+ auto* s5 = Structure("S5", utils::Vector{Member("x", ty.Of(s6)), //
+ Member("y", ty.Of(atomic_array)), //
+ Member("z", array_atomic_u32_8)}); //
+ auto* s4 = Structure("S4", utils::Vector{Member("x", ty.Of(s6)), //
+ Member("y", ty.Of(s5)), //
+ Member("z", array_atomic_i32_4)}); //
+ auto* s3 = Structure("S3", utils::Vector{Member("x", ty.Of(s4))});
+ auto* s2 = Structure("S2", utils::Vector{Member("x", ty.Of(s3))});
+ auto* s1 = Structure("S1", utils::Vector{Member("x", ty.Of(s2))});
+ auto* s0 = Structure("S0", utils::Vector{Member("x", ty.Of(s1))});
GlobalVar(Source{{56, 78}}, "g", ty.Of(s0), ast::StorageClass::kStorage, ast::Access::kRead,
GroupAndBinding(0, 0));
diff --git a/src/tint/resolver/attribute_validation_test.cc b/src/tint/resolver/attribute_validation_test.cc
index 36221e2..ed0227e 100644
--- a/src/tint/resolver/attribute_validation_test.cc
+++ b/src/tint/resolver/attribute_validation_test.cc
@@ -84,9 +84,9 @@
};
struct TestWithParams : ResolverTestWithParam<TestParams> {};
-static ast::AttributeList createAttributes(const Source& source,
- ProgramBuilder& builder,
- AttributeKind kind) {
+static utils::Vector<const ast::Attribute*, 2> createAttributes(const Source& source,
+ ProgramBuilder& builder,
+ AttributeKind kind) {
switch (kind) {
case AttributeKind::kAlign:
return {builder.create<ast::StructMemberAlignAttribute>(source, 4u)};
@@ -128,10 +128,10 @@
auto& params = GetParam();
Func("main",
- {
+ utils::Vector{
Param("a", ty.vec4<f32>(), createAttributes({}, *this, params.kind)),
},
- ty.void_(), {});
+ ty.void_(), utils::Empty);
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -163,11 +163,11 @@
TEST_P(FunctionReturnTypeAttributeTest, IsValid) {
auto& params = GetParam();
- Func("main", {}, ty.f32(),
- {
+ Func("main", utils::Empty, ty.f32(),
+ utils::Vector{
Return(1_f),
},
- {}, createAttributes({}, *this, params.kind));
+ utils::Empty, createAttributes({}, *this, params.kind));
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -201,11 +201,11 @@
TEST_P(ComputeShaderParameterAttributeTest, IsValid) {
auto& params = GetParam();
Func("main",
- {
+ utils::Vector{
Param("a", ty.vec4<f32>(), createAttributes(Source{{12, 34}}, *this, params.kind)),
},
- ty.void_(), {},
- {
+ ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -250,11 +250,11 @@
auto& params = GetParam();
auto attrs = createAttributes(Source{{12, 34}}, *this, params.kind);
if (params.kind != AttributeKind::kBuiltin && params.kind != AttributeKind::kLocation) {
- attrs.push_back(Builtin(Source{{34, 56}}, ast::BuiltinValue::kPosition));
+ attrs.Push(Builtin(Source{{34, 56}}, ast::BuiltinValue::kPosition));
}
auto* p = Param("a", ty.vec4<f32>(), attrs);
- Func("frag_main", {p}, ty.void_(), {},
- {
+ Func("frag_main", utils::Vector{p}, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -287,17 +287,17 @@
auto& params = GetParam();
auto attrs = createAttributes(Source{{12, 34}}, *this, params.kind);
if (params.kind != AttributeKind::kLocation) {
- attrs.push_back(Location(Source{{34, 56}}, 2));
+ attrs.Push(Location(Source{{34, 56}}, 2));
}
auto* p = Param("a", ty.vec4<f32>(), attrs);
- Func("vertex_main", {p}, ty.vec4<f32>(),
- {
+ Func("vertex_main", utils::Vector{p}, ty.vec4<f32>(),
+ utils::Vector{
Return(Construct(ty.vec4<f32>())),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kVertex),
},
- {
+ utils::Vector{
Builtin(ast::BuiltinValue::kPosition),
});
@@ -338,11 +338,11 @@
using ComputeShaderReturnTypeAttributeTest = TestWithParams;
TEST_P(ComputeShaderReturnTypeAttributeTest, IsValid) {
auto& params = GetParam();
- Func("main", {}, ty.vec4<f32>(),
- {
+ Func("main", utils::Empty, ty.vec4<f32>(),
+ utils::Vector{
Return(Construct(ty.vec4<f32>(), 1_f)),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
},
@@ -389,9 +389,10 @@
TEST_P(FragmentShaderReturnTypeAttributeTest, IsValid) {
auto& params = GetParam();
auto attrs = createAttributes(Source{{12, 34}}, *this, params.kind);
- attrs.push_back(Location(Source{{34, 56}}, 2));
- Func("frag_main", {}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
- {
+ attrs.Push(Location(Source{{34, 56}}, 2));
+ Func("frag_main", utils::Empty, ty.vec4<f32>(),
+ utils::Vector{Return(Construct(ty.vec4<f32>()))},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
attrs);
@@ -442,13 +443,13 @@
auto attrs = createAttributes(Source{{12, 34}}, *this, params.kind);
// a vertex shader must include the 'position' builtin in its return type
if (params.kind != AttributeKind::kBuiltin) {
- attrs.push_back(Builtin(Source{{34, 56}}, ast::BuiltinValue::kPosition));
+ attrs.Push(Builtin(Source{{34, 56}}, ast::BuiltinValue::kPosition));
}
- Func("vertex_main", {}, ty.vec4<f32>(),
- {
+ Func("vertex_main", utils::Empty, ty.vec4<f32>(),
+ utils::Vector{
Return(Construct(ty.vec4<f32>())),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kVertex),
},
attrs);
@@ -487,14 +488,14 @@
using EntryPointParameterAttributeTest = TestWithParams;
TEST_F(EntryPointParameterAttributeTest, DuplicateAttribute) {
- Func("main", {}, ty.f32(),
- {
+ Func("main", utils::Empty, ty.f32(),
+ utils::Vector{
Return(1_f),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(Source{{12, 34}}, 2),
Location(Source{{56, 78}}, 3),
});
@@ -507,14 +508,14 @@
TEST_F(EntryPointParameterAttributeTest, DuplicateInternalAttribute) {
auto* s = Param("s", ty.sampler(ast::SamplerKind::kSampler),
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
Disable(ast::DisabledValidation::kBindingPointCollision),
Disable(ast::DisabledValidation::kEntryPointParameter),
});
- Func("f", {s}, ty.void_(), {},
- {
+ Func("f", utils::Vector{s}, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -523,14 +524,14 @@
using EntryPointReturnTypeAttributeTest = ResolverTest;
TEST_F(EntryPointReturnTypeAttributeTest, DuplicateAttribute) {
- Func("main", {}, ty.f32(),
- {
+ Func("main", utils::Empty, ty.f32(),
+ utils::Vector{
Return(1_f),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- ast::AttributeList{
+ utils::Vector{
Location(Source{{12, 34}}, 2),
Location(Source{{56, 78}}, 3),
});
@@ -542,11 +543,11 @@
}
TEST_F(EntryPointReturnTypeAttributeTest, DuplicateInternalAttribute) {
- Func("f", {}, ty.i32(), {Return(1_i)},
- {
+ Func("f", utils::Empty, ty.i32(), utils::Vector{Return(1_i)},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- ast::AttributeList{
+ utils::Vector{
Disable(ast::DisabledValidation::kBindingPointCollision),
Disable(ast::DisabledValidation::kEntryPointParameter),
});
@@ -561,7 +562,7 @@
TEST_P(StructAttributeTest, IsValid) {
auto& params = GetParam();
- auto* str = create<ast::Struct>(Sym("mystruct"), ast::StructMemberList{Member("a", ty.f32())},
+ auto* str = create<ast::Struct>(Sym("mystruct"), utils::Vector{Member("a", ty.f32())},
createAttributes(Source{{12, 34}}, *this, params.kind));
AST().AddGlobalDeclaration(str);
@@ -592,16 +593,14 @@
using StructMemberAttributeTest = TestWithParams;
TEST_P(StructMemberAttributeTest, IsValid) {
auto& params = GetParam();
- ast::StructMemberList members;
+ utils::Vector<const ast::StructMember*, 1> members;
if (params.kind == AttributeKind::kBuiltin) {
- members.push_back(
- {Member("a", ty.vec4<f32>(), createAttributes(Source{{12, 34}}, *this, params.kind))});
+ members.Push(
+ Member("a", ty.vec4<f32>(), createAttributes(Source{{12, 34}}, *this, params.kind)));
} else {
- members.push_back(
- {Member("a", ty.f32(), createAttributes(Source{{12, 34}}, *this, params.kind))});
+ members.Push(Member("a", ty.f32(), createAttributes(Source{{12, 34}}, *this, params.kind)));
}
Structure("mystruct", members);
- WrapInFunction();
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
@@ -627,38 +626,35 @@
TestParams{AttributeKind::kBindingAndGroup, false}));
TEST_F(StructMemberAttributeTest, DuplicateAttribute) {
Structure("mystruct",
- {
+ utils::Vector{
Member("a", ty.i32(),
- {
+ utils::Vector{
create<ast::StructMemberAlignAttribute>(Source{{12, 34}}, 4u),
create<ast::StructMemberAlignAttribute>(Source{{56, 78}}, 8u),
}),
});
- WrapInFunction();
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(56:78 error: duplicate align attribute
12:34 note: first attribute declared here)");
}
TEST_F(StructMemberAttributeTest, InvariantAttributeWithPosition) {
- Structure("mystruct", {
+ Structure("mystruct", utils::Vector{
Member("a", ty.vec4<f32>(),
- {
+ utils::Vector{
Invariant(),
Builtin(ast::BuiltinValue::kPosition),
}),
});
- WrapInFunction();
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(StructMemberAttributeTest, InvariantAttributeWithoutPosition) {
- Structure("mystruct", {
+ Structure("mystruct", utils::Vector{
Member("a", ty.vec4<f32>(),
- {
+ utils::Vector{
Invariant(Source{{12, 34}}),
}),
});
- WrapInFunction();
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: invariant attribute must only be applied to a "
@@ -672,12 +668,10 @@
auto& params = GetParam();
auto* arr = ty.array(ty.f32(), nullptr, createAttributes(Source{{12, 34}}, *this, params.kind));
- Structure("mystruct", {
+ Structure("mystruct", utils::Vector{
Member("a", arr),
});
- WrapInFunction();
-
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
@@ -714,8 +708,6 @@
createAttributes(Source{{12, 34}}, *this, params.kind));
}
- WrapInFunction();
-
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
@@ -744,14 +736,12 @@
TEST_F(VariableAttributeTest, DuplicateAttribute) {
GlobalVar("a", ty.sampler(ast::SamplerKind::kSampler),
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(Source{{12, 34}}, 2u),
create<ast::GroupAttribute>(2u),
create<ast::BindingAttribute>(Source{{56, 78}}, 3u),
});
- WrapInFunction();
-
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(56:78 error: duplicate binding attribute
@@ -760,7 +750,7 @@
TEST_F(VariableAttributeTest, LocalVariable) {
auto* v = Var("a", ty.f32(),
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(Source{{12, 34}}, 2u),
});
@@ -777,8 +767,6 @@
GlobalConst("a", ty.f32(), Expr(1.23_f),
createAttributes(Source{{12, 34}}, *this, params.kind));
- WrapInFunction();
-
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
@@ -806,13 +794,11 @@
TEST_F(ConstantAttributeTest, DuplicateAttribute) {
GlobalConst("a", ty.f32(), Expr(1.23_f),
- ast::AttributeList{
+ utils::Vector{
create<ast::IdAttribute>(Source{{12, 34}}, 0u),
create<ast::IdAttribute>(Source{{56, 78}}, 1u),
});
- WrapInFunction();
-
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(56:78 error: duplicate id attribute
@@ -825,8 +811,6 @@
Override("a", ty.f32(), Expr(1.23_f), createAttributes(Source{{12, 34}}, *this, params.kind));
- WrapInFunction();
-
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
@@ -853,13 +837,11 @@
TEST_F(OverrideAttributeTest, DuplicateAttribute) {
Override("a", ty.f32(), Expr(1.23_f),
- ast::AttributeList{
+ utils::Vector{
create<ast::IdAttribute>(Source{{12, 34}}, 0u),
create<ast::IdAttribute>(Source{{56, 78}}, 1u),
});
- WrapInFunction();
-
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(56:78 error: duplicate id attribute
@@ -895,8 +877,10 @@
<< ", should_pass: " << params.should_pass;
SCOPED_TRACE(ss.str());
- auto* arr =
- ty.array(el_ty, 4_u, {create<ast::StrideAttribute>(Source{{12, 34}}, params.stride)});
+ auto* arr = ty.array(el_ty, 4_u,
+ utils::Vector{
+ create<ast::StrideAttribute>(Source{{12, 34}}, params.stride),
+ });
GlobalVar("myarray", arr, ast::StorageClass::kPrivate);
@@ -976,7 +960,7 @@
TEST_F(ArrayStrideTest, DuplicateAttribute) {
auto* arr = ty.array(Source{{12, 34}}, ty.i32(), 4_u,
- {
+ utils::Vector{
create<ast::StrideAttribute>(Source{{12, 34}}, 4u),
create<ast::StrideAttribute>(Source{{56, 78}}, 4u),
});
@@ -997,7 +981,9 @@
using ResourceAttributeTest = ResolverTest;
TEST_F(ResourceAttributeTest, UniformBufferMissingBinding) {
- auto* s = Structure("S", {Member("x", ty.i32())});
+ auto* s = Structure("S", utils::Vector{
+ Member("x", ty.i32()),
+ });
GlobalVar(Source{{12, 34}}, "G", ty.Of(s), ast::StorageClass::kUniform);
EXPECT_FALSE(r()->Resolve());
@@ -1006,7 +992,9 @@
}
TEST_F(ResourceAttributeTest, StorageBufferMissingBinding) {
- auto* s = Structure("S", {Member("x", ty.i32())});
+ auto* s = Structure("S", utils::Vector{
+ Member("x", ty.i32()),
+ });
GlobalVar(Source{{12, 34}}, "G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead);
EXPECT_FALSE(r()->Resolve());
@@ -1035,7 +1023,7 @@
TEST_F(ResourceAttributeTest, BindingPairMissingBinding) {
GlobalVar(Source{{12, 34}}, "G", ty.sampler(ast::SamplerKind::kSampler),
ast::StorageClass::kNone,
- ast::AttributeList{
+ utils::Vector{
create<ast::GroupAttribute>(1u),
});
@@ -1047,7 +1035,7 @@
TEST_F(ResourceAttributeTest, BindingPairMissingGroup) {
GlobalVar(Source{{12, 34}}, "G", ty.sampler(ast::SamplerKind::kSampler),
ast::StorageClass::kNone,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
});
@@ -1059,25 +1047,25 @@
TEST_F(ResourceAttributeTest, BindingPointUsedTwiceByEntryPoint) {
GlobalVar(Source{{12, 34}}, "A", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
ast::StorageClass::kNone,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
GlobalVar(Source{{56, 78}}, "B", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
ast::StorageClass::kNone,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("F", {}, ty.void_(),
- {
+ Func("F", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.vec4<f32>(), ast::StorageClass::kNone,
Call("textureLoad", "A", vec2<i32>(1_i, 2_i), 0_i))),
Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kNone,
Call("textureLoad", "B", vec2<i32>(1_i, 2_i), 0_i))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1091,31 +1079,31 @@
TEST_F(ResourceAttributeTest, BindingPointUsedTwiceByDifferentEntryPoints) {
GlobalVar(Source{{12, 34}}, "A", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
ast::StorageClass::kNone,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
GlobalVar(Source{{56, 78}}, "B", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
ast::StorageClass::kNone,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("F_A", {}, ty.void_(),
- {
+ Func("F_A", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.vec4<f32>(), ast::StorageClass::kNone,
Call("textureLoad", "A", vec2<i32>(1_i, 2_i), 0_i))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
- Func("F_B", {}, ty.void_(),
- {
+ Func("F_B", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kNone,
Call("textureLoad", "B", vec2<i32>(1_i, 2_i), 0_i))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1124,7 +1112,7 @@
TEST_F(ResourceAttributeTest, BindingPointOnNonResource) {
GlobalVar(Source{{12, 34}}, "G", ty.f32(), ast::StorageClass::kPrivate,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
@@ -1141,32 +1129,38 @@
namespace {
using InvariantAttributeTests = ResolverTest;
TEST_F(InvariantAttributeTests, InvariantWithPosition) {
- auto* param = Param(
- "p", ty.vec4<f32>(),
- {Invariant(Source{{12, 34}}), Builtin(Source{{56, 78}}, ast::BuiltinValue::kPosition)});
- Func("main", {param}, ty.vec4<f32>(),
- {
+ auto* param = Param("p", ty.vec4<f32>(),
+ utils::Vector{
+ Invariant(Source{{12, 34}}),
+ Builtin(Source{{56, 78}}, ast::BuiltinValue::kPosition),
+ });
+ Func("main", utils::Vector{param}, ty.vec4<f32>(),
+ utils::Vector{
Return(Construct(ty.vec4<f32>())),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0),
});
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(InvariantAttributeTests, InvariantWithoutPosition) {
- auto* param = Param("p", ty.vec4<f32>(), {Invariant(Source{{12, 34}}), Location(0)});
- Func("main", {param}, ty.vec4<f32>(),
- {
+ auto* param = Param("p", ty.vec4<f32>(),
+ utils::Vector{
+ Invariant(Source{{12, 34}}),
+ Location(0),
+ });
+ Func("main", utils::Vector{param}, ty.vec4<f32>(),
+ utils::Vector{
Return(Construct(ty.vec4<f32>())),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0),
});
EXPECT_FALSE(r()->Resolve());
@@ -1182,15 +1176,20 @@
using WorkgroupAttribute = ResolverTest;
TEST_F(WorkgroupAttribute, ComputeShaderPass) {
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute),
- create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(WorkgroupAttribute, Missing) {
- Func(Source{{12, 34}}, "main", {}, ty.void_(), {}, {Stage(ast::PipelineStage::kCompute)});
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1199,8 +1198,10 @@
}
TEST_F(WorkgroupAttribute, NotAnEntryPoint) {
- Func("main", {}, ty.void_(), {},
- {create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1209,9 +1210,11 @@
}
TEST_F(WorkgroupAttribute, NotAComputeShader) {
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kFragment),
- create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1220,8 +1223,8 @@
}
TEST_F(WorkgroupAttribute, DuplicateAttribute) {
- Func(Source{{12, 34}}, "main", {}, ty.void_(), {},
- {
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(Source{{12, 34}}, 1_i, nullptr, nullptr),
WorkgroupSize(Source{{56, 78}}, 2_i, nullptr, nullptr),
@@ -1254,15 +1257,15 @@
auto& params = GetParam();
Func("main",
- {
+ utils::Vector{
Param("a", ty.f32(),
- {
+ utils::Vector{
Location(0),
Interpolate(Source{{12, 34}}, params.type, params.sampling),
}),
},
- ty.void_(), {},
- {
+ ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1280,15 +1283,15 @@
auto& params = GetParam();
Func("main",
- {
+ utils::Vector{
Param("a", ty.i32(),
- {
+ utils::Vector{
Location(0),
Interpolate(Source{{12, 34}}, params.type, params.sampling),
}),
},
- ty.void_(), {},
- {
+ ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1311,15 +1314,15 @@
auto& params = GetParam();
Func("main",
- {
+ utils::Vector{
Param("a", ty.vec4<u32>(),
- {
+ utils::Vector{
Location(0),
Interpolate(Source{{12, 34}}, params.type, params.sampling),
}),
},
- ty.void_(), {},
- {
+ ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1357,8 +1360,9 @@
Params{ast::InterpolationType::kFlat, ast::InterpolationSampling::kSample, false}));
TEST_F(InterpolateTest, FragmentInput_Integer_MissingFlatInterpolation) {
- Func("main", {Param(Source{{12, 34}}, "a", ty.i32(), {Location(0)})}, ty.void_(), {},
- {
+ Func("main", utils::Vector{Param(Source{{12, 34}}, "a", ty.i32(), utils::Vector{Location(0)})},
+ ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1369,16 +1373,17 @@
}
TEST_F(InterpolateTest, VertexOutput_Integer_MissingFlatInterpolation) {
- auto* s =
- Structure("S", {
- Member("pos", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)}),
- Member(Source{{12, 34}}, "u", ty.u32(), {Location(0)}),
- });
- Func("main", {}, ty.Of(s),
- {
+ auto* s = Structure(
+ "S",
+ utils::Vector{
+ Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
+ Member(Source{{12, 34}}, "u", ty.u32(), utils::Vector{Location(0)}),
+ });
+ Func("main", utils::Empty, ty.Of(s),
+ utils::Vector{
Return(Construct(ty.Of(s))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kVertex),
});
@@ -1391,16 +1396,16 @@
TEST_F(InterpolateTest, MissingLocationAttribute_Parameter) {
Func("main",
- {
+ utils::Vector{
Param("a", ty.vec4<f32>(),
- {
+ utils::Vector{
Builtin(ast::BuiltinValue::kPosition),
Interpolate(Source{{12, 34}}, ast::InterpolationType::kFlat,
ast::InterpolationSampling::kNone),
}),
},
- ty.void_(), {},
- {
+ ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -1410,14 +1415,14 @@
}
TEST_F(InterpolateTest, MissingLocationAttribute_ReturnType) {
- Func("main", {}, ty.vec4<f32>(),
- {
+ Func("main", utils::Empty, ty.vec4<f32>(),
+ utils::Vector{
Return(Construct(ty.vec4<f32>())),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kVertex),
},
- {
+ utils::Vector{
Builtin(ast::BuiltinValue::kPosition),
Interpolate(Source{{12, 34}}, ast::InterpolationType::kFlat,
ast::InterpolationSampling::kNone),
@@ -1429,9 +1434,12 @@
}
TEST_F(InterpolateTest, MissingLocationAttribute_Struct) {
- Structure("S", {Member("a", ty.f32(),
- {Interpolate(Source{{12, 34}}, ast::InterpolationType::kFlat,
- ast::InterpolationSampling::kNone)})});
+ Structure("S",
+ utils::Vector{
+ Member("a", ty.f32(),
+ utils::Vector{Interpolate(Source{{12, 34}}, ast::InterpolationType::kFlat,
+ ast::InterpolationSampling::kNone)}),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
diff --git a/src/tint/resolver/builtin_test.cc b/src/tint/resolver/builtin_test.cc
index 7bb7eb2..6046a73 100644
--- a/src/tint/resolver/builtin_test.cc
+++ b/src/tint/resolver/builtin_test.cc
@@ -44,6 +44,8 @@
namespace tint::resolver {
namespace {
+using ExpressionList = utils::Vector<const ast::Expression*, 8>;
+
using BuiltinType = sem::BuiltinType;
using ResolverBuiltinTest = ResolverTest;
@@ -209,9 +211,9 @@
TEST_F(ResolverBuiltinArrayTest, ArrayLength_Vector) {
auto* ary = ty.array<i32>();
- auto* str = Structure("S", {Member("x", ary)});
+ auto* str = Structure("S", utils::Vector{Member("x", ary)});
GlobalVar("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -899,8 +901,9 @@
)");
}
-// frexp: (f32) -> __frexp_result, (vecN<f32>) -> __frexp_result_vecN
-TEST_F(ResolverBuiltinFloatTest, FrexpScalar) {
+// frexp: (f32) -> __frexp_result, (vecN<f32>) -> __frexp_result_vecN, (f16) -> __frexp_result_16,
+// (vecN<f16>) -> __frexp_result_vecN_f16
+TEST_F(ResolverBuiltinFloatTest, FrexpScalar_f32) {
auto* call = Call("frexp", 1_f);
WrapInFunction(call);
@@ -929,7 +932,38 @@
EXPECT_EQ(ty->SizeNoPadding(), 8u);
}
-TEST_F(ResolverBuiltinFloatTest, FrexpVector) {
+TEST_F(ResolverBuiltinFloatTest, FrexpScalar_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("frexp", 1_h);
+ WrapInFunction(call);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(call), nullptr);
+ auto* ty = TypeOf(call)->As<sem::Struct>();
+ ASSERT_NE(ty, nullptr);
+ ASSERT_EQ(ty->Members().size(), 2u);
+
+ auto* sig = ty->Members()[0];
+ EXPECT_TRUE(sig->Type()->Is<sem::F16>());
+ EXPECT_EQ(sig->Offset(), 0u);
+ EXPECT_EQ(sig->Size(), 2u);
+ EXPECT_EQ(sig->Align(), 2u);
+ EXPECT_EQ(sig->Name(), Sym("sig"));
+
+ auto* exp = ty->Members()[1];
+ EXPECT_TRUE(exp->Type()->Is<sem::I32>());
+ EXPECT_EQ(exp->Offset(), 4u);
+ EXPECT_EQ(exp->Size(), 4u);
+ EXPECT_EQ(exp->Align(), 4u);
+ EXPECT_EQ(exp->Name(), Sym("exp"));
+
+ EXPECT_EQ(ty->Size(), 8u);
+ EXPECT_EQ(ty->SizeNoPadding(), 8u);
+}
+
+TEST_F(ResolverBuiltinFloatTest, FrexpVector_f32) {
auto* call = Call("frexp", vec3<f32>());
WrapInFunction(call);
@@ -962,6 +996,41 @@
EXPECT_EQ(ty->SizeNoPadding(), 28u);
}
+TEST_F(ResolverBuiltinFloatTest, FrexpVector_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("frexp", vec3<f16>());
+ WrapInFunction(call);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(call), nullptr);
+ auto* ty = TypeOf(call)->As<sem::Struct>();
+ ASSERT_NE(ty, nullptr);
+ ASSERT_EQ(ty->Members().size(), 2u);
+
+ auto* sig = ty->Members()[0];
+ ASSERT_TRUE(sig->Type()->Is<sem::Vector>());
+ EXPECT_EQ(sig->Type()->As<sem::Vector>()->Width(), 3u);
+ EXPECT_TRUE(sig->Type()->As<sem::Vector>()->type()->Is<sem::F16>());
+ EXPECT_EQ(sig->Offset(), 0u);
+ EXPECT_EQ(sig->Size(), 6u);
+ EXPECT_EQ(sig->Align(), 8u);
+ EXPECT_EQ(sig->Name(), Sym("sig"));
+
+ auto* exp = ty->Members()[1];
+ ASSERT_TRUE(exp->Type()->Is<sem::Vector>());
+ EXPECT_EQ(exp->Type()->As<sem::Vector>()->Width(), 3u);
+ EXPECT_TRUE(exp->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
+ EXPECT_EQ(exp->Offset(), 16u);
+ EXPECT_EQ(exp->Size(), 12u);
+ EXPECT_EQ(exp->Align(), 16u);
+ EXPECT_EQ(exp->Name(), Sym("exp"));
+
+ EXPECT_EQ(ty->Size(), 32u);
+ EXPECT_EQ(ty->SizeNoPadding(), 28u);
+}
+
TEST_F(ResolverBuiltinFloatTest, Frexp_Error_FirstParamInt) {
GlobalVar("v", ty.i32(), ast::StorageClass::kWorkgroup);
auto* call = Call("frexp", 1_i, AddressOf("v"));
@@ -973,8 +1042,8 @@
R"(error: no matching call to frexp(i32, ptr<workgroup, i32, read_write>)
2 candidate functions:
- frexp(f32) -> __frexp_result
- frexp(vecN<f32>) -> __frexp_result_vecN
+ frexp(T) -> __frexp_result_T where: T is f32 or f16
+ frexp(vecN<T>) -> __frexp_result_vecN_T where: T is f32 or f16
)");
}
@@ -989,8 +1058,8 @@
R"(error: no matching call to frexp(f32, ptr<workgroup, f32, read_write>)
2 candidate functions:
- frexp(f32) -> __frexp_result
- frexp(vecN<f32>) -> __frexp_result_vecN
+ frexp(T) -> __frexp_result_T where: T is f32 or f16
+ frexp(vecN<T>) -> __frexp_result_vecN_T where: T is f32 or f16
)");
}
@@ -1003,8 +1072,8 @@
EXPECT_EQ(r()->error(), R"(error: no matching call to frexp(f32, i32)
2 candidate functions:
- frexp(f32) -> __frexp_result
- frexp(vecN<f32>) -> __frexp_result_vecN
+ frexp(T) -> __frexp_result_T where: T is f32 or f16
+ frexp(vecN<T>) -> __frexp_result_vecN_T where: T is f32 or f16
)");
}
@@ -1019,8 +1088,8 @@
R"(error: no matching call to frexp(vec2<f32>, ptr<workgroup, vec4<i32>, read_write>)
2 candidate functions:
- frexp(vecN<f32>) -> __frexp_result_vecN
- frexp(f32) -> __frexp_result
+ frexp(T) -> __frexp_result_T where: T is f32 or f16
+ frexp(vecN<T>) -> __frexp_result_vecN_T where: T is f32 or f16
)");
}
@@ -1127,8 +1196,9 @@
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
}
-// modf: (f32) -> __modf_result, (vecN<f32>) -> __modf_result_vecN
-TEST_F(ResolverBuiltinFloatTest, ModfScalar) {
+// modf: (f32) -> __modf_result, (vecN<f32>) -> __modf_result_vecN, (f16) -> __modf_result_f16,
+// (vecN<f16>) -> __modf_result_vecN_f16
+TEST_F(ResolverBuiltinFloatTest, ModfScalar_f32) {
auto* call = Call("modf", 1_f);
WrapInFunction(call);
@@ -1157,7 +1227,38 @@
EXPECT_EQ(ty->SizeNoPadding(), 8u);
}
-TEST_F(ResolverBuiltinFloatTest, ModfVector) {
+TEST_F(ResolverBuiltinFloatTest, ModfScalar_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("modf", 1_h);
+ WrapInFunction(call);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(call), nullptr);
+ auto* ty = TypeOf(call)->As<sem::Struct>();
+ ASSERT_NE(ty, nullptr);
+ ASSERT_EQ(ty->Members().size(), 2u);
+
+ auto* fract = ty->Members()[0];
+ EXPECT_TRUE(fract->Type()->Is<sem::F16>());
+ EXPECT_EQ(fract->Offset(), 0u);
+ EXPECT_EQ(fract->Size(), 2u);
+ EXPECT_EQ(fract->Align(), 2u);
+ EXPECT_EQ(fract->Name(), Sym("fract"));
+
+ auto* whole = ty->Members()[1];
+ EXPECT_TRUE(whole->Type()->Is<sem::F16>());
+ EXPECT_EQ(whole->Offset(), 2u);
+ EXPECT_EQ(whole->Size(), 2u);
+ EXPECT_EQ(whole->Align(), 2u);
+ EXPECT_EQ(whole->Name(), Sym("whole"));
+
+ EXPECT_EQ(ty->Size(), 4u);
+ EXPECT_EQ(ty->SizeNoPadding(), 4u);
+}
+
+TEST_F(ResolverBuiltinFloatTest, ModfVector_f32) {
auto* call = Call("modf", vec3<f32>());
WrapInFunction(call);
@@ -1190,6 +1291,41 @@
EXPECT_EQ(ty->SizeNoPadding(), 28u);
}
+TEST_F(ResolverBuiltinFloatTest, ModfVector_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("modf", vec3<f16>());
+ WrapInFunction(call);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(call), nullptr);
+ auto* ty = TypeOf(call)->As<sem::Struct>();
+ ASSERT_NE(ty, nullptr);
+ ASSERT_EQ(ty->Members().size(), 2u);
+
+ auto* fract = ty->Members()[0];
+ ASSERT_TRUE(fract->Type()->Is<sem::Vector>());
+ EXPECT_EQ(fract->Type()->As<sem::Vector>()->Width(), 3u);
+ EXPECT_TRUE(fract->Type()->As<sem::Vector>()->type()->Is<sem::F16>());
+ EXPECT_EQ(fract->Offset(), 0u);
+ EXPECT_EQ(fract->Size(), 6u);
+ EXPECT_EQ(fract->Align(), 8u);
+ EXPECT_EQ(fract->Name(), Sym("fract"));
+
+ auto* whole = ty->Members()[1];
+ ASSERT_TRUE(whole->Type()->Is<sem::Vector>());
+ EXPECT_EQ(whole->Type()->As<sem::Vector>()->Width(), 3u);
+ EXPECT_TRUE(whole->Type()->As<sem::Vector>()->type()->Is<sem::F16>());
+ EXPECT_EQ(whole->Offset(), 8u);
+ EXPECT_EQ(whole->Size(), 6u);
+ EXPECT_EQ(whole->Align(), 8u);
+ EXPECT_EQ(whole->Name(), Sym("whole"));
+
+ EXPECT_EQ(ty->Size(), 16u);
+ EXPECT_EQ(ty->SizeNoPadding(), 14u);
+}
+
TEST_F(ResolverBuiltinFloatTest, Modf_Error_FirstParamInt) {
GlobalVar("whole", ty.f32(), ast::StorageClass::kWorkgroup);
auto* call = Call("modf", 1_i, AddressOf("whole"));
@@ -1201,8 +1337,8 @@
R"(error: no matching call to modf(i32, ptr<workgroup, f32, read_write>)
2 candidate functions:
- modf(f32) -> __modf_result
- modf(vecN<f32>) -> __modf_result_vecN
+ modf(T) -> __modf_result_T where: T is f32 or f16
+ modf(vecN<T>) -> __modf_result_vecN_T where: T is f32 or f16
)");
}
@@ -1217,8 +1353,8 @@
R"(error: no matching call to modf(f32, ptr<workgroup, i32, read_write>)
2 candidate functions:
- modf(f32) -> __modf_result
- modf(vecN<f32>) -> __modf_result_vecN
+ modf(T) -> __modf_result_T where: T is f32 or f16
+ modf(vecN<T>) -> __modf_result_vecN_T where: T is f32 or f16
)");
}
@@ -1231,8 +1367,8 @@
EXPECT_EQ(r()->error(), R"(error: no matching call to modf(f32, f32)
2 candidate functions:
- modf(f32) -> __modf_result
- modf(vecN<f32>) -> __modf_result_vecN
+ modf(T) -> __modf_result_T where: T is f32 or f16
+ modf(vecN<T>) -> __modf_result_vecN_T where: T is f32 or f16
)");
}
@@ -1247,8 +1383,8 @@
R"(error: no matching call to modf(vec2<f32>, ptr<workgroup, vec4<f32>, read_write>)
2 candidate functions:
- modf(vecN<f32>) -> __modf_result_vecN
- modf(f32) -> __modf_result
+ modf(T) -> __modf_result_T where: T is f32 or f16
+ modf(vecN<T>) -> __modf_result_vecN_T where: T is f32 or f16
)");
}
@@ -1906,8 +2042,8 @@
GlobalVar("ident", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call(name, "ident");
- Func("func", {}, ty.void_(), {Ignore(expr)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{Ignore(expr)},
+ utils::Vector{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1920,8 +2056,8 @@
GlobalVar("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call(name, "ident");
- Func("func", {}, ty.void_(), {Ignore(expr)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{Ignore(expr)},
+ utils::Vector{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2008,10 +2144,10 @@
return nullptr;
}
- void add_call_param(std::string name, const ast::Type* type, ast::ExpressionList* call_params) {
+ void add_call_param(std::string name, const ast::Type* type, ExpressionList* call_params) {
if (type->IsAnyOf<ast::Texture, ast::Sampler>()) {
GlobalVar(name, type,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -2020,7 +2156,7 @@
GlobalVar(name, type, ast::StorageClass::kPrivate);
}
- call_params->push_back(Expr(name));
+ call_params->Push(Expr(name));
}
const ast::Type* subtype(Texture type) {
if (type == Texture::kF32) {
@@ -2042,7 +2178,7 @@
auto* coords_type = GetCoordsType(dim, ty.i32());
auto* texture_type = ty.sampled_texture(dim, s);
- ast::ExpressionList call_params;
+ ExpressionList call_params;
add_call_param("texture", texture_type, &call_params);
add_call_param("coords", coords_type, &call_params);
@@ -2082,7 +2218,7 @@
testing::ValuesIn(ast::builtin::test::TextureOverloadCase::ValidCases()));
static std::string to_str(const std::string& function,
- utils::ConstVectorRef<const sem::Parameter*> params) {
+ utils::VectorRef<const sem::Parameter*> params) {
std::stringstream out;
out << function << "(";
bool first = true;
@@ -2337,7 +2473,8 @@
auto* call = Call(param.function, param.args(this));
auto* stmt = CallStmt(call);
- Func("func", {}, ty.void_(), {stmt}, {Stage(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{stmt},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/builtin_validation_test.cc b/src/tint/resolver/builtin_validation_test.cc
index be7a23f..83603c3 100644
--- a/src/tint/resolver/builtin_validation_test.cc
+++ b/src/tint/resolver/builtin_validation_test.cc
@@ -24,8 +24,8 @@
TEST_F(ResolverBuiltinValidationTest, FunctionTypeMustMatchReturnStatementType_void_fail) {
// fn func { return workgroupBarrier(); }
- Func("func", {}, ty.void_(),
- {
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
Return(Call(Source{Source::Location{12, 34}}, "workgroupBarrier")),
});
@@ -36,13 +36,15 @@
TEST_F(ResolverBuiltinValidationTest, InvalidPipelineStageDirect) {
// @compute @workgroup_size(1) fn func { return dpdx(1.0); }
- auto* dpdx =
- create<ast::CallExpression>(Source{{3, 4}}, Expr("dpdx"), ast::ExpressionList{Expr(1_f)});
- Func(Source{{1, 2}}, "func", {}, ty.void_(),
- {
+ auto* dpdx = create<ast::CallExpression>(Source{{3, 4}}, Expr("dpdx"),
+ utils::Vector{
+ Expr(1_f),
+ });
+ Func(Source{{1, 2}}, "func", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(dpdx),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -57,16 +59,33 @@
// fn f2 { f1(); }
// @compute @workgroup_size(1) fn main { return f2(); }
- auto* dpdx =
- create<ast::CallExpression>(Source{{3, 4}}, Expr("dpdx"), ast::ExpressionList{Expr(1_f)});
- Func(Source{{1, 2}}, "f0", {}, ty.void_(), {CallStmt(dpdx)});
+ auto* dpdx = create<ast::CallExpression>(Source{{3, 4}}, Expr("dpdx"),
+ utils::Vector{
+ Expr(1_f),
+ });
+ Func(Source{{1, 2}}, "f0", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(dpdx),
+ });
- Func(Source{{3, 4}}, "f1", {}, ty.void_(), {CallStmt(Call("f0"))});
+ Func(Source{{3, 4}}, "f1", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("f0")),
+ });
- Func(Source{{5, 6}}, "f2", {}, ty.void_(), {CallStmt(Call("f1"))});
+ Func(Source{{5, 6}}, "f2", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("f1")),
+ });
- Func(Source{{7, 8}}, "main", {}, ty.void_(), {CallStmt(Call("f2"))},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ Func(Source{{7, 8}}, "main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("f2")),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(1_i),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -78,7 +97,7 @@
}
TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsFunction) {
- Func(Source{{12, 34}}, "mix", {}, ty.i32(), {});
+ Func(Source{{12, 34}}, "mix", utils::Empty, ty.i32(), {});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -111,7 +130,10 @@
}
TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsStruct) {
- Structure(Source{{12, 34}}, "mix", {Member("m", ty.i32())});
+ Structure(Source{{12, 34}}, "mix",
+ utils::Vector{
+ Member("m", ty.i32()),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -232,7 +254,7 @@
overload.BuildSamplerVariable(this);
auto args = overload.args(this);
- auto*& arg_to_replace = (param.position == Position::kFirst) ? args.front() : args.back();
+ auto*& arg_to_replace = (param.position == Position::kFirst) ? args.Front() : args.Back();
// BuildTextureVariable() uses a Literal for scalars, and a CallExpression for
// a vector constructor.
@@ -245,8 +267,13 @@
arg_to_replace = expr(Source{{12, 34}}, *this);
// Call the builtin with the constexpr argument replaced
- Func("func", {}, ty.void_(), {CallStmt(Call(overload.function, args))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call(overload.function, args)),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
if (expr.invalid_index == Constexpr::kValid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -281,7 +308,7 @@
GlobalConst("G", nullptr, expr({}, *this));
auto args = overload.args(this);
- auto*& arg_to_replace = (param.position == Position::kFirst) ? args.front() : args.back();
+ auto*& arg_to_replace = (param.position == Position::kFirst) ? args.Front() : args.Back();
// Make the expression to be replaced, reachable. This keeps the resolver
// happy.
@@ -290,8 +317,13 @@
arg_to_replace = Expr(Source{{12, 34}}, "G");
// Call the builtin with the constexpr argument replaced
- Func("func", {}, ty.void_(), {CallStmt(Call(overload.function, args))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call(overload.function, args)),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
std::stringstream err;
@@ -386,10 +418,10 @@
// fn func { return dot4I8Packed(1u, 2u); }
Enable(ast::Extension::kChromiumExperimentalDp4A);
- Func("func", {}, ty.i32(),
- {
+ Func("func", utils::Empty, ty.i32(),
+ utils::Vector{
Return(Call(Source{Source::Location{12, 34}}, "dot4I8Packed",
- ast::ExpressionList{Expr(1_u), Expr(2_u)})),
+ utils::Vector{Expr(1_u), Expr(2_u)})),
});
EXPECT_TRUE(r()->Resolve());
@@ -397,10 +429,10 @@
TEST_F(ResolverDP4aExtensionValidationTest, Dot4I8PackedWithoutExtension) {
// fn func { return dot4I8Packed(1u, 2u); }
- Func("func", {}, ty.i32(),
- {
+ Func("func", utils::Empty, ty.i32(),
+ utils::Vector{
Return(Call(Source{Source::Location{12, 34}}, "dot4I8Packed",
- ast::ExpressionList{Expr(1_u), Expr(2_u)})),
+ utils::Vector{Expr(1_u), Expr(2_u)})),
});
EXPECT_FALSE(r()->Resolve());
@@ -414,10 +446,10 @@
// fn func { return dot4U8Packed(1u, 2u); }
Enable(ast::Extension::kChromiumExperimentalDp4A);
- Func("func", {}, ty.u32(),
- {
+ Func("func", utils::Empty, ty.u32(),
+ utils::Vector{
Return(Call(Source{Source::Location{12, 34}}, "dot4U8Packed",
- ast::ExpressionList{Expr(1_u), Expr(2_u)})),
+ utils::Vector{Expr(1_u), Expr(2_u)})),
});
EXPECT_TRUE(r()->Resolve());
@@ -425,10 +457,10 @@
TEST_F(ResolverDP4aExtensionValidationTest, Dot4U8PackedWithoutExtension) {
// fn func { return dot4U8Packed(1u, 2u); }
- Func("func", {}, ty.u32(),
- {
+ Func("func", utils::Empty, ty.u32(),
+ utils::Vector{
Return(Call(Source{Source::Location{12, 34}}, "dot4U8Packed",
- ast::ExpressionList{Expr(1_u), Expr(2_u)})),
+ utils::Vector{Expr(1_u), Expr(2_u)})),
});
EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/builtins_validation_test.cc b/src/tint/resolver/builtins_validation_test.cc
index c3ec4a7..6318901 100644
--- a/src/tint/resolver/builtins_validation_test.cc
+++ b/src/tint/resolver/builtins_validation_test.cc
@@ -101,18 +101,26 @@
const Params& params = GetParam();
auto* p = GlobalVar("p", ty.vec4<f32>(), ast::StorageClass::kPrivate);
- auto* input = Param("input", params.type(*this), {Builtin(Source{{12, 34}}, params.builtin)});
+ auto* input = Param("input", params.type(*this),
+ utils::Vector{Builtin(Source{{12, 34}}, params.builtin)});
switch (params.stage) {
case ast::PipelineStage::kVertex:
- Func("main", {input}, ty.vec4<f32>(), {Return(p)}, {Stage(ast::PipelineStage::kVertex)},
- {Builtin(Source{{12, 34}}, ast::BuiltinValue::kPosition)});
+ Func("main", utils::Vector{input}, ty.vec4<f32>(), utils::Vector{Return(p)},
+ utils::Vector{Stage(ast::PipelineStage::kVertex)},
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kPosition),
+ });
break;
case ast::PipelineStage::kFragment:
- Func("main", {input}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)}, {});
+ Func("main", utils::Vector{input}, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ {});
break;
case ast::PipelineStage::kCompute:
- Func("main", {input}, ty.void_(), {},
- {
+ Func("main", utils::Vector{input}, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -141,17 +149,20 @@
// @builtin(frag_depth) fd: f32,
// ) -> @location(0) f32 { return 1.0; }
Func("fs_main",
- {
- Param("fd", ty.f32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kFragDepth)}),
+ utils::Vector{
+ Param("fd", ty.f32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kFragDepth),
+ }),
},
ty.f32(),
- {
+ utils::Vector{
Return(1_f),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0),
});
EXPECT_FALSE(r()->Resolve());
@@ -168,23 +179,25 @@
// fn fragShader(arg: MyInputs) -> @location(0) f32 { return 1.0; }
auto* s = Structure("MyInputs",
- {
+ utils::Vector{
Member("frag_depth", ty.f32(),
- {Builtin(Source{{12, 34}}, ast::BuiltinValue::kFragDepth)}),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kFragDepth),
+ }),
});
Func("fragShader",
- {
+ utils::Vector{
Param("arg", ty.Of(s)),
},
ty.f32(),
- {
+ utils::Vector{
Return(1_f),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0),
});
EXPECT_FALSE(r()->Resolve());
@@ -201,10 +214,17 @@
// @fragment
// fn fragShader() { var s : S; }
- Structure("S", {Member("idx", ty.u32(), {Builtin(ast::BuiltinValue::kVertexIndex)})});
+ Structure("S", utils::Vector{
+ Member("idx", ty.u32(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kVertexIndex),
+ }),
+ });
- Func("fragShader", {}, ty.void_(), {Decl(Var("s", ty.type_name("S")))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("fragShader", utils::Empty, ty.void_(), utils::Vector{Decl(Var("s", ty.type_name("S")))},
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_TRUE(r()->Resolve());
}
@@ -217,23 +237,25 @@
// @fragment
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
- auto* s =
- Structure("MyInputs", {
- Member("position", ty.vec4<u32>(),
- {Builtin(Source{{12, 34}}, ast::BuiltinValue::kPosition)}),
- });
+ auto* s = Structure("MyInputs",
+ utils::Vector{
+ Member("position", ty.vec4<u32>(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kPosition),
+ }),
+ });
Func("fragShader",
- {
+ utils::Vector{
Param("arg", ty.Of(s)),
},
ty.f32(),
- {
+ utils::Vector{
Return(1_f),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0),
});
@@ -244,8 +266,14 @@
TEST_F(ResolverBuiltinsValidationTest, PositionNotF32_ReturnType_Fail) {
// @vertex
// fn main() -> @builtin(position) f32 { return 1.0; }
- Func("main", {}, ty.f32(), {Return(1_f)}, {Stage(ast::PipelineStage::kVertex)},
- {Builtin(Source{{12, 34}}, ast::BuiltinValue::kPosition)});
+ Func("main", utils::Empty, ty.f32(),
+ utils::Vector{
+ Return(1_f),
+ },
+ utils::Vector{Stage(ast::PipelineStage::kVertex)},
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kPosition),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(position) must be 'vec4<f32>'");
@@ -259,18 +287,20 @@
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
auto* s = Structure("MyInputs",
- {
+ utils::Vector{
Member("frag_depth", ty.i32(),
- {Builtin(Source{{12, 34}}, ast::BuiltinValue::kFragDepth)}),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kFragDepth),
+ }),
});
- Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(),
- {
+ Func("fragShader", utils::Vector{Param("arg", ty.Of(s))}, ty.f32(),
+ utils::Vector{
Return(1_f),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0),
});
@@ -285,13 +315,23 @@
// @fragment
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
- auto* s = Structure(
- "MyInputs",
- {
- Member("m", ty.f32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kSampleMask)}),
- });
- Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
- {Stage(ast::PipelineStage::kFragment)}, {Location(0)});
+ auto* s = Structure("MyInputs",
+ utils::Vector{
+ Member("m", ty.f32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kSampleMask),
+ }),
+ });
+ Func("fragShader", utils::Vector{Param("arg", ty.Of(s))}, ty.f32(),
+ utils::Vector{
+ Return(1_f),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Location(0),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(sample_mask) must be 'u32'");
@@ -300,8 +340,13 @@
TEST_F(ResolverBuiltinsValidationTest, SampleMaskNotU32_ReturnType_Fail) {
// @fragment
// fn main() -> @builtin(sample_mask) i32 { return 1; }
- Func("main", {}, ty.i32(), {Return(1_i)}, {Stage(ast::PipelineStage::kFragment)},
- {Builtin(Source{{12, 34}}, ast::BuiltinValue::kSampleMask)});
+ Func("main", utils::Empty, ty.i32(), utils::Vector{Return(1_i)},
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kSampleMask),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(sample_mask) must be 'u32'");
@@ -313,17 +358,20 @@
// @builtin(sample_mask) arg: bool
// ) -> @location(0) f32 { return 1.0; }
Func("fs_main",
- {
- Param("arg", ty.bool_(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kSampleMask)}),
+ utils::Vector{
+ Param("arg", ty.bool_(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kSampleMask),
+ }),
},
ty.f32(),
- {
+ utils::Vector{
Return(1_f),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0),
});
EXPECT_FALSE(r()->Resolve());
@@ -337,13 +385,23 @@
// @fragment
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
- auto* s = Structure(
- "MyInputs",
- {
- Member("m", ty.f32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kSampleIndex)}),
- });
- Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
- {Stage(ast::PipelineStage::kFragment)}, {Location(0)});
+ auto* s = Structure("MyInputs",
+ utils::Vector{
+ Member("m", ty.f32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kSampleIndex),
+ }),
+ });
+ Func("fragShader", utils::Vector{Param("arg", ty.Of(s))}, ty.f32(),
+ utils::Vector{
+ Return(1_f),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Location(0),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(sample_index) must be 'u32'");
@@ -355,14 +413,20 @@
// @builtin(sample_index) arg: bool
// ) -> @location(0) f32 { return 1.0; }
Func("fs_main",
- {
- Param("arg", ty.bool_(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kSampleIndex)}),
+ utils::Vector{
+ Param("arg", ty.bool_(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kSampleIndex),
+ }),
},
- ty.f32(), {Return(1_f)},
- {
+ ty.f32(),
+ utils::Vector{
+ Return(1_f),
+ },
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0),
});
EXPECT_FALSE(r()->Resolve());
@@ -375,14 +439,20 @@
// @builtin(kPosition) p: vec3<f32>,
// ) -> @location(0) f32 { return 1.0; }
Func("fs_main",
- {
- Param("p", ty.vec3<f32>(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kPosition)}),
+ utils::Vector{
+ Param("p", ty.vec3<f32>(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kPosition),
+ }),
},
- ty.f32(), {Return(1_f)},
- {
+ ty.f32(),
+ utils::Vector{
+ Return(1_f),
+ },
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(0),
});
EXPECT_FALSE(r()->Resolve());
@@ -393,8 +463,17 @@
// @fragment
// fn fs_main() -> @builtin(kFragDepth) f32 { var fd: i32; return fd; }
auto* fd = Var("fd", ty.i32());
- Func("fs_main", {}, ty.i32(), {Decl(fd), Return(fd)}, {Stage(ast::PipelineStage::kFragment)},
- {Builtin(Source{{12, 34}}, ast::BuiltinValue::kFragDepth)});
+ Func("fs_main", utils::Empty, ty.i32(),
+ utils::Vector{
+ Decl(fd),
+ Return(fd),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kFragDepth),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(frag_depth) must be 'f32'");
}
@@ -405,10 +484,21 @@
// @builtin(kVertexIndex) vi : f32,
// @builtin(kPosition) p :vec4<f32>
// ) -> @builtin(kPosition) vec4<f32> { return vec4<f32>(); }
- auto* p = Param("p", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)});
- auto* vi = Param("vi", ty.f32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kVertexIndex)});
- Func("main", {vi, p}, ty.vec4<f32>(), {Return(Expr("p"))}, {Stage(ast::PipelineStage::kVertex)},
- {Builtin(ast::BuiltinValue::kPosition)});
+ auto* p = Param("p", ty.vec4<f32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ });
+ auto* vi = Param("vi", ty.f32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kVertexIndex),
+ });
+ Func("main", utils::Vector{vi, p}, ty.vec4<f32>(), utils::Vector{Return(Expr("p"))},
+ utils::Vector{
+ Stage(ast::PipelineStage::kVertex),
+ },
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(vertex_index) must be 'u32'");
}
@@ -419,11 +509,21 @@
// @builtin(kInstanceIndex) ii : f32,
// @builtin(kPosition) p :vec4<f32>
// ) -> @builtin(kPosition) vec4<f32> { return vec4<f32>(); }
- auto* p = Param("p", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)});
- auto* ii =
- Param("ii", ty.f32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kInstanceIndex)});
- Func("main", {ii, p}, ty.vec4<f32>(), {Return(Expr("p"))}, {Stage(ast::PipelineStage::kVertex)},
- {Builtin(ast::BuiltinValue::kPosition)});
+ auto* p = Param("p", ty.vec4<f32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ });
+ auto* ii = Param("ii", ty.f32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kInstanceIndex),
+ });
+ Func("main", utils::Vector{ii, p}, ty.vec4<f32>(), utils::Vector{Return(Expr("p"))},
+ utils::Vector{
+ Stage(ast::PipelineStage::kVertex),
+ },
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(instance_index) must be 'u32'");
}
@@ -436,13 +536,34 @@
// @builtin(sample_index) si: u32,
// @builtin(sample_mask) sm : u32
// ) -> @builtin(frag_depth) f32 { var fd: f32; return fd; }
- auto* p = Param("p", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)});
- auto* ff = Param("ff", ty.bool_(), {Builtin(ast::BuiltinValue::kFrontFacing)});
- auto* si = Param("si", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)});
- auto* sm = Param("sm", ty.u32(), {Builtin(ast::BuiltinValue::kSampleMask)});
+ auto* p = Param("p", ty.vec4<f32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ });
+ auto* ff = Param("ff", ty.bool_(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kFrontFacing),
+ });
+ auto* si = Param("si", ty.u32(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kSampleIndex),
+ });
+ auto* sm = Param("sm", ty.u32(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kSampleMask),
+ });
auto* var_fd = Var("fd", ty.f32());
- Func("fs_main", {p, ff, si, sm}, ty.f32(), {Decl(var_fd), Return(var_fd)},
- {Stage(ast::PipelineStage::kFragment)}, {Builtin(ast::BuiltinValue::kFragDepth)});
+ Func("fs_main", utils::Vector{p, ff, si, sm}, ty.f32(),
+ utils::Vector{
+ Decl(var_fd),
+ Return(var_fd),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kFragDepth),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -452,17 +573,25 @@
// @builtin(vertex_index) vi : u32,
// @builtin(instance_index) ii : u32,
// ) -> @builtin(position) vec4<f32> { var p :vec4<f32>; return p; }
- auto* vi = Param("vi", ty.u32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kVertexIndex)});
+ auto* vi = Param("vi", ty.u32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kVertexIndex),
+ });
- auto* ii =
- Param("ii", ty.u32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kInstanceIndex)});
+ auto* ii = Param("ii", ty.u32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kInstanceIndex),
+ });
auto* p = Var("p", ty.vec4<f32>());
- Func("main", {vi, ii}, ty.vec4<f32>(),
- {
+ Func("main", utils::Vector{vi, ii}, ty.vec4<f32>(),
+ utils::Vector{
Decl(p),
Return(p),
},
- {Stage(ast::PipelineStage::kVertex)}, {Builtin(ast::BuiltinValue::kPosition)});
+ utils::Vector{Stage(ast::PipelineStage::kVertex)},
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -477,25 +606,42 @@
// @builtin(num_workgroups) nwgs: vec3<u32>,
// ) {}
- auto* li_id = Param("li_id", ty.vec3<u32>(), {Builtin(ast::BuiltinValue::kLocalInvocationId)});
- auto* li_index =
- Param("li_index", ty.u32(), {Builtin(ast::BuiltinValue::kLocalInvocationIndex)});
- auto* gi = Param("gi", ty.vec3<u32>(), {Builtin(ast::BuiltinValue::kGlobalInvocationId)});
- auto* wi = Param("wi", ty.vec3<u32>(), {Builtin(ast::BuiltinValue::kWorkgroupId)});
- auto* nwgs = Param("nwgs", ty.vec3<u32>(), {Builtin(ast::BuiltinValue::kNumWorkgroups)});
+ auto* li_id = Param("li_id", ty.vec3<u32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kLocalInvocationId),
+ });
+ auto* li_index = Param("li_index", ty.u32(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kLocalInvocationIndex),
+ });
+ auto* gi = Param("gi", ty.vec3<u32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kGlobalInvocationId),
+ });
+ auto* wi = Param("wi", ty.vec3<u32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kWorkgroupId),
+ });
+ auto* nwgs = Param("nwgs", ty.vec3<u32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kNumWorkgroups),
+ });
- Func("main", {li_id, li_index, gi, wi, nwgs}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute),
- WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
+ Func("main", utils::Vector{li_id, li_index, gi, wi, nwgs}, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_WorkGroupIdNotVec3U32) {
- auto* wi = Param("wi", ty.f32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kWorkgroupId)});
- Func("main", {wi}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute),
- WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
+ auto* wi = Param("wi", ty.f32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kWorkgroupId),
+ });
+ Func("main", utils::Vector{wi}, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -504,11 +650,13 @@
}
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_NumWorkgroupsNotVec3U32) {
- auto* nwgs =
- Param("nwgs", ty.f32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kNumWorkgroups)});
- Func("main", {nwgs}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute),
- WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
+ auto* nwgs = Param("nwgs", ty.f32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kNumWorkgroups),
+ });
+ Func("main", utils::Vector{nwgs}, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -518,10 +666,12 @@
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_GlobalInvocationNotVec3U32) {
auto* gi = Param("gi", ty.vec3<i32>(),
- {Builtin(Source{{12, 34}}, ast::BuiltinValue::kGlobalInvocationId)});
- Func("main", {gi}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute),
- WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kGlobalInvocationId),
+ });
+ Func("main", utils::Vector{gi}, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -531,10 +681,12 @@
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_LocalInvocationIndexNotU32) {
auto* li_index = Param("li_index", ty.vec3<u32>(),
- {Builtin(Source{{12, 34}}, ast::BuiltinValue::kLocalInvocationIndex)});
- Func("main", {li_index}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute),
- WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kLocalInvocationIndex),
+ });
+ Func("main", utils::Vector{li_index}, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -544,10 +696,12 @@
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_LocalInvocationNotVec3U32) {
auto* li_id = Param("li_id", ty.vec2<u32>(),
- {Builtin(Source{{12, 34}}, ast::BuiltinValue::kLocalInvocationId)});
- Func("main", {li_id}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute),
- WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kLocalInvocationId),
+ });
+ Func("main", utils::Vector{li_id}, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -565,13 +719,34 @@
// @fragment
// fn fragShader(arg: MyInputs) -> @location(0) f32 { return 1.0; }
- auto* s = Structure(
- "MyInputs", {Member("position", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)}),
- Member("front_facing", ty.bool_(), {Builtin(ast::BuiltinValue::kFrontFacing)}),
- Member("sample_index", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)}),
- Member("sample_mask", ty.u32(), {Builtin(ast::BuiltinValue::kSampleMask)})});
- Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
- {Stage(ast::PipelineStage::kFragment)}, {Location(0)});
+ auto* s = Structure("MyInputs", utils::Vector{
+ Member("position", ty.vec4<f32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ }),
+ Member("front_facing", ty.bool_(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kFrontFacing),
+ }),
+ Member("sample_index", ty.u32(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kSampleIndex),
+ }),
+ Member("sample_mask", ty.u32(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kSampleMask),
+ }),
+ });
+ Func("fragShader", utils::Vector{Param("arg", ty.Of(s))}, ty.f32(),
+ utils::Vector{
+ Return(1_f),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Location(0),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -581,10 +756,20 @@
// @builtin(front_facing) is_front: i32;
// ) -> @location(0) f32 { return 1.0; }
- auto* is_front =
- Param("is_front", ty.i32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kFrontFacing)});
- Func("fs_main", {is_front}, ty.f32(), {Return(1_f)}, {Stage(ast::PipelineStage::kFragment)},
- {Location(0)});
+ auto* is_front = Param("is_front", ty.i32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kFrontFacing),
+ });
+ Func("fs_main", utils::Vector{is_front}, ty.f32(),
+ utils::Vector{
+ Return(1_f),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Location(0),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(front_facing) must be 'bool'");
@@ -597,11 +782,23 @@
// @fragment
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
- auto* s = Structure(
- "MyInputs",
- {Member("pos", ty.f32(), {Builtin(Source{{12, 34}}, ast::BuiltinValue::kFrontFacing)})});
- Func("fragShader", {Param("is_front", ty.Of(s))}, ty.f32(), {Return(1_f)},
- {Stage(ast::PipelineStage::kFragment)}, {Location(0)});
+ auto* s = Structure("MyInputs",
+ utils::Vector{
+ Member("pos", ty.f32(),
+ utils::Vector{
+ Builtin(Source{{12, 34}}, ast::BuiltinValue::kFrontFacing),
+ }),
+ });
+ Func("fragShader", utils::Vector{Param("is_front", ty.Of(s))}, ty.f32(),
+ utils::Vector{
+ Return(1_f),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Location(0),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(front_facing) must be 'bool'");
@@ -900,13 +1097,18 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(Expr(1_f));
+ params.Push(Expr(1_f));
}
auto* builtin = Call(name, params);
- Func("func", {}, ty.void_(), {CallStmt(builtin)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(builtin),
+ },
+ utils::Vector{
+ create<ast::StageAttribute>(ast::PipelineStage::kFragment),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->Is<sem::F32>());
@@ -916,13 +1118,18 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec2<f32>(1_f, 1_f));
+ params.Push(vec2<f32>(1_f, 1_f));
}
auto* builtin = Call(name, params);
- Func("func", {}, ty.void_(), {CallStmt(builtin)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(builtin),
+ },
+ utils::Vector{
+ create<ast::StageAttribute>(ast::PipelineStage::kFragment),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
@@ -932,13 +1139,18 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec3<f32>(1_f, 1_f, 1_f));
+ params.Push(vec3<f32>(1_f, 1_f, 1_f));
}
auto* builtin = Call(name, params);
- Func("func", {}, ty.void_(), {CallStmt(builtin)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(builtin),
+ },
+ utils::Vector{
+ create<ast::StageAttribute>(ast::PipelineStage::kFragment),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
@@ -948,13 +1160,18 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec4<f32>(1_f, 1_f, 1_f, 1_f));
+ params.Push(vec4<f32>(1_f, 1_f, 1_f, 1_f));
}
auto* builtin = Call(name, params);
- Func("func", {}, ty.void_(), {CallStmt(builtin)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(builtin),
+ },
+ utils::Vector{
+ create<ast::StageAttribute>(ast::PipelineStage::kFragment),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
@@ -1010,9 +1227,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(Construct<u32>(1_i));
+ params.Push(Construct<u32>(1_i));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
@@ -1025,9 +1242,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec2<u32>(1_u, 1_u));
+ params.Push(vec2<u32>(1_u, 1_u));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
@@ -1040,9 +1257,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec3<u32>(1_u, 1_u, 1_u));
+ params.Push(vec3<u32>(1_u, 1_u, 1_u));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
@@ -1055,9 +1272,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec4<u32>(1_u, 1_u, 1_u, 1_u));
+ params.Push(vec4<u32>(1_u, 1_u, 1_u, 1_u));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
@@ -1070,9 +1287,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(Construct<i32>(1_i));
+ params.Push(Construct<i32>(1_i));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
@@ -1085,9 +1302,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec2<i32>(1_i, 1_i));
+ params.Push(vec2<i32>(1_i, 1_i));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
@@ -1100,9 +1317,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec3<i32>(1_i, 1_i, 1_i));
+ params.Push(vec3<i32>(1_i, 1_i, 1_i));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
@@ -1115,9 +1332,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec4<i32>(1_i, 1_i, 1_i, 1_i));
+ params.Push(vec4<i32>(1_i, 1_i, 1_i, 1_i));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
@@ -1142,9 +1359,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec2<bool>(true, true));
+ params.Push(vec2<bool>(true, true));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
@@ -1156,9 +1373,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec3<bool>(true, true, true));
+ params.Push(vec3<bool>(true, true, true));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
@@ -1170,9 +1387,9 @@
std::string name = std::get<0>(GetParam());
uint32_t num_params = std::get<1>(GetParam());
- ast::ExpressionList params;
+ utils::Vector<const ast::Expression*, 8> params;
for (uint32_t i = 0; i < num_params; ++i) {
- params.push_back(vec4<bool>(true, true, true, true));
+ params.Push(vec4<bool>(true, true, true, true));
}
auto* builtin = Call(name, params);
WrapInFunction(builtin);
diff --git a/src/tint/resolver/call_test.cc b/src/tint/resolver/call_test.cc
index 3020254..37aaffa 100644
--- a/src/tint/resolver/call_test.cc
+++ b/src/tint/resolver/call_test.cc
@@ -84,14 +84,14 @@
TEST_F(ResolverCallTest, Valid) {
Enable(ast::Extension::kF16);
- ast::ParameterList params;
- ast::ExpressionList args;
+ utils::Vector<const ast::Parameter*, 4> params;
+ utils::Vector<const ast::Expression*, 4> args;
for (auto& p : all_param_types) {
- params.push_back(Param(Sym(), p.create_type(*this)));
- args.push_back(p.create_value(*this, 0));
+ params.Push(Param(Sym(), p.create_type(*this)));
+ args.Push(p.create_value(*this, 0));
}
- auto* func = Func("foo", std::move(params), ty.f32(), {Return(1.23_f)});
+ auto* func = Func("foo", std::move(params), ty.f32(), utils::Vector{Return(1.23_f)});
auto* call_expr = Call("foo", std::move(args));
WrapInFunction(call_expr);
@@ -104,8 +104,8 @@
TEST_F(ResolverCallTest, OutOfOrder) {
auto* call_expr = Call("b");
- Func("a", {}, ty.void_(), {CallStmt(call_expr)});
- auto* b = Func("b", {}, ty.void_(), {});
+ Func("a", utils::Empty, ty.void_(), utils::Vector{CallStmt(call_expr)});
+ auto* b = Func("b", utils::Empty, ty.void_(), utils::Empty);
EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/call_validation_test.cc b/src/tint/resolver/call_validation_test.cc
index 9625be7..4243093 100644
--- a/src/tint/resolver/call_validation_test.cc
+++ b/src/tint/resolver/call_validation_test.cc
@@ -26,7 +26,15 @@
using ResolverCallValidationTest = ResolverTest;
TEST_F(ResolverCallValidationTest, TooFewArgs) {
- Func("foo", {Param(Sym(), ty.i32()), Param(Sym(), ty.f32())}, ty.void_(), {Return()});
+ Func("foo",
+ utils::Vector{
+ Param(Sym(), ty.i32()),
+ Param(Sym(), ty.f32()),
+ },
+ ty.void_(),
+ utils::Vector{
+ Return(),
+ });
auto* call = Call(Source{{12, 34}}, "foo", 1_i);
WrapInFunction(call);
@@ -35,7 +43,15 @@
}
TEST_F(ResolverCallValidationTest, TooManyArgs) {
- Func("foo", {Param(Sym(), ty.i32()), Param(Sym(), ty.f32())}, ty.void_(), {Return()});
+ Func("foo",
+ utils::Vector{
+ Param(Sym(), ty.i32()),
+ Param(Sym(), ty.f32()),
+ },
+ ty.void_(),
+ utils::Vector{
+ Return(),
+ });
auto* call = Call(Source{{12, 34}}, "foo", 1_i, 1_f, 1_f);
WrapInFunction(call);
@@ -44,7 +60,15 @@
}
TEST_F(ResolverCallValidationTest, MismatchedArgs) {
- Func("foo", {Param(Sym(), ty.i32()), Param(Sym(), ty.f32())}, ty.void_(), {Return()});
+ Func("foo",
+ utils::Vector{
+ Param(Sym(), ty.i32()),
+ Param(Sym(), ty.f32()),
+ },
+ ty.void_(),
+ utils::Vector{
+ Return(),
+ });
auto* call = Call("foo", Expr(Source{{12, 34}}, true), 1_f);
WrapInFunction(call);
@@ -58,10 +82,14 @@
// fn func() -> f32 { return 1.0; }
// fn main() {func(); return; }
- Func("func", {}, ty.f32(), {Return(Expr(1_f))}, {});
+ Func("func", utils::Empty, ty.f32(),
+ utils::Vector{
+ Return(Expr(1_f)),
+ },
+ utils::Empty);
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Source{{12, 34}}, Call("func")),
Return(),
});
@@ -76,9 +104,9 @@
// foo(&z);
// }
auto* param = Param("p", ty.pointer<i32>(ast::StorageClass::kFunction));
- Func("foo", {param}, ty.void_(), {});
- Func("main", {}, ty.void_(),
- {
+ Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("z", ty.i32(), Expr(1_i))),
CallStmt(Call("foo", AddressOf(Source{{12, 34}}, Expr("z")))),
});
@@ -93,9 +121,9 @@
// foo(&z);
// }
auto* param = Param("p", ty.pointer<i32>(ast::StorageClass::kFunction));
- Func("foo", {param}, ty.void_(), {});
- Func("main", {}, ty.void_(),
- {
+ Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("z", ty.i32(), Expr(1_i))),
CallStmt(Call("foo", AddressOf(Expr(Source{{12, 34}}, "z")))),
});
@@ -111,11 +139,13 @@
// var v: S;
// foo(&v.m);
// }
- auto* S = Structure("S", {Member("m", ty.i32())});
+ auto* S = Structure("S", utils::Vector{
+ Member("m", ty.i32()),
+ });
auto* param = Param("p", ty.pointer<i32>(ast::StorageClass::kFunction));
- Func("foo", {param}, ty.void_(), {});
- Func("main", {}, ty.void_(),
- {
+ Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("v", ty.Of(S))),
CallStmt(Call("foo", AddressOf(Source{{12, 34}}, MemberAccessor("v", "m")))),
});
@@ -133,11 +163,13 @@
// let v: S = S();
// foo(&v.m);
// }
- auto* S = Structure("S", {Member("m", ty.i32())});
+ auto* S = Structure("S", utils::Vector{
+ Member("m", ty.i32()),
+ });
auto* param = Param("p", ty.pointer<i32>(ast::StorageClass::kFunction));
- Func("foo", {param}, ty.void_(), {});
- Func("main", {}, ty.void_(),
- {
+ Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("v", ty.Of(S), Construct(ty.Of(S)))),
CallStmt(Call("foo", AddressOf(MemberAccessor(Source{{12, 34}}, "v", "m")))),
});
@@ -151,9 +183,19 @@
// fn bar(p: ptr<function, i32>) {
// foo(p);
// }
- Func("foo", {Param("p", ty.pointer<i32>(ast::StorageClass::kFunction))}, ty.void_(), {});
- Func("bar", {Param("p", ty.pointer<i32>(ast::StorageClass::kFunction))}, ty.void_(),
- ast::StatementList{CallStmt(Call("foo", Expr("p")))});
+ Func("foo",
+ utils::Vector{
+ Param("p", ty.pointer<i32>(ast::StorageClass::kFunction)),
+ },
+ ty.void_(), utils::Empty);
+ Func("bar",
+ utils::Vector{
+ Param("p", ty.pointer<i32>(ast::StorageClass::kFunction)),
+ },
+ ty.void_(),
+ utils::Vector{
+ CallStmt(Call("foo", Expr("p"))),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -168,15 +210,25 @@
// var v: i32;
// bar(&v);
// }
- Func("foo", {Param("p", ty.pointer<i32>(ast::StorageClass::kFunction))}, ty.void_(), {});
- Func("bar", {Param("p", ty.pointer<i32>(ast::StorageClass::kFunction))}, ty.void_(),
- ast::StatementList{CallStmt(Call("foo", Expr("p")))});
- Func("main", {}, ty.void_(),
- {
+ Func("foo",
+ utils::Vector{
+ Param("p", ty.pointer<i32>(ast::StorageClass::kFunction)),
+ },
+ ty.void_(), utils::Empty);
+ Func("bar",
+ utils::Vector{
+ Param("p", ty.pointer<i32>(ast::StorageClass::kFunction)),
+ },
+ ty.void_(),
+ utils::Vector{
+ CallStmt(Call("foo", Expr("p"))),
+ });
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("v", ty.i32(), Expr(1_i))),
CallStmt(Call("foo", AddressOf(Expr("v")))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -191,17 +243,21 @@
// let p: ptr<function, i32> = &v;
// var c: i32 = x(p);
// }
- Func("x", {Param("p", ty.pointer<i32>(ast::StorageClass::kFunction))}, ty.void_(), {});
+ Func("x",
+ utils::Vector{
+ Param("p", ty.pointer<i32>(ast::StorageClass::kFunction)),
+ },
+ ty.void_(), utils::Empty);
auto* v = Var("v", ty.i32());
auto* p = Let("p", ty.pointer(ty.i32(), ast::StorageClass::kFunction), AddressOf(v));
auto* c = Var("c", ty.i32(), ast::StorageClass::kNone, Call("x", Expr(Source{{12, 34}}, p)));
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(v),
Decl(p),
Decl(c),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
EXPECT_FALSE(r()->Resolve());
@@ -218,16 +274,20 @@
// fn main() {
// var c: i32 = foo(p);
// }
- Func("foo", {Param("p", ty.pointer<i32>(ast::StorageClass::kPrivate))}, ty.void_(), {});
+ Func("foo",
+ utils::Vector{
+ Param("p", ty.pointer<i32>(ast::StorageClass::kPrivate)),
+ },
+ ty.void_(), utils::Empty);
auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* p = Let("p", ty.pointer(ty.i32(), ast::StorageClass::kPrivate), AddressOf(v));
auto* c = Var("c", ty.i32(), ast::StorageClass::kNone, Call("foo", Expr(Source{{12, 34}}, p)));
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(p),
Decl(c),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
EXPECT_FALSE(r()->Resolve());
@@ -242,7 +302,10 @@
// v();
// }
GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
- Func("f", {}, ty.void_(), {CallStmt(Call(Source{{12, 34}}, "v"))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call(Source{{12, 34}}, "v")),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(error: cannot call variable 'v'
@@ -255,9 +318,9 @@
// var x : i32;
// x();
// }
- Func("x", {}, ty.void_(), {});
- Func("f", {}, ty.void_(),
- {
+ Func("x", utils::Empty, ty.void_(), utils::Empty);
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var(Source{{56, 78}}, "x", ty.i32())),
CallStmt(Call(Source{{12, 34}}, "x")),
});
diff --git a/src/tint/resolver/compound_statement_test.cc b/src/tint/resolver/compound_statement_test.cc
index d962b3e..0a96ced 100644
--- a/src/tint/resolver/compound_statement_test.cc
+++ b/src/tint/resolver/compound_statement_test.cc
@@ -35,7 +35,7 @@
// var x : 32;
// }
auto* stmt = Decl(Var("x", ty.i32()));
- auto* f = Func("F", {}, ty.void_(), {stmt});
+ auto* f = Func("F", utils::Empty, ty.void_(), utils::Vector{stmt});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -57,7 +57,7 @@
// }
auto* stmt = Decl(Var("x", ty.i32()));
auto* block = Block(stmt);
- auto* f = Func("F", {}, ty.void_(), {block});
+ auto* f = Func("F", utils::Empty, ty.void_(), utils::Vector{block});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -92,7 +92,7 @@
auto* brk = Break();
auto* stmt = Ignore(1_i);
auto* loop = Loop(Block(brk), Block(stmt));
- auto* f = Func("F", {}, ty.void_(), {loop});
+ auto* f = Func("F", utils::Empty, ty.void_(), utils::Vector{loop});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -155,7 +155,7 @@
// }
auto* brk = Break();
auto* loop = Loop(Block(brk), Block());
- Func("F", {}, ty.void_(), {loop});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{loop});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -186,7 +186,7 @@
auto* stmt = Return();
auto* body = Block(stmt);
auto* for_ = For(init, cond, cont, body);
- auto* f = Func("F", {}, ty.void_(), {for_});
+ auto* f = Func("F", utils::Empty, ty.void_(), utils::Vector{for_});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -250,7 +250,7 @@
auto* stmt = Return();
auto* body = Block(stmt);
auto* while_ = While(cond, body);
- auto* f = Func("W", {}, ty.void_(), {while_});
+ auto* f = Func("W", utils::Empty, ty.void_(), utils::Vector{while_});
ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc
index dec4992..5144e63 100644
--- a/src/tint/resolver/const_eval.cc
+++ b/src/tint/resolver/const_eval.cc
@@ -458,7 +458,7 @@
}
/// TransformElements constructs a new constant by applying the transformation function 'f' on each
-/// of the most deeply nested elements of 'cs'.
+/// of the most deeply nested elements of 'cs'. Assumes that all constants are the same type.
template <typename F, typename... CONSTANTS>
const Constant* TransformElements(ProgramBuilder& builder, F&& f, CONSTANTS&&... cs) {
uint32_t n = 0;
@@ -470,17 +470,51 @@
utils::Vector<const sem::Constant*, 8> els;
els.Reserve(n);
for (uint32_t i = 0; i < n; i++) {
- els.Push(TransformElements(builder, f, cs->Index(i)...));
+ els.Push(TransformElements(builder, std::forward<F>(f), cs->Index(i)...));
}
return CreateComposite(builder, ty, std::move(els));
}
+/// TransformBinaryElements constructs a new constant by applying the transformation function 'f' on
+/// each of the most deeply nested elements of both `c0` and `c1`. Unlike TransformElements, this
+/// function handles the constants being of different types, e.g. vector-scalar, scalar-vector.
+template <typename F>
+const Constant* TransformBinaryElements(ProgramBuilder& builder,
+ F&& f,
+ const sem::Constant* c0,
+ const sem::Constant* c1) {
+ uint32_t n0 = 0, n1 = 0;
+ sem::Type::ElementOf(c0->Type(), &n0);
+ sem::Type::ElementOf(c1->Type(), &n1);
+ uint32_t max_n = std::max(n0, n1);
+ // If arity of both constants is 1, invoke callback
+ if (max_n == 1u) {
+ return f(c0, c1);
+ }
+
+ utils::Vector<const sem::Constant*, 8> els;
+ els.Reserve(max_n);
+ for (uint32_t i = 0; i < max_n; i++) {
+ auto nested_or_self = [&](auto& c, uint32_t num_elems) {
+ if (num_elems == 1) {
+ return c;
+ }
+ return c->Index(i);
+ };
+ els.Push(TransformBinaryElements(builder, std::forward<F>(f), nested_or_self(c0, n0),
+ nested_or_self(c1, n1)));
+ }
+ // Use larger type
+ auto* ty = n0 > n1 ? c0->Type() : c1->Type();
+ return CreateComposite(builder, ty, std::move(els));
+}
+
} // namespace
ConstEval::ConstEval(ProgramBuilder& b) : builder(b) {}
-const sem::Constant* ConstEval::Literal(const sem::Type* ty,
- const ast::LiteralExpression* literal) {
+ConstEval::ConstantResult ConstEval::Literal(const sem::Type* ty,
+ const ast::LiteralExpression* literal) {
return Switch(
literal,
[&](const ast::BoolLiteralExpression* lit) {
@@ -510,9 +544,9 @@
});
}
-const sem::Constant* ConstEval::ArrayOrStructCtor(
+ConstEval::ConstantResult ConstEval::ArrayOrStructCtor(
const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args) {
+ utils::VectorRef<const sem::Expression*> args) {
if (args.IsEmpty()) {
return ZeroValue(builder, ty);
}
@@ -531,59 +565,59 @@
return CreateComposite(builder, ty, std::move(els));
}
-const sem::Constant* ConstEval::Conv(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args) {
+ConstEval::ConstantResult ConstEval::Conv(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source) {
uint32_t el_count = 0;
auto* el_ty = sem::Type::ElementOf(ty, &el_count);
if (!el_ty) {
return nullptr;
}
- auto& src = args[0]->Declaration()->source;
- auto* arg = args[0]->ConstantValue();
- if (!arg) {
+ if (!args[0]) {
return nullptr; // Single argument is not constant.
}
- if (auto conv = Convert(ty, arg, src)) {
+ if (auto conv = Convert(ty, args[0], source)) {
return conv.Get();
}
return nullptr;
}
-const sem::Constant* ConstEval::Zero(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*>) {
+ConstEval::ConstantResult ConstEval::Zero(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*>,
+ const Source&) {
return ZeroValue(builder, ty);
}
-const sem::Constant* ConstEval::Identity(const sem::Type*,
- utils::ConstVectorRef<const sem::Expression*> args) {
- return args[0]->ConstantValue();
+ConstEval::ConstantResult ConstEval::Identity(const sem::Type*,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
+ return args[0];
}
-const sem::Constant* ConstEval::VecSplat(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args) {
- if (auto* arg = args[0]->ConstantValue()) {
+ConstEval::ConstantResult ConstEval::VecSplat(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
+ if (auto* arg = args[0]) {
return builder.create<Splat>(ty, arg, static_cast<const sem::Vector*>(ty)->Width());
}
return nullptr;
}
-const sem::Constant* ConstEval::VecCtorS(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args) {
- utils::Vector<const sem::Constant*, 4> els;
- for (auto* arg : args) {
- els.Push(arg->ConstantValue());
- }
- return CreateComposite(builder, ty, std::move(els));
+ConstEval::ConstantResult ConstEval::VecCtorS(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
+ return CreateComposite(builder, ty, args);
}
-const sem::Constant* ConstEval::VecCtorM(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args) {
+ConstEval::ConstantResult ConstEval::VecCtorM(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
utils::Vector<const sem::Constant*, 4> els;
for (auto* arg : args) {
- auto* val = arg->ConstantValue();
+ auto* val = arg;
if (!val) {
return nullptr;
}
@@ -604,8 +638,9 @@
return CreateComposite(builder, ty, std::move(els));
}
-const sem::Constant* ConstEval::MatCtorS(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args) {
+ConstEval::ConstantResult ConstEval::MatCtorS(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
auto* m = static_cast<const sem::Matrix*>(ty);
utils::Vector<const sem::Constant*, 4> els;
@@ -613,32 +648,29 @@
utils::Vector<const sem::Constant*, 4> column;
for (uint32_t r = 0; r < m->rows(); r++) {
auto i = r + c * m->rows();
- column.Push(args[i]->ConstantValue());
+ column.Push(args[i]);
}
els.Push(CreateComposite(builder, m->ColumnType(), std::move(column)));
}
return CreateComposite(builder, ty, std::move(els));
}
-const sem::Constant* ConstEval::MatCtorV(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args) {
- utils::Vector<const sem::Constant*, 4> els;
- for (auto* arg : args) {
- els.Push(arg->ConstantValue());
- }
- return CreateComposite(builder, ty, std::move(els));
+ConstEval::ConstantResult ConstEval::MatCtorV(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
+ return CreateComposite(builder, ty, args);
}
-const sem::Constant* ConstEval::Index(const sem::Expression* obj_expr,
- const sem::Expression* idx_expr) {
+ConstEval::ConstantResult ConstEval::Index(const sem::Expression* obj_expr,
+ const sem::Expression* idx_expr) {
auto obj_val = obj_expr->ConstantValue();
if (!obj_val) {
- return {};
+ return nullptr;
}
auto idx_val = idx_expr->ConstantValue();
if (!idx_val) {
- return {};
+ return nullptr;
}
uint32_t el_count = 0;
@@ -657,18 +689,18 @@
return obj_val->Index(static_cast<size_t>(idx));
}
-const sem::Constant* ConstEval::MemberAccess(const sem::Expression* obj_expr,
- const sem::StructMember* member) {
+ConstEval::ConstantResult ConstEval::MemberAccess(const sem::Expression* obj_expr,
+ const sem::StructMember* member) {
auto obj_val = obj_expr->ConstantValue();
if (!obj_val) {
- return {};
+ return nullptr;
}
return obj_val->Index(static_cast<size_t>(member->Index()));
}
-const sem::Constant* ConstEval::Swizzle(const sem::Type* ty,
- const sem::Expression* vec_expr,
- utils::ConstVectorRef<uint32_t> indices) {
+ConstEval::ConstantResult ConstEval::Swizzle(const sem::Type* ty,
+ const sem::Expression* vec_expr,
+ utils::VectorRef<uint32_t> indices) {
auto* vec_val = vec_expr->ConstantValue();
if (!vec_val) {
return nullptr;
@@ -682,30 +714,32 @@
}
}
-const sem::Constant* ConstEval::Bitcast(const sem::Type*, const sem::Expression*) {
+ConstEval::ConstantResult ConstEval::Bitcast(const sem::Type*, const sem::Expression*) {
// TODO(crbug.com/tint/1581): Implement @const intrinsics
return nullptr;
}
-const sem::Constant* ConstEval::OpComplement(const sem::Type*,
- utils::ConstVectorRef<const sem::Expression*> args) {
+ConstEval::ConstantResult ConstEval::OpComplement(const sem::Type*,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
auto transform = [&](const sem::Constant* c) {
auto create = [&](auto i) {
return CreateElement(builder, c->Type(), decltype(i)(~i.value));
};
return Dispatch_ia_iu32(create, c);
};
- return TransformElements(builder, transform, args[0]->ConstantValue());
+ return TransformElements(builder, transform, args[0]);
}
-const sem::Constant* ConstEval::OpMinus(const sem::Type*,
- utils::ConstVectorRef<const sem::Expression*> args) {
+ConstEval::ConstantResult ConstEval::OpMinus(const sem::Type*,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
auto transform = [&](const sem::Constant* c) {
- auto create = [&](auto i) { //
- // For signed integrals, avoid C++ UB by not negating the
- // smallest negative number. In WGSL, this operation is well
- // defined to return the same value, see:
- // https://gpuweb.github.io/gpuweb/wgsl/#arithmetic-expr.
+ auto create = [&](auto i) {
+ // For signed integrals, avoid C++ UB by not negating the
+ // smallest negative number. In WGSL, this operation is well
+ // defined to return the same value, see:
+ // https://gpuweb.github.io/gpuweb/wgsl/#arithmetic-expr.
using T = UnwrapNumber<decltype(i)>;
if constexpr (std::is_integral_v<T>) {
auto v = i.value;
@@ -719,23 +753,69 @@
};
return Dispatch_fia_fi32_f16(create, c);
};
- return TransformElements(builder, transform, args[0]->ConstantValue());
+ return TransformElements(builder, transform, args[0]);
}
-const sem::Constant* ConstEval::atan2(const sem::Type*,
- utils::ConstVectorRef<const sem::Expression*> args) {
+ConstEval::ConstantResult ConstEval::OpPlus(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source) {
+ auto transform = [&](const sem::Constant* c0, const sem::Constant* c1) {
+ auto create = [&](auto i, auto j) -> const Constant* {
+ using NumberT = decltype(i);
+ using T = UnwrapNumber<NumberT>;
+
+ auto add_values = [](T lhs, T rhs) {
+ if constexpr (std::is_integral_v<T> && std::is_signed_v<T>) {
+ // Ensure no UB for signed overflow
+ using UT = std::make_unsigned_t<T>;
+ return static_cast<T>(static_cast<UT>(lhs) + static_cast<UT>(rhs));
+ } else {
+ return lhs + rhs;
+ }
+ };
+
+ NumberT result;
+ if constexpr (std::is_same_v<NumberT, AInt> || std::is_same_v<NumberT, AFloat>) {
+ // Check for over/underflow for abstract values
+ if (auto r = CheckedAdd(i, j)) {
+ result = r->value;
+ } else {
+ AddError("'" + std::to_string(add_values(i.value, j.value)) +
+ "' cannot be represented as '" +
+ ty->FriendlyName(builder.Symbols()) + "'",
+ source);
+ return nullptr;
+ }
+ } else {
+ result = add_values(i.value, j.value);
+ }
+ return CreateElement(builder, c0->Type(), result);
+ };
+ return Dispatch_fia_fiu32_f16(create, c0, c1);
+ };
+
+ auto r = TransformBinaryElements(builder, transform, args[0], args[1]);
+ if (builder.Diagnostics().contains_errors()) {
+ return utils::Failure;
+ }
+ return r;
+}
+
+ConstEval::ConstantResult ConstEval::atan2(const sem::Type*,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
auto transform = [&](const sem::Constant* c0, const sem::Constant* c1) {
auto create = [&](auto i, auto j) {
return CreateElement(builder, c0->Type(), decltype(i)(std::atan2(i.value, j.value)));
};
return Dispatch_fa_f32_f16(create, c0, c1);
};
- return TransformElements(builder, transform, args[0]->ConstantValue(),
- args[1]->ConstantValue());
+ return TransformElements(builder, transform, args[0], args[1]);
}
-const sem::Constant* ConstEval::clamp(const sem::Type*,
- utils::ConstVectorRef<const sem::Expression*> args) {
+ConstEval::ConstantResult ConstEval::clamp(const sem::Type*,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
auto transform = [&](const sem::Constant* c0, const sem::Constant* c1,
const sem::Constant* c2) {
auto create = [&](auto e, auto low, auto high) {
@@ -744,8 +824,7 @@
};
return Dispatch_fia_fiu32_f16(create, c0, c1, c2);
};
- return TransformElements(builder, transform, args[0]->ConstantValue(), args[1]->ConstantValue(),
- args[2]->ConstantValue());
+ return TransformElements(builder, transform, args[0], args[1], args[2]);
}
utils::Result<const sem::Constant*> ConstEval::Convert(const sem::Type* target_ty,
diff --git a/src/tint/resolver/const_eval.h b/src/tint/resolver/const_eval.h
index 4d299f4..dbc3dbd 100644
--- a/src/tint/resolver/const_eval.h
+++ b/src/tint/resolver/const_eval.h
@@ -44,10 +44,6 @@
/// before calling a method to evaluate an expression's value.
class ConstEval {
public:
- /// Typedef for a constant evaluation function
- using Function = const sem::Constant* (
- ConstEval::*)(const sem::Type* result_ty, utils::ConstVectorRef<const sem::Expression*>);
-
/// The result type of a method that may raise a diagnostic error and the caller should abort
/// resolving. Can be one of three distinct values:
/// * A non-null sem::Constant pointer. Returned when a expression resolves to a creation time
@@ -59,6 +55,11 @@
/// resolving.
using ConstantResult = utils::Result<const sem::Constant*>;
+ /// Typedef for a constant evaluation function
+ using Function = ConstantResult (ConstEval::*)(const sem::Type* result_ty,
+ utils::VectorRef<const sem::Constant*>,
+ const Source&);
+
/// Constructor
/// @param b the program builder
explicit ConstEval(ProgramBuilder& b);
@@ -70,37 +71,37 @@
/// @param ty the target type - must be an array or constructor
/// @param args the input arguments
/// @return the constructed value, or null if the value cannot be calculated
- const sem::Constant* ArrayOrStructCtor(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult ArrayOrStructCtor(const sem::Type* ty,
+ utils::VectorRef<const sem::Expression*> args);
/// @param ty the target type
/// @param expr the input expression
/// @return the bit-cast of the given expression to the given type, or null if the value cannot
/// be calculated
- const sem::Constant* Bitcast(const sem::Type* ty, const sem::Expression* expr);
+ ConstantResult Bitcast(const sem::Type* ty, const sem::Expression* expr);
/// @param obj the object being indexed
/// @param idx the index expression
/// @return the result of the index, or null if the value cannot be calculated
- const sem::Constant* Index(const sem::Expression* obj, const sem::Expression* idx);
+ ConstantResult Index(const sem::Expression* obj, const sem::Expression* idx);
/// @param ty the result type
/// @param lit the literal AST node
/// @return the constant value of the literal
- const sem::Constant* Literal(const sem::Type* ty, const ast::LiteralExpression* lit);
+ ConstantResult Literal(const sem::Type* ty, const ast::LiteralExpression* lit);
/// @param obj the object being accessed
/// @param member the member
/// @return the result of the member access, or null if the value cannot be calculated
- const sem::Constant* MemberAccess(const sem::Expression* obj, const sem::StructMember* member);
+ ConstantResult MemberAccess(const sem::Expression* obj, const sem::StructMember* member);
/// @param ty the result type
/// @param vector the vector being swizzled
/// @param indices the swizzle indices
/// @return the result of the swizzle, or null if the value cannot be calculated
- const sem::Constant* Swizzle(const sem::Type* ty,
- const sem::Expression* vector,
- utils::ConstVectorRef<uint32_t> indices);
+ ConstantResult Swizzle(const sem::Type* ty,
+ const sem::Expression* vector,
+ utils::VectorRef<uint32_t> indices);
/// Convert the `value` to `target_type`
/// @param ty the result type
@@ -116,76 +117,109 @@
/// Type conversion
/// @param ty the result type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the converted value, or null if the value cannot be calculated
- const sem::Constant* Conv(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult Conv(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
/// Zero value type constructor
/// @param ty the result type
/// @param args the input arguments (no arguments provided)
+ /// @param source the source location of the conversion
/// @return the constructed value, or null if the value cannot be calculated
- const sem::Constant* Zero(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult Zero(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
/// Identity value type constructor
/// @param ty the result type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the constructed value, or null if the value cannot be calculated
- const sem::Constant* Identity(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult Identity(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
/// Vector splat constructor
/// @param ty the vector type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the constructed value, or null if the value cannot be calculated
- const sem::Constant* VecSplat(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult VecSplat(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
/// Vector constructor using scalars
/// @param ty the vector type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the constructed value, or null if the value cannot be calculated
- const sem::Constant* VecCtorS(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult VecCtorS(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
/// Vector constructor using a mix of scalars and smaller vectors
/// @param ty the vector type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the constructed value, or null if the value cannot be calculated
- const sem::Constant* VecCtorM(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult VecCtorM(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
/// Matrix constructor using scalar values
/// @param ty the matrix type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the constructed value, or null if the value cannot be calculated
- const sem::Constant* MatCtorS(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult MatCtorS(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
/// Matrix constructor using column vectors
/// @param ty the matrix type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the constructed value, or null if the value cannot be calculated
- const sem::Constant* MatCtorV(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult MatCtorV(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
////////////////////////////////////////////////////////////////////////////
- // Operators
+ // Unary Operators
////////////////////////////////////////////////////////////////////////////
/// Complement operator '~'
/// @param ty the integer type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the result value, or null if the value cannot be calculated
- const sem::Constant* OpComplement(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult OpComplement(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
/// Minus operator '-'
/// @param ty the expression type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the result value, or null if the value cannot be calculated
- const sem::Constant* OpMinus(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult OpMinus(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Binary Operators
+ ////////////////////////////////////////////////////////////////////////////
+
+ /// Plus operator '+'
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location of the conversion
+ /// @return the result value, or null if the value cannot be calculated
+ ConstantResult OpPlus(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
////////////////////////////////////////////////////////////////////////////
// Builtins
@@ -194,16 +228,20 @@
/// atan2 builtin
/// @param ty the expression type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the result value, or null if the value cannot be calculated
- const sem::Constant* atan2(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult atan2(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
/// clamp builtin
/// @param ty the expression type
/// @param args the input arguments
+ /// @param source the source location of the conversion
/// @return the result value, or null if the value cannot be calculated
- const sem::Constant* clamp(const sem::Type* ty,
- utils::ConstVectorRef<const sem::Expression*> args);
+ ConstantResult clamp(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
private:
/// Adds the given error message to the diagnostics
diff --git a/src/tint/resolver/const_eval_test.cc b/src/tint/resolver/const_eval_test.cc
index 3a6c971..6623a5a 100644
--- a/src/tint/resolver/const_eval_test.cc
+++ b/src/tint/resolver/const_eval_test.cc
@@ -43,15 +43,26 @@
template <typename T>
constexpr auto Negate(const Number<T>& v) {
- // For signed integrals, avoid C++ UB by not negating the smallest negative number. In
- // WGSL, this operation is well defined to return the same value, see:
- // https://gpuweb.github.io/gpuweb/wgsl/#arithmetic-expr.
- if constexpr (std::is_integral_v<T> && std::is_signed_v<T>) {
- if (v == std::numeric_limits<T>::min()) {
- return v;
+ if constexpr (std::is_integral_v<T>) {
+ if constexpr (std::is_signed_v<T>) {
+ // For signed integrals, avoid C++ UB by not negating the smallest negative number. In
+ // WGSL, this operation is well defined to return the same value, see:
+ // https://gpuweb.github.io/gpuweb/wgsl/#arithmetic-expr.
+ if (v == std::numeric_limits<T>::min()) {
+ return v;
+ }
+ return -v;
+
+ } else {
+ // Allow negating unsigned values
+ using ST = std::make_signed_t<T>;
+ auto as_signed = Number<ST>{static_cast<ST>(v)};
+ return Number<T>{static_cast<T>(Negate(as_signed))};
}
+ } else {
+ // float case
+ return -v;
}
- return -v;
}
template <typename T>
@@ -65,7 +76,7 @@
// Concats any number of std::vectors
template <typename Vec, typename... Vecs>
-auto Concat(Vec&& v1, Vecs&&... vs) {
+[[nodiscard]] auto Concat(Vec&& v1, Vecs&&... vs) {
auto total_size = v1.size() + (vs.size() + ...);
v1.reserve(total_size);
(std::move(vs.begin(), vs.end(), std::back_inserter(v1)), ...);
@@ -1771,7 +1782,7 @@
}
TEST_F(ResolverConstEvalTest, Array_Struct_f32_Zero) {
- Structure("S", {
+ Structure("S", utils::Vector{
Member("m1", ty.f32()),
Member("m2", ty.f32()),
});
@@ -1914,7 +1925,7 @@
}
TEST_F(ResolverConstEvalTest, Array_Struct_f32_Elements) {
- Structure("S", {
+ Structure("S", utils::Vector{
Member("m1", ty.f32()),
Member("m2", ty.f32()),
});
@@ -1958,7 +1969,8 @@
}
TEST_F(ResolverConstEvalTest, Struct_I32s_ZeroInit) {
- Structure("S", {Member("m1", ty.i32()), Member("m2", ty.i32()), Member("m3", ty.i32())});
+ Structure(
+ "S", utils::Vector{Member("m1", ty.i32()), Member("m2", ty.i32()), Member("m3", ty.i32())});
auto* expr = Construct(ty.type_name("S"));
WrapInFunction(expr);
@@ -1997,7 +2009,7 @@
TEST_F(ResolverConstEvalTest, Struct_MixedScalars_ZeroInit) {
Enable(ast::Extension::kF16);
- Structure("S", {
+ Structure("S", utils::Vector{
Member("m1", ty.i32()),
Member("m2", ty.u32()),
Member("m3", ty.f32()),
@@ -2052,7 +2064,7 @@
}
TEST_F(ResolverConstEvalTest, Struct_VectorF32s_ZeroInit) {
- Structure("S", {
+ Structure("S", utils::Vector{
Member("m1", ty.vec3<f32>()),
Member("m2", ty.vec3<f32>()),
Member("m3", ty.vec3<f32>()),
@@ -2104,7 +2116,7 @@
TEST_F(ResolverConstEvalTest, Struct_MixedVectors_ZeroInit) {
Enable(ast::Extension::kF16);
- Structure("S", {
+ Structure("S", utils::Vector{
Member("m1", ty.vec2<i32>()),
Member("m2", ty.vec3<u32>()),
Member("m3", ty.vec4<f32>()),
@@ -2173,13 +2185,13 @@
}
TEST_F(ResolverConstEvalTest, Struct_Struct_ZeroInit) {
- Structure("Inner", {
+ Structure("Inner", utils::Vector{
Member("m1", ty.i32()),
Member("m2", ty.u32()),
Member("m3", ty.f32()),
});
- Structure("Outer", {
+ Structure("Outer", utils::Vector{
Member("m1", ty.type_name("Inner")),
Member("m2", ty.type_name("Inner")),
});
@@ -2219,7 +2231,7 @@
TEST_F(ResolverConstEvalTest, Struct_MixedScalars_Construct) {
Enable(ast::Extension::kF16);
- Structure("S", {
+ Structure("S", utils::Vector{
Member("m1", ty.i32()),
Member("m2", ty.u32()),
Member("m3", ty.f32()),
@@ -2276,7 +2288,7 @@
TEST_F(ResolverConstEvalTest, Struct_MixedVectors_Construct) {
Enable(ast::Extension::kF16);
- Structure("S", {
+ Structure("S", utils::Vector{
Member("m1", ty.vec2<i32>()),
Member("m2", ty.vec3<u32>()),
Member("m3", ty.vec4<f32>()),
@@ -2346,13 +2358,13 @@
}
TEST_F(ResolverConstEvalTest, Struct_Struct_Construct) {
- Structure("Inner", {
+ Structure("Inner", utils::Vector{
Member("m1", ty.i32()),
Member("m2", ty.u32()),
Member("m3", ty.f32()),
});
- Structure("Outer", {
+ Structure("Outer", utils::Vector{
Member("m1", ty.type_name("Inner")),
Member("m2", ty.type_name("Inner")),
});
@@ -2392,7 +2404,7 @@
}
TEST_F(ResolverConstEvalTest, Struct_Array_Construct) {
- Structure("S", {
+ Structure("S", utils::Vector{
Member("m1", ty.array<i32, 2>()),
Member("m2", ty.array<f32, 3>()),
});
@@ -2921,13 +2933,13 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
TEST_F(ResolverConstEvalTest, MemberAccess) {
- Structure("Inner", {
+ Structure("Inner", utils::Vector{
Member("i1", ty.i32()),
Member("i2", ty.u32()),
Member("i3", ty.f32()),
});
- Structure("Outer", {
+ Structure("Outer", utils::Vector{
Member("o1", ty.type_name("Inner")),
Member("o2", ty.type_name("Inner")),
});
@@ -3114,34 +3126,195 @@
} // namespace unary_op
-namespace builtin {
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Binary op
+////////////////////////////////////////////////////////////////////////////////////////////////////
+namespace binary_op {
-template <typename T>
-struct Values {
- std::vector<T> args;
- T result;
- bool result_pos_or_neg;
-};
+using Types = std::variant<AInt, AFloat, u32, i32, f32, f16>;
struct Case {
- std::variant<Values<AInt>, Values<AFloat>, Values<u32>, Values<i32>, Values<f32>, Values<f16>>
- values;
+ Types lhs;
+ Types rhs;
+ Types expected;
+ bool is_overflow;
};
static std::ostream& operator<<(std::ostream& o, const Case& c) {
std::visit(
- [&](auto&& v) {
- for (auto& e : v.args) {
- o << e << ((&e != &v.args.back()) ? " " : "");
+ [&](auto&& lhs, auto&& rhs, auto&& expected) {
+ o << "lhs: " << lhs << ", rhs: " << rhs << ", expected: " << expected;
+ },
+ c.lhs, c.rhs, c.expected);
+ return o;
+}
+
+template <typename T, typename U, typename V>
+Case C(T lhs, U rhs, V expected, bool is_overflow = false) {
+ return Case{lhs, rhs, expected, is_overflow};
+}
+
+using ResolverConstEvalBinaryOpTest = ResolverTestWithParam<std::tuple<ast::BinaryOp, Case>>;
+TEST_P(ResolverConstEvalBinaryOpTest, Test) {
+ Enable(ast::Extension::kF16);
+
+ auto op = std::get<0>(GetParam());
+ auto c = std::get<1>(GetParam());
+ std::visit(
+ [&](auto&& lhs, auto&& rhs, auto&& expected) {
+ using T = std::decay_t<decltype(expected)>;
+
+ if constexpr (std::is_same_v<T, AInt> || std::is_same_v<T, AFloat>) {
+ if (c.is_overflow) {
+ return;
+ }
+ }
+
+ auto* expr = create<ast::BinaryExpression>(op, Expr(lhs), Expr(rhs));
+ GlobalConst("C", nullptr, expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ const sem::Constant* value = sem->ConstantValue();
+ ASSERT_NE(value, nullptr);
+ EXPECT_TYPE(value->Type(), sem->Type());
+ EXPECT_EQ(value->As<T>(), expected);
+
+ if constexpr (IsInteger<UnwrapNumber<T>>) {
+ // Check that the constant's integer doesn't contain unexpected data in the MSBs
+ // that are outside of the bit-width of T.
+ EXPECT_EQ(value->As<AInt>(), AInt(expected));
}
},
- c.values);
+ c.lhs, c.rhs, c.expected);
+}
+
+INSTANTIATE_TEST_SUITE_P(MixedAbstractArgs,
+ ResolverConstEvalBinaryOpTest,
+ testing::Combine(testing::Values(ast::BinaryOp::kAdd),
+ testing::ValuesIn(std::vector{
+ // Mixed abstract type args
+ C(1_a, 2.3_a, 3.3_a),
+ C(2.3_a, 1_a, 3.3_a),
+ })));
+
+template <typename T>
+std::vector<Case> OpAddIntCases() {
+ static_assert(IsInteger<UnwrapNumber<T>>);
+ return {
+ C(T{0}, T{0}, T{0}),
+ C(T{1}, T{2}, T{3}),
+ C(T::Lowest(), T{1}, T{T::Lowest() + 1}),
+ C(T::Highest(), Negate(T{1}), T{T::Highest() - 1}),
+ C(T::Lowest(), T::Highest(), Negate(T{1})),
+ C(T::Highest(), T{1}, T::Lowest(), true),
+ C(T::Lowest(), Negate(T{1}), T::Highest(), true),
+ };
+}
+template <typename T>
+std::vector<Case> OpAddFloatCases() {
+ static_assert(IsFloatingPoint<UnwrapNumber<T>>);
+ return {
+ C(T{0}, T{0}, T{0}),
+ C(T{1}, T{2}, T{3}),
+ C(T::Lowest(), T{1}, T{T::Lowest() + 1}),
+ C(T::Highest(), Negate(T{1}), T{T::Highest() - 1}),
+ C(T::Lowest(), T::Highest(), T{0}),
+ C(T::Highest(), T::Highest(), T::Inf(), true),
+ C(T::Lowest(), Negate(T::Highest()), -T::Inf(), true),
+ };
+}
+INSTANTIATE_TEST_SUITE_P(Add,
+ ResolverConstEvalBinaryOpTest,
+ testing::Combine(testing::Values(ast::BinaryOp::kAdd),
+ testing::ValuesIn(Concat( //
+ OpAddIntCases<AInt>(),
+ OpAddIntCases<i32>(),
+ OpAddIntCases<u32>(),
+ OpAddFloatCases<AFloat>(),
+ OpAddFloatCases<f32>(),
+ OpAddFloatCases<f16>()))));
+
+TEST_F(ResolverConstEvalTest, BinaryAbstractAddOverflow_AInt) {
+ GlobalConst("c", nullptr, Add(Source{{1, 1}}, Expr(AInt::Highest()), 1_a));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "1:1 error: '-9223372036854775808' cannot be represented as 'abstract-int'");
+}
+
+TEST_F(ResolverConstEvalTest, BinaryAbstractAddUnderflow_AInt) {
+ GlobalConst("c", nullptr, Add(Source{{1, 1}}, Expr(AInt::Lowest()), -1_a));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "1:1 error: '9223372036854775807' cannot be represented as 'abstract-int'");
+}
+
+TEST_F(ResolverConstEvalTest, BinaryAbstractAddOverflow_AFloat) {
+ GlobalConst("c", nullptr, Add(Source{{1, 1}}, Expr(AFloat::Highest()), AFloat::Highest()));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "1:1 error: 'inf' cannot be represented as 'abstract-float'");
+}
+
+TEST_F(ResolverConstEvalTest, BinaryAbstractAddUnderflow_AFloat) {
+ GlobalConst("c", nullptr, Add(Source{{1, 1}}, Expr(AFloat::Lowest()), AFloat::Lowest()));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "1:1 error: '-inf' cannot be represented as 'abstract-float'");
+}
+
+TEST_F(ResolverConstEvalTest, BinaryAbstractMixed_ScalarScalar) {
+ auto* a = Const("a", nullptr, Expr(1_a)); // AInt
+ auto* b = Const("b", nullptr, Expr(2.3_a)); // AFloat
+ auto* c = Add(Expr("a"), Expr("b"));
+ WrapInFunction(a, b, c);
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ auto* sem = Sem().Get(c);
+ ASSERT_TRUE(sem);
+ ASSERT_TRUE(sem->ConstantValue());
+ auto result = sem->ConstantValue()->As<AFloat>();
+ EXPECT_EQ(result, 3.3f);
+}
+
+TEST_F(ResolverConstEvalTest, BinaryAbstractMixed_ScalarVector) {
+ auto* a = Const("a", nullptr, Expr(1_a)); // AInt
+ auto* b = Const("b", nullptr, Construct(ty.vec(nullptr, 3), Expr(2.3_a))); // AFloat
+ auto* c = Add(Expr("a"), Expr("b"));
+ WrapInFunction(a, b, c);
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ auto* sem = Sem().Get(c);
+ ASSERT_TRUE(sem);
+ ASSERT_TRUE(sem->ConstantValue());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 3.3f);
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 3.3f);
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 3.3f);
+}
+
+} // namespace binary_op
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Builtin
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace builtin {
+
+using Types = std::variant<AInt, AFloat, u32, i32, f32, f16>;
+
+struct Case {
+ utils::Vector<Types, 8> args;
+ Types result;
+ bool result_pos_or_neg;
+};
+
+static std::ostream& operator<<(std::ostream& o, const Case& c) {
+ for (auto& a : c.args) {
+ std::visit([&](auto&& v) { o << v << ((&a != &c.args.Back()) ? " " : ""); }, a);
+ }
return o;
}
template <typename T>
-Case C(std::vector<T> args, T result, bool result_pos_or_neg = false) {
- return Case{Values<T>{std::move(args), result, result_pos_or_neg}};
+Case C(std::initializer_list<Types> args, T result, bool result_pos_or_neg = false) {
+ return Case{std::move(args), std::move(result), result_pos_or_neg};
}
using ResolverConstEvalBuiltinTest = ResolverTestWithParam<std::tuple<sem::BuiltinType, Case>>;
@@ -3151,12 +3324,15 @@
auto builtin = std::get<0>(GetParam());
auto c = std::get<1>(GetParam());
+
+ utils::Vector<const ast::Expression*, 8> args;
+ for (auto& a : c.args) {
+ std::visit([&](auto&& v) { args.Push(Expr(v)); }, a);
+ }
+
std::visit(
- [&](auto&& values) {
- using T = decltype(values.result);
- auto args = utils::Transform(values.args, [&](auto&& a) {
- return static_cast<const ast::Expression*>(Expr(a));
- });
+ [&](auto&& result) {
+ using T = std::decay_t<decltype(result)>;
auto* expr = Call(sem::str(builtin), std::move(args));
GlobalConst("C", nullptr, expr);
@@ -3171,22 +3347,22 @@
auto actual = value->As<T>();
if constexpr (IsFloatingPoint<UnwrapNumber<T>>) {
- if (std::isnan(values.result)) {
+ if (std::isnan(result)) {
EXPECT_TRUE(std::isnan(actual));
} else {
- EXPECT_FLOAT_EQ(values.result_pos_or_neg ? Abs(actual) : actual, values.result);
+ EXPECT_FLOAT_EQ(c.result_pos_or_neg ? Abs(actual) : actual, result);
}
} else {
- EXPECT_EQ(values.result_pos_or_neg ? Abs(actual) : actual, values.result);
+ EXPECT_EQ(c.result_pos_or_neg ? Abs(actual) : actual, result);
}
if constexpr (IsInteger<UnwrapNumber<T>>) {
// Check that the constant's integer doesn't contain unexpected data in the MSBs
// that are outside of the bit-width of T.
- EXPECT_EQ(value->As<AInt>(), AInt(values.result));
+ EXPECT_EQ(value->As<AInt>(), AInt(result));
}
},
- c.values);
+ c.result);
}
template <typename T, bool finite_only>
@@ -3246,6 +3422,15 @@
}
INSTANTIATE_TEST_SUITE_P( //
+ MixedAbstractArgs,
+ ResolverConstEvalBuiltinTest,
+ testing::Combine(testing::Values(sem::BuiltinType::kAtan2),
+ testing::ValuesIn(std::vector{
+ C({1_a, 1.0_a}, 0.78539819_a),
+ C({1.0_a, 1_a}, 0.78539819_a),
+ })));
+
+INSTANTIATE_TEST_SUITE_P( //
Atan2,
ResolverConstEvalBuiltinTest,
testing::Combine(testing::Values(sem::BuiltinType::kAtan2),
diff --git a/src/tint/resolver/control_block_validation_test.cc b/src/tint/resolver/control_block_validation_test.cc
index a5ba7ca..9b0d289 100644
--- a/src/tint/resolver/control_block_validation_test.cc
+++ b/src/tint/resolver/control_block_validation_test.cc
@@ -213,8 +213,8 @@
// }
auto* var = Var("a", ty.i32(), Expr(2_i));
- auto* block = Block(Decl(var), Switch("a", //
- Case(Source{{12, 34}}, {Expr(1_u)}), //
+ auto* block = Block(Decl(var), Switch("a", //
+ Case(Source{{12, 34}}, utils::Vector{Expr(1_u)}), //
DefaultCase()));
WrapInFunction(block);
@@ -232,9 +232,9 @@
// }
auto* var = Var("a", ty.u32(), Expr(2_u));
- auto* block = Block(Decl(var), //
- Switch("a", //
- Case(Source{{12, 34}}, {Expr(-1_i)}), //
+ auto* block = Block(Decl(var), //
+ Switch("a", //
+ Case(Source{{12, 34}}, utils::Vector{Expr(-1_i)}), //
DefaultCase()));
WrapInFunction(block);
@@ -256,7 +256,7 @@
auto* block = Block(Decl(var), //
Switch("a", //
Case(Expr(0_u)),
- Case({
+ Case(utils::Vector{
Expr(Source{{12, 34}}, 2_u),
Expr(3_u),
Expr(Source{{56, 78}}, 2_u),
@@ -282,7 +282,7 @@
auto* block = Block(Decl(var), //
Switch("a", //
Case(Expr(Source{{12, 34}}, -10_i)),
- Case({
+ Case(utils::Vector{
Expr(0_i),
Expr(1_i),
Expr(2_i),
diff --git a/src/tint/resolver/dependency_graph.cc b/src/tint/resolver/dependency_graph.cc
index 3d550ff..6dd35a5 100644
--- a/src/tint/resolver/dependency_graph.cc
+++ b/src/tint/resolver/dependency_graph.cc
@@ -204,6 +204,7 @@
[&](const ast::Enable*) {
// Enable directives do not effect the dependency graph.
},
+ [&](const ast::StaticAssert* assertion) { TraverseExpression(assertion->condition); },
[&](Default) { UnhandledNode(diagnostics_, global->node); });
}
@@ -237,7 +238,7 @@
/// Traverses the statements, performing symbol resolution and determining
/// global dependencies.
- void TraverseStatements(const ast::StatementList& stmts) {
+ void TraverseStatements(utils::VectorRef<const ast::Statement*> stmts) {
for (auto* s : stmts) {
TraverseStatement(s);
}
@@ -315,6 +316,7 @@
TraverseExpression(w->condition);
TraverseStatement(w->body);
},
+ [&](const ast::StaticAssert* assertion) { TraverseExpression(assertion->condition); },
[&](Default) {
if (!stmt->IsAnyOf<ast::BreakStatement, ast::ContinueStatement,
ast::DiscardStatement, ast::FallthroughStatement>()) {
@@ -404,7 +406,7 @@
/// Traverses the attribute list, performing symbol resolution and
/// determining global dependencies.
- void TraverseAttributes(const ast::AttributeList& attrs) {
+ void TraverseAttributes(utils::VectorRef<const ast::Attribute*> attrs) {
for (auto* attr : attrs) {
TraverseAttribute(attr);
}
@@ -487,6 +489,10 @@
/// #diagnostics.
/// @returns true if analysis found no errors, otherwise false.
bool Run(const ast::Module& module) {
+ // Reserve container memory
+ graph_.resolved_symbols.reserve(module.GlobalDeclarations().Length());
+ sorted_.reserve(module.GlobalDeclarations().Length());
+
// Collect all the named globals from the AST module
GatherGlobals(module);
@@ -515,6 +521,8 @@
[&](const ast::TypeDecl* td) { return td->name; },
[&](const ast::Function* func) { return func->symbol; },
[&](const ast::Variable* var) { return var->symbol; },
+ [&](const ast::Enable*) { return Symbol(); },
+ [&](const ast::StaticAssert*) { return Symbol(); },
[&](Default) {
UnhandledNode(diagnostics_, node);
return Symbol{};
@@ -533,11 +541,12 @@
/// declaration
std::string KindOf(const ast::Node* node) {
return Switch(
- node, //
- [&](const ast::Struct*) { return "struct"; }, //
- [&](const ast::Alias*) { return "alias"; }, //
- [&](const ast::Function*) { return "function"; }, //
- [&](const ast::Variable* v) { return v->Kind(); }, //
+ node, //
+ [&](const ast::Struct*) { return "struct"; }, //
+ [&](const ast::Alias*) { return "alias"; }, //
+ [&](const ast::Function*) { return "function"; }, //
+ [&](const ast::Variable* v) { return v->Kind(); }, //
+ [&](const ast::StaticAssert*) { return "static_assert"; }, //
[&](Default) {
UnhandledNode(diagnostics_, node);
return "<error>";
@@ -549,9 +558,8 @@
void GatherGlobals(const ast::Module& module) {
for (auto* node : module.GlobalDeclarations()) {
auto* global = allocator_.Create(node);
- // Enable directives do not form a symbol. Skip them.
- if (!node->Is<ast::Enable>()) {
- globals_.emplace(SymbolOf(node), global);
+ if (auto symbol = SymbolOf(node); symbol.IsValid()) {
+ globals_.emplace(symbol, global);
}
declaration_order_.emplace_back(global);
}
diff --git a/src/tint/resolver/dependency_graph_test.cc b/src/tint/resolver/dependency_graph_test.cc
index b7ffa79..7a8110b 100644
--- a/src/tint/resolver/dependency_graph_test.cc
+++ b/src/tint/resolver/dependency_graph_test.cc
@@ -384,13 +384,13 @@
/// The program builder
ProgramBuilder* const builder;
/// Parameters to a function that may need to be built
- ast::ParameterList parameters;
+ utils::Vector<const ast::Parameter*, 8> parameters;
/// Shallow function var / let declaration statements
- ast::StatementList statements;
+ utils::Vector<const ast::Statement*, 8> statements;
/// Nested function local var / let declaration statements
- ast::StatementList nested_statements;
+ utils::Vector<const ast::Statement*, 8> nested_statements;
/// Function attributes
- ast::AttributeList func_attrs;
+ utils::Vector<const ast::Attribute*, 8> func_attrs;
/// Constructor
/// @param builder the program builder
@@ -431,32 +431,32 @@
case SymbolDeclKind::Alias:
return b.Alias(source, symbol, b.ty.i32());
case SymbolDeclKind::Struct:
- return b.Structure(source, symbol, {b.Member("m", b.ty.i32())});
+ return b.Structure(source, symbol, utils::Vector{b.Member("m", b.ty.i32())});
case SymbolDeclKind::Function:
- return b.Func(source, symbol, {}, b.ty.void_(), {});
+ return b.Func(source, symbol, utils::Empty, b.ty.void_(), utils::Empty);
case SymbolDeclKind::Parameter: {
auto* node = b.Param(source, symbol, b.ty.i32());
- parameters.emplace_back(node);
+ parameters.Push(node);
return node;
}
case SymbolDeclKind::LocalVar: {
auto* node = b.Var(source, symbol, b.ty.i32());
- statements.emplace_back(b.Decl(node));
+ statements.Push(b.Decl(node));
return node;
}
case SymbolDeclKind::LocalLet: {
auto* node = b.Let(source, symbol, b.ty.i32(), b.Expr(1_i));
- statements.emplace_back(b.Decl(node));
+ statements.Push(b.Decl(node));
return node;
}
case SymbolDeclKind::NestedLocalVar: {
auto* node = b.Var(source, symbol, b.ty.i32());
- nested_statements.emplace_back(b.Decl(node));
+ nested_statements.Push(b.Decl(node));
return node;
}
case SymbolDeclKind::NestedLocalLet: {
auto* node = b.Let(source, symbol, b.ty.i32(), b.Expr(1_i));
- nested_statements.emplace_back(b.Decl(node));
+ nested_statements.Push(b.Decl(node));
return node;
}
}
@@ -543,83 +543,82 @@
}
case SymbolUseKind::StructMemberType: {
auto* node = b.ty.type_name(source, symbol);
- b.Structure(b.Sym(), {b.Member("m", node)});
+ b.Structure(b.Sym(), utils::Vector{b.Member("m", node)});
return node;
}
case SymbolUseKind::CallFunction: {
auto* node = b.Expr(source, symbol);
- statements.emplace_back(b.CallStmt(b.Call(node)));
+ statements.Push(b.CallStmt(b.Call(node)));
return node;
}
case SymbolUseKind::ParameterType: {
auto* node = b.ty.type_name(source, symbol);
- parameters.emplace_back(b.Param(b.Sym(), node));
+ parameters.Push(b.Param(b.Sym(), node));
return node;
}
case SymbolUseKind::LocalVarType: {
auto* node = b.ty.type_name(source, symbol);
- statements.emplace_back(b.Decl(b.Var(b.Sym(), node)));
+ statements.Push(b.Decl(b.Var(b.Sym(), node)));
return node;
}
case SymbolUseKind::LocalVarArrayElemType: {
auto* node = b.ty.type_name(source, symbol);
- statements.emplace_back(b.Decl(b.Var(b.Sym(), b.ty.array(node, 4_u), b.Expr(1_i))));
+ statements.Push(b.Decl(b.Var(b.Sym(), b.ty.array(node, 4_u), b.Expr(1_i))));
return node;
}
case SymbolUseKind::LocalVarArraySizeValue: {
auto* node = b.Expr(source, symbol);
- statements.emplace_back(
- b.Decl(b.Var(b.Sym(), b.ty.array(b.ty.i32(), node), b.Expr(1_i))));
+ statements.Push(b.Decl(b.Var(b.Sym(), b.ty.array(b.ty.i32(), node), b.Expr(1_i))));
return node;
}
case SymbolUseKind::LocalVarVectorElemType: {
auto* node = b.ty.type_name(source, symbol);
- statements.emplace_back(b.Decl(b.Var(b.Sym(), b.ty.vec3(node))));
+ statements.Push(b.Decl(b.Var(b.Sym(), b.ty.vec3(node))));
return node;
}
case SymbolUseKind::LocalVarMatrixElemType: {
auto* node = b.ty.type_name(source, symbol);
- statements.emplace_back(b.Decl(b.Var(b.Sym(), b.ty.mat3x4(node))));
+ statements.Push(b.Decl(b.Var(b.Sym(), b.ty.mat3x4(node))));
return node;
}
case SymbolUseKind::LocalVarValue: {
auto* node = b.Expr(source, symbol);
- statements.emplace_back(b.Decl(b.Var(b.Sym(), b.ty.i32(), node)));
+ statements.Push(b.Decl(b.Var(b.Sym(), b.ty.i32(), node)));
return node;
}
case SymbolUseKind::LocalLetType: {
auto* node = b.ty.type_name(source, symbol);
- statements.emplace_back(b.Decl(b.Let(b.Sym(), node, b.Expr(1_i))));
+ statements.Push(b.Decl(b.Let(b.Sym(), node, b.Expr(1_i))));
return node;
}
case SymbolUseKind::LocalLetValue: {
auto* node = b.Expr(source, symbol);
- statements.emplace_back(b.Decl(b.Let(b.Sym(), b.ty.i32(), node)));
+ statements.Push(b.Decl(b.Let(b.Sym(), b.ty.i32(), node)));
return node;
}
case SymbolUseKind::NestedLocalVarType: {
auto* node = b.ty.type_name(source, symbol);
- nested_statements.emplace_back(b.Decl(b.Var(b.Sym(), node)));
+ nested_statements.Push(b.Decl(b.Var(b.Sym(), node)));
return node;
}
case SymbolUseKind::NestedLocalVarValue: {
auto* node = b.Expr(source, symbol);
- nested_statements.emplace_back(b.Decl(b.Var(b.Sym(), b.ty.i32(), node)));
+ nested_statements.Push(b.Decl(b.Var(b.Sym(), b.ty.i32(), node)));
return node;
}
case SymbolUseKind::NestedLocalLetType: {
auto* node = b.ty.type_name(source, symbol);
- nested_statements.emplace_back(b.Decl(b.Let(b.Sym(), node, b.Expr(1_i))));
+ nested_statements.Push(b.Decl(b.Let(b.Sym(), node, b.Expr(1_i))));
return node;
}
case SymbolUseKind::NestedLocalLetValue: {
auto* node = b.Expr(source, symbol);
- nested_statements.emplace_back(b.Decl(b.Let(b.Sym(), b.ty.i32(), node)));
+ nested_statements.Push(b.Decl(b.Let(b.Sym(), b.ty.i32(), node)));
return node;
}
case SymbolUseKind::WorkgroupSizeValue: {
auto* node = b.Expr(source, symbol);
- func_attrs.emplace_back(b.WorkgroupSize(1_i, node, 2_i));
+ func_attrs.Push(b.WorkgroupSize(1_i, node, 2_i));
return node;
}
}
@@ -628,15 +627,15 @@
void SymbolTestHelper::Build() {
auto& b = *builder;
- if (!nested_statements.empty()) {
- statements.emplace_back(b.Block(nested_statements));
- nested_statements.clear();
+ if (!nested_statements.IsEmpty()) {
+ statements.Push(b.Block(nested_statements));
+ nested_statements.Clear();
}
- if (!parameters.empty() || !statements.empty() || !func_attrs.empty()) {
+ if (!parameters.IsEmpty() || !statements.IsEmpty() || !func_attrs.IsEmpty()) {
b.Func("func", parameters, b.ty.void_(), statements, func_attrs);
- parameters.clear();
- statements.clear();
- func_attrs.clear();
+ parameters.Clear();
+ statements.Clear();
+ func_attrs.Clear();
}
}
@@ -651,8 +650,8 @@
// fn A() { B(); }
// fn B() {}
- Func("A", {}, ty.void_(), {CallStmt(Call(Expr(Source{{12, 34}}, "B")))});
- Func(Source{{56, 78}}, "B", {}, ty.void_(), {Return()});
+ Func("A", utils::Empty, ty.void_(), utils::Vector{CallStmt(Call(Expr(Source{{12, 34}}, "B")))});
+ Func(Source{{56, 78}}, "B", utils::Empty, ty.void_(), utils::Vector{Return()});
Build();
}
@@ -663,7 +662,8 @@
// }
// type T = i32;
- Func("F", {}, ty.void_(), {Block(Ignore(Construct(ty.type_name(Source{{12, 34}}, "T"))))});
+ Func("F", utils::Empty, ty.void_(),
+ utils::Vector{Block(Ignore(Construct(ty.type_name(Source{{12, 34}}, "T"))))});
Alias(Source{{56, 78}}, "T", ty.i32());
Build();
@@ -675,7 +675,8 @@
// }
// type T = i32;
- Func("F", {}, ty.void_(), {Block(Decl(Var("v", ty.type_name(Source{{12, 34}}, "T"))))});
+ Func("F", utils::Empty, ty.void_(),
+ utils::Vector{Block(Decl(Var("v", ty.type_name(Source{{12, 34}}, "T"))))});
Alias(Source{{56, 78}}, "T", ty.i32());
Build();
@@ -685,7 +686,8 @@
// fn F(p : T) {}
// type T = i32;
- Func("F", {Param("p", ty.type_name(Source{{12, 34}}, "T"))}, ty.void_(), {});
+ Func("F", utils::Vector{Param("p", ty.type_name(Source{{12, 34}}, "T"))}, ty.void_(),
+ utils::Empty);
Alias(Source{{56, 78}}, "T", ty.i32());
Build();
@@ -695,7 +697,7 @@
// fn F() -> T {}
// type T = i32;
- Func("F", {}, ty.type_name(Source{{12, 34}}, "T"), {});
+ Func("F", utils::Empty, ty.type_name(Source{{12, 34}}, "T"), utils::Empty);
Alias(Source{{56, 78}}, "T", ty.i32());
Build();
@@ -705,7 +707,7 @@
// struct S { m : T };
// type T = i32;
- Structure("S", {Member("m", ty.type_name(Source{{12, 34}}, "T"))});
+ Structure("S", utils::Vector{Member("m", ty.type_name(Source{{12, 34}}, "T"))});
Alias(Source{{56, 78}}, "T", ty.i32());
Build();
@@ -717,8 +719,8 @@
// }
// var G: f32 = 2.1;
- Func("F", {}, ty.void_(),
- {
+ Func("F", utils::Empty, ty.void_(),
+ utils::Vector{
Block(Assign(Expr(Source{{12, 34}}, "G"), 3.14_f)),
});
@@ -808,8 +810,8 @@
TEST_F(ResolverDependencyGraphCyclicRefTest, DirectCall) {
// fn main() { main(); }
- Func(Source{{12, 34}}, "main", {}, ty.void_(),
- {CallStmt(Call(Expr(Source{{56, 78}}, "main")))});
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.void_(),
+ utils::Vector{CallStmt(Call(Expr(Source{{56, 78}}, "main")))});
Build(R"(12:34 error: cyclic dependency found: 'main' -> 'main'
56:78 note: function 'main' calls function 'main' here)");
@@ -822,15 +824,18 @@
// 4: fn c() { d(); }
// 5: fn b() { c(); }
- Func(Source{{1, 1}}, "a", {}, ty.void_(), {CallStmt(Call(Expr(Source{{1, 10}}, "b")))});
- Func(Source{{2, 1}}, "e", {}, ty.void_(), {});
- Func(Source{{3, 1}}, "d", {}, ty.void_(),
- {
+ Func(Source{{1, 1}}, "a", utils::Empty, ty.void_(),
+ utils::Vector{CallStmt(Call(Expr(Source{{1, 10}}, "b")))});
+ Func(Source{{2, 1}}, "e", utils::Empty, ty.void_(), utils::Empty);
+ Func(Source{{3, 1}}, "d", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call(Expr(Source{{3, 10}}, "e"))),
CallStmt(Call(Expr(Source{{3, 10}}, "b"))),
});
- Func(Source{{4, 1}}, "c", {}, ty.void_(), {CallStmt(Call(Expr(Source{{4, 10}}, "d")))});
- Func(Source{{5, 1}}, "b", {}, ty.void_(), {CallStmt(Call(Expr(Source{{5, 10}}, "c")))});
+ Func(Source{{4, 1}}, "c", utils::Empty, ty.void_(),
+ utils::Vector{CallStmt(Call(Expr(Source{{4, 10}}, "d")))});
+ Func(Source{{5, 1}}, "b", utils::Empty, ty.void_(),
+ utils::Vector{CallStmt(Call(Expr(Source{{5, 10}}, "c")))});
Build(R"(5:1 error: cyclic dependency found: 'b' -> 'c' -> 'd' -> 'b'
5:10 note: function 'b' calls function 'c' here
@@ -871,7 +876,8 @@
// a: S;
// };
- Structure(Source{{12, 34}}, "S", {Member("a", ty.type_name(Source{{56, 78}}, "S"))});
+ Structure(Source{{12, 34}}, "S",
+ utils::Vector{Member("a", ty.type_name(Source{{56, 78}}, "S"))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -884,9 +890,9 @@
// 2: struct X { y: Y; };
// 3: struct Z { x: X; };
- Structure(Source{{1, 1}}, "Y", {Member("z", ty.type_name(Source{{1, 10}}, "Z"))});
- Structure(Source{{2, 1}}, "X", {Member("y", ty.type_name(Source{{2, 10}}, "Y"))});
- Structure(Source{{3, 1}}, "Z", {Member("x", ty.type_name(Source{{3, 10}}, "X"))});
+ Structure(Source{{1, 1}}, "Y", utils::Vector{Member("z", ty.type_name(Source{{1, 10}}, "Z"))});
+ Structure(Source{{2, 1}}, "X", utils::Vector{Member("y", ty.type_name(Source{{2, 10}}, "Y"))});
+ Structure(Source{{3, 1}}, "Z", utils::Vector{Member("x", ty.type_name(Source{{3, 10}}, "X"))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -960,10 +966,10 @@
// 5: type R = A;
// 6: const L : S = Z;
- Func(Source{{1, 1}}, "F", {}, ty.type_name(Source{{1, 5}}, "R"),
- {Return(Expr(Source{{1, 10}}, "Z"))});
+ Func(Source{{1, 1}}, "F", utils::Empty, ty.type_name(Source{{1, 5}}, "R"),
+ utils::Vector{Return(Expr(Source{{1, 10}}, "Z"))});
Alias(Source{{2, 1}}, "A", ty.type_name(Source{{2, 10}}, "S"));
- Structure(Source{{3, 1}}, "S", {Member("a", ty.type_name(Source{{3, 10}}, "A"))});
+ Structure(Source{{3, 1}}, "S", utils::Vector{Member("a", ty.type_name(Source{{3, 10}}, "A"))});
GlobalVar(Source{{4, 1}}, "Z", nullptr, Expr(Source{{4, 10}}, "L"));
Alias(Source{{5, 1}}, "R", ty.type_name(Source{{5, 10}}, "A"));
GlobalConst(Source{{6, 1}}, "L", ty.type_name(Source{{5, 5}}, "S"), Expr(Source{{5, 10}}, "Z"));
@@ -1039,7 +1045,7 @@
helper.Add(use_kind, symbol, Source{{56, 78}});
helper.Build();
- ASSERT_EQ(AST().GlobalDeclarations().size(), 2u);
+ ASSERT_EQ(AST().GlobalDeclarations().Length(), 2u);
auto* decl = AST().GlobalDeclarations()[0];
auto* use = AST().GlobalDeclarations()[1];
@@ -1059,7 +1065,7 @@
helper.Add(decl_kind, symbol, Source{{12, 34}});
helper.Build();
- ASSERT_EQ(AST().GlobalDeclarations().size(), 2u);
+ ASSERT_EQ(AST().GlobalDeclarations().Length(), 2u);
auto* use = AST().GlobalDeclarations()[0];
auto* decl = AST().GlobalDeclarations()[1];
@@ -1164,9 +1170,9 @@
SymbolTestHelper helper(this);
auto* outer = helper.Add(outer_kind, symbol, Source{{12, 34}});
helper.Add(inner_kind, symbol, Source{{56, 78}});
- auto* inner_var = helper.nested_statements.size()
+ auto* inner_var = helper.nested_statements.Length()
? helper.nested_statements[0]->As<ast::VariableDeclStatement>()->variable
- : helper.statements.size()
+ : helper.statements.Length()
? helper.statements[0]->As<ast::VariableDeclStatement>()->variable
: helper.parameters[0];
helper.Build();
@@ -1203,7 +1209,7 @@
const auto* value_decl = GlobalVar(value_sym, ty.i32(), ast::StorageClass::kPrivate);
const auto* type_decl = Alias(type_sym, ty.i32());
- const auto* func_decl = Func(func_sym, {}, ty.void_(), {});
+ const auto* func_decl = Func(func_sym, utils::Empty, ty.void_(), utils::Empty);
struct SymbolUse {
const ast::Node* decl = nullptr;
@@ -1211,10 +1217,10 @@
std::string where;
};
- std::vector<SymbolUse> symbol_uses;
+ utils::Vector<SymbolUse, 64> symbol_uses;
auto add_use = [&](const ast::Node* decl, auto* use, int line, const char* kind) {
- symbol_uses.emplace_back(
+ symbol_uses.Push(
SymbolUse{decl, use, std::string(__FILE__) + ":" + std::to_string(line) + ": " + kind});
return use;
};
@@ -1223,13 +1229,13 @@
#define F add_use(func_decl, Expr(func_sym), __LINE__, "F()")
Alias(Sym(), T);
- Structure(Sym(), {Member(Sym(), T)});
+ Structure(Sym(), utils::Vector{Member(Sym(), T)});
GlobalVar(Sym(), T, V);
GlobalConst(Sym(), T, V);
- Func(Sym(), //
- {Param(Sym(), T)}, //
- T, // Return type
- {
+ Func(Sym(), //
+ utils::Vector{Param(Sym(), T)}, //
+ T, // Return type
+ utils::Vector{
Decl(Var(Sym(), T, V)), //
Decl(Let(Sym(), T, V)), //
CallStmt(Call(F, V)), //
@@ -1278,7 +1284,7 @@
GlobalVar(Sym(), ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
ast::Access::kRead)); //
GlobalVar(Sym(), ty.sampler(ast::SamplerKind::kSampler));
- Func(Sym(), {}, ty.void_(), {});
+ Func(Sym(), utils::Empty, ty.void_(), utils::Empty);
#undef V
#undef T
#undef F
@@ -1303,10 +1309,10 @@
// DependencyAnalysis::SortGlobals(), found by clusterfuzz.
// See: crbug.com/chromium/1273451
TEST_F(ResolverDependencyGraphTraversalTest, chromium_1273451) {
- Structure("A", {Member("a", ty.i32())});
- Structure("B", {Member("b", ty.i32())});
- Func("f", {Param("a", ty.type_name("A"))}, ty.type_name("B"),
- {
+ Structure("A", utils::Vector{Member("a", ty.i32())});
+ Structure("B", utils::Vector{Member("b", ty.i32())});
+ Func("f", utils::Vector{Param("a", ty.type_name("A"))}, ty.type_name("B"),
+ utils::Vector{
Return(Construct(ty.type_name("B"))),
});
Build();
diff --git a/src/tint/resolver/entry_point_validation_test.cc b/src/tint/resolver/entry_point_validation_test.cc
index 8df0425..d997912 100644
--- a/src/tint/resolver/entry_point_validation_test.cc
+++ b/src/tint/resolver/entry_point_validation_test.cc
@@ -49,8 +49,16 @@
TEST_F(ResolverEntryPointValidationTest, ReturnTypeAttribute_Location) {
// @fragment
// fn main() -> @location(0) f32 { return 1.0; }
- Func(Source{{12, 34}}, "main", {}, ty.f32(), {Return(1_f)},
- {Stage(ast::PipelineStage::kFragment)}, {Location(0)});
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.f32(),
+ utils::Vector{
+ Return(1_f),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Location(0),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -58,8 +66,16 @@
TEST_F(ResolverEntryPointValidationTest, ReturnTypeAttribute_Builtin) {
// @vertex
// fn main() -> @builtin(position) vec4<f32> { return vec4<f32>(); }
- Func(Source{{12, 34}}, "main", {}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
- {Stage(ast::PipelineStage::kVertex)}, {Builtin(ast::BuiltinValue::kPosition)});
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.vec4<f32>(),
+ utils::Vector{
+ Return(Construct(ty.vec4<f32>())),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kVertex),
+ },
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -69,8 +85,13 @@
// fn main() -> f32 {
// return 1.0;
// }
- Func(Source{{12, 34}}, "main", {}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
- {Stage(ast::PipelineStage::kVertex)});
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.vec4<f32>(),
+ utils::Vector{
+ Return(Construct(ty.vec4<f32>())),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kVertex),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: missing entry point IO attribute on return type");
@@ -81,9 +102,17 @@
// fn main() -> @location(0) @builtin(position) vec4<f32> {
// return vec4<f32>();
// }
- Func(Source{{12, 34}}, "main", {}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
- {Stage(ast::PipelineStage::kVertex)},
- {Location(Source{{13, 43}}, 0), Builtin(Source{{14, 52}}, ast::BuiltinValue::kPosition)});
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.vec4<f32>(),
+ utils::Vector{
+ Return(Construct(ty.vec4<f32>())),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kVertex),
+ },
+ utils::Vector{
+ Location(Source{{13, 43}}, 0),
+ Builtin(Source{{14, 52}}, ast::BuiltinValue::kPosition),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
@@ -99,11 +128,18 @@
// fn main() -> Output {
// return Output();
// }
- auto* output =
- Structure("Output", {Member("a", ty.f32(), {Location(0)}),
- Member("b", ty.f32(), {Builtin(ast::BuiltinValue::kFragDepth)})});
- Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
- {Stage(ast::PipelineStage::kFragment)});
+ auto* output = Structure(
+ "Output", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{Location(0)}),
+ Member("b", ty.f32(), utils::Vector{Builtin(ast::BuiltinValue::kFragDepth)}),
+ });
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+ utils::Vector{
+ Return(Construct(ty.Of(output))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -116,12 +152,20 @@
// fn main() -> Output {
// return Output();
// }
- auto* output =
- Structure("Output", {Member("a", ty.f32(),
- {Location(Source{{13, 43}}, 0),
- Builtin(Source{{14, 52}}, ast::BuiltinValue::kFragDepth)})});
- Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
- {Stage(ast::PipelineStage::kFragment)});
+ auto* output = Structure(
+ "Output",
+ utils::Vector{
+ Member("a", ty.f32(),
+ utils::Vector{Location(Source{{13, 43}}, 0),
+ Builtin(Source{{14, 52}}, ast::BuiltinValue::kFragDepth)}),
+ });
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+ utils::Vector{
+ Return(Construct(ty.Of(output))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
@@ -138,10 +182,18 @@
// fn main() -> Output {
// return Output();
// }
- auto* output = Structure("Output", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)}),
- Member(Source{{14, 52}}, "b", ty.f32(), {})});
- Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
- {Stage(ast::PipelineStage::kFragment)});
+ auto* output =
+ Structure("Output", utils::Vector{
+ Member(Source{{13, 43}}, "a", ty.f32(), utils::Vector{Location(0)}),
+ Member(Source{{14, 52}}, "b", ty.f32(), {}),
+ });
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+ utils::Vector{
+ Return(Construct(ty.Of(output))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -158,11 +210,18 @@
// fn main() -> Output {
// return Output();
// }
- auto* output =
- Structure("Output", {Member("a", ty.f32(), {Builtin(ast::BuiltinValue::kFragDepth)}),
- Member("b", ty.f32(), {Builtin(ast::BuiltinValue::kFragDepth)})});
- Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
- {Stage(ast::PipelineStage::kFragment)});
+ auto* output = Structure(
+ "Output", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{Builtin(ast::BuiltinValue::kFragDepth)}),
+ Member("b", ty.f32(), utils::Vector{Builtin(ast::BuiltinValue::kFragDepth)}),
+ });
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+ utils::Vector{
+ Return(Construct(ty.Of(output))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -174,8 +233,18 @@
TEST_F(ResolverEntryPointValidationTest, ParameterAttribute_Location) {
// @fragment
// fn main(@location(0) param : f32) {}
- auto* param = Param("param", ty.f32(), {Location(0)});
- Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ auto* param = Param("param", ty.f32(),
+ utils::Vector{
+ Location(0),
+ });
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -184,7 +253,14 @@
// @fragment
// fn main(param : f32) {}
auto* param = Param(Source{{13, 43}}, "param", ty.vec4<f32>());
- Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "13:43 error: missing entry point IO attribute on parameter");
@@ -194,9 +270,18 @@
// @fragment
// fn main(@location(0) @builtin(sample_index) param : u32) {}
auto* param = Param("param", ty.u32(),
- {Location(Source{{13, 43}}, 0),
- Builtin(Source{{14, 52}}, ast::BuiltinValue::kSampleIndex)});
- Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ utils::Vector{
+ Location(Source{{13, 43}}, 0),
+ Builtin(Source{{14, 52}}, ast::BuiltinValue::kSampleIndex),
+ });
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
@@ -210,11 +295,20 @@
// };
// @fragment
// fn main(param : Input) {}
- auto* input =
- Structure("Input", {Member("a", ty.f32(), {Location(0)}),
- Member("b", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)})});
+ auto* input = Structure(
+ "Input", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{Location(0)}),
+ Member("b", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kSampleIndex)}),
+ });
auto* param = Param("param", ty.Of(input));
- Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -225,12 +319,22 @@
// };
// @fragment
// fn main(param : Input) {}
- auto* input =
- Structure("Input", {Member("a", ty.u32(),
- {Location(Source{{13, 43}}, 0),
- Builtin(Source{{14, 52}}, ast::BuiltinValue::kSampleIndex)})});
+ auto* input = Structure(
+ "Input",
+ utils::Vector{
+ Member("a", ty.u32(),
+ utils::Vector{Location(Source{{13, 43}}, 0),
+ Builtin(Source{{14, 52}}, ast::BuiltinValue::kSampleIndex)}),
+ });
auto* param = Param("param", ty.Of(input));
- Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
@@ -245,10 +349,20 @@
// };
// @fragment
// fn main(param : Input) {}
- auto* input = Structure("Input", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)}),
- Member(Source{{14, 52}}, "b", ty.f32(), {})});
+ auto* input =
+ Structure("Input", utils::Vector{
+ Member(Source{{13, 43}}, "a", ty.f32(), utils::Vector{Location(0)}),
+ Member(Source{{14, 52}}, "b", ty.f32(), {}),
+ });
auto* param = Param("param", ty.Of(input));
- Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(14:52 error: missing entry point IO attribute
@@ -259,10 +373,23 @@
// @fragment
// fn main(@builtin(sample_index) param_a : u32,
// @builtin(sample_index) param_b : u32) {}
- auto* param_a = Param("param_a", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)});
- auto* param_b = Param("param_b", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)});
- Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {},
- {Stage(ast::PipelineStage::kFragment)});
+ auto* param_a = Param("param_a", ty.u32(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kSampleIndex),
+ });
+ auto* param_b = Param("param_b", ty.u32(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kSampleIndex),
+ });
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param_a,
+ param_b,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -279,14 +406,27 @@
// };
// @fragment
// fn main(param_a : InputA, param_b : InputB) {}
- auto* input_a =
- Structure("InputA", {Member("a", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)})});
- auto* input_b =
- Structure("InputB", {Member("a", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)})});
+ auto* input_a = Structure(
+ "InputA",
+ utils::Vector{
+ Member("a", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kSampleIndex)}),
+ });
+ auto* input_b = Structure(
+ "InputB",
+ utils::Vector{
+ Member("a", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kSampleIndex)}),
+ });
auto* param_a = Param("param_a", ty.Of(input_a));
auto* param_b = Param("param_b", ty.Of(input_b));
- Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {},
- {Stage(ast::PipelineStage::kFragment)});
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param_a,
+ param_b,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -298,7 +438,10 @@
TEST_F(ResolverEntryPointValidationTest, VertexShaderMustReturnPosition) {
// @vertex
// fn main() {}
- Func(Source{{12, 34}}, "main", {}, ty.void_(), {}, {Stage(ast::PipelineStage::kVertex)});
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kVertex),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -306,6 +449,135 @@
"in its return type");
}
+TEST_F(ResolverEntryPointValidationTest, PushConstantAllowedWithEnable) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> a : u32;
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar("a", ty.u32(), ast::StorageClass::kPushConstant);
+
+ EXPECT_TRUE(r()->Resolve());
+}
+
+TEST_F(ResolverEntryPointValidationTest, PushConstantDisallowedWithoutEnable) {
+ // var<push_constant> a : u32;
+ GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::StorageClass::kPushConstant);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "1:2 error: use of variable storage class 'push_constant' requires enabling "
+ "extension 'chromium_experimental_push_constant'");
+}
+
+TEST_F(ResolverEntryPointValidationTest, PushConstantAllowedWithIgnoreStorageClassAttribute) {
+ // var<push_constant> a : u32; // With ast::DisabledValidation::kIgnoreStorageClass
+ GlobalVar("a", ty.u32(), ast::StorageClass::kPushConstant,
+ utils::Vector{Disable(ast::DisabledValidation::kIgnoreStorageClass)});
+
+ EXPECT_TRUE(r()->Resolve());
+}
+
+TEST_F(ResolverEntryPointValidationTest, PushConstantOneVariableUsedInEntryPoint) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> a : u32;
+ // @compute @workgroup_size(1) fn main() {
+ // _ = a;
+ // }
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar("a", ty.u32(), ast::StorageClass::kPushConstant);
+
+ Func("main", {}, ty.void_(), utils::Vector{Assign(Phony(), "a")},
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupAttribute>(Expr(1_i))});
+
+ EXPECT_TRUE(r()->Resolve());
+}
+
+TEST_F(ResolverEntryPointValidationTest, PushConstantTwoVariablesUsedInEntryPoint) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> a : u32;
+ // var<push_constant> b : u32;
+ // @compute @workgroup_size(1) fn main() {
+ // _ = a;
+ // _ = b;
+ // }
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::StorageClass::kPushConstant);
+ GlobalVar(Source{{3, 4}}, "b", ty.u32(), ast::StorageClass::kPushConstant);
+
+ Func(Source{{5, 6}}, "main", {}, ty.void_(),
+ utils::Vector{Assign(Phony(), "a"), Assign(Phony(), "b")},
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupAttribute>(Expr(1_i))});
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(5:6 error: entry point 'main' uses two different 'push_constant' variables.
+3:4 note: first 'push_constant' variable declaration is here
+1:2 note: second 'push_constant' variable declaration is here)");
+}
+
+TEST_F(ResolverEntryPointValidationTest,
+ PushConstantTwoVariablesUsedInEntryPointWithFunctionGraph) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> a : u32;
+ // var<push_constant> b : u32;
+ // fn uses_a() {
+ // _ = a;
+ // }
+ // fn uses_b() {
+ // _ = b;
+ // }
+ // @compute @workgroup_size(1) fn main() {
+ // uses_a();
+ // uses_b();
+ // }
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::StorageClass::kPushConstant);
+ GlobalVar(Source{{3, 4}}, "b", ty.u32(), ast::StorageClass::kPushConstant);
+
+ Func(Source{{5, 6}}, "uses_a", {}, ty.void_(), utils::Vector{Assign(Phony(), "a")});
+ Func(Source{{7, 8}}, "uses_b", {}, ty.void_(), utils::Vector{Assign(Phony(), "b")});
+
+ Func(Source{{9, 10}}, "main", {}, ty.void_(),
+ utils::Vector{CallStmt(Call("uses_a")), CallStmt(Call("uses_b"))},
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupAttribute>(Expr(1_i))});
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(9:10 error: entry point 'main' uses two different 'push_constant' variables.
+3:4 note: first 'push_constant' variable declaration is here
+7:8 note: called by function 'uses_b'
+9:10 note: called by entry point 'main'
+1:2 note: second 'push_constant' variable declaration is here
+5:6 note: called by function 'uses_a'
+9:10 note: called by entry point 'main')");
+}
+
+TEST_F(ResolverEntryPointValidationTest, PushConstantTwoVariablesUsedInDifferentEntryPoint) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> a : u32;
+ // var<push_constant> b : u32;
+ // @compute @workgroup_size(1) fn uses_a() {
+ // _ = a;
+ // }
+ // @compute @workgroup_size(1) fn uses_b() {
+ // _ = a;
+ // }
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar("a", ty.u32(), ast::StorageClass::kPushConstant);
+ GlobalVar("b", ty.u32(), ast::StorageClass::kPushConstant);
+
+ Func("uses_a", {}, ty.void_(), utils::Vector{Assign(Phony(), "a")},
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupAttribute>(Expr(1_i))});
+ Func("uses_b", {}, ty.void_(), utils::Vector{Assign(Phony(), "b")},
+ utils::Vector{Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupAttribute>(Expr(1_i))});
+
+ EXPECT_TRUE(r()->Resolve());
+}
+
namespace TypeValidationTests {
struct Params {
builder::ast_type_func_ptr create_ast_type;
@@ -354,8 +626,19 @@
Enable(ast::Extension::kF16);
- auto* a = Param("a", params.create_ast_type(*this), {Location(0), Flat()});
- Func(Source{{12, 34}}, "main", {a}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ auto* a = Param("a", params.create_ast_type(*this),
+ utils::Vector{
+ Location(0),
+ Flat(),
+ });
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ a,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -374,10 +657,19 @@
Enable(ast::Extension::kF16);
- auto* input =
- Structure("Input", {Member("a", params.create_ast_type(*this), {Location(0), Flat()})});
+ auto* input = Structure(
+ "Input", utils::Vector{
+ Member("a", params.create_ast_type(*this), utils::Vector{Location(0), Flat()}),
+ });
auto* a = Param("a", ty.Of(input), {});
- Func(Source{{12, 34}}, "main", {a}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ a,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -395,9 +687,16 @@
Enable(ast::Extension::kF16);
- Func(Source{{12, 34}}, "main", {}, params.create_ast_type(*this),
- {Return(Construct(params.create_ast_type(*this)))}, {Stage(ast::PipelineStage::kFragment)},
- {Location(0)});
+ Func(Source{{12, 34}}, "main", utils::Empty, params.create_ast_type(*this),
+ utils::Vector{
+ Return(Construct(params.create_ast_type(*this))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Location(0),
+ });
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -418,9 +717,17 @@
Enable(ast::Extension::kF16);
- auto* output = Structure("Output", {Member("a", params.create_ast_type(*this), {Location(0)})});
- Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
- {Stage(ast::PipelineStage::kFragment)});
+ auto* output = Structure(
+ "Output", utils::Vector{
+ Member("a", params.create_ast_type(*this), utils::Vector{Location(0)}),
+ });
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+ utils::Vector{
+ Return(Construct(ty.Of(output))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -442,8 +749,19 @@
// @fragment
// fn frag_main(@location(0) @interpolate(flat) a: i32) {}
- auto* p = Param(Source{{12, 34}}, "a", ty.i32(), {Location(0), Flat()});
- Func("frag_main", {p}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ auto* p = Param(Source{{12, 34}}, "a", ty.i32(),
+ utils::Vector{
+ Location(0),
+ Flat(),
+ });
+ Func("frag_main",
+ utils::Vector{
+ p,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -452,8 +770,18 @@
// @fragment
// fn frag_main(@location(0) a: bool) {}
- auto* p = Param(Source{{12, 34}}, "a", ty.bool_(), {Location(Source{{34, 56}}, 0)});
- Func("frag_main", {p}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ auto* p = Param(Source{{12, 34}}, "a", ty.bool_(),
+ utils::Vector{
+ Location(Source{{34, 56}}, 0),
+ });
+ Func("frag_main",
+ utils::Vector{
+ p,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -467,9 +795,16 @@
// @fragment
// fn frag_main()->@location(0) array<f32, 2> { return array<f32, 2>(); }
- Func(Source{{12, 34}}, "frag_main", {}, ty.array<f32, 2>(),
- {Return(Construct(ty.array<f32, 2>()))}, {Stage(ast::PipelineStage::kFragment)},
- {Location(Source{{34, 56}}, 0)});
+ Func(Source{{12, 34}}, "frag_main", utils::Empty, ty.array<f32, 2>(),
+ utils::Vector{
+ Return(Construct(ty.array<f32, 2>())),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Location(Source{{34, 56}}, 0),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -485,9 +820,21 @@
// };
// @fragment
// fn main(@location(0) param : Input) {}
- auto* input = Structure("Input", {Member("a", ty.f32())});
- auto* param = Param(Source{{12, 34}}, "param", ty.Of(input), {Location(Source{{13, 43}}, 0)});
- Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ auto* input = Structure("Input", utils::Vector{
+ Member("a", ty.f32()),
+ });
+ auto* param = Param(Source{{12, 34}}, "param", ty.Of(input),
+ utils::Vector{
+ Location(Source{{13, 43}}, 0),
+ });
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -506,10 +853,22 @@
// };
// @fragment
// fn main(param : Input) {}
- auto* inner = Structure("Inner", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)})});
- auto* input = Structure("Input", {Member(Source{{14, 52}}, "a", ty.Of(inner))});
+ auto* inner =
+ Structure("Inner", utils::Vector{
+ Member(Source{{13, 43}}, "a", ty.f32(), utils::Vector{Location(0)}),
+ });
+ auto* input = Structure("Input", utils::Vector{
+ Member(Source{{14, 52}}, "a", ty.Of(inner)),
+ });
auto* param = Param("param", ty.Of(input));
- Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -523,10 +882,19 @@
// };
// @fragment
// fn main(param : Input) {}
- auto* input =
- Structure("Input", {Member(Source{{13, 43}}, "a", ty.array<f32>(), {Location(0)})});
+ auto* input = Structure(
+ "Input", utils::Vector{
+ Member(Source{{13, 43}}, "a", ty.array<f32>(), utils::Vector{Location(0)}),
+ });
auto* param = Param("param", ty.Of(input));
- Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -542,11 +910,20 @@
// fn frag_main( a: S) {}
auto* m = Member(Source{{34, 56}}, "m", ty.array<i32>(),
- ast::AttributeList{Location(Source{{12, 34}}, 0u)});
- auto* s = Structure("S", {m});
+ utils::Vector{
+ Location(Source{{12, 34}}, 0u),
+ });
+ auto* s = Structure("S", utils::Vector{m});
auto* p = Param("a", ty.Of(s));
- Func("frag_main", {p}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ Func("frag_main",
+ utils::Vector{
+ p,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -561,11 +938,19 @@
// @fragment
// fn frag_main() -> S {}
auto* m = Member(Source{{34, 56}}, "m", ty.atomic<i32>(),
- ast::AttributeList{Location(Source{{12, 34}}, 0u)});
- auto* s = Structure("S", {m});
+ utils::Vector{
+ Location(Source{{12, 34}}, 0u),
+ });
+ auto* s = Structure("S", utils::Vector{m});
- Func("frag_main", {}, ty.Of(s), {Return(Construct(ty.Of(s)))},
- {Stage(ast::PipelineStage::kFragment)}, {});
+ Func("frag_main", utils::Empty, ty.Of(s),
+ utils::Vector{
+ Return(Construct(ty.Of(s))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ {});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -579,8 +964,10 @@
// struct S { @location(0) m: mat3x2<f32>; };
auto* m = Member(Source{{34, 56}}, "m", ty.mat3x2<f32>(),
- ast::AttributeList{Location(Source{{12, 34}}, 0u)});
- Structure("S", {m});
+ utils::Vector{
+ Location(Source{{12, 34}}, 0u),
+ });
+ Structure("S", utils::Vector{m});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -599,11 +986,18 @@
// fn main() -> Output {
// return Output();
// }
- auto* output =
- Structure("Output", {Member("a", ty.f32(), {Location(0)}),
- Member("b", ty.f32(), {Builtin(ast::BuiltinValue::kFragDepth)})});
- Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
- {Stage(ast::PipelineStage::kFragment)});
+ auto* output = Structure(
+ "Output", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{Location(0)}),
+ Member("b", ty.f32(), utils::Vector{Builtin(ast::BuiltinValue::kFragDepth)}),
+ });
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+ utils::Vector{
+ Return(Construct(ty.Of(output))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -616,9 +1010,19 @@
// fn main() -> @location(0) Output {
// return Output();
// }
- auto* output = Structure("Output", {Member("a", ty.f32())});
- Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
- {Stage(ast::PipelineStage::kVertex)}, {Location(Source{{13, 43}}, 0)});
+ auto* output = Structure("Output", utils::Vector{
+ Member("a", ty.f32()),
+ });
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+ utils::Vector{
+ Return(Construct(ty.Of(output))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kVertex),
+ },
+ utils::Vector{
+ Location(Source{{13, 43}}, 0),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -637,10 +1041,20 @@
// };
// @fragment
// fn main() -> Output { return Output(); }
- auto* inner = Structure("Inner", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)})});
- auto* output = Structure("Output", {Member(Source{{14, 52}}, "a", ty.Of(inner))});
- Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
- {Stage(ast::PipelineStage::kFragment)});
+ auto* inner =
+ Structure("Inner", utils::Vector{
+ Member(Source{{13, 43}}, "a", ty.f32(), utils::Vector{Location(0)}),
+ });
+ auto* output = Structure("Output", utils::Vector{
+ Member(Source{{14, 52}}, "a", ty.Of(inner)),
+ });
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+ utils::Vector{
+ Return(Construct(ty.Of(output))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -656,10 +1070,17 @@
// fn main() -> Output {
// return Output();
// }
- auto* output = Structure("Output", {Member(Source{{13, 43}}, "a", ty.array<f32>(),
- {Location(Source{{12, 34}}, 0)})});
- Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
- {Stage(ast::PipelineStage::kFragment)});
+ auto* output = Structure("Output", utils::Vector{
+ Member(Source{{13, 43}}, "a", ty.array<f32>(),
+ utils::Vector{Location(Source{{12, 34}}, 0)}),
+ });
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+ utils::Vector{
+ Return(Construct(ty.Of(output))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -670,32 +1091,51 @@
}
TEST_F(LocationAttributeTests, ComputeShaderLocation_Input) {
- Func("main", {}, ty.i32(), {Return(Expr(1_i))},
- {Stage(ast::PipelineStage::kCompute),
- create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))},
- ast::AttributeList{Location(Source{{12, 34}}, 1)});
+ Func("main", utils::Empty, ty.i32(),
+ utils::Vector{
+ Return(Expr(1_i)),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+ },
+ utils::Vector{
+ Location(Source{{12, 34}}, 1),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: attribute is not valid for compute shader output");
}
TEST_F(LocationAttributeTests, ComputeShaderLocation_Output) {
- auto* input = Param("input", ty.i32(), ast::AttributeList{Location(Source{{12, 34}}, 0u)});
- Func("main", {input}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute),
- create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
+ auto* input = Param("input", ty.i32(),
+ utils::Vector{
+ Location(Source{{12, 34}}, 0u),
+ });
+ Func("main", utils::Vector{input}, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: attribute is not valid for compute shader inputs");
}
TEST_F(LocationAttributeTests, ComputeShaderLocationStructMember_Output) {
- auto* m = Member("m", ty.i32(), ast::AttributeList{Location(Source{{12, 34}}, 0u)});
- auto* s = Structure("S", {m});
- Func(Source{{56, 78}}, "main", {}, ty.Of(s),
- ast::StatementList{Return(Expr(Construct(ty.Of(s))))},
- {Stage(ast::PipelineStage::kCompute),
- create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
+ auto* m = Member("m", ty.i32(),
+ utils::Vector{
+ Location(Source{{12, 34}}, 0u),
+ });
+ auto* s = Structure("S", utils::Vector{m});
+ Func(Source{{56, 78}}, "main", utils::Empty, ty.Of(s),
+ utils::Vector{
+ Return(Expr(Construct(ty.Of(s)))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -704,12 +1144,17 @@
}
TEST_F(LocationAttributeTests, ComputeShaderLocationStructMember_Input) {
- auto* m = Member("m", ty.i32(), ast::AttributeList{Location(Source{{12, 34}}, 0u)});
- auto* s = Structure("S", {m});
+ auto* m = Member("m", ty.i32(),
+ utils::Vector{
+ Location(Source{{12, 34}}, 0u),
+ });
+ auto* s = Structure("S", utils::Vector{m});
auto* input = Param("input", ty.Of(s));
- Func(Source{{56, 78}}, "main", {input}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute),
- create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
+ Func(Source{{56, 78}}, "main", utils::Vector{input}, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -721,10 +1166,23 @@
// @fragment
// fn main(@location(1) param_a : f32,
// @location(1) param_b : f32) {}
- auto* param_a = Param("param_a", ty.f32(), {Location(1)});
- auto* param_b = Param("param_b", ty.f32(), {Location(Source{{12, 34}}, 1)});
- Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {},
- {Stage(ast::PipelineStage::kFragment)});
+ auto* param_a = Param("param_a", ty.f32(),
+ utils::Vector{
+ Location(1),
+ });
+ auto* param_b = Param("param_b", ty.f32(),
+ utils::Vector{
+ Location(Source{{12, 34}}, 1),
+ });
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param_a,
+ param_b,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: location(1) attribute appears multiple times");
@@ -739,12 +1197,24 @@
// };
// @fragment
// fn main(param_a : InputA, param_b : InputB) {}
- auto* input_a = Structure("InputA", {Member("a", ty.f32(), {Location(1)})});
- auto* input_b = Structure("InputB", {Member("a", ty.f32(), {Location(Source{{34, 56}}, 1)})});
+ auto* input_a = Structure("InputA", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{Location(1)}),
+ });
+ auto* input_b =
+ Structure("InputB", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{Location(Source{{34, 56}}, 1)}),
+ });
auto* param_a = Param("param_a", ty.Of(input_a));
auto* param_b = Param("param_b", ty.Of(input_b));
- Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {},
- {Stage(ast::PipelineStage::kFragment)});
+ Func(Source{{12, 34}}, "main",
+ utils::Vector{
+ param_a,
+ param_b,
+ },
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
diff --git a/src/tint/resolver/evaluation_stage_test.cc b/src/tint/resolver/evaluation_stage_test.cc
index 236e4b3..4b603bb 100644
--- a/src/tint/resolver/evaluation_stage_test.cc
+++ b/src/tint/resolver/evaluation_stage_test.cc
@@ -269,7 +269,7 @@
// struct S { m : i32 };
// const str = S();
// str.m
- Structure("S", {Member("m", ty.i32())});
+ Structure("S", utils::Vector{Member("m", ty.i32())});
auto* str = Const("str", nullptr, Construct(ty.type_name("S")));
auto* expr = MemberAccessor(str, "m");
WrapInFunction(str, expr);
@@ -283,7 +283,7 @@
// struct S { m : i32 };
// var str = S();
// str.m
- Structure("S", {Member("m", ty.i32())});
+ Structure("S", utils::Vector{Member("m", ty.i32())});
auto* str = Var("str", nullptr, Construct(ty.type_name("S")));
auto* expr = MemberAccessor(str, "m");
WrapInFunction(str, expr);
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index c1ea33c..372d91a 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -30,8 +30,8 @@
TEST_F(ResolverFunctionValidationTest, DuplicateParameterName) {
// fn func_a(common_name : f32) { }
// fn func_b(common_name : f32) { }
- Func("func_a", {Param("common_name", ty.f32())}, ty.void_(), {});
- Func("func_b", {Param("common_name", ty.f32())}, ty.void_(), {});
+ Func("func_a", utils::Vector{Param("common_name", ty.f32())}, ty.void_(), utils::Empty);
+ Func("func_b", utils::Vector{Param("common_name", ty.f32())}, ty.void_(), utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -40,7 +40,7 @@
// var<private> common_name : f32;
// fn func(common_name : f32) { }
GlobalVar("common_name", ty.f32(), ast::StorageClass::kPrivate);
- Func("func", {Param("common_name", ty.f32())}, ty.void_(), {});
+ Func("func", utils::Vector{Param("common_name", ty.f32())}, ty.void_(), utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -49,8 +49,10 @@
// fn func(common_name : f32) {
// let common_name = 1i;
// }
- Func("func", {Param(Source{{12, 34}}, "common_name", ty.f32())}, ty.void_(),
- {Decl(Let(Source{{56, 78}}, "common_name", nullptr, Expr(1_i)))});
+ Func("func", utils::Vector{Param(Source{{12, 34}}, "common_name", ty.f32())}, ty.void_(),
+ utils::Vector{
+ Decl(Let(Source{{56, 78}}, "common_name", nullptr, Expr(1_i))),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(56:78 error: redeclaration of 'common_name'
@@ -59,12 +61,14 @@
TEST_F(ResolverFunctionValidationTest, NestedLocalMayShadowParameter) {
// fn func(common_name : f32) {
- // {
+ // utils::Vector {
// let common_name = 1i;
// }
// }
- Func("func", {Param(Source{{12, 34}}, "common_name", ty.f32())}, ty.void_(),
- {Block(Decl(Let(Source{{56, 78}}, "common_name", nullptr, Expr(1_i))))});
+ Func("func", utils::Vector{Param(Source{{12, 34}}, "common_name", ty.f32())}, ty.void_(),
+ utils::Vector{
+ Block(Decl(Let(Source{{56, 78}}, "common_name", nullptr, Expr(1_i)))),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -73,8 +77,8 @@
// fn func { var a:i32 = 2i; }
auto* var = Var("a", ty.i32(), Expr(2_i));
- Func(Source{{12, 34}}, "func", {}, ty.void_(),
- {
+ Func(Source{{12, 34}}, "func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
});
@@ -88,8 +92,8 @@
// }
auto* var = Var("func", ty.i32(), Expr(0_i));
- Func("func", {}, ty.i32(),
- {
+ Func("func", utils::Empty, ty.i32(),
+ utils::Vector{
Decl(var),
Return(Source{{12, 34}}, Expr("func")),
});
@@ -102,13 +106,13 @@
// fn b() -> i32 { return 2; }
auto* var = Var("b", ty.i32(), Expr(0_i));
- Func("a", {}, ty.void_(),
- {
+ Func("a", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
});
- Func(Source{{12, 34}}, "b", {}, ty.i32(),
- {
+ Func(Source{{12, 34}}, "b", utils::Empty, ty.i32(),
+ utils::Vector{
Return(2_i),
});
@@ -126,7 +130,7 @@
auto* ret = Return();
auto* assign_a = Assign(Source{{12, 34}}, "a", 2_i);
- Func("func", {}, ty.void_(), {decl_a, ret, assign_a});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{decl_a, ret, assign_a});
ASSERT_TRUE(r()->Resolve());
@@ -139,7 +143,7 @@
TEST_F(ResolverFunctionValidationTest, UnreachableCode_return_InBlocks) {
// fn func() -> {
// var a : i32;
- // {{{return;}}}
+ // utils::Vector {{{return;}}}
// a = 2i;
//}
@@ -147,7 +151,8 @@
auto* ret = Return();
auto* assign_a = Assign(Source{{12, 34}}, "a", 2_i);
- Func("func", {}, ty.void_(), {decl_a, Block(Block(Block(ret))), assign_a});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{decl_a, Block(Block(Block(ret))), assign_a});
ASSERT_TRUE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 warning: code is unreachable");
@@ -167,7 +172,7 @@
auto* discard = Discard();
auto* assign_a = Assign(Source{{12, 34}}, "a", 2_i);
- Func("func", {}, ty.void_(), {decl_a, discard, assign_a});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{decl_a, discard, assign_a});
ASSERT_TRUE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 warning: code is unreachable");
@@ -179,7 +184,7 @@
TEST_F(ResolverFunctionValidationTest, UnreachableCode_discard_InBlocks) {
// fn func() -> {
// var a : i32;
- // {{{discard;}}}
+ // utils::Vector {{{discard;}}}
// a = 2i;
//}
@@ -187,7 +192,8 @@
auto* discard = Discard();
auto* assign_a = Assign(Source{{12, 34}}, "a", 2_i);
- Func("func", {}, ty.void_(), {decl_a, Block(Block(Block(discard))), assign_a});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{decl_a, Block(Block(Block(discard))), assign_a});
ASSERT_TRUE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 warning: code is unreachable");
@@ -201,8 +207,8 @@
auto* var = Var("a", ty.i32(), Expr(2_i));
- Func(Source{{12, 34}}, "func", {}, ty.i32(),
- {
+ Func(Source{{12, 34}}, "func", utils::Empty, ty.i32(),
+ utils::Vector{
Decl(var),
});
@@ -213,7 +219,7 @@
TEST_F(ResolverFunctionValidationTest, VoidFunctionEndWithoutReturnStatementEmptyBody_Pass) {
// fn func {}
- Func(Source{{12, 34}}, "func", {}, ty.void_(), {});
+ Func(Source{{12, 34}}, "func", utils::Empty, ty.void_(), utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -221,7 +227,7 @@
TEST_F(ResolverFunctionValidationTest, FunctionEndWithoutReturnStatementEmptyBody_Fail) {
// fn func() -> int {}
- Func(Source{{12, 34}}, "func", {}, ty.i32(), {});
+ Func(Source{{12, 34}}, "func", utils::Empty, ty.i32(), utils::Empty);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: missing return at end of function");
@@ -230,14 +236,20 @@
TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementType_Pass) {
// fn func { return; }
- Func("func", {}, ty.void_(), {Return()});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Return(),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverFunctionValidationTest, VoidFunctionReturnsAInt) {
// fn func { return 2; }
- Func("func", {}, ty.void_(), {Return(Source{{12, 34}}, Expr(2_a))});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Return(Source{{12, 34}}, Expr(2_a)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -247,7 +259,10 @@
TEST_F(ResolverFunctionValidationTest, VoidFunctionReturnsAFloat) {
// fn func { return 2.0; }
- Func("func", {}, ty.void_(), {Return(Source{{12, 34}}, Expr(2.0_a))});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Return(Source{{12, 34}}, Expr(2.0_a)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -257,7 +272,10 @@
TEST_F(ResolverFunctionValidationTest, VoidFunctionReturnsI32) {
// fn func { return 2i; }
- Func("func", {}, ty.void_(), {Return(Source{{12, 34}}, Expr(2_i))});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Return(Source{{12, 34}}, Expr(2_i)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -268,9 +286,12 @@
TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementType_void_fail) {
// fn v { return; }
// fn func { return v(); }
- Func("v", {}, ty.void_(), {Return()});
- Func("func", {}, ty.void_(),
- {
+ Func("v", utils::Empty, ty.void_(),
+ utils::Vector{
+ Return(),
+ });
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
Return(Call(Source{{12, 34}}, "v")),
});
@@ -280,8 +301,8 @@
TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementTypeMissing_fail) {
// fn func() -> f32 { return; }
- Func("func", {}, ty.f32(),
- {
+ Func("func", utils::Empty, ty.f32(),
+ utils::Vector{
Return(Source{{12, 34}}, nullptr),
});
@@ -293,8 +314,8 @@
TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementTypeF32_pass) {
// fn func() -> f32 { return 2.0; }
- Func("func", {}, ty.f32(),
- {
+ Func("func", utils::Empty, ty.f32(),
+ utils::Vector{
Return(Source{{12, 34}}, Expr(2_f)),
});
@@ -303,8 +324,8 @@
TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementTypeF32_fail) {
// fn func() -> f32 { return 2i; }
- Func("func", {}, ty.f32(),
- {
+ Func("func", utils::Empty, ty.f32(),
+ utils::Vector{
Return(Source{{12, 34}}, Expr(2_i)),
});
@@ -318,8 +339,8 @@
// type myf32 = f32;
// fn func() -> myf32 { return 2.0; }
auto* myf32 = Alias("myf32", ty.f32());
- Func("func", {}, ty.Of(myf32),
- {
+ Func("func", utils::Empty, ty.Of(myf32),
+ utils::Vector{
Return(Source{{12, 34}}, Expr(2_f)),
});
@@ -330,8 +351,8 @@
// type myf32 = f32;
// fn func() -> myf32 { return 2u; }
auto* myf32 = Alias("myf32", ty.f32());
- Func("func", {}, ty.Of(myf32),
- {
+ Func("func", utils::Empty, ty.Of(myf32),
+ utils::Vector{
Return(Source{{12, 34}}, Expr(2_u)),
});
@@ -344,11 +365,14 @@
TEST_F(ResolverFunctionValidationTest, CannotCallEntryPoint) {
// @compute @workgroup_size(1) fn entrypoint() {}
// fn func() { return entrypoint(); }
- Func("entrypoint", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ Func("entrypoint", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(1_i),
+ });
- Func("func", {}, ty.void_(),
- {
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call(Source{{12, 34}}, "entrypoint")),
});
@@ -360,7 +384,10 @@
TEST_F(ResolverFunctionValidationTest, CannotCallFunctionAtModuleScope) {
// fn F() -> i32 { return 1; }
// var x = F();
- Func("F", {}, ty.i32(), {Return(1_i)});
+ Func("F", utils::Empty, ty.i32(),
+ utils::Vector{
+ Return(1_i),
+ });
GlobalVar("x", nullptr, Call(Source{{12, 34}}, "F"), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
@@ -371,11 +398,11 @@
// @fragment
// @vertex
// fn main() { return; }
- Func(Source{{12, 34}}, "main", {}, ty.void_(),
- {
+ Func(Source{{12, 34}}, "main", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
},
- ast::AttributeList{
+ utils::Vector{
Stage(Source{{12, 34}}, ast::PipelineStage::kVertex),
Stage(Source{{56, 78}}, ast::PipelineStage::kFragment),
});
@@ -387,8 +414,8 @@
}
TEST_F(ResolverFunctionValidationTest, NoPipelineEntryPoints) {
- Func("vtx_func", {}, ty.void_(),
- {
+ Func("vtx_func", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -403,8 +430,8 @@
auto* bar = Param("bar", ty.f32());
auto* baz = Var("baz", ty.f32(), Expr("bar"));
- Func("foo", {bar}, ty.void_(),
- {
+ Func("foo", utils::Vector{bar}, ty.void_(),
+ utils::Vector{
Decl(baz),
});
@@ -419,8 +446,8 @@
auto* bar = Param("bar", ty.f32());
auto* baz = Let("baz", ty.f32(), Expr("bar"));
- Func("foo", {bar}, ty.void_(),
- {
+ Func("foo", utils::Vector{bar}, ty.void_(),
+ utils::Vector{
Decl(baz),
});
@@ -428,8 +455,11 @@
}
TEST_F(ResolverFunctionValidationTest, FunctionParamsConst) {
- Func("foo", {Param(Sym("arg"), ty.i32())}, ty.void_(),
- {Assign(Expr(Source{{12, 34}}, "arg"), Expr(1_i)), Return()});
+ Func("foo", utils::Vector{Param(Sym("arg"), ty.i32())}, ty.void_(),
+ utils::Vector{
+ Assign(Expr(Source{{12, 34}}, "arg"), Expr(1_i)),
+ Return(),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -443,8 +473,11 @@
// fn main() {}
auto* x = GlobalConst("x", ty.u32(), Expr(4_u));
auto* y = GlobalConst("y", ty.u32(), Expr(8_u));
- auto* func = Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize("x", "y", 16_u)});
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize("x", "y", 16_u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -464,8 +497,11 @@
// @compute @workgroup_size(1i, 2i, 3i)
// fn main() {}
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Source{{12, 34}}, 1_i, 2_i, 3_i)});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Source{{12, 34}}, 1_i, 2_i, 3_i),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -474,8 +510,11 @@
// @compute @workgroup_size(1u, 2u, 3u)
// fn main() {}
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Source{{12, 34}}, 1_u, 2_u, 3_u)});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Source{{12, 34}}, 1_u, 2_u, 3_u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -484,8 +523,11 @@
// @compute @workgroup_size(1, 2i, 3)
// fn main() {}
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Source{{12, 34}}, 1_a, 2_i, 3_a)});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Source{{12, 34}}, 1_a, 2_i, 3_a),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -494,8 +536,11 @@
// @compute @workgroup_size(1u, 2, 3u)
// fn main() {}
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Source{{12, 34}}, 1_u, 2_a, 3_u)});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Source{{12, 34}}, 1_u, 2_a, 3_u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -504,8 +549,11 @@
// @compute @workgroup_size(1u, 2, 3_i)
// fn main() {}
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Source{{12, 34}}, 1_u, 2_a, 3_i)});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Source{{12, 34}}, 1_u, 2_a, 3_i),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -516,8 +564,11 @@
// @compute @workgroup_size(1_i, 2u, 3)
// fn main() {}
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Source{{12, 34}}, 1_i, 2_u, 3_a)});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Source{{12, 34}}, 1_i, 2_u, 3_a),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -529,8 +580,11 @@
// @compute @workgroup_size(1i, x)
// fn main() {}
GlobalConst("x", ty.u32(), Expr(64_u));
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Source{{12, 34}}, 1_i, "x")});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Source{{12, 34}}, 1_i, "x"),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -544,8 +598,11 @@
// fn main() {}
GlobalConst("x", ty.u32(), Expr(64_u));
GlobalConst("y", ty.i32(), Expr(32_i));
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Source{{12, 34}}, "x", "y")});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Source{{12, 34}}, "x", "y"),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -559,8 +616,11 @@
// fn main() {}
GlobalConst("x", ty.u32(), Expr(4_u));
GlobalConst("y", ty.u32(), Expr(8_u));
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Source{{12, 34}}, "x", "y", 16_i)});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Source{{12, 34}}, "x", "y", 16_i),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -571,8 +631,11 @@
// @compute @workgroup_size(64.0)
// fn main() {}
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, 64_f))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{{12, 34}}, 64_f)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -584,8 +647,11 @@
// @compute @workgroup_size(-2i)
// fn main() {}
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, -2_i))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{{12, 34}}, -2_i)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
@@ -595,8 +661,11 @@
// @compute @workgroup_size(0i)
// fn main() {}
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, 0_i))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{{12, 34}}, 0_i)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
@@ -607,8 +676,11 @@
// @compute @workgroup_size(x)
// fn main() {}
GlobalConst("x", ty.f32(), Expr(64_f));
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, "x"))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{{12, 34}}, "x")),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -621,8 +693,11 @@
// @compute @workgroup_size(x)
// fn main() {}
GlobalConst("x", ty.i32(), Expr(-2_i));
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, "x"))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{{12, 34}}, "x")),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
@@ -633,8 +708,11 @@
// @compute @workgroup_size(x)
// fn main() {}
GlobalConst("x", ty.i32(), Expr(0_i));
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, "x"))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{{12, 34}}, "x")),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
@@ -645,8 +723,11 @@
// @compute @workgroup_size(x)
// fn main() {}
GlobalConst("x", ty.i32(), Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32()))));
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, "x"))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{{12, 34}}, "x")),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
@@ -657,8 +738,11 @@
// @compute @workgroup_size(x)
// fn main() {}
GlobalVar("x", ty.i32(), ast::StorageClass::kPrivate, Expr(64_i));
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, "x"))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Expr(Source{{12, 34}}, "x")),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -669,9 +753,11 @@
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_InvalidExpr) {
// @compute @workgroup_size(i32(1))
// fn main() {}
- Func("main", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute),
- WorkgroupSize(Construct(Source{{12, 34}}, ty.i32(), 1_i))});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(Construct(Source{{12, 34}}, ty.i32(), 1_i)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -681,7 +767,7 @@
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_NonPlain) {
auto* ret_type = ty.pointer(Source{{12, 34}}, ty.i32(), ast::StorageClass::kFunction);
- Func("f", {}, ret_type, {});
+ Func("f", utils::Empty, ret_type, utils::Empty);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: function return type must be a constructible type");
@@ -689,7 +775,7 @@
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_AtomicInt) {
auto* ret_type = ty.atomic(Source{{12, 34}}, ty.i32());
- Func("f", {}, ret_type, {});
+ Func("f", utils::Empty, ret_type, utils::Empty);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: function return type must be a constructible type");
@@ -697,16 +783,18 @@
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_ArrayOfAtomic) {
auto* ret_type = ty.array(Source{{12, 34}}, ty.atomic(ty.i32()), 10_u);
- Func("f", {}, ret_type, {});
+ Func("f", utils::Empty, ret_type, utils::Empty);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: function return type must be a constructible type");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_StructOfAtomic) {
- Structure("S", {Member("m", ty.atomic(ty.i32()))});
+ Structure("S", utils::Vector{
+ Member("m", ty.atomic(ty.i32())),
+ });
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
- Func("f", {}, ret_type, {});
+ Func("f", utils::Empty, ret_type, utils::Empty);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: function return type must be a constructible type");
@@ -714,47 +802,51 @@
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_RuntimeArray) {
auto* ret_type = ty.array(Source{{12, 34}}, ty.i32());
- Func("f", {}, ret_type, {});
+ Func("f", utils::Empty, ret_type, utils::Empty);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: function return type must be a constructible type");
}
TEST_F(ResolverFunctionValidationTest, ParameterStoreType_NonAtomicFree) {
- Structure("S", {Member("m", ty.atomic(ty.i32()))});
+ Structure("S", utils::Vector{
+ Member("m", ty.atomic(ty.i32())),
+ });
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
auto* bar = Param(Source{{12, 34}}, "bar", ret_type);
- Func("f", {bar}, ty.void_(), {});
+ Func("f", utils::Vector{bar}, ty.void_(), utils::Empty);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: type of function parameter must be constructible");
}
TEST_F(ResolverFunctionValidationTest, ParameterSotreType_AtomicFree) {
- Structure("S", {Member("m", ty.i32())});
+ Structure("S", utils::Vector{
+ Member("m", ty.i32()),
+ });
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
auto* bar = Param(Source{{12, 34}}, "bar", ret_type);
- Func("f", {bar}, ty.void_(), {});
+ Func("f", utils::Vector{bar}, ty.void_(), utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverFunctionValidationTest, ParametersAtLimit) {
- ast::ParameterList params;
+ utils::Vector<const ast::Parameter*, 256> params;
for (int i = 0; i < 255; i++) {
- params.emplace_back(Param("param_" + std::to_string(i), ty.i32()));
+ params.Push(Param("param_" + std::to_string(i), ty.i32()));
}
- Func(Source{{12, 34}}, "f", params, ty.void_(), {});
+ Func(Source{{12, 34}}, "f", params, ty.void_(), utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverFunctionValidationTest, ParametersOverLimit) {
- ast::ParameterList params;
+ utils::Vector<const ast::Parameter*, 256> params;
for (int i = 0; i < 256; i++) {
- params.emplace_back(Param("param_" + std::to_string(i), ty.i32()));
+ params.Push(Param("param_" + std::to_string(i), ty.i32()));
}
- Func(Source{{12, 34}}, "f", params, ty.void_(), {});
+ Func(Source{{12, 34}}, "f", params, ty.void_(), utils::Empty);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: functions may declare at most 255 parameters");
@@ -763,8 +855,9 @@
TEST_F(ResolverFunctionValidationTest, ParameterVectorNoType) {
// fn f(p : vec3) {}
- Func(Source{{12, 34}}, "f", {Param("p", create<ast::Vector>(Source{{12, 34}}, nullptr, 3u))},
- ty.void_(), {});
+ Func(Source{{12, 34}}, "f",
+ utils::Vector{Param("p", create<ast::Vector>(Source{{12, 34}}, nullptr, 3u))}, ty.void_(),
+ utils::Empty);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
@@ -774,7 +867,8 @@
// fn f(p : vec3) {}
Func(Source{{12, 34}}, "f",
- {Param("p", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3u, 3u))}, ty.void_(), {});
+ utils::Vector{Param("p", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3u, 3u))},
+ ty.void_(), utils::Empty);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
@@ -792,7 +886,7 @@
auto& param = GetParam();
auto* ptr_type = ty.pointer(Source{{12, 34}}, ty.i32(), param.storage_class);
auto* arg = Param(Source{{12, 34}}, "p", ptr_type);
- Func("f", {arg}, ty.void_(), {});
+ Func("f", utils::Vector{arg}, ty.void_(), utils::Empty);
if (param.should_pass) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/host_shareable_validation_test.cc b/src/tint/resolver/host_shareable_validation_test.cc
index 1bd9ed7..d67a108 100644
--- a/src/tint/resolver/host_shareable_validation_test.cc
+++ b/src/tint/resolver/host_shareable_validation_test.cc
@@ -24,10 +24,10 @@
using ResolverHostShareableValidationTest = ResolverTest;
TEST_F(ResolverHostShareableValidationTest, BoolMember) {
- auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.bool_())});
+ auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.bool_())});
GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -42,10 +42,10 @@
}
TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) {
- auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.vec3<bool>())});
+ auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.vec3<bool>())});
GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -61,10 +61,10 @@
TEST_F(ResolverHostShareableValidationTest, Aliases) {
auto* a1 = Alias("a1", ty.bool_());
- auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.Of(a1))});
+ auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.Of(a1))});
auto* a2 = Alias("a2", ty.Of(s));
GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -79,14 +79,14 @@
}
TEST_F(ResolverHostShareableValidationTest, NestedStructures) {
- auto* i1 = Structure("I1", {Member(Source{{1, 2}}, "x", ty.bool_())});
- auto* i2 = Structure("I2", {Member(Source{{3, 4}}, "y", ty.Of(i1))});
- auto* i3 = Structure("I3", {Member(Source{{5, 6}}, "z", ty.Of(i2))});
+ auto* i1 = Structure("I1", utils::Vector{Member(Source{{1, 2}}, "x", ty.bool_())});
+ auto* i2 = Structure("I2", utils::Vector{Member(Source{{3, 4}}, "y", ty.Of(i1))});
+ auto* i3 = Structure("I3", utils::Vector{Member(Source{{5, 6}}, "z", ty.Of(i2))});
- auto* s = Structure("S", {Member(Source{{7, 8}}, "m", ty.Of(i3))});
+ auto* s = Structure("S", utils::Vector{Member(Source{{7, 8}}, "m", ty.Of(i3))});
GlobalVar(Source{{9, 10}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -106,33 +106,32 @@
TEST_F(ResolverHostShareableValidationTest, NoError) {
Enable(ast::Extension::kF16);
- auto* i1 = Structure("I1", {
+ auto* i1 = Structure("I1", utils::Vector{
Member(Source{{1, 1}}, "w1", ty.f32()),
Member(Source{{2, 1}}, "x1", ty.f32()),
Member(Source{{3, 1}}, "y1", ty.vec3<f32>()),
Member(Source{{4, 1}}, "z1", ty.array<i32, 4>()),
});
auto* a1 = Alias("a1", ty.Of(i1));
- auto* i2 = Structure("I2", {
+ auto* i2 = Structure("I2", utils::Vector{
Member(Source{{5, 1}}, "x2", ty.mat2x2<f32>()),
Member(Source{{6, 1}}, "w2", ty.mat3x4<f32>()),
Member(Source{{7, 1}}, "z2", ty.Of(i1)),
});
auto* a2 = Alias("a2", ty.Of(i2));
- auto* i3 = Structure("I3", {
+ auto* i3 = Structure("I3", utils::Vector{
Member(Source{{4, 1}}, "x3", ty.Of(a1)),
Member(Source{{5, 1}}, "y3", ty.Of(i2)),
Member(Source{{6, 1}}, "z3", ty.Of(a2)),
});
- auto* s = Structure("S", {Member(Source{{7, 8}}, "m", ty.Of(i3))});
+ auto* s = Structure("S", utils::Vector{Member(Source{{7, 8}}, "m", ty.Of(i3))});
GlobalVar(Source{{9, 10}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
- WrapInFunction();
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
diff --git a/src/tint/resolver/increment_decrement_validation_test.cc b/src/tint/resolver/increment_decrement_validation_test.cc
index 5061e49..a7e636f 100644
--- a/src/tint/resolver/increment_decrement_validation_test.cc
+++ b/src/tint/resolver/increment_decrement_validation_test.cc
@@ -161,7 +161,10 @@
// a++;
// }
auto* a = Param(Source{{12, 34}}, "a", ty.i32());
- Func("func", {a}, ty.void_(), {Increment(Expr(Source{{56, 78}}, "a"))});
+ Func("func", utils::Vector{a}, ty.void_(),
+ utils::Vector{
+ Increment(Expr(Source{{56, 78}}, "a")),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(56:78 error: cannot modify function parameter
@@ -175,7 +178,10 @@
// {
// a++;
// }
- Func("func", {}, ty.i32(), {Return(0_i)});
+ Func("func", utils::Empty, ty.i32(),
+ utils::Vector{
+ Return(0_i),
+ });
WrapInFunction(Increment(Call(Source{{56, 78}}, "func")));
EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/inferred_type_test.cc b/src/tint/resolver/inferred_type_test.cc
index a183b20..4051d82 100644
--- a/src/tint/resolver/inferred_type_test.cc
+++ b/src/tint/resolver/inferred_type_test.cc
@@ -83,7 +83,6 @@
// const a = <type constructor>;
auto* ctor_expr = params.create_value(*this, 0);
auto* a = GlobalConst("a", nullptr, ctor_expr);
- WrapInFunction();
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_EQ(TypeOf(a), expected_type);
@@ -97,7 +96,6 @@
// var a = <type constructor>;
auto* ctor_expr = params.create_value(*this, 0);
auto* var = GlobalVar("a", nullptr, ast::StorageClass::kPrivate, ctor_expr);
- WrapInFunction();
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_EQ(TypeOf(var)->UnwrapRef(), expected_type);
@@ -147,7 +145,7 @@
TEST_F(ResolverInferredTypeTest, InferStruct_Pass) {
auto* member = Member("x", ty.i32());
- auto* str = Structure("S", {member});
+ auto* str = Structure("S", utils::Vector{member});
auto* expected_type =
create<sem::Struct>(str, str->name,
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index bb5791f..67a75c3 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -123,17 +123,17 @@
/// If none of the above applies, then `ty` is a type mismatch for the template type, and
/// nullptr is returned.
const sem::Type* Type(size_t idx, const sem::Type* ty) {
- auto res = types_.emplace(idx, ty);
- if (res.second) {
+ if (idx >= types_.Length()) {
+ types_.Resize(idx + 1);
+ }
+ auto& t = types_[idx];
+ if (t == nullptr) {
+ t = ty;
return ty;
}
- auto* existing = res.first->second;
- if (existing == ty) {
- return ty;
- }
- ty = sem::Type::Common(utils::Vector{existing, ty});
+ ty = sem::Type::Common(utils::Vector{t, ty});
if (ty) {
- res.first->second = ty;
+ t = ty;
}
return ty;
}
@@ -142,28 +142,44 @@
/// Num() returns true. If the number is defined, then `Num()` returns true iff it is equal to
/// `ty`.
bool Num(size_t idx, Number number) {
- auto res = numbers_.emplace(idx, number.Value());
- return res.second || res.first->second == number.Value();
+ if (idx >= numbers_.Length()) {
+ numbers_.Resize(idx + 1, Number::invalid);
+ }
+ auto& n = numbers_[idx];
+ if (!n.IsValid()) {
+ n = number.Value();
+ return true;
+ }
+ return n.Value() == number.Value();
}
/// Type returns the template type with index `idx`, or nullptr if the type was not defined.
const sem::Type* Type(size_t idx) const {
- auto it = types_.find(idx);
- return (it != types_.end()) ? it->second : nullptr;
+ if (idx >= types_.Length()) {
+ return nullptr;
+ }
+ return types_[idx];
}
/// SetType replaces the template type with index `idx` with type `ty`.
- void SetType(size_t idx, const sem::Type* ty) { types_[idx] = ty; }
+ void SetType(size_t idx, const sem::Type* ty) {
+ if (idx >= types_.Length()) {
+ types_.Resize(idx + 1);
+ }
+ types_[idx] = ty;
+ }
/// Type returns the number type with index `idx`.
Number Num(size_t idx) const {
- auto it = numbers_.find(idx);
- return (it != numbers_.end()) ? Number(it->second) : Number::invalid;
+ if (idx >= numbers_.Length()) {
+ return Number::invalid;
+ }
+ return numbers_[idx];
}
private:
- std::unordered_map<size_t, const sem::Type*> types_;
- std::unordered_map<size_t, uint32_t> numbers_;
+ utils::Vector<const sem::Type*, 4> types_;
+ utils::Vector<Number, 2> numbers_;
};
/// Index type used for matcher indices
@@ -716,24 +732,34 @@
// Builtin types starting with a _ prefix cannot be declared in WGSL, so they
// can only be used as return types. Because of this, they must only match Any,
// which is used as the return type matcher.
-bool match_modf_result(const sem::Type* ty) {
- return ty->Is<Any>();
-}
-bool match_modf_result_vec(const sem::Type* ty, Number& N) {
+bool match_modf_result(const sem::Type* ty, const sem::Type*& T) {
if (!ty->Is<Any>()) {
return false;
}
- N = Number::any;
+ T = ty;
return true;
}
-bool match_frexp_result(const sem::Type* ty) {
- return ty->Is<Any>();
-}
-bool match_frexp_result_vec(const sem::Type* ty, Number& N) {
+bool match_modf_result_vec(const sem::Type* ty, Number& N, const sem::Type*& T) {
if (!ty->Is<Any>()) {
return false;
}
N = Number::any;
+ T = ty;
+ return true;
+}
+bool match_frexp_result(const sem::Type* ty, const sem::Type*& T) {
+ if (!ty->Is<Any>()) {
+ return false;
+ }
+ T = ty;
+ return true;
+}
+bool match_frexp_result_vec(const sem::Type* ty, Number& N, const sem::Type*& T) {
+ if (!ty->Is<Any>()) {
+ return false;
+ }
+ N = Number::any;
+ T = ty;
return true;
}
@@ -747,7 +773,7 @@
struct NameAndType {
std::string name;
- sem::Type* type;
+ const sem::Type* type;
};
const sem::Struct* build_struct(MatchState& state,
std::string name,
@@ -781,27 +807,46 @@
/* size_no_padding */ size_without_padding);
}
-const sem::Struct* build_modf_result(MatchState& state) {
- auto* f32 = state.builder.create<sem::F32>();
- return build_struct(state, "__modf_result", {{"fract", f32}, {"whole", f32}});
+const sem::Struct* build_modf_result(MatchState& state, const sem::Type* el) {
+ std::string display_name;
+ if (el->Is<sem::F16>()) {
+ display_name = "__modf_result_f16";
+ } else {
+ display_name = "__modf_result";
+ }
+ return build_struct(state, display_name, {{"fract", el}, {"whole", el}});
}
-const sem::Struct* build_modf_result_vec(MatchState& state, Number& n) {
- auto* vec_f32 = state.builder.create<sem::Vector>(state.builder.create<sem::F32>(), n.Value());
- return build_struct(state, "__modf_result_vec" + std::to_string(n.Value()),
- {{"fract", vec_f32}, {"whole", vec_f32}});
+const sem::Struct* build_modf_result_vec(MatchState& state, Number& n, const sem::Type* el) {
+ std::string display_name;
+ if (el->Is<sem::F16>()) {
+ display_name = "__modf_result_vec" + std::to_string(n.Value()) + "_f16";
+ } else {
+ display_name = "__modf_result_vec" + std::to_string(n.Value());
+ }
+ auto* vec = state.builder.create<sem::Vector>(el, n.Value());
+ return build_struct(state, display_name, {{"fract", vec}, {"whole", vec}});
}
-const sem::Struct* build_frexp_result(MatchState& state) {
- auto* f32 = state.builder.create<sem::F32>();
+const sem::Struct* build_frexp_result(MatchState& state, const sem::Type* el) {
+ std::string display_name;
+ if (el->Is<sem::F16>()) {
+ display_name = "__frexp_result_f16";
+ } else {
+ display_name = "__frexp_result";
+ }
auto* i32 = state.builder.create<sem::I32>();
- return build_struct(state, "__frexp_result", {{"sig", f32}, {"exp", i32}});
+ return build_struct(state, display_name, {{"sig", el}, {"exp", i32}});
}
-const sem::Struct* build_frexp_result_vec(MatchState& state, Number& n) {
- auto* vec_f32 = state.builder.create<sem::Vector>(state.builder.create<sem::F32>(), n.Value());
+const sem::Struct* build_frexp_result_vec(MatchState& state, Number& n, const sem::Type* el) {
+ std::string display_name;
+ if (el->Is<sem::F16>()) {
+ display_name = "__frexp_result_vec" + std::to_string(n.Value()) + "_f16";
+ } else {
+ display_name = "__frexp_result_vec" + std::to_string(n.Value());
+ }
+ auto* vec = state.builder.create<sem::Vector>(el, n.Value());
auto* vec_i32 = state.builder.create<sem::Vector>(state.builder.create<sem::I32>(), n.Value());
- return build_struct(state, "__frexp_result_vec" + std::to_string(n.Value()),
- {{"sig", vec_f32}, {"exp", vec_i32}});
+ return build_struct(state, display_name, {{"sig", vec}, {"exp", vec_i32}});
}
-
const sem::Struct* build_atomic_compare_exchange_result(MatchState& state, const sem::Type* ty) {
return build_struct(
state, "__atomic_compare_exchange_result" + ty->FriendlyName(state.builder.Symbols()),
@@ -1026,14 +1071,14 @@
// Prints the list of candidates for emitting diagnostics
void PrintCandidates(std::ostream& ss,
- utils::ConstVectorRef<Candidate> candidates,
+ utils::VectorRef<Candidate> candidates,
const char* intrinsic_name) const;
/// Raises an error when no overload is a clear winner of overload resolution
void ErrAmbiguousOverload(const char* intrinsic_name,
- utils::ConstVectorRef<const sem::Type*> args,
+ utils::VectorRef<const sem::Type*> args,
TemplateState templates,
- utils::ConstVectorRef<Candidate> candidates) const;
+ utils::VectorRef<Candidate> candidates) const;
ProgramBuilder& builder;
Matchers matchers;
@@ -1604,7 +1649,7 @@
}
void Impl::PrintCandidates(std::ostream& ss,
- utils::ConstVectorRef<Candidate> candidates,
+ utils::VectorRef<Candidate> candidates,
const char* intrinsic_name) const {
for (auto& candidate : candidates) {
ss << " ";
@@ -1638,9 +1683,9 @@
}
void Impl::ErrAmbiguousOverload(const char* intrinsic_name,
- utils::ConstVectorRef<const sem::Type*> args,
+ utils::VectorRef<const sem::Type*> args,
TemplateState templates,
- utils::ConstVectorRef<Candidate> candidates) const {
+ utils::VectorRef<Candidate> candidates) const {
std::stringstream ss;
ss << "ambiguous overload while attempting to match " << intrinsic_name;
for (size_t i = 0; i < std::numeric_limits<size_t>::max(); i++) {
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl
index 28bcc51..16c177c 100644
--- a/src/tint/resolver/intrinsic_table.inl
+++ b/src/tint/resolver/intrinsic_table.inl
@@ -1386,14 +1386,22 @@
};
const sem::Type* ModfResult::Match(MatchState& state, const sem::Type* ty) const {
- if (!match_modf_result(ty)) {
+ const sem::Type* T = nullptr;
+ if (!match_modf_result(ty, T)) {
return nullptr;
}
- return build_modf_result(state);
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_modf_result(state, T);
}
-std::string ModfResult::String(MatchState*) const {
- return "__modf_result";
+std::string ModfResult::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ std::stringstream ss;
+ ss << "__modf_result_" << T;
+ return ss.str();
}
/// TypeMatcher for 'type __modf_result_vec'
@@ -1413,20 +1421,26 @@
const sem::Type* ModfResultVec::Match(MatchState& state, const sem::Type* ty) const {
Number N = Number::invalid;
- if (!match_modf_result_vec(ty, N)) {
+ const sem::Type* T = nullptr;
+ if (!match_modf_result_vec(ty, N, T)) {
return nullptr;
}
N = state.Num(N);
if (!N.IsValid()) {
return nullptr;
}
- return build_modf_result_vec(state, N);
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_modf_result_vec(state, N, T);
}
std::string ModfResultVec::String(MatchState* state) const {
const std::string N = state->NumName();
+ const std::string T = state->TypeName();
std::stringstream ss;
- ss << "__modf_result_vec" << N;
+ ss << "__modf_result_vec" << N << "_" << T;
return ss.str();
}
@@ -1446,14 +1460,22 @@
};
const sem::Type* FrexpResult::Match(MatchState& state, const sem::Type* ty) const {
- if (!match_frexp_result(ty)) {
+ const sem::Type* T = nullptr;
+ if (!match_frexp_result(ty, T)) {
return nullptr;
}
- return build_frexp_result(state);
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_frexp_result(state, T);
}
-std::string FrexpResult::String(MatchState*) const {
- return "__frexp_result";
+std::string FrexpResult::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ std::stringstream ss;
+ ss << "__frexp_result_" << T;
+ return ss.str();
}
/// TypeMatcher for 'type __frexp_result_vec'
@@ -1473,20 +1495,26 @@
const sem::Type* FrexpResultVec::Match(MatchState& state, const sem::Type* ty) const {
Number N = Number::invalid;
- if (!match_frexp_result_vec(ty, N)) {
+ const sem::Type* T = nullptr;
+ if (!match_frexp_result_vec(ty, N, T)) {
return nullptr;
}
N = state.Num(N);
if (!N.IsValid()) {
return nullptr;
}
- return build_frexp_result_vec(state, N);
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_frexp_result_vec(state, N, T);
}
std::string FrexpResultVec::String(MatchState* state) const {
const std::string N = state->NumName();
+ const std::string T = state->TypeName();
std::stringstream ss;
- ss << "__frexp_result_vec" << N;
+ ss << "__frexp_result_vec" << N << "_" << T;
return ss.str();
}
@@ -2724,12 +2752,12 @@
/* [42] */ 41,
/* [43] */ 5,
/* [44] */ 6,
- /* [45] */ 42,
- /* [46] */ 0,
- /* [47] */ 1,
- /* [48] */ 40,
- /* [49] */ 5,
- /* [50] */ 6,
+ /* [45] */ 40,
+ /* [46] */ 5,
+ /* [47] */ 6,
+ /* [48] */ 42,
+ /* [49] */ 0,
+ /* [50] */ 1,
/* [51] */ 43,
/* [52] */ 4,
/* [53] */ 6,
@@ -2757,162 +2785,166 @@
/* [75] */ 41,
/* [76] */ 3,
/* [77] */ 6,
- /* [78] */ 43,
+ /* [78] */ 48,
/* [79] */ 0,
- /* [80] */ 1,
- /* [81] */ 41,
+ /* [80] */ 0,
+ /* [81] */ 43,
/* [82] */ 0,
/* [83] */ 1,
- /* [84] */ 40,
+ /* [84] */ 41,
/* [85] */ 0,
/* [86] */ 1,
- /* [87] */ 21,
+ /* [87] */ 40,
/* [88] */ 0,
- /* [89] */ 5,
+ /* [89] */ 1,
/* [90] */ 21,
/* [91] */ 0,
- /* [92] */ 6,
- /* [93] */ 40,
- /* [94] */ 3,
+ /* [92] */ 5,
+ /* [93] */ 21,
+ /* [94] */ 0,
/* [95] */ 6,
- /* [96] */ 17,
+ /* [96] */ 46,
/* [97] */ 0,
- /* [98] */ 10,
- /* [99] */ 1,
- /* [100] */ 10,
- /* [101] */ 7,
- /* [102] */ 10,
- /* [103] */ 8,
+ /* [98] */ 0,
+ /* [99] */ 40,
+ /* [100] */ 3,
+ /* [101] */ 6,
+ /* [102] */ 17,
+ /* [103] */ 0,
/* [104] */ 10,
- /* [105] */ 5,
- /* [106] */ 9,
- /* [107] */ 0,
+ /* [105] */ 7,
+ /* [106] */ 10,
+ /* [107] */ 1,
/* [108] */ 10,
- /* [109] */ 0,
+ /* [109] */ 8,
/* [110] */ 10,
- /* [111] */ 6,
+ /* [111] */ 5,
/* [112] */ 10,
- /* [113] */ 2,
- /* [114] */ 11,
- /* [115] */ 0,
+ /* [113] */ 0,
+ /* [114] */ 10,
+ /* [115] */ 6,
/* [116] */ 9,
- /* [117] */ 2,
- /* [118] */ 9,
- /* [119] */ 1,
+ /* [117] */ 0,
+ /* [118] */ 10,
+ /* [119] */ 2,
/* [120] */ 11,
- /* [121] */ 7,
+ /* [121] */ 0,
/* [122] */ 9,
- /* [123] */ 6,
+ /* [123] */ 2,
/* [124] */ 9,
- /* [125] */ 5,
- /* [126] */ 9,
- /* [127] */ 8,
+ /* [125] */ 1,
+ /* [126] */ 11,
+ /* [127] */ 7,
/* [128] */ 9,
- /* [129] */ 7,
- /* [130] */ 46,
- /* [131] */ 0,
- /* [132] */ 28,
- /* [133] */ 0,
- /* [134] */ 11,
- /* [135] */ 1,
- /* [136] */ 29,
+ /* [129] */ 6,
+ /* [130] */ 9,
+ /* [131] */ 5,
+ /* [132] */ 9,
+ /* [133] */ 8,
+ /* [134] */ 9,
+ /* [135] */ 7,
+ /* [136] */ 45,
/* [137] */ 0,
- /* [138] */ 30,
+ /* [138] */ 28,
/* [139] */ 0,
- /* [140] */ 11,
- /* [141] */ 8,
- /* [142] */ 31,
+ /* [140] */ 29,
+ /* [141] */ 0,
+ /* [142] */ 30,
/* [143] */ 0,
/* [144] */ 11,
- /* [145] */ 5,
- /* [146] */ 32,
+ /* [145] */ 1,
+ /* [146] */ 31,
/* [147] */ 0,
- /* [148] */ 33,
+ /* [148] */ 32,
/* [149] */ 0,
/* [150] */ 11,
- /* [151] */ 6,
- /* [152] */ 34,
+ /* [151] */ 8,
+ /* [152] */ 33,
/* [153] */ 0,
- /* [154] */ 11,
- /* [155] */ 2,
- /* [156] */ 12,
- /* [157] */ 0,
- /* [158] */ 12,
- /* [159] */ 7,
- /* [160] */ 31,
- /* [161] */ 7,
+ /* [154] */ 34,
+ /* [155] */ 0,
+ /* [156] */ 11,
+ /* [157] */ 5,
+ /* [158] */ 11,
+ /* [159] */ 6,
+ /* [160] */ 11,
+ /* [161] */ 2,
/* [162] */ 12,
- /* [163] */ 8,
- /* [164] */ 13,
- /* [165] */ 0,
- /* [166] */ 48,
- /* [167] */ 0,
+ /* [163] */ 0,
+ /* [164] */ 12,
+ /* [165] */ 7,
+ /* [166] */ 12,
+ /* [167] */ 8,
/* [168] */ 13,
- /* [169] */ 7,
+ /* [169] */ 0,
/* [170] */ 13,
- /* [171] */ 8,
- /* [172] */ 14,
+ /* [171] */ 7,
+ /* [172] */ 47,
/* [173] */ 0,
- /* [174] */ 14,
- /* [175] */ 7,
+ /* [174] */ 13,
+ /* [175] */ 8,
/* [176] */ 14,
- /* [177] */ 8,
- /* [178] */ 15,
- /* [179] */ 0,
- /* [180] */ 15,
- /* [181] */ 7,
+ /* [177] */ 0,
+ /* [178] */ 14,
+ /* [179] */ 7,
+ /* [180] */ 14,
+ /* [181] */ 8,
/* [182] */ 15,
- /* [183] */ 8,
- /* [184] */ 16,
- /* [185] */ 0,
- /* [186] */ 16,
- /* [187] */ 7,
+ /* [183] */ 0,
+ /* [184] */ 15,
+ /* [185] */ 7,
+ /* [186] */ 15,
+ /* [187] */ 8,
/* [188] */ 16,
- /* [189] */ 8,
- /* [190] */ 17,
+ /* [189] */ 0,
+ /* [190] */ 16,
/* [191] */ 7,
- /* [192] */ 17,
+ /* [192] */ 16,
/* [193] */ 8,
- /* [194] */ 18,
- /* [195] */ 0,
- /* [196] */ 18,
- /* [197] */ 7,
+ /* [194] */ 17,
+ /* [195] */ 7,
+ /* [196] */ 17,
+ /* [197] */ 8,
/* [198] */ 18,
- /* [199] */ 8,
- /* [200] */ 19,
- /* [201] */ 0,
- /* [202] */ 49,
- /* [203] */ 0,
- /* [204] */ 28,
- /* [205] */ 7,
- /* [206] */ 29,
- /* [207] */ 7,
- /* [208] */ 30,
+ /* [199] */ 0,
+ /* [200] */ 18,
+ /* [201] */ 7,
+ /* [202] */ 18,
+ /* [203] */ 8,
+ /* [204] */ 19,
+ /* [205] */ 0,
+ /* [206] */ 49,
+ /* [207] */ 0,
+ /* [208] */ 28,
/* [209] */ 7,
- /* [210] */ 19,
+ /* [210] */ 29,
/* [211] */ 7,
- /* [212] */ 19,
- /* [213] */ 8,
- /* [214] */ 32,
+ /* [212] */ 30,
+ /* [213] */ 7,
+ /* [214] */ 31,
/* [215] */ 7,
- /* [216] */ 33,
+ /* [216] */ 19,
/* [217] */ 7,
- /* [218] */ 20,
- /* [219] */ 0,
- /* [220] */ 20,
+ /* [218] */ 19,
+ /* [219] */ 8,
+ /* [220] */ 32,
/* [221] */ 7,
- /* [222] */ 20,
- /* [223] */ 8,
- /* [224] */ 26,
- /* [225] */ 38,
- /* [226] */ 27,
- /* [227] */ 37,
- /* [228] */ 36,
- /* [229] */ 35,
- /* [230] */ 44,
- /* [231] */ 39,
- /* [232] */ 45,
- /* [233] */ 47,
+ /* [222] */ 33,
+ /* [223] */ 7,
+ /* [224] */ 20,
+ /* [225] */ 0,
+ /* [226] */ 20,
+ /* [227] */ 7,
+ /* [228] */ 20,
+ /* [229] */ 8,
+ /* [230] */ 26,
+ /* [231] */ 38,
+ /* [232] */ 27,
+ /* [233] */ 37,
+ /* [234] */ 36,
+ /* [235] */ 35,
+ /* [236] */ 44,
+ /* [237] */ 39,
};
// Assert that the MatcherIndex is big enough to index all the matchers, plus
@@ -3250,17 +3282,17 @@
{
/* [65] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[208],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [66] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [67] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [68] */
@@ -3270,32 +3302,32 @@
{
/* [69] */
/* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [70] */
/* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [71] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [72] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [73] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [74] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [75] */
@@ -3310,37 +3342,37 @@
{
/* [77] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [78] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[160],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [79] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [80] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [81] */
/* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [82] */
/* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [83] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[110],
},
{
/* [84] */
@@ -3375,17 +3407,17 @@
{
/* [90] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [91] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [92] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [93] */
@@ -3400,7 +3432,7 @@
{
/* [95] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [96] */
@@ -3410,17 +3442,17 @@
{
/* [97] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [98] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [99] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [100] */
@@ -3430,22 +3462,22 @@
{
/* [101] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [102] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[208],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [103] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [104] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [105] */
@@ -3455,42 +3487,42 @@
{
/* [106] */
/* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [107] */
/* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [108] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[206],
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [109] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [110] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [111] */
/* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [112] */
/* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [113] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [114] */
@@ -3525,17 +3557,17 @@
{
/* [120] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [121] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [122] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [123] */
@@ -3545,27 +3577,27 @@
{
/* [124] */
/* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [125] */
/* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [126] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [127] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [128] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [129] */
@@ -3580,22 +3612,22 @@
{
/* [131] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [132] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[208],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [133] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [134] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [135] */
@@ -3610,22 +3642,22 @@
{
/* [137] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [138] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [139] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [140] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [141] */
@@ -3640,22 +3672,22 @@
{
/* [143] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [144] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[208],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [145] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [146] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [147] */
@@ -3670,22 +3702,22 @@
{
/* [149] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [150] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[208],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [151] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [152] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [153] */
@@ -3700,17 +3732,17 @@
{
/* [155] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [156] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [157] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [158] */
@@ -3725,17 +3757,17 @@
{
/* [160] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [161] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [162] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [163] */
@@ -3745,22 +3777,22 @@
{
/* [164] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [165] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [166] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [167] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [168] */
@@ -3770,7 +3802,7 @@
{
/* [169] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [170] */
@@ -3780,17 +3812,17 @@
{
/* [171] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
+ /* matcher indices */ &kMatcherIndices[152],
},
{
/* [172] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [173] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [174] */
@@ -3800,17 +3832,17 @@
{
/* [175] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[225],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [176] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [177] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [178] */
@@ -3825,42 +3857,42 @@
{
/* [180] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[206],
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [181] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [182] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [183] */
/* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [184] */
/* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [185] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [186] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [187] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [188] */
@@ -3870,22 +3902,22 @@
{
/* [189] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [190] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [191] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [192] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [193] */
@@ -3900,17 +3932,17 @@
{
/* [195] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [196] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [197] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [198] */
@@ -3920,22 +3952,22 @@
{
/* [199] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [200] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[160],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [201] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [202] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [203] */
@@ -3945,22 +3977,22 @@
{
/* [204] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[110],
},
{
/* [205] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[160],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [206] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [207] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [208] */
@@ -3970,22 +4002,22 @@
{
/* [209] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[110],
},
{
/* [210] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[225],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [211] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [212] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [213] */
@@ -4005,17 +4037,17 @@
{
/* [216] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [217] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [218] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [219] */
@@ -4025,17 +4057,17 @@
{
/* [220] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [221] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [222] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [223] */
@@ -4050,17 +4082,17 @@
{
/* [225] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[206],
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [226] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [227] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [228] */
@@ -4070,22 +4102,22 @@
{
/* [229] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [230] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[208],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [231] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [232] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [233] */
@@ -4095,47 +4127,47 @@
{
/* [234] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [235] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[160],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [236] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [237] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [238] */
/* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [239] */
/* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [240] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [241] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [242] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [243] */
@@ -4145,32 +4177,32 @@
{
/* [244] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [245] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[214],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [246] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [247] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [248] */
/* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [249] */
/* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [250] */
@@ -4180,37 +4212,37 @@
{
/* [251] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[136],
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [252] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [253] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [254] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [255] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[225],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [256] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [257] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [258] */
@@ -4225,17 +4257,17 @@
{
/* [260] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[208],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [261] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [262] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [263] */
@@ -4250,17 +4282,17 @@
{
/* [265] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[206],
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [266] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [267] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [268] */
@@ -4270,22 +4302,22 @@
{
/* [269] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [270] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [271] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [272] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [273] */
@@ -4300,17 +4332,17 @@
{
/* [275] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [276] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [277] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [278] */
@@ -4320,22 +4352,22 @@
{
/* [279] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [280] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [281] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [282] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [283] */
@@ -4350,17 +4382,17 @@
{
/* [285] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [286] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [287] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [288] */
@@ -4375,17 +4407,17 @@
{
/* [290] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[225],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [291] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [292] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [293] */
@@ -4400,17 +4432,17 @@
{
/* [295] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[214],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [296] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [297] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [298] */
@@ -4420,17 +4452,17 @@
{
/* [299] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[160],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [300] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [301] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [302] */
@@ -4440,17 +4472,17 @@
{
/* [303] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [304] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [305] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [306] */
@@ -4460,17 +4492,17 @@
{
/* [307] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[227],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [308] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [309] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [310] */
@@ -4485,7 +4517,7 @@
{
/* [312] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [313] */
@@ -4495,22 +4527,22 @@
{
/* [314] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[144],
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [315] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[206],
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [316] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [317] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [318] */
@@ -4520,17 +4552,17 @@
{
/* [319] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [320] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [321] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [322] */
@@ -4540,37 +4572,37 @@
{
/* [323] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [324] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [325] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [326] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [327] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [328] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [329] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [330] */
@@ -4580,22 +4612,22 @@
{
/* [331] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[160],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [332] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [333] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [334] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[110],
},
{
/* [335] */
@@ -4605,7 +4637,7 @@
{
/* [336] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [337] */
@@ -4615,22 +4647,22 @@
{
/* [338] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[120],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [339] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[225],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [340] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [341] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [342] */
@@ -4640,17 +4672,17 @@
{
/* [343] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[206],
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [344] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [345] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [346] */
@@ -4660,17 +4692,17 @@
{
/* [347] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[208],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [348] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [349] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [350] */
@@ -4680,37 +4712,37 @@
{
/* [351] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[206],
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [352] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [353] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [354] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [355] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[227],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [356] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [357] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [358] */
@@ -4725,7 +4757,7 @@
{
/* [360] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [361] */
@@ -4735,17 +4767,17 @@
{
/* [362] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[150],
+ /* matcher indices */ &kMatcherIndices[158],
},
{
/* [363] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [364] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [365] */
@@ -4760,17 +4792,17 @@
{
/* [367] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [368] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [369] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [370] */
@@ -4780,17 +4812,17 @@
{
/* [371] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[227],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [372] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [373] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [374] */
@@ -4800,17 +4832,17 @@
{
/* [375] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[225],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [376] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [377] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [378] */
@@ -4820,17 +4852,17 @@
{
/* [379] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [380] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [381] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [382] */
@@ -4840,12 +4872,12 @@
{
/* [383] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [384] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [385] */
@@ -4860,57 +4892,57 @@
{
/* [387] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [388] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [389] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [390] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [391] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [392] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [393] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [394] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [395] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [396] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [397] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [398] */
@@ -4940,17 +4972,17 @@
{
/* [403] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[227],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [404] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [405] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [406] */
@@ -4965,17 +4997,17 @@
{
/* [408] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
+ /* matcher indices */ &kMatcherIndices[148],
},
{
/* [409] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [410] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [411] */
@@ -5000,37 +5032,37 @@
{
/* [415] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [416] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [417] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [418] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [419] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [420] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [421] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [422] */
@@ -5085,32 +5117,32 @@
{
/* [432] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[136],
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [433] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [434] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [435] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[214],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [436] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [437] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [438] */
@@ -5120,17 +5152,17 @@
{
/* [439] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[160],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [440] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [441] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [442] */
@@ -5140,22 +5172,22 @@
{
/* [443] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [444] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [445] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [446] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [447] */
@@ -5235,17 +5267,17 @@
{
/* [462] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[227],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [463] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [464] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [465] */
@@ -5255,57 +5287,57 @@
{
/* [466] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [467] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[150],
+ /* matcher indices */ &kMatcherIndices[158],
},
{
/* [468] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [469] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [470] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [471] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[236],
},
{
/* [472] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [473] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [474] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [475] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [476] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [477] */
@@ -5355,7 +5387,7 @@
{
/* [486] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[93],
+ /* matcher indices */ &kMatcherIndices[99],
},
{
/* [487] */
@@ -5365,22 +5397,22 @@
{
/* [488] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[120],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [489] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[214],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [490] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [491] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [492] */
@@ -5390,27 +5422,27 @@
{
/* [493] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [494] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[120],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [495] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[160],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [496] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [497] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [498] */
@@ -5420,12 +5452,12 @@
{
/* [499] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[110],
},
{
/* [500] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[120],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [501] */
@@ -5440,7 +5472,7 @@
{
/* [503] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[144],
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [504] */
@@ -5450,37 +5482,37 @@
{
/* [505] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [506] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[144],
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [507] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[206],
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [508] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [509] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [510] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[204],
+ /* matcher indices */ &kMatcherIndices[208],
},
{
/* [511] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [512] */
@@ -5495,17 +5527,17 @@
{
/* [514] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[110],
},
{
/* [515] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[144],
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [516] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[48],
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [517] */
@@ -5515,7 +5547,7 @@
{
/* [518] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[150],
+ /* matcher indices */ &kMatcherIndices[158],
},
{
/* [519] */
@@ -5525,17 +5557,17 @@
{
/* [520] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[110],
},
{
/* [521] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[150],
+ /* matcher indices */ &kMatcherIndices[158],
},
{
/* [522] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [523] */
@@ -5565,12 +5597,12 @@
{
/* [528] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[136],
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [529] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [530] */
@@ -5580,12 +5612,12 @@
{
/* [531] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[142],
+ /* matcher indices */ &kMatcherIndices[146],
},
{
/* [532] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[110],
},
{
/* [533] */
@@ -5670,12 +5702,12 @@
{
/* [549] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[152],
+ /* matcher indices */ &kMatcherIndices[154],
},
{
/* [550] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [551] */
@@ -5685,12 +5717,12 @@
{
/* [552] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [553] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [554] */
@@ -5700,12 +5732,12 @@
{
/* [555] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[237],
},
{
/* [556] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [557] */
@@ -5715,17 +5747,17 @@
{
/* [558] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [559] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [560] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [561] */
@@ -5745,7 +5777,7 @@
{
/* [564] */
/* usage */ ParameterUsage::kXy,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [565] */
@@ -5795,7 +5827,7 @@
{
/* [574] */
/* usage */ ParameterUsage::kYz,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [575] */
@@ -5815,52 +5847,52 @@
{
/* [578] */
/* usage */ ParameterUsage::kZw,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [579] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [580] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [581] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [582] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [583] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [584] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [585] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[227],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [586] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [587] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [588] */
@@ -5890,32 +5922,32 @@
{
/* [593] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [594] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [595] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [596] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [597] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [598] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [599] */
@@ -5935,12 +5967,12 @@
{
/* [602] */
/* usage */ ParameterUsage::kZyw,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [603] */
/* usage */ ParameterUsage::kXyz,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [604] */
@@ -5950,12 +5982,12 @@
{
/* [605] */
/* usage */ ParameterUsage::kXy,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [606] */
/* usage */ ParameterUsage::kZw,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [607] */
@@ -5965,12 +5997,12 @@
{
/* [608] */
/* usage */ ParameterUsage::kYz,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [609] */
/* usage */ ParameterUsage::kXy,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [610] */
@@ -6005,12 +6037,12 @@
{
/* [616] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[90],
+ /* matcher indices */ &kMatcherIndices[93],
},
{
/* [617] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [618] */
@@ -6030,7 +6062,7 @@
{
/* [621] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[136],
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [622] */
@@ -6045,12 +6077,12 @@
{
/* [624] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[90],
+ /* matcher indices */ &kMatcherIndices[93],
},
{
/* [625] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [626] */
@@ -6070,7 +6102,7 @@
{
/* [629] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[142],
+ /* matcher indices */ &kMatcherIndices[146],
},
{
/* [630] */
@@ -6090,7 +6122,7 @@
{
/* [633] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
+ /* matcher indices */ &kMatcherIndices[148],
},
{
/* [634] */
@@ -6110,7 +6142,7 @@
{
/* [637] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
+ /* matcher indices */ &kMatcherIndices[152],
},
{
/* [638] */
@@ -6140,7 +6172,7 @@
{
/* [643] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [644] */
@@ -6160,7 +6192,7 @@
{
/* [647] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [648] */
@@ -6180,7 +6212,7 @@
{
/* [651] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[227],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [652] */
@@ -6200,7 +6232,7 @@
{
/* [655] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[225],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [656] */
@@ -6815,7 +6847,7 @@
{
/* [778] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[87],
+ /* matcher indices */ &kMatcherIndices[90],
},
{
/* [779] */
@@ -6840,22 +6872,22 @@
{
/* [783] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[236],
},
{
/* [784] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [785] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [786] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [787] */
@@ -6915,7 +6947,7 @@
{
/* [798] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[4],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [799] */
@@ -6975,7 +7007,7 @@
{
/* [810] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [811] */
@@ -7100,7 +7132,7 @@
{
/* [835] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[225],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [836] */
@@ -7200,12 +7232,12 @@
{
/* [855] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[4],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [856] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [857] */
@@ -7245,112 +7277,112 @@
{
/* [864] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [865] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [866] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [867] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[120],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [868] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[120],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [869] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[237],
},
{
/* [870] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[152],
+ /* matcher indices */ &kMatcherIndices[154],
},
{
/* [871] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[225],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [872] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[227],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [873] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [874] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [875] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
+ /* matcher indices */ &kMatcherIndices[152],
},
{
/* [876] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
+ /* matcher indices */ &kMatcherIndices[148],
},
{
/* [877] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[142],
+ /* matcher indices */ &kMatcherIndices[146],
},
{
/* [878] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [879] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[136],
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [880] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [881] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[45],
+ /* matcher indices */ &kMatcherIndices[48],
},
{
/* [882] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[225],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [883] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [884] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
+ /* matcher indices */ &kMatcherIndices[152],
},
{
/* [885] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [886] */
@@ -7430,92 +7462,92 @@
{
/* [901] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[236],
},
{
/* [902] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[78],
+ /* matcher indices */ &kMatcherIndices[81],
},
{
/* [903] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[45],
+ /* matcher indices */ &kMatcherIndices[48],
},
{
/* [904] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[81],
+ /* matcher indices */ &kMatcherIndices[84],
},
{
/* [905] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[84],
+ /* matcher indices */ &kMatcherIndices[87],
},
{
/* [906] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[222],
+ /* matcher indices */ &kMatcherIndices[228],
},
{
/* [907] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[237],
},
{
/* [908] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[220],
+ /* matcher indices */ &kMatcherIndices[226],
},
{
/* [909] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[227],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [910] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[228],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [911] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[229],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [912] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[152],
+ /* matcher indices */ &kMatcherIndices[154],
},
{
/* [913] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
+ /* matcher indices */ &kMatcherIndices[152],
},
{
/* [914] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
+ /* matcher indices */ &kMatcherIndices[148],
},
{
/* [915] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[142],
+ /* matcher indices */ &kMatcherIndices[146],
},
{
/* [916] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [917] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[136],
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [918] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [919] */
@@ -7535,7 +7567,7 @@
{
/* [922] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[218],
+ /* matcher indices */ &kMatcherIndices[224],
},
{
/* [923] */
@@ -7550,7 +7582,7 @@
{
/* [925] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[212],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [926] */
@@ -7565,12 +7597,12 @@
{
/* [928] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[210],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [929] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[103],
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [930] */
@@ -7600,7 +7632,7 @@
{
/* [935] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[106],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [936] */
@@ -7615,37 +7647,37 @@
{
/* [938] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[124],
},
{
/* [939] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[124],
},
{
/* [940] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[124],
},
{
/* [941] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[124],
},
{
/* [942] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[124],
},
{
/* [943] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[200],
+ /* matcher indices */ &kMatcherIndices[204],
},
{
/* [944] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [945] */
@@ -7670,37 +7702,37 @@
{
/* [949] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[98],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [950] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[98],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [951] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[98],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [952] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[98],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [953] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[98],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [954] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [955] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [956] */
@@ -7750,32 +7782,32 @@
{
/* [965] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[134],
+ /* matcher indices */ &kMatcherIndices[144],
},
{
/* [966] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[134],
+ /* matcher indices */ &kMatcherIndices[144],
},
{
/* [967] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[134],
+ /* matcher indices */ &kMatcherIndices[144],
},
{
/* [968] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[134],
+ /* matcher indices */ &kMatcherIndices[144],
},
{
/* [969] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[196],
+ /* matcher indices */ &kMatcherIndices[200],
},
{
/* [970] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[156],
+ /* matcher indices */ &kMatcherIndices[162],
},
{
/* [971] */
@@ -7790,12 +7822,12 @@
{
/* [973] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[158],
+ /* matcher indices */ &kMatcherIndices[164],
},
{
/* [974] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[162],
+ /* matcher indices */ &kMatcherIndices[166],
},
{
/* [975] */
@@ -7805,7 +7837,7 @@
{
/* [976] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[164],
+ /* matcher indices */ &kMatcherIndices[168],
},
{
/* [977] */
@@ -7820,12 +7852,12 @@
{
/* [979] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[168],
+ /* matcher indices */ &kMatcherIndices[170],
},
{
/* [980] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[170],
+ /* matcher indices */ &kMatcherIndices[174],
},
{
/* [981] */
@@ -7835,7 +7867,7 @@
{
/* [982] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[172],
+ /* matcher indices */ &kMatcherIndices[176],
},
{
/* [983] */
@@ -7850,22 +7882,22 @@
{
/* [985] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[174],
+ /* matcher indices */ &kMatcherIndices[178],
},
{
/* [986] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[176],
+ /* matcher indices */ &kMatcherIndices[180],
},
{
/* [987] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [988] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[178],
+ /* matcher indices */ &kMatcherIndices[182],
},
{
/* [989] */
@@ -7880,22 +7912,22 @@
{
/* [991] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[180],
+ /* matcher indices */ &kMatcherIndices[184],
},
{
/* [992] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[182],
+ /* matcher indices */ &kMatcherIndices[186],
},
{
/* [993] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[192],
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [994] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[184],
+ /* matcher indices */ &kMatcherIndices[188],
},
{
/* [995] */
@@ -7910,22 +7942,22 @@
{
/* [997] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[186],
+ /* matcher indices */ &kMatcherIndices[190],
},
{
/* [998] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[188],
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [999] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[190],
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [1000] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[96],
+ /* matcher indices */ &kMatcherIndices[102],
},
{
/* [1001] */
@@ -7940,7 +7972,7 @@
{
/* [1003] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[134],
+ /* matcher indices */ &kMatcherIndices[144],
},
};
@@ -7948,57 +7980,57 @@
{
/* [0] */
/* name */ "T",
- /* matcher index */ 2,
+ /* matcher index */ 7,
},
{
/* [1] */
/* name */ "U",
- /* matcher index */ 56,
+ /* matcher index */ 52,
},
{
/* [2] */
/* name */ "T",
- /* matcher index */ 7,
+ /* matcher index */ 8,
},
{
/* [3] */
/* name */ "U",
- /* matcher index */ 52,
+ /* matcher index */ 53,
},
{
/* [4] */
/* name */ "T",
- /* matcher index */ 8,
+ /* matcher index */ 5,
},
{
/* [5] */
/* name */ "U",
- /* matcher index */ 53,
+ /* matcher index */ 54,
},
{
/* [6] */
/* name */ "T",
- /* matcher index */ 5,
+ /* matcher index */ 6,
},
{
/* [7] */
/* name */ "U",
- /* matcher index */ 54,
+ /* matcher index */ 55,
},
{
/* [8] */
/* name */ "T",
- /* matcher index */ 6,
+ /* matcher index */ 2,
},
{
/* [9] */
/* name */ "U",
- /* matcher index */ 55,
+ /* matcher index */ 56,
},
{
/* [10] */
/* name */ "T",
- /* matcher index */ 68,
+ /* matcher index */ 62,
},
{
/* [11] */
@@ -8018,62 +8050,62 @@
{
/* [14] */
/* name */ "T",
- /* matcher index */ 63,
+ /* matcher index */ 68,
},
{
/* [15] */
/* name */ "T",
- /* matcher index */ 51,
+ /* matcher index */ 63,
},
{
/* [16] */
/* name */ "T",
- /* matcher index */ 64,
+ /* matcher index */ 51,
},
{
/* [17] */
/* name */ "T",
- /* matcher index */ 50,
+ /* matcher index */ 64,
},
{
/* [18] */
/* name */ "T",
- /* matcher index */ kNoMatcher,
+ /* matcher index */ 50,
},
{
/* [19] */
/* name */ "T",
- /* matcher index */ 56,
+ /* matcher index */ kNoMatcher,
},
{
/* [20] */
/* name */ "T",
- /* matcher index */ 53,
+ /* matcher index */ 56,
},
{
/* [21] */
/* name */ "T",
- /* matcher index */ 52,
+ /* matcher index */ 53,
},
{
/* [22] */
/* name */ "T",
- /* matcher index */ 55,
+ /* matcher index */ 52,
},
{
/* [23] */
/* name */ "T",
- /* matcher index */ 54,
+ /* matcher index */ 55,
},
{
/* [24] */
/* name */ "T",
- /* matcher index */ 58,
+ /* matcher index */ 54,
},
{
/* [25] */
/* name */ "T",
- /* matcher index */ 62,
+ /* matcher index */ 58,
},
};
@@ -8136,7 +8168,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[918],
/* return matcher indices */ &kMatcherIndices[34],
@@ -8148,7 +8180,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[617],
/* return matcher indices */ &kMatcherIndices[34],
@@ -8160,10 +8192,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[917],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8172,10 +8204,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[621],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8184,10 +8216,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[916],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8196,10 +8228,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[625],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8208,10 +8240,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[915],
- /* return matcher indices */ &kMatcherIndices[104],
+ /* return matcher indices */ &kMatcherIndices[110],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8220,10 +8252,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[629],
- /* return matcher indices */ &kMatcherIndices[104],
+ /* return matcher indices */ &kMatcherIndices[110],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8232,10 +8264,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[914],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8244,10 +8276,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[633],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8256,10 +8288,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[913],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8268,10 +8300,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[637],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8280,10 +8312,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[912],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8295,7 +8327,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[911],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8307,7 +8339,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[643],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8319,7 +8351,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[910],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8331,7 +8363,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[647],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8343,7 +8375,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[909],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8355,7 +8387,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[651],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8367,7 +8399,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[835],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8379,7 +8411,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[655],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8391,7 +8423,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[907],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8415,7 +8447,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[3],
/* parameters */ &kParameters[904],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8427,7 +8459,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[3],
/* parameters */ &kParameters[903],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8439,7 +8471,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[3],
/* parameters */ &kParameters[902],
- /* return matcher indices */ &kMatcherIndices[104],
+ /* return matcher indices */ &kMatcherIndices[110],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8451,7 +8483,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[901],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8460,10 +8492,10 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -8472,10 +8504,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[955],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -8484,10 +8516,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[956],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecSplat,
},
@@ -8496,10 +8528,10 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[399],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorS,
},
@@ -8508,10 +8540,10 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[564],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorM,
},
@@ -8520,10 +8552,10 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[573],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorM,
},
@@ -8532,10 +8564,10 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[576],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorM,
},
@@ -8544,10 +8576,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[605],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorM,
},
@@ -8556,10 +8588,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[603],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorM,
},
@@ -8568,10 +8600,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[601],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorM,
},
@@ -8580,10 +8612,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1003],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -8592,10 +8624,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[965],
- /* return matcher indices */ &kMatcherIndices[140],
+ /* return matcher indices */ &kMatcherIndices[150],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -8604,10 +8636,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[6],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[966],
- /* return matcher indices */ &kMatcherIndices[144],
+ /* return matcher indices */ &kMatcherIndices[156],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -8616,10 +8648,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[6],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[967],
- /* return matcher indices */ &kMatcherIndices[150],
+ /* return matcher indices */ &kMatcherIndices[158],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -8628,10 +8660,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[8],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[968],
- /* return matcher indices */ &kMatcherIndices[154],
+ /* return matcher indices */ &kMatcherIndices[160],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -8643,7 +8675,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[510],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -8655,7 +8687,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[507],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -8667,7 +8699,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[351],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -8679,7 +8711,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[347],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -8691,7 +8723,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[230],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -8703,7 +8735,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[495],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -8715,7 +8747,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[331],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -8727,7 +8759,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[489],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -8739,7 +8771,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[327],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -8823,7 +8855,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[315],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8835,7 +8867,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[265],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8847,7 +8879,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[260],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8859,7 +8891,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[132],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8871,7 +8903,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[299],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8883,7 +8915,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[205],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8895,7 +8927,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[295],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8907,7 +8939,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[285],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8991,7 +9023,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[471],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9000,10 +9032,10 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[431],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9012,10 +9044,10 @@
/* num parameters */ 5,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[250],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9024,10 +9056,10 @@
/* num parameters */ 5,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[215],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9036,10 +9068,10 @@
/* num parameters */ 6,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[96],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9048,10 +9080,10 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[407],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9060,10 +9092,10 @@
/* num parameters */ 5,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[170],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9075,7 +9107,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[558],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9087,7 +9119,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[387],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9099,7 +9131,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[379],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9111,7 +9143,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[160],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9123,7 +9155,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[585],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9135,7 +9167,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[375],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9288,10 +9320,10 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[108],
+ /* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -9300,10 +9332,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[944],
- /* return matcher indices */ &kMatcherIndices[108],
+ /* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -9312,10 +9344,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[945],
- /* return matcher indices */ &kMatcherIndices[108],
+ /* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecSplat,
},
@@ -9324,10 +9356,10 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[588],
- /* return matcher indices */ &kMatcherIndices[108],
+ /* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorS,
},
@@ -9336,10 +9368,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[609],
- /* return matcher indices */ &kMatcherIndices[108],
+ /* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorM,
},
@@ -9348,10 +9380,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[607],
- /* return matcher indices */ &kMatcherIndices[108],
+ /* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorM,
},
@@ -9360,10 +9392,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[949],
- /* return matcher indices */ &kMatcherIndices[100],
+ /* return matcher indices */ &kMatcherIndices[104],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9372,10 +9404,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[950],
- /* return matcher indices */ &kMatcherIndices[102],
+ /* return matcher indices */ &kMatcherIndices[108],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9384,10 +9416,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[6],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[951],
- /* return matcher indices */ &kMatcherIndices[104],
+ /* return matcher indices */ &kMatcherIndices[110],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9396,10 +9428,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[6],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[952],
- /* return matcher indices */ &kMatcherIndices[110],
+ /* return matcher indices */ &kMatcherIndices[114],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9408,10 +9440,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[8],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[953],
- /* return matcher indices */ &kMatcherIndices[112],
+ /* return matcher indices */ &kMatcherIndices[118],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9420,7 +9452,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[880],
/* return matcher indices */ &kMatcherIndices[34],
@@ -9432,7 +9464,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[879],
/* return matcher indices */ &kMatcherIndices[34],
@@ -9444,7 +9476,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[878],
/* return matcher indices */ &kMatcherIndices[34],
@@ -9456,7 +9488,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[877],
/* return matcher indices */ &kMatcherIndices[34],
@@ -9468,7 +9500,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[876],
/* return matcher indices */ &kMatcherIndices[34],
@@ -9480,7 +9512,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[875],
/* return matcher indices */ &kMatcherIndices[34],
@@ -9540,7 +9572,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[727],
/* return matcher indices */ &kMatcherIndices[1],
@@ -9552,7 +9584,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[725],
/* return matcher indices */ &kMatcherIndices[30],
@@ -9564,7 +9596,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[723],
/* return matcher indices */ &kMatcherIndices[30],
@@ -9576,7 +9608,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[721],
/* return matcher indices */ &kMatcherIndices[30],
@@ -9648,10 +9680,10 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[522],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9660,10 +9692,10 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[528],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9672,10 +9704,10 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[363],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9684,10 +9716,10 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[531],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9696,10 +9728,10 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[549],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9747,7 +9779,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[783],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9756,10 +9788,10 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[106],
+ /* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -9768,10 +9800,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[935],
- /* return matcher indices */ &kMatcherIndices[106],
+ /* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -9780,10 +9812,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[936],
- /* return matcher indices */ &kMatcherIndices[106],
+ /* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecSplat,
},
@@ -9792,10 +9824,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[611],
- /* return matcher indices */ &kMatcherIndices[106],
+ /* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecCtorS,
},
@@ -9804,10 +9836,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[938],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* return matcher indices */ &kMatcherIndices[134],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9816,10 +9848,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[939],
- /* return matcher indices */ &kMatcherIndices[126],
+ /* return matcher indices */ &kMatcherIndices[132],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9828,10 +9860,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[6],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[940],
- /* return matcher indices */ &kMatcherIndices[124],
+ /* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9840,10 +9872,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[6],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[941],
- /* return matcher indices */ &kMatcherIndices[122],
+ /* return matcher indices */ &kMatcherIndices[128],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9852,10 +9884,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[8],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[942],
- /* return matcher indices */ &kMatcherIndices[116],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9867,7 +9899,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[180],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9879,7 +9911,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[108],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9891,7 +9923,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[102],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9903,7 +9935,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[65],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9915,7 +9947,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[235],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9927,7 +9959,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[78],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9939,7 +9971,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[245],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9951,7 +9983,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[120],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9963,7 +9995,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[343],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9975,7 +10007,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[225],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9987,7 +10019,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[150],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9999,7 +10031,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[144],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10011,7 +10043,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[439],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10023,7 +10055,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[200],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10035,7 +10067,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[435],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10047,7 +10079,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[280],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10059,7 +10091,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[218],
+ /* return matcher indices */ &kMatcherIndices[224],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -10071,7 +10103,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[922],
- /* return matcher indices */ &kMatcherIndices[218],
+ /* return matcher indices */ &kMatcherIndices[224],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -10083,7 +10115,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[0],
- /* return matcher indices */ &kMatcherIndices[218],
+ /* return matcher indices */ &kMatcherIndices[224],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorS,
},
@@ -10095,7 +10127,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[443],
- /* return matcher indices */ &kMatcherIndices[218],
+ /* return matcher indices */ &kMatcherIndices[224],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorV,
},
@@ -10104,10 +10136,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[908],
- /* return matcher indices */ &kMatcherIndices[222],
+ /* return matcher indices */ &kMatcherIndices[228],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10116,10 +10148,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[906],
- /* return matcher indices */ &kMatcherIndices[220],
+ /* return matcher indices */ &kMatcherIndices[226],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10203,7 +10235,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[172],
+ /* return matcher indices */ &kMatcherIndices[176],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -10215,7 +10247,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[982],
- /* return matcher indices */ &kMatcherIndices[172],
+ /* return matcher indices */ &kMatcherIndices[176],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -10227,7 +10259,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[57],
- /* return matcher indices */ &kMatcherIndices[172],
+ /* return matcher indices */ &kMatcherIndices[176],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorS,
},
@@ -10239,7 +10271,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[593],
- /* return matcher indices */ &kMatcherIndices[172],
+ /* return matcher indices */ &kMatcherIndices[176],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorV,
},
@@ -10248,10 +10280,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[985],
- /* return matcher indices */ &kMatcherIndices[176],
+ /* return matcher indices */ &kMatcherIndices[180],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10260,10 +10292,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[986],
- /* return matcher indices */ &kMatcherIndices[174],
+ /* return matcher indices */ &kMatcherIndices[178],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10275,7 +10307,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[156],
+ /* return matcher indices */ &kMatcherIndices[162],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -10287,7 +10319,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[970],
- /* return matcher indices */ &kMatcherIndices[156],
+ /* return matcher indices */ &kMatcherIndices[162],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -10299,7 +10331,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[411],
- /* return matcher indices */ &kMatcherIndices[156],
+ /* return matcher indices */ &kMatcherIndices[162],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorS,
},
@@ -10311,7 +10343,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[597],
- /* return matcher indices */ &kMatcherIndices[156],
+ /* return matcher indices */ &kMatcherIndices[162],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorV,
},
@@ -10320,10 +10352,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[973],
- /* return matcher indices */ &kMatcherIndices[162],
+ /* return matcher indices */ &kMatcherIndices[166],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10332,10 +10364,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[974],
- /* return matcher indices */ &kMatcherIndices[158],
+ /* return matcher indices */ &kMatcherIndices[164],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10419,7 +10451,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[367],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10431,7 +10463,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[185],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10443,7 +10475,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[190],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10455,7 +10487,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[126],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10467,7 +10499,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[355],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10479,7 +10511,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[210],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10491,7 +10523,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[164],
+ /* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -10503,7 +10535,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[976],
- /* return matcher indices */ &kMatcherIndices[164],
+ /* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -10515,7 +10547,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[84],
- /* return matcher indices */ &kMatcherIndices[164],
+ /* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorS,
},
@@ -10527,7 +10559,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[595],
- /* return matcher indices */ &kMatcherIndices[164],
+ /* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorV,
},
@@ -10536,10 +10568,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[979],
- /* return matcher indices */ &kMatcherIndices[170],
+ /* return matcher indices */ &kMatcherIndices[174],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10548,10 +10580,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[980],
- /* return matcher indices */ &kMatcherIndices[168],
+ /* return matcher indices */ &kMatcherIndices[170],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10563,7 +10595,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[194],
+ /* return matcher indices */ &kMatcherIndices[198],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -10575,7 +10607,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[987],
- /* return matcher indices */ &kMatcherIndices[194],
+ /* return matcher indices */ &kMatcherIndices[198],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -10587,7 +10619,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[49],
- /* return matcher indices */ &kMatcherIndices[194],
+ /* return matcher indices */ &kMatcherIndices[198],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorS,
},
@@ -10599,7 +10631,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[415],
- /* return matcher indices */ &kMatcherIndices[194],
+ /* return matcher indices */ &kMatcherIndices[198],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorV,
},
@@ -10608,10 +10640,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[969],
- /* return matcher indices */ &kMatcherIndices[198],
+ /* return matcher indices */ &kMatcherIndices[202],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10620,10 +10652,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[954],
- /* return matcher indices */ &kMatcherIndices[196],
+ /* return matcher indices */ &kMatcherIndices[200],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10635,7 +10667,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[200],
+ /* return matcher indices */ &kMatcherIndices[204],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -10647,7 +10679,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[943],
- /* return matcher indices */ &kMatcherIndices[200],
+ /* return matcher indices */ &kMatcherIndices[204],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -10659,7 +10691,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[16],
- /* return matcher indices */ &kMatcherIndices[200],
+ /* return matcher indices */ &kMatcherIndices[204],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorS,
},
@@ -10671,7 +10703,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[391],
- /* return matcher indices */ &kMatcherIndices[200],
+ /* return matcher indices */ &kMatcherIndices[204],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorV,
},
@@ -10680,10 +10712,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[928],
- /* return matcher indices */ &kMatcherIndices[212],
+ /* return matcher indices */ &kMatcherIndices[218],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10692,10 +10724,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[925],
- /* return matcher indices */ &kMatcherIndices[210],
+ /* return matcher indices */ &kMatcherIndices[216],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10707,7 +10739,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[96],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -10719,7 +10751,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1000],
- /* return matcher indices */ &kMatcherIndices[96],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -10731,7 +10763,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[28],
- /* return matcher indices */ &kMatcherIndices[96],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorS,
},
@@ -10743,7 +10775,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[468],
- /* return matcher indices */ &kMatcherIndices[96],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorV,
},
@@ -10752,10 +10784,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[999],
- /* return matcher indices */ &kMatcherIndices[192],
+ /* return matcher indices */ &kMatcherIndices[196],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10764,10 +10796,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[993],
- /* return matcher indices */ &kMatcherIndices[190],
+ /* return matcher indices */ &kMatcherIndices[194],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10779,7 +10811,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[184],
+ /* return matcher indices */ &kMatcherIndices[188],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -10791,7 +10823,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[994],
- /* return matcher indices */ &kMatcherIndices[184],
+ /* return matcher indices */ &kMatcherIndices[188],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -10803,7 +10835,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[40],
- /* return matcher indices */ &kMatcherIndices[184],
+ /* return matcher indices */ &kMatcherIndices[188],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorS,
},
@@ -10815,7 +10847,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[582],
- /* return matcher indices */ &kMatcherIndices[184],
+ /* return matcher indices */ &kMatcherIndices[188],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorV,
},
@@ -10824,10 +10856,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[997],
- /* return matcher indices */ &kMatcherIndices[188],
+ /* return matcher indices */ &kMatcherIndices[192],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10836,10 +10868,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[998],
- /* return matcher indices */ &kMatcherIndices[186],
+ /* return matcher indices */ &kMatcherIndices[190],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10851,7 +10883,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[178],
+ /* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -10863,7 +10895,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[988],
- /* return matcher indices */ &kMatcherIndices[178],
+ /* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -10875,7 +10907,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[114],
- /* return matcher indices */ &kMatcherIndices[178],
+ /* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorS,
},
@@ -10887,7 +10919,7 @@
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[579],
- /* return matcher indices */ &kMatcherIndices[178],
+ /* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatCtorV,
},
@@ -10896,10 +10928,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[991],
- /* return matcher indices */ &kMatcherIndices[182],
+ /* return matcher indices */ &kMatcherIndices[186],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10908,10 +10940,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[992],
- /* return matcher indices */ &kMatcherIndices[180],
+ /* return matcher indices */ &kMatcherIndices[184],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10920,7 +10952,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[737],
/* return matcher indices */ &kMatcherIndices[1],
@@ -10932,7 +10964,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[735],
/* return matcher indices */ &kMatcherIndices[30],
@@ -10944,7 +10976,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[733],
/* return matcher indices */ &kMatcherIndices[30],
@@ -10956,7 +10988,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[731],
/* return matcher indices */ &kMatcherIndices[30],
@@ -10980,7 +11012,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[885],
/* return matcher indices */ &kMatcherIndices[34],
@@ -10992,7 +11024,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[884],
/* return matcher indices */ &kMatcherIndices[34],
@@ -11040,67 +11072,67 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[749],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::OpPlus,
},
{
/* [243] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[747],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::OpPlus,
},
{
/* [244] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[745],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::OpPlus,
},
{
/* [245] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[743],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::OpPlus,
},
{
/* [246] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[741],
/* return matcher indices */ &kMatcherIndices[10],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::OpPlus,
},
{
/* [247] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[701],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11112,7 +11144,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[699],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11124,7 +11156,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[695],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11136,7 +11168,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[693],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11172,7 +11204,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[683],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11184,7 +11216,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[681],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11220,7 +11252,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[675],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11232,7 +11264,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[673],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11244,7 +11276,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[709],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11256,7 +11288,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[707],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11268,7 +11300,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[705],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11280,7 +11312,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[781],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11316,7 +11348,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[921],
/* return matcher indices */ &kMatcherIndices[34],
@@ -11352,7 +11384,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[19],
+ /* template types */ &kTemplateTypes[20],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[933],
/* return matcher indices */ &kMatcherIndices[16],
@@ -11367,7 +11399,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1004],
- /* return matcher indices */ &kMatcherIndices[103],
+ /* return matcher indices */ &kMatcherIndices[109],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -11379,7 +11411,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[929],
- /* return matcher indices */ &kMatcherIndices[103],
+ /* return matcher indices */ &kMatcherIndices[109],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -11388,10 +11420,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[21],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[930],
- /* return matcher indices */ &kMatcherIndices[103],
+ /* return matcher indices */ &kMatcherIndices[109],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -11424,7 +11456,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[21],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[927],
/* return matcher indices */ &kMatcherIndices[4],
@@ -11436,7 +11468,7 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[540],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11448,7 +11480,7 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[543],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11460,7 +11492,7 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[546],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11496,7 +11528,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[924],
/* return matcher indices */ &kMatcherIndices[35],
@@ -11544,7 +11576,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[860],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11556,7 +11588,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[861],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11566,24 +11598,24 @@
{
/* [286] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[26],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[798],
- /* return matcher indices */ &kMatcherIndices[233],
+ /* return matcher indices */ &kMatcherIndices[172],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [287] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[26],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[810],
- /* return matcher indices */ &kMatcherIndices[166],
+ /* return matcher indices */ &kMatcherIndices[78],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11664,7 +11696,7 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[423],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11676,7 +11708,7 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[427],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11808,7 +11840,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[763],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11820,7 +11852,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[761],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11832,7 +11864,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[759],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11844,7 +11876,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[757],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11878,24 +11910,24 @@
{
/* [312] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[26],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[855],
- /* return matcher indices */ &kMatcherIndices[232],
+ /* return matcher indices */ &kMatcherIndices[136],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [313] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[26],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[856],
- /* return matcher indices */ &kMatcherIndices[130],
+ /* return matcher indices */ &kMatcherIndices[96],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11952,7 +11984,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[806],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11964,7 +11996,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[805],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11976,7 +12008,7 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[459],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11988,7 +12020,7 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[456],
/* return matcher indices */ &kMatcherIndices[30],
@@ -12144,7 +12176,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[889],
/* return matcher indices */ &kMatcherIndices[1],
@@ -12156,7 +12188,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[890],
/* return matcher indices */ &kMatcherIndices[30],
@@ -12360,7 +12392,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[804],
/* return matcher indices */ &kMatcherIndices[1],
@@ -12372,7 +12404,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[803],
/* return matcher indices */ &kMatcherIndices[30],
@@ -12504,7 +12536,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[619],
/* return matcher indices */ &kMatcherIndices[1],
@@ -12516,7 +12548,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[615],
/* return matcher indices */ &kMatcherIndices[30],
@@ -12552,7 +12584,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[635],
/* return matcher indices */ &kMatcherIndices[16],
@@ -12564,7 +12596,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[631],
/* return matcher indices */ &kMatcherIndices[39],
@@ -12576,7 +12608,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[641],
/* return matcher indices */ &kMatcherIndices[16],
@@ -12588,7 +12620,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[639],
/* return matcher indices */ &kMatcherIndices[39],
@@ -12600,7 +12632,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[649],
/* return matcher indices */ &kMatcherIndices[16],
@@ -12612,7 +12644,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[645],
/* return matcher indices */ &kMatcherIndices[39],
@@ -12672,7 +12704,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[1002],
/* return matcher indices */ &kMatcherIndices[1],
@@ -12684,7 +12716,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[996],
/* return matcher indices */ &kMatcherIndices[30],
@@ -12696,7 +12728,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[832],
/* return matcher indices */ &kMatcherIndices[1],
@@ -12708,7 +12740,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[831],
/* return matcher indices */ &kMatcherIndices[30],
@@ -12720,7 +12752,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[834],
/* return matcher indices */ &kMatcherIndices[1],
@@ -12732,7 +12764,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[833],
/* return matcher indices */ &kMatcherIndices[30],
@@ -12744,7 +12776,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[17],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[870],
/* return matcher indices */ &kMatcherIndices[34],
@@ -12768,7 +12800,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[837],
/* return matcher indices */ &kMatcherIndices[1],
@@ -12780,7 +12812,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[836],
/* return matcher indices */ &kMatcherIndices[30],
@@ -12792,7 +12824,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[657],
/* return matcher indices */ &kMatcherIndices[16],
@@ -12804,7 +12836,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[653],
/* return matcher indices */ &kMatcherIndices[39],
@@ -12960,7 +12992,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[659],
/* return matcher indices */ &kMatcherIndices[16],
@@ -12972,7 +13004,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[599],
/* return matcher indices */ &kMatcherIndices[39],
@@ -12984,7 +13016,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[663],
/* return matcher indices */ &kMatcherIndices[16],
@@ -12996,7 +13028,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[15],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[661],
/* return matcher indices */ &kMatcherIndices[39],
@@ -13056,7 +13088,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[691],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13068,7 +13100,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[689],
/* return matcher indices */ &kMatcherIndices[30],
@@ -13200,7 +13232,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[862],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13212,7 +13244,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[863],
/* return matcher indices */ &kMatcherIndices[30],
@@ -13248,7 +13280,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[627],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13260,7 +13292,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[623],
/* return matcher indices */ &kMatcherIndices[30],
@@ -13272,10 +13304,10 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[561],
- /* return matcher indices */ &kMatcherIndices[202],
+ /* return matcher indices */ &kMatcherIndices[206],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -13284,7 +13316,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[753],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13296,7 +13328,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[755],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13308,7 +13340,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[765],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13320,7 +13352,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[767],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13332,7 +13364,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[769],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13344,7 +13376,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[771],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13356,7 +13388,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[773],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13368,7 +13400,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[775],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13404,7 +13436,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[591],
/* return matcher indices */ nullptr,
@@ -13416,7 +13448,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[9],
/* parameters */ &kParameters[847],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13455,7 +13487,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[937],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -13467,7 +13499,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[947],
- /* return matcher indices */ &kMatcherIndices[120],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -13479,7 +13511,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[948],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* return matcher indices */ &kMatcherIndices[134],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -13491,7 +13523,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[961],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* return matcher indices */ &kMatcherIndices[134],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -13503,7 +13535,7 @@
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[962],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* return matcher indices */ &kMatcherIndices[134],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -13611,7 +13643,7 @@
/* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[785],
- /* return matcher indices */ &kMatcherIndices[108],
+ /* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -13656,7 +13688,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[791],
/* return matcher indices */ &kMatcherIndices[1],
@@ -13680,7 +13712,7 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[18],
+ /* template types */ &kTemplateTypes[19],
/* template numbers */ &kTemplateNumbers[8],
/* parameters */ &kParameters[960],
/* return matcher indices */ &kMatcherIndices[35],
@@ -13977,8 +14009,8 @@
},
{
/* [40] */
- /* fn frexp(f32) -> __frexp_result */
- /* fn frexp<N : num>(vec<N, f32>) -> __frexp_result_vec<N> */
+ /* fn frexp<T : f32_f16>(T) -> __frexp_result<T> */
+ /* fn frexp<N : num, T : f32_f16>(vec<N, T>) -> __frexp_result_vec<N, T> */
/* num overloads */ 2,
/* overloads */ &kOverloads[286],
},
@@ -14069,8 +14101,8 @@
},
{
/* [53] */
- /* fn modf(f32) -> __modf_result */
- /* fn modf<N : num>(vec<N, f32>) -> __modf_result_vec<N> */
+ /* fn modf<T : f32_f16>(T) -> __modf_result<T> */
+ /* fn modf<N : num, T : f32_f16>(vec<N, T>) -> __modf_result_vec<N, T> */
/* num overloads */ 2,
/* overloads */ &kOverloads[312],
},
@@ -14578,11 +14610,11 @@
constexpr IntrinsicInfo kBinaryOperators[] = {
{
/* [0] */
- /* op +<T : fiu32_f16>(T, T) -> T */
- /* op +<T : fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
- /* op +<T : fiu32_f16, N : num>(vec<N, T>, T) -> vec<N, T> */
- /* op +<T : fiu32_f16, N : num>(T, vec<N, T>) -> vec<N, T> */
- /* op +<T : f32_f16, N : num, M : num>(mat<N, M, T>, mat<N, M, T>) -> mat<N, M, T> */
+ /* op +<T : fia_fiu32_f16>(T, T) -> T */
+ /* op +<T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
+ /* op +<T : fia_fiu32_f16, N : num>(vec<N, T>, T) -> vec<N, T> */
+ /* op +<T : fia_fiu32_f16, N : num>(T, vec<N, T>) -> vec<N, T> */
+ /* op +<T : fa_f32_f16, N : num, M : num>(mat<N, M, T>, mat<N, M, T>) -> mat<N, M, T> */
/* num overloads */ 5,
/* overloads */ &kOverloads[242],
},
diff --git a/src/tint/resolver/intrinsic_table_test.cc b/src/tint/resolver/intrinsic_table_test.cc
index 9301386..02c97f7 100644
--- a/src/tint/resolver/intrinsic_table_test.cc
+++ b/src/tint/resolver/intrinsic_table_test.cc
@@ -886,20 +886,21 @@
IntrinsicTableAbstractBinaryTest,
testing::Values( // clang-format off
// result | param lhs | param rhs | arg lhs | arg rhs
-Case::Create<f32, f32, f32, AFloat, AFloat>(),
-Case::Create<f32, f32, f32, AFloat, AInt>(),
-Case::Create<f32, f32, f32, AInt, AFloat>(),
-Case::Create<i32, i32, i32, AInt, AInt>()
+Case::Create<AFloat, AFloat, AFloat, AFloat, AFloat>(),
+Case::Create<AFloat, AFloat, AFloat, AFloat, AInt>(),
+Case::Create<AFloat, AFloat, AFloat, AInt, AFloat>(),
+Case::Create<AInt, AInt, AInt, AInt, AInt>()
)); // clang-format on
-INSTANTIATE_TEST_SUITE_P(VecAFloat_VecAInt,
- IntrinsicTableAbstractBinaryTest,
- testing::Values( // clang-format off
+INSTANTIATE_TEST_SUITE_P(
+ VecAFloat_VecAInt,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
// result | param lhs | param rhs | arg lhs | arg rhs
-Case::Create<f32V, f32V, f32V, AFloatV, AFloatV>(),
-Case::Create<f32V, f32V, f32V, AFloatV, AIntV>(),
-Case::Create<f32V, f32V, f32V, AIntV, AFloatV>(),
-Case::Create<i32V, i32V, i32V, AIntV, AIntV>()
+Case::Create<AFloatV, AFloatV, AFloatV, AFloatV, AFloatV>(),
+Case::Create<AFloatV, AFloatV, AFloatV, AFloatV, AIntV>(),
+Case::Create<AFloatV, AFloatV, AFloatV, AIntV, AFloatV>(),
+Case::Create<AIntV, AIntV, AIntV, AIntV, AIntV>()
)); // clang-format on
INSTANTIATE_TEST_SUITE_P(AFloat_f32,
diff --git a/src/tint/resolver/is_storeable_test.cc b/src/tint/resolver/is_storeable_test.cc
index 80c3e20..0423f72 100644
--- a/src/tint/resolver/is_storeable_test.cc
+++ b/src/tint/resolver/is_storeable_test.cc
@@ -99,7 +99,7 @@
}
TEST_F(ResolverIsStorableTest, Struct_AllMembersStorable) {
- Structure("S", {
+ Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
@@ -108,7 +108,7 @@
}
TEST_F(ResolverIsStorableTest, Struct_SomeMembersNonStorable) {
- Structure("S", {
+ Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.pointer<i32>(ast::StorageClass::kPrivate)),
});
@@ -120,11 +120,11 @@
}
TEST_F(ResolverIsStorableTest, Struct_NestedStorable) {
- auto* storable = Structure("Storable", {
+ auto* storable = Structure("Storable", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
- Structure("S", {
+ Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.Of(storable)),
});
@@ -134,11 +134,11 @@
TEST_F(ResolverIsStorableTest, Struct_NestedNonStorable) {
auto* non_storable =
- Structure("nonstorable", {
+ Structure("nonstorable", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.pointer<i32>(ast::StorageClass::kPrivate)),
});
- Structure("S", {
+ Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.Of(non_storable)),
});
diff --git a/src/tint/resolver/materialize_test.cc b/src/tint/resolver/materialize_test.cc
index 70985dd..26f109f 100644
--- a/src/tint/resolver/materialize_test.cc
+++ b/src/tint/resolver/materialize_test.cc
@@ -334,20 +334,20 @@
WrapInFunction(Assign(Phony(), abstract_expr));
break;
case Method::kFnArg:
- Func("F", {Param("P", target_ty())}, ty.void_(), {});
+ Func("F", utils::Vector{Param("P", target_ty())}, ty.void_(), utils::Empty);
WrapInFunction(CallStmt(Call("F", abstract_expr)));
break;
case Method::kBuiltinArg:
WrapInFunction(CallStmt(Call("min", target_expr(), abstract_expr)));
break;
case Method::kReturn:
- Func("F", {}, target_ty(), {Return(abstract_expr)});
+ Func("F", utils::Empty, target_ty(), utils::Vector{Return(abstract_expr)});
break;
case Method::kArray:
WrapInFunction(Construct(ty.array(target_ty(), 1_i), abstract_expr));
break;
case Method::kStruct:
- Structure("S", {Member("v", target_ty())});
+ Structure("S", utils::Vector{Member("v", target_ty())});
WrapInFunction(Construct(ty.type_name("S"), abstract_expr));
break;
case Method::kBinaryOp:
@@ -376,9 +376,9 @@
DefaultCase()));
break;
case Method::kWorkgroupSize:
- Func("f", {}, ty.void_(), {},
- {WorkgroupSize(target_expr(), abstract_expr, Expr(123_a)),
- Stage(ast::PipelineStage::kCompute)});
+ Func("f", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{WorkgroupSize(target_expr(), abstract_expr, Expr(123_a)),
+ Stage(ast::PipelineStage::kCompute)});
break;
case Method::kRuntimeIndex:
auto* runtime_index = Var("runtime_index", nullptr, Expr(1_i));
@@ -464,9 +464,10 @@
/// Methods that do not materialize
constexpr Method kNoMaterializeMethods[] = {
- Method::kPhonyAssign,
- // TODO(crbug.com/tint/1504): Enable once we have abstract overloads of builtins / binary
- // ops: Method::kBuiltinArg, Method::kBinaryOp,
+ Method::kPhonyAssign, //
+ Method::kBinaryOp,
+ // TODO(crbug.com/tint/1504): Enable once "min" supports const evaluation
+ // Method::kBuiltinArg,
};
INSTANTIATE_TEST_SUITE_P(
MaterializeScalar,
@@ -863,10 +864,10 @@
const auto& method = std::get<1>(param);
const auto& data = std::get<2>(param);
- ast::ExpressionList abstract_exprs;
+ utils::Vector<const ast::Expression*, 4> abstract_exprs;
auto abstract_expr = [&] {
auto* expr = data.abstract_expr(*this, data.literal_value);
- abstract_exprs.emplace_back(expr);
+ abstract_exprs.Push(expr);
return expr;
};
switch (method) {
@@ -894,8 +895,9 @@
DefaultCase()));
break;
case Method::kWorkgroupSize:
- Func("f", {}, ty.void_(), {},
- {WorkgroupSize(abstract_expr()), Stage(ast::PipelineStage::kCompute)});
+ Func(
+ "f", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{WorkgroupSize(abstract_expr()), Stage(ast::PipelineStage::kCompute)});
break;
case Method::kIndex:
GlobalVar("arr", ty.array<i32, 4>(), ast::StorageClass::kPrivate);
@@ -1163,7 +1165,7 @@
using MaterializeAbstractNumericToUnrelatedType = resolver::ResolverTest;
TEST_F(MaterializeAbstractNumericToUnrelatedType, AIntToStructVarCtor) {
- Structure("S", {Member("a", ty.i32())});
+ Structure("S", utils::Vector{Member("a", ty.i32())});
WrapInFunction(Decl(Var("v", ty.type_name("S"), Expr(Source{{12, 34}}, 1_a))));
EXPECT_FALSE(r()->Resolve());
EXPECT_THAT(
@@ -1172,7 +1174,7 @@
}
TEST_F(MaterializeAbstractNumericToUnrelatedType, AIntToStructLetCtor) {
- Structure("S", {Member("a", ty.i32())});
+ Structure("S", utils::Vector{Member("a", ty.i32())});
WrapInFunction(Decl(Let("v", ty.type_name("S"), Expr(Source{{12, 34}}, 1_a))));
EXPECT_FALSE(r()->Resolve());
EXPECT_THAT(
diff --git a/src/tint/resolver/override_test.cc b/src/tint/resolver/override_test.cc
index f1e13e9..2615d73 100644
--- a/src/tint/resolver/override_test.cc
+++ b/src/tint/resolver/override_test.cc
@@ -50,7 +50,7 @@
}
TEST_F(ResolverOverrideTest, WithId) {
- auto* a = Override("a", ty.f32(), Expr(1_f), {Id(7u)});
+ auto* a = Override("a", ty.f32(), Expr(1_f), utils::Vector{Id(7u)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -69,10 +69,10 @@
std::vector<ast::Variable*> variables;
auto* a = Override("a", ty.f32(), Expr(1_f));
auto* b = Override("b", ty.f32(), Expr(1_f));
- auto* c = Override("c", ty.f32(), Expr(1_f), {Id(2u)});
- auto* d = Override("d", ty.f32(), Expr(1_f), {Id(4u)});
+ auto* c = Override("c", ty.f32(), Expr(1_f), utils::Vector{Id(2u)});
+ auto* d = Override("d", ty.f32(), Expr(1_f), utils::Vector{Id(4u)});
auto* e = Override("e", ty.f32(), Expr(1_f));
- auto* f = Override("f", ty.f32(), Expr(1_f), {Id(1u)});
+ auto* f = Override("f", ty.f32(), Expr(1_f), utils::Vector{Id(1u)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -86,8 +86,8 @@
}
TEST_F(ResolverOverrideTest, DuplicateIds) {
- Override("a", ty.f32(), Expr(1_f), {Id(Source{{12, 34}}, 7u)});
- Override("b", ty.f32(), Expr(1_f), {Id(Source{{56, 78}}, 7u)});
+ Override("a", ty.f32(), Expr(1_f), utils::Vector{Id(Source{{12, 34}}, 7u)});
+ Override("b", ty.f32(), Expr(1_f), utils::Vector{Id(Source{{56, 78}}, 7u)});
EXPECT_FALSE(r()->Resolve());
@@ -96,7 +96,7 @@
}
TEST_F(ResolverOverrideTest, IdTooLarge) {
- Override("a", ty.f32(), Expr(1_f), {Id(Source{{12, 34}}, 65536u)});
+ Override("a", ty.f32(), Expr(1_f), utils::Vector{Id(Source{{12, 34}}, 65536u)});
EXPECT_FALSE(r()->Resolve());
@@ -106,7 +106,7 @@
TEST_F(ResolverOverrideTest, F16_TemporallyBan) {
Enable(ast::Extension::kF16);
- Override(Source{{12, 34}}, "a", ty.f16(), Expr(1_h), {Id(1u)});
+ Override(Source{{12, 34}}, "a", ty.f16(), Expr(1_h), utils::Vector{Id(1u)});
EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/ptr_ref_test.cc b/src/tint/resolver/ptr_ref_test.cc
index 037c6ff..0a757b4 100644
--- a/src/tint/resolver/ptr_ref_test.cc
+++ b/src/tint/resolver/ptr_ref_test.cc
@@ -57,17 +57,17 @@
TEST_F(ResolverPtrRefTest, DefaultPtrStorageClass) {
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
- auto* buf = Structure("S", {Member("m", ty.i32())});
+ auto* buf = Structure("S", utils::Vector{Member("m", ty.i32())});
auto* function = Var("f", ty.i32());
auto* private_ = GlobalVar("p", ty.i32(), ast::StorageClass::kPrivate);
auto* workgroup = GlobalVar("w", ty.i32(), ast::StorageClass::kWorkgroup);
auto* uniform = GlobalVar("ub", ty.Of(buf), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
auto* storage = GlobalVar("sb", ty.Of(buf), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(0u),
});
diff --git a/src/tint/resolver/ptr_ref_validation_test.cc b/src/tint/resolver/ptr_ref_validation_test.cc
index 768783b..5de5007 100644
--- a/src/tint/resolver/ptr_ref_validation_test.cc
+++ b/src/tint/resolver/ptr_ref_validation_test.cc
@@ -141,10 +141,10 @@
// fn f() {
// let p : pointer<storage, i32> = &s.inner.arr[2i];
// }
- auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
- auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
+ auto* inner = Structure("Inner", utils::Vector{Member("arr", ty.array<i32, 4>())});
+ auto* buf = Structure("S", utils::Vector{Member("inner", ty.Of(inner))});
auto* storage = GlobalVar("s", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 097d591..2edab1f 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -140,6 +140,7 @@
[&](const ast::TypeDecl* td) { return TypeDecl(td); },
[&](const ast::Function* func) { return Function(func); },
[&](const ast::Variable* var) { return GlobalVariable(var); },
+ [&](const ast::StaticAssert* sa) { return StaticAssert(sa); },
[&](Default) {
TINT_UNREACHABLE(Resolver, diagnostics_)
<< "unhandled global declaration: " << decl->TypeInfo().name;
@@ -159,6 +160,10 @@
return false;
}
+ if (!validator_.PushConstants(entry_points_)) {
+ return false;
+ }
+
if (!enabled_extensions_.contains(ast::Extension::kChromiumDisableUniformityAnalysis)) {
if (!AnalyzeUniformity(builder_, dependencies_)) {
// TODO(jrprice): Reject programs that fail uniformity analysis.
@@ -726,13 +731,40 @@
// TODO(bclayton): Call this at the end of resolve on all uniform and storage
// referenced structs
- if (!validator_.StorageClassLayout(sem, valid_type_storage_layouts_)) {
+ if (!validator_.StorageClassLayout(sem, enabled_extensions_, valid_type_storage_layouts_)) {
return nullptr;
}
return sem;
}
+sem::Statement* Resolver::StaticAssert(const ast::StaticAssert* assertion) {
+ auto* expr = Expression(assertion->condition);
+ if (!expr) {
+ return nullptr;
+ }
+ auto* cond = expr->ConstantValue();
+ if (!cond) {
+ AddError("static assertion condition must be a constant expression",
+ assertion->condition->source);
+ return nullptr;
+ }
+ if (auto* ty = cond->Type(); !ty->Is<sem::Bool>()) {
+ AddError(
+ "static assertion condition must be a bool, got '" + builder_->FriendlyName(ty) + "'",
+ assertion->condition->source);
+ return nullptr;
+ }
+ if (!cond->As<bool>()) {
+ AddError("static assertion failed", assertion->source);
+ return nullptr;
+ }
+ auto* sem =
+ builder_->create<sem::Statement>(assertion, current_compound_statement_, current_function_);
+ builder_->Sem().Add(assertion, sem);
+ return sem;
+}
+
sem::Function* Resolver::Function(const ast::Function* decl) {
uint32_t parameter_index = 0;
std::unordered_map<Symbol, Source> parameter_names;
@@ -988,7 +1020,7 @@
return true;
}
-bool Resolver::Statements(const ast::StatementList& stmts) {
+bool Resolver::Statements(utils::VectorRef<const ast::Statement*> stmts) {
sem::Behaviors behaviors{sem::Behavior::kNext};
bool reachable = true;
@@ -1038,6 +1070,7 @@
[&](const ast::IncrementDecrementStatement* i) { return IncrementDecrementStatement(i); },
[&](const ast::ReturnStatement* r) { return ReturnStatement(r); },
[&](const ast::VariableDeclStatement* v) { return VariableDeclStatement(v); },
+ [&](const ast::StaticAssert* sa) { return StaticAssert(sa); },
// Error cases
[&](const ast::CaseStatement*) {
@@ -1054,7 +1087,7 @@
auto* sem =
builder_->create<sem::CaseStatement>(stmt, current_compound_statement_, current_function_);
return StatementScope(stmt, sem, [&] {
- sem->Selectors().reserve(stmt->selectors.size());
+ sem->Selectors().reserve(stmt->selectors.Length());
for (auto* sel : stmt->selectors) {
auto* expr = Expression(sel);
if (!expr) {
@@ -1243,7 +1276,7 @@
}
sem::Expression* Resolver::Expression(const ast::Expression* root) {
- utils::Vector<const ast::Expression*, 128> sorted;
+ utils::Vector<const ast::Expression*, 64> sorted;
constexpr size_t kMaxExpressionDepth = 512U;
bool failed = false;
if (!ast::TraverseExpressions<ast::TraverseOrder::RightToLeft>(
@@ -1402,7 +1435,8 @@
return m;
}
-bool Resolver::MaterializeArguments(utils::VectorRef<const sem::Expression*> args,
+template <size_t N>
+bool Resolver::MaterializeArguments(utils::Vector<const sem::Expression*, N>& args,
const sem::CallTarget* target) {
for (size_t i = 0, n = std::min(args.Length(), target->Parameters().Length()); i < n; i++) {
const auto* param_ty = target->Parameters()[i]->Type();
@@ -1418,10 +1452,33 @@
}
bool Resolver::ShouldMaterializeArgument(const sem::Type* parameter_ty) const {
- const auto* param_el_ty = sem::Type::ElementOf(parameter_ty);
+ const auto* param_el_ty = sem::Type::DeepestElementOf(parameter_ty);
return param_el_ty && !param_el_ty->Is<sem::AbstractNumeric>();
}
+bool Resolver::Convert(const sem::Constant*& c, const sem::Type* target_ty, const Source& source) {
+ auto r = const_eval_.Convert(target_ty, c, source);
+ if (!r) {
+ return false;
+ }
+ c = r.Get();
+ return true;
+}
+
+template <size_t N>
+utils::Result<utils::Vector<const sem::Constant*, N>> Resolver::ConvertArguments(
+ const utils::Vector<const sem::Expression*, N>& args,
+ const sem::CallTarget* target) {
+ auto const_args = utils::Transform(args, [](auto* arg) { return arg->ConstantValue(); });
+ for (size_t i = 0, n = std::min(args.Length(), target->Parameters().Length()); i < n; i++) {
+ if (!Convert(const_args[i], target->Parameters()[i]->Type(),
+ args[i]->Declaration()->source)) {
+ return utils::Failure;
+ }
+ }
+ return const_args;
+}
+
sem::Expression* Resolver::IndexAccessor(const ast::IndexAccessorExpression* expr) {
auto* idx = Materialize(sem_.Get(expr->index));
if (!idx) {
@@ -1467,7 +1524,12 @@
}
auto stage = sem::EarliestStage(obj->Stage(), idx->Stage());
- auto val = const_eval_.Index(obj, idx);
+ const sem::Constant* val = nullptr;
+ if (auto r = const_eval_.Index(obj, idx)) {
+ val = r.Get();
+ } else {
+ return nullptr;
+ }
bool has_side_effects = idx->HasSideEffects() || obj->HasSideEffects();
auto* sem = builder_->create<sem::IndexAccessorExpression>(
expr, ty, stage, obj, idx, current_statement_, std::move(val), has_side_effects,
@@ -1486,7 +1548,12 @@
return nullptr;
}
- auto val = const_eval_.Bitcast(ty, inner);
+ const sem::Constant* val = nullptr;
+ if (auto r = const_eval_.Bitcast(ty, inner)) {
+ val = r.Get();
+ } else {
+ return nullptr;
+ }
auto stage = sem::EvaluationStage::kRuntime; // TODO(crbug.com/tint/1581)
auto* sem = builder_->create<sem::Expression>(expr, ty, stage, current_statement_,
std::move(val), inner->HasSideEffects());
@@ -1509,10 +1576,10 @@
// Resolve all of the arguments, their types and the set of behaviors.
utils::Vector<const sem::Expression*, 8> args;
- args.Reserve(expr->args.size());
+ args.Reserve(expr->args.Length());
auto args_stage = sem::EvaluationStage::kConstant;
sem::Behaviors arg_behaviors;
- for (size_t i = 0; i < expr->args.size(); i++) {
+ for (size_t i = 0; i < expr->args.Length(); i++) {
auto* arg = sem_.Get(expr->args[i]);
if (!arg) {
return nullptr;
@@ -1541,8 +1608,14 @@
const sem::Constant* value = nullptr;
auto stage = sem::EarliestStage(ctor_or_conv.target->Stage(), args_stage);
if (stage == sem::EvaluationStage::kConstant) {
- value =
- (const_eval_.*ctor_or_conv.const_eval_fn)(ctor_or_conv.target->ReturnType(), args);
+ auto const_args =
+ utils::Transform(args, [](auto* arg) { return arg->ConstantValue(); });
+ if (auto r = (const_eval_.*ctor_or_conv.const_eval_fn)(
+ ctor_or_conv.target->ReturnType(), const_args, expr->source)) {
+ value = r.Get();
+ } else {
+ return nullptr;
+ }
}
return builder_->create<sem::Call>(expr, ctor_or_conv.target, stage, std::move(args),
current_statement_, value, has_side_effects);
@@ -1559,7 +1632,11 @@
auto stage = args_stage; // The evaluation stage of the call
const sem::Constant* value = nullptr; // The constant value for the call
if (stage == sem::EvaluationStage::kConstant) {
- value = const_eval_.ArrayOrStructCtor(ty, args);
+ if (auto r = const_eval_.ArrayOrStructCtor(ty, args)) {
+ value = r.Get();
+ } else {
+ return nullptr;
+ }
if (!value) {
// Constant evaluation failed.
// Can happen for expressions that will fail validation (later).
@@ -1774,9 +1851,7 @@
// there's no need to infer element types.
return ty_ctor_or_conv(ty);
},
- [&](sem::Function* func) {
- return FunctionCall(expr, func, std::move(args), arg_behaviors);
- },
+ [&](sem::Function* func) { return FunctionCall(expr, func, args, arg_behaviors); },
[&](sem::Variable* var) {
auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
AddError("cannot call variable '" + name + "'", ident->source);
@@ -1787,7 +1862,7 @@
auto name = builder_->Symbols().NameFor(ident->symbol);
auto builtin_type = sem::ParseBuiltinType(name);
if (builtin_type != sem::BuiltinType::kNone) {
- return BuiltinCall(expr, builtin_type, std::move(args));
+ return BuiltinCall(expr, builtin_type, args);
}
TINT_ICE(Resolver, diagnostics_)
@@ -1805,12 +1880,13 @@
return validator_.Call(call, current_statement_) ? call : nullptr;
}
+template <size_t N>
sem::Call* Resolver::BuiltinCall(const ast::CallExpression* expr,
sem::BuiltinType builtin_type,
- utils::VectorRef<const sem::Expression*> args) {
+ utils::Vector<const sem::Expression*, N>& args) {
IntrinsicTable::Builtin builtin;
{
- auto arg_tys = utils::Transform<8>(args, [](auto* arg) { return arg->Type(); });
+ auto arg_tys = utils::Transform(args, [](auto* arg) { return arg->Type(); });
builtin = intrinsic_table_->Lookup(builtin_type, arg_tys, expr->source);
if (!builtin.sem) {
return nullptr;
@@ -1840,7 +1916,16 @@
// If the builtin is @const, and all arguments have constant values, evaluate the builtin now.
const sem::Constant* value = nullptr;
if (stage == sem::EvaluationStage::kConstant) {
- value = (const_eval_.*builtin.const_eval_fn)(builtin.sem->ReturnType(), args);
+ auto const_args = ConvertArguments(args, builtin.sem);
+ if (!const_args) {
+ return nullptr;
+ }
+ if (auto r = (const_eval_.*builtin.const_eval_fn)(builtin.sem->ReturnType(),
+ const_args.Get(), expr->source)) {
+ value = r.Get();
+ } else {
+ return nullptr;
+ }
}
bool has_side_effects =
@@ -1872,9 +1957,8 @@
return call;
}
-void Resolver::CollectTextureSamplerPairs(
- const sem::Builtin* builtin,
- utils::ConstVectorRef<const sem::Expression*> args) const {
+void Resolver::CollectTextureSamplerPairs(const sem::Builtin* builtin,
+ utils::VectorRef<const sem::Expression*> args) const {
// Collect a texture/sampler pair for this builtin.
const auto& signature = builtin->Signature();
int texture_index = signature.IndexOf(sem::ParameterUsage::kTexture);
@@ -1892,9 +1976,10 @@
}
}
+template <size_t N>
sem::Call* Resolver::FunctionCall(const ast::CallExpression* expr,
sem::Function* target,
- utils::VectorRef<const sem::Expression*> args,
+ utils::Vector<const sem::Expression*, N>& args,
sem::Behaviors arg_behaviors) {
auto sym = expr->target.name->symbol;
auto name = builder_->Symbols().NameFor(sym);
@@ -1940,9 +2025,8 @@
return call;
}
-void Resolver::CollectTextureSamplerPairs(
- sem::Function* func,
- utils::ConstVectorRef<const sem::Expression*> args) const {
+void Resolver::CollectTextureSamplerPairs(sem::Function* func,
+ utils::VectorRef<const sem::Expression*> args) const {
// Map all texture/sampler pairs from the target function to the
// current function. These can only be global or parameter
// variables. Resolve any parameter variables to the corresponding
@@ -2003,7 +2087,12 @@
return nullptr;
}
- auto val = const_eval_.Literal(ty, literal);
+ const sem::Constant* val = nullptr;
+ if (auto r = const_eval_.Literal(ty, literal)) {
+ val = r.Get();
+ } else {
+ return nullptr;
+ }
return builder_->create<sem::Expression>(literal, ty, sem::EvaluationStage::kConstant,
current_statement_, std::move(val),
/* has_side_effects */ false);
@@ -2124,7 +2213,12 @@
ret = builder_->create<sem::Reference>(ret, ref->StorageClass(), ref->Access());
}
- auto* val = const_eval_.MemberAccess(object, member);
+ const sem::Constant* val = nullptr;
+ if (auto r = const_eval_.MemberAccess(object, member)) {
+ val = r.Get();
+ } else {
+ return nullptr;
+ }
return builder_->create<sem::StructMemberAccess>(expr, ret, current_statement_, val, object,
member, has_side_effects, source_var);
}
@@ -2192,9 +2286,12 @@
// the swizzle.
ret = builder_->create<sem::Vector>(vec->type(), static_cast<uint32_t>(size));
}
- auto* val = const_eval_.Swizzle(ret, object, swizzle);
- return builder_->create<sem::Swizzle>(expr, ret, current_statement_, val, object,
- std::move(swizzle), has_side_effects, source_var);
+ if (auto r = const_eval_.Swizzle(ret, object, swizzle)) {
+ auto* val = r.Get();
+ return builder_->create<sem::Swizzle>(expr, ret, current_statement_, val, object,
+ std::move(swizzle), has_side_effects, source_var);
+ }
+ return nullptr;
}
AddError("invalid member accessor expression. Expected vector or struct, got '" +
@@ -2208,7 +2305,6 @@
const auto* rhs = sem_.Get(expr->rhs);
auto* lhs_ty = lhs->Type()->UnwrapRef();
auto* rhs_ty = rhs->Type()->UnwrapRef();
- auto stage = sem::EvaluationStage::kRuntime; // TODO(crbug.com/tint/1581)
auto op = intrinsic_table_->Lookup(expr->op, lhs_ty, rhs_ty, expr->source, false);
if (!op.result) {
@@ -2228,8 +2324,26 @@
}
const sem::Constant* value = nullptr;
- if (op.const_eval_fn) {
- value = (const_eval_.*op.const_eval_fn)(op.result, utils::Vector{lhs, rhs});
+ auto stage = sem::EarliestStage(lhs->Stage(), rhs->Stage());
+ if (stage == sem::EvaluationStage::kConstant) {
+ if (op.const_eval_fn) {
+ auto const_args = utils::Vector{lhs->ConstantValue(), rhs->ConstantValue()};
+ // Implicit conversion (e.g. AInt -> AFloat)
+ if (!Convert(const_args[0], op.lhs, lhs->Declaration()->source)) {
+ return nullptr;
+ }
+ if (!Convert(const_args[1], op.rhs, rhs->Declaration()->source)) {
+ return nullptr;
+ }
+
+ if (auto r = (const_eval_.*op.const_eval_fn)(op.result, const_args, expr->source)) {
+ value = r.Get();
+ } else {
+ return nullptr;
+ }
+ } else {
+ stage = sem::EvaluationStage::kRuntime;
+ }
}
bool has_side_effects = lhs->HasSideEffects() || rhs->HasSideEffects();
@@ -2305,7 +2419,13 @@
stage = expr->Stage();
if (stage == sem::EvaluationStage::kConstant) {
if (op.const_eval_fn) {
- value = (const_eval_.*op.const_eval_fn)(ty, utils::Vector{expr});
+ if (auto r = (const_eval_.*op.const_eval_fn)(
+ ty, utils::Vector{expr->ConstantValue()},
+ expr->Declaration()->source)) {
+ value = r.Get();
+ } else {
+ return nullptr;
+ }
} else {
stage = sem::EvaluationStage::kRuntime;
}
@@ -2419,7 +2539,7 @@
return static_cast<uint32_t>(count);
}
-bool Resolver::ArrayAttributes(const ast::AttributeList& attributes,
+bool Resolver::ArrayAttributes(utils::VectorRef<const ast::Attribute*> attributes,
const sem::Type* el_ty,
uint32_t& explicit_stride) {
if (!validator_.NoDuplicateAttributes(attributes)) {
@@ -2490,7 +2610,7 @@
}
sem::StructMemberList sem_members;
- sem_members.reserve(str->members.size());
+ sem_members.reserve(str->members.Length());
// Calculate the effective size and alignment of each field, and the overall
// size of the structure.
@@ -2689,8 +2809,8 @@
utils::Vector<const sem::Type*, 8> types;
types.Push(cond_ty);
- std::vector<sem::CaseStatement*> cases;
- cases.reserve(stmt->body.size());
+ utils::Vector<sem::CaseStatement*, 4> cases;
+ cases.Reserve(stmt->body.Length());
for (auto* case_stmt : stmt->body) {
Mark(case_stmt);
auto* c = CaseStatement(case_stmt);
@@ -2700,7 +2820,7 @@
for (auto* expr : c->Selectors()) {
types.Push(expr->Type()->UnwrapRef());
}
- cases.emplace_back(c);
+ cases.Push(c);
behaviors.Add(c->Behaviors());
sem->Cases().emplace_back(c);
}
diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h
index fa5a569..4c61c47 100644
--- a/src/tint/resolver/resolver.h
+++ b/src/tint/resolver/resolver.h
@@ -160,19 +160,6 @@
/// ProgramBuilder.
void CreateSemanticNodes() const;
- /// Retrieves information for the requested import.
- /// @param src the source of the import
- /// @param path the import path
- /// @param name the method name to get information on
- /// @param params the parameters to the method call
- /// @param id out parameter for the external call ID. Must not be a nullptr.
- /// @returns the return type of `name` in `path` or nullptr on error.
- sem::Type* GetImportData(const Source& src,
- const std::string& path,
- const std::string& name,
- const ast::ExpressionList& params,
- uint32_t* id);
-
/// Expression traverses the graph of expressions starting at `expr`, building a postordered
/// list (leaf-first) of all the expression nodes. Each of the expressions are then resolved by
/// dispatching to the appropriate expression handlers below.
@@ -193,14 +180,16 @@
sem::Expression* Bitcast(const ast::BitcastExpression*);
sem::Call* Call(const ast::CallExpression*);
sem::Function* Function(const ast::Function*);
+ template <size_t N>
sem::Call* FunctionCall(const ast::CallExpression*,
sem::Function* target,
- utils::VectorRef<const sem::Expression*> args,
+ utils::Vector<const sem::Expression*, N>& args,
sem::Behaviors arg_behaviors);
sem::Expression* Identifier(const ast::IdentifierExpression*);
+ template <size_t N>
sem::Call* BuiltinCall(const ast::CallExpression*,
sem::BuiltinType,
- utils::VectorRef<const sem::Expression*> args);
+ utils::Vector<const sem::Expression*, N>& args);
sem::Expression* Literal(const ast::LiteralExpression*);
sem::Expression* MemberAccessor(const ast::MemberAccessorExpression*);
sem::Expression* UnaryOp(const ast::UnaryOpExpression*);
@@ -223,13 +212,26 @@
/// Materializes all the arguments in `args` to the parameter types of `target`.
/// @returns true on success, false on failure.
- bool MaterializeArguments(utils::VectorRef<const sem::Expression*> args,
+ template <size_t N>
+ bool MaterializeArguments(utils::Vector<const sem::Expression*, N>& args,
const sem::CallTarget* target);
/// @returns true if an argument of an abstract numeric type, passed to a parameter of type
/// `parameter_ty` should be materialized.
bool ShouldMaterializeArgument(const sem::Type* parameter_ty) const;
+ /// Converts `c` to `target_ty`
+ /// @returns true on success, false on failure.
+ bool Convert(const sem::Constant*& c, const sem::Type* target_ty, const Source& source);
+
+ /// Transforms `args` to a vector of constants, and converts each constant to the call target's
+ /// parameter type.
+ /// @returns the vector of constants, `utils::Failure` on failure.
+ template <size_t N>
+ utils::Result<utils::Vector<const sem::Constant*, N>> ConvertArguments(
+ const utils::Vector<const sem::Expression*, N>& args,
+ const sem::CallTarget* target);
+
/// @param ty the type that may hold abstract numeric types
/// @param target_ty the target type for the expression (variable type, parameter type, etc).
/// May be nullptr.
@@ -260,16 +262,17 @@
sem::LoopStatement* LoopStatement(const ast::LoopStatement*);
sem::Statement* ReturnStatement(const ast::ReturnStatement*);
sem::Statement* Statement(const ast::Statement*);
+ sem::Statement* StaticAssert(const ast::StaticAssert*);
sem::SwitchStatement* SwitchStatement(const ast::SwitchStatement* s);
sem::Statement* VariableDeclStatement(const ast::VariableDeclStatement*);
- bool Statements(const ast::StatementList&);
+ bool Statements(utils::VectorRef<const ast::Statement*>);
// CollectTextureSamplerPairs() collects all the texture/sampler pairs from the target function
// / builtin, and records these on the current function by calling AddTextureSamplerPair().
void CollectTextureSamplerPairs(sem::Function* func,
- utils::ConstVectorRef<const sem::Expression*> args) const;
+ utils::VectorRef<const sem::Expression*> args) const;
void CollectTextureSamplerPairs(const sem::Builtin* builtin,
- utils::ConstVectorRef<const sem::Expression*> args) const;
+ utils::VectorRef<const sem::Expression*> args) const;
/// Resolves the WorkgroupSize for the given function, assigning it to
/// current_function_
@@ -306,7 +309,7 @@
/// @param el_ty the element type of the array.
/// @param explicit_stride assigned the specified stride of the array in bytes.
/// @returns true on success, false on failure
- bool ArrayAttributes(const ast::AttributeList& attributes,
+ bool ArrayAttributes(utils::VectorRef<const ast::Attribute*> attributes,
const sem::Type* el_ty,
uint32_t& explicit_stride);
diff --git a/src/tint/resolver/resolver_behavior_test.cc b/src/tint/resolver/resolver_behavior_test.cc
index b125e39..43f0bf1 100644
--- a/src/tint/resolver/resolver_behavior_test.cc
+++ b/src/tint/resolver/resolver_behavior_test.cc
@@ -33,8 +33,8 @@
// Create a function called 'DiscardOrNext' which returns an i32, and has
// the behavior of {Discard, Return}, which when called, will have the
// behavior {Discard, Next}.
- Func("DiscardOrNext", {}, ty.i32(),
- {
+ Func("DiscardOrNext", utils::Empty, ty.i32(),
+ utils::Vector{
If(true, Block(Discard())),
Return(1_i),
});
@@ -72,8 +72,8 @@
}
TEST_F(ResolverBehaviorTest, ExprIndex_Arr) {
- Func("ArrayDiscardOrNext", {}, ty.array<i32, 4>(),
- {
+ Func("ArrayDiscardOrNext", utils::Empty, ty.array<i32, 4>(),
+ utils::Vector{
If(true, Block(Discard())),
Return(Construct(ty.array<i32, 4>())),
});
@@ -165,7 +165,7 @@
}
TEST_F(ResolverBehaviorTest, StmtCallReturn) {
- Func("f", {}, ty.void_(), {Return()});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Return()});
auto* stmt = CallStmt(Call("f"));
WrapInFunction(stmt);
@@ -176,7 +176,7 @@
}
TEST_F(ResolverBehaviorTest, StmtCallFuncDiscard) {
- Func("f", {}, ty.void_(), {Discard()});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Discard()});
auto* stmt = CallStmt(Call("f"));
WrapInFunction(stmt);
@@ -522,7 +522,7 @@
TEST_F(ResolverBehaviorTest, StmtReturn_DiscardOrNext) {
auto* stmt = Return(Call("DiscardOrNext"));
- Func("F", {}, ty.i32(), {stmt});
+ Func("F", utils::Empty, ty.i32(), utils::Vector{stmt});
ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc
index bacbcd6..ecc251a 100644
--- a/src/tint/resolver/resolver_test.cc
+++ b/src/tint/resolver/resolver_test.cc
@@ -233,7 +233,7 @@
auto* cond = Expr(2_i);
auto* ret = Return(cond);
- Func("test", {}, ty.i32(), {ret}, {});
+ Func("test", utils::Empty, ty.i32(), utils::Vector{ret}, utils::Empty);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -270,8 +270,8 @@
}
TEST_F(ResolverTest, Stmt_Call) {
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -357,7 +357,7 @@
auto* bar_f32_init = bar_f32->constructor;
auto* bar_f32_decl = Decl(bar_f32);
- Func("func", {}, ty.void_(), {inner, foo_f32_decl, bar_f32_decl});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{inner, foo_f32_decl, bar_f32_decl});
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(foo_i32_init), nullptr);
@@ -372,8 +372,8 @@
EXPECT_EQ(StmtOf(bar_i32_init), bar_i32_decl);
EXPECT_EQ(StmtOf(foo_f32_init), foo_f32_decl);
EXPECT_EQ(StmtOf(bar_f32_init), bar_f32_decl);
- EXPECT_TRUE(CheckVarUsers(foo_i32, {bar_i32->constructor}));
- EXPECT_TRUE(CheckVarUsers(foo_f32, {bar_f32->constructor}));
+ EXPECT_TRUE(CheckVarUsers(foo_i32, utils::Vector{bar_i32->constructor}));
+ EXPECT_TRUE(CheckVarUsers(foo_f32, utils::Vector{bar_f32->constructor}));
ASSERT_NE(VarOf(bar_i32->constructor), nullptr);
EXPECT_EQ(VarOf(bar_i32->constructor)->Declaration(), foo_i32);
ASSERT_NE(VarOf(bar_f32->constructor), nullptr);
@@ -393,7 +393,7 @@
auto* fn_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
auto* fn_i32_init = fn_i32->constructor;
auto* fn_i32_decl = Decl(fn_i32);
- Func("func_i32", {}, ty.void_(), {fn_i32_decl});
+ Func("func_i32", utils::Empty, ty.void_(), utils::Vector{fn_i32_decl});
// Declare f32 "foo" at module scope
auto* mod_f32 = Var("foo", ty.f32(), ast::StorageClass::kPrivate, Expr(2_f));
@@ -404,7 +404,7 @@
auto* fn_f32 = Var("bar", ty.f32(), ast::StorageClass::kNone, Expr("foo"));
auto* fn_f32_init = fn_f32->constructor;
auto* fn_f32_decl = Decl(fn_f32);
- Func("func_f32", {}, ty.void_(), {fn_f32_decl});
+ Func("func_f32", utils::Empty, ty.void_(), utils::Vector{fn_f32_decl});
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_NE(TypeOf(mod_init), nullptr);
@@ -416,8 +416,8 @@
EXPECT_EQ(StmtOf(fn_i32_init), fn_i32_decl);
EXPECT_EQ(StmtOf(mod_init), nullptr);
EXPECT_EQ(StmtOf(fn_f32_init), fn_f32_decl);
- EXPECT_TRUE(CheckVarUsers(fn_i32, {}));
- EXPECT_TRUE(CheckVarUsers(mod_f32, {fn_f32->constructor}));
+ EXPECT_TRUE(CheckVarUsers(fn_i32, utils::Empty));
+ EXPECT_TRUE(CheckVarUsers(mod_f32, utils::Vector{fn_f32->constructor}));
ASSERT_NE(VarOf(fn_f32->constructor), nullptr);
EXPECT_EQ(VarOf(fn_f32->constructor)->Declaration(), mod_f32);
}
@@ -491,7 +491,7 @@
}
TEST_F(ResolverTest, Expr_Call) {
- Func("my_func", {}, ty.f32(), {Return(0_f)});
+ Func("my_func", utils::Empty, ty.f32(), utils::Vector{Return(0_f)});
auto* call = Call("my_func");
WrapInFunction(call);
@@ -503,7 +503,7 @@
}
TEST_F(ResolverTest, Expr_Call_InBinaryOp) {
- Func("func", {}, ty.f32(), {Return(0_f)});
+ Func("func", utils::Empty, ty.f32(), utils::Vector{Return(0_f)});
auto* expr = Add(Call("func"), Call("func"));
WrapInFunction(expr);
@@ -515,8 +515,8 @@
}
TEST_F(ResolverTest, Expr_Call_WithParams) {
- Func("my_func", {Param(Sym(), ty.f32())}, ty.f32(),
- {
+ Func("my_func", utils::Vector{Param(Sym(), ty.f32())}, ty.f32(),
+ utils::Vector{
Return(1.2_f),
});
@@ -610,7 +610,7 @@
ASSERT_NE(TypeOf(ident), nullptr);
ASSERT_TRUE(TypeOf(ident)->Is<sem::Reference>());
EXPECT_TRUE(TypeOf(ident)->UnwrapRef()->Is<sem::F32>());
- EXPECT_TRUE(CheckVarUsers(my_var, {ident}));
+ EXPECT_TRUE(CheckVarUsers(my_var, utils::Vector{ident}));
ASSERT_NE(VarOf(ident), nullptr);
EXPECT_EQ(VarOf(ident)->Declaration(), my_var);
}
@@ -625,7 +625,7 @@
ASSERT_NE(TypeOf(ident), nullptr);
EXPECT_TRUE(TypeOf(ident)->Is<sem::F32>());
- EXPECT_TRUE(CheckVarUsers(my_var, {ident}));
+ EXPECT_TRUE(CheckVarUsers(my_var, utils::Vector{ident}));
ASSERT_NE(VarOf(ident), nullptr);
EXPECT_EQ(VarOf(ident)->Declaration(), my_var);
}
@@ -635,8 +635,8 @@
auto* var = Let("my_var", ty.f32(), Construct(ty.f32()));
auto* decl = Decl(Var("b", ty.f32(), ast::StorageClass::kNone, my_var_a));
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
decl,
});
@@ -646,7 +646,7 @@
ASSERT_NE(TypeOf(my_var_a), nullptr);
EXPECT_TRUE(TypeOf(my_var_a)->Is<sem::F32>());
EXPECT_EQ(StmtOf(my_var_a), decl);
- EXPECT_TRUE(CheckVarUsers(var, {my_var_a}));
+ EXPECT_TRUE(CheckVarUsers(var, utils::Vector{my_var_a}));
ASSERT_NE(VarOf(my_var_a), nullptr);
EXPECT_EQ(VarOf(my_var_a)->Declaration(), var);
}
@@ -658,8 +658,8 @@
auto* a = Var("a", ty.array<bool, 10>(), array<bool, 10>());
auto* idx = Var("idx", ty.f32(), Construct(ty.f32()));
auto* f = Var("f", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, idx)));
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(a),
Decl(idx),
Decl(f),
@@ -676,8 +676,8 @@
auto* var = Var("my_var", ty.f32());
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
assign,
});
@@ -692,7 +692,7 @@
ASSERT_TRUE(TypeOf(my_var_b)->Is<sem::Reference>());
EXPECT_TRUE(TypeOf(my_var_b)->UnwrapRef()->Is<sem::F32>());
EXPECT_EQ(StmtOf(my_var_b), assign);
- EXPECT_TRUE(CheckVarUsers(var, {my_var_a, my_var_b}));
+ EXPECT_TRUE(CheckVarUsers(var, utils::Vector{my_var_a, my_var_b}));
ASSERT_NE(VarOf(my_var_a), nullptr);
EXPECT_EQ(VarOf(my_var_a)->Declaration(), var);
ASSERT_NE(VarOf(my_var_b), nullptr);
@@ -705,8 +705,8 @@
auto* v_decl = Decl(Var("v", ty.f32()));
auto* p_decl = Decl(Let("p", ty.pointer<f32>(ast::StorageClass::kFunction), AddressOf(v)));
auto* assign = Assign(Deref(p), 1.23_f);
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
v_decl,
p_decl,
assign,
@@ -725,8 +725,8 @@
}
TEST_F(ResolverTest, Expr_Call_Function) {
- Func("my_func", {}, ty.f32(),
- {
+ Func("my_func", utils::Empty, ty.f32(),
+ utils::Vector{
Return(0_f),
});
@@ -752,12 +752,12 @@
auto* param_c = Param("c", ty.u32());
auto* func = Func("my_func",
- {
+ utils::Vector{
param_a,
param_b,
param_c,
},
- ty.void_(), {});
+ ty.void_(), utils::Empty);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -774,19 +774,19 @@
}
TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
- auto* s = Structure("S", {Member("m", ty.u32())});
+ auto* s = Structure("S", utils::Vector{Member("m", ty.u32())});
auto* sb_var =
GlobalVar("sb_var", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
auto* wg_var = GlobalVar("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
auto* priv_var = GlobalVar("priv_var", ty.f32(), ast::StorageClass::kPrivate);
- auto* func = Func("my_func", {}, ty.void_(),
- {
+ auto* func = Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign("wg_var", "wg_var"),
Assign("sb_var", "sb_var"),
Assign("priv_var", "priv_var"),
@@ -807,26 +807,26 @@
}
TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
- auto* s = Structure("S", {Member("m", ty.u32())});
+ auto* s = Structure("S", utils::Vector{Member("m", ty.u32())});
auto* sb_var =
GlobalVar("sb_var", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
auto* wg_var = GlobalVar("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
auto* priv_var = GlobalVar("priv_var", ty.f32(), ast::StorageClass::kPrivate);
- Func("my_func", {}, ty.f32(),
- {Assign("wg_var", "wg_var"), Assign("sb_var", "sb_var"), Assign("priv_var", "priv_var"),
- Return(0_f)});
+ Func("my_func", utils::Empty, ty.f32(),
+ utils::Vector{Assign("wg_var", "wg_var"), Assign("sb_var", "sb_var"),
+ Assign("priv_var", "priv_var"), Return(0_f)});
- auto* func2 = Func("func", {}, ty.void_(),
- {
+ auto* func2 = Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
WrapInStatement(Call("my_func")),
},
- ast::AttributeList{});
+ utils::Empty);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -842,8 +842,8 @@
}
TEST_F(ResolverTest, Function_NotRegisterFunctionVariable) {
- auto* func = Func("my_func", {}, ty.void_(),
- {
+ auto* func = Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("var", ty.f32())),
Assign("var", 1_f),
});
@@ -858,8 +858,8 @@
}
TEST_F(ResolverTest, Function_NotRegisterFunctionConstant) {
- auto* func = Func("my_func", {}, ty.void_(),
- {
+ auto* func = Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("var", ty.f32(), Construct(ty.f32()))),
});
@@ -873,7 +873,7 @@
}
TEST_F(ResolverTest, Function_NotRegisterFunctionParams) {
- auto* func = Func("my_func", {Param("var", ty.f32())}, ty.void_(), {});
+ auto* func = Func("my_func", utils::Vector{Param("var", ty.f32())}, ty.void_(), utils::Empty);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* func_sem = Sem().Get(func);
@@ -884,12 +884,12 @@
}
TEST_F(ResolverTest, Function_CallSites) {
- auto* foo = Func("foo", {}, ty.void_(), {});
+ auto* foo = Func("foo", utils::Empty, ty.void_(), utils::Empty);
auto* call_1 = Call("foo");
auto* call_2 = Call("foo");
- auto* bar = Func("bar", {}, ty.void_(),
- {
+ auto* bar = Func("bar", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(call_1),
CallStmt(call_2),
});
@@ -910,7 +910,7 @@
TEST_F(ResolverTest, Function_WorkgroupSize_NotSet) {
// @compute @workgroup_size(1)
// fn main() {}
- auto* func = Func("main", {}, ty.void_(), {});
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -928,8 +928,8 @@
TEST_F(ResolverTest, Function_WorkgroupSize_Literals) {
// @compute @workgroup_size(8, 2, 3)
// fn main() {}
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(8_i, 2_i, 3_i),
});
@@ -956,8 +956,8 @@
GlobalConst("width", ty.i32(), Expr(16_i));
GlobalConst("height", ty.i32(), Expr(8_i));
GlobalConst("depth", ty.i32(), Expr(2_i));
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize("width", "height", "depth"),
});
@@ -984,8 +984,8 @@
Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 8_i))));
GlobalConst("height", ty.i32(),
Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 4_i))));
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize("width", "height"),
});
@@ -1009,11 +1009,11 @@
// @id(2) override depth = 2i;
// @compute @workgroup_size(width, height, depth)
// fn main() {}
- auto* width = Override("width", ty.i32(), Expr(16_i), {Id(0)});
- auto* height = Override("height", ty.i32(), Expr(8_i), {Id(1)});
- auto* depth = Override("depth", ty.i32(), Expr(2_i), {Id(2)});
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* width = Override("width", ty.i32(), Expr(16_i), utils::Vector{Id(0)});
+ auto* height = Override("height", ty.i32(), Expr(8_i), utils::Vector{Id(1)});
+ auto* depth = Override("depth", ty.i32(), Expr(2_i), utils::Vector{Id(2)});
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize("width", "height", "depth"),
});
@@ -1037,11 +1037,11 @@
// @id(2) override depth : i32;
// @compute @workgroup_size(width, height, depth)
// fn main() {}
- auto* width = Override("width", ty.i32(), nullptr, {Id(0)});
- auto* height = Override("height", ty.i32(), nullptr, {Id(1)});
- auto* depth = Override("depth", ty.i32(), nullptr, {Id(2)});
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* width = Override("width", ty.i32(), nullptr, utils::Vector{Id(0)});
+ auto* height = Override("height", ty.i32(), nullptr, utils::Vector{Id(1)});
+ auto* depth = Override("depth", ty.i32(), nullptr, utils::Vector{Id(2)});
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize("width", "height", "depth"),
});
@@ -1064,10 +1064,10 @@
// const depth = 3i;
// @compute @workgroup_size(8, height, depth)
// fn main() {}
- auto* height = Override("height", ty.i32(), Expr(2_i), {Id(0)});
+ auto* height = Override("height", ty.i32(), Expr(2_i), utils::Vector{Id(0)});
GlobalConst("depth", ty.i32(), Expr(3_i));
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(8_i, "height", "depth"),
});
@@ -1086,8 +1086,8 @@
}
TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
- auto* st =
- Structure("S", {Member("first_member", ty.i32()), Member("second_member", ty.f32())});
+ auto* st = Structure(
+ "S", utils::Vector{Member("first_member", ty.i32()), Member("second_member", ty.f32())});
GlobalVar("my_struct", ty.Of(st), ast::StorageClass::kPrivate);
auto* mem = MemberAccessor("my_struct", "second_member");
@@ -1109,8 +1109,8 @@
}
TEST_F(ResolverTest, Expr_MemberAccessor_Struct_Alias) {
- auto* st =
- Structure("S", {Member("first_member", ty.i32()), Member("second_member", ty.f32())});
+ auto* st = Structure(
+ "S", utils::Vector{Member("first_member", ty.i32()), Member("second_member", ty.f32())});
auto* alias = Alias("alias", ty.Of(st));
GlobalVar("my_struct", ty.Of(alias), ast::StorageClass::kPrivate);
@@ -1184,8 +1184,8 @@
// }
//
- auto* stB = Structure("B", {Member("foo", ty.vec4<f32>())});
- auto* stA = Structure("A", {Member("mem", ty.array(ty.Of(stB), 3_i))});
+ auto* stB = Structure("B", utils::Vector{Member("foo", ty.vec4<f32>())});
+ auto* stA = Structure("A", utils::Vector{Member("mem", ty.array(ty.Of(stB), 3_i))});
GlobalVar("c", ty.Of(stA), ast::StorageClass::kPrivate);
auto* mem =
@@ -1202,8 +1202,8 @@
}
TEST_F(ResolverTest, Expr_MemberAccessor_InBinaryOp) {
- auto* st =
- Structure("S", {Member("first_member", ty.f32()), Member("second_member", ty.f32())});
+ auto* st = Structure(
+ "S", utils::Vector{Member("first_member", ty.f32()), Member("second_member", ty.f32())});
GlobalVar("my_struct", ty.Of(st), ast::StorageClass::kPrivate);
auto* expr = Add(MemberAccessor("my_struct", "first_member"),
@@ -1726,7 +1726,7 @@
auto* var = Var("var", ty.i32());
auto* stmt = Decl(var);
- Func("func", {}, ty.void_(), {stmt});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{stmt});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1736,7 +1736,7 @@
TEST_F(ResolverTest, StorageClass_SetForSampler) {
auto* t = ty.sampler(ast::SamplerKind::kSampler);
auto* var = GlobalVar("var", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -1749,7 +1749,7 @@
TEST_F(ResolverTest, StorageClass_SetForTexture) {
auto* t = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
auto* var = GlobalVar("var", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -1762,7 +1762,7 @@
TEST_F(ResolverTest, StorageClass_DoesNotSetOnConst) {
auto* var = Let("var", ty.i32(), Construct(ty.i32()));
auto* stmt = Decl(var);
- Func("func", {}, ty.void_(), {stmt});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{stmt});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1772,9 +1772,9 @@
TEST_F(ResolverTest, Access_SetForStorageBuffer) {
// struct S { x : i32 };
// var<storage> g : S;
- auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
+ auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
auto* var = GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -1789,10 +1789,10 @@
// @group(3) @binding(4) var s2 : sampler;
auto* s1 = GlobalVar(
Sym(), ty.sampler(ast::SamplerKind::kSampler),
- ast::AttributeList{create<ast::GroupAttribute>(1u), create<ast::BindingAttribute>(2u)});
+ utils::Vector{create<ast::GroupAttribute>(1u), create<ast::BindingAttribute>(2u)});
auto* s2 = GlobalVar(
Sym(), ty.sampler(ast::SamplerKind::kSampler),
- ast::AttributeList{create<ast::GroupAttribute>(3u), create<ast::BindingAttribute>(4u)});
+ utils::Vector{create<ast::GroupAttribute>(3u), create<ast::BindingAttribute>(4u)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1819,37 +1819,37 @@
GlobalVar("call_b", ty.f32(), ast::StorageClass::kPrivate);
GlobalVar("call_c", ty.f32(), ast::StorageClass::kPrivate);
- auto* func_b = Func("b", {}, ty.f32(),
- {
+ auto* func_b = Func("b", utils::Empty, ty.f32(),
+ utils::Vector{
Return(0_f),
});
- auto* func_c = Func("c", {}, ty.f32(),
- {
+ auto* func_c = Func("c", utils::Empty, ty.f32(),
+ utils::Vector{
Assign("second", Call("b")),
Return(0_f),
});
- auto* func_a = Func("a", {}, ty.f32(),
- {
+ auto* func_a = Func("a", utils::Empty, ty.f32(),
+ utils::Vector{
Assign("first", Call("c")),
Return(0_f),
});
- auto* ep_1 = Func("ep_1", {}, ty.void_(),
- {
+ auto* ep_1 = Func("ep_1", utils::Empty, ty.void_(),
+ utils::Vector{
Assign("call_a", Call("a")),
Assign("call_b", Call("b")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
- auto* ep_2 = Func("ep_2", {}, ty.void_(),
- {
+ auto* ep_2 = Func("ep_2", utils::Empty, ty.void_(),
+ utils::Vector{
Assign("call_c", Call("c")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -1906,38 +1906,38 @@
auto fn_a = [](int level) { return "l" + std::to_string(level + 1) + "a"; };
auto fn_b = [](int level) { return "l" + std::to_string(level + 1) + "b"; };
- Func(fn_a(levels), {}, ty.void_(), {});
- Func(fn_b(levels), {}, ty.void_(), {});
+ Func(fn_a(levels), utils::Empty, ty.void_(), utils::Empty);
+ Func(fn_b(levels), utils::Empty, ty.void_(), utils::Empty);
for (int i = levels - 1; i >= 0; i--) {
- Func(fn_a(i), {}, ty.void_(),
- {
+ Func(fn_a(i), utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call(fn_a(i + 1))),
CallStmt(Call(fn_b(i + 1))),
},
- {});
- Func(fn_b(i), {}, ty.void_(),
- {
+ utils::Empty);
+ Func(fn_b(i), utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call(fn_a(i + 1))),
CallStmt(Call(fn_b(i + 1))),
},
- {});
+ utils::Empty);
}
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call(fn_a(0))),
CallStmt(Call(fn_b(0))),
},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ utils::Vector{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
// Test for crbug.com/tint/728
TEST_F(ResolverTest, ASTNodesAreReached) {
- Structure("A", {Member("x", ty.array<f32, 4>(4))});
- Structure("B", {Member("x", ty.array<f32, 4>(4))});
+ Structure("A", utils::Vector{Member("x", ty.array<f32, 4>(4))});
+ Structure("B", utils::Vector{Member("x", ty.array<f32, 4>(4))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -1999,8 +1999,8 @@
GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 2));
auto* call = CallStmt(Call("textureSample", "t", "s", vec2<f32>(1_f, 2_f)));
- const ast::Function* f =
- Func("test_function", {}, ty.void_(), {call}, {Stage(ast::PipelineStage::kFragment)});
+ const ast::Function* f = Func("test_function", utils::Empty, ty.void_(), utils::Vector{call},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2016,10 +2016,12 @@
GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 2));
auto* inner_call = CallStmt(Call("textureSample", "t", "s", vec2<f32>(1_f, 2_f)));
- const ast::Function* inner_func = Func("inner_func", {}, ty.void_(), {inner_call});
+ const ast::Function* inner_func =
+ Func("inner_func", utils::Empty, ty.void_(), utils::Vector{inner_call});
auto* outer_call = CallStmt(Call("inner_func"));
const ast::Function* outer_func =
- Func("outer_func", {}, ty.void_(), {outer_call}, {Stage(ast::PipelineStage::kFragment)});
+ Func("outer_func", utils::Empty, ty.void_(), utils::Vector{outer_call},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2039,14 +2041,16 @@
GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 2));
auto* inner_call_1 = CallStmt(Call("textureSample", "t", "s", vec2<f32>(1_f, 2_f)));
- const ast::Function* inner_func_1 = Func("inner_func_1", {}, ty.void_(), {inner_call_1});
+ const ast::Function* inner_func_1 =
+ Func("inner_func_1", utils::Empty, ty.void_(), utils::Vector{inner_call_1});
auto* inner_call_2 = CallStmt(Call("textureSample", "t", "s", vec2<f32>(3_f, 4_f)));
- const ast::Function* inner_func_2 = Func("inner_func_2", {}, ty.void_(), {inner_call_2});
+ const ast::Function* inner_func_2 =
+ Func("inner_func_2", utils::Empty, ty.void_(), utils::Vector{inner_call_2});
auto* outer_call_1 = CallStmt(Call("inner_func_1"));
auto* outer_call_2 = CallStmt(Call("inner_func_2"));
const ast::Function* outer_func =
- Func("outer_func", {}, ty.void_(), {outer_call_1, outer_call_2},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("outer_func", utils::Empty, ty.void_(), utils::Vector{outer_call_1, outer_call_2},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2074,14 +2078,16 @@
GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 3));
auto* inner_call_1 = CallStmt(Call("textureSample", "t1", "s", vec2<f32>(1_f, 2_f)));
- const ast::Function* inner_func_1 = Func("inner_func_1", {}, ty.void_(), {inner_call_1});
+ const ast::Function* inner_func_1 =
+ Func("inner_func_1", utils::Empty, ty.void_(), utils::Vector{inner_call_1});
auto* inner_call_2 = CallStmt(Call("textureSample", "t2", "s", vec2<f32>(3_f, 4_f)));
- const ast::Function* inner_func_2 = Func("inner_func_2", {}, ty.void_(), {inner_call_2});
+ const ast::Function* inner_func_2 =
+ Func("inner_func_2", utils::Empty, ty.void_(), utils::Vector{inner_call_2});
auto* outer_call_1 = CallStmt(Call("inner_func_1"));
auto* outer_call_2 = CallStmt(Call("inner_func_2"));
const ast::Function* outer_func =
- Func("outer_func", {}, ty.void_(), {outer_call_1, outer_call_2},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("outer_func", utils::Empty, ty.void_(), utils::Vector{outer_call_1, outer_call_2},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2119,18 +2125,18 @@
}
TEST_F(ResolverTest, ModuleDependencyOrderedDeclarations) {
- auto* f0 = Func("f0", {}, ty.void_(), {});
+ auto* f0 = Func("f0", utils::Empty, ty.void_(), utils::Empty);
auto* v0 = GlobalVar("v0", ty.i32(), ast::StorageClass::kPrivate);
auto* a0 = Alias("a0", ty.i32());
- auto* s0 = Structure("s0", {Member("m", ty.i32())});
- auto* f1 = Func("f1", {}, ty.void_(), {});
+ auto* s0 = Structure("s0", utils::Vector{Member("m", ty.i32())});
+ auto* f1 = Func("f1", utils::Empty, ty.void_(), utils::Empty);
auto* v1 = GlobalVar("v1", ty.i32(), ast::StorageClass::kPrivate);
auto* a1 = Alias("a1", ty.i32());
- auto* s1 = Structure("s1", {Member("m", ty.i32())});
- auto* f2 = Func("f2", {}, ty.void_(), {});
+ auto* s1 = Structure("s1", utils::Vector{Member("m", ty.i32())});
+ auto* f2 = Func("f2", utils::Empty, ty.void_(), utils::Empty);
auto* v2 = GlobalVar("v2", ty.i32(), ast::StorageClass::kPrivate);
auto* a2 = Alias("a2", ty.i32());
- auto* s2 = Structure("s2", {Member("m", ty.i32())});
+ auto* s2 = Structure("s2", utils::Vector{Member("m", ty.i32())});
EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/resolver_test_helper.h b/src/tint/resolver/resolver_test_helper.h
index efb215b..bab1d84 100644
--- a/src/tint/resolver/resolver_test_helper.h
+++ b/src/tint/resolver/resolver_test_helper.h
@@ -18,7 +18,6 @@
#include <functional>
#include <memory>
#include <string>
-#include <vector>
#include "gtest/gtest.h"
#include "src/tint/program_builder.h"
@@ -28,6 +27,7 @@
#include "src/tint/sem/expression.h"
#include "src/tint/sem/statement.h"
#include "src/tint/sem/variable.h"
+#include "src/tint/utils/vector.h"
namespace tint::resolver {
@@ -88,9 +88,9 @@
/// @param expected_users the expected users of the variable
/// @return true if all users are as expected
bool CheckVarUsers(const ast::Variable* var,
- std::vector<const ast::Expression*>&& expected_users) {
+ utils::VectorRef<const ast::Expression*> expected_users) {
auto& var_users = Sem().Get(var)->Users();
- if (var_users.size() != expected_users.size()) {
+ if (var_users.size() != expected_users.Length()) {
return false;
}
for (size_t i = 0; i < var_users.size(); i++) {
@@ -389,10 +389,10 @@
/// @param b the ProgramBuilder
/// @param elem_value the value each element will be initialized with
/// @return the list of expressions that are used to construct the vector
- static inline ast::ExpressionList ExprArgs(ProgramBuilder& b, double elem_value) {
- ast::ExpressionList args;
+ static inline auto ExprArgs(ProgramBuilder& b, double elem_value) {
+ utils::Vector<const ast::Expression*, N> args;
for (uint32_t i = 0; i < N; i++) {
- args.emplace_back(DataType<T>::Expr(b, elem_value));
+ args.Push(DataType<T>::Expr(b, elem_value));
}
return args;
}
@@ -433,10 +433,10 @@
/// @param b the ProgramBuilder
/// @param elem_value the value each element will be initialized with
/// @return the list of expressions that are used to construct the matrix
- static inline ast::ExpressionList ExprArgs(ProgramBuilder& b, double elem_value) {
- ast::ExpressionList args;
+ static inline auto ExprArgs(ProgramBuilder& b, double elem_value) {
+ utils::Vector<const ast::Expression*, N> args;
for (uint32_t i = 0; i < N; i++) {
- args.emplace_back(DataType<vec<M, T>>::Expr(b, elem_value));
+ args.Push(DataType<vec<M, T>>::Expr(b, elem_value));
}
return args;
}
@@ -566,10 +566,10 @@
/// @param b the ProgramBuilder
/// @param elem_value the value each element will be initialized with
/// @return the list of expressions that are used to construct the array
- static inline ast::ExpressionList ExprArgs(ProgramBuilder& b, double elem_value) {
- ast::ExpressionList args;
+ static inline auto ExprArgs(ProgramBuilder& b, double elem_value) {
+ utils::Vector<const ast::Expression*, N> args;
for (uint32_t i = 0; i < N; i++) {
- args.emplace_back(DataType<T>::Expr(b, elem_value));
+ args.Push(DataType<T>::Expr(b, elem_value));
}
return args;
}
diff --git a/src/tint/resolver/side_effects_test.cc b/src/tint/resolver/side_effects_test.cc
index 689c7b8..d0cb32c 100644
--- a/src/tint/resolver/side_effects_test.cc
+++ b/src/tint/resolver/side_effects_test.cc
@@ -19,6 +19,7 @@
#include "src/tint/sem/expression.h"
#include "src/tint/sem/index_accessor_expression.h"
#include "src/tint/sem/member_accessor_expression.h"
+#include "src/tint/utils/vector.h"
using namespace tint::number_suffixes; // NOLINT
@@ -31,8 +32,8 @@
auto global = Sym();
GlobalVar(global, ty.Of<T>(), ast::StorageClass::kPrivate);
auto local = Sym();
- Func(name, {}, ty.Of<T>(),
- {
+ Func(name, utils::Empty, ty.Of<T>(),
+ utils::Vector{
Decl(Var(local, ty.Of<T>())),
Assign(global, local),
Return(global),
@@ -44,8 +45,8 @@
auto global = Sym();
GlobalVar(global, make_type(), ast::StorageClass::kPrivate);
auto local = Sym();
- Func(name, {}, make_type(),
- {
+ Func(name, utils::Empty, make_type(),
+ utils::Vector{
Decl(Var(local, make_type())),
Assign(global, local),
Return(global),
@@ -89,8 +90,8 @@
TEST_F(SideEffectsTest, Call_Builtin_NoSE) {
GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call("dpdx", "a");
- Func("f", {}, ty.void_(), {Ignore(expr)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Ignore(expr)},
+ utils::Vector{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
@@ -102,8 +103,8 @@
TEST_F(SideEffectsTest, Call_Builtin_NoSE_WithSEArg) {
MakeSideEffectFunc<f32>("se");
auto* expr = Call("dpdx", Call("se"));
- Func("f", {}, ty.void_(), {Ignore(expr)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Ignore(expr)},
+ utils::Vector{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
@@ -124,8 +125,230 @@
EXPECT_TRUE(sem->HasSideEffects());
}
+namespace builtin {
+struct Case {
+ const char* name;
+ utils::Vector<const char*, 3> args;
+ bool has_side_effects;
+ ast::PipelineStage pipeline_stage;
+};
+static Case C(const char* name,
+ utils::VectorRef<const char*> args,
+ bool has_side_effects,
+ ast::PipelineStage stage = ast::PipelineStage::kFragment) {
+ Case c;
+ c.name = name;
+ c.args = std::move(args);
+ c.has_side_effects = has_side_effects;
+ c.pipeline_stage = stage;
+ return c;
+}
+static std::ostream& operator<<(std::ostream& o, const Case& c) {
+ o << c.name << "(";
+ for (size_t i = 0; i < c.args.Length(); ++i) {
+ o << c.args[i];
+ if (i + 1 != c.args.Length()) {
+ o << ", ";
+ }
+ }
+ o << "), ";
+ o << "has_side_effects = " << c.has_side_effects;
+ return o;
+}
+
+using SideEffectsBuiltinTest = resolver::ResolverTestWithParam<Case>;
+
+TEST_P(SideEffectsBuiltinTest, Test) {
+ Enable(ast::Extension::kChromiumExperimentalDp4A);
+ auto& c = GetParam();
+
+ uint32_t next_binding = 0;
+ GlobalVar("f", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("i", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("u", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("vf", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("vf2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("vi2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("vf4", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("vb", ty.vec3<bool>(), ast::StorageClass::kPrivate);
+ GlobalVar("m", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("arr", ty.array<f32, 10>(), ast::StorageClass::kPrivate);
+ GlobalVar("storage_arr", ty.array<f32>(), ast::StorageClass::kStorage,
+ GroupAndBinding(0, next_binding++));
+ GlobalVar("a", ty.atomic(ty.i32()), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ GroupAndBinding(0, next_binding++));
+ if (c.pipeline_stage != ast::PipelineStage::kCompute) {
+ GlobalVar("t2d", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ GroupAndBinding(0, next_binding++));
+ GlobalVar("tdepth2d", ty.depth_texture(ast::TextureDimension::k2d),
+ GroupAndBinding(0, next_binding++));
+ GlobalVar("t2d_arr", ty.sampled_texture(ast::TextureDimension::k2dArray, ty.f32()),
+ GroupAndBinding(0, next_binding++));
+ GlobalVar("t2d_multi", ty.multisampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ GroupAndBinding(0, next_binding++));
+ GlobalVar("tstorage2d",
+ ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
+ ast::Access::kWrite),
+ GroupAndBinding(0, next_binding++));
+ GlobalVar("s2d", ty.sampler(ast::SamplerKind::kSampler),
+ GroupAndBinding(0, next_binding++));
+ GlobalVar("scomp", ty.sampler(ast::SamplerKind::kComparisonSampler),
+ GroupAndBinding(0, next_binding++));
+ }
+
+ utils::Vector<const ast::Statement*, 4> stmts;
+ stmts.Push(Decl(Let("pstorage_arr", nullptr, AddressOf("storage_arr"))));
+ stmts.Push(Decl(Let("pa", nullptr, AddressOf("a"))));
+
+ utils::Vector<const ast::Expression*, 5> args;
+ for (auto& a : c.args) {
+ args.Push(Expr(a));
+ }
+ auto* expr = Call(c.name, args);
+
+ utils::Vector<const ast::Attribute*, 2> attrs;
+ attrs.Push(create<ast::StageAttribute>(c.pipeline_stage));
+ if (c.pipeline_stage == ast::PipelineStage::kCompute) {
+ attrs.Push(WorkgroupSize(Expr(1_u)));
+ }
+
+ stmts.Push(create<ast::CallStatement>(expr));
+
+ Func("func", utils::Empty, ty.void_(), stmts, attrs);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ EXPECT_TRUE(sem->Is<sem::Call>());
+ EXPECT_EQ(c.has_side_effects, sem->HasSideEffects());
+}
+INSTANTIATE_TEST_SUITE_P(
+ SideEffectsTest_Builtins,
+ SideEffectsBuiltinTest,
+ testing::ValuesIn(std::vector<Case>{
+ // No side-effect builts
+ C("abs", utils::Vector{"f"}, false), //
+ C("acos", utils::Vector{"f"}, false), //
+ C("acosh", utils::Vector{"f"}, false), //
+ C("all", utils::Vector{"vb"}, false), //
+ C("any", utils::Vector{"vb"}, false), //
+ C("arrayLength", utils::Vector{"pstorage_arr"}, false), //
+ C("asin", utils::Vector{"f"}, false), //
+ C("asinh", utils::Vector{"f"}, false), //
+ C("atan", utils::Vector{"f"}, false), //
+ C("atan2", utils::Vector{"f", "f"}, false), //
+ C("atanh", utils::Vector{"f"}, false), //
+ C("atomicLoad", utils::Vector{"pa"}, false), //
+ C("ceil", utils::Vector{"f"}, false), //
+ C("clamp", utils::Vector{"f", "f", "f"}, false), //
+ C("cos", utils::Vector{"f"}, false), //
+ C("cosh", utils::Vector{"f"}, false), //
+ C("countLeadingZeros", utils::Vector{"i"}, false), //
+ C("countOneBits", utils::Vector{"i"}, false), //
+ C("countTrailingZeros", utils::Vector{"i"}, false), //
+ C("cross", utils::Vector{"vf", "vf"}, false), //
+ C("degrees", utils::Vector{"f"}, false), //
+ C("determinant", utils::Vector{"m"}, false), //
+ C("distance", utils::Vector{"f", "f"}, false), //
+ C("dot", utils::Vector{"vf", "vf"}, false), //
+ C("dot4I8Packed", utils::Vector{"u", "u"}, false), //
+ C("dot4U8Packed", utils::Vector{"u", "u"}, false), //
+ C("exp", utils::Vector{"f"}, false), //
+ C("exp2", utils::Vector{"f"}, false), //
+ C("extractBits", utils::Vector{"i", "u", "u"}, false), //
+ C("faceForward", utils::Vector{"vf", "vf", "vf"}, false), //
+ C("firstLeadingBit", utils::Vector{"u"}, false), //
+ C("firstTrailingBit", utils::Vector{"u"}, false), //
+ C("floor", utils::Vector{"f"}, false), //
+ C("fma", utils::Vector{"f", "f", "f"}, false), //
+ C("fract", utils::Vector{"vf"}, false), //
+ C("frexp", utils::Vector{"f"}, false), //
+ C("insertBits", utils::Vector{"i", "i", "u", "u"}, false), //
+ C("inverseSqrt", utils::Vector{"f"}, false), //
+ C("ldexp", utils::Vector{"f", "i"}, false), //
+ C("length", utils::Vector{"vf"}, false), //
+ C("log", utils::Vector{"f"}, false), //
+ C("log2", utils::Vector{"f"}, false), //
+ C("max", utils::Vector{"f", "f"}, false), //
+ C("min", utils::Vector{"f", "f"}, false), //
+ C("mix", utils::Vector{"f", "f", "f"}, false), //
+ C("modf", utils::Vector{"f"}, false), //
+ C("normalize", utils::Vector{"vf"}, false), //
+ C("pack2x16float", utils::Vector{"vf2"}, false), //
+ C("pack2x16snorm", utils::Vector{"vf2"}, false), //
+ C("pack2x16unorm", utils::Vector{"vf2"}, false), //
+ C("pack4x8snorm", utils::Vector{"vf4"}, false), //
+ C("pack4x8unorm", utils::Vector{"vf4"}, false), //
+ C("pow", utils::Vector{"f", "f"}, false), //
+ C("radians", utils::Vector{"f"}, false), //
+ C("reflect", utils::Vector{"vf", "vf"}, false), //
+ C("refract", utils::Vector{"vf", "vf", "f"}, false), //
+ C("reverseBits", utils::Vector{"u"}, false), //
+ C("round", utils::Vector{"f"}, false), //
+ C("select", utils::Vector{"f", "f", "b"}, false), //
+ C("sign", utils::Vector{"f"}, false), //
+ C("sin", utils::Vector{"f"}, false), //
+ C("sinh", utils::Vector{"f"}, false), //
+ C("smoothstep", utils::Vector{"f", "f", "f"}, false), //
+ C("sqrt", utils::Vector{"f"}, false), //
+ C("step", utils::Vector{"f", "f"}, false), //
+ C("tan", utils::Vector{"f"}, false), //
+ C("tanh", utils::Vector{"f"}, false), //
+ C("textureDimensions", utils::Vector{"t2d"}, false), //
+ C("textureGather", utils::Vector{"tdepth2d", "s2d", "vf2"}, false), //
+ C("textureGatherCompare", utils::Vector{"tdepth2d", "scomp", "vf2", "f"}, false), //
+ C("textureLoad", utils::Vector{"t2d", "vi2", "i"}, false), //
+ C("textureNumLayers", utils::Vector{"t2d_arr"}, false), //
+ C("textureNumLevels", utils::Vector{"t2d"}, false), //
+ C("textureNumSamples", utils::Vector{"t2d_multi"}, false), //
+ C("textureSampleCompareLevel", utils::Vector{"tdepth2d", "scomp", "vf2", "f"}, false), //
+ C("textureSampleGrad", utils::Vector{"t2d", "s2d", "vf2", "vf2", "vf2"}, false), //
+ C("textureSampleLevel", utils::Vector{"t2d", "s2d", "vf2", "f"}, false), //
+ C("transpose", utils::Vector{"m"}, false), //
+ C("trunc", utils::Vector{"f"}, false), //
+ C("unpack2x16float", utils::Vector{"u"}, false), //
+ C("unpack2x16snorm", utils::Vector{"u"}, false), //
+ C("unpack2x16unorm", utils::Vector{"u"}, false), //
+ C("unpack4x8snorm", utils::Vector{"u"}, false), //
+ C("unpack4x8unorm", utils::Vector{"u"}, false), //
+ C("storageBarrier", utils::Empty, false, ast::PipelineStage::kCompute), //
+ C("workgroupBarrier", utils::Empty, false, ast::PipelineStage::kCompute), //
+ C("textureSample", utils::Vector{"t2d", "s2d", "vf2"}, false), //
+ C("textureSampleBias", utils::Vector{"t2d", "s2d", "vf2", "f"}, false), //
+ C("textureSampleCompare", utils::Vector{"tdepth2d", "scomp", "vf2", "f"}, false), //
+ C("dpdx", utils::Vector{"f"}, false), //
+ C("dpdxCoarse", utils::Vector{"f"}, false), //
+ C("dpdxFine", utils::Vector{"f"}, false), //
+ C("dpdy", utils::Vector{"f"}, false), //
+ C("dpdyCoarse", utils::Vector{"f"}, false), //
+ C("dpdyFine", utils::Vector{"f"}, false), //
+ C("fwidth", utils::Vector{"f"}, false), //
+ C("fwidthCoarse", utils::Vector{"f"}, false), //
+ C("fwidthFine", utils::Vector{"f"}, false), //
+
+ // Side-effect builtins
+ C("atomicAdd", utils::Vector{"pa", "i"}, true), //
+ C("atomicAnd", utils::Vector{"pa", "i"}, true), //
+ C("atomicCompareExchangeWeak", utils::Vector{"pa", "i", "i"}, true), //
+ C("atomicExchange", utils::Vector{"pa", "i"}, true), //
+ C("atomicMax", utils::Vector{"pa", "i"}, true), //
+ C("atomicMin", utils::Vector{"pa", "i"}, true), //
+ C("atomicOr", utils::Vector{"pa", "i"}, true), //
+ C("atomicStore", utils::Vector{"pa", "i"}, true), //
+ C("atomicSub", utils::Vector{"pa", "i"}, true), //
+ C("atomicXor", utils::Vector{"pa", "i"}, true), //
+ C("textureStore", utils::Vector{"tstorage2d", "vi2", "vf4"}, true), //
+
+ // Unimplemented builtins
+ // C("quantizeToF16", utils::Vector{"f"}, false), //
+ // C("saturate", utils::Vector{"f"}, false), //
+ }));
+
+} // namespace builtin
+
TEST_F(SideEffectsTest, Call_Function) {
- Func("f", {}, ty.i32(), {Return(1_i)});
+ Func("f", utils::Empty, ty.i32(), utils::Vector{Return(1_i)});
auto* expr = Call("f");
WrapInFunction(expr);
@@ -185,7 +408,7 @@
}
TEST_F(SideEffectsTest, MemberAccessor_Struct_NoSE) {
- auto* s = Structure("S", {Member("m", ty.i32())});
+ auto* s = Structure("S", utils::Vector{Member("m", ty.i32())});
auto* var = Decl(Var("a", ty.Of(s)));
auto* expr = MemberAccessor("a", "m");
WrapInFunction(var, expr);
@@ -197,7 +420,7 @@
}
TEST_F(SideEffectsTest, MemberAccessor_Struct_SE) {
- auto* s = Structure("S", {Member("m", ty.i32())});
+ auto* s = Structure("S", utils::Vector{Member("m", ty.i32())});
MakeSideEffectFunc("se", [&] { return ty.Of(s); });
auto* expr = MemberAccessor(Call("se"), "m");
WrapInFunction(expr);
diff --git a/src/tint/resolver/source_variable_test.cc b/src/tint/resolver/source_variable_test.cc
index 2648e93..f80c980 100644
--- a/src/tint/resolver/source_variable_test.cc
+++ b/src/tint/resolver/source_variable_test.cc
@@ -128,7 +128,7 @@
TEST_F(ResolverSourceVariableTest, Parameter) {
auto* a = Param("a", ty.f32());
auto* expr = Expr(a);
- Func("foo", {a}, ty.void_(), {WrapInStatement(expr)});
+ Func("foo", utils::Vector{a}, ty.void_(), utils::Vector{WrapInStatement(expr)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -145,7 +145,8 @@
auto* expr_param = Expr(param);
auto* let = Let("b", nullptr, expr_param);
auto* expr_let = Expr("b");
- Func("foo", {param}, ty.void_(), {WrapInStatement(let), WrapInStatement(expr_let)});
+ Func("foo", utils::Vector{param}, ty.void_(),
+ utils::Vector{WrapInStatement(let), WrapInStatement(expr_let)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -213,7 +214,7 @@
// {
// a.f
// }
- auto* S = Structure("S", {Member("f", ty.f32())});
+ auto* S = Structure("S", utils::Vector{Member("f", ty.f32())});
auto* a = GlobalVar("a", ty.Of(S), ast::StorageClass::kPrivate);
auto* expr = MemberAccessor(a, "f");
WrapInFunction(expr);
diff --git a/src/tint/resolver/static_assert_test.cc b/src/tint/resolver/static_assert_test.cc
new file mode 100644
index 0000000..3cb67c9
--- /dev/null
+++ b/src/tint/resolver/static_assert_test.cc
@@ -0,0 +1,110 @@
+// Copyright 2022 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/resolver/resolver.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/resolver/resolver_test_helper.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::resolver {
+namespace {
+
+using ResolverStaticAssertTest = ResolverTest;
+
+TEST_F(ResolverStaticAssertTest, Global_True_Pass) {
+ GlobalStaticAssert(true);
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverStaticAssertTest, Global_False_Fail) {
+ GlobalStaticAssert(Source{{12, 34}}, false);
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
+}
+
+TEST_F(ResolverStaticAssertTest, Global_Const_Pass) {
+ GlobalConst("C", ty.bool_(), Expr(true));
+ GlobalStaticAssert("C");
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverStaticAssertTest, Global_Const_Fail) {
+ GlobalConst("C", ty.bool_(), Expr(false));
+ GlobalStaticAssert(Source{{12, 34}}, "C");
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
+}
+
+// TODO(crbug.com/tint/1581): Enable once the '<' operator is implemented for constant evaluation.
+TEST_F(ResolverStaticAssertTest, DISABLED_Global_LessThan_Pass) {
+ GlobalStaticAssert(LessThan(2_i, 3_i));
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+// TODO(crbug.com/tint/1581): Enable once the '<' operator is implemented for constant evaluation.
+TEST_F(ResolverStaticAssertTest, DISABLED_Global_LessThan_Fail) {
+ GlobalStaticAssert(Source{{12, 34}}, LessThan(4_i, 3_i));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
+}
+
+TEST_F(ResolverStaticAssertTest, Local_True_Pass) {
+ WrapInFunction(StaticAssert(true));
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverStaticAssertTest, Local_False_Fail) {
+ WrapInFunction(StaticAssert(Source{{12, 34}}, false));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
+}
+
+TEST_F(ResolverStaticAssertTest, Local_Const_Pass) {
+ GlobalConst("C", ty.bool_(), Expr(true));
+ WrapInFunction(StaticAssert("C"));
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverStaticAssertTest, Local_Const_Fail) {
+ GlobalConst("C", ty.bool_(), Expr(false));
+ WrapInFunction(StaticAssert(Source{{12, 34}}, "C"));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
+}
+
+TEST_F(ResolverStaticAssertTest, Local_NonConst) {
+ GlobalVar("V", ty.bool_(), Expr(true), ast::StorageClass::kPrivate);
+ WrapInFunction(StaticAssert(Expr(Source{{12, 34}}, "V")));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "12:34 error: static assertion condition must be a constant expression");
+}
+
+// TODO(crbug.com/tint/1581): Enable once the '<' operator is implemented for constant evaluation.
+TEST_F(ResolverStaticAssertTest, DISABLED_Local_LessThan_Pass) {
+ WrapInFunction(StaticAssert(LessThan(2_i, 3_i)));
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+// TODO(crbug.com/tint/1581): Enable once the '<' operator is implemented for constant evaluation.
+TEST_F(ResolverStaticAssertTest, DISABLED_Local_LessThan_Fail) {
+ WrapInFunction(StaticAssert(Source{{12, 34}}, LessThan(4_i, 3_i)));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
+}
+
+} // namespace
+} // namespace tint::resolver
diff --git a/src/tint/resolver/storage_class_layout_validation_test.cc b/src/tint/resolver/storage_class_layout_validation_test.cc
index 770361a..c55aece 100644
--- a/src/tint/resolver/storage_class_layout_validation_test.cc
+++ b/src/tint/resolver/storage_class_layout_validation_test.cc
@@ -34,8 +34,10 @@
// var<storage> a : S;
Structure(Source{{12, 34}}, "S",
- {Member("a", ty.f32(), {MemberSize(5)}),
- Member(Source{{34, 56}}, "b", ty.f32(), {MemberAlign(1)})});
+ utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberSize(5)}),
+ Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(1)}),
+ });
GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kStorage,
GroupAndBinding(0, 0));
@@ -62,8 +64,10 @@
// var<storage> a : S;
Structure(Source{{12, 34}}, "S",
- {Member("a", ty.f32(), {MemberSize(5)}),
- Member(Source{{34, 56}}, "b", ty.f32(), {MemberAlign(4)})});
+ utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberSize(5)}),
+ Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(4)}),
+ });
GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kStorage,
GroupAndBinding(0, 0));
@@ -85,10 +89,13 @@
// @group(0) @binding(0)
// var<uniform> a : Outer;
- Structure(Source{{12, 34}}, "Inner", {Member("scalar", ty.i32())});
+ Structure(Source{{12, 34}}, "Inner",
+ utils::Vector{
+ Member("scalar", ty.i32()),
+ });
Structure(Source{{34, 56}}, "Outer",
- {
+ utils::Vector{
Member("scalar", ty.f32()),
Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
});
@@ -126,12 +133,16 @@
// @group(0) @binding(0)
// var<uniform> a : Outer;
- Structure(Source{{12, 34}}, "Inner", {Member("scalar", ty.i32())});
+ Structure(Source{{12, 34}}, "Inner",
+ utils::Vector{
+ Member("scalar", ty.i32()),
+ });
Structure(Source{{34, 56}}, "Outer",
- {
+ utils::Vector{
Member("scalar", ty.f32()),
- Member(Source{{56, 78}}, "inner", ty.type_name("Inner"), {MemberAlign(16)}),
+ Member(Source{{56, 78}}, "inner", ty.type_name("Inner"),
+ utils::Vector{MemberAlign(16)}),
});
GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
@@ -154,7 +165,7 @@
Alias("Inner", ty.array(ty.f32(), 10_u, 16));
Structure(Source{{12, 34}}, "Outer",
- {
+ utils::Vector{
Member("scalar", ty.f32()),
Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
});
@@ -187,9 +198,10 @@
Alias("Inner", ty.array(ty.f32(), 10_u, 16));
Structure(Source{{12, 34}}, "Outer",
- {
+ utils::Vector{
Member("scalar", ty.f32()),
- Member(Source{{34, 56}}, "inner", ty.type_name("Inner"), {MemberAlign(16)}),
+ Member(Source{{34, 56}}, "inner", ty.type_name("Inner"),
+ utils::Vector{MemberAlign(16)}),
});
GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
@@ -214,10 +226,12 @@
// var<uniform> a : Outer;
Structure(Source{{12, 34}}, "Inner",
- {Member("scalar", ty.i32(), {MemberAlign(1), MemberSize(5)})});
+ utils::Vector{
+ Member("scalar", ty.i32(), utils::Vector{MemberAlign(1), MemberSize(5)}),
+ });
Structure(Source{{34, 56}}, "Outer",
- {
+ utils::Vector{
Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
Member(Source{{78, 90}}, "scalar", ty.i32()),
});
@@ -261,15 +275,15 @@
// var<uniform> a : Outer;
Structure(Source{{12, 34}}, "Inner",
- {
+ utils::Vector{
Member("a", ty.i32()),
Member("b", ty.i32()),
Member("c", ty.i32()),
- Member("scalar", ty.i32(), {MemberAlign(1), MemberSize(5)}),
+ Member("scalar", ty.i32(), utils::Vector{MemberAlign(1), MemberSize(5)}),
});
Structure(Source{{34, 56}}, "Outer",
- {
+ utils::Vector{
Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
Member(Source{{78, 90}}, "scalar", ty.i32()),
});
@@ -312,12 +326,14 @@
// var<uniform> a : Outer;
Structure(Source{{12, 34}}, "Inner",
- {Member("scalar", ty.i32(), {MemberAlign(1), MemberSize(5)})});
+ utils::Vector{
+ Member("scalar", ty.i32(), utils::Vector{MemberAlign(1), MemberSize(5)}),
+ });
Structure(Source{{34, 56}}, "Outer",
- {
+ utils::Vector{
Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
- Member(Source{{78, 90}}, "scalar", ty.i32(), {MemberAlign(16)}),
+ Member(Source{{78, 90}}, "scalar", ty.i32(), utils::Vector{MemberAlign(16)}),
});
GlobalVar(Source{{22, 34}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
@@ -336,7 +352,7 @@
// @group(0) @binding(0)
// var<uniform> a : ScalarPackedAtEndOfVec3;
- Structure("ScalarPackedAtEndOfVec3", {
+ Structure("ScalarPackedAtEndOfVec3", utils::Vector{
Member("v", ty.vec3(ty.f32())),
Member("s", ty.f32()),
});
@@ -362,7 +378,7 @@
Alias("Inner", ty.array(ty.f32(), 10_u));
Structure(Source{{12, 34}}, "Outer",
- {
+ utils::Vector{
Member("inner", ty.type_name(Source{{34, 56}}, "Inner")),
Member("scalar", ty.i32()),
});
@@ -396,7 +412,7 @@
Alias("Inner", ty.array(ty.vec2<f32>(), 10_u));
Structure(Source{{12, 34}}, "Outer",
- {
+ utils::Vector{
Member("inner", ty.type_name(Source{{34, 56}}, "Inner")),
Member("scalar", ty.i32()),
});
@@ -432,14 +448,14 @@
// @group(0) @binding(0)
// var<uniform> a : Outer;
- auto* array_elem = Structure("ArrayElem", {
+ auto* array_elem = Structure("ArrayElem", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.i32()),
});
Alias("Inner", ty.array(ty.Of(array_elem), 10_u));
Structure(Source{{12, 34}}, "Outer",
- {
+ utils::Vector{
Member("inner", ty.type_name(Source{{34, 56}}, "Inner")),
Member("scalar", ty.i32()),
});
@@ -480,7 +496,7 @@
// var<uniform> a : array<Outer, 4u>;
Structure(Source{{12, 34}}, "Outer",
- {
+ utils::Vector{
Member("inner", ty.array(Source{{34, 56}}, ty.array(ty.f32(), 4_u), 4_u)),
});
@@ -512,7 +528,7 @@
Alias("Inner", ty.array(ty.f32(), 10_u, 16));
Structure(Source{{12, 34}}, "Outer",
- {
+ utils::Vector{
Member("inner", ty.type_name(Source{{34, 56}}, "Inner")),
Member("scalar", ty.i32()),
});
@@ -523,5 +539,48 @@
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
+// Detect unaligned member for push constants buffers
+TEST_F(ResolverStorageClassLayoutValidationTest, PushConstant_UnalignedMember) {
+ // enable chromium_experimental_push_constant;
+ // struct S {
+ // @size(5) a : f32;
+ // @align(1) b : f32;
+ // };
+ // var<push_constant> a : S;
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ Structure(
+ Source{{12, 34}}, "S",
+ utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(5)}),
+ Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(1)})});
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kPushConstant);
+
+ ASSERT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(34:56 error: the offset of a struct member of type 'f32' in storage class 'push_constant' must be a multiple of 4 bytes, but 'b' is currently at offset 5. Consider setting @align(4) on this member
+12:34 note: see layout of struct:
+/* align(4) size(12) */ struct S {
+/* offset(0) align(4) size( 5) */ a : f32;
+/* offset(5) align(1) size( 4) */ b : f32;
+/* offset(9) align(1) size( 3) */ // -- implicit struct size padding --;
+/* */ };
+78:90 note: see declaration of variable)");
+}
+
+TEST_F(ResolverStorageClassLayoutValidationTest, PushConstant_Aligned) {
+ // enable chromium_experimental_push_constant;
+ // struct S {
+ // @size(5) a : f32;
+ // @align(4) b : f32;
+ // };
+ // var<push_constant> a : S;
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(5)}),
+ Member("b", ty.f32(), utils::Vector{MemberAlign(4)})});
+ GlobalVar("a", ty.type_name("S"), ast::StorageClass::kPushConstant);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/resolver/storage_class_validation_test.cc b/src/tint/resolver/storage_class_validation_test.cc
index f3e6f32..e1b3dab 100644
--- a/src/tint/resolver/storage_class_validation_test.cc
+++ b/src/tint/resolver/storage_class_validation_test.cc
@@ -55,7 +55,7 @@
}
TEST_F(ResolverStorageClassValidationTest, Private_RuntimeArrayInStruct) {
- auto* s = Structure("S", {Member("m", ty.array(ty.i32()))});
+ auto* s = Structure("S", utils::Vector{Member("m", ty.array(ty.i32()))});
GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
@@ -75,7 +75,7 @@
}
TEST_F(ResolverStorageClassValidationTest, Workgroup_RuntimeArrayInStruct) {
- auto* s = Structure("S", {Member("m", ty.array(ty.i32()))});
+ auto* s = Structure("S", utils::Vector{Member("m", ty.array(ty.i32()))});
GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kWorkgroup);
EXPECT_FALSE(r()->Resolve());
@@ -88,7 +88,7 @@
TEST_F(ResolverStorageClassValidationTest, StorageBufferBool) {
// var<storage> g : bool;
GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -106,7 +106,7 @@
// var<storage, read> g : a;
auto* a = Alias("a", ty.bool_());
GlobalVar(Source{{56, 78}}, "g", ty.Of(a), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -126,7 +126,7 @@
Enable(ast::Extension::kF16);
GlobalVar("g", ty.f16(Source{{56, 78}}), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -145,7 +145,7 @@
auto* a = Alias("a", ty.f16());
GlobalVar("g", ty.type_name(Source{{56, 78}}, a->name), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -161,7 +161,7 @@
// var<storage> g : vec4<f16>;
Enable(ast::Extension::kF16);
GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of<f16>(), 4u), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -178,10 +178,10 @@
// var<storage, read> g : array<S, 3u>;
Enable(ast::Extension::kF16);
- auto* s = Structure("S", {Member("a", ty.f16(Source{{56, 78}}))});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f16(Source{{56, 78}}))});
auto* a = ty.array(ty.Of(s), 3_u);
GlobalVar("g", a, ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -197,9 +197,9 @@
// var<storage, read> g : S;
Enable(ast::Extension::kF16);
- auto* s = Structure("S", {Member("x", ty.f16(Source{{12, 34}}))});
+ auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))});
GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -216,11 +216,11 @@
// var<storage, read> g : a1;
Enable(ast::Extension::kF16);
- auto* s = Structure("S", {Member("x", ty.f16(Source{{12, 34}}))});
+ auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))});
auto* a1 = Alias("a1", ty.Of(s));
auto* a2 = Alias("a2", ty.Of(a1));
GlobalVar("g", ty.Of(a2), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -235,7 +235,7 @@
// var<storage> g : ptr<private, f32>;
GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -251,7 +251,7 @@
TEST_F(ResolverStorageClassValidationTest, StorageBufferIntScalar) {
// var<storage> g : i32;
GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -262,7 +262,7 @@
TEST_F(ResolverStorageClassValidationTest, StorageBufferVectorF32) {
// var<storage> g : vec4<f32>;
GlobalVar(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -272,10 +272,10 @@
TEST_F(ResolverStorageClassValidationTest, StorageBufferArrayF32) {
// var<storage, read> g : array<S, 3u>;
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
auto* a = ty.array(ty.Of(s), 3_u);
GlobalVar(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -324,9 +324,9 @@
TEST_F(ResolverStorageClassValidationTest, StorageBufferStructI32) {
// struct S { x : i32 };
// var<storage, read> g : S;
- auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
+ auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -338,11 +338,11 @@
// struct S { x : i32 };
// type a1 = S;
// var<storage, read> g : a1;
- auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
+ auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
auto* a1 = Alias("a1", ty.Of(s));
auto* a2 = Alias("a2", ty.Of(a1));
GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -354,10 +354,10 @@
// struct S { m: array<f32>; };
// @group(0) @binding(0) var<uniform, > svar : S;
- auto* s = Structure(Source{{12, 34}}, "S", {Member("m", ty.array<i32>())});
+ auto* s = Structure(Source{{12, 34}}, "S", utils::Vector{Member("m", ty.array<i32>())});
GlobalVar(Source{{56, 78}}, "svar", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -372,7 +372,7 @@
TEST_F(ResolverStorageClassValidationTest, UniformBufferBool) {
// var<uniform> g : bool;
GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -390,7 +390,7 @@
// var<uniform> g : a;
auto* a = Alias("a", ty.bool_());
GlobalVar(Source{{56, 78}}, "g", ty.Of(a), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -410,7 +410,7 @@
Enable(ast::Extension::kF16);
GlobalVar("g", ty.f16(Source{{56, 78}}), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -429,7 +429,7 @@
auto* a = Alias("a", ty.f16());
GlobalVar("g", ty.type_name(Source{{56, 78}}, a->name), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -445,7 +445,7 @@
// var<uniform> g : vec4<f16>;
Enable(ast::Extension::kF16);
GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of<f16>(), 4u), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -463,10 +463,11 @@
// var<uniform> g : array<S, 3u>;
Enable(ast::Extension::kF16);
- auto* s = Structure("S", {Member("a", ty.f16(Source{{56, 78}}), {MemberSize(16)})});
+ auto* s = Structure(
+ "S", utils::Vector{Member("a", ty.f16(Source{{56, 78}}), utils::Vector{MemberSize(16)})});
auto* a = ty.array(ty.Of(s), 3_u);
GlobalVar("g", a, ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -482,9 +483,9 @@
// var<uniform> g : S;
Enable(ast::Extension::kF16);
- auto* s = Structure("S", {Member("x", ty.f16(Source{{12, 34}}))});
+ auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))});
GlobalVar("g", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -501,10 +502,10 @@
// var<uniform> g : a1;
Enable(ast::Extension::kF16);
- auto* s = Structure("S", {Member("x", ty.f16(Source{{12, 34}}))});
+ auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))});
auto* a1 = Alias("a1", ty.Of(s));
GlobalVar("g", ty.Of(a1), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -519,7 +520,7 @@
// var<uniform> g : ptr<private, f32>;
GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -535,7 +536,7 @@
TEST_F(ResolverStorageClassValidationTest, UniformBufferIntScalar) {
// var<uniform> g : i32;
GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -546,7 +547,7 @@
TEST_F(ResolverStorageClassValidationTest, UniformBufferVectorF32) {
// var<uniform> g : vec4<f32>;
GlobalVar(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -559,10 +560,10 @@
// @size(16) f : f32;
// }
// var<uniform> g : array<S, 3u>;
- auto* s = Structure("S", {Member("a", ty.f32(), {MemberSize(16)})});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(16)})});
auto* a = ty.array(ty.Of(s), 3_u);
GlobalVar(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -573,9 +574,9 @@
TEST_F(ResolverStorageClassValidationTest, UniformBufferStructI32) {
// struct S { x : i32 };
// var<uniform> g : S;
- auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
+ auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -587,10 +588,10 @@
// struct S { x : i32 };
// type a1 = S;
// var<uniform> g : a1;
- auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
+ auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
auto* a1 = Alias("a1", ty.Of(s));
GlobalVar(Source{{56, 78}}, "g", ty.Of(a1), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -598,5 +599,89 @@
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
+TEST_F(ResolverStorageClassValidationTest, PushConstantBool) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> g : bool;
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kPushConstant);
+
+ ASSERT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(56:78 error: Type 'bool' cannot be used in storage class 'push_constant' as it is non-host-shareable
+56:78 note: while instantiating 'var' g)");
+}
+
+TEST_F(ResolverStorageClassValidationTest, PushConstantF16) {
+ // enable chromium_experimental_push_constant;
+ // enable f16;
+ // var<push_constant> g : f16;
+ Enable(ast::Extension::kF16);
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar("g", ty.f16(Source{{56, 78}}), ast::StorageClass::kPushConstant);
+
+ ASSERT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "56:78 error: using f16 types in 'push_constant' storage class is not "
+ "implemented yet");
+}
+
+TEST_F(ResolverStorageClassValidationTest, PushConstantPointer) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> g : ptr<private, f32>;
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
+ ast::StorageClass::kPushConstant);
+
+ ASSERT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in storage class 'push_constant' as it is non-host-shareable
+56:78 note: while instantiating 'var' g)");
+}
+
+TEST_F(ResolverStorageClassValidationTest, PushConstantIntScalar) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> g : i32;
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar("g", ty.i32(), ast::StorageClass::kPushConstant);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverStorageClassValidationTest, PushConstantVectorF32) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> g : vec4<f32>;
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPushConstant);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverStorageClassValidationTest, PushConstantArrayF32) {
+ // enable chromium_experimental_push_constant;
+ // struct S { a : f32}
+ // var<push_constant> g : array<S, 3u>;
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
+ auto* a = ty.array(ty.Of(s), 3_u);
+ GlobalVar("g", a, ast::StorageClass::kPushConstant);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverStorageClassValidationTest, PushConstantWithInitializer) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> a : u32 = 0u;
+ Enable(ast::Extension::kChromiumExperimentalPushConstant);
+ GlobalVar(Source{{1u, 2u}}, "a", ty.u32(), ast::StorageClass::kPushConstant,
+ Expr(Source{{3u, 4u}}, u32(0)));
+
+ ASSERT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(1:2 error: var of storage class 'push_constant' cannot have an initializer. var initializers are only supported for the storage classes 'private' and 'function')");
+}
+
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/resolver/struct_layout_test.cc b/src/tint/resolver/struct_layout_test.cc
index 73ecd4e..59faf8d 100644
--- a/src/tint/resolver/struct_layout_test.cc
+++ b/src/tint/resolver/struct_layout_test.cc
@@ -26,7 +26,7 @@
using ResolverStructLayoutTest = ResolverTest;
TEST_F(ResolverStructLayoutTest, Scalars) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.u32()),
Member("c", ty.i32()),
@@ -57,7 +57,7 @@
TEST_F(ResolverStructLayoutTest, ScalarsWithF16) {
Enable(ast::Extension::kF16);
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.f16()),
Member("c", ty.u32()),
@@ -109,7 +109,7 @@
auto* alias_a = Alias("a", ty.f32());
auto* alias_b = Alias("b", ty.f32());
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.Of(alias_a)),
Member("b", ty.Of(alias_b)),
});
@@ -136,7 +136,7 @@
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayStaticSize) {
Enable(ast::Extension::kF16);
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.array<i32, 3>()),
Member("b", ty.array<f32, 5>()),
Member("c", ty.array<f16, 7>()),
@@ -176,7 +176,7 @@
TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayStaticSize) {
Enable(ast::Extension::kF16);
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.array<i32, 3>(/*stride*/ 8)),
Member("b", ty.array<f32, 5>(/*stride*/ 16)),
Member("c", ty.array<f16, 7>(/*stride*/ 4)),
@@ -214,7 +214,7 @@
}
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayRuntimeSized) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("c", ty.array<f32>()),
});
@@ -235,7 +235,7 @@
}
TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayRuntimeSized) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("c", ty.array<f32>(/*stride*/ 32)),
});
@@ -258,7 +258,7 @@
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfExplicitStrideArray) {
auto* inner = ty.array<i32, 2>(/*stride*/ 16); // size: 32
auto* outer = ty.array(inner, 12_u); // size: 12 * 32
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("c", outer),
});
@@ -279,13 +279,13 @@
}
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfStructure) {
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec2<i32>()),
Member("b", ty.vec3<i32>()),
Member("c", ty.vec4<i32>()),
}); // size: 48
auto* outer = ty.array(ty.Of(inner), 12_u); // size: 12 * 48
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("c", outer),
});
@@ -306,7 +306,7 @@
}
TEST_F(ResolverStructLayoutTest, Vector) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.vec2<i32>()),
Member("b", ty.vec3<i32>()),
Member("c", ty.vec4<i32>()),
@@ -337,7 +337,7 @@
TEST_F(ResolverStructLayoutTest, Matrix) {
Enable(ast::Extension::kF16);
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a_1", ty.mat2x2<f32>()),
Member("a_2", ty.mat2x2<f16>()),
Member("b_1", ty.mat2x3<f32>()),
@@ -427,10 +427,10 @@
}
TEST_F(ResolverStructLayoutTest, NestedStruct) {
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.mat3x3<f32>()),
});
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.Of(inner)),
Member("c", ty.i32()),
@@ -459,16 +459,16 @@
}
TEST_F(ResolverStructLayoutTest, SizeAttributes) {
- auto* inner = Structure("Inner", {
- Member("a", ty.f32(), {MemberSize(8)}),
- Member("b", ty.f32(), {MemberSize(16)}),
- Member("c", ty.f32(), {MemberSize(8)}),
+ auto* inner = Structure("Inner", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberSize(8)}),
+ Member("b", ty.f32(), utils::Vector{MemberSize(16)}),
+ Member("c", ty.f32(), utils::Vector{MemberSize(8)}),
});
- auto* s = Structure("S", {
- Member("a", ty.f32(), {MemberSize(4)}),
- Member("b", ty.u32(), {MemberSize(8)}),
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberSize(4)}),
+ Member("b", ty.u32(), utils::Vector{MemberSize(8)}),
Member("c", ty.Of(inner)),
- Member("d", ty.i32(), {MemberSize(32)}),
+ Member("d", ty.i32(), utils::Vector{MemberSize(32)}),
});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -497,16 +497,16 @@
}
TEST_F(ResolverStructLayoutTest, AlignAttributes) {
- auto* inner = Structure("Inner", {
- Member("a", ty.f32(), {MemberAlign(8)}),
- Member("b", ty.f32(), {MemberAlign(16)}),
- Member("c", ty.f32(), {MemberAlign(4)}),
+ auto* inner = Structure("Inner", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberAlign(8)}),
+ Member("b", ty.f32(), utils::Vector{MemberAlign(16)}),
+ Member("c", ty.f32(), utils::Vector{MemberAlign(4)}),
});
- auto* s = Structure("S", {
- Member("a", ty.f32(), {MemberAlign(4)}),
- Member("b", ty.u32(), {MemberAlign(8)}),
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberAlign(4)}),
+ Member("b", ty.u32(), utils::Vector{MemberAlign(8)}),
Member("c", ty.Of(inner)),
- Member("d", ty.i32(), {MemberAlign(32)}),
+ Member("d", ty.i32(), utils::Vector{MemberAlign(32)}),
});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -535,8 +535,8 @@
}
TEST_F(ResolverStructLayoutTest, StructWithLotsOfPadding) {
- auto* s = Structure("S", {
- Member("a", ty.i32(), {MemberAlign(1024)}),
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.i32(), utils::Vector{MemberAlign(1024)}),
});
ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/struct_pipeline_stage_use_test.cc b/src/tint/resolver/struct_pipeline_stage_use_test.cc
index 58c7cae..acf30f6 100644
--- a/src/tint/resolver/struct_pipeline_stage_use_test.cc
+++ b/src/tint/resolver/struct_pipeline_stage_use_test.cc
@@ -29,7 +29,7 @@
using ResolverPipelineStageUseTest = ResolverTest;
TEST_F(ResolverPipelineStageUseTest, UnusedStruct) {
- auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0)})});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -39,9 +39,9 @@
}
TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointParam) {
- auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0)})});
- Func("foo", {Param("param", ty.Of(s))}, ty.void_(), {}, {});
+ Func("foo", utils::Vector{Param("param", ty.Of(s))}, ty.void_(), utils::Empty, utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -51,9 +51,10 @@
}
TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointReturnType) {
- auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0)})});
- Func("foo", {}, ty.Of(s), {Return(Construct(ty.Of(s), Expr(0_f)))}, {});
+ Func("foo", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s), Expr(0_f)))},
+ utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -63,10 +64,12 @@
}
TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderParam) {
- auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0)})});
- Func("main", {Param("param", ty.Of(s))}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
- {Stage(ast::PipelineStage::kVertex)}, {Builtin(ast::BuiltinValue::kPosition)});
+ Func("main", utils::Vector{Param("param", ty.Of(s))}, ty.vec4<f32>(),
+ utils::Vector{Return(Construct(ty.vec4<f32>()))},
+ utils::Vector{Stage(ast::PipelineStage::kVertex)},
+ utils::Vector{Builtin(ast::BuiltinValue::kPosition)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -78,9 +81,11 @@
TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderReturnType) {
auto* s =
- Structure("S", {Member("a", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)})});
+ Structure("S", utils::Vector{Member("a", ty.vec4<f32>(),
+ utils::Vector{Builtin(ast::BuiltinValue::kPosition)})});
- Func("main", {}, ty.Of(s), {Return(Construct(ty.Of(s)))}, {Stage(ast::PipelineStage::kVertex)});
+ Func("main", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s)))},
+ utils::Vector{Stage(ast::PipelineStage::kVertex)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -91,10 +96,10 @@
}
TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderParam) {
- auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0)})});
- Func("main", {Param("param", ty.Of(s))}, ty.void_(), {},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Vector{Param("param", ty.Of(s))}, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -105,10 +110,10 @@
}
TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderReturnType) {
- auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0)})});
- Func("main", {}, ty.Of(s), {Return(Construct(ty.Of(s), Expr(0_f)))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s), Expr(0_f)))},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -120,10 +125,11 @@
TEST_F(ResolverPipelineStageUseTest, StructUsedAsComputeShaderParam) {
auto* s = Structure(
- "S", {Member("a", ty.u32(), {Builtin(ast::BuiltinValue::kLocalInvocationIndex)})});
+ "S", utils::Vector{Member(
+ "a", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kLocalInvocationIndex)})});
- Func("main", {Param("param", ty.Of(s))}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ Func("main", utils::Vector{Param("param", ty.Of(s))}, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -135,13 +141,14 @@
TEST_F(ResolverPipelineStageUseTest, StructUsedMultipleStages) {
auto* s =
- Structure("S", {Member("a", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)})});
+ Structure("S", utils::Vector{Member("a", ty.vec4<f32>(),
+ utils::Vector{Builtin(ast::BuiltinValue::kPosition)})});
- Func("vert_main", {}, ty.Of(s), {Return(Construct(ty.Of(s)))},
- {Stage(ast::PipelineStage::kVertex)});
+ Func("vert_main", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s)))},
+ utils::Vector{Stage(ast::PipelineStage::kVertex)});
- Func("frag_main", {Param("param", ty.Of(s))}, ty.void_(), {},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("frag_main", utils::Vector{Param("param", ty.Of(s))}, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -153,11 +160,11 @@
}
TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamViaAlias) {
- auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0)})});
auto* s_alias = Alias("S_alias", ty.Of(s));
- Func("main", {Param("param", ty.Of(s_alias))}, ty.void_(), {},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Vector{Param("param", ty.Of(s_alias))}, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -168,11 +175,12 @@
}
TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeViaAlias) {
- auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0)})});
auto* s_alias = Alias("S_alias", ty.Of(s));
- Func("main", {}, ty.Of(s_alias), {Return(Construct(ty.Of(s_alias), Expr(0_f)))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.Of(s_alias),
+ utils::Vector{Return(Construct(ty.Of(s_alias), Expr(0_f)))},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/struct_storage_class_use_test.cc b/src/tint/resolver/struct_storage_class_use_test.cc
index 5a929a5..d58c906 100644
--- a/src/tint/resolver/struct_storage_class_use_test.cc
+++ b/src/tint/resolver/struct_storage_class_use_test.cc
@@ -28,7 +28,7 @@
using ResolverStorageClassUseTest = ResolverTest;
TEST_F(ResolverStorageClassUseTest, UnreachableStruct) {
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -38,9 +38,9 @@
}
TEST_F(ResolverStorageClassUseTest, StructReachableFromParameter) {
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
- Func("f", {Param("param", ty.Of(s))}, ty.void_(), {}, {});
+ Func("f", utils::Vector{Param("param", ty.Of(s))}, ty.void_(), utils::Empty, utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -50,9 +50,9 @@
}
TEST_F(ResolverStorageClassUseTest, StructReachableFromReturnType) {
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
- Func("f", {}, ty.Of(s), {Return(Construct(ty.Of(s)))}, {});
+ Func("f", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s)))}, utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -62,7 +62,7 @@
}
TEST_F(ResolverStorageClassUseTest, StructReachableFromGlobal) {
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
@@ -74,7 +74,7 @@
}
TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalAlias) {
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
auto* a = Alias("A", ty.Of(s));
GlobalVar("g", ty.Of(a), ast::StorageClass::kPrivate);
@@ -86,8 +86,8 @@
}
TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalStruct) {
- auto* s = Structure("S", {Member("a", ty.f32())});
- auto* o = Structure("O", {Member("a", ty.Of(s))});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
+ auto* o = Structure("O", utils::Vector{Member("a", ty.Of(s))});
GlobalVar("g", ty.Of(o), ast::StorageClass::kPrivate);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -98,7 +98,7 @@
}
TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalArray) {
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
auto* a = ty.array(ty.Of(s), 3_u);
GlobalVar("g", a, ast::StorageClass::kPrivate);
@@ -110,7 +110,7 @@
}
TEST_F(ResolverStorageClassUseTest, StructReachableFromLocal) {
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
WrapInFunction(Var("g", ty.Of(s)));
@@ -122,7 +122,7 @@
}
TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalAlias) {
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
auto* a = Alias("A", ty.Of(s));
WrapInFunction(Var("g", ty.Of(a)));
@@ -134,8 +134,8 @@
}
TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalStruct) {
- auto* s = Structure("S", {Member("a", ty.f32())});
- auto* o = Structure("O", {Member("a", ty.Of(s))});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
+ auto* o = Structure("O", utils::Vector{Member("a", ty.Of(s))});
WrapInFunction(Var("g", ty.Of(o)));
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -146,7 +146,7 @@
}
TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalArray) {
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
auto* a = ty.array(ty.Of(s), 3_u);
WrapInFunction(Var("g", a));
@@ -158,14 +158,14 @@
}
TEST_F(ResolverStorageClassUseTest, StructMultipleStorageClassUses) {
- auto* s = Structure("S", {Member("a", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
GlobalVar("x", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
GlobalVar("y", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(0u),
});
diff --git a/src/tint/resolver/type_constructor_validation_test.cc b/src/tint/resolver/type_constructor_validation_test.cc
index fe1973b..33c15f3 100644
--- a/src/tint/resolver/type_constructor_validation_test.cc
+++ b/src/tint/resolver/type_constructor_validation_test.cc
@@ -186,8 +186,8 @@
Enable(ast::Extension::kF16);
- Func("foo", {}, params.create_rhs_ast_type(*this),
- {Return(Construct(params.create_rhs_ast_type(*this)))}, {});
+ Func("foo", utils::Empty, params.create_rhs_ast_type(*this),
+ utils::Vector{Return(Construct(params.create_rhs_ast_type(*this)))}, {});
auto* a = Var("a", nullptr, Call("foo"));
// Self-assign 'a' to force the expression to be resolved so we can test its
@@ -2474,10 +2474,10 @@
const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns - 1; i++) {
auto* vec_type = param.create_column_ast_type(*this);
- args.push_back(Construct(vec_type));
+ args.Push(Construct(vec_type));
if (i > 0) {
args_tys << ", ";
}
@@ -2503,9 +2503,9 @@
const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns * param.rows - 1; i++) {
- args.push_back(Construct(param.create_element_ast_type(*this)));
+ args.Push(Construct(param.create_element_ast_type(*this)));
if (i > 0) {
args_tys << ", ";
}
@@ -2531,10 +2531,10 @@
const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns + 1; i++) {
auto* vec_type = param.create_column_ast_type(*this);
- args.push_back(Construct(vec_type));
+ args.Push(Construct(vec_type));
if (i > 0) {
args_tys << ", ";
}
@@ -2560,9 +2560,9 @@
const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns * param.rows + 1; i++) {
- args.push_back(Construct(param.create_element_ast_type(*this)));
+ args.Push(Construct(param.create_element_ast_type(*this)));
if (i > 0) {
args_tys << ", ";
}
@@ -2587,10 +2587,10 @@
Enable(ast::Extension::kF16);
std::stringstream args_tys;
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = ty.vec<u32>(param.rows);
- args.push_back(Construct(vec_type));
+ args.Push(Construct(vec_type));
if (i > 0) {
args_tys << ", ";
}
@@ -2615,9 +2615,9 @@
Enable(ast::Extension::kF16);
std::stringstream args_tys;
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns; i++) {
- args.push_back(Expr(1_u));
+ args.Push(Expr(1_u));
if (i > 0) {
args_tys << ", ";
}
@@ -2648,10 +2648,10 @@
const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns; i++) {
auto* valid_vec_type = param.create_column_ast_type(*this);
- args.push_back(Construct(valid_vec_type));
+ args.Push(Construct(valid_vec_type));
if (i > 0) {
args_tys << ", ";
}
@@ -2659,7 +2659,7 @@
}
const size_t kInvalidLoc = 2 * (param.columns - 1);
auto* invalid_vec_type = ty.vec(param.create_element_ast_type(*this), param.rows - 1);
- args.push_back(Construct(Source{{12, kInvalidLoc}}, invalid_vec_type));
+ args.Push(Construct(Source{{12, kInvalidLoc}}, invalid_vec_type));
args_tys << ", vec" << (param.rows - 1) << "<" + element_type_name + ">";
auto* matrix_type = param.create_mat_ast_type(*this);
@@ -2686,17 +2686,17 @@
const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns; i++) {
auto* valid_vec_type = param.create_column_ast_type(*this);
- args.push_back(Construct(valid_vec_type));
+ args.Push(Construct(valid_vec_type));
if (i > 0) {
args_tys << ", ";
}
args_tys << "vec" << param.rows << "<" + element_type_name + ">";
}
auto* invalid_vec_type = ty.vec(param.create_element_ast_type(*this), param.rows + 1);
- args.push_back(Construct(invalid_vec_type));
+ args.Push(Construct(invalid_vec_type));
args_tys << ", vec" << (param.rows + 1) << "<" + element_type_name + ">";
auto* matrix_type = param.create_mat_ast_type(*this);
@@ -2731,10 +2731,10 @@
Enable(ast::Extension::kF16);
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 4> args;
for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = param.create_column_ast_type(*this);
- args.push_back(Construct(vec_type));
+ args.Push(Construct(vec_type));
}
auto* matrix_type = param.create_mat_ast_type(*this);
@@ -2752,9 +2752,9 @@
Enable(ast::Extension::kF16);
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 16> args;
for (uint32_t i = 0; i < param.columns * param.rows; i++) {
- args.push_back(Construct(param.create_element_ast_type(*this)));
+ args.Push(Construct(param.create_element_ast_type(*this)));
}
auto* matrix_type = param.create_mat_ast_type(*this);
@@ -2775,10 +2775,10 @@
auto* elem_type_alias = Alias("ElemType", param.create_element_ast_type(*this));
std::stringstream args_tys;
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 4> args;
for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = ty.vec(ty.u32(), param.rows);
- args.push_back(Construct(vec_type));
+ args.Push(Construct(vec_type));
if (i > 0) {
args_tys << ", ";
}
@@ -2804,10 +2804,10 @@
auto* elem_type_alias = Alias("ElemType", param.create_element_ast_type(*this));
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = param.create_column_ast_type(*this);
- args.push_back(Construct(vec_type));
+ args.Push(Construct(vec_type));
}
auto* matrix_type = ty.mat(ty.Of(elem_type_alias), param.columns, param.rows);
@@ -2837,9 +2837,9 @@
auto* vec_type = param.create_column_ast_type(*this);
auto* vec_alias = Alias("ColVectorAlias", vec_type);
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 4> args;
for (uint32_t i = 0; i < param.columns; i++) {
- args.push_back(Construct(ty.Of(vec_alias)));
+ args.Push(Construct(ty.Of(vec_alias)));
}
auto* tc = Construct(Source{}, matrix_type, std::move(args));
@@ -2857,10 +2857,10 @@
auto* u32_type_alias = Alias("UnsignedInt", ty.u32());
std::stringstream args_tys;
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 4> args;
for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = ty.vec(ty.Of(u32_type_alias), param.rows);
- args.push_back(Construct(vec_type));
+ args.Push(Construct(vec_type));
if (i > 0) {
args_tys << ", ";
}
@@ -2882,10 +2882,10 @@
auto* elem_type_alias = Alias("ElemType", param.create_element_ast_type(*this));
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 4> args;
for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = ty.vec(ty.Of(elem_type_alias), param.rows);
- args.push_back(Construct(vec_type));
+ args.Push(Construct(vec_type));
}
auto* matrix_type = param.create_mat_ast_type(*this);
@@ -2900,9 +2900,9 @@
Enable(ast::Extension::kF16);
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns; i++) {
- args.push_back(Construct(param.create_column_ast_type(*this)));
+ args.Push(Construct(param.create_column_ast_type(*this)));
}
auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
@@ -2917,9 +2917,9 @@
Enable(ast::Extension::kF16);
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.rows * param.columns; i++) {
- args.push_back(param.create_element_ast_value(*this, static_cast<double>(i)));
+ args.Push(param.create_element_ast_value(*this, static_cast<double>(i)));
}
auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
@@ -2937,17 +2937,17 @@
err << "12:34 error: no matching constructor for mat" << param.columns << "x" << param.rows
<< "(";
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
for (uint32_t i = 0; i < param.columns; i++) {
if (i > 0) {
err << ", ";
}
if (i == 1) {
// Odd one out
- args.push_back(Construct(ty.vec<i32>(param.rows)));
+ args.Push(Construct(ty.vec<i32>(param.rows)));
err << "vec" << param.rows << "<i32>";
} else {
- args.push_back(Construct(param.create_column_ast_type(*this)));
+ args.Push(Construct(param.create_column_ast_type(*this)));
err << "vec" << param.rows << "<" + param.get_element_type_name() + ">";
}
}
@@ -2968,16 +2968,16 @@
err << "12:34 error: no matching constructor for mat" << param.columns << "x" << param.rows
<< "(";
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 16> args;
for (uint32_t i = 0; i < param.rows * param.columns; i++) {
if (i > 0) {
err << ", ";
}
if (i == 3) {
- args.push_back(Expr(static_cast<i32>(i))); // The odd one out
+ args.Push(Expr(static_cast<i32>(i))); // The odd one out
err << "i32";
} else {
- args.push_back(param.create_element_ast_value(*this, static_cast<double>(i)));
+ args.Push(param.create_element_ast_value(*this, static_cast<double>(i)));
err << param.get_element_type_name();
}
}
@@ -3054,14 +3054,14 @@
Enable(ast::Extension::kF16);
- ast::StructMemberList members;
- ast::ExpressionList values;
+ utils::Vector<const ast::StructMember*, 16> members;
+ utils::Vector<const ast::Expression*, 16> values;
for (uint32_t i = 0; i < N; i++) {
auto* struct_type = str_params.ast(*this);
- members.push_back(Member("member_" + std::to_string(i), struct_type));
+ members.Push(Member("member_" + std::to_string(i), struct_type));
if (i < N - 1) {
auto* ctor_value_expr = str_params.expr(*this, 0);
- values.push_back(ctor_value_expr);
+ values.Push(ctor_value_expr);
}
}
auto* s = Structure("s", members);
@@ -3079,15 +3079,15 @@
Enable(ast::Extension::kF16);
- ast::StructMemberList members;
- ast::ExpressionList values;
+ utils::Vector<const ast::StructMember*, 16> members;
+ utils::Vector<const ast::Expression*, 8> values;
for (uint32_t i = 0; i < N + 1; i++) {
if (i < N) {
auto* struct_type = str_params.ast(*this);
- members.push_back(Member("member_" + std::to_string(i), struct_type));
+ members.Push(Member("member_" + std::to_string(i), struct_type));
}
auto* ctor_value_expr = str_params.expr(*this, 0);
- values.push_back(ctor_value_expr);
+ values.Push(ctor_value_expr);
}
auto* s = Structure("s", members);
auto* tc = Construct(Source{{12, 34}}, ty.Of(s), values);
@@ -3116,17 +3116,17 @@
return;
}
- ast::StructMemberList members;
- ast::ExpressionList values;
+ utils::Vector<const ast::StructMember*, 16> members;
+ utils::Vector<const ast::Expression*, 8> values;
// make the last value of the constructor to have a different type
uint32_t constructor_value_with_different_type = N - 1;
for (uint32_t i = 0; i < N; i++) {
auto* struct_type = str_params.ast(*this);
- members.push_back(Member("member_" + std::to_string(i), struct_type));
+ members.Push(Member("member_" + std::to_string(i), struct_type));
auto* ctor_value_expr = (i == constructor_value_with_different_type)
? ctor_params.expr(*this, 0)
: str_params.expr(*this, 0);
- values.push_back(ctor_value_expr);
+ values.Push(ctor_value_expr);
}
auto* s = Structure("s", members);
auto* tc = Construct(ty.Of(s), values);
@@ -3149,12 +3149,12 @@
TEST_F(ResolverTypeConstructorValidationTest, Struct_Nested) {
auto* inner_m = Member("m", ty.i32());
- auto* inner_s = Structure("inner_s", {inner_m});
+ auto* inner_s = Structure("inner_s", utils::Vector{inner_m});
auto* m0 = Member("m0", ty.i32());
auto* m1 = Member("m1", ty.Of(inner_s));
auto* m2 = Member("m2", ty.i32());
- auto* s = Structure("s", {m0, m1, m2});
+ auto* s = Structure("s", utils::Vector{m0, m1, m2});
auto* tc = Construct(Source{{12, 34}}, ty.Of(s), 1_i, 1_i, 1_i);
WrapInFunction(tc);
@@ -3166,14 +3166,14 @@
TEST_F(ResolverTypeConstructorValidationTest, Struct) {
auto* m = Member("m", ty.i32());
- auto* s = Structure("MyInputs", {m});
+ auto* s = Structure("MyInputs", utils::Vector{m});
auto* tc = Construct(Source{{12, 34}}, ty.Of(s));
WrapInFunction(tc);
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverTypeConstructorValidationTest, Struct_Empty) {
- auto* str = Structure("S", {
+ auto* str = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
Member("c", ty.vec3<i32>()),
@@ -3200,7 +3200,7 @@
}
TEST_F(ResolverTypeConstructorValidationTest, NonConstructibleType_AtomicStructMember) {
- auto* str = Structure("S", {Member("a", ty.atomic(ty.i32()))});
+ auto* str = Structure("S", utils::Vector{Member("a", ty.atomic(ty.i32()))});
WrapInFunction(Assign(Phony(), Construct(Source{{12, 34}}, ty.Of(str))));
EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index e746e51..d7c2e64 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -75,7 +75,10 @@
TEST_F(ResolverTypeValidationTest, GlobalOverrideNoConstructor_Pass) {
// @id(0) override a :i32;
- Override(Source{{12, 34}}, "a", ty.i32(), nullptr, ast::AttributeList{Id(0)});
+ Override(Source{{12, 34}}, "a", ty.i32(), nullptr,
+ utils::Vector{
+ Id(0),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -111,8 +114,8 @@
// }
// var a: f32 = 2.1;
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.f32(), ast::StorageClass::kNone, Expr(2_f))),
});
@@ -163,14 +166,14 @@
auto* var1 = Var("a", ty.f32(), ast::StorageClass::kNone, Expr(1_f));
- Func("func0", {}, ty.void_(),
- {
+ Func("func0", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Source{{12, 34}}, var0),
Return(),
});
- Func("func1", {}, ty.void_(),
- {
+ Func("func1", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Source{{13, 34}}, var1),
Return(),
});
@@ -383,11 +386,11 @@
auto* var = Var(Source{{12, 34}}, "a", ty.array<i32>(), ast::StorageClass::kNone);
- Func("func", {}, ty.void_(),
- {
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kVertex),
});
@@ -402,7 +405,9 @@
// a: vec3;
// };
- Structure("S", {Member("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3u))});
+ Structure("S", utils::Vector{
+ Member("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3u)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
@@ -412,7 +417,9 @@
// struct S {
// a: mat3x3;
// };
- Structure("S", {Member("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3u, 3u))});
+ Structure("S", utils::Vector{
+ Member("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3u, 3u)),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
@@ -425,13 +432,11 @@
// };
Structure(Source{{12, 34}}, "Foo",
- {
+ utils::Vector{
Member("a", ty.array<f32, 0x20000000>()),
Member("b", ty.array<f32, 0x20000000>()),
});
- WrapInFunction();
-
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: struct size (0x100000000) must not exceed 0xffffffff bytes");
@@ -444,14 +449,12 @@
// c: f32;
// };
- Structure("Foo", {
+ Structure("Foo", utils::Vector{
Member("a", ty.array<f32, 0x3fffffff>()),
Member("b", ty.f32()),
Member(Source{{12, 34}}, "c", ty.f32()),
});
- WrapInFunction();
-
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: struct member offset (0x100000000) must not exceed 0xffffffff bytes");
@@ -463,13 +466,11 @@
// rt: array<f32>;
// };
- Structure("Foo", {
+ Structure("Foo", utils::Vector{
Member("vf", ty.f32()),
Member("rt", ty.array<f32>()),
});
- WrapInFunction();
-
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -478,7 +479,9 @@
// rt : array<array<f32>, 4u>;
// };
- Structure("Foo", {Member("rt", ty.array(Source{{12, 34}}, ty.array<f32>(), 4_u))});
+ Structure("Foo", utils::Vector{
+ Member("rt", ty.array(Source{{12, 34}}, ty.array<f32>(), 4_u)),
+ });
EXPECT_FALSE(r()->Resolve()) << r()->error();
EXPECT_EQ(r()->error(),
@@ -491,7 +494,9 @@
// };
// var<private> a : array<Foo, 4>;
- auto* foo = Structure("Foo", {Member("rt", ty.array<f32>())});
+ auto* foo = Structure("Foo", utils::Vector{
+ Member("rt", ty.array<f32>()),
+ });
GlobalVar("v", ty.array(Source{{12, 34}}, ty.Of(foo), 4_u), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve()) << r()->error();
@@ -507,8 +512,12 @@
// inner : Foo;
// };
- auto* foo = Structure("Foo", {Member("rt", ty.array<f32>())});
- Structure("Outer", {Member(Source{{12, 34}}, "inner", ty.Of(foo))});
+ auto* foo = Structure("Foo", utils::Vector{
+ Member("rt", ty.array<f32>()),
+ });
+ Structure("Outer", utils::Vector{
+ Member(Source{{12, 34}}, "inner", ty.Of(foo)),
+ });
EXPECT_FALSE(r()->Resolve()) << r()->error();
EXPECT_EQ(r()->error(),
@@ -522,13 +531,11 @@
// vf: f32;
// };
- Structure("Foo", {
+ Structure("Foo", utils::Vector{
Member(Source{{12, 34}}, "rt", ty.array<f32>()),
Member("vf", ty.f32()),
});
- WrapInFunction();
-
EXPECT_FALSE(r()->Resolve()) << r()->error();
EXPECT_EQ(r()->error(),
R"(12:34 error: runtime arrays may only appear as the last member of a struct)");
@@ -561,16 +568,16 @@
auto* param = Param(Source{{12, 34}}, "a", ty.array<i32>());
- Func("func", {param}, ty.void_(),
- {
+ Func("func", utils::Vector{param}, ty.void_(),
+ utils::Vector{
Return(),
});
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kVertex),
});
@@ -586,8 +593,8 @@
auto* param =
Param(Source{{12, 34}}, "a", ty.pointer(ty.array<i32>(), ast::StorageClass::kWorkgroup));
- Func("func", {param}, ty.void_(),
- {
+ Func("func", utils::Vector{param}, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -605,13 +612,11 @@
//}
auto* alias = Alias("RTArr", ty.array<u32>());
- Structure("s", {
+ Structure("s", utils::Vector{
Member(Source{{12, 34}}, "b", ty.Of(alias)),
Member("a", ty.u32()),
});
- WrapInFunction();
-
EXPECT_FALSE(r()->Resolve()) << r()->error();
EXPECT_EQ(r()->error(),
"12:34 error: runtime arrays may only appear as the last member of a struct");
@@ -625,13 +630,11 @@
//}
auto* alias = Alias("RTArr", ty.array<u32>());
- Structure("s", {
+ Structure("s", utils::Vector{
Member("a", ty.u32()),
Member("b", ty.Of(alias)),
});
- WrapInFunction();
-
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -659,7 +662,7 @@
TEST_F(ResolverTypeValidationTest, FunctionAsType) {
// fn f() {}
// var<private> v : f;
- Func("f", {}, ty.void_(), {});
+ Func("f", utils::Empty, ty.void_(), {});
GlobalVar("v", ty.type_name("f"), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
@@ -761,7 +764,10 @@
TEST_P(SampledTextureDimensionTest, All) {
auto& params = GetParam();
GlobalVar(Source{{12, 34}}, "a", ty.sampled_texture(params.dim, ty.i32()),
- ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
+ ast::StorageClass::kNone, nullptr,
+ utils::Vector{
+ GroupAndBinding(0, 0),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -779,7 +785,10 @@
TEST_P(MultisampledTextureDimensionTest, All) {
auto& params = GetParam();
GlobalVar("a", ty.multisampled_texture(Source{{12, 34}}, params.dim, ty.i32()),
- ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
+ ast::StorageClass::kNone, nullptr,
+ utils::Vector{
+ GroupAndBinding(0, 0),
+ });
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -832,7 +841,10 @@
GlobalVar(
"a",
ty.sampled_texture(Source{{12, 34}}, ast::TextureDimension::k2d, params.type_func(*this)),
- ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
+ ast::StorageClass::kNone, nullptr,
+ utils::Vector{
+ GroupAndBinding(0, 0),
+ });
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -851,7 +863,10 @@
GlobalVar("a",
ty.multisampled_texture(Source{{12, 34}}, ast::TextureDimension::k2d,
params.type_func(*this)),
- ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
+ ast::StorageClass::kNone, nullptr,
+ utils::Vector{
+ GroupAndBinding(0, 0),
+ });
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -890,7 +905,10 @@
auto* st = ty.storage_texture(Source{{12, 34}}, params.dim, ast::TexelFormat::kR32Uint,
ast::Access::kWrite);
- GlobalVar("a", st, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a", st, ast::StorageClass::kNone,
+ utils::Vector{
+ GroupAndBinding(0, 0),
+ });
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -940,17 +958,29 @@
auto* st_a = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d, params.format,
ast::Access::kWrite);
- GlobalVar("a", st_a, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a", st_a, ast::StorageClass::kNone,
+ utils::Vector{
+ GroupAndBinding(0, 0),
+ });
auto* st_b = ty.storage_texture(ast::TextureDimension::k2d, params.format, ast::Access::kWrite);
- GlobalVar("b", st_b, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 1)});
+ GlobalVar("b", st_b, ast::StorageClass::kNone,
+ utils::Vector{
+ GroupAndBinding(0, 1),
+ });
auto* st_c =
ty.storage_texture(ast::TextureDimension::k2dArray, params.format, ast::Access::kWrite);
- GlobalVar("c", st_c, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 2)});
+ GlobalVar("c", st_c, ast::StorageClass::kNone,
+ utils::Vector{
+ GroupAndBinding(0, 2),
+ });
auto* st_d = ty.storage_texture(ast::TextureDimension::k3d, params.format, ast::Access::kWrite);
- GlobalVar("d", st_d, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 3)});
+ GlobalVar("d", st_d, ast::StorageClass::kNone,
+ utils::Vector{
+ GroupAndBinding(0, 3),
+ });
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -974,7 +1004,10 @@
auto* st = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d,
ast::TexelFormat::kR32Uint, ast::Access::kUndefined);
- GlobalVar("a", st, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a", st, ast::StorageClass::kNone,
+ utils::Vector{
+ GroupAndBinding(0, 0),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: storage texture missing access control");
@@ -988,7 +1021,9 @@
ast::TexelFormat::kR32Uint, ast::Access::kReadWrite);
GlobalVar("a", st, ast::StorageClass::kNone, nullptr,
- ast::AttributeList{GroupAndBinding(0, 0)});
+ utils::Vector{
+ GroupAndBinding(0, 0),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1003,7 +1038,9 @@
ast::TexelFormat::kR32Uint, ast::Access::kRead);
GlobalVar("a", st, ast::StorageClass::kNone, nullptr,
- ast::AttributeList{GroupAndBinding(0, 0)});
+ utils::Vector{
+ GroupAndBinding(0, 0),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1018,7 +1055,9 @@
ast::Access::kWrite);
GlobalVar("a", st, ast::StorageClass::kNone, nullptr,
- ast::AttributeList{GroupAndBinding(0, 0)});
+ utils::Vector{
+ GroupAndBinding(0, 0),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc
index 905fc0e..9ccb7ef 100644
--- a/src/tint/resolver/uniformity.cc
+++ b/src/tint/resolver/uniformity.cc
@@ -152,8 +152,8 @@
}
// Create nodes for parameters.
- parameters.resize(func->params.size());
- for (size_t i = 0; i < func->params.size(); i++) {
+ parameters.resize(func->params.Length());
+ for (size_t i = 0; i < func->params.Length(); i++) {
auto* param = func->params[i];
auto param_name = builder->Symbols().NameFor(param->symbol);
auto* sem = builder->Sem().Get<sem::Parameter>(param);
@@ -349,7 +349,7 @@
// Set the parameter tag to ParameterRequiredToBeUniform for each parameter node that
// was reachable.
- for (size_t i = 0; i < func->params.size(); i++) {
+ for (size_t i = 0; i < func->params.Length(); i++) {
auto* param = func->params[i];
if (reachable.contains(current_function_->variables.Get(sem_.Get(param)))) {
current_function_->parameters[i].tag = ParameterRequiredToBeUniform;
@@ -367,7 +367,7 @@
// Set the parameter tag to ParameterRequiredToBeUniformForSubsequentControlFlow for
// each parameter node that was reachable.
- for (size_t i = 0; i < func->params.size(); i++) {
+ for (size_t i = 0; i < func->params.Length(); i++) {
auto* param = func->params[i];
if (reachable.contains(current_function_->variables.Get(sem_.Get(param)))) {
current_function_->parameters[i].tag =
@@ -386,7 +386,7 @@
// Set the parameter tag to ParameterRequiredToBeUniformForReturnValue for each
// parameter node that was reachable.
- for (size_t i = 0; i < func->params.size(); i++) {
+ for (size_t i = 0; i < func->params.Length(); i++) {
auto* param = func->params[i];
if (reachable.contains(current_function_->variables.Get(sem_.Get(param)))) {
current_function_->parameters[i].tag =
@@ -396,7 +396,7 @@
}
// Traverse the graph for each pointer parameter.
- for (size_t i = 0; i < func->params.size(); i++) {
+ for (size_t i = 0; i < func->params.Length(); i++) {
if (current_function_->parameters[i].pointer_return_value == nullptr) {
continue;
}
@@ -411,7 +411,7 @@
}
// Check every other parameter to see if they feed into this parameter's final value.
- for (size_t j = 0; j < func->params.size(); j++) {
+ for (size_t j = 0; j < func->params.Length(); j++) {
auto* param_source = sem_.Get<sem::Parameter>(func->params[j]);
if (reachable.contains(current_function_->parameters[j].init_value)) {
current_function_->parameters[i].pointer_param_output_sources.push_back(
@@ -847,6 +847,7 @@
return cfx;
}
},
+
[&](const ast::ReturnStatement* r) {
Node* cf_ret;
if (r->value) {
@@ -870,6 +871,7 @@
return cf_ret;
},
+
[&](const ast::SwitchStatement* s) {
auto* sem_switch = sem_.Get(s);
auto [cfx, v_cond] = ProcessExpression(cf, s->condition);
@@ -938,6 +940,7 @@
return cf_end ? cf_end : cf;
},
+
[&](const ast::VariableDeclStatement* decl) {
Node* node;
if (decl->variable->constructor) {
@@ -956,6 +959,11 @@
return cf;
},
+
+ [&](const ast::StaticAssert*) {
+ return cf; // No impact on uniformity
+ },
+
[&](Default) {
TINT_ICE(Resolver, diagnostics_)
<< "unknown statement type: " << std::string(stmt->TypeInfo().name);
@@ -1204,7 +1212,7 @@
// Process call arguments
Node* cf_last_arg = cf;
std::vector<Node*> args;
- for (size_t i = 0; i < call->args.size(); i++) {
+ for (size_t i = 0; i < call->args.Length(); i++) {
auto [cf_i, arg_i] = ProcessExpression(cf_last_arg, call->args[i]);
// Capture the index of this argument in a new node.
diff --git a/src/tint/resolver/uniformity_test.cc b/src/tint/resolver/uniformity_test.cc
index b335c27..bbf7a4b 100644
--- a/src/tint/resolver/uniformity_test.cc
+++ b/src/tint/resolver/uniformity_test.cc
@@ -3422,8 +3422,13 @@
)";
RunTest(src, false);
- EXPECT_EQ(error_,
- R"(test:14:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ EXPECT_EQ(
+ error_,
+ R"(test:11:7 warning: use of deprecated language feature: fallthrough is set to be removed from WGSL. Case can accept multiple selectors if the existing case bodies are empty. default is not yet supported in a case selector list.
+ fallthrough;
+ ^^^^^^^^^^^
+
+test:14:7 warning: 'workgroupBarrier' must only be called from uniform control flow
workgroupBarrier();
^^^^^^^^^^^^^^^^
@@ -3487,8 +3492,13 @@
)";
RunTest(src, false);
- EXPECT_EQ(error_,
- R"(test:14:9 warning: 'workgroupBarrier' must only be called from uniform control flow
+ EXPECT_EQ(
+ error_,
+ R"(test:10:7 warning: use of deprecated language feature: fallthrough is set to be removed from WGSL. Case can accept multiple selectors if the existing case bodies are empty. default is not yet supported in a case selector list.
+ fallthrough;
+ ^^^^^^^^^^^
+
+test:14:9 warning: 'workgroupBarrier' must only be called from uniform control flow
workgroupBarrier();
^^^^^^^^^^^^^^^^
@@ -3541,32 +3551,6 @@
)");
}
-TEST_F(UniformityAnalysisTest, Switch_VarBecomesUniformInDifferentCase_WithFallthrough) {
- std::string src = R"(
-@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
-@group(0) @binding(0) var<uniform> condition : i32;
-
-fn foo() {
- var x = non_uniform;
- switch (condition) {
- case 0: {
- x = 5;
- fallthrough;
- }
- case 42: {
- if (x == 0) {
- workgroupBarrier();
- }
- }
- default: {
- }
- }
-}
-)";
-
- RunTest(src, true);
-}
-
TEST_F(UniformityAnalysisTest, Switch_VarBecomesNonUniformInCase_BarrierAfter) {
std::string src = R"(
@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
@@ -5299,18 +5283,18 @@
// ...
// *p254 = rhs;
// }
- ast::ParameterList params;
- ast::StatementList foo_body;
+ utils::Vector<const ast::Parameter*, 8> params;
+ utils::Vector<const ast::Statement*, 8> foo_body;
const ast::Expression* rhs_init = b.Deref("p0");
for (int i = 1; i < 255; i++) {
rhs_init = b.Add(rhs_init, b.Deref("p" + std::to_string(i)));
}
- foo_body.push_back(b.Decl(b.Let("rhs", nullptr, rhs_init)));
+ foo_body.Push(b.Decl(b.Let("rhs", nullptr, rhs_init)));
for (int i = 0; i < 255; i++) {
- params.push_back(
+ params.Push(
b.Param("p" + std::to_string(i), ty.pointer(ty.i32(), ast::StorageClass::kFunction)));
if (i > 0) {
- foo_body.push_back(b.Assign(b.Deref("p" + std::to_string(i)), "rhs"));
+ foo_body.Push(b.Assign(b.Deref("p" + std::to_string(i)), "rhs"));
}
}
b.Func("foo", std::move(params), ty.void_(), foo_body);
@@ -5328,18 +5312,17 @@
// }
// }
b.GlobalVar("non_uniform_global", ty.i32(), ast::StorageClass::kPrivate);
- ast::StatementList main_body;
- ast::ExpressionList args;
+ utils::Vector<const ast::Statement*, 8> main_body;
+ utils::Vector<const ast::Expression*, 8> args;
for (int i = 0; i < 255; i++) {
auto name = "v" + std::to_string(i);
- main_body.push_back(b.Decl(b.Var(name, ty.i32())));
- args.push_back(b.AddressOf(name));
+ main_body.Push(b.Decl(b.Var(name, ty.i32())));
+ args.Push(b.AddressOf(name));
}
- main_body.push_back(b.Assign("v0", "non_uniform_global"));
- main_body.push_back(b.CallStmt(b.create<ast::CallExpression>(b.Expr("foo"), args)));
- main_body.push_back(
- b.If(b.Equal("v254", 0_i), b.Block(b.CallStmt(b.Call("workgroupBarrier")))));
- b.Func("main", {}, ty.void_(), main_body);
+ main_body.Push(b.Assign("v0", "non_uniform_global"));
+ main_body.Push(b.CallStmt(b.create<ast::CallExpression>(b.Expr("foo"), args)));
+ main_body.Push(b.If(b.Equal("v254", 0_i), b.Block(b.CallStmt(b.Call("workgroupBarrier")))));
+ b.Func("main", utils::Empty, ty.void_(), main_body);
// TODO(jrprice): Expect false when uniformity issues become errors.
EXPECT_TRUE(RunTest(std::move(b))) << error_;
@@ -6539,15 +6522,15 @@
// }
// }
b.GlobalVar("v0", ty.i32(), ast::StorageClass::kPrivate, b.Expr(0_i));
- ast::StatementList foo_body;
+ utils::Vector<const ast::Statement*, 8> foo_body;
std::string v_last = "v0";
for (int i = 1; i < 100000; i++) {
auto v = "v" + std::to_string(i);
- foo_body.push_back(b.Decl(b.Var(v, nullptr, b.Expr(v_last))));
+ foo_body.Push(b.Decl(b.Var(v, nullptr, b.Expr(v_last))));
v_last = v;
}
- foo_body.push_back(b.If(b.Equal(v_last, 0_i), b.Block(b.CallStmt(b.Call("workgroupBarrier")))));
- b.Func("foo", {}, ty.void_(), foo_body);
+ foo_body.Push(b.If(b.Equal(v_last, 0_i), b.Block(b.CallStmt(b.Call("workgroupBarrier")))));
+ b.Func("foo", utils::Empty, ty.void_(), foo_body);
// TODO(jrprice): Expect false when uniformity issues become errors.
EXPECT_TRUE(RunTest(std::move(b))) << error_;
diff --git a/src/tint/resolver/validation_test.cc b/src/tint/resolver/validation_test.cc
index 45c6d87..52d4c87 100644
--- a/src/tint/resolver/validation_test.cc
+++ b/src/tint/resolver/validation_test.cc
@@ -65,15 +65,15 @@
GlobalVar("dst", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* stmt = Assign(Expr("dst"), Expr(Source{{3, 4}}, "wg"));
- Func(Source{{9, 10}}, "f0", {}, ty.vec4<f32>(),
- {
+ Func(Source{{9, 10}}, "f0", utils::Empty, ty.vec4<f32>(),
+ utils::Vector{
stmt,
Return(Expr("dst")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kVertex),
},
- {
+ utils::Vector{
Builtin(ast::BuiltinValue::kPosition),
});
@@ -97,10 +97,15 @@
GlobalVar("dst", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* stmt = Assign(Expr("dst"), Expr(Source{{3, 4}}, "wg"));
- Func(Source{{5, 6}}, "f2", {}, ty.void_(), {stmt});
- Func(Source{{7, 8}}, "f1", {}, ty.void_(), {CallStmt(Call("f2"))});
- Func(Source{{9, 10}}, "f0", {}, ty.void_(), {CallStmt(Call("f1"))},
- ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+ Func(Source{{5, 6}}, "f2", utils::Empty, ty.void_(), utils::Vector{stmt});
+ Func(Source{{7, 8}}, "f1", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("f2")),
+ });
+ Func(Source{{9, 10}}, "f0", utils::Empty, ty.void_(), utils::Vector{CallStmt(Call("f1"))},
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -153,7 +158,7 @@
}
TEST_F(ResolverValidationTest, Expr_DontCall_Function) {
- Func("func", {}, ty.void_(), {}, {});
+ Func("func", utils::Empty, ty.void_(), utils::Empty, {});
WrapInFunction(Expr(Source{{{3, 3}, {3, 8}}}, "func"));
EXPECT_FALSE(r()->Resolve());
@@ -223,8 +228,8 @@
GlobalVar("global_var", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Expr(Source{{12, 34}}, "global_var"), 3.14_f),
Return(),
});
@@ -297,8 +302,8 @@
TEST_F(ResolverValidationTest, StorageClass_FunctionVariableWorkgroupClass) {
auto* var = Var("var", ty.i32(), ast::StorageClass::kWorkgroup);
- Func("func", {}, ty.void_(),
- {
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
});
@@ -311,8 +316,8 @@
TEST_F(ResolverValidationTest, StorageClass_FunctionVariableI32) {
auto* var = Var("s", ty.i32(), ast::StorageClass::kPrivate);
- Func("func", {}, ty.void_(),
- {
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
});
@@ -325,7 +330,7 @@
TEST_F(ResolverValidationTest, StorageClass_SamplerExplicitStorageClass) {
auto* t = ty.sampler(ast::SamplerKind::kSampler);
GlobalVar(Source{{12, 34}}, "var", t, ast::StorageClass::kHandle,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -339,7 +344,7 @@
TEST_F(ResolverValidationTest, StorageClass_TextureExplicitStorageClass) {
auto* t = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
GlobalVar(Source{{12, 34}}, "var", t, ast::StorageClass::kHandle,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -425,7 +430,11 @@
auto* z = Expr(Source{{{3, 3}, {3, 8}}}, "z");
auto* accessor_expr = MemberAccessor(star_p, z);
auto* x = Var("x", ty.f32(), accessor_expr);
- Func("func", {p}, ty.f32(), {Decl(x), Return(x)});
+ Func("func", utils::Vector{p}, ty.f32(),
+ utils::Vector{
+ Decl(x),
+ Return(x),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -439,7 +448,11 @@
auto* accessor_expr = MemberAccessor(p, z);
auto* star_p = Deref(accessor_expr);
auto* x = Var("x", ty.f32(), star_p);
- Func("func", {p}, ty.f32(), {Decl(x), Return(x)});
+ Func("func", utils::Vector{p}, ty.f32(),
+ utils::Vector{
+ Decl(x),
+ Return(x),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -806,8 +819,14 @@
// }
// }
- Func("MayDiscard", {}, ty.void_(), {If(true, Block(Discard()))});
- Func("SomeFunc", {}, ty.void_(), {CallStmt(Call("MayDiscard"))});
+ Func("MayDiscard", utils::Empty, ty.void_(),
+ utils::Vector{
+ If(true, Block(Discard())),
+ });
+ Func("SomeFunc", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("MayDiscard")),
+ });
WrapInFunction(Loop( // outer loop
Block(), // outer loop block
@@ -926,8 +945,14 @@
// break;
// }
- Func("MayDiscard", {}, ty.void_(), {If(true, Block(Discard()))});
- Func("F", {}, ty.void_(), {CallStmt(Call("MayDiscard"))});
+ Func("MayDiscard", utils::Empty, ty.void_(),
+ utils::Vector{
+ If(true, Block(Discard())),
+ });
+ Func("F", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("MayDiscard")),
+ });
WrapInFunction(For(nullptr, nullptr,
Loop(Source{{56, 78}}, //
@@ -1191,30 +1216,40 @@
}
TEST_F(ResolverValidationTest, StructMemberDuplicateName) {
- Structure("S",
- {Member(Source{{12, 34}}, "a", ty.i32()), Member(Source{{56, 78}}, "a", ty.i32())});
+ Structure("S", utils::Vector{
+ Member(Source{{12, 34}}, "a", ty.i32()),
+ Member(Source{{56, 78}}, "a", ty.i32()),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"56:78 error: redefinition of 'a'\n12:34 note: previous definition "
"is here");
}
TEST_F(ResolverValidationTest, StructMemberDuplicateNameDifferentTypes) {
- Structure("S", {Member(Source{{12, 34}}, "a", ty.bool_()),
- Member(Source{{12, 34}}, "a", ty.vec3<f32>())});
+ Structure("S", utils::Vector{
+ Member(Source{{12, 34}}, "a", ty.bool_()),
+ Member(Source{{12, 34}}, "a", ty.vec3<f32>()),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: redefinition of 'a'\n12:34 note: previous definition "
"is here");
}
TEST_F(ResolverValidationTest, StructMemberDuplicateNamePass) {
- Structure("S", {Member("a", ty.i32()), Member("b", ty.f32())});
- Structure("S1", {Member("a", ty.i32()), Member("b", ty.f32())});
+ Structure("S", utils::Vector{
+ Member("a", ty.i32()),
+ Member("b", ty.f32()),
+ });
+ Structure("S1", utils::Vector{
+ Member("a", ty.i32()),
+ Member("b", ty.f32()),
+ });
EXPECT_TRUE(r()->Resolve());
}
TEST_F(ResolverValidationTest, NonPOTStructMemberAlignAttribute) {
- Structure("S", {
- Member("a", ty.f32(), {MemberAlign(Source{{12, 34}}, 3)}),
+ Structure("S", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberAlign(Source{{12, 34}}, 3)}),
});
EXPECT_FALSE(r()->Resolve());
@@ -1222,8 +1257,8 @@
}
TEST_F(ResolverValidationTest, ZeroStructMemberAlignAttribute) {
- Structure("S", {
- Member("a", ty.f32(), {MemberAlign(Source{{12, 34}}, 0)}),
+ Structure("S", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberAlign(Source{{12, 34}}, 0)}),
});
EXPECT_FALSE(r()->Resolve());
@@ -1231,8 +1266,8 @@
}
TEST_F(ResolverValidationTest, ZeroStructMemberSizeAttribute) {
- Structure("S", {
- Member("a", ty.f32(), {MemberSize(Source{{12, 34}}, 0)}),
+ Structure("S", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberSize(Source{{12, 34}}, 0)}),
});
EXPECT_FALSE(r()->Resolve());
@@ -1240,8 +1275,9 @@
}
TEST_F(ResolverValidationTest, OffsetAndSizeAttribute) {
- Structure("S", {
- Member(Source{{12, 34}}, "a", ty.f32(), {MemberOffset(0), MemberSize(4)}),
+ Structure("S", utils::Vector{
+ Member(Source{{12, 34}}, "a", ty.f32(),
+ utils::Vector{MemberOffset(0), MemberSize(4)}),
});
EXPECT_FALSE(r()->Resolve());
@@ -1251,8 +1287,9 @@
}
TEST_F(ResolverValidationTest, OffsetAndAlignAttribute) {
- Structure("S", {
- Member(Source{{12, 34}}, "a", ty.f32(), {MemberOffset(0), MemberAlign(4)}),
+ Structure("S", utils::Vector{
+ Member(Source{{12, 34}}, "a", ty.f32(),
+ utils::Vector{MemberOffset(0), MemberAlign(4)}),
});
EXPECT_FALSE(r()->Resolve());
@@ -1262,9 +1299,9 @@
}
TEST_F(ResolverValidationTest, OffsetAndAlignAndSizeAttribute) {
- Structure("S", {
+ Structure("S", utils::Vector{
Member(Source{{12, 34}}, "a", ty.f32(),
- {MemberOffset(0), MemberAlign(4), MemberSize(4)}),
+ utils::Vector{MemberOffset(0), MemberAlign(4), MemberSize(4)}),
});
EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index ec858c4..f3a02ed 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -395,7 +395,7 @@
// Temporally forbid using f16 types in "uniform" and "storage" storage class.
// TODO(tint:1473, tint:1502): Remove this error after f16 is supported in "uniform" and
- // "storage" storage class.
+ // "storage" storage class but keep for "push_constant" storage class.
if (Is<sem::F16>(sem::Type::DeepestElementOf(store_ty))) {
AddError(
"using f16 types in '" + utils::ToString(sc) + "' storage class is not implemented yet",
@@ -516,7 +516,19 @@
}
bool Validator::StorageClassLayout(const sem::Variable* var,
+ const ast::Extensions& enabled_extensions,
ValidTypeStorageLayouts& layouts) const {
+ if (var->StorageClass() == ast::StorageClass::kPushConstant &&
+ !enabled_extensions.contains(ast::Extension::kChromiumExperimentalPushConstant) &&
+ IsValidationEnabled(var->Declaration()->attributes,
+ ast::DisabledValidation::kIgnoreStorageClass)) {
+ AddError(
+ "use of variable storage class 'push_constant' requires enabling extension "
+ "'chromium_experimental_push_constant'",
+ var->Declaration()->source);
+ return false;
+ }
+
if (auto* str = var->Type()->UnwrapRef()->As<sem::Struct>()) {
if (!StorageClassLayout(str, var->StorageClass(), str->Declaration()->source, layouts)) {
AddNote("see declaration of variable", var->Declaration()->source);
@@ -629,7 +641,7 @@
},
[&](const ast::Override*) { return Override(global, override_ids); },
[&](const ast::Const*) {
- if (!decl->attributes.empty()) {
+ if (!decl->attributes.IsEmpty()) {
AddError("attribute is not valid for module-scope 'const' declaration",
decl->attributes[0]->source);
return false;
@@ -1032,7 +1044,7 @@
}
}
- if (decl->params.size() > 255) {
+ if (decl->params.Length() > 255) {
AddError("functions may declare at most 255 parameters", decl->source);
return false;
}
@@ -1114,12 +1126,13 @@
};
// Inner lambda that is applied to a type and all of its members.
- auto validate_entry_point_attributes_inner = [&](const ast::AttributeList& attrs,
+ auto validate_entry_point_attributes_inner = [&](utils::VectorRef<const ast::Attribute*> attrs,
const sem::Type* ty, Source source,
ParamOrRetType param_or_ret,
bool is_struct_member) {
// Temporally forbid using f16 types in entry point IO.
- // TODO(tint:1473, tint:1502): Remove this error after f16 is supported in entry point IO.
+ // TODO(tint:1473, tint:1502): Remove this error after f16 is supported in entry point
+ // IO.
if (Is<sem::F16>(sem::Type::DeepestElementOf(ty))) {
AddError("entry point IO of f16 types is not implemented yet", source);
return false;
@@ -1257,8 +1270,9 @@
};
// Outer lambda for validating the entry point attributes for a type.
- auto validate_entry_point_attributes = [&](const ast::AttributeList& attrs, const sem::Type* ty,
- Source source, ParamOrRetType param_or_ret) {
+ auto validate_entry_point_attributes = [&](utils::VectorRef<const ast::Attribute*> attrs,
+ const sem::Type* ty, Source source,
+ ParamOrRetType param_or_ret) {
if (!validate_entry_point_attributes_inner(attrs, ty, source, param_or_ret,
/*is_struct_member*/ false)) {
return false;
@@ -1367,7 +1381,7 @@
return true;
}
-bool Validator::Statements(const ast::StatementList& stmts) const {
+bool Validator::Statements(utils::VectorRef<const ast::Statement*> stmts) const {
for (auto* stmt : stmts) {
if (!sem_.Get(stmt)->IsReachable()) {
/// TODO(https://github.com/gpuweb/gpuweb/issues/2378): This may need to
@@ -1431,7 +1445,7 @@
return fail("break statement is not directly in if statement block",
stmt->Declaration()->source);
}
- if (block->Declaration()->statements.size() != 1) {
+ if (block->Declaration()->statements.Length() != 1) {
return fail("if statement block contains multiple statements",
block->Declaration()->source);
}
@@ -1530,7 +1544,7 @@
if (auto* c = As<sem::CaseStatement>(block->Parent())) {
if (block->Declaration()->Last() == stmt->Declaration()) {
if (auto* s = As<sem::SwitchStatement>(c->Parent())) {
- if (c->Declaration() != s->Declaration()->body.back()) {
+ if (c->Declaration() != s->Declaration()->body.Back()) {
return true;
}
AddError(
@@ -1737,8 +1751,8 @@
return false;
}
- if (decl->args.size() != target->Parameters().Length()) {
- bool more = decl->args.size() > target->Parameters().Length();
+ if (decl->args.Length() != target->Parameters().Length()) {
+ bool more = decl->args.Length() > target->Parameters().Length();
AddError("too " + (more ? std::string("many") : std::string("few")) +
" arguments in call to '" + name + "', expected " +
std::to_string(target->Parameters().Length()) + ", got " +
@@ -1835,12 +1849,12 @@
return false;
}
- if (ctor->args.size() > 0) {
- if (ctor->args.size() != struct_type->Members().size()) {
- std::string fm = ctor->args.size() < struct_type->Members().size() ? "few" : "many";
+ if (ctor->args.Length() > 0) {
+ if (ctor->args.Length() != struct_type->Members().size()) {
+ std::string fm = ctor->args.Length() < struct_type->Members().size() ? "few" : "many";
AddError("struct constructor has too " + fm + " inputs: expected " +
std::to_string(struct_type->Members().size()) + ", found " +
- std::to_string(ctor->args.size()),
+ std::to_string(ctor->args.Length()),
ctor->source);
return false;
}
@@ -1882,17 +1896,17 @@
} else if (!elem_ty->IsConstructible()) {
AddError("array constructor has non-constructible element type", ctor->source);
return false;
- } else if (!values.empty() && (values.size() != array_type->Count())) {
- std::string fm = values.size() < array_type->Count() ? "few" : "many";
+ } else if (!values.IsEmpty() && (values.Length() != array_type->Count())) {
+ std::string fm = values.Length() < array_type->Count() ? "few" : "many";
AddError("array constructor has too " + fm + " elements: expected " +
std::to_string(array_type->Count()) + ", found " +
- std::to_string(values.size()),
+ std::to_string(values.Length()),
ctor->source);
return false;
- } else if (values.size() > array_type->Count()) {
+ } else if (values.Length() > array_type->Count()) {
AddError("array constructor has too many elements: expected " +
std::to_string(array_type->Count()) + ", found " +
- std::to_string(values.size()),
+ std::to_string(values.Length()),
ctor->source);
return false;
}
@@ -2000,6 +2014,73 @@
return true;
}
+bool Validator::PushConstants(const std::vector<sem::Function*>& entry_points) const {
+ for (auto* entry_point : entry_points) {
+ // State checked and modified by check_push_constant so that it remembers previously seen
+ // push_constant variables for an entry-point.
+ const sem::Variable* push_constant_var = nullptr;
+ const sem::Function* push_constant_func = nullptr;
+
+ auto check_push_constant = [&](const sem::Function* func, const sem::Function* ep) {
+ for (auto* var : func->DirectlyReferencedGlobals()) {
+ if (var->StorageClass() != ast::StorageClass::kPushConstant ||
+ var == push_constant_var) {
+ continue;
+ }
+
+ if (push_constant_var == nullptr) {
+ push_constant_var = var;
+ push_constant_func = func;
+ continue;
+ }
+
+ AddError("entry point '" + symbols_.NameFor(ep->Declaration()->symbol) +
+ "' uses two different 'push_constant' variables.",
+ ep->Declaration()->source);
+ AddNote("first 'push_constant' variable declaration is here",
+ var->Declaration()->source);
+ if (func != ep) {
+ TraverseCallChain(diagnostics_, ep, func, [&](const sem::Function* f) {
+ AddNote("called by function '" +
+ symbols_.NameFor(f->Declaration()->symbol) + "'",
+ f->Declaration()->source);
+ });
+ AddNote("called by entry point '" +
+ symbols_.NameFor(ep->Declaration()->symbol) + "'",
+ ep->Declaration()->source);
+ }
+ AddNote("second 'push_constant' variable declaration is here",
+ push_constant_var->Declaration()->source);
+ if (push_constant_func != ep) {
+ TraverseCallChain(
+ diagnostics_, ep, push_constant_func, [&](const sem::Function* f) {
+ AddNote("called by function '" +
+ symbols_.NameFor(f->Declaration()->symbol) + "'",
+ f->Declaration()->source);
+ });
+ AddNote("called by entry point '" +
+ symbols_.NameFor(ep->Declaration()->symbol) + "'",
+ ep->Declaration()->source);
+ }
+ return false;
+ }
+
+ return true;
+ };
+
+ if (!check_push_constant(entry_point, entry_point)) {
+ return false;
+ }
+ for (auto* func : entry_point->TransitivelyCalledFunctions()) {
+ if (!check_push_constant(func, entry_point)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
bool Validator::Array(const sem::Array* arr, const Source& source) const {
auto* el_ty = arr->ElemType();
@@ -2369,7 +2450,7 @@
return true;
}
-bool Validator::NoDuplicateAttributes(const ast::AttributeList& attributes) const {
+bool Validator::NoDuplicateAttributes(utils::VectorRef<const ast::Attribute*> attributes) const {
std::unordered_map<const TypeInfo*, Source> seen;
for (auto* d : attributes) {
auto res = seen.emplace(&d->TypeInfo(), d->source);
@@ -2382,7 +2463,7 @@
return true;
}
-bool Validator::IsValidationDisabled(const ast::AttributeList& attributes,
+bool Validator::IsValidationDisabled(utils::VectorRef<const ast::Attribute*> attributes,
ast::DisabledValidation validation) const {
for (auto* attribute : attributes) {
if (auto* dv = attribute->As<ast::DisableValidationAttribute>()) {
@@ -2394,7 +2475,7 @@
return false;
}
-bool Validator::IsValidationEnabled(const ast::AttributeList& attributes,
+bool Validator::IsValidationEnabled(utils::VectorRef<const ast::Attribute*> attributes,
ast::DisabledValidation validation) const {
return !IsValidationDisabled(attributes, validation);
}
diff --git a/src/tint/resolver/validator.h b/src/tint/resolver/validator.h
index 385e020..57ac064 100644
--- a/src/tint/resolver/validator.h
+++ b/src/tint/resolver/validator.h
@@ -116,6 +116,11 @@
/// @returns true on success, false otherwise.
bool PipelineStages(const std::vector<sem::Function*>& entry_points) const;
+ /// Validates push_constant variables
+ /// @param entry_points the entry points to the module
+ /// @returns true on success, false otherwise.
+ bool PushConstants(const std::vector<sem::Function*>& entry_points) const;
+
/// Validates aliases
/// @param alias the alias to validate
/// @returns true on success, false otherwise.
@@ -320,7 +325,7 @@
/// Validates a list of statements
/// @param stmts the statements to validate
/// @returns true on success, false otherwise
- bool Statements(const ast::StatementList& stmts) const;
+ bool Statements(utils::VectorRef<const ast::Statement*> stmts) const;
/// Validates a storage texture
/// @param t the texture to validate
@@ -417,7 +422,7 @@
/// Validates there are no duplicate attributes
/// @param attributes the list of attributes to validate
/// @returns true on success, false otherwise.
- bool NoDuplicateAttributes(const ast::AttributeList& attributes) const;
+ bool NoDuplicateAttributes(utils::VectorRef<const ast::Attribute*> attributes) const;
/// Validates a storage class layout
/// @param type the type to validate
@@ -433,15 +438,18 @@
/// Validates a storage class layout
/// @param var the variable to validate
/// @param layouts previously validated storage layouts
+ /// @param enabled_extensions all the extensions declared in current module
/// @returns true on success, false otherwise.
- bool StorageClassLayout(const sem::Variable* var, ValidTypeStorageLayouts& layouts) const;
+ bool StorageClassLayout(const sem::Variable* var,
+ const ast::Extensions& enabled_extensions,
+ ValidTypeStorageLayouts& layouts) const;
/// @returns true if the attribute list contains a
/// ast::DisableValidationAttribute with the validation mode equal to
/// `validation`
/// @param attributes the attribute list to check
/// @param validation the validation mode to check
- bool IsValidationDisabled(const ast::AttributeList& attributes,
+ bool IsValidationDisabled(utils::VectorRef<const ast::Attribute*> attributes,
ast::DisabledValidation validation) const;
/// @returns true if the attribute list does not contains a
@@ -449,7 +457,7 @@
/// `validation`
/// @param attributes the attribute list to check
/// @param validation the validation mode to check
- bool IsValidationEnabled(const ast::AttributeList& attributes,
+ bool IsValidationEnabled(utils::VectorRef<const ast::Attribute*> attributes,
ast::DisabledValidation validation) const;
private:
diff --git a/src/tint/resolver/variable_test.cc b/src/tint/resolver/variable_test.cc
index 49c1f8b..cc4bd65 100644
--- a/src/tint/resolver/variable_test.cc
+++ b/src/tint/resolver/variable_test.cc
@@ -43,7 +43,7 @@
Enable(ast::Extension::kF16);
- auto* S = Structure("S", {Member("i", ty.i32())});
+ auto* S = Structure("S", utils::Vector{Member("i", ty.i32())});
auto* A = Alias("A", ty.Of(S));
auto* i = Var("i", ty.i32(), ast::StorageClass::kNone);
@@ -54,8 +54,8 @@
auto* s = Var("s", ty.Of(S), ast::StorageClass::kNone);
auto* a = Var("a", ty.Of(A), ast::StorageClass::kNone);
- Func("F", {}, ty.void_(),
- {
+ Func("F", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(i),
Decl(u),
Decl(f),
@@ -108,7 +108,7 @@
Enable(ast::Extension::kF16);
- auto* S = Structure("S", {Member("i", ty.i32())});
+ auto* S = Structure("S", utils::Vector{Member("i", ty.i32())});
auto* A = Alias("A", ty.Of(S));
auto* i_c = Expr(1_i);
@@ -127,8 +127,8 @@
auto* s = Var("s", ty.Of(S), ast::StorageClass::kNone, s_c);
auto* a = Var("a", ty.Of(A), ast::StorageClass::kNone, a_c);
- Func("F", {}, ty.void_(),
- {
+ Func("F", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(i),
Decl(u),
Decl(f),
@@ -182,7 +182,7 @@
auto* t = Alias("a", ty.i32());
auto* v = Var("a", nullptr, Expr(false));
- Func("F", {}, ty.void_(), {Decl(v)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(v)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -201,9 +201,9 @@
// var a = true;
// }
- auto* t = Structure("a", {Member("m", ty.i32())});
+ auto* t = Structure("a", utils::Vector{Member("m", ty.i32())});
auto* v = Var("a", nullptr, Expr(false));
- Func("F", {}, ty.void_(), {Decl(v)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(v)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -219,7 +219,7 @@
// }
auto* v = Var("a", nullptr, Expr(false));
- auto* f = Func("a", {}, ty.void_(), {Decl(v)});
+ auto* f = Func("a", utils::Empty, ty.void_(), utils::Vector{Decl(v)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -240,7 +240,7 @@
auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
auto* v = Var("a", nullptr, Expr("a"));
- Func("F", {}, ty.void_(), {Decl(v)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(v)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -263,7 +263,7 @@
auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
auto* v = Var("a", nullptr, Expr("a"));
- Func("F", {}, ty.void_(), {Decl(v)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(v)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -287,7 +287,7 @@
auto* x = Var("a", ty.i32(), Expr(1_i));
auto* y = Var("a", nullptr, Expr("a"));
- Func("F", {}, ty.void_(), {Decl(x), Block(Decl(y))});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(x), Block(Decl(y))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -313,7 +313,7 @@
auto* c = Const("a", ty.i32(), Expr(1_i));
auto* v = Var("a", nullptr, Expr("a"));
- Func("X", {}, ty.void_(), {Decl(c), Block(Decl(v))});
+ Func("X", utils::Empty, ty.void_(), utils::Vector{Decl(c), Block(Decl(v))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -339,7 +339,7 @@
auto* l = Let("a", ty.i32(), Expr(1_i));
auto* v = Var("a", nullptr, Expr("a"));
- Func("X", {}, ty.void_(), {Decl(l), Block(Decl(v))});
+ Func("X", utils::Empty, ty.void_(), utils::Vector{Decl(l), Block(Decl(v))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -364,7 +364,7 @@
auto* p = Param("a", ty.i32());
auto* v = Var("a", nullptr, Expr("a"));
- Func("X", {p}, ty.void_(), {Block(Decl(v))});
+ Func("X", utils::Vector{p}, ty.void_(), utils::Vector{Block(Decl(v))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -399,7 +399,7 @@
Enable(ast::Extension::kF16);
- auto* S = Structure("S", {Member("i", ty.i32())});
+ auto* S = Structure("S", utils::Vector{Member("i", ty.i32())});
auto* A = Alias("A", ty.Of(S));
auto* v = Var("v", ty.i32(), ast::StorageClass::kNone);
@@ -421,8 +421,8 @@
auto* a = Let("a", ty.Of(A), a_c);
auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), p_c);
- Func("F", {}, ty.void_(),
- {
+ Func("F", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(v),
Decl(i),
Decl(u),
@@ -468,10 +468,10 @@
// fn f() {
// let p = &s.inner.arr[4];
// }
- auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
- auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
+ auto* inner = Structure("Inner", utils::Vector{Member("arr", ty.array<i32, 4>())});
+ auto* buf = Structure("S", utils::Vector{Member("inner", ty.Of(inner))});
auto* storage = GlobalVar("s", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -499,7 +499,7 @@
auto* t = Alias("a", ty.i32());
auto* l = Let("a", nullptr, Expr(false));
- Func("F", {}, ty.void_(), {Decl(l)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(l)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -518,9 +518,9 @@
// let a = false;
// }
- auto* t = Structure("a", {Member("m", ty.i32())});
+ auto* t = Structure("a", utils::Vector{Member("m", ty.i32())});
auto* l = Let("a", nullptr, Expr(false));
- Func("F", {}, ty.void_(), {Decl(l)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(l)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -536,7 +536,7 @@
// }
auto* l = Let("a", nullptr, Expr(false));
- auto* fb = Func("a", {}, ty.void_(), {Decl(l)});
+ auto* fb = Func("a", utils::Empty, ty.void_(), utils::Vector{Decl(l)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -557,7 +557,7 @@
auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
auto* l = Let("a", nullptr, Expr("a"));
- Func("F", {}, ty.void_(), {Decl(l)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(l)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -580,7 +580,7 @@
auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
auto* l = Let("a", nullptr, Expr("a"));
- Func("F", {}, ty.void_(), {Decl(l)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(l)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -604,7 +604,7 @@
auto* v = Var("a", ty.i32(), Expr(1_i));
auto* l = Let("a", nullptr, Expr("a"));
- Func("F", {}, ty.void_(), {Decl(v), Block(Decl(l))});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(v), Block(Decl(l))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -630,7 +630,7 @@
auto* x = Const("a", ty.i32(), Expr(1_i));
auto* y = Let("a", nullptr, Expr("a"));
- Func("X", {}, ty.void_(), {Decl(x), Block(Decl(y))});
+ Func("X", utils::Empty, ty.void_(), utils::Vector{Decl(x), Block(Decl(y))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -656,7 +656,7 @@
auto* x = Let("a", ty.i32(), Expr(1_i));
auto* y = Let("a", nullptr, Expr("a"));
- Func("X", {}, ty.void_(), {Decl(x), Block(Decl(y))});
+ Func("X", utils::Empty, ty.void_(), utils::Vector{Decl(x), Block(Decl(y))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -681,7 +681,7 @@
auto* p = Param("a", ty.i32());
auto* l = Let("a", nullptr, Expr("a"));
- Func("X", {p}, ty.void_(), {Block(Decl(l))});
+ Func("X", utils::Vector{p}, ty.void_(), utils::Vector{Block(Decl(l))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -709,7 +709,7 @@
auto* t = Alias("a", ty.i32());
auto* c = Const("a", nullptr, Expr(false));
- Func("F", {}, ty.void_(), {Decl(c)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(c)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -728,9 +728,9 @@
// const a = false;
// }
- auto* t = Structure("a", {Member("m", ty.i32())});
+ auto* t = Structure("a", utils::Vector{Member("m", ty.i32())});
auto* c = Const("a", nullptr, Expr(false));
- Func("F", {}, ty.void_(), {Decl(c)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(c)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -746,7 +746,7 @@
// }
auto* c = Const("a", nullptr, Expr(false));
- auto* fb = Func("a", {}, ty.void_(), {Decl(c)});
+ auto* fb = Func("a", utils::Empty, ty.void_(), utils::Vector{Decl(c)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -767,7 +767,7 @@
auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
auto* c = Const("a", nullptr, Expr(1_i));
- Func("F", {}, ty.void_(), {Decl(c)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(c)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -786,7 +786,7 @@
auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
auto* c = Const("a", nullptr, Expr("a"));
- Func("F", {}, ty.void_(), {Decl(c)});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(c)});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -810,7 +810,7 @@
auto* v = Var("a", ty.i32(), Expr(1_i));
auto* c = Const("a", nullptr, Expr(1_i));
- Func("F", {}, ty.void_(), {Decl(v), Block(Decl(c))});
+ Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(v), Block(Decl(c))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -832,7 +832,7 @@
auto* x = Const("a", ty.i32(), Expr(1_i));
auto* y = Const("a", nullptr, Expr("a"));
- Func("X", {}, ty.void_(), {Decl(x), Block(Decl(y))});
+ Func("X", utils::Empty, ty.void_(), utils::Vector{Decl(x), Block(Decl(y))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -858,7 +858,7 @@
auto* l = Let("a", ty.i32(), Expr(1_i));
auto* c = Const("a", nullptr, Expr(1_i));
- Func("X", {}, ty.void_(), {Decl(l), Block(Decl(c))});
+ Func("X", utils::Empty, ty.void_(), utils::Vector{Decl(l), Block(Decl(c))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -879,7 +879,7 @@
auto* p = Param("a", ty.i32());
auto* c = Const("a", nullptr, Expr(1_i));
- Func("X", {p}, ty.void_(), {Block(Decl(c))});
+ Func("X", utils::Vector{p}, ty.void_(), utils::Vector{Block(Decl(c))});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -892,7 +892,7 @@
}
TEST_F(ResolverVariableTest, LocalConst_ExplicitType_Decls) {
- Structure("S", {Member("m", ty.u32())});
+ Structure("S", utils::Vector{Member("m", ty.u32())});
auto* c_i32 = Const("a", ty.i32(), Expr(0_i));
auto* c_u32 = Const("b", ty.u32(), Expr(0_u));
@@ -936,7 +936,7 @@
}
TEST_F(ResolverVariableTest, LocalConst_ImplicitType_Decls) {
- Structure("S", {Member("m", ty.u32())});
+ Structure("S", utils::Vector{Member("m", ty.u32())});
auto* c_i32 = Const("a", nullptr, Expr(0_i));
auto* c_u32 = Const("b", nullptr, Expr(0_u));
@@ -1037,21 +1037,21 @@
TEST_F(ResolverVariableTest, GlobalVar_StorageClass) {
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
- auto* buf = Structure("S", {Member("m", ty.i32())});
+ auto* buf = Structure("S", utils::Vector{Member("m", ty.i32())});
auto* private_ = GlobalVar("p", ty.i32(), ast::StorageClass::kPrivate);
auto* workgroup = GlobalVar("w", ty.i32(), ast::StorageClass::kWorkgroup);
auto* uniform = GlobalVar("ub", ty.Of(buf), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
auto* storage = GlobalVar("sb", ty.Of(buf), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(0u),
});
auto* handle = GlobalVar("h", ty.depth_texture(ast::TextureDimension::k2d),
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(2u),
create<ast::GroupAttribute>(0u),
});
@@ -1074,10 +1074,10 @@
TEST_F(ResolverVariableTest, GlobalVar_ExplicitStorageClass) {
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
- auto* buf = Structure("S", {Member("m", ty.i32())});
+ auto* buf = Structure("S", utils::Vector{Member("m", ty.i32())});
auto* storage =
GlobalVar("sb", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(0u),
});
@@ -1219,7 +1219,7 @@
// }
auto* p = Param("a", ty.bool_());
- auto* f = Func("a", {p}, ty.void_(), {});
+ auto* f = Func("a", utils::Vector{p}, ty.void_(), utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1240,7 +1240,7 @@
auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
auto* p = Param("a", ty.bool_());
- Func("F", {p}, ty.void_(), {});
+ Func("F", utils::Vector{p}, ty.void_(), utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1261,7 +1261,7 @@
auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
auto* p = Param("a", ty.bool_());
- Func("F", {p}, ty.void_(), {});
+ Func("F", utils::Vector{p}, ty.void_(), utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1282,7 +1282,7 @@
auto* a = Alias("a", ty.i32());
auto* p = Param("a", ty.type_name("a"));
- Func("F", {p}, ty.void_(), {});
+ Func("F", utils::Vector{p}, ty.void_(), utils::Empty);
ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/variable_validation_test.cc b/src/tint/resolver/variable_validation_test.cc
index 08312fe..97b177e 100644
--- a/src/tint/resolver/variable_validation_test.cc
+++ b/src/tint/resolver/variable_validation_test.cc
@@ -98,7 +98,10 @@
// ...
// @id(N) override oN : i32;
constexpr size_t kLimit = std::numeric_limits<decltype(OverrideId::value)>::max();
- Override("reserved", ty.i32(), nullptr, {Id(kLimit)});
+ Override("reserved", ty.i32(), nullptr,
+ utils::Vector{
+ Id(kLimit),
+ });
for (size_t i = 0; i < kLimit; i++) {
Override("o" + std::to_string(i), ty.i32(), nullptr);
}
@@ -288,10 +291,14 @@
// fn f() {
// let p : pointer<storage, i32, read_write> = &s.inner.arr[2i];
// }
- auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
- auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
+ auto* inner = Structure("Inner", utils::Vector{
+ Member("arr", ty.array<i32, 4>()),
+ });
+ auto* buf = Structure("S", utils::Vector{
+ Member("inner", ty.Of(inner)),
+ });
auto* storage = GlobalVar("s", ty.Of(buf), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -319,7 +326,9 @@
}
TEST_F(ResolverVariableValidationTest, NonConstructibleType_RuntimeArray) {
- auto* s = Structure("S", {Member(Source{{56, 78}}, "m", ty.array(ty.i32()))});
+ auto* s = Structure("S", utils::Vector{
+ Member(Source{{56, 78}}, "m", ty.array(ty.i32())),
+ });
auto* v = Var(Source{{12, 34}}, "v", ty.Of(s));
WrapInFunction(v);
@@ -331,7 +340,9 @@
}
TEST_F(ResolverVariableValidationTest, NonConstructibleType_Struct_WithAtomic) {
- auto* s = Structure("S", {Member("m", ty.atomic(ty.i32()))});
+ auto* s = Structure("S", utils::Vector{
+ Member("m", ty.atomic(ty.i32())),
+ });
auto* v = Var("v", ty.Of(s));
WrapInFunction(v);
diff --git a/src/tint/sem/builtin.cc b/src/tint/sem/builtin.cc
index 7d0c56e..ecb2331 100644
--- a/src/tint/sem/builtin.cc
+++ b/src/tint/sem/builtin.cc
@@ -153,11 +153,21 @@
}
bool Builtin::HasSideEffects() const {
- if (IsAtomic() && type_ != sem::BuiltinType::kAtomicLoad) {
- return true;
- }
- if (type_ == sem::BuiltinType::kTextureStore) {
- return true;
+ switch (type_) {
+ case sem::BuiltinType::kAtomicAdd:
+ case sem::BuiltinType::kAtomicAnd:
+ case sem::BuiltinType::kAtomicCompareExchangeWeak:
+ case sem::BuiltinType::kAtomicExchange:
+ case sem::BuiltinType::kAtomicMax:
+ case sem::BuiltinType::kAtomicMin:
+ case sem::BuiltinType::kAtomicOr:
+ case sem::BuiltinType::kAtomicStore:
+ case sem::BuiltinType::kAtomicSub:
+ case sem::BuiltinType::kAtomicXor:
+ case sem::BuiltinType::kTextureStore:
+ return true;
+ default:
+ break;
}
return false;
}
diff --git a/src/tint/sem/sem_struct_test.cc b/src/tint/sem/sem_struct_test.cc
index 4a63712..3ea14e1 100644
--- a/src/tint/sem/sem_struct_test.cc
+++ b/src/tint/sem/sem_struct_test.cc
@@ -23,7 +23,7 @@
TEST_F(StructTest, Creation) {
auto name = Sym("S");
- auto* impl = create<ast::Struct>(name, ast::StructMemberList{}, ast::AttributeList{});
+ auto* impl = create<ast::Struct>(name, utils::Empty, utils::Empty);
auto* ptr = impl;
auto* s = create<sem::Struct>(impl, impl->name, StructMemberList{}, 4u /* align */,
8u /* size */, 16u /* size_no_padding */);
@@ -34,10 +34,10 @@
}
TEST_F(StructTest, Hash) {
- auto* a_impl = create<ast::Struct>(Sym("a"), ast::StructMemberList{}, ast::AttributeList{});
+ auto* a_impl = create<ast::Struct>(Sym("a"), utils::Empty, utils::Empty);
auto* a = create<sem::Struct>(a_impl, a_impl->name, StructMemberList{}, 4u /* align */,
4u /* size */, 4u /* size_no_padding */);
- auto* b_impl = create<ast::Struct>(Sym("b"), ast::StructMemberList{}, ast::AttributeList{});
+ auto* b_impl = create<ast::Struct>(Sym("b"), utils::Empty, utils::Empty);
auto* b = create<sem::Struct>(b_impl, b_impl->name, StructMemberList{}, 4u /* align */,
4u /* size */, 4u /* size_no_padding */);
@@ -45,10 +45,10 @@
}
TEST_F(StructTest, Equals) {
- auto* a_impl = create<ast::Struct>(Sym("a"), ast::StructMemberList{}, ast::AttributeList{});
+ auto* a_impl = create<ast::Struct>(Sym("a"), utils::Empty, utils::Empty);
auto* a = create<sem::Struct>(a_impl, a_impl->name, StructMemberList{}, 4u /* align */,
4u /* size */, 4u /* size_no_padding */);
- auto* b_impl = create<ast::Struct>(Sym("b"), ast::StructMemberList{}, ast::AttributeList{});
+ auto* b_impl = create<ast::Struct>(Sym("b"), utils::Empty, utils::Empty);
auto* b = create<sem::Struct>(b_impl, b_impl->name, StructMemberList{}, 4u /* align */,
4u /* size */, 4u /* size_no_padding */);
@@ -59,7 +59,7 @@
TEST_F(StructTest, FriendlyName) {
auto name = Sym("my_struct");
- auto* impl = create<ast::Struct>(name, ast::StructMemberList{}, ast::AttributeList{});
+ auto* impl = create<ast::Struct>(name, utils::Empty, utils::Empty);
auto* s = create<sem::Struct>(impl, impl->name, StructMemberList{}, 4u /* align */,
4u /* size */, 4u /* size_no_padding */);
EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
@@ -67,7 +67,7 @@
TEST_F(StructTest, Layout) {
auto* inner_st = //
- Structure("Inner", {
+ Structure("Inner", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.u32()),
Member("c", ty.f32()),
@@ -75,7 +75,7 @@
Member("e", ty.mat4x2<f32>()),
});
- auto* outer_st = Structure("Outer", {
+ auto* outer_st = Structure("Outer", utils::Vector{
Member("inner", ty.type_name("Inner")),
Member("a", ty.i32()),
});
diff --git a/src/tint/sem/type.cc b/src/tint/sem/type.cc
index fcc1654..b4887dd 100644
--- a/src/tint/sem/type.cc
+++ b/src/tint/sem/type.cc
@@ -272,7 +272,7 @@
return el_ty;
}
-const sem::Type* Type::Common(utils::ConstVectorRef<const Type*> types) {
+const sem::Type* Type::Common(utils::VectorRef<const Type*> types) {
const auto count = types.Length();
if (count == 0) {
return nullptr;
diff --git a/src/tint/sem/type.h b/src/tint/sem/type.h
index c2b83e5..8bac821 100644
--- a/src/tint/sem/type.h
+++ b/src/tint/sem/type.h
@@ -161,7 +161,7 @@
/// @returns the lowest-ranking type that all types in `types` can be implicitly converted to,
/// or nullptr if there is no consistent common type across all types in `types`.
/// @see https://www.w3.org/TR/WGSL/#conversion-rank
- static const sem::Type* Common(utils::ConstVectorRef<const Type*> types);
+ static const sem::Type* Common(utils::VectorRef<const Type*> types);
protected:
Type();
diff --git a/src/tint/tint.natvis b/src/tint/tint.natvis
index bce3ce5..45ecf93 100644
--- a/src/tint/tint.natvis
+++ b/src/tint/tint.natvis
@@ -16,6 +16,34 @@
-->
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+ <Type Name="tint::utils::Slice<*>">
+ <DisplayString>{{ length={len}, capacity={cap} }}</DisplayString>
+ <Expand>
+ <!--<Item Name="[length]">len</Item>
+ <Item Name="[capacity]">cap</Item>-->
+ <ArrayItems>
+ <Size>len</Size>
+ <ValuePointer>data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="tint::utils::Vector<*,*>">
+ <Expand>
+ <Item Name="[heap]">impl_.slice.cap > (int)$T2</Item>
+ <ExpandedItem>impl_.slice</ExpandedItem>
+ <!--<Item Name="[slice]">impl_.slice</Item>-->
+ </Expand>
+ </Type>
+
+ <Type Name="tint::utils::VectorRef<*>">
+ <Expand>
+ <Item Name="[can move]">can_move_</Item>
+ <ExpandedItem>slice_</ExpandedItem>
+ <!--<Item Name="[slice]">slice_</Item>-->
+ </Expand>
+ </Type>
+
<Type Name="tint::Symbol">
<!-- Requires TINT_SYMBOL_STORE_DEBUG_NAME defined to 1 -->
<DisplayString Optional="true">{debug_name_,sb}</DisplayString>
@@ -63,7 +91,7 @@
</Type>
<Type Name="tint::ast::IdentifierExpression">
- <!--the ",sb" specifier removes the double quotes on the displayed string -->
+ <!--the ",sb" specifier removes the double quotes on the displayed string -->
<DisplayString>{symbol}</DisplayString>
<Expand>
<Item Name="symbol">symbol</Item>
diff --git a/src/tint/traits.h b/src/tint/traits.h
index eb81b3f..d830d2c 100644
--- a/src/tint/traits.h
+++ b/src/tint/traits.h
@@ -91,7 +91,7 @@
/// If `CONDITION` is true then EnableIf resolves to type T, otherwise an
/// invalid type.
-template <bool CONDITION, typename T>
+template <bool CONDITION, typename T = void>
using EnableIf = typename std::enable_if<CONDITION, T>::type;
/// If `T` is of type `BASE`, or derives from `BASE`, then EnableIfIsType
diff --git a/src/tint/transform/add_empty_entry_point.cc b/src/tint/transform/add_empty_entry_point.cc
index f037649..5ef4fe8 100644
--- a/src/tint/transform/add_empty_entry_point.cc
+++ b/src/tint/transform/add_empty_entry_point.cc
@@ -39,7 +39,10 @@
void AddEmptyEntryPoint::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
ctx.dst->Func(ctx.dst->Symbols().New("unused_entry_point"), {}, ctx.dst->ty.void_(), {},
- {ctx.dst->Stage(ast::PipelineStage::kCompute), ctx.dst->WorkgroupSize(1_i)});
+ utils::Vector{
+ ctx.dst->Stage(ast::PipelineStage::kCompute),
+ ctx.dst->WorkgroupSize(1_i),
+ });
ctx.Clone();
}
diff --git a/src/tint/transform/add_spirv_block_attribute.cc b/src/tint/transform/add_spirv_block_attribute.cc
index 85c20c3..3615812 100644
--- a/src/tint/transform/add_spirv_block_attribute.cc
+++ b/src/tint/transform/add_spirv_block_attribute.cc
@@ -58,7 +58,8 @@
for (auto* var : ctx.src->AST().Globals<ast::Var>()) {
auto* sem_var = sem.Get<sem::GlobalVariable>(var);
if (var->declared_storage_class != ast::StorageClass::kStorage &&
- var->declared_storage_class != ast::StorageClass::kUniform) {
+ var->declared_storage_class != ast::StorageClass::kUniform &&
+ var->declared_storage_class != ast::StorageClass::kPushConstant) {
continue;
}
@@ -75,8 +76,8 @@
auto wrapper_name = ctx.src->Symbols().NameFor(var->symbol) + "_block";
auto* ret = ctx.dst->create<ast::Struct>(
ctx.dst->Symbols().New(wrapper_name),
- ast::StructMemberList{ctx.dst->Member(kMemberName, CreateASTTypeFor(ctx, ty))},
- ast::AttributeList{block});
+ utils::Vector{ctx.dst->Member(kMemberName, CreateASTTypeFor(ctx, ty))},
+ utils::Vector{block});
ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), var, ret);
return ret;
});
diff --git a/src/tint/transform/add_spirv_block_attribute_test.cc b/src/tint/transform/add_spirv_block_attribute_test.cc
index 455be60..90f9219 100644
--- a/src/tint/transform/add_spirv_block_attribute_test.cc
+++ b/src/tint/transform/add_spirv_block_attribute_test.cc
@@ -196,6 +196,71 @@
EXPECT_EQ(expect, str(got));
}
+TEST_F(AddSpirvBlockAttributeTest, BasicScalar_PushConstant) {
+ auto* src = R"(
+enable chromium_experimental_push_constant;
+var<push_constant> u : f32;
+
+@fragment
+fn main() {
+ let f = u;
+}
+)";
+ auto* expect = R"(
+enable chromium_experimental_push_constant;
+
+@internal(spirv_block)
+struct u_block {
+ inner : f32,
+}
+
+var<push_constant> u : u_block;
+
+@fragment
+fn main() {
+ let f = u.inner;
+}
+)";
+
+ auto got = Run<AddSpirvBlockAttribute>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(AddSpirvBlockAttributeTest, BasicStruct_PushConstant) {
+ auto* src = R"(
+enable chromium_experimental_push_constant;
+struct S {
+ f : f32,
+};
+var<push_constant> u : S;
+
+@fragment
+fn main() {
+ let f = u.f;
+}
+)";
+ auto* expect = R"(
+enable chromium_experimental_push_constant;
+
+@internal(spirv_block)
+struct S {
+ f : f32,
+}
+
+var<push_constant> u : S;
+
+@fragment
+fn main() {
+ let f = u.f;
+}
+)";
+
+ auto got = Run<AddSpirvBlockAttribute>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
TEST_F(AddSpirvBlockAttributeTest, Nested_OuterBuffer_InnerNotBuffer) {
auto* src = R"(
struct Inner {
diff --git a/src/tint/transform/array_length_from_uniform.cc b/src/tint/transform/array_length_from_uniform.cc
index 81471ad..cdb75c8 100644
--- a/src/tint/transform/array_length_from_uniform.cc
+++ b/src/tint/transform/array_length_from_uniform.cc
@@ -141,13 +141,14 @@
// aligned.
auto* buffer_size_struct = ctx.dst->Structure(
ctx.dst->Sym(),
- {ctx.dst->Member(kBufferSizeMemberName,
- ctx.dst->ty.array(ctx.dst->ty.vec4(ctx.dst->ty.u32()),
- u32((max_buffer_size_index / 4) + 1)))});
+ utils::Vector{
+ ctx.dst->Member(kBufferSizeMemberName,
+ ctx.dst->ty.array(ctx.dst->ty.vec4(ctx.dst->ty.u32()),
+ u32((max_buffer_size_index / 4) + 1))),
+ });
buffer_size_ubo = ctx.dst->GlobalVar(
ctx.dst->Sym(), ctx.dst->ty.Of(buffer_size_struct), ast::StorageClass::kUniform,
- ast::AttributeList{
- ctx.dst->GroupAndBinding(cfg->ubo_binding.group, cfg->ubo_binding.binding)});
+ ctx.dst->GroupAndBinding(cfg->ubo_binding.group, cfg->ubo_binding.binding));
}
return buffer_size_ubo;
};
diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc
index b0f6297..3ca7035 100644
--- a/src/tint/transform/builtin_polyfill.cc
+++ b/src/tint/transform/builtin_polyfill.cc
@@ -15,6 +15,7 @@
#include "src/tint/transform/builtin_polyfill.h"
#include <unordered_map>
+#include <utility>
#include "src/tint/program_builder.h"
#include "src/tint/sem/builtin.h"
@@ -59,16 +60,16 @@
return b.Construct(T(ty), expr);
};
- ast::StatementList body;
+ utils::Vector<const ast::Statement*, 4> body;
switch (polyfill.acosh) {
case Level::kFull:
// return log(x + sqrt(x*x - 1));
- body.emplace_back(b.Return(
+ body.Push(b.Return(
b.Call("log", b.Add("x", b.Call("sqrt", b.Sub(b.Mul("x", "x"), 1_a))))));
break;
case Level::kRangeCheck: {
// return select(acosh(x), 0, x < 1);
- body.emplace_back(b.Return(
+ body.Push(b.Return(
b.Call("select", b.Call("acosh", "x"), V(0.0_a), b.LessThan("x", V(1.0_a)))));
break;
}
@@ -78,7 +79,7 @@
return {};
}
- b.Func(name, {b.Param("x", T(ty))}, T(ty), body);
+ b.Func(name, utils::Vector{b.Param("x", T(ty))}, T(ty), body);
return name;
}
@@ -89,13 +90,11 @@
Symbol asinh(const sem::Type* ty) {
auto name = b.Symbols().New("tint_sinh");
- ast::StatementList body;
-
// return log(x + sqrt(x*x + 1));
- body.emplace_back(
- b.Return(b.Call("log", b.Add("x", b.Call("sqrt", b.Add(b.Mul("x", "x"), 1_a))))));
-
- b.Func(name, {b.Param("x", T(ty))}, T(ty), body);
+ b.Func(name, utils::Vector{b.Param("x", T(ty))}, T(ty),
+ utils::Vector{
+ b.Return(b.Call("log", b.Add("x", b.Call("sqrt", b.Add(b.Mul("x", "x"), 1_a))))),
+ });
return name;
}
@@ -115,17 +114,17 @@
return b.Construct(T(ty), expr);
};
- ast::StatementList body;
+ utils::Vector<const ast::Statement*, 1> body;
switch (polyfill.atanh) {
case Level::kFull:
// return log((1+x) / (1-x)) * 0.5
- body.emplace_back(
+ body.Push(
b.Return(b.Mul(b.Call("log", b.Div(b.Add(1_a, "x"), b.Sub(1_a, "x"))), 0.5_a)));
break;
case Level::kRangeCheck:
// return select(atanh(x), 0, x >= 1);
- body.emplace_back(b.Return(b.Call("select", b.Call("atanh", "x"), V(0.0_a),
- b.GreaterThanEqual("x", V(1.0_a)))));
+ body.Push(b.Return(b.Call("select", b.Call("atanh", "x"), V(0.0_a),
+ b.GreaterThanEqual("x", V(1.0_a)))));
break;
default:
TINT_ICE(Transform, b.Diagnostics())
@@ -133,7 +132,7 @@
return {};
}
- b.Func(name, {b.Param("x", T(ty))}, T(ty), body);
+ b.Func(name, utils::Vector{b.Param("x", T(ty))}, T(ty), body);
return name;
}
@@ -156,8 +155,12 @@
return ScalarOrVector(width, u32(value));
};
b.Func(
- name, {b.Param("v", T(ty))}, T(ty),
- {
+ name,
+ utils::Vector{
+ b.Param("v", T(ty)),
+ },
+ T(ty),
+ utils::Vector{
// var x = U(v);
b.Decl(b.Var("x", nullptr, b.Construct(U(), b.Expr("v")))),
// let b16 = select(0, 16, x <= 0x0000ffff);
@@ -217,8 +220,12 @@
return b.Construct(b.ty.vec<bool>(width), value);
};
b.Func(
- name, {b.Param("v", T(ty))}, T(ty),
- {
+ name,
+ utils::Vector{
+ b.Param("v", T(ty)),
+ },
+ T(ty),
+ utils::Vector{
// var x = U(v);
b.Decl(b.Var("x", nullptr, b.Construct(U(), b.Expr("v")))),
// let b16 = select(16, 0, bool(x & 0x0000ffff));
@@ -270,20 +277,20 @@
return b.Construct(b.ty.vec<u32>(width), value);
};
- ast::StatementList body = {
+ utils::Vector<const ast::Statement*, 8> body{
b.Decl(b.Let("s", nullptr, b.Call("min", "offset", u32(W)))),
b.Decl(b.Let("e", nullptr, b.Call("min", u32(W), b.Add("s", "count")))),
};
switch (polyfill.extract_bits) {
case Level::kFull:
- body.emplace_back(b.Decl(b.Let("shl", nullptr, b.Sub(u32(W), "e"))));
- body.emplace_back(b.Decl(b.Let("shr", nullptr, b.Add("shl", "s"))));
- body.emplace_back(
+ body.Push(b.Decl(b.Let("shl", nullptr, b.Sub(u32(W), "e"))));
+ body.Push(b.Decl(b.Let("shr", nullptr, b.Add("shl", "s"))));
+ body.Push(
b.Return(b.Shr(b.Shl("v", vecN_u32(b.Expr("shl"))), vecN_u32(b.Expr("shr")))));
break;
case Level::kClampParameters:
- body.emplace_back(b.Return(b.Call("extractBits", "v", "s", b.Sub("e", "s"))));
+ body.Push(b.Return(b.Call("extractBits", "v", "s", b.Sub("e", "s"))));
break;
default:
TINT_ICE(Transform, b.Diagnostics())
@@ -292,12 +299,12 @@
}
b.Func(name,
- {
+ utils::Vector{
b.Param("v", T(ty)),
b.Param("offset", b.ty.u32()),
b.Param("count", b.ty.u32()),
},
- T(ty), body);
+ T(ty), std::move(body));
return name;
}
@@ -338,8 +345,12 @@
}
b.Func(
- name, {b.Param("v", T(ty))}, T(ty),
- {
+ name,
+ utils::Vector{
+ b.Param("v", T(ty)),
+ },
+ T(ty),
+ utils::Vector{
// var x = v; (unsigned)
// var x = select(U(v), ~U(v), v < 0); (signed)
b.Decl(b.Var("x", nullptr, x)),
@@ -400,8 +411,12 @@
return b.Construct(b.ty.vec<bool>(width), value);
};
b.Func(
- name, {b.Param("v", T(ty))}, T(ty),
- {
+ name,
+ utils::Vector{
+ b.Param("v", T(ty)),
+ },
+ T(ty),
+ utils::Vector{
// var x = U(v);
b.Decl(b.Var("x", nullptr, b.Construct(U(), b.Expr("v")))),
// let b16 = select(16, 0, bool(x & 0x0000ffff));
@@ -463,7 +478,7 @@
return b.vec(b.ty.u32(), width, value);
};
- ast::StatementList body = {
+ utils::Vector<const ast::Statement*, 8> body = {
b.Decl(b.Let("s", nullptr, b.Call("min", "offset", u32(W)))),
b.Decl(b.Let("e", nullptr, b.Call("min", u32(W), b.Add("s", "count")))),
};
@@ -471,15 +486,15 @@
switch (polyfill.insert_bits) {
case Level::kFull:
// let mask = ((1 << s) - 1) ^ ((1 << e) - 1)
- body.emplace_back(
+ body.Push(
b.Decl(b.Let("mask", nullptr,
b.Xor(b.Sub(b.Shl(1_u, "s"), 1_u), b.Sub(b.Shl(1_u, "e"), 1_u)))));
// return ((n << s) & mask) | (v & ~mask)
- body.emplace_back(b.Return(b.Or(b.And(b.Shl("n", U("s")), V("mask")),
- b.And("v", V(b.Complement("mask"))))));
+ body.Push(b.Return(b.Or(b.And(b.Shl("n", U("s")), V("mask")),
+ b.And("v", V(b.Complement("mask"))))));
break;
case Level::kClampParameters:
- body.emplace_back(b.Return(b.Call("insertBits", "v", "n", "s", b.Sub("e", "s"))));
+ body.Push(b.Return(b.Call("insertBits", "v", "n", "s", b.Sub("e", "s"))));
break;
default:
TINT_ICE(Transform, b.Diagnostics())
@@ -488,7 +503,7 @@
}
b.Func(name,
- {
+ utils::Vector{
b.Param("v", T(ty)),
b.Param("n", T(ty)),
b.Param("offset", b.ty.u32()),
diff --git a/src/tint/transform/calculate_array_length.cc b/src/tint/transform/calculate_array_length.cc
index cfeaca8..6c15e73 100644
--- a/src/tint/transform/calculate_array_length.cc
+++ b/src/tint/transform/calculate_array_length.cc
@@ -101,20 +101,20 @@
ctx.dst->Disable(ast::DisabledValidation::kFunctionParameter);
ctx.dst->AST().AddFunction(ctx.dst->create<ast::Function>(
name,
- ast::ParameterList{
+ utils::Vector{
ctx.dst->Param("buffer",
ctx.dst->ty.pointer(type, buffer_type->StorageClass(),
buffer_type->Access()),
- {disable_validation}),
+ utils::Vector{disable_validation}),
ctx.dst->Param("result", ctx.dst->ty.pointer(ctx.dst->ty.u32(),
ast::StorageClass::kFunction)),
},
ctx.dst->ty.void_(), nullptr,
- ast::AttributeList{
+ utils::Vector{
ctx.dst->ASTNodes().Create<BufferSizeIntrinsic>(ctx.dst->ID(),
ctx.dst->AllocateNodeID()),
},
- ast::AttributeList{}));
+ utils::Empty));
return name;
});
diff --git a/src/tint/transform/canonicalize_entry_point_io.cc b/src/tint/transform/canonicalize_entry_point_io.cc
index acec84f..7670f09 100644
--- a/src/tint/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/transform/canonicalize_entry_point_io.cc
@@ -69,7 +69,7 @@
}
// Returns true if `attrs` contains a `sample_mask` builtin.
-bool HasSampleMask(const ast::AttributeList& attrs) {
+bool HasSampleMask(utils::VectorRef<const ast::Attribute*> attrs) {
auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(attrs);
return builtin && builtin->builtin == ast::BuiltinValue::kSampleMask;
}
@@ -85,7 +85,7 @@
/// The type of the output value.
const ast::Type* type;
/// The shader IO attributes.
- ast::AttributeList attributes;
+ utils::Vector<const ast::Attribute*, 2> attributes;
/// The value itself.
const ast::Expression* value;
};
@@ -100,19 +100,19 @@
const sem::Function* func_sem;
/// The new entry point wrapper function's parameters.
- ast::ParameterList wrapper_ep_parameters;
+ utils::Vector<const ast::Parameter*, 8> wrapper_ep_parameters;
/// The members of the wrapper function's struct parameter.
- ast::StructMemberList wrapper_struct_param_members;
+ utils::Vector<const ast::StructMember*, 8> wrapper_struct_param_members;
/// The name of the wrapper function's struct parameter.
Symbol wrapper_struct_param_name;
/// The parameters that will be passed to the original function.
- ast::ExpressionList inner_call_parameters;
+ utils::Vector<const ast::Expression*, 8> inner_call_parameters;
/// The members of the wrapper function's struct return type.
- ast::StructMemberList wrapper_struct_output_members;
+ utils::Vector<const ast::StructMember*, 8> wrapper_struct_output_members;
/// The wrapper function output values.
- std::vector<OutputValue> wrapper_output_values;
+ utils::Vector<OutputValue, 8> wrapper_output_values;
/// The body of the wrapper function.
- ast::StatementList wrapper_body;
+ utils::Vector<const ast::Statement*, 8> wrapper_body;
/// Input names used by the entrypoint
std::unordered_set<std::string> input_names;
@@ -129,12 +129,13 @@
/// @param src the attributes to clone
/// @param do_interpolate whether to clone InterpolateAttribute
/// @return the cloned attributes
- ast::AttributeList CloneShaderIOAttributes(const ast::AttributeList& src, bool do_interpolate) {
- ast::AttributeList new_attributes;
+ template <size_t N>
+ auto CloneShaderIOAttributes(utils::Vector<const ast::Attribute*, N> src, bool do_interpolate) {
+ utils::Vector<const ast::Attribute*, N> new_attributes;
for (auto* attr : src) {
if (IsShaderIOAttribute(attr) &&
- (do_interpolate || !attr->Is<ast::InterpolateAttribute>())) {
- new_attributes.push_back(ctx.Clone(attr));
+ (do_interpolate || !attr->template Is<ast::InterpolateAttribute>())) {
+ new_attributes.Push(ctx.Clone(attr));
}
}
return new_attributes;
@@ -156,7 +157,7 @@
/// @returns an expression which evaluates to the value of the shader input
const ast::Expression* AddInput(std::string name,
const sem::Type* type,
- ast::AttributeList attributes) {
+ utils::Vector<const ast::Attribute*, 8> attributes) {
auto* ast_type = CreateASTTypeFor(ctx, type);
if (cfg.shader_style == ShaderStyle::kSpirv || cfg.shader_style == ShaderStyle::kGlsl) {
// Vulkan requires that integer user-defined fragment inputs are always decorated with
@@ -169,12 +170,12 @@
!ast::HasAttribute<ast::InterpolateAttribute>(attributes) &&
(ast::HasAttribute<ast::LocationAttribute>(attributes) ||
cfg.shader_style == ShaderStyle::kSpirv)) {
- attributes.push_back(ctx.dst->Interpolate(ast::InterpolationType::kFlat,
- ast::InterpolationSampling::kNone));
+ attributes.Push(ctx.dst->Interpolate(ast::InterpolationType::kFlat,
+ ast::InterpolationSampling::kNone));
}
// Disable validation for use of the `input` storage class.
- attributes.push_back(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
+ attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
// In GLSL, if it's a builtin, override the name with the
// corresponding gl_ builtin name
@@ -206,14 +207,13 @@
// parameter list and pass it directly to the inner function.
Symbol symbol = input_names.emplace(name).second ? ctx.dst->Symbols().Register(name)
: ctx.dst->Symbols().New(name);
- wrapper_ep_parameters.push_back(
- ctx.dst->Param(symbol, ast_type, std::move(attributes)));
+ wrapper_ep_parameters.Push(ctx.dst->Param(symbol, ast_type, std::move(attributes)));
return ctx.dst->Expr(symbol);
} else {
// Otherwise, move it to the new structure member list.
Symbol symbol = input_names.emplace(name).second ? ctx.dst->Symbols().Register(name)
: ctx.dst->Symbols().New(name);
- wrapper_struct_param_members.push_back(
+ wrapper_struct_param_members.Push(
ctx.dst->Member(symbol, ast_type, std::move(attributes)));
return ctx.dst->MemberAccessor(InputStructSymbol(), symbol);
}
@@ -226,7 +226,7 @@
/// @param value the value of the shader output
void AddOutput(std::string name,
const sem::Type* type,
- ast::AttributeList attributes,
+ utils::Vector<const ast::Attribute*, 8> attributes,
const ast::Expression* value) {
// Vulkan requires that integer user-defined vertex outputs are always decorated with
// `Flat`.
@@ -237,8 +237,8 @@
type->is_integer_scalar_or_vector() &&
ast::HasAttribute<ast::LocationAttribute>(attributes) &&
!ast::HasAttribute<ast::InterpolateAttribute>(attributes)) {
- attributes.push_back(ctx.dst->Interpolate(ast::InterpolationType::kFlat,
- ast::InterpolationSampling::kNone));
+ attributes.Push(ctx.dst->Interpolate(ast::InterpolationType::kFlat,
+ ast::InterpolationSampling::kNone));
}
// In GLSL, if it's a builtin, override the name with the
@@ -256,7 +256,7 @@
output.type = CreateASTTypeFor(ctx, type);
output.attributes = std::move(attributes);
output.value = value;
- wrapper_output_values.push_back(output);
+ wrapper_output_values.Push(output);
}
/// Process a non-struct parameter.
@@ -269,19 +269,19 @@
bool do_interpolate = func_ast->PipelineStage() != ast::PipelineStage::kVertex;
// Remove the shader IO attributes from the inner function parameter, and
// attach them to the new object instead.
- ast::AttributeList attributes;
+ utils::Vector<const ast::Attribute*, 8> attributes;
for (auto* attr : param->Declaration()->attributes) {
if (IsShaderIOAttribute(attr)) {
ctx.Remove(param->Declaration()->attributes, attr);
if ((do_interpolate || !attr->Is<ast::InterpolateAttribute>())) {
- attributes.push_back(ctx.Clone(attr));
+ attributes.Push(ctx.Clone(attr));
}
}
}
auto name = ctx.src->Symbols().NameFor(param->Declaration()->symbol);
auto* input_expr = AddInput(name, param->Type(), std::move(attributes));
- inner_call_parameters.push_back(input_expr);
+ inner_call_parameters.Push(input_expr);
}
/// Process a struct parameter.
@@ -297,7 +297,7 @@
// Recreate struct members in the outer entry point and build an initializer
// list to pass them through to the inner function.
- ast::ExpressionList inner_struct_values;
+ utils::Vector<const ast::Expression*, 8> inner_struct_values;
for (auto* member : str->Members()) {
if (member->Type()->Is<sem::Struct>()) {
TINT_ICE(Transform, ctx.dst->Diagnostics()) << "nested IO struct";
@@ -309,11 +309,11 @@
auto attributes = CloneShaderIOAttributes(member_ast->attributes, do_interpolate);
auto* input_expr = AddInput(name, member->Type(), std::move(attributes));
- inner_struct_values.push_back(input_expr);
+ inner_struct_values.Push(input_expr);
}
// Construct the original structure using the new shader input objects.
- inner_call_parameters.push_back(
+ inner_call_parameters.Push(
ctx.dst->Construct(ctx.Clone(param->Declaration()->type), inner_struct_values));
}
@@ -394,19 +394,19 @@
// Create the new struct type.
auto struct_name = ctx.dst->Sym();
- auto* in_struct = ctx.dst->create<ast::Struct>(struct_name, wrapper_struct_param_members,
- ast::AttributeList{});
+ auto* in_struct =
+ ctx.dst->create<ast::Struct>(struct_name, wrapper_struct_param_members, utils::Empty);
ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func_ast, in_struct);
// Create a new function parameter using this struct type.
auto* param = ctx.dst->Param(InputStructSymbol(), ctx.dst->ty.type_name(struct_name));
- wrapper_ep_parameters.push_back(param);
+ wrapper_ep_parameters.Push(param);
}
/// Create and return the wrapper function's struct result object.
/// @returns the struct type
ast::Struct* CreateOutputStruct() {
- ast::StatementList assignments;
+ utils::Vector<const ast::Statement*, 8> assignments;
auto wrapper_result = ctx.dst->Symbols().New("wrapper_result");
@@ -422,9 +422,9 @@
}
member_names.insert(ctx.dst->Symbols().NameFor(name));
- wrapper_struct_output_members.push_back(
+ wrapper_struct_output_members.Push(
ctx.dst->Member(name, outval.type, std::move(outval.attributes)));
- assignments.push_back(
+ assignments.Push(
ctx.dst->Assign(ctx.dst->MemberAccessor(wrapper_result, name), outval.value));
}
@@ -434,14 +434,16 @@
// Create the new struct type.
auto* out_struct = ctx.dst->create<ast::Struct>(
- ctx.dst->Sym(), wrapper_struct_output_members, ast::AttributeList{});
+ ctx.dst->Sym(), wrapper_struct_output_members, utils::Empty);
ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func_ast, out_struct);
// Create the output struct object, assign its members, and return it.
auto* result_object = ctx.dst->Var(wrapper_result, ctx.dst->ty.type_name(out_struct->name));
- wrapper_body.push_back(ctx.dst->Decl(result_object));
- wrapper_body.insert(wrapper_body.end(), assignments.begin(), assignments.end());
- wrapper_body.push_back(ctx.dst->Return(wrapper_result));
+ wrapper_body.Push(ctx.dst->Decl(result_object));
+ for (auto* assignment : assignments) {
+ wrapper_body.Push(assignment);
+ }
+ wrapper_body.Push(ctx.dst->Return(wrapper_result));
return out_struct;
}
@@ -450,8 +452,8 @@
void CreateGlobalOutputVariables() {
for (auto& outval : wrapper_output_values) {
// Disable validation for use of the `output` storage class.
- ast::AttributeList attributes = std::move(outval.attributes);
- attributes.push_back(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
+ utils::Vector<const ast::Attribute*, 8> attributes = std::move(outval.attributes);
+ attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
// Create the global variable and assign it the output value.
auto name = ctx.dst->Symbols().New(outval.name);
@@ -464,7 +466,7 @@
lhs = ctx.dst->IndexAccessor(lhs, 0_i);
}
ctx.dst->GlobalVar(name, type, ast::StorageClass::kOut, std::move(attributes));
- wrapper_body.push_back(ctx.dst->Assign(lhs, outval.value));
+ wrapper_body.Push(ctx.dst->Assign(lhs, outval.value));
}
}
@@ -488,7 +490,7 @@
// processing.
auto* inner_function = ctx.dst->create<ast::Function>(
inner_name, ctx.Clone(func_ast->params), ctx.Clone(func_ast->return_type),
- ctx.Clone(func_ast->body), ast::AttributeList{}, ast::AttributeList{});
+ ctx.Clone(func_ast->body), utils::Empty, utils::Empty);
ctx.Replace(func_ast, inner_function);
// Call the function.
@@ -527,7 +529,7 @@
}
// Create a structure parameter for the outer entry point if necessary.
- if (!wrapper_struct_param_members.empty()) {
+ if (!wrapper_struct_param_members.IsEmpty()) {
CreateInputStruct();
}
}
@@ -539,12 +541,12 @@
std::function<const ast::Type*()> wrapper_ret_type = [&] { return ctx.dst->ty.void_(); };
if (func_sem->ReturnType()->Is<sem::Void>()) {
// The function call is just a statement with no result.
- wrapper_body.push_back(ctx.dst->CallStmt(call_inner));
+ wrapper_body.Push(ctx.dst->CallStmt(call_inner));
} else {
// Capture the result of calling the original function.
auto* inner_result =
ctx.dst->Let(ctx.dst->Symbols().New("inner_result"), nullptr, call_inner);
- wrapper_body.push_back(ctx.dst->Decl(inner_result));
+ wrapper_body.Push(ctx.dst->Decl(inner_result));
// Process the original return type to determine the outputs that the
// outer function needs to produce.
@@ -562,7 +564,7 @@
}
// Produce the entry point outputs, if necessary.
- if (!wrapper_output_values.empty()) {
+ if (!wrapper_output_values.IsEmpty()) {
if (cfg.shader_style == ShaderStyle::kSpirv || cfg.shader_style == ShaderStyle::kGlsl) {
CreateGlobalOutputVariables();
} else {
@@ -578,11 +580,11 @@
auto* pos_y = GLPosition("y");
auto* negate_pos_y =
ctx.dst->create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, GLPosition("y"));
- wrapper_body.push_back(ctx.dst->Assign(pos_y, negate_pos_y));
+ wrapper_body.Push(ctx.dst->Assign(pos_y, negate_pos_y));
auto* two_z = ctx.dst->Mul(ctx.dst->Expr(2_f), GLPosition("z"));
auto* fixed_z = ctx.dst->Sub(two_z, GLPosition("w"));
- wrapper_body.push_back(ctx.dst->Assign(GLPosition("z"), fixed_z));
+ wrapper_body.Push(ctx.dst->Assign(GLPosition("z"), fixed_z));
}
// Create the wrapper entry point function.
@@ -597,7 +599,7 @@
auto* wrapper_func = ctx.dst->create<ast::Function>(
name, wrapper_ep_parameters, wrapper_ret_type(), ctx.dst->Block(wrapper_body),
- ctx.Clone(func_ast->attributes), ast::AttributeList{});
+ ctx.Clone(func_ast->attributes), utils::Empty);
ctx.InsertAfter(ctx.src->AST().GlobalDeclarations(), func_ast, wrapper_func);
}
diff --git a/src/tint/transform/combine_samplers.cc b/src/tint/transform/combine_samplers.cc
index 4e31789..2f5101e 100644
--- a/src/tint/transform/combine_samplers.cc
+++ b/src/tint/transform/combine_samplers.cc
@@ -78,9 +78,9 @@
/// Group and binding attributes used by all combined sampler globals.
/// Group 0 and binding 0 are used, with collisions disabled.
/// @returns the newly-created attribute list
- ast::AttributeList Attributes() const {
- auto attributes = ctx.dst->GroupAndBinding(0, 0);
- attributes.push_back(ctx.dst->Disable(ast::DisabledValidation::kBindingPointCollision));
+ auto Attributes() const {
+ utils::Vector<const ast::Attribute*, 3> attributes = ctx.dst->GroupAndBinding(0, 0);
+ attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kBindingPointCollision));
return attributes;
}
@@ -170,7 +170,7 @@
if (pairs.empty()) {
return nullptr;
}
- ast::ParameterList params;
+ utils::Vector<const ast::Parameter*, 8> params;
for (auto pair : func->TextureSamplerPairs()) {
const sem::Variable* texture_var = pair.first;
const sem::Variable* sampler_var = pair.second;
@@ -191,7 +191,7 @@
// add a new function parameter to represent the combined sampler.
auto* type = CreateCombinedASTTypeFor(texture_var, sampler_var);
auto* var = ctx.dst->Param(ctx.dst->Symbols().New(name), type);
- params.push_back(var);
+ params.Push(var);
function_combined_texture_samplers_[func][pair] = var;
}
}
@@ -199,7 +199,7 @@
// function signature.
for (auto* var : src->params) {
if (!sem.Get(var->type)->IsAnyOf<sem::Texture, sem::Sampler>()) {
- params.push_back(ctx.Clone(var));
+ params.Push(ctx.Clone(var));
}
}
// Create a new function signature that differs only in the parameter
@@ -221,7 +221,7 @@
// the combined global samplers, as appropriate.
ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::Expression* {
if (auto* call = sem.Get(expr)->UnwrapMaterialize()->As<sem::Call>()) {
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
// Replace all texture builtin calls.
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
const auto& signature = builtin->Signature();
@@ -252,7 +252,7 @@
? global_combined_texture_samplers_[new_pair]
: function_combined_texture_samplers_[call->Stmt()->Function()]
[new_pair];
- args.push_back(ctx.dst->Expr(var->symbol));
+ args.Push(ctx.dst->Expr(var->symbol));
} else if (auto* sampler_type = type->As<sem::Sampler>()) {
ast::SamplerKind kind = sampler_type->kind();
int index = (kind == ast::SamplerKind::kSampler) ? 0 : 1;
@@ -260,9 +260,9 @@
if (!p) {
p = CreatePlaceholder(kind);
}
- args.push_back(ctx.dst->Expr(p->symbol));
+ args.Push(ctx.dst->Expr(p->symbol));
} else {
- args.push_back(ctx.Clone(arg));
+ args.Push(ctx.Clone(arg));
}
}
const ast::Expression* value =
@@ -304,7 +304,7 @@
: function_combined_texture_samplers_[call->Stmt()->Function()]
[new_pair];
auto* arg = ctx.dst->Expr(var->symbol);
- args.push_back(arg);
+ args.Push(arg);
}
// Append all of the remaining non-texture and non-sampler
// parameters.
@@ -312,7 +312,7 @@
if (!ctx.src->TypeOf(arg)
->UnwrapRef()
->IsAnyOf<sem::Texture, sem::Sampler>()) {
- args.push_back(ctx.Clone(arg));
+ args.Push(ctx.Clone(arg));
}
}
return ctx.dst->Call(ctx.Clone(expr->target.name), args);
diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc
index 135a42a..d725a4b 100644
--- a/src/tint/transform/decompose_memory_access.cc
+++ b/src/tint/transform/decompose_memory_access.cc
@@ -440,10 +440,10 @@
auto access = var_user->Variable()->Access();
return utils::GetOrCreate(
load_funcs, LoadStoreKey{storage_class, access, buf_ty, el_ty}, [&] {
- ast::ParameterList params = {
+ utils::Vector params{
b.Param("buffer",
b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), storage_class, access),
- {b.Disable(ast::DisabledValidation::kFunctionParameter)}),
+ utils::Vector{b.Disable(ast::DisabledValidation::kFunctionParameter)}),
b.Param("offset", b.ty.u32()),
};
@@ -453,11 +453,11 @@
auto* el_ast_ty = CreateASTTypeFor(ctx, el_ty);
auto* func = b.create<ast::Function>(
name, params, el_ast_ty, nullptr,
- ast::AttributeList{
+ utils::Vector{
intrinsic,
b.Disable(ast::DisabledValidation::kFunctionHasNoBody),
},
- ast::AttributeList{});
+ utils::Empty);
b.AST().AddFunction(func);
} else if (auto* arr_ty = el_ty->As<sem::Array>()) {
// fn load_func(buffer : buf_ty, offset : u32) -> array<T, N> {
@@ -481,29 +481,29 @@
b.For(for_init, for_cond, for_cont, b.Block(b.Assign(arr_el, el_val)));
b.Func(name, params, CreateASTTypeFor(ctx, arr_ty),
- {
+ utils::Vector{
b.Decl(arr),
for_loop,
b.Return(arr),
});
} else {
- ast::ExpressionList values;
+ utils::Vector<const ast::Expression*, 8> values;
if (auto* mat_ty = el_ty->As<sem::Matrix>()) {
auto* vec_ty = mat_ty->ColumnType();
Symbol load = LoadFunc(buf_ty, vec_ty, var_user);
for (uint32_t i = 0; i < mat_ty->columns(); i++) {
auto* offset = b.Add("offset", u32(i * mat_ty->ColumnStride()));
- values.emplace_back(b.Call(load, "buffer", offset));
+ values.Push(b.Call(load, "buffer", offset));
}
} else if (auto* str = el_ty->As<sem::Struct>()) {
for (auto* member : str->Members()) {
auto* offset = b.Add("offset", u32(member->Offset()));
Symbol load = LoadFunc(buf_ty, member->Type()->UnwrapRef(), var_user);
- values.emplace_back(b.Call(load, "buffer", offset));
+ values.Push(b.Call(load, "buffer", offset));
}
}
b.Func(name, params, CreateASTTypeFor(ctx, el_ty),
- {
+ utils::Vector{
b.Return(b.Construct(CreateASTTypeFor(ctx, el_ty), values)),
});
}
@@ -526,10 +526,10 @@
auto access = var_user->Variable()->Access();
return utils::GetOrCreate(
store_funcs, LoadStoreKey{storage_class, access, buf_ty, el_ty}, [&] {
- ast::ParameterList params{
+ utils::Vector params{
b.Param("buffer",
b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), storage_class, access),
- {b.Disable(ast::DisabledValidation::kFunctionParameter)}),
+ utils::Vector{b.Disable(ast::DisabledValidation::kFunctionParameter)}),
b.Param("offset", b.ty.u32()),
b.Param("value", CreateASTTypeFor(ctx, el_ty)),
};
@@ -539,14 +539,14 @@
if (auto* intrinsic = IntrinsicStoreFor(ctx.dst, storage_class, el_ty)) {
auto* func = b.create<ast::Function>(
name, params, b.ty.void_(), nullptr,
- ast::AttributeList{
+ utils::Vector{
intrinsic,
b.Disable(ast::DisabledValidation::kFunctionHasNoBody),
},
- ast::AttributeList{});
+ utils::Empty);
b.AST().AddFunction(func);
} else {
- auto body = Switch(
+ auto body = Switch<utils::Vector<const ast::Statement*, 8>>(
el_ty, //
[&](const sem::Array* arr_ty) {
// fn store_func(buffer : buf_ty, offset : u32, value : el_ty) {
@@ -573,22 +573,22 @@
auto* for_loop =
b.For(for_init, for_cond, for_cont, b.Block(store_stmt));
- return ast::StatementList{b.Decl(array), for_loop};
+ return utils::Vector{b.Decl(array), for_loop};
},
[&](const sem::Matrix* mat_ty) {
auto* vec_ty = mat_ty->ColumnType();
Symbol store = StoreFunc(buf_ty, vec_ty, var_user);
- ast::StatementList stmts;
+ utils::Vector<const ast::Statement*, 4> stmts;
for (uint32_t i = 0; i < mat_ty->columns(); i++) {
auto* offset = b.Add("offset", u32(i * mat_ty->ColumnStride()));
auto* element = b.IndexAccessor("value", u32(i));
auto* call = b.Call(store, "buffer", offset, element);
- stmts.emplace_back(b.CallStmt(call));
+ stmts.Push(b.CallStmt(call));
}
return stmts;
},
[&](const sem::Struct* str) {
- ast::StatementList stmts;
+ utils::Vector<const ast::Statement*, 8> stmts;
for (auto* member : str->Members()) {
auto* offset = b.Add("offset", u32(member->Offset()));
auto* element = b.MemberAccessor(
@@ -596,7 +596,7 @@
Symbol store =
StoreFunc(buf_ty, member->Type()->UnwrapRef(), var_user);
auto* call = b.Call(store, "buffer", offset, element);
- stmts.emplace_back(b.CallStmt(call));
+ stmts.Push(b.CallStmt(call));
}
return stmts;
});
@@ -626,11 +626,11 @@
return utils::GetOrCreate(atomic_funcs, AtomicKey{access, buf_ty, el_ty, op}, [&] {
// The first parameter to all WGSL atomics is the expression to the
// atomic. This is replaced with two parameters: the buffer and offset.
- ast::ParameterList params = {
+ utils::Vector params{
b.Param("buffer",
b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), ast::StorageClass::kStorage,
access),
- {b.Disable(ast::DisabledValidation::kFunctionParameter)}),
+ utils::Vector{b.Disable(ast::DisabledValidation::kFunctionParameter)}),
b.Param("offset", b.ty.u32()),
};
@@ -638,7 +638,7 @@
for (size_t i = 1; i < intrinsic->Parameters().Length(); i++) {
auto* param = intrinsic->Parameters()[i];
auto* ty = CreateASTTypeFor(ctx, param->Type());
- params.emplace_back(b.Param("param_" + std::to_string(i), ty));
+ params.Push(b.Param("param_" + std::to_string(i), ty));
}
auto* atomic = IntrinsicAtomicFor(ctx.dst, op, el_ty);
@@ -655,10 +655,10 @@
auto* str = intrinsic->ReturnType()->As<sem::Struct>();
TINT_ASSERT(Transform, str && str->Declaration() == nullptr);
- ast::StructMemberList ast_members;
- ast_members.reserve(str->Members().size());
+ utils::Vector<const ast::StructMember*, 8> ast_members;
+ ast_members.Reserve(str->Members().size());
for (auto& m : str->Members()) {
- ast_members.push_back(
+ ast_members.Push(
b.Member(ctx.Clone(m->Name()), CreateASTTypeFor(ctx, m->Type())));
}
@@ -671,11 +671,11 @@
auto* func = b.create<ast::Function>(
b.Symbols().New(std::string{"tint_"} + intrinsic->str()), params, ret_ty, nullptr,
- ast::AttributeList{
+ utils::Vector{
atomic,
b.Disable(ast::DisabledValidation::kFunctionHasNoBody),
},
- ast::AttributeList{});
+ utils::Empty);
b.AST().AddFunction(func);
return func->symbol;
@@ -933,10 +933,11 @@
Symbol func = state.AtomicFunc(buf_ty, el_ty, builtin,
access.var->As<sem::VariableUser>());
- ast::ExpressionList args{ctx.dst->AddressOf(ctx.Clone(buf)), offset};
- for (size_t i = 1; i < call_expr->args.size(); i++) {
+ utils::Vector<const ast::Expression*, 8> args{
+ ctx.dst->AddressOf(ctx.Clone(buf)), offset};
+ for (size_t i = 1; i < call_expr->args.Length(); i++) {
auto* arg = call_expr->args[i];
- args.emplace_back(ctx.Clone(arg));
+ args.Push(ctx.Clone(arg));
}
return ctx.dst->Call(func, args);
});
diff --git a/src/tint/transform/decompose_strided_array.cc b/src/tint/transform/decompose_strided_array.cc
index ba6252b..61841f6 100644
--- a/src/tint/transform/decompose_strided_array.cc
+++ b/src/tint/transform/decompose_strided_array.cc
@@ -72,8 +72,10 @@
auto name = ctx.dst->Symbols().New("strided_arr");
auto* member_ty = ctx.Clone(ast->type);
auto* member = ctx.dst->Member(kMemberName, member_ty,
- {ctx.dst->MemberSize(arr->Stride())});
- ctx.dst->Structure(name, {member});
+ utils::Vector{
+ ctx.dst->MemberSize(arr->Stride()),
+ });
+ ctx.dst->Structure(name, utils::Vector{member});
return name;
});
auto* count = ctx.Clone(ast->count);
@@ -114,7 +116,7 @@
// ->
// `array<strided_arr, 3>(strided_arr(1), strided_arr(2), strided_arr(3))`
ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::Expression* {
- if (!expr->args.empty()) {
+ if (!expr->args.IsEmpty()) {
if (auto* call = sem.Get(expr)->UnwrapMaterialize()->As<sem::Call>()) {
if (auto* ctor = call->Target()->As<sem::TypeConstructor>()) {
if (auto* arr = ctor->ReturnType()->As<sem::Array>()) {
@@ -130,18 +132,18 @@
target.name = ctx.Clone(expr->target.name);
}
- ast::ExpressionList args;
+ utils::Vector<const ast::Expression*, 8> args;
if (auto it = decomposed.find(arr); it != decomposed.end()) {
- args.reserve(expr->args.size());
+ args.Reserve(expr->args.Length());
for (auto* arg : expr->args) {
- args.emplace_back(ctx.dst->Call(it->second, ctx.Clone(arg)));
+ args.Push(ctx.dst->Call(it->second, ctx.Clone(arg)));
}
} else {
args = ctx.Clone(expr->args);
}
- return target.type ? ctx.dst->Construct(target.type, args)
- : ctx.dst->Call(target.name, args);
+ return target.type ? ctx.dst->Construct(target.type, std::move(args))
+ : ctx.dst->Call(target.name, std::move(args));
}
}
}
diff --git a/src/tint/transform/decompose_strided_array_test.cc b/src/tint/transform/decompose_strided_array_test.cc
index 65b394a..4b0a335 100644
--- a/src/tint/transform/decompose_strided_array_test.cc
+++ b/src/tint/transform/decompose_strided_array_test.cc
@@ -79,12 +79,12 @@
ProgramBuilder b;
b.GlobalVar("arr", b.ty.array<f32, 4u>(4), ast::StorageClass::kPrivate);
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("a", b.ty.array<f32, 4u>(4), b.Expr("arr"))),
b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor("arr", 1_i))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -115,12 +115,12 @@
ProgramBuilder b;
b.GlobalVar("arr", b.ty.array<f32, 4u>(32), ast::StorageClass::kPrivate);
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.Expr("arr"))),
b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor("arr", 1_i))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -157,14 +157,14 @@
// let b : f32 = s.a[1];
// }
ProgramBuilder b;
- auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
+ auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.MemberAccessor("s", "a"))),
b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -205,16 +205,16 @@
// let b : f32 = s.a[1][2];
// }
ProgramBuilder b;
- auto* S = b.Structure("S", {b.Member("a", b.ty.array(b.ty.vec4<f32>(), 4_u, 16))});
+ auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array(b.ty.vec4<f32>(), 4_u, 16))});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
b.Func(
- "f", {}, b.ty.void_(),
- {
+ "f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("a", b.ty.array(b.ty.vec4<f32>(), 4_u, 16), b.MemberAccessor("s", "a"))),
b.Decl(b.Let("b", b.ty.f32(),
b.IndexAccessor(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 2_i))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -251,14 +251,14 @@
// let b : f32 = s.a[1];
// }
ProgramBuilder b;
- auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
+ auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.MemberAccessor("s", "a"))),
b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -299,14 +299,14 @@
// let b : f32 = s.a[1];
// }
ProgramBuilder b;
- auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(4))});
+ auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(4))});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("a", b.ty.array<f32, 4u>(4), b.MemberAccessor("s", "a"))),
b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -343,17 +343,17 @@
// s.a[1i] = 5.0;
// }
ProgramBuilder b;
- auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
+ auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4u>(32))),
b.Assign(b.MemberAccessor("s", "a"),
b.Construct(b.ty.array<f32, 4u>(32), 1_f, 2_f, 3_f, 4_f)),
b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 5_f),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -397,17 +397,17 @@
// s.a[1] = 5.0;
// }
ProgramBuilder b;
- auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(4))});
+ auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(4))});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4u>(4))),
b.Assign(b.MemberAccessor("s", "a"),
b.Construct(b.ty.array<f32, 4u>(4), 1_f, 2_f, 3_f, 4_f)),
b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 5_f),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -449,11 +449,11 @@
// (*b)[1] = 5.0;
// }
ProgramBuilder b;
- auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
+ auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("a", nullptr, b.AddressOf(b.MemberAccessor("s", "a")))),
b.Decl(b.Let("b", nullptr, b.AddressOf(b.Deref(b.AddressOf(b.Deref("a")))))),
b.Decl(b.Let("c", nullptr, b.Deref("b"))),
@@ -461,7 +461,7 @@
b.Assign(b.Deref("b"), b.Construct(b.ty.array<f32, 4u>(32), 1_f, 2_f, 3_f, 4_f)),
b.Assign(b.IndexAccessor(b.Deref("b"), 1_i), 5_f),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -510,11 +510,11 @@
// }
ProgramBuilder b;
b.Alias("ARR", b.ty.array<f32, 4u>(32));
- auto* S = b.Structure("S", {b.Member("a", b.ty.type_name("ARR"))});
+ auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.type_name("ARR"))});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("a", b.ty.type_name("ARR"), b.MemberAccessor("s", "a"))),
b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i))),
b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.type_name("ARR"))),
@@ -522,7 +522,7 @@
b.Construct(b.ty.type_name("ARR"), 1_f, 2_f, 3_f, 4_f)),
b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 5_f),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -580,11 +580,11 @@
b.ty.array( //
b.ty.array(b.ty.type_name("ARR_A"), 3_u, 16), //
4_u, 128));
- auto* S = b.Structure("S", {b.Member("a", b.ty.type_name("ARR_B"))});
+ auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.type_name("ARR_B"))});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("a", b.ty.type_name("ARR_B"), b.MemberAccessor("s", "a"))),
b.Decl(b.Let("b", b.ty.array(b.ty.type_name("ARR_A"), 3_u, 16),
b.IndexAccessor( //
@@ -614,7 +614,7 @@
1_i),
5_f),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
diff --git a/src/tint/transform/decompose_strided_matrix.cc b/src/tint/transform/decompose_strided_matrix.cc
index 3d474ed..75c96f6 100644
--- a/src/tint/transform/decompose_strided_matrix.cc
+++ b/src/tint/transform/decompose_strided_matrix.cc
@@ -170,16 +170,16 @@
auto array = [&] { return info.array(ctx.dst); };
auto mat = ctx.dst->Sym("m");
- ast::ExpressionList columns(info.matrix->columns());
- for (uint32_t i = 0; i < static_cast<uint32_t>(columns.size()); i++) {
- columns[i] = ctx.dst->IndexAccessor(mat, u32(i));
+ utils::Vector<const ast::Expression*, 4> columns;
+ for (uint32_t i = 0; i < static_cast<uint32_t>(info.matrix->columns()); i++) {
+ columns.Push(ctx.dst->IndexAccessor(mat, u32(i)));
}
ctx.dst->Func(name,
- {
+ utils::Vector{
ctx.dst->Param(mat, matrix()),
},
array(),
- {
+ utils::Vector{
ctx.dst->Return(ctx.dst->Construct(array(), columns)),
});
return name;
@@ -211,16 +211,16 @@
auto array = [&] { return info.array(ctx.dst); };
auto arr = ctx.dst->Sym("arr");
- ast::ExpressionList columns(info.matrix->columns());
- for (uint32_t i = 0; i < static_cast<uint32_t>(columns.size()); i++) {
- columns[i] = ctx.dst->IndexAccessor(arr, u32(i));
+ utils::Vector<const ast::Expression*, 4> columns;
+ for (uint32_t i = 0; i < static_cast<uint32_t>(info.matrix->columns()); i++) {
+ columns.Push(ctx.dst->IndexAccessor(arr, u32(i)));
}
ctx.dst->Func(name,
- {
+ utils::Vector{
ctx.dst->Param(arr, array()),
},
matrix(),
- {
+ utils::Vector{
ctx.dst->Return(ctx.dst->Construct(matrix(), columns)),
});
return name;
diff --git a/src/tint/transform/decompose_strided_matrix_test.cc b/src/tint/transform/decompose_strided_matrix_test.cc
index daff16f..afb06e8 100644
--- a/src/tint/transform/decompose_strided_matrix_test.cc
+++ b/src/tint/transform/decompose_strided_matrix_test.cc
@@ -68,20 +68,20 @@
// }
ProgramBuilder b;
auto* S = b.Structure(
- "S", {
+ "S", utils::Vector{
b.Member("m", b.ty.mat2x2<f32>(),
- {
+ utils::Vector{
b.create<ast::StructMemberOffsetAttribute>(16u),
b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -124,9 +124,9 @@
// }
ProgramBuilder b;
auto* S = b.Structure(
- "S", {
+ "S", utils::Vector{
b.Member("m", b.ty.mat2x2<f32>(),
- {
+ utils::Vector{
b.create<ast::StructMemberOffsetAttribute>(16u),
b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
@@ -134,11 +134,11 @@
});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
b.Func(
- "f", {}, b.ty.void_(),
- {
+ "f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("x", b.ty.vec2<f32>(), b.IndexAccessor(b.MemberAccessor("s", "m"), 1_i))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -177,20 +177,20 @@
// }
ProgramBuilder b;
auto* S = b.Structure(
- "S", {
+ "S", utils::Vector{
b.Member("m", b.ty.mat2x2<f32>(),
- {
+ utils::Vector{
b.create<ast::StructMemberOffsetAttribute>(16u),
b.create<ast::StrideAttribute>(8u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -230,9 +230,9 @@
// }
ProgramBuilder b;
auto* S = b.Structure(
- "S", {
+ "S", utils::Vector{
b.Member("m", b.ty.mat2x2<f32>(),
- {
+ utils::Vector{
b.create<ast::StructMemberOffsetAttribute>(8u),
b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
@@ -240,11 +240,11 @@
});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -287,9 +287,9 @@
// }
ProgramBuilder b;
auto* S = b.Structure(
- "S", {
+ "S", utils::Vector{
b.Member("m", b.ty.mat2x2<f32>(),
- {
+ utils::Vector{
b.create<ast::StructMemberOffsetAttribute>(16u),
b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
@@ -298,11 +298,11 @@
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
b.GroupAndBinding(0, 0));
b.Func(
- "f", {}, b.ty.void_(),
- {
+ "f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("x", b.ty.vec2<f32>(), b.IndexAccessor(b.MemberAccessor("s", "m"), 1_i))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -341,9 +341,9 @@
// }
ProgramBuilder b;
auto* S = b.Structure(
- "S", {
+ "S", utils::Vector{
b.Member("m", b.ty.mat2x2<f32>(),
- {
+ utils::Vector{
b.create<ast::StructMemberOffsetAttribute>(8u),
b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
@@ -351,12 +351,12 @@
});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Assign(b.MemberAccessor("s", "m"),
b.mat2x2<f32>(b.vec2<f32>(1_f, 2_f), b.vec2<f32>(3_f, 4_f))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -399,9 +399,9 @@
// }
ProgramBuilder b;
auto* S = b.Structure(
- "S", {
+ "S", utils::Vector{
b.Member("m", b.ty.mat2x2<f32>(),
- {
+ utils::Vector{
b.create<ast::StructMemberOffsetAttribute>(8u),
b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
@@ -409,11 +409,11 @@
});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Assign(b.IndexAccessor(b.MemberAccessor("s", "m"), 1_i), b.vec2<f32>(1_f, 2_f)),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -458,9 +458,9 @@
// }
ProgramBuilder b;
auto* S = b.Structure(
- "S", {
+ "S", utils::Vector{
b.Member("m", b.ty.mat2x2<f32>(),
- {
+ utils::Vector{
b.create<ast::StructMemberOffsetAttribute>(8u),
b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
@@ -468,8 +468,8 @@
});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
b.GroupAndBinding(0, 0));
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("a", nullptr, b.AddressOf(b.MemberAccessor("s", "m")))),
b.Decl(b.Let("b", nullptr, b.AddressOf(b.Deref(b.AddressOf(b.Deref("a")))))),
b.Decl(b.Let("x", nullptr, b.Deref("b"))),
@@ -478,7 +478,7 @@
b.Assign(b.Deref("b"), b.mat2x2<f32>(b.vec2<f32>(1_f, 2_f), b.vec2<f32>(3_f, 4_f))),
b.Assign(b.IndexAccessor(b.Deref("b"), 1_i), b.vec2<f32>(5_f, 6_f)),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -529,20 +529,20 @@
// }
ProgramBuilder b;
auto* S = b.Structure(
- "S", {
+ "S", utils::Vector{
b.Member("m", b.ty.mat2x2<f32>(),
- {
+ utils::Vector{
b.create<ast::StructMemberOffsetAttribute>(8u),
b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kPrivate);
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
@@ -582,21 +582,21 @@
// }
ProgramBuilder b;
auto* S = b.Structure(
- "S", {
+ "S", utils::Vector{
b.Member("m", b.ty.mat2x2<f32>(),
- {
+ utils::Vector{
b.create<ast::StructMemberOffsetAttribute>(8u),
b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kPrivate);
- b.Func("f", {}, b.ty.void_(),
- {
+ b.Func("f", utils::Empty, b.ty.void_(),
+ utils::Vector{
b.Assign(b.MemberAccessor("s", "m"),
b.mat2x2<f32>(b.vec2<f32>(1_f, 2_f), b.vec2<f32>(3_f, 4_f))),
},
- {
+ utils::Vector{
b.Stage(ast::PipelineStage::kCompute),
b.WorkgroupSize(1_i),
});
diff --git a/src/tint/transform/first_index_offset.cc b/src/tint/transform/first_index_offset.cc
index 6af162d..a966f7f 100644
--- a/src/tint/transform/first_index_offset.cc
+++ b/src/tint/transform/first_index_offset.cc
@@ -114,16 +114,16 @@
if (has_vertex_or_instance_index) {
// Add uniform buffer members and calculate byte offsets
- ast::StructMemberList members;
- members.push_back(ctx.dst->Member(kFirstVertexName, ctx.dst->ty.u32()));
- members.push_back(ctx.dst->Member(kFirstInstanceName, ctx.dst->ty.u32()));
+ utils::Vector<const ast::StructMember*, 8> members;
+ members.Push(ctx.dst->Member(kFirstVertexName, ctx.dst->ty.u32()));
+ members.Push(ctx.dst->Member(kFirstInstanceName, ctx.dst->ty.u32()));
auto* struct_ = ctx.dst->Structure(ctx.dst->Sym(), std::move(members));
// Create a global to hold the uniform buffer
Symbol buffer_name = ctx.dst->Sym();
ctx.dst->GlobalVar(buffer_name, ctx.dst->ty.Of(struct_), ast::StorageClass::kUniform,
nullptr,
- ast::AttributeList{
+ utils::Vector{
ctx.dst->create<ast::BindingAttribute>(ub_binding),
ctx.dst->create<ast::GroupAttribute>(ub_group),
});
diff --git a/src/tint/transform/fold_trivial_single_use_lets.cc b/src/tint/transform/fold_trivial_single_use_lets.cc
index 4dbc8c2..8a949ec 100644
--- a/src/tint/transform/fold_trivial_single_use_lets.cc
+++ b/src/tint/transform/fold_trivial_single_use_lets.cc
@@ -52,7 +52,7 @@
for (auto* node : ctx.src->ASTNodes().Objects()) {
if (auto* block = node->As<ast::BlockStatement>()) {
auto& stmts = block->statements;
- for (size_t stmt_idx = 0; stmt_idx < stmts.size(); stmt_idx++) {
+ for (size_t stmt_idx = 0; stmt_idx < stmts.Length(); stmt_idx++) {
auto* stmt = stmts[stmt_idx];
if (auto* let_decl = AsTrivialLetDecl(stmt)) {
auto* let = let_decl->variable;
@@ -65,7 +65,7 @@
auto* user = users[0];
auto* user_stmt = user->Stmt()->Declaration();
- for (size_t i = stmt_idx; i < stmts.size(); i++) {
+ for (size_t i = stmt_idx; i < stmts.Length(); i++) {
if (user_stmt == stmts[i]) {
auto* user_expr = user->Declaration();
ctx.Remove(stmts, let_decl);
diff --git a/src/tint/transform/for_loop_to_loop.cc b/src/tint/transform/for_loop_to_loop.cc
index 8fff0a8..e585790 100644
--- a/src/tint/transform/for_loop_to_loop.cc
+++ b/src/tint/transform/for_loop_to_loop.cc
@@ -35,7 +35,7 @@
void ForLoopToLoop::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
ctx.ReplaceAll([&](const ast::ForLoopStatement* for_loop) -> const ast::Statement* {
- ast::StatementList stmts;
+ utils::Vector<const ast::Statement*, 8> stmts;
if (auto* cond = for_loop->condition) {
// !condition
auto* not_cond =
@@ -45,10 +45,10 @@
auto* break_body = ctx.dst->Block(ctx.dst->create<ast::BreakStatement>());
// if (!condition) { break; }
- stmts.emplace_back(ctx.dst->If(not_cond, break_body));
+ stmts.Push(ctx.dst->If(not_cond, break_body));
}
for (auto* stmt : for_loop->body->statements) {
- stmts.emplace_back(ctx.Clone(stmt));
+ stmts.Push(ctx.Clone(stmt));
}
const ast::BlockStatement* continuing = nullptr;
diff --git a/src/tint/transform/localize_struct_array_assignment.cc b/src/tint/transform/localize_struct_array_assignment.cc
index 7c3d695..d43ddae 100644
--- a/src/tint/transform/localize_struct_array_assignment.cc
+++ b/src/tint/transform/localize_struct_array_assignment.cc
@@ -98,8 +98,8 @@
void Run() {
struct Shared {
bool process_nested_nodes = false;
- ast::StatementList insert_before_stmts;
- ast::StatementList insert_after_stmts;
+ utils::Vector<const ast::Statement*, 4> insert_before_stmts;
+ utils::Vector<const ast::Statement*, 4> insert_after_stmts;
} s;
ctx.ReplaceAll([&](const ast::AssignmentStatement* assign_stmt) -> const ast::Statement* {
@@ -130,10 +130,12 @@
// Combine insert_before_stmts + new_assign_stmt + insert_after_stmts into
// a block and return it
- ast::StatementList stmts = std::move(s.insert_before_stmts);
- stmts.reserve(1 + s.insert_after_stmts.size());
- stmts.emplace_back(new_assign_stmt);
- stmts.insert(stmts.end(), s.insert_after_stmts.begin(), s.insert_after_stmts.end());
+ auto stmts = std::move(s.insert_before_stmts);
+ stmts.Reserve(1 + s.insert_after_stmts.Length());
+ stmts.Push(new_assign_stmt);
+ for (auto* stmt : s.insert_after_stmts) {
+ stmts.Push(stmt);
+ }
return b.Block(std::move(stmts));
});
@@ -156,7 +158,7 @@
// Store the address of the member access into a let as we need to read
// the value twice e.g. let tint_symbol = &(s.a1);
auto mem_access_ptr = b.Sym();
- s.insert_before_stmts.push_back(
+ s.insert_before_stmts.Push(
b.Decl(b.Let(mem_access_ptr, nullptr, b.AddressOf(mem_access))));
// Disable further transforms when cloning
@@ -165,7 +167,7 @@
// Copy entire array out of struct into local temp var
// e.g. var tint_symbol_1 = *(tint_symbol);
auto tmp_var = b.Sym();
- s.insert_before_stmts.push_back(
+ s.insert_before_stmts.Push(
b.Decl(b.Var(tmp_var, nullptr, b.Deref(mem_access_ptr))));
// Replace input index_access with a clone of itself, but with its
@@ -177,8 +179,13 @@
// Assign temp var back to array
// e.g. *(tint_symbol) = tint_symbol_1;
auto* assign_rhs_to_temp = b.Assign(b.Deref(mem_access_ptr), tmp_var);
- s.insert_after_stmts.insert(s.insert_after_stmts.begin(),
- assign_rhs_to_temp); // push_front
+ {
+ utils::Vector<const ast::Statement*, 8> stmts{assign_rhs_to_temp};
+ for (auto* stmt : s.insert_after_stmts) {
+ stmts.Push(stmt);
+ }
+ s.insert_after_stmts = std::move(stmts);
+ }
return new_index_access;
});
diff --git a/src/tint/transform/loop_to_for_loop.cc b/src/tint/transform/loop_to_for_loop.cc
index 3e0a4b5..00bf5ec 100644
--- a/src/tint/transform/loop_to_for_loop.cc
+++ b/src/tint/transform/loop_to_for_loop.cc
@@ -29,7 +29,7 @@
namespace {
bool IsBlockWithSingleBreak(const ast::BlockStatement* block) {
- if (block->statements.size() != 1) {
+ if (block->statements.Length() != 1) {
return false;
}
return block->statements[0]->Is<ast::BreakStatement>();
@@ -74,7 +74,7 @@
// loop { if (condition) { break; } ... }
// loop { if (condition) {} else { break; } ... }
auto& stmts = loop->body->statements;
- if (stmts.empty()) {
+ if (stmts.IsEmpty()) {
return nullptr;
}
auto* if_stmt = stmts[0]->As<ast::IfStatement>();
@@ -96,7 +96,7 @@
// function call statement.
const ast::Statement* continuing = nullptr;
if (auto* loop_cont = loop->continuing) {
- if (loop_cont->statements.size() != 1) {
+ if (loop_cont->statements.Length() != 1) {
return nullptr;
}
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param.cc b/src/tint/transform/module_scope_var_to_entry_point_param.cc
index 7bd3991..122fb3c 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param.cc
+++ b/src/tint/transform/module_scope_var_to_entry_point_param.cc
@@ -26,12 +26,15 @@
#include "src/tint/sem/module.h"
#include "src/tint/sem/statement.h"
#include "src/tint/sem/variable.h"
+#include "src/tint/utils/string.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::ModuleScopeVarToEntryPointParam);
namespace tint::transform {
namespace {
+using WorkgroupParameterMemberList = utils::Vector<const ast::StructMember*, 8>;
+
// The name of the struct member for arrays that are wrapped in structures.
const char* kWrappedArrayMemberName = "arr";
@@ -102,7 +105,7 @@
const sem::Variable* var,
Symbol new_var_symbol,
std::function<Symbol()> workgroup_param,
- ast::StructMemberList& workgroup_parameter_members,
+ WorkgroupParameterMemberList& workgroup_parameter_members,
bool& is_pointer,
bool& is_wrapped) {
auto* var_ast = var->Declaration()->As<ast::Var>();
@@ -119,7 +122,7 @@
auto* disable_validation =
ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter);
auto attrs = ctx.Clone(var->Declaration()->attributes);
- attrs.push_back(disable_validation);
+ attrs.Push(disable_validation);
auto* param = ctx.dst->Param(new_var_symbol, store_type(), attrs);
ctx.InsertFront(func->params, param);
@@ -130,10 +133,8 @@
// Variables into the Storage and Uniform storage classes are redeclared as entry
// point parameters with a pointer type.
auto attributes = ctx.Clone(var->Declaration()->attributes);
- attributes.push_back(
- ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter));
- attributes.push_back(
- ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
+ attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter));
+ attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
auto* param_type = store_type();
if (auto* arr = ty->As<sem::Array>(); arr && arr->IsRuntimeSized()) {
@@ -142,7 +143,9 @@
// representable in Tint's AST.
CloneStructTypes(ty);
auto* wrapper = ctx.dst->Structure(
- ctx.dst->Sym(), {ctx.dst->Member(kWrappedArrayMemberName, param_type)});
+ ctx.dst->Sym(), utils::Vector{
+ ctx.dst->Member(kWrappedArrayMemberName, param_type),
+ });
param_type = ctx.dst->ty.Of(wrapper);
is_wrapped = true;
}
@@ -162,7 +165,7 @@
// Create a member in the workgroup parameter struct.
auto member = ctx.Clone(var->Declaration()->symbol);
- workgroup_parameter_members.push_back(ctx.dst->Member(member, store_type()));
+ workgroup_parameter_members.Push(ctx.dst->Member(member, store_type()));
CloneStructTypes(var->Type()->UnwrapRef());
// Create a function-scope variable that is a pointer to the member.
@@ -186,14 +189,21 @@
ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass);
auto* constructor = ctx.Clone(var->Declaration()->constructor);
auto* local_var = ctx.dst->Var(new_var_symbol, store_type(), sc, constructor,
- ast::AttributeList{disable_validation});
+ utils::Vector{disable_validation});
ctx.InsertFront(func->body->statements, ctx.dst->Decl(local_var));
break;
}
+ case ast::StorageClass::kPushConstant: {
+ ctx.dst->Diagnostics().add_error(
+ diag::System::Transform,
+ "unhandled module-scope storage class (" + utils::ToString(sc) + ")");
+ break;
+ }
default: {
TINT_ICE(Transform, ctx.dst->Diagnostics())
<< "unhandled module-scope storage class (" << sc << ")";
+ break;
}
}
}
@@ -219,6 +229,12 @@
case ast::StorageClass::kHandle:
case ast::StorageClass::kWorkgroup:
break;
+ case ast::StorageClass::kPushConstant: {
+ ctx.dst->Diagnostics().add_error(
+ diag::System::Transform,
+ "unhandled module-scope storage class (" + utils::ToString(sc) + ")");
+ break;
+ }
default: {
TINT_ICE(Transform, ctx.dst->Diagnostics())
<< "unhandled module-scope storage class (" << sc << ")";
@@ -226,19 +242,20 @@
}
// Use a pointer for non-handle types.
- ast::AttributeList attributes;
+ utils::Vector<const ast::Attribute*, 2> attributes;
if (!ty->is_handle()) {
param_type = ctx.dst->ty.pointer(param_type, sc, var_ast->declared_access);
is_pointer = true;
// Disable validation of the parameter's storage class and of arguments passed to it.
- attributes.push_back(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
- attributes.push_back(
+ attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
+ attributes.Push(
ctx.dst->Disable(ast::DisabledValidation::kIgnoreInvalidPointerArgument));
}
// Redeclare the variable as a parameter.
- ctx.InsertBack(func->params, ctx.dst->Param(new_var_symbol, param_type, attributes));
+ ctx.InsertBack(func->params,
+ ctx.dst->Param(new_var_symbol, param_type, std::move(attributes)));
}
/// Replace all uses of `var` in `func` with references to `new_var`.
@@ -278,10 +295,10 @@
/// Process the module.
void Process() {
// Predetermine the list of function calls that need to be replaced.
- using CallList = std::vector<const ast::CallExpression*>;
+ using CallList = utils::Vector<const ast::CallExpression*, 8>;
std::unordered_map<const ast::Function*, CallList> calls_to_replace;
- std::vector<const ast::Function*> functions_to_process;
+ utils::Vector<const ast::Function*, 8> functions_to_process;
// Build a list of functions that transitively reference any module-scope variables.
for (auto* decl : ctx.src->Sem().Module()->DependencyOrderedDeclarations()) {
@@ -300,11 +317,11 @@
}
}
if (needs_processing) {
- functions_to_process.push_back(func_ast);
+ functions_to_process.Push(func_ast);
// Find all of the calls to this function that will need to be replaced.
for (auto* call : func_sem->CallSites()) {
- calls_to_replace[call->Stmt()->Function()->Declaration()].push_back(
+ calls_to_replace[call->Stmt()->Function()->Declaration()].Push(
call->Declaration());
}
}
@@ -340,7 +357,7 @@
// We aggregate all workgroup variables into a struct to avoid hitting MSL's limit for
// threadgroup memory arguments.
Symbol workgroup_parameter_symbol;
- ast::StructMemberList workgroup_parameter_members;
+ WorkgroupParameterMemberList workgroup_parameter_members;
auto workgroup_param = [&]() {
if (!workgroup_parameter_symbol.IsValid()) {
workgroup_parameter_symbol = ctx.dst->Sym();
@@ -387,7 +404,7 @@
auto* local_var = ctx.dst->Var(new_var_symbol,
CreateASTTypeFor(ctx, var->Type()->UnwrapRef()),
ast::StorageClass::kPrivate, constructor,
- ast::AttributeList{disable_validation});
+ utils::Vector{disable_validation});
ctx.InsertFront(func_ast->body->statements, ctx.dst->Decl(local_var));
local_private_vars_.insert(var);
} else {
@@ -408,7 +425,7 @@
ReplaceUsesInFunction(func_ast, var, new_var_symbol, is_pointer, is_wrapped);
}
- if (!workgroup_parameter_members.empty()) {
+ if (!workgroup_parameter_members.IsEmpty()) {
// Create the workgroup memory parameter.
// The parameter is a struct that contains members for each workgroup variable.
auto* str =
@@ -417,7 +434,8 @@
ctx.dst->ty.pointer(ctx.dst->ty.Of(str), ast::StorageClass::kWorkgroup);
auto* disable_validation =
ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter);
- auto* param = ctx.dst->Param(workgroup_param(), param_type, {disable_validation});
+ auto* param = ctx.dst->Param(workgroup_param(), param_type,
+ utils::Vector{disable_validation});
ctx.InsertFront(func_ast->params, param);
}
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index a554616..f68a165 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -95,7 +95,7 @@
// If the attributes are empty, then this must be a texture_external
// passed as a function parameter. These variables are transformed
// elsewhere.
- if (global->attributes.empty()) {
+ if (global->attributes.IsEmpty()) {
continue;
}
@@ -140,7 +140,7 @@
// Replace the original texture_external binding with a texture_2d<f32>
// binding.
- ast::AttributeList cloned_attributes = ctx.Clone(global->attributes);
+ auto cloned_attributes = ctx.Clone(global->attributes);
const ast::Expression* cloned_constructor = ctx.Clone(global->constructor);
auto* replacement =
@@ -239,7 +239,7 @@
/// Creates the parameter structs associated with the transform.
void createExtTexParamsStructs() {
// Create GammaTransferParams struct.
- ast::StructMemberList gamma_transfer_member_list = {
+ utils::Vector gamma_transfer_member_list{
b.Member("G", b.ty.f32()), b.Member("A", b.ty.f32()), b.Member("B", b.ty.f32()),
b.Member("C", b.ty.f32()), b.Member("D", b.ty.f32()), b.Member("E", b.ty.f32()),
b.Member("F", b.ty.f32()), b.Member("padding", b.ty.u32())};
@@ -249,7 +249,7 @@
b.Structure(gamma_transfer_struct_sym, gamma_transfer_member_list);
// Create ExternalTextureParams struct.
- ast::StructMemberList ext_tex_params_member_list = {
+ utils::Vector ext_tex_params_member_list{
b.Member("numPlanes", b.ty.u32()),
b.Member("doYuvToRgbConversionOnly", b.ty.u32()),
b.Member("yuvToRgbConversionMatrix", b.ty.mat3x4(b.ty.f32())),
@@ -269,12 +269,12 @@
b.Func(
gamma_correction_sym,
- {
+ utils::Vector{
b.Param("v", b.ty.vec3<f32>()),
b.Param("params", b.ty.type_name(gamma_transfer_struct_sym)),
},
b.ty.vec3<f32>(),
- {
+ utils::Vector{
// let cond = abs(v) < vec3(params.D);
b.Decl(b.Let(
"cond", nullptr,
@@ -303,7 +303,7 @@
/// bodies of the textureSampleExternal and textureLoadExternal functions.
/// @param call_type determines which function body to generate
/// @returns a statement list that makes of the body of the chosen function
- ast::StatementList createTexFnExtStatementList(sem::BuiltinType call_type) {
+ auto createTexFnExtStatementList(sem::BuiltinType call_type) {
const ast::CallExpression* single_plane_call = nullptr;
const ast::CallExpression* plane_0_call = nullptr;
const ast::CallExpression* plane_1_call = nullptr;
@@ -325,7 +325,7 @@
TINT_ICE(Transform, b.Diagnostics()) << "unhandled builtin: " << call_type;
}
- return {
+ return utils::Vector{
// var color: vec3<f32>;
b.Decl(b.Var("color", b.ty.vec3(b.ty.f32()))),
// if ((params.numPlanes == 1u))
@@ -366,13 +366,12 @@
/// @returns a call expression to textureSampleExternal
const ast::CallExpression* createTexSmpExt(const ast::CallExpression* expr,
NewBindingSymbols syms) {
- ast::ExpressionList params;
const ast::Expression* plane_0_binding_param = ctx.Clone(expr->args[0]);
- if (expr->args.size() != 3) {
+ if (expr->args.Length() != 3) {
TINT_ICE(Transform, b.Diagnostics()) << "expected textureSampleLevel call with a "
"texture_external to have 3 parameters, found "
- << expr->args.size() << " parameters";
+ << expr->args.Length() << " parameters";
}
// TextureSampleExternal calls the gammaCorrection function, so ensure it
@@ -387,7 +386,7 @@
// Emit the textureSampleExternal function.
b.Func(
texture_sample_external_sym,
- {
+ utils::Vector{
b.Param("plane0", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
b.Param("plane1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
b.Param("smp", b.ty.sampler(ast::SamplerKind::kSampler)),
@@ -395,15 +394,19 @@
b.Param("params", b.ty.type_name(params_struct_sym)),
},
b.ty.vec4(b.ty.f32()),
- {
+ utils::Vector{
createTexFnExtStatementList(sem::BuiltinType::kTextureSampleLevel),
});
}
const ast::IdentifierExpression* exp = b.Expr(texture_sample_external_sym);
- params = {plane_0_binding_param, b.Expr(syms.plane_1), ctx.Clone(expr->args[1]),
- ctx.Clone(expr->args[2]), b.Expr(syms.params)};
- return b.Call(exp, params);
+ return b.Call(exp, utils::Vector{
+ plane_0_binding_param,
+ b.Expr(syms.plane_1),
+ ctx.Clone(expr->args[1]),
+ ctx.Clone(expr->args[2]),
+ b.Expr(syms.params),
+ });
}
/// Creates the textureLoadExternal function if needed and returns a call
@@ -413,14 +416,13 @@
/// @returns a call expression to textureLoadExternal
const ast::CallExpression* createTexLdExt(const ast::CallExpression* expr,
NewBindingSymbols syms) {
- ast::ExpressionList params;
const ast::Expression* plane_0_binding_param = ctx.Clone(expr->args[0]);
- if (expr->args.size() != 2) {
+ if (expr->args.Length() != 2) {
TINT_ICE(Transform, b.Diagnostics())
<< "expected textureLoad call with a texture_external "
"to have 2 parameters, found "
- << expr->args.size() << " parameters";
+ << expr->args.Length() << " parameters";
}
// TextureLoadExternal calls the gammaCorrection function, so ensure it
@@ -435,14 +437,14 @@
// Emit the textureLoadExternal function.
b.Func(
texture_load_external_sym,
- {
+ utils::Vector{
b.Param("plane0", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
b.Param("plane1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
b.Param("coord", b.ty.vec2(b.ty.i32())),
b.Param("params", b.ty.type_name(params_struct_sym)),
},
b.ty.vec4(b.ty.f32()),
- {
+ utils::Vector{
createTexFnExtStatementList(sem::BuiltinType::kTextureLoad),
});
}
diff --git a/src/tint/transform/num_workgroups_from_uniform.cc b/src/tint/transform/num_workgroups_from_uniform.cc
index 86310a9..b9476f2 100644
--- a/src/tint/transform/num_workgroups_from_uniform.cc
+++ b/src/tint/transform/num_workgroups_from_uniform.cc
@@ -121,7 +121,9 @@
if (!num_workgroups_ubo) {
auto* num_workgroups_struct = ctx.dst->Structure(
ctx.dst->Sym(),
- {ctx.dst->Member(kNumWorkgroupsMemberName, ctx.dst->ty.vec3(ctx.dst->ty.u32()))});
+ utils::Vector{
+ ctx.dst->Member(kNumWorkgroupsMemberName, ctx.dst->ty.vec3(ctx.dst->ty.u32())),
+ });
uint32_t group, binding;
if (cfg->ubo_binding.has_value()) {
@@ -146,7 +148,7 @@
num_workgroups_ubo = ctx.dst->GlobalVar(
ctx.dst->Sym(), ctx.dst->ty.Of(num_workgroups_struct), ast::StorageClass::kUniform,
- ast::AttributeList{ctx.dst->GroupAndBinding(group, binding)});
+ ctx.dst->GroupAndBinding(group, binding));
}
return num_workgroups_ubo;
};
diff --git a/src/tint/transform/promote_side_effects_to_decl.cc b/src/tint/transform/promote_side_effects_to_decl.cc
index 7551c23..46e8f46 100644
--- a/src/tint/transform/promote_side_effects_to_decl.cc
+++ b/src/tint/transform/promote_side_effects_to_decl.cc
@@ -180,11 +180,12 @@
}
// Hoists any expressions in `maybe_hoist` and clears it
- void Flush(ast::ExpressionList& maybe_hoist) {
+ template <size_t N>
+ void Flush(tint::utils::Vector<const ast::Expression*, N>& maybe_hoist) {
for (auto* m : maybe_hoist) {
Hoist(m);
}
- maybe_hoist.clear();
+ maybe_hoist.Clear();
}
// Recursive function that processes expressions for side-effects. It
@@ -197,7 +198,9 @@
// * For index and member accessor expressions, special care is taken to not
// over-hoist the lhs expressions, as these may be be chained to refer to a
// single memory location.
- bool ProcessExpression(const ast::Expression* expr, ast::ExpressionList& maybe_hoist) {
+ template <size_t N>
+ bool ProcessExpression(const ast::Expression* expr,
+ tint::utils::Vector<const ast::Expression*, N>& maybe_hoist) {
auto process = [&](const ast::Expression* e) -> bool {
return ProcessExpression(e, maybe_hoist);
};
@@ -205,7 +208,7 @@
auto default_process = [&](const ast::Expression* e) {
auto maybe = process(e);
if (maybe) {
- maybe_hoist.emplace_back(e);
+ maybe_hoist.Push(e);
}
if (HasSideEffects(e)) {
Flush(maybe_hoist);
@@ -240,7 +243,7 @@
// for "v[a][b][c] + g()" we want to hoist all of "v[a][b][c]", not "t1 =
// v[a]", then "t2 = t1[b]" then "t3 = t2[c]").
if (maybe && HasSideEffects(lhs)) {
- maybe_hoist.emplace_back(lhs);
+ maybe_hoist.Push(lhs);
Flush(maybe_hoist);
maybe = false;
}
@@ -337,7 +340,7 @@
return;
}
- ast::ExpressionList maybe_hoist;
+ tint::utils::Vector<const ast::Expression*, 8> maybe_hoist;
ProcessExpression(expr, maybe_hoist);
}
@@ -345,9 +348,9 @@
// evaluate the rhs before the lhs, and possibly hoist the rhs expression.
void ProcessAssignment(const ast::Expression* lhs, const ast::Expression* rhs) {
// Evaluate rhs before lhs
- ast::ExpressionList maybe_hoist;
+ tint::utils::Vector<const ast::Expression*, 8> maybe_hoist;
if (ProcessExpression(rhs, maybe_hoist)) {
- maybe_hoist.emplace_back(rhs);
+ maybe_hoist.Push(rhs);
}
// If the rhs has side-effects, it may affect the lhs, so hoist it right
@@ -414,7 +417,9 @@
}
// Recursive function used to decompose an expression for short-circuit eval.
- const ast::Expression* Decompose(const ast::Expression* expr, ast::StatementList* curr_stmts) {
+ template <size_t N>
+ const ast::Expression* Decompose(const ast::Expression* expr,
+ tint::utils::Vector<const ast::Statement*, N>* curr_stmts) {
// Helper to avoid passing in same args.
auto decompose = [&](auto& e) { return Decompose(e, curr_stmts); };
@@ -424,7 +429,7 @@
auto name = b.Symbols().New();
auto* v = b.Let(name, nullptr, ctx.Clone(e));
auto* decl = b.Decl(v);
- curr_stmts->push_back(decl);
+ curr_stmts->Push(decl);
return b.Expr(name);
}
return ctx.Clone(e);
@@ -471,7 +476,7 @@
// let r = temp;
auto name = b.Sym();
- curr_stmts->push_back(b.Decl(b.Var(name, nullptr, decompose(bin_expr->lhs))));
+ curr_stmts->Push(b.Decl(b.Var(name, nullptr, decompose(bin_expr->lhs))));
const ast::Expression* if_cond = nullptr;
if (bin_expr->IsLogicalOr()) {
@@ -482,14 +487,14 @@
const ast::BlockStatement* if_body = nullptr;
{
- ast::StatementList stmts;
+ tint::utils::Vector<const ast::Statement*, N> stmts;
TINT_SCOPED_ASSIGNMENT(curr_stmts, &stmts);
auto* new_rhs = decompose(bin_expr->rhs);
- curr_stmts->push_back(b.Assign(name, new_rhs));
+ curr_stmts->Push(b.Assign(name, new_rhs));
if_body = b.Block(std::move(*curr_stmts));
}
- curr_stmts->push_back(b.If(if_cond, if_body));
+ curr_stmts->Push(b.If(if_cond, if_body));
return b.Expr(name);
},
@@ -537,8 +542,10 @@
}
// Inserts statements in `stmts` before `stmt`
- void InsertBefore(const ast::StatementList& stmts, const ast::Statement* stmt) {
- if (!stmts.empty()) {
+ template <size_t N>
+ void InsertBefore(tint::utils::Vector<const ast::Statement*, N>& stmts,
+ const ast::Statement* stmt) {
+ if (!stmts.IsEmpty()) {
auto ip = utils::GetInsertionPoint(ctx, stmt);
for (auto* s : stmts) {
ctx.InsertBefore(ip.first->Declaration()->statements, ip.second, s);
@@ -556,7 +563,7 @@
return nullptr;
}
// rhs before lhs
- ast::StatementList stmts;
+ tint::utils::Vector<const ast::Statement*, 8> stmts;
ctx.Replace(s->rhs, Decompose(s->rhs, &stmts));
ctx.Replace(s->lhs, Decompose(s->lhs, &stmts));
InsertBefore(stmts, s);
@@ -566,7 +573,7 @@
if (!sem.Get(s->expr)->HasSideEffects()) {
return nullptr;
}
- ast::StatementList stmts;
+ tint::utils::Vector<const ast::Statement*, 8> stmts;
ctx.Replace(s->expr, Decompose(s->expr, &stmts));
InsertBefore(stmts, s);
return ctx.CloneWithoutTransform(s);
@@ -575,7 +582,7 @@
if (!s->condition || !sem.Get(s->condition)->HasSideEffects()) {
return nullptr;
}
- ast::StatementList stmts;
+ tint::utils::Vector<const ast::Statement*, 8> stmts;
ctx.Replace(s->condition, Decompose(s->condition, &stmts));
InsertBefore(stmts, s);
return ctx.CloneWithoutTransform(s);
@@ -584,7 +591,7 @@
if (!sem.Get(s->condition)->HasSideEffects()) {
return nullptr;
}
- ast::StatementList stmts;
+ tint::utils::Vector<const ast::Statement*, 8> stmts;
ctx.Replace(s->condition, Decompose(s->condition, &stmts));
InsertBefore(stmts, s);
return ctx.CloneWithoutTransform(s);
@@ -593,7 +600,7 @@
if (!sem.Get(s->condition)->HasSideEffects()) {
return nullptr;
}
- ast::StatementList stmts;
+ tint::utils::Vector<const ast::Statement*, 8> stmts;
ctx.Replace(s->condition, Decompose(s->condition, &stmts));
InsertBefore(stmts, s);
return ctx.CloneWithoutTransform(s);
@@ -602,7 +609,7 @@
if (!s->value || !sem.Get(s->value)->HasSideEffects()) {
return nullptr;
}
- ast::StatementList stmts;
+ tint::utils::Vector<const ast::Statement*, 8> stmts;
ctx.Replace(s->value, Decompose(s->value, &stmts));
InsertBefore(stmts, s);
return ctx.CloneWithoutTransform(s);
@@ -611,7 +618,7 @@
if (!sem.Get(s->condition)) {
return nullptr;
}
- ast::StatementList stmts;
+ tint::utils::Vector<const ast::Statement*, 8> stmts;
ctx.Replace(s->condition, Decompose(s->condition, &stmts));
InsertBefore(stmts, s);
return ctx.CloneWithoutTransform(s);
@@ -621,7 +628,7 @@
if (!var->constructor || !sem.Get(var->constructor)->HasSideEffects()) {
return nullptr;
}
- ast::StatementList stmts;
+ tint::utils::Vector<const ast::Statement*, 8> stmts;
ctx.Replace(var->constructor, Decompose(var->constructor, &stmts));
InsertBefore(stmts, s);
return b.Decl(ctx.CloneWithoutTransform(var));
diff --git a/src/tint/transform/remove_phonies.cc b/src/tint/transform/remove_phonies.cc
index 7ba109a..5e64252 100644
--- a/src/tint/transform/remove_phonies.cc
+++ b/src/tint/transform/remove_phonies.cc
@@ -72,6 +72,11 @@
if (node->Is<ast::PhonyExpression>()) {
return true;
}
+ if (auto* stmt = node->As<ast::CallStatement>()) {
+ if (program->Sem().Get(stmt->expr)->ConstantValue() != nullptr) {
+ return true;
+ }
+ }
}
return false;
}
@@ -82,74 +87,86 @@
std::unordered_map<SinkSignature, Symbol, SinkSignature::Hasher> sinks;
for (auto* node : ctx.src->ASTNodes().Objects()) {
- if (auto* stmt = node->As<ast::AssignmentStatement>()) {
- if (stmt->lhs->Is<ast::PhonyExpression>()) {
- std::vector<const ast::Expression*> side_effects;
- if (!ast::TraverseExpressions(
- stmt->rhs, ctx.dst->Diagnostics(), [&](const ast::CallExpression* expr) {
- // ast::CallExpression may map to a function or builtin call
- // (both may have side-effects), or a type constructor or
- // type conversion (both do not have side effects).
- auto* call = sem.Get<sem::Call>(expr);
- if (!call) {
- // Semantic node must be a Materialize, in which case the expression
- // was creation-time (compile time), so could not have side effects.
- // Just skip.
- return ast::TraverseAction::Skip;
- }
- if (call->Target()->IsAnyOf<sem::Function, sem::Builtin>() &&
- call->HasSideEffects()) {
- side_effects.push_back(expr);
- return ast::TraverseAction::Skip;
- }
- return ast::TraverseAction::Descend;
- })) {
- return;
- }
-
- if (side_effects.empty()) {
- // Phony assignment with no side effects.
- // Just remove it.
- RemoveStatement(ctx, stmt);
- continue;
- }
-
- if (side_effects.size() == 1) {
- if (auto* call = side_effects[0]->As<ast::CallExpression>()) {
- // Phony assignment with single call side effect.
- // Replace phony assignment with call.
- ctx.Replace(stmt, [&, call] { return ctx.dst->CallStmt(ctx.Clone(call)); });
- continue;
+ Switch(
+ node,
+ [&](const ast::AssignmentStatement* stmt) {
+ if (stmt->lhs->Is<ast::PhonyExpression>()) {
+ std::vector<const ast::Expression*> side_effects;
+ if (!ast::TraverseExpressions(
+ stmt->rhs, ctx.dst->Diagnostics(),
+ [&](const ast::CallExpression* expr) {
+ // ast::CallExpression may map to a function or builtin call
+ // (both may have side-effects), or a type constructor or
+ // type conversion (both do not have side effects).
+ auto* call = sem.Get<sem::Call>(expr);
+ if (!call) {
+ // Semantic node must be a Materialize, in which case the
+ // expression was creation-time (compile time), so could not
+ // have side effects. Just skip.
+ return ast::TraverseAction::Skip;
+ }
+ if (call->Target()->IsAnyOf<sem::Function, sem::Builtin>() &&
+ call->HasSideEffects()) {
+ side_effects.push_back(expr);
+ return ast::TraverseAction::Skip;
+ }
+ return ast::TraverseAction::Descend;
+ })) {
+ return;
}
- }
- // Phony assignment with multiple side effects.
- // Generate a call to a placeholder function with the side
- // effects as arguments.
- ctx.Replace(stmt, [&, side_effects] {
- SinkSignature sig;
- for (auto* arg : side_effects) {
- sig.types.push_back(sem.Get(arg)->Type()->UnwrapRef());
+ if (side_effects.empty()) {
+ // Phony assignment with no side effects.
+ // Just remove it.
+ RemoveStatement(ctx, stmt);
+ return;
}
- auto sink = utils::GetOrCreate(sinks, sig, [&] {
- auto name = ctx.dst->Symbols().New("phony_sink");
- ast::ParameterList params;
- for (auto* ty : sig.types) {
- auto* ast_ty = CreateASTTypeFor(ctx, ty);
- params.push_back(
- ctx.dst->Param("p" + std::to_string(params.size()), ast_ty));
+
+ if (side_effects.size() == 1) {
+ if (auto* call = side_effects[0]->As<ast::CallExpression>()) {
+ // Phony assignment with single call side effect.
+ // Replace phony assignment with call.
+ ctx.Replace(stmt,
+ [&, call] { return ctx.dst->CallStmt(ctx.Clone(call)); });
+ return;
}
- ctx.dst->Func(name, params, ctx.dst->ty.void_(), {});
- return name;
- });
- ast::ExpressionList args;
- for (auto* arg : side_effects) {
- args.push_back(ctx.Clone(arg));
}
- return ctx.dst->CallStmt(ctx.dst->Call(sink, args));
- });
- }
- }
+
+ // Phony assignment with multiple side effects.
+ // Generate a call to a placeholder function with the side
+ // effects as arguments.
+ ctx.Replace(stmt, [&, side_effects] {
+ SinkSignature sig;
+ for (auto* arg : side_effects) {
+ sig.types.push_back(sem.Get(arg)->Type()->UnwrapRef());
+ }
+ auto sink = utils::GetOrCreate(sinks, sig, [&] {
+ auto name = ctx.dst->Symbols().New("phony_sink");
+ utils::Vector<const ast::Parameter*, 8> params;
+ for (auto* ty : sig.types) {
+ auto* ast_ty = CreateASTTypeFor(ctx, ty);
+ params.Push(
+ ctx.dst->Param("p" + std::to_string(params.Length()), ast_ty));
+ }
+ ctx.dst->Func(name, params, ctx.dst->ty.void_(), {});
+ return name;
+ });
+ utils::Vector<const ast::Expression*, 8> args;
+ for (auto* arg : side_effects) {
+ args.Push(ctx.Clone(arg));
+ }
+ return ctx.dst->CallStmt(ctx.dst->Call(sink, args));
+ });
+ }
+ },
+ [&](const ast::CallStatement* stmt) {
+ // Remove call statements to const value-returning functions.
+ // TODO(crbug.com/tint/1637): Remove if `stmt->expr` has no side-effects.
+ auto* sem_expr = sem.Get(stmt->expr);
+ if ((sem_expr->ConstantValue() != nullptr) && !sem_expr->HasSideEffects()) {
+ ctx.Remove(sem.Get(stmt)->Block()->Declaration()->statements, stmt);
+ }
+ });
}
ctx.Clone();
diff --git a/src/tint/transform/remove_phonies.h b/src/tint/transform/remove_phonies.h
index d04023b..daa1812 100644
--- a/src/tint/transform/remove_phonies.h
+++ b/src/tint/transform/remove_phonies.h
@@ -24,7 +24,7 @@
/// RemovePhonies is a Transform that removes all phony-assignment statements,
/// while preserving function call expressions in the RHS of the assignment that
-/// may have side-effects.
+/// may have side-effects. It also removes calls to builtins that return a constant value.
class RemovePhonies final : public Castable<RemovePhonies, Transform> {
public:
/// Constructor
diff --git a/src/tint/transform/remove_phonies_test.cc b/src/tint/transform/remove_phonies_test.cc
index dc91b5a..a072e51 100644
--- a/src/tint/transform/remove_phonies_test.cc
+++ b/src/tint/transform/remove_phonies_test.cc
@@ -67,6 +67,8 @@
_ = mat2x2<f32>(9.0, 10.0, 11.0, 12.0);
_ = atan2(1.0, 2.0);
_ = clamp(1.0, 2.0, 3.0);
+ atan2(1.0, 2.0);
+ clamp(1.0, 2.0, 3.0);
}
)";
diff --git a/src/tint/transform/renamer_test.cc b/src/tint/transform/renamer_test.cc
index 516b164..c57dea3 100644
--- a/src/tint/transform/renamer_test.cc
+++ b/src/tint/transform/renamer_test.cc
@@ -328,234 +328,234 @@
INSTANTIATE_TEST_SUITE_P(RenamerTestGlsl,
RenamerTestGlsl,
- testing::Values("active",
- // "asm", // WGSL keyword
- "atomic_uint",
- "attribute",
- // "bool", // WGSL keyword
- // "break", // WGSL keyword
- "buffer",
- "bvec2",
- "bvec3",
- "bvec4",
- // "case", // WGSL keyword
- "cast",
- "centroid",
- "class",
- "coherent",
- "common",
- // "const", // WGSL keyword
- // "continue", // WGSL keyword
- // "default", // WGSL keyword
- // "discard", // WGSL keyword
- "dmat2",
- "dmat2x2",
- "dmat2x3",
- "dmat2x4",
- "dmat3",
- "dmat3x2",
- "dmat3x3",
- "dmat3x4",
- "dmat4",
- "dmat4x2",
- "dmat4x3",
- "dmat4x4",
- // "do", // WGSL keyword
- "double",
- "dvec2",
- "dvec3",
- "dvec4",
- // "else" // WGSL keyword
- // "enum", // WGSL keyword
- "extern",
- "external",
- // "false", // WGSL keyword
- "filter",
- "fixed",
- "flat",
- "float",
- // "for", // WGSL keyword
- "fvec2",
- "fvec3",
- "fvec4",
- "gl_BaseInstance",
- "gl_BaseVertex",
- "gl_ClipDistance",
- "gl_DepthRangeParameters",
- "gl_DrawID",
- "gl_FragCoord",
- "gl_FragDepth",
- "gl_FrontFacing",
- "gl_GlobalInvocationID",
- "gl_InstanceID",
- "gl_LocalInvocationID",
- "gl_LocalInvocationIndex",
- "gl_NumSamples",
- "gl_NumWorkGroups",
- "gl_PerVertex",
- "gl_PointCoord",
- "gl_PointSize",
- "gl_Position",
- "gl_PrimitiveID",
- "gl_SampleID",
- "gl_SampleMask",
- "gl_SampleMaskIn",
- "gl_SamplePosition",
- "gl_VertexID",
- "gl_WorkGroupID",
- "gl_WorkGroupSize",
- "goto",
- "half",
- "highp",
- "hvec2",
- "hvec3",
- "hvec4",
- // "if", // WGSL keyword
- "iimage1D",
- "iimage1DArray",
- "iimage2D",
- "iimage2DArray",
- "iimage2DMS",
- "iimage2DMSArray",
- "iimage2DRect",
- "iimage3D",
- "iimageBuffer",
- "iimageCube",
- "iimageCubeArray",
- "image1D",
- "image1DArray",
- "image2D",
- "image2DArray",
- "image2DMS",
- "image2DMSArray",
- "image2DRect",
- "image3D",
- "imageBuffer",
- "imageCube",
- "imageCubeArray",
- "in",
- "inline",
- "inout",
- "input",
- "int",
- "interface",
- "invariant",
- "isampler1D",
- "isampler1DArray",
- "isampler2D",
- "isampler2DArray",
- "isampler2DMS",
- "isampler2DMSArray",
- "isampler2DRect",
- "isampler3D",
- "isamplerBuffer",
- "isamplerCube",
- "isamplerCubeArray",
- "ivec2",
- "ivec3",
- "ivec4",
- "layout",
- "long",
- "lowp",
- // "mat2x2", // WGSL keyword
- // "mat2x3", // WGSL keyword
- // "mat2x4", // WGSL keyword
- // "mat2",
- "mat3",
- // "mat3x2", // WGSL keyword
- // "mat3x3", // WGSL keyword
- // "mat3x4", // WGSL keyword
- "mat4",
- // "mat4x2", // WGSL keyword
- // "mat4x3", // WGSL keyword
- // "mat4x4", // WGSL keyword
- "mediump",
- "namespace",
- "noinline",
- "noperspective",
- "out",
- "output",
- "partition",
- "patch",
- "precise",
- "precision",
- "public",
- "readonly",
- "resource",
- "restrict",
- // "return", // WGSL keyword
- "sample",
- "sampler1D",
- "sampler1DArray",
- "sampler1DArrayShadow",
- "sampler1DShadow",
- "sampler2D",
- "sampler2DArray",
- "sampler2DArrayShadow",
- "sampler2DMS",
- "sampler2DMSArray",
- "sampler2DRect",
- "sampler2DRectShadow",
- "sampler2DShadow",
- "sampler3D",
- "sampler3DRect",
- "samplerBuffer",
- "samplerCube",
- "samplerCubeArray",
- "samplerCubeArrayShadow",
- "samplerCubeShadow",
- "shared",
- "short",
- "sizeof",
- "smooth",
- "static",
- // "struct", // WGSL keyword
- "subroutine",
- "superp",
- // "switch", // WGSL keyword
- "template",
- "this",
- // "true", // WGSL keyword
- // "typedef", // WGSL keyword
- "uimage1D",
- "uimage1DArray",
- "uimage2D",
- "uimage2DArray",
- "uimage2DMS",
- "uimage2DMSArray",
- "uimage2DRect",
- "uimage3D",
- "uimageBuffer",
- "uimageCube",
- "uimageCubeArray",
- "uint",
- // "uniform", // WGSL keyword
- "union",
- "unsigned",
- "usampler1D",
- "usampler1DArray",
- "usampler2D",
- "usampler2DArray",
- "usampler2DMS",
- "usampler2DMSArray",
- "usampler2DRect",
- "usampler3D",
- "usamplerBuffer",
- "usamplerCube",
- "usamplerCubeArray",
- // "using", // WGSL keyword
- "uvec2",
- "uvec3",
- "uvec4",
- "varying",
- // "vec2", // WGSL keyword
- // "vec3", // WGSL keyword
- // "vec4", // WGSL keyword
- // "void", // WGSL keyword
- "volatile",
- // "while", // WGSL keyword
- "writeonly",
- kUnicodeIdentifier));
+ testing::Values( // "active", // Also reserved in WGSL
+ // "asm", // WGSL keyword
+ "atomic_uint",
+ // "attribute", // Also reserved in WGSL
+ // "bool", // WGSL keyword
+ // "break", // WGSL keyword
+ "buffer",
+ "bvec2",
+ "bvec3",
+ "bvec4",
+ // "case", // WGSL keyword
+ // "cast", // Also reserved in WGSL
+ "centroid",
+ // "class", // Also reserved in WGSL
+ // "coherent", // Also reserved in WGSL
+ // "common", // Also reserved in WGSL
+ // "const", // WGSL keyword
+ // "continue", // WGSL keyword
+ // "default", // WGSL keyword
+ // "discard", // WGSL keyword
+ "dmat2",
+ "dmat2x2",
+ "dmat2x3",
+ "dmat2x4",
+ "dmat3",
+ "dmat3x2",
+ "dmat3x3",
+ "dmat3x4",
+ "dmat4",
+ "dmat4x2",
+ "dmat4x3",
+ "dmat4x4",
+ // "do", // WGSL keyword
+ "double",
+ "dvec2",
+ "dvec3",
+ "dvec4",
+ // "else" // WGSL keyword
+ // "enum", // WGSL keyword
+ // "extern", // Also reserved in WGSL
+ // "external", // Also reserved in WGSL
+ // "false", // WGSL keyword
+ // "filter", // Also reserved in WGSL
+ "fixed",
+ "flat",
+ "float",
+ // "for", // WGSL keyword
+ "fvec2",
+ "fvec3",
+ "fvec4",
+ "gl_BaseInstance",
+ "gl_BaseVertex",
+ "gl_ClipDistance",
+ "gl_DepthRangeParameters",
+ "gl_DrawID",
+ "gl_FragCoord",
+ "gl_FragDepth",
+ "gl_FrontFacing",
+ "gl_GlobalInvocationID",
+ "gl_InstanceID",
+ "gl_LocalInvocationID",
+ "gl_LocalInvocationIndex",
+ "gl_NumSamples",
+ "gl_NumWorkGroups",
+ "gl_PerVertex",
+ "gl_PointCoord",
+ "gl_PointSize",
+ "gl_Position",
+ "gl_PrimitiveID",
+ "gl_SampleID",
+ "gl_SampleMask",
+ "gl_SampleMaskIn",
+ "gl_SamplePosition",
+ "gl_VertexID",
+ "gl_WorkGroupID",
+ "gl_WorkGroupSize",
+ // "goto", // Also reserved in WGSL
+ "half",
+ // "highp", // Also reserved in WGSL
+ "hvec2",
+ "hvec3",
+ "hvec4",
+ // "if", // WGSL keyword
+ "iimage1D",
+ "iimage1DArray",
+ "iimage2D",
+ "iimage2DArray",
+ "iimage2DMS",
+ "iimage2DMSArray",
+ "iimage2DRect",
+ "iimage3D",
+ "iimageBuffer",
+ "iimageCube",
+ "iimageCubeArray",
+ "image1D",
+ "image1DArray",
+ "image2D",
+ "image2DArray",
+ "image2DMS",
+ "image2DMSArray",
+ "image2DRect",
+ "image3D",
+ "imageBuffer",
+ "imageCube",
+ "imageCubeArray",
+ "in",
+ // "inline", // Also reserved in WGSL
+ // "inout", // Also reserved in WGSL
+ "input",
+ "int",
+ // "interface", // Also reserved in WGSL
+ // "invariant", // Also reserved in WGSL
+ "isampler1D",
+ "isampler1DArray",
+ "isampler2D",
+ "isampler2DArray",
+ "isampler2DMS",
+ "isampler2DMSArray",
+ "isampler2DRect",
+ "isampler3D",
+ "isamplerBuffer",
+ "isamplerCube",
+ "isamplerCubeArray",
+ "ivec2",
+ "ivec3",
+ "ivec4",
+ // "layout", // Also reserved in WGSL
+ "long",
+ // "lowp", // Also reserved in WGSL
+ // "mat2x2", // WGSL keyword
+ // "mat2x3", // WGSL keyword
+ // "mat2x4", // WGSL keyword
+ // "mat2",
+ "mat3",
+ // "mat3x2", // WGSL keyword
+ // "mat3x3", // WGSL keyword
+ // "mat3x4", // WGSL keyword
+ "mat4",
+ // "mat4x2", // WGSL keyword
+ // "mat4x3", // WGSL keyword
+ // "mat4x4", // WGSL keyword
+ // "mediump", // Also reserved in WGSL
+ // "namespace", // Also reserved in WGSL
+ // "noinline", // Also reserved in WGSL
+ // "noperspective", // Also reserved in WGSL
+ "out",
+ "output",
+ // "partition", // Also reserved in WGSL
+ // "patch", // Also reserved in WGSL
+ // "precise", // Also reserved in WGSL
+ // "precision", // Also reserved in WGSL
+ // "public", // Also reserved in WGSL
+ // "readonly", // Also reserved in WGSL
+ // "resource", // Also reserved in WGSL
+ // "restrict", // Also reserved in WGSL
+ // "return", // WGSL keyword
+ "sample",
+ "sampler1D",
+ "sampler1DArray",
+ "sampler1DArrayShadow",
+ "sampler1DShadow",
+ "sampler2D",
+ "sampler2DArray",
+ "sampler2DArrayShadow",
+ "sampler2DMS",
+ "sampler2DMSArray",
+ "sampler2DRect",
+ "sampler2DRectShadow",
+ "sampler2DShadow",
+ "sampler3D",
+ "sampler3DRect",
+ "samplerBuffer",
+ "samplerCube",
+ "samplerCubeArray",
+ "samplerCubeArrayShadow",
+ "samplerCubeShadow",
+ // "shared" // Also reserved in WGSL,
+ "short",
+ // "sizeof", // Also reserved in WGSL
+ // "smooth", // Also reserved in WGSL
+ // "static", // Also reserved in WGSL
+ // "struct", // WGSL keyword
+ // "subroutine", // Also reserved in WGSL
+ "superp",
+ // "switch", // WGSL keyword
+ // "template", // Also reserved in WGSL
+ // "this", // Also reserved in WGSL
+ // "true", // WGSL keyword
+ // "typedef", // WGSL keyword
+ "uimage1D",
+ "uimage1DArray",
+ "uimage2D",
+ "uimage2DArray",
+ "uimage2DMS",
+ "uimage2DMSArray",
+ "uimage2DRect",
+ "uimage3D",
+ "uimageBuffer",
+ "uimageCube",
+ "uimageCubeArray",
+ "uint",
+ // "uniform", // WGSL keyword
+ // "union", // Also reserved in WGSL
+ "unsigned",
+ "usampler1D",
+ "usampler1DArray",
+ "usampler2D",
+ "usampler2DArray",
+ "usampler2DMS",
+ "usampler2DMSArray",
+ "usampler2DRect",
+ "usampler3D",
+ "usamplerBuffer",
+ "usamplerCube",
+ "usamplerCubeArray",
+ // "using", // WGSL keyword
+ "uvec2",
+ "uvec3",
+ "uvec4",
+ // "varying", // Also reserved in WGSL
+ // "vec2", // WGSL keyword
+ // "vec3", // WGSL keyword
+ // "vec4", // WGSL keyword
+ // "void", // WGSL keyword
+ // "volatile", // Also reserved in WGSL
+ // "while", // WGSL keyword
+ // "writeonly", // Also reserved in WGSL
+ kUnicodeIdentifier));
INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
RenamerTestHlsl,
@@ -575,8 +575,8 @@
"COLOR",
"CheckAccessFullyMapped",
"ComparisonFunc",
- "CompileShader",
- "ComputeShader",
+ // "CompileShader", // Also reserved in WGSL
+ // "ComputeShader", // Also reserved in WGSL
"ConsumeStructuredBuffer",
"D3DCOLORtoUBYTE4",
"DEPTH",
@@ -584,18 +584,18 @@
"DepthStencilView",
"DeviceMemoryBarrier",
"DeviceMemroyBarrierWithGroupSync",
- "DomainShader",
+ // "DomainShader", // Also reserved in WGSL
"EvaluateAttributeAtCentroid",
"EvaluateAttributeAtSample",
"EvaluateAttributeSnapped",
"FOG",
"Filter",
- "GeometryShader",
+ // "GeometryShader", // Also reserved in WGSL
"GetRenderTargetSampleCount",
"GetRenderTargetSamplePosition",
"GroupMemoryBarrier",
"GroupMemroyBarrierWithGroupSync",
- "Hullshader",
+ // "Hullshader", // Also reserved in WGSL
"InputPatch",
"InterlockedAdd",
"InterlockedAnd",
@@ -612,7 +612,7 @@
"MinLOD",
"MipLODBias",
"NORMAL",
- "NULL",
+ // "NULL", // Also reserved in WGSL
"Normal",
"OutputPatch",
"POSITION",
@@ -703,11 +703,11 @@
// "asin", // WGSL builtin
"asint",
// "asm", // WGSL keyword
- "asm_fragment",
+ // "asm_fragment", // Also reserved in WGSL
"asuint",
// "atan", // WGSL builtin
// "atan2", // WGSL builtin
- "auto",
+ // "auto", // Also reserved in WGSL
// "bool", // WGSL keyword
"bool1",
"bool1x1",
@@ -733,19 +733,19 @@
// "break", // WGSL keyword
// "call", // WGSL builtin
// "case", // WGSL keyword
- "catch",
+ // "catch", // Also reserved in WGSL
"cbuffer",
// "ceil", // WGSL builtin
"centroid",
"char",
// "clamp", // WGSL builtin
- "class",
+ // "class", // Also reserved in WGSL
"clip",
- "column_major",
- "compile",
- "compile_fragment",
+ // "column_major", // Also reserved in WGSL
+ // "compile", // Also reserved in WGSL
+ // "compile_fragment", // Also reserved in WGSL
// "const", // WGSL keyword
- "const_cast",
+ // "const_cast", // Also reserved in WGSL
// "continue", // WGSL keyword
// "cos", // WGSL builtin
// "cosh", // WGSL builtin
@@ -759,7 +759,7 @@
"ddy_fine",
// "default", // WGSL keyword
"degrees",
- "delete",
+ // "delete", // Also reserved in WGSL
// "determinant", // WGSL builtin
// "discard", // WGSL keyword
// "distance", // WGSL builtin
@@ -808,15 +808,15 @@
"dword4x2",
"dword4x3",
"dword4x4",
- "dynamic_cast",
+ // "dynamic_cast", // Also reserved in WGSL
// "else", // WGSL keyword
// "enum", // WGSL keyword
"errorf",
// "exp", // WGSL builtin
// "exp2", // WGSL builtin
- "explicit",
- "export",
- "extern",
+ // "explicit", // Also reserved in WGSL
+ // "export", // Also reserved in WGSL
+ // "extern", // Also reserved in WGSL
"f16to32",
"f32tof16",
// "faceforward", // WGSL builtin
@@ -853,11 +853,11 @@
"forcecase",
"frac",
// "frexp", // WGSL builtin
- "friend",
+ // "friend", // Also reserved in WGSL
// "fwidth", // WGSL builtin
- "fxgroup",
- "goto",
- "groupshared",
+ // "fxgroup", // Also reserved in WGSL
+ // "goto", // Also reserved in WGSL
+ // "groupshared", // Also reserved in WGSL
"half",
"half1",
"half1x1",
@@ -881,8 +881,8 @@
"half4x4",
// "if", // WGSL keyword
// "in", // WGSL keyword
- "inline",
- "inout",
+ // "inline", // Also reserved in WGSL
+ // "inout", // Also reserved in WGSL
"int",
"int1",
"int1x1",
@@ -904,15 +904,15 @@
"int4x2",
"int4x3",
"int4x4",
- "interface",
+ // "interface", // Also reserved in WGSL
"isfinite",
"isinf",
"isnan",
// "ldexp", // WGSL builtin
// "length", // WGSL builtin
"lerp",
- "line",
- "lineadj",
+ // "line", // Also reserved in WGSL
+ // "lineadj", // Also reserved in WGSL
"linear",
"lit",
// "log", // WGSL builtin
@@ -1032,33 +1032,33 @@
// "modf", // WGSL builtin
"msad4",
"mul",
- "mutable",
- "namespace",
- "new",
- "nointerpolation",
+ // "mutable", // Also reserved in WGSL
+ // "namespace", // Also reserved in WGSL
+ // "new", // Also reserved in WGSL
+ // "nointerpolation", // Also reserved in WGSL
"noise",
- "noperspective",
+ // "noperspective", // Also reserved in WGSL
// "normalize", // WGSL builtin
"numthreads",
- "operator",
+ // "operator", // Also reserved in WGSL
// "out", // WGSL keyword
- "packoffset",
- "pass",
- "pixelfragment",
+ // "packoffset", // Also reserved in WGSL
+ // "pass", // Also reserved in WGSL
+ // "pixelfragment", // Also reserved in WGSL
"pixelshader",
- "point",
+ // "point", // Also reserved in WGSL
// "pow", // WGSL builtin
- "precise",
+ // "precise", // Also reserved in WGSL
"printf",
// "private", // WGSL keyword
- "protected",
- "public",
+ // "protected", // Also reserved in WGSL
+ // "public", // Also reserved in WGSL
"radians",
"rcp",
// "reflect", // WGSL builtin
"refract",
- "register",
- "reinterpret_cast",
+ // "register", // Also reserved in WGSL
+ // "reinterpret_cast", // Also reserved in WGSL
// "return", // WGSL keyword
// "reversebits", // WGSL builtin
// "round", // WGSL builtin
@@ -1071,21 +1071,21 @@
"samplerCUBE",
"sampler_state",
"saturate",
- "shared",
+ // "shared", // Also reserved in WGSL
"short",
// "sign", // WGSL builtin
- "signed",
+ // "signed", // Also reserved in WGSL
// "sin", // WGSL builtin
"sincos",
// "sinh", // WGSL builtin
- "sizeof",
+ // "sizeof", // Also reserved in WGSL
// "smoothstep", // WGSL builtin
- "snorm",
+ // "snorm", // Also reserved in WGSL
// "sqrt", // WGSL builtin
"stateblock",
"stateblock_state",
- "static",
- "static_cast",
+ // "static", // Also reserved in WGSL
+ // "static_cast", // Also reserved in WGSL
// "step", // WGSL builtin
"string",
// "struct", // WGSL keyword
@@ -1096,7 +1096,7 @@
"technique",
"technique10",
"technique11",
- "template",
+ // "template", // Also reserved in WGSL
"tex1D",
"tex1Dbias",
"tex1Dgrad",
@@ -1127,16 +1127,16 @@
"texture3D",
"textureCube",
"textureCubeArray",
- "this",
- "throw",
+ // "this", // Also reserved in WGSL
+ // "throw", // Also reserved in WGSL
"transpose",
"triangle",
"triangleadj",
// "true", // WGSL keyword
// "trunc", // WGSL builtin
- "try",
+ // "try", // Also reserved in WGSL
// "typedef", // WGSL keyword
- "typename",
+ // "typename", // Also reserved in WGSL
"uint",
"uint1",
"uint1x1",
@@ -1159,17 +1159,17 @@
"uint4x3",
"uint4x4",
// "uniform", // WGSL keyword
- "union",
- "unorm",
+ // "union", // Also reserved in WGSL
+ // "unorm", // Also reserved in WGSL
"unroll",
"unsigned",
// "using", // WGSL reserved keyword
"vector",
"vertexfragment",
"vertexshader",
- "virtual",
+ // "virtual", // Also reserved in WGSL
// "void", // WGSL keyword
- "volatile",
+ // "volatile", // Also reserved in WGSL
// "while" // WGSL reserved keyword
kUnicodeIdentifier));
@@ -1178,87 +1178,87 @@
RenamerTestMsl,
testing::Values(
// c++14 spec
- "alignas",
- "alignof",
+ // "alignas", // Also reserved in WGSL
+ // "alignof", // Also reserved in WGSL
"and",
"and_eq",
// "asm", // Also reserved in WGSL
- "auto",
+ // "auto", // Also reserved in WGSL
"bitand",
"bitor",
// "bool", // Also used in WGSL
// "break", // Also used in WGSL
// "case", // Also used in WGSL
- "catch",
+ // "catch", // Also reserved in WGSL
"char",
"char16_t",
"char32_t",
- "class",
+ // "class", // Also reserved in WGSL
"compl",
// "const", // Also used in WGSL
- "const_cast",
- "constexpr",
+ // "const_cast", // Also reserved in WGSL
+ // "constexpr", // Also reserved in WGSL
// "continue", // Also used in WGSL
- "decltype",
+ // "decltype", // Also reserved in WGSL
// "default", // Also used in WGSL
- "delete",
+ // "delete", // Also reserved in WGSL
// "do", // Also used in WGSL
"double",
- "dynamic_cast",
+ // "dynamic_cast", // Also reserved in WGSL
// "else", // Also used in WGSL
// "enum", // Also used in WGSL
- "explicit",
- "extern",
+ // "explicit", // Also reserved in WGSL
+ // "extern", // Also reserved in WGSL
// "false", // Also used in WGSL
- "final",
+ // "final", // Also reserved in WGSL
"float",
// "for", // Also used in WGSL
- "friend",
- "goto",
+ // "friend", // Also reserved in WGSL
+ // "goto", // Also reserved in WGSL
// "if", // Also used in WGSL
- "inline",
+ // "inline", // Also reserved in WGSL
"int",
"long",
- "mutable",
- "namespace",
- "new",
- "noexcept",
+ // "mutable", // Also reserved in WGSL
+ // "namespace", // Also reserved in WGSL
+ // "new", // Also reserved in WGSL
+ // "noexcept", // Also reserved in WGSL
"not",
"not_eq",
- "nullptr",
- "operator",
+ // "nullptr", // Also reserved in WGSL
+ // "operator", // Also reserved in WGSL
"or",
"or_eq",
// "override", // Also used in WGSL
// "private", // Also used in WGSL
- "protected",
- "public",
- "register",
- "reinterpret_cast",
+ // "protected", // Also reserved in WGSL
+ // "public", // Also reserved in WGSL
+ // "register", // Also reserved in WGSL
+ // "reinterpret_cast", // Also reserved in WGSL
// "return", // Also used in WGSL
"short",
- "signed",
- "sizeof",
- "static",
- "static_assert",
- "static_cast",
+ // "signed", // Also reserved in WGSL
+ // "sizeof", // Also reserved in WGSL
+ // "static", // Also reserved in WGSL
+ // "static_assert", // Also reserved in WGSL
+ // "static_cast", // Also reserved in WGSL
// "struct", // Also used in WGSL
// "switch", // Also used in WGSL
- "template",
- "this",
- "thread_local",
- "throw",
+ // "template", // Also reserved in WGSL
+ // "this", // Also reserved in WGSL
+ // "thread_local", // Also reserved in WGSL
+ // "throw", // Also reserved in WGSL
// "true", // Also used in WGSL
- "try",
+ // "try", // Also reserved in WGSL
// "typedef", // Also used in WGSL
- "typeid",
- "typename",
- "union",
+ // "typeid", // Also reserved in WGSL
+ // "typename", // Also reserved in WGSL
+ // "union", // Also reserved in WGSL
"unsigned",
// "using", // WGSL reserved keyword
- "virtual",
+ // "virtual", // Also reserved in WGSL
// "void", // Also used in WGSL
- "volatile",
+ // "volatile", // Also reserved in WGSL
"wchar_t",
// "while", // WGSL reserved keyword
"xor",
diff --git a/src/tint/transform/spirv_atomic.cc b/src/tint/transform/spirv_atomic.cc
index 0cdd4a3..b79f60f 100644
--- a/src/tint/transform/spirv_atomic.cc
+++ b/src/tint/transform/spirv_atomic.cc
@@ -116,15 +116,16 @@
const auto& forked = it->second;
// Re-create the structure swapping in the atomic-flavoured members
- std::vector<const ast::StructMember*> members(str->members.size());
- for (size_t i = 0; i < str->members.size(); i++) {
+ utils::Vector<const ast::StructMember*, 8> members;
+ members.Reserve(str->members.Length());
+ for (size_t i = 0; i < str->members.Length(); i++) {
auto* member = str->members[i];
if (forked.atomic_members.count(i)) {
auto* type = AtomicTypeFor(ctx.src->Sem().Get(member)->Type());
auto name = ctx.src->Symbols().NameFor(member->symbol);
- members[i] = b.Member(name, type, ctx.Clone(member->attributes));
+ members.Push(b.Member(name, type, ctx.Clone(member->attributes)));
} else {
- members[i] = ctx.Clone(member);
+ members.Push(ctx.Clone(member));
}
}
b.Structure(forked.name, std::move(members));
diff --git a/src/tint/transform/spirv_atomic_test.cc b/src/tint/transform/spirv_atomic_test.cc
index cbd8a26..7f6db34 100644
--- a/src/tint/transform/spirv_atomic_test.cc
+++ b/src/tint/transform/spirv_atomic_test.cc
@@ -44,76 +44,99 @@
};
for (auto& a : two_params) {
b.Func(std::string{"stub_"} + sem::str(a) + "_u32",
- {
+ utils::Vector{
b.Param("p0", b.ty.u32()),
b.Param("p1", b.ty.u32()),
},
- b.ty.u32(), {b.Return(0_u)},
- {b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), b.AllocateNodeID(), a)});
+ b.ty.u32(),
+ utils::Vector{
+ b.Return(0_u),
+ },
+ utils::Vector{
+ b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), b.AllocateNodeID(), a),
+ });
b.Func(std::string{"stub_"} + sem::str(a) + "_i32",
- {
+ utils::Vector{
b.Param("p0", b.ty.i32()),
b.Param("p1", b.ty.i32()),
},
- b.ty.i32(), {b.Return(0_i)},
- {b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), b.AllocateNodeID(), a)});
+ b.ty.i32(),
+ utils::Vector{
+ b.Return(0_i),
+ },
+ utils::Vector{
+ b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), b.AllocateNodeID(), a),
+ });
}
b.Func("stub_atomicLoad_u32",
- {
+ utils::Vector{
b.Param("p0", b.ty.u32()),
},
- b.ty.u32(), {b.Return(0_u)},
- {
+ b.ty.u32(),
+ utils::Vector{
+ b.Return(0_u),
+ },
+ utils::Vector{
b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), b.AllocateNodeID(),
sem::BuiltinType::kAtomicLoad),
});
b.Func("stub_atomicLoad_i32",
- {
+ utils::Vector{
b.Param("p0", b.ty.i32()),
},
- b.ty.i32(), {b.Return(0_i)},
- {
+ b.ty.i32(),
+ utils::Vector{
+ b.Return(0_i),
+ },
+ utils::Vector{
b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), b.AllocateNodeID(),
sem::BuiltinType::kAtomicLoad),
});
b.Func("stub_atomicStore_u32",
- {
+ utils::Vector{
b.Param("p0", b.ty.u32()),
b.Param("p1", b.ty.u32()),
},
- b.ty.void_(), {},
- {
+ b.ty.void_(), utils::Empty,
+ utils::Vector{
b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), b.AllocateNodeID(),
sem::BuiltinType::kAtomicStore),
});
b.Func("stub_atomicStore_i32",
- {
+ utils::Vector{
b.Param("p0", b.ty.i32()),
b.Param("p1", b.ty.i32()),
},
- b.ty.void_(), {},
- {
+ b.ty.void_(), utils::Empty,
+ utils::Vector{
b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), b.AllocateNodeID(),
sem::BuiltinType::kAtomicStore),
});
b.Func("stub_atomic_compare_exchange_weak_u32",
- {
+ utils::Vector{
b.Param("p0", b.ty.u32()),
b.Param("p1", b.ty.u32()),
b.Param("p2", b.ty.u32()),
},
- b.ty.u32(), {b.Return(0_u)},
- {
+ b.ty.u32(),
+ utils::Vector{
+ b.Return(0_u),
+ },
+ utils::Vector{
b.ASTNodes().Create<SpirvAtomic::Stub>(
b.ID(), b.AllocateNodeID(), sem::BuiltinType::kAtomicCompareExchangeWeak),
});
b.Func("stub_atomic_compare_exchange_weak_i32",
- {b.Param("p0", b.ty.i32()), b.Param("p1", b.ty.i32()), b.Param("p2", b.ty.i32())},
- b.ty.i32(), {b.Return(0_i)},
- {
+ utils::Vector{b.Param("p0", b.ty.i32()), b.Param("p1", b.ty.i32()),
+ b.Param("p2", b.ty.i32())},
+ b.ty.i32(),
+ utils::Vector{
+ b.Return(0_i),
+ },
+ utils::Vector{
b.ASTNodes().Create<SpirvAtomic::Stub>(
b.ID(), b.AllocateNodeID(), sem::BuiltinType::kAtomicCompareExchangeWeak),
});
diff --git a/src/tint/transform/transform.cc b/src/tint/transform/transform.cc
index f3ab173..3adfff6 100644
--- a/src/tint/transform/transform.cc
+++ b/src/tint/transform/transform.cc
@@ -106,9 +106,9 @@
}
if (auto* a = ty->As<sem::Array>()) {
auto* el = CreateASTTypeFor(ctx, a->ElemType());
- ast::AttributeList attrs;
+ utils::Vector<const ast::Attribute*, 1> attrs;
if (!a->IsStrideImplicit()) {
- attrs.emplace_back(ctx.dst->create<ast::StrideAttribute>(a->Stride()));
+ attrs.Push(ctx.dst->create<ast::StrideAttribute>(a->Stride()));
}
if (a->IsRuntimeSized()) {
return ctx.dst->ty.array(el, nullptr, std::move(attrs));
diff --git a/src/tint/transform/transform_test.cc b/src/tint/transform/transform_test.cc
index 3e342c5..4ec4d1d 100644
--- a/src/tint/transform/transform_test.cc
+++ b/src/tint/transform/transform_test.cc
@@ -69,7 +69,7 @@
});
ASSERT_TRUE(arr->Is<ast::Array>());
ASSERT_TRUE(arr->As<ast::Array>()->type->Is<ast::F32>());
- ASSERT_EQ(arr->As<ast::Array>()->attributes.size(), 0u);
+ ASSERT_EQ(arr->As<ast::Array>()->attributes.Length(), 0u);
auto* size = arr->As<ast::Array>()->count->As<ast::IntLiteralExpression>();
ASSERT_NE(size, nullptr);
@@ -82,7 +82,7 @@
});
ASSERT_TRUE(arr->Is<ast::Array>());
ASSERT_TRUE(arr->As<ast::Array>()->type->Is<ast::F32>());
- ASSERT_EQ(arr->As<ast::Array>()->attributes.size(), 1u);
+ ASSERT_EQ(arr->As<ast::Array>()->attributes.Length(), 1u);
ASSERT_TRUE(arr->As<ast::Array>()->attributes[0]->Is<ast::StrideAttribute>());
ASSERT_EQ(arr->As<ast::Array>()->attributes[0]->As<ast::StrideAttribute>()->stride, 64u);
diff --git a/src/tint/transform/unwind_discard_functions.cc b/src/tint/transform/unwind_discard_functions.cc
index d41ef6c..8c62f04 100644
--- a/src/tint/transform/unwind_discard_functions.cc
+++ b/src/tint/transform/unwind_discard_functions.cc
@@ -67,7 +67,8 @@
Symbol ModuleDiscardFuncName() {
if (!module_discard_func_name.IsValid()) {
module_discard_func_name = b.Symbols().New("tint_discard_func");
- b.Func(module_discard_func_name, {}, b.ty.void_(), {b.Discard()});
+ b.Func(module_discard_func_name, tint::utils::Empty, b.ty.void_(),
+ tint::utils::Vector{b.Discard()});
}
return module_discard_func_name;
}
@@ -108,14 +109,14 @@
// }
//
const ast::IfStatement* IfDiscardReturn(const ast::Statement* stmt) {
- ast::StatementList stmts;
+ tint::utils::Vector<const ast::Statement*, 2> stmts;
// For entry point functions, also emit the discard statement
if (IsInEntryPointFunc(stmt)) {
- stmts.emplace_back(CallDiscardFunc());
+ stmts.Push(CallDiscardFunc());
}
- stmts.emplace_back(Return(stmt));
+ stmts.Push(Return(stmt));
auto var_name = ModuleDiscardVarName();
return b.If(var_name, b.Block(stmts));
diff --git a/src/tint/transform/utils/get_insertion_point_test.cc b/src/tint/transform/utils/get_insertion_point_test.cc
index 071cfea..72fedd0 100644
--- a/src/tint/transform/utils/get_insertion_point_test.cc
+++ b/src/tint/transform/utils/get_insertion_point_test.cc
@@ -35,7 +35,7 @@
auto* expr = b.Expr(1_i);
auto* var = b.Decl(b.Var("a", nullptr, expr));
auto* block = b.Block(var);
- b.Func("f", {}, b.ty.void_(), {block});
+ b.Func("f", tint::utils::Empty, b.ty.void_(), tint::utils::Vector{block});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -56,9 +56,9 @@
ProgramBuilder b;
auto* expr = b.Expr(1_i);
auto* var = b.Decl(b.Var("a", nullptr, expr));
- auto* fl = b.For(var, b.Expr(true), {}, b.Block());
+ auto* fl = b.For(var, b.Expr(true), nullptr, b.Block());
auto* func_block = b.Block(fl);
- b.Func("f", {}, b.ty.void_(), {func_block});
+ b.Func("f", tint::utils::Empty, b.ty.void_(), tint::utils::Vector{func_block});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -79,7 +79,7 @@
auto* expr = b.Expr(1_i);
auto* var = b.Decl(b.Var("a", nullptr, expr));
auto* s = b.For({}, b.Expr(true), var, b.Block());
- b.Func("f", {}, b.ty.void_(), {s});
+ b.Func("f", tint::utils::Empty, b.ty.void_(), tint::utils::Vector{s});
Program original(std::move(b));
ProgramBuilder cloned_b;
diff --git a/src/tint/transform/utils/hoist_to_decl_before.cc b/src/tint/transform/utils/hoist_to_decl_before.cc
index 2995522..9133267 100644
--- a/src/tint/transform/utils/hoist_to_decl_before.cc
+++ b/src/tint/transform/utils/hoist_to_decl_before.cc
@@ -36,14 +36,14 @@
/// loop, so that declaration statements can be inserted before the
/// condition expression or continuing statement.
struct LoopInfo {
- ast::StatementList cond_decls;
- ast::StatementList cont_decls;
+ utils::Vector<const ast::Statement*, 8> cond_decls;
+ utils::Vector<const ast::Statement*, 8> cont_decls;
};
/// Info for each else-if that needs decomposing
struct ElseIfInfo {
/// Decls to insert before condition
- ast::StatementList cond_decls;
+ utils::Vector<const ast::Statement*, 8> cond_decls;
};
/// For-loops that need to be decomposed to loops.
@@ -85,10 +85,10 @@
// { break; }
auto* break_body = b.Block(b.create<ast::BreakStatement>());
// if (!condition) { break; }
- body_stmts.emplace_back(b.If(not_cond, break_body));
+ body_stmts.Push(b.If(not_cond, break_body));
}
// Next emit the for-loop body
- body_stmts.emplace_back(ctx.Clone(for_loop->body));
+ body_stmts.Push(ctx.Clone(for_loop->body));
// Finally create the continuing block if there was one.
const ast::BlockStatement* continuing = nullptr;
@@ -96,7 +96,7 @@
// Continuing block starts with any let declarations used by
// the continuing.
auto cont_stmts = info.cont_decls;
- cont_stmts.emplace_back(ctx.Clone(cont));
+ cont_stmts.Push(ctx.Clone(cont));
continuing = b.Block(cont_stmts);
}
@@ -141,10 +141,10 @@
// { break; }
auto* break_body = b.Block(b.create<ast::BreakStatement>());
// if (!condition) { break; }
- body_stmts.emplace_back(b.If(not_cond, break_body));
+ body_stmts.Push(b.If(not_cond, break_body));
// Next emit the body
- body_stmts.emplace_back(ctx.Clone(while_loop->body));
+ body_stmts.Push(ctx.Clone(while_loop->body));
const ast::BlockStatement* continuing = nullptr;
@@ -173,7 +173,7 @@
auto* cond = ctx.Clone(else_if->condition);
auto* body = ctx.Clone(else_if->body);
auto* new_if = b.If(cond, body, b.Else(ctx.Clone(else_if->else_statement)));
- body_stmts.emplace_back(new_if);
+ body_stmts.Push(new_if);
// Replace the 'else-if' with the new 'else' block.
return b.Block(body_stmts);
@@ -231,7 +231,7 @@
// Index the map to convert this else if, even if `stmt` is nullptr.
auto& decls = else_if_info.cond_decls;
if (stmt) {
- decls.emplace_back(stmt);
+ decls.Push(stmt);
}
return true;
}
@@ -243,7 +243,7 @@
// Index the map to convert this for-loop, even if `stmt` is nullptr.
auto& decls = for_loops[fl].cond_decls;
if (stmt) {
- decls.emplace_back(stmt);
+ decls.Push(stmt);
}
return true;
}
@@ -255,7 +255,7 @@
// Index the map to convert this while, even if `stmt` is nullptr.
auto& decls = while_loops[w].cond_decls;
if (stmt) {
- decls.emplace_back(stmt);
+ decls.Push(stmt);
}
return true;
}
@@ -290,7 +290,7 @@
// Index the map to convert this for-loop, even if `stmt` is nullptr.
auto& decls = for_loops[fl].cont_decls;
if (stmt) {
- decls.emplace_back(stmt);
+ decls.Push(stmt);
}
return true;
}
diff --git a/src/tint/transform/utils/hoist_to_decl_before_test.cc b/src/tint/transform/utils/hoist_to_decl_before_test.cc
index 22784ba..6d4533d 100644
--- a/src/tint/transform/utils/hoist_to_decl_before_test.cc
+++ b/src/tint/transform/utils/hoist_to_decl_before_test.cc
@@ -36,7 +36,7 @@
ProgramBuilder b;
auto* expr = b.Expr(1_i);
auto* var = b.Decl(b.Var("a", nullptr, expr));
- b.Func("f", {}, b.ty.void_(), {var});
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -67,8 +67,8 @@
// }
ProgramBuilder b;
auto* expr = b.Expr(1_i);
- auto* s = b.For(b.Decl(b.Var("a", nullptr, expr)), b.Expr(true), {}, b.Block());
- b.Func("f", {}, b.ty.void_(), {s});
+ auto* s = b.For(b.Decl(b.Var("a", nullptr, expr)), b.Expr(true), nullptr, b.Block());
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{s});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -102,8 +102,8 @@
ProgramBuilder b;
auto* var = b.Decl(b.Var("a", b.ty.bool_()));
auto* expr = b.Expr("a");
- auto* s = b.For({}, expr, {}, b.Block());
- b.Func("f", {}, b.ty.void_(), {var, s});
+ auto* s = b.For(nullptr, expr, nullptr, b.Block());
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var, s});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -141,8 +141,8 @@
// }
ProgramBuilder b;
auto* expr = b.Expr(1_i);
- auto* s = b.For({}, b.Expr(true), b.Decl(b.Var("a", nullptr, expr)), b.Block());
- b.Func("f", {}, b.ty.void_(), {s});
+ auto* s = b.For(nullptr, b.Expr(true), b.Decl(b.Var("a", nullptr, expr)), b.Block());
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{s});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -186,7 +186,7 @@
auto* var = b.Decl(b.Var("a", b.ty.bool_()));
auto* expr = b.Expr("a");
auto* s = b.While(expr, b.Block());
- b.Func("f", {}, b.ty.void_(), {var, s});
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var, s});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -231,7 +231,7 @@
auto* s = b.If(b.Expr(true), b.Block(), //
b.Else(b.If(expr, b.Block(), //
b.Else(b.Block()))));
- b.Func("f", {}, b.ty.void_(), {var, s});
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var, s});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -270,7 +270,7 @@
auto* var1 = b.Decl(b.Var("a", b.ty.array<i32, 10>()));
auto* expr = b.IndexAccessor("a", 0_i);
auto* var2 = b.Decl(b.Var("b", nullptr, expr));
- b.Func("f", {}, b.ty.void_(), {var1, var2});
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var1, var2});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -305,7 +305,7 @@
auto* var1 = b.Decl(b.Var("a", b.ty.array(b.ty.array<i32, 10>(), 10_i)));
auto* expr = b.IndexAccessor(b.IndexAccessor("a", 0_i), 0_i);
auto* var2 = b.Decl(b.Var("b", nullptr, expr));
- b.Func("f", {}, b.ty.void_(), {var1, var2});
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var1, var2});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -339,8 +339,8 @@
ProgramBuilder b;
auto* var = b.Decl(b.Var("a", b.ty.bool_()));
auto* expr = b.Expr("a");
- auto* s = b.For({}, expr, {}, b.Block());
- b.Func("f", {}, b.ty.void_(), {var, s});
+ auto* s = b.For(nullptr, expr, nullptr, b.Block());
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var, s});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -377,8 +377,8 @@
// }
ProgramBuilder b;
auto* expr = b.Expr(1_i);
- auto* s = b.For({}, b.Expr(true), b.Decl(b.Var("a", nullptr, expr)), b.Block());
- b.Func("f", {}, b.ty.void_(), {s});
+ auto* s = b.For(nullptr, b.Expr(true), b.Decl(b.Var("a", nullptr, expr)), b.Block());
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{s});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -425,7 +425,7 @@
auto* s = b.If(b.Expr(true), b.Block(), //
b.Else(b.If(expr, b.Block(), //
b.Else(b.Block()))));
- b.Func("f", {}, b.ty.void_(), {var, s});
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var, s});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -461,9 +461,9 @@
// var a = 1i;
// }
ProgramBuilder b;
- b.Func("foo", {}, b.ty.void_(), {});
+ b.Func("foo", utils::Empty, b.ty.void_(), utils::Empty);
auto* var = b.Decl(b.Var("a", nullptr, b.Expr(1_i)));
- b.Func("f", {}, b.ty.void_(), {var});
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -499,10 +499,10 @@
// }
// }
ProgramBuilder b;
- b.Func("foo", {}, b.ty.void_(), {});
+ b.Func("foo", utils::Empty, b.ty.void_(), utils::Empty);
auto* var = b.Decl(b.Var("a", nullptr, b.Expr(1_i)));
- auto* s = b.For(var, b.Expr(true), {}, b.Block());
- b.Func("f", {}, b.ty.void_(), {s});
+ auto* s = b.For(var, b.Expr(true), nullptr, b.Block());
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{s});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -540,11 +540,11 @@
// }
// }
ProgramBuilder b;
- b.Func("foo", {}, b.ty.void_(), {});
+ b.Func("foo", utils::Empty, b.ty.void_(), utils::Empty);
auto* var = b.Decl(b.Var("a", nullptr, b.Expr(1_i)));
auto* cont = b.CompoundAssign("a", b.Expr(1_i), ast::BinaryOp::kAdd);
- auto* s = b.For({}, b.Expr(true), cont, b.Block());
- b.Func("f", {}, b.ty.void_(), {var, s});
+ auto* s = b.For(nullptr, b.Expr(true), cont, b.Block());
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var, s});
Program original(std::move(b));
ProgramBuilder cloned_b;
@@ -594,12 +594,12 @@
// }
// }
ProgramBuilder b;
- b.Func("foo", {}, b.ty.void_(), {});
+ b.Func("foo", utils::Empty, b.ty.void_(), utils::Empty);
auto* var = b.Decl(b.Var("a", b.ty.bool_()));
auto* elseif = b.If(b.Expr("a"), b.Block(), b.Else(b.Block()));
auto* s = b.If(b.Expr(true), b.Block(), //
b.Else(elseif));
- b.Func("f", {}, b.ty.void_(), {var, s});
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var, s});
Program original(std::move(b));
ProgramBuilder cloned_b;
diff --git a/src/tint/transform/vectorize_scalar_matrix_constructors.cc b/src/tint/transform/vectorize_scalar_matrix_constructors.cc
index f48ac8e..113db5f 100644
--- a/src/tint/transform/vectorize_scalar_matrix_constructors.cc
+++ b/src/tint/transform/vectorize_scalar_matrix_constructors.cc
@@ -79,16 +79,16 @@
// Constructs a matrix using vector columns, with the elements constructed using the
// 'element(uint32_t c, uint32_t r)' callback.
auto build_mat = [&](auto&& element) {
- ast::ExpressionList columns(mat_type->columns());
+ utils::Vector<const ast::Expression*, 4> columns;
for (uint32_t c = 0; c < mat_type->columns(); c++) {
- ast::ExpressionList row_values(mat_type->rows());
+ utils::Vector<const ast::Expression*, 4> row_values;
for (uint32_t r = 0; r < mat_type->rows(); r++) {
- row_values[r] = element(c, r);
+ row_values.Push(element(c, r));
}
// Construct the column vector.
- columns[c] = ctx.dst->vec(CreateASTTypeFor(ctx, mat_type->type()), mat_type->rows(),
- row_values);
+ columns.Push(ctx.dst->vec(CreateASTTypeFor(ctx, mat_type->type()), mat_type->rows(),
+ std::move(row_values)));
}
return ctx.dst->Construct(CreateASTTypeFor(ctx, mat_type), columns);
};
@@ -102,12 +102,12 @@
ctx.dst->Symbols().New("build_mat" + std::to_string(mat_type->columns()) + "x" +
std::to_string(mat_type->rows()));
ctx.dst->Func(name,
- {
+ utils::Vector{
// Single scalar parameter
ctx.dst->Param("value", CreateASTTypeFor(ctx, mat_type->type())),
},
CreateASTTypeFor(ctx, mat_type),
- {
+ utils::Vector{
ctx.dst->Return(build_mat([&](uint32_t, uint32_t) { //
return ctx.dst->Expr("value");
})),
diff --git a/src/tint/transform/vertex_pulling.cc b/src/tint/transform/vertex_pulling.cc
index 43531eb..6eb2bbf 100644
--- a/src/tint/transform/vertex_pulling.cc
+++ b/src/tint/transform/vertex_pulling.cc
@@ -228,7 +228,7 @@
Symbol pulling_position_name;
Symbol struct_buffer_name;
std::unordered_map<uint32_t, Symbol> vertex_buffer_names;
- ast::ParameterList new_function_parameters;
+ utils::Vector<const ast::Parameter*, 8> new_function_parameters;
/// Generate the vertex buffer binding name
/// @param index index to append to buffer name
@@ -254,14 +254,14 @@
static const char kStructName[] = "TintVertexData";
auto* struct_type =
ctx.dst->Structure(ctx.dst->Symbols().New(kStructName),
- {
+ utils::Vector{
ctx.dst->Member(GetStructBufferName(), ctx.dst->ty.array<u32>()),
});
for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
// The decorated variable with struct type
ctx.dst->GlobalVar(GetVertexBufferName(i), ctx.dst->ty.Of(struct_type),
ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
ctx.dst->create<ast::BindingAttribute>(i),
ctx.dst->create<ast::GroupAttribute>(cfg.pulling_group),
});
@@ -273,7 +273,7 @@
// Assign by looking at the vertex descriptor to find attributes with
// matching location.
- ast::StatementList stmts;
+ utils::Vector<const ast::Statement*, 8> stmts;
for (uint32_t buffer_idx = 0; buffer_idx < cfg.vertex_state.size(); ++buffer_idx) {
const VertexBufferLayoutDescriptor& buffer_layout = cfg.vertex_state[buffer_idx];
@@ -303,8 +303,7 @@
}
// let pulling_offset_n = <attribute_offset>
- stmts.emplace_back(
- ctx.dst->Decl(ctx.dst->Let(buffer_array_base, nullptr, attribute_offset)));
+ stmts.Push(ctx.dst->Decl(ctx.dst->Let(buffer_array_base, nullptr, attribute_offset)));
for (const VertexAttributeDescriptor& attribute_desc : buffer_layout.attributes) {
auto it = location_info.find(attribute_desc.shader_location);
@@ -356,24 +355,24 @@
} else if (var_dt.width > fmt_dt.width) {
// WGSL variable vector width is wider than the loaded vector width
const ast::Type* ty = nullptr;
- ast::ExpressionList values{fetch};
+ utils::Vector<const ast::Expression*, 8> values{fetch};
switch (var_dt.base_type) {
case BaseType::kI32:
ty = ctx.dst->ty.i32();
for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
- values.emplace_back(ctx.dst->Expr((i == 3) ? 1_i : 0_i));
+ values.Push(ctx.dst->Expr((i == 3) ? 1_i : 0_i));
}
break;
case BaseType::kU32:
ty = ctx.dst->ty.u32();
for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
- values.emplace_back(ctx.dst->Expr((i == 3) ? 1_u : 0_u));
+ values.Push(ctx.dst->Expr((i == 3) ? 1_u : 0_u));
}
break;
case BaseType::kF32:
ty = ctx.dst->ty.f32();
for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
- values.emplace_back(ctx.dst->Expr((i == 3) ? 1_f : 0_f));
+ values.Push(ctx.dst->Expr((i == 3) ? 1_f : 0_f));
}
break;
default:
@@ -384,15 +383,15 @@
}
// Assign the value to the WGSL variable
- stmts.emplace_back(ctx.dst->Assign(var.expr(), value));
+ stmts.Push(ctx.dst->Assign(var.expr(), value));
}
}
- if (stmts.empty()) {
+ if (stmts.IsEmpty()) {
return nullptr;
}
- return ctx.dst->create<ast::BlockStatement>(stmts);
+ return ctx.dst->create<ast::BlockStatement>(std::move(stmts));
}
/// Generates an expression reading from a buffer a specific format.
@@ -679,11 +678,11 @@
const ast::Type* base_type,
VertexFormat base_format,
uint32_t count) {
- ast::ExpressionList expr_list;
+ utils::Vector<const ast::Expression*, 8> expr_list;
for (uint32_t i = 0; i < count; ++i) {
// Offset read position by element_stride for each component
uint32_t primitive_offset = offset + element_stride * i;
- expr_list.push_back(LoadPrimitive(array_base, primitive_offset, buffer, base_format));
+ expr_list.Push(LoadPrimitive(array_base, primitive_offset, buffer, base_format));
}
return ctx.dst->Construct(ctx.dst->create<ast::Vector>(base_type, count),
@@ -718,7 +717,7 @@
return ctx.dst->Expr(ctx.Clone(param->symbol));
};
}
- new_function_parameters.push_back(ctx.Clone(param));
+ new_function_parameters.Push(ctx.Clone(param));
} else {
TINT_ICE(Transform, ctx.dst->Diagnostics()) << "Invalid entry point parameter";
}
@@ -739,7 +738,7 @@
// Process the struct members.
bool has_locations = false;
- ast::StructMemberList members_to_clone;
+ utils::Vector<const ast::StructMember*, 8> members_to_clone;
for (auto* member : struct_ty->members) {
auto member_sym = ctx.Clone(member->symbol);
std::function<const ast::Expression*()> member_expr = [this, param_sym, member_sym]() {
@@ -761,7 +760,7 @@
} else if (builtin->builtin == ast::BuiltinValue::kInstanceIndex) {
instance_index_expr = member_expr;
}
- members_to_clone.push_back(member);
+ members_to_clone.Push(member);
} else {
TINT_ICE(Transform, ctx.dst->Diagnostics()) << "Invalid entry point parameter";
}
@@ -769,7 +768,7 @@
if (!has_locations) {
// Nothing to do.
- new_function_parameters.push_back(ctx.Clone(param));
+ new_function_parameters.Push(ctx.Clone(param));
return;
}
@@ -777,21 +776,20 @@
auto* func_var = ctx.dst->Var(param_sym, ctx.Clone(param->type));
ctx.InsertFront(func->body->statements, ctx.dst->Decl(func_var));
- if (!members_to_clone.empty()) {
+ if (!members_to_clone.IsEmpty()) {
// Create a new struct without the location attributes.
- ast::StructMemberList new_members;
+ utils::Vector<const ast::StructMember*, 8> new_members;
for (auto* member : members_to_clone) {
auto member_sym = ctx.Clone(member->symbol);
auto* member_type = ctx.Clone(member->type);
auto member_attrs = ctx.Clone(member->attributes);
- new_members.push_back(
- ctx.dst->Member(member_sym, member_type, std::move(member_attrs)));
+ new_members.Push(ctx.dst->Member(member_sym, member_type, std::move(member_attrs)));
}
auto* new_struct = ctx.dst->Structure(ctx.dst->Sym(), new_members);
// Create a new function parameter with this struct.
auto* new_param = ctx.dst->Param(ctx.dst->Sym(), ctx.dst->ty.Of(new_struct));
- new_function_parameters.push_back(new_param);
+ new_function_parameters.Push(new_param);
// Copy values from the new parameter to the function-scope variable.
for (auto* member : members_to_clone) {
@@ -825,9 +823,9 @@
for (const VertexBufferLayoutDescriptor& layout : cfg.vertex_state) {
if (layout.step_mode == VertexStepMode::kVertex) {
auto name = ctx.dst->Symbols().New("tint_pulling_vertex_index");
- new_function_parameters.push_back(
- ctx.dst->Param(name, ctx.dst->ty.u32(),
- {ctx.dst->Builtin(ast::BuiltinValue::kVertexIndex)}));
+ new_function_parameters.Push(ctx.dst->Param(
+ name, ctx.dst->ty.u32(),
+ utils::Vector{ctx.dst->Builtin(ast::BuiltinValue::kVertexIndex)}));
vertex_index_expr = [this, name]() { return ctx.dst->Expr(name); };
break;
}
@@ -837,9 +835,9 @@
for (const VertexBufferLayoutDescriptor& layout : cfg.vertex_state) {
if (layout.step_mode == VertexStepMode::kInstance) {
auto name = ctx.dst->Symbols().New("tint_pulling_instance_index");
- new_function_parameters.push_back(
- ctx.dst->Param(name, ctx.dst->ty.u32(),
- {ctx.dst->Builtin(ast::BuiltinValue::kInstanceIndex)}));
+ new_function_parameters.Push(ctx.dst->Param(
+ name, ctx.dst->ty.u32(),
+ utils::Vector{ctx.dst->Builtin(ast::BuiltinValue::kInstanceIndex)}));
instance_index_expr = [this, name]() { return ctx.dst->Expr(name); };
break;
}
diff --git a/src/tint/transform/while_to_loop.cc b/src/tint/transform/while_to_loop.cc
index 00ebb01..45944e6 100644
--- a/src/tint/transform/while_to_loop.cc
+++ b/src/tint/transform/while_to_loop.cc
@@ -36,7 +36,7 @@
void WhileToLoop::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
ctx.ReplaceAll([&](const ast::WhileStatement* w) -> const ast::Statement* {
- ast::StatementList stmts;
+ utils::Vector<const ast::Statement*, 16> stmts;
auto* cond = w->condition;
// !condition
@@ -47,10 +47,10 @@
auto* break_body = ctx.dst->Block(ctx.dst->create<ast::BreakStatement>());
// if (!condition) { break; }
- stmts.emplace_back(ctx.dst->If(not_cond, break_body));
+ stmts.Push(ctx.dst->If(not_cond, break_body));
for (auto* stmt : w->body->statements) {
- stmts.emplace_back(ctx.Clone(stmt));
+ stmts.Push(ctx.Clone(stmt));
}
const ast::BlockStatement* continuing = nullptr;
diff --git a/src/tint/transform/zero_init_workgroup_memory.cc b/src/tint/transform/zero_init_workgroup_memory.cc
index 890ecef..963ca01 100644
--- a/src/tint/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/transform/zero_init_workgroup_memory.cc
@@ -32,6 +32,8 @@
namespace tint::transform {
+using StatementList = utils::Vector<const ast::Statement*, 8>;
+
/// PIMPL state for the ZeroInitWorkgroupMemory transform
struct ZeroInitWorkgroupMemory::State {
/// The clone context
@@ -162,7 +164,9 @@
if (!local_index) {
// No existing local index parameter. Append one to the entry point.
auto* param = b.Param(b.Symbols().New("local_invocation_index"), b.ty.u32(),
- {b.Builtin(ast::BuiltinValue::kLocalInvocationIndex)});
+ utils::Vector{
+ b.Builtin(ast::BuiltinValue::kLocalInvocationIndex),
+ });
ctx.InsertBack(fn->params, param);
local_index = [=] { return b.Expr(param->symbol); };
}
@@ -216,7 +220,7 @@
auto block =
DeclareArrayIndices(num_iterations, array_indices, [&] { return b.Expr(idx); });
for (auto& s : stmts) {
- block.emplace_back(s.stmt);
+ block.Push(s.stmt);
}
auto* for_loop = b.For(init, cond, cont, b.Block(block));
ctx.InsertFront(fn->body->statements, for_loop);
@@ -232,7 +236,7 @@
auto block = DeclareArrayIndices(num_iterations, array_indices,
[&] { return b.Expr(local_index()); });
for (auto& s : stmts) {
- block.emplace_back(s.stmt);
+ block.Push(s.stmt);
}
auto* if_stmt = b.If(cond, b.Block(block));
ctx.InsertFront(fn->body->statements, if_stmt);
@@ -246,7 +250,7 @@
auto block = DeclareArrayIndices(num_iterations, array_indices,
[&] { return b.Expr(local_index()); });
for (auto& s : stmts) {
- block.emplace_back(s.stmt);
+ block.Push(s.stmt);
}
ctx.InsertFront(fn->body->statements, b.Block(block));
}
@@ -327,11 +331,10 @@
/// @param iteration a function that returns the index of the current
/// iteration.
/// @returns the list of `let` statements that declare the array indices
- ast::StatementList DeclareArrayIndices(
- uint32_t num_iterations,
- const ArrayIndices& array_indices,
- const std::function<const ast::Expression*()>& iteration) {
- ast::StatementList stmts;
+ StatementList DeclareArrayIndices(uint32_t num_iterations,
+ const ArrayIndices& array_indices,
+ const std::function<const ast::Expression*()>& iteration) {
+ StatementList stmts;
std::map<Symbol, ArrayIndex> indices_by_name;
for (auto index : array_indices) {
auto name = array_index_names.at(index);
@@ -341,7 +344,7 @@
: iteration();
auto* div = (index.division != 1u) ? b.Div(mod, u32(index.division)) : mod;
auto* decl = b.Decl(b.Let(name, b.ty.u32(), div));
- stmts.emplace_back(decl);
+ stmts.Push(decl);
}
return stmts;
}
diff --git a/src/tint/utils/io/command_posix.cc b/src/tint/utils/io/command_posix.cc
index ff0a138..b3371e7 100644
--- a/src/tint/utils/io/command_posix.cc
+++ b/src/tint/utils/io/command_posix.cc
@@ -251,7 +251,9 @@
std::vector<const char*> args;
args.emplace_back(path_.c_str());
for (auto& arg : arguments) {
- args.emplace_back(arg.c_str());
+ if (!arg.empty()) {
+ args.emplace_back(arg.c_str());
+ }
}
args.emplace_back(nullptr);
auto res = execv(path_.c_str(), const_cast<char* const*>(args.data()));
diff --git a/src/tint/utils/io/command_windows.cc b/src/tint/utils/io/command_windows.cc
index 36c39c6..8c94e25 100644
--- a/src/tint/utils/io/command_windows.cc
+++ b/src/tint/utils/io/command_windows.cc
@@ -200,7 +200,9 @@
std::stringstream args;
args << path_;
for (auto& arg : arguments) {
- args << " " << arg;
+ if (!arg.empty()) {
+ args << " " << arg;
+ }
}
PROCESS_INFORMATION pi{};
diff --git a/src/tint/utils/result.h b/src/tint/utils/result.h
index 6cfe668..b535f4f 100644
--- a/src/tint/utils/result.h
+++ b/src/tint/utils/result.h
@@ -32,7 +32,7 @@
/// information about the failure, except that something failed. Must not be the same type
/// as SUCCESS_TYPE.
template <typename SUCCESS_TYPE, typename FAILURE_TYPE = FailureType>
-struct Result {
+struct [[nodiscard]] Result {
static_assert(!std::is_same_v<SUCCESS_TYPE, FAILURE_TYPE>,
"Result must not have the same type for SUCCESS_TYPE and FAILURE_TYPE");
diff --git a/src/tint/utils/transform.h b/src/tint/utils/transform.h
index 412dbed..2faca46 100644
--- a/src/tint/utils/transform.h
+++ b/src/tint/utils/transform.h
@@ -119,40 +119,6 @@
return result;
}
-/// Transform performs an element-wise transformation of a vector reference.
-/// @param in the input vector.
-/// @param transform the transformation function with signature: `OUT(IN)`
-/// @tparam N the small-array size of the returned Vector
-/// @returns a new vector with each element of the source vector transformed by `transform`.
-template <size_t N, typename IN, typename TRANSFORMER>
-auto Transform(ConstVectorRef<IN> in, TRANSFORMER&& transform)
- -> Vector<decltype(transform(in[0])), N> {
- const auto count = in.Length();
- Vector<decltype(transform(in[0])), N> result;
- result.Reserve(count);
- for (size_t i = 0; i < count; ++i) {
- result.Push(transform(in[i]));
- }
- return result;
-}
-
-/// Transform performs an element-wise transformation of a vector reference.
-/// @param in the input vector.
-/// @param transform the transformation function with signature: `OUT(IN, size_t)`
-/// @tparam N the small-array size of the returned Vector
-/// @returns a new vector with each element of the source vector transformed by `transform`.
-template <size_t N, typename IN, typename TRANSFORMER>
-auto Transform(ConstVectorRef<IN> in, TRANSFORMER&& transform)
- -> Vector<decltype(transform(in[0], 1u)), N> {
- const auto count = in.Length();
- Vector<decltype(transform(in[0], 1u)), N> result;
- result.Reserve(count);
- for (size_t i = 0; i < count; ++i) {
- result.Push(transform(in[i], i));
- }
- return result;
-}
-
/// TransformN performs an element-wise transformation of a vector, transforming and returning at
/// most `n` elements.
/// @param in the input vector.
diff --git a/src/tint/utils/transform_test.cc b/src/tint/utils/transform_test.cc
index 656b827..71b3f0c 100644
--- a/src/tint/utils/transform_test.cc
+++ b/src/tint/utils/transform_test.cc
@@ -345,72 +345,5 @@
}
}
-TEST(TransformTest, ConstVectorRefEmpty) {
- const Vector<int, 4> empty{};
- ConstVectorRef<int> ref(empty);
- {
- auto transformed = Transform<4>(ref, [](int) -> int {
- [] { FAIL() << "Callback should not be called for empty vector"; }();
- return 0;
- });
- CHECK_ELEMENT_TYPE(transformed, int);
- EXPECT_EQ(transformed.Length(), 0u);
- }
- {
- auto transformed = Transform<4>(ref, [](int, size_t) -> int {
- [] { FAIL() << "Callback should not be called for empty vector"; }();
- return 0;
- });
- CHECK_ELEMENT_TYPE(transformed, int);
- EXPECT_EQ(transformed.Length(), 0u);
- }
-}
-
-TEST(TransformTest, ConstVectorRefIdentity) {
- const Vector<int, 4> input{1, 2, 3, 4};
- ConstVectorRef<int> ref(input);
- auto transformed = Transform<8>(ref, [](int i) { return i; });
- CHECK_ELEMENT_TYPE(transformed, int);
- EXPECT_THAT(transformed, testing::ElementsAre(1, 2, 3, 4));
-}
-
-TEST(TransformTest, ConstVectorRefIdentityWithIndex) {
- const Vector<int, 4> input{1, 2, 3, 4};
- ConstVectorRef<int> ref(input);
- auto transformed = Transform<2>(ref, [](int i, size_t) { return i; });
- CHECK_ELEMENT_TYPE(transformed, int);
- EXPECT_THAT(transformed, testing::ElementsAre(1, 2, 3, 4));
-}
-
-TEST(TransformTest, ConstVectorRefIndex) {
- const Vector<int, 4> input{10, 20, 30, 40};
- ConstVectorRef<int> ref(input);
- {
- auto transformed = Transform<4>(ref, [](int, size_t idx) { return idx; });
- CHECK_ELEMENT_TYPE(transformed, size_t);
- EXPECT_THAT(transformed, testing::ElementsAre(0u, 1u, 2u, 3u));
- }
-}
-
-TEST(TransformTest, TransformConstVectorRefSameType) {
- const Vector<int, 4> input{1, 2, 3, 4};
- ConstVectorRef<int> ref(input);
- {
- auto transformed = Transform<4>(ref, [](int i) { return i * 10; });
- CHECK_ELEMENT_TYPE(transformed, int);
- EXPECT_THAT(transformed, testing::ElementsAre(10, 20, 30, 40));
- }
-}
-
-TEST(TransformTest, TransformConstVectorRefDifferentType) {
- const Vector<int, 4> input{1, 2, 3, 4};
- ConstVectorRef<int> ref(input);
- {
- auto transformed = Transform<4>(ref, [](int i) { return std::to_string(i); });
- CHECK_ELEMENT_TYPE(transformed, std::string);
- EXPECT_THAT(transformed, testing::ElementsAre("1", "2", "3", "4"));
- }
-}
-
} // namespace
} // namespace tint::utils
diff --git a/src/tint/utils/unique_vector.h b/src/tint/utils/unique_vector.h
index 0f3f18d..d4018b2 100644
--- a/src/tint/utils/unique_vector.h
+++ b/src/tint/utils/unique_vector.h
@@ -93,6 +93,13 @@
/// @returns a const reference to the internal vector
operator const std::vector<T>&() const { return vector; }
+ /// Pre-allocates `count` elements in the vector and set
+ /// @param count the number of elements to pre-allocate
+ void reserve(size_t count) {
+ vector.reserve(count);
+ set.reserve(count);
+ }
+
/// Removes the last element from the vector
/// @returns the popped element
T pop_back() {
diff --git a/src/tint/utils/vector.h b/src/tint/utils/vector.h
index d339a49..518a693 100644
--- a/src/tint/utils/vector.h
+++ b/src/tint/utils/vector.h
@@ -17,6 +17,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <algorithm>
#include <array>
#include <iterator>
#include <utility>
@@ -32,12 +33,18 @@
template <typename>
class VectorRef;
template <typename>
-class ConstVectorRef;
+class VectorRef;
} // namespace tint::utils
namespace tint::utils {
+/// A type used to indicate an empty array.
+struct EmptyType {};
+
+/// An instance of the EmptyType.
+static constexpr EmptyType Empty;
+
/// A slice represents a contigious array of elements of type T.
template <typename T>
struct Slice {
@@ -165,6 +172,9 @@
Vector() = default;
/// Constructor
+ Vector(EmptyType) {} // NOLINT(runtime/explicit)
+
+ /// Constructor
/// @param elements the elements to place into the vector
Vector(std::initializer_list<T> elements) {
Reserve(elements.size());
@@ -217,10 +227,7 @@
/// Copy constructor from an immutable vector reference
/// @param other the vector reference to copy
- explicit Vector(const ConstVectorRef<T>& other) { Copy(other.slice_); }
-
- /// Move constructor from an immutable vector reference (invalid)
- Vector(ConstVectorRef<T>&&) = delete; // NOLINT(runtime/explicit)
+ explicit Vector(const VectorRef<T>& other) { Copy(other.slice_); }
/// Destructor
~Vector() { ClearAndFree(); }
@@ -263,6 +270,26 @@
return *this;
}
+ /// Assignment operator (differing N length)
+ /// @param other the vector reference to copy
+ /// @returns this vector so calls can be chained
+ Vector& operator=(const VectorRef<T>& other) {
+ if (&other.slice_ != &impl_.slice) {
+ Copy(other.slice_);
+ }
+ return *this;
+ }
+
+ /// Move operator (differing N length)
+ /// @param other the vector reference to copy
+ /// @returns this vector so calls can be chained
+ Vector& operator=(VectorRef<T>&& other) {
+ if (&other.slice_ != &impl_.slice) {
+ MoveOrCopy(std::move(other));
+ }
+ return *this;
+ }
+
/// Index operator
/// @param i the element index. Must be less than `len`.
/// @returns a reference to the i'th element.
@@ -367,7 +394,12 @@
/// Removes and returns the last element from the vector.
/// @returns the popped element
- T Pop() { return std::move(impl_.slice.data[--impl_.slice.len]); }
+ T Pop() {
+ auto& el = impl_.slice.data[--impl_.slice.len];
+ auto val = std::move(el);
+ el.~T();
+ return val;
+ }
/// @returns true if the vector is empty.
bool IsEmpty() const { return impl_.slice.len == 0; }
@@ -419,7 +451,7 @@
/// Friend class
template <typename>
- friend class ConstVectorRef;
+ friend class VectorRef;
/// The slice type used by this vector
using Slice = utils::Slice<T>;
@@ -430,7 +462,7 @@
}
/// Expands the capacity of the vector
- void Grow() { Reserve(impl_.slice.cap * 2); }
+ void Grow() { Reserve(std::max(impl_.slice.cap, static_cast<size_t>(1)) * 2); }
/// Moves 'other' to this vector, if possible, otherwise performs a copy.
void MoveOrCopy(VectorRef<T>&& other) {
@@ -573,11 +605,10 @@
/// VectorRef is a weak reference to a Vector, used to pass vectors as parameters, avoiding copies
/// between the caller and the callee. VectorRef can accept a Vector of any 'N' value, decoupling
-/// the caller's vector internal size from the callee's vector size.
-///
-/// A VectorRef tracks the usage of moves either side of the call. If at the call site, a Vector
-/// argument is moved to a VectorRef parameter, and within the callee, the VectorRef parameter is
-/// moved to a Vector, then the Vector heap allocation will be moved. For example:
+/// the caller's vector internal size from the callee's vector size. A VectorRef tracks the usage of
+/// moves either side of the call. If at the call site, a Vector argument is moved to a VectorRef
+/// parameter, and within the callee, the VectorRef parameter is moved to a Vector, then the Vector
+/// heap allocation will be moved. For example:
///
/// ```
/// void func_a() {
@@ -596,12 +627,30 @@
/// The slice type used by this vector reference
using Slice = utils::Slice<T>;
+ /// @returns an empty slice.
+ static Slice& EmptySlice() {
+ static Slice empty;
+ return empty;
+ }
+
public:
+ /// Constructor - empty reference
+ VectorRef() : slice_(EmptySlice()) {}
+
+ /// Constructor
+ VectorRef(EmptyType) : slice_(EmptySlice()) {} // NOLINT(runtime/explicit)
+
/// Constructor from a Vector
/// @param vector the vector to create a reference of
template <size_t N>
VectorRef(Vector<T, N>& vector) // NOLINT(runtime/explicit)
- : slice_(vector.impl_.slice), can_move_(false) {}
+ : slice_(vector.impl_.slice) {}
+
+ /// Constructor from a const Vector
+ /// @param vector the vector to create a reference of
+ template <size_t N>
+ VectorRef(const Vector<T, N>& vector) // NOLINT(runtime/explicit)
+ : slice_(const_cast<Slice&>(vector.impl_.slice)) {}
/// Constructor from a moved Vector
/// @param vector the vector being moved
@@ -611,7 +660,7 @@
/// Copy constructor
/// @param other the vector reference
- VectorRef(const VectorRef& other) : slice_(other.slice_), can_move_(false) {}
+ VectorRef(const VectorRef& other) : slice_(other.slice_) {}
/// Move constructor
/// @param other the vector reference
@@ -621,7 +670,7 @@
/// @param other the other vector reference
template <typename U, typename = std::enable_if_t<CanReinterpretSlice<T, U>>>
VectorRef(const VectorRef<U>& other) // NOLINT(runtime/explicit)
- : slice_(*ReinterpretSlice<T>(&other.slice_)), can_move_(false) {}
+ : slice_(*ReinterpretSlice<T>(&other.slice_)) {}
/// Move constructor with covariance / const conversion
/// @param other the vector reference
@@ -634,7 +683,7 @@
/// @see CanReinterpretSlice for rules about conversion
template <typename U, size_t N, typename = std::enable_if_t<CanReinterpretSlice<T, U>>>
VectorRef(Vector<U, N>& vector) // NOLINT(runtime/explicit)
- : slice_(*ReinterpretSlice<T>(&vector.impl_.slice)), can_move_(false) {}
+ : slice_(*ReinterpretSlice<T>(&vector.impl_.slice)) {}
/// Constructor from a moved Vector with covariance / const conversion
/// @param vector the vector to create a reference of
@@ -646,11 +695,6 @@
/// Index operator
/// @param i the element index. Must be less than `len`.
/// @returns a reference to the i'th element.
- T& operator[](size_t i) { return slice_[i]; }
-
- /// Index operator
- /// @param i the element index. Must be less than `len`.
- /// @returns a reference to the i'th element.
const T& operator[](size_t i) const { return slice_[i]; }
/// @return the number of elements in the vector
@@ -710,7 +754,7 @@
/// Friend class
template <typename>
- friend class ConstVectorRef;
+ friend class VectorRef;
/// The slice of the vector being referenced.
Slice& slice_;
@@ -718,99 +762,6 @@
bool can_move_ = false;
};
-/// ConstVectorRef is a weak, immutable reference to a Vector, used to pass vectors as parameters,
-/// avoiding copies between the caller and the callee. VectorRef can accept a Vector of any 'N'
-/// value, decoupling the caller's vector internal size from the callee's vector size.
-template <typename T>
-class ConstVectorRef {
- /// The slice type used by this vector reference
- using Slice = utils::Slice<T>;
-
- public:
- /// Constructor from a Vector.
- /// @param vector the vector reference
- template <size_t N>
- ConstVectorRef(const Vector<T, N>& vector) // NOLINT(runtime/explicit)
- : slice_(vector.impl_.slice) {}
-
- /// Copy constructor
- /// @param other the vector reference
- ConstVectorRef(const ConstVectorRef& other) = default;
-
- /// Conversion constructor to convert from a non-const to const vector reference
- /// @param other the vector reference
- ConstVectorRef(const VectorRef<T>& other) : slice_(other.slice_) {} // NOLINT(runtime/explicit)
-
- /// Move constructor. Deleted as this won't move anything.
- ConstVectorRef(ConstVectorRef&&) = delete;
-
- /// Constructor from a Vector with covariance / const conversion
- /// @param vector the vector to create a reference of
- /// @see CanReinterpretSlice for rules about conversion
- template <typename U, size_t N, typename = std::enable_if_t<CanReinterpretSlice<T, U>>>
- ConstVectorRef(const Vector<U, N>& vector) // NOLINT(runtime/explicit)
- : slice_(*ReinterpretSlice<T>(&vector.impl_.slice)) {}
-
- /// Constructor from a VectorRef with covariance / const conversion
- /// @param other the vector reference
- /// @see CanReinterpretSlice for rules about conversion
- template <typename U, typename = std::enable_if_t<CanReinterpretSlice<T, U>>>
- ConstVectorRef(const VectorRef<U>& other) // NOLINT(runtime/explicit)
- : slice_(*ReinterpretSlice<T>(&other.slice_)) {}
-
- /// Constructor from a ConstVectorRef with covariance / const conversion
- /// @param other the vector reference
- /// @see CanReinterpretSlice for rules about conversion
- template <typename U, typename = std::enable_if_t<CanReinterpretSlice<T, U>>>
- ConstVectorRef(const ConstVectorRef<U>& other) // NOLINT(runtime/explicit)
- : slice_(*ReinterpretSlice<T>(&other.slice_)) {}
-
- /// Index operator
- /// @param i the element index. Must be less than `len`.
- /// @returns a reference to the i'th element.
- const T& operator[](size_t i) const { return slice_[i]; }
-
- /// @return the number of elements in the vector
- size_t Length() const { return slice_.len; }
-
- /// @return the number of elements that the vector could hold before a heap allocation needs to
- /// be made
- size_t Capacity() const { return slice_.cap; }
-
- /// @returns true if the vector is empty.
- bool IsEmpty() const { return slice_.len == 0; }
-
- /// @returns a reference to the first element in the vector
- const T& Front() const { return slice_.Front(); }
-
- /// @returns a reference to the last element in the vector
- const T& Back() const { return slice_.Back(); }
-
- /// @returns a pointer to the first element in the vector
- const T* begin() const { return slice_.begin(); }
-
- /// @returns a pointer to one past the last element in the vector
- const T* end() const { return slice_.end(); }
-
- /// @returns a reverse iterator starting with the last element in the vector
- auto rbegin() const { return slice_.rbegin(); }
-
- /// @returns the end for a reverse iterator
- auto rend() const { return slice_.rend(); }
-
- private:
- /// Friend class
- template <typename, size_t>
- friend class Vector;
-
- /// Friend class
- template <typename>
- friend class ConstVectorRef;
-
- /// The slice of the vector being referenced.
- const Slice& slice_;
-};
-
/// Helper for converting a Vector to a std::vector.
/// @note This helper exists to help code migration. Avoid if possible.
template <typename T, size_t N>
diff --git a/src/tint/utils/vector_test.cc b/src/tint/utils/vector_test.cc
index 6e529dc..b4e9fb5 100644
--- a/src/tint/utils/vector_test.cc
+++ b/src/tint/utils/vector_test.cc
@@ -105,12 +105,24 @@
EXPECT_EQ(vec.Capacity(), 2u);
}
-TEST(TintVectorTest, Empty_NoSmallArray) {
+TEST(TintVectorTest, NoSmallArray) {
Vector<int, 0> vec;
EXPECT_EQ(vec.Length(), 0u);
EXPECT_EQ(vec.Capacity(), 0u);
}
+TEST(TintVectorTest, Empty_SmallArray_Empty) {
+ Vector<int, 2> vec(Empty);
+ EXPECT_EQ(vec.Length(), 0u);
+ EXPECT_EQ(vec.Capacity(), 2u);
+}
+
+TEST(TintVectorTest, Empty_NoSmallArray) {
+ Vector<int, 0> vec(Empty);
+ EXPECT_EQ(vec.Length(), 0u);
+ EXPECT_EQ(vec.Capacity(), 0u);
+}
+
TEST(TintVectorTest, InitializerList_NoSpill) {
Vector<std::string, 2> vec{"one", "two"};
EXPECT_EQ(vec.Length(), 2u);
@@ -139,6 +151,17 @@
EXPECT_TRUE(AllExternallyHeld(vec));
}
+TEST(TintVectorTest, Push_NoSmallArray) {
+ Vector<std::string, 0> vec;
+ vec.Push("one");
+ vec.Push("two");
+ EXPECT_EQ(vec.Length(), 2u);
+ EXPECT_EQ(vec.Capacity(), 2u);
+ EXPECT_EQ(vec[0], "one");
+ EXPECT_EQ(vec[1], "two");
+ EXPECT_TRUE(AllExternallyHeld(vec));
+}
+
TEST(TintVectorTest, InferTN_1CString) {
auto vec = Vector{"one"};
static_assert(std::is_same_v<decltype(vec)::value_type, const char*>);
@@ -800,7 +823,7 @@
EXPECT_TRUE(AllInternallyHeld(vec));
}
-TEST(TintVectorTest, DoubleMoveAssign_WithSpill) {
+TEST(TintVectorTest, RepeatMoveAssign_WithSpill) {
Vector<std::string, 1> vec_a{"hello", "world"};
Vector<std::string, 1> vec_b{"Ciao", "mondo"};
Vector<std::string, 1> vec_c{"bonjour", "le", "monde"};
@@ -816,6 +839,288 @@
EXPECT_TRUE(AllExternallyHeld(vec));
}
+TEST(TintVectorTest, CopyAssignRef_NoSpill_N2_to_N2) {
+ Vector<std::string, 2> vec_a{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 2> vec_b;
+ vec_b = ref;
+ EXPECT_EQ(vec_b.Length(), 2u);
+ EXPECT_EQ(vec_b.Capacity(), 2u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_TRUE(AllInternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, CopyAssignRef_WithSpill_N2_to_N2) {
+ Vector<std::string, 2> vec_a{"hello", "world", "spill"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 2> vec_b;
+ vec_b = ref;
+ EXPECT_EQ(vec_b.Length(), 3u);
+ EXPECT_EQ(vec_b.Capacity(), 3u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_EQ(vec_b[2], "spill");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, CopyAssignRef_NoSpill_N2_to_N1) {
+ Vector<std::string, 2> vec_a{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 1> vec_b;
+ vec_b = ref;
+ EXPECT_EQ(vec_b.Length(), 2u);
+ EXPECT_EQ(vec_b.Capacity(), 2u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, CopyAssignRef_WithSpill_N2_to_N1) {
+ Vector<std::string, 2> vec_a{"hello", "world", "spill"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 1> vec_b;
+ vec_b = ref;
+ EXPECT_EQ(vec_b.Length(), 3u);
+ EXPECT_EQ(vec_b.Capacity(), 3u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_EQ(vec_b[2], "spill");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, CopyAssignRef_NoSpill_N2_to_N3) {
+ Vector<std::string, 2> vec_a{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 3> vec_b;
+ vec_b = ref;
+ EXPECT_EQ(vec_b.Length(), 2u);
+ EXPECT_EQ(vec_b.Capacity(), 3u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_TRUE(AllInternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, CopyAssignRef_WithSpill_N2_to_N3) {
+ Vector<std::string, 2> vec_a{"hello", "world", "spill"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 3> vec_b;
+ vec_b = ref;
+ EXPECT_EQ(vec_b.Length(), 3u);
+ EXPECT_EQ(vec_b.Capacity(), 3u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_EQ(vec_b[2], "spill");
+ EXPECT_TRUE(AllInternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, CopyAssignRef_NoSpill_N2_to_N0) {
+ Vector<std::string, 2> vec_a{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 0> vec_b;
+ vec_b = ref;
+ EXPECT_EQ(vec_b.Length(), 2u);
+ EXPECT_EQ(vec_b.Capacity(), 2u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, CopyAssignRef_WithSpill_N2_to_N0) {
+ Vector<std::string, 2> vec_a{"hello", "world", "spill"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 0> vec_b;
+ vec_b = ref;
+ EXPECT_EQ(vec_b.Length(), 3u);
+ EXPECT_EQ(vec_b.Capacity(), 3u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_EQ(vec_b[2], "spill");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, CopyAssignRef_Self_NoSpill) {
+ Vector<std::string, 2> vec{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec)};
+ vec = ref;
+ EXPECT_EQ(vec.Length(), 2u);
+ EXPECT_EQ(vec.Capacity(), 2u);
+ EXPECT_EQ(vec[0], "hello");
+ EXPECT_EQ(vec[1], "world");
+ EXPECT_TRUE(AllInternallyHeld(vec));
+}
+
+TEST(TintVectorTest, CopyAssignRef_Self_WithSpill) {
+ Vector<std::string, 1> vec{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec)};
+ vec = ref;
+ EXPECT_EQ(vec.Length(), 2u);
+ EXPECT_EQ(vec.Capacity(), 2u);
+ EXPECT_EQ(vec[0], "hello");
+ EXPECT_EQ(vec[1], "world");
+ EXPECT_TRUE(AllExternallyHeld(vec));
+}
+
+TEST(TintVectorTest, MoveAssignRef_NoSpill_N2_to_N2) {
+ Vector<std::string, 2> vec_a{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 2> vec_b;
+ vec_b = std::move(ref);
+ EXPECT_EQ(vec_b.Length(), 2u);
+ EXPECT_EQ(vec_b.Capacity(), 2u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_TRUE(AllInternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, MoveAssignRef_WithSpill_N2_to_N2) {
+ Vector<std::string, 2> vec_a{"hello", "world", "spill"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 2> vec_b;
+ vec_b = std::move(ref);
+ EXPECT_EQ(vec_b.Length(), 3u);
+ EXPECT_EQ(vec_b.Capacity(), 3u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_EQ(vec_b[2], "spill");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, MoveAssignRef_NoSpill_N2_to_N1) {
+ Vector<std::string, 2> vec_a{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 1> vec_b;
+ vec_b = std::move(ref);
+ EXPECT_EQ(vec_b.Length(), 2u);
+ EXPECT_EQ(vec_b.Capacity(), 2u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, MoveAssignRef_SpillSpill_N2_to_N1) {
+ Vector<std::string, 2> vec_a{"hello", "world", "spill"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 1> vec_b;
+ vec_b = std::move(ref);
+ EXPECT_EQ(vec_b.Length(), 3u);
+ EXPECT_EQ(vec_b.Capacity(), 3u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_EQ(vec_b[2], "spill");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, MoveAssignRef_NoSpill_N2_to_N3) {
+ Vector<std::string, 2> vec_a{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 3> vec_b;
+ vec_b = std::move(ref);
+ EXPECT_EQ(vec_b.Length(), 2u);
+ EXPECT_EQ(vec_b.Capacity(), 3u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_TRUE(AllInternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, MoveAssignRef_WithSpill_N2_to_N3) {
+ Vector<std::string, 2> vec_a{"hello", "world", "spill"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 3> vec_b;
+ vec_b = std::move(ref);
+ EXPECT_EQ(vec_b.Length(), 3u);
+ EXPECT_EQ(vec_b.Capacity(), 3u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_EQ(vec_b[2], "spill");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, MoveAssignRef_NoSpill_N2_to_N0) {
+ Vector<std::string, 2> vec_a{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 0> vec_b;
+ vec_b = std::move(ref);
+ EXPECT_EQ(vec_b.Length(), 2u);
+ EXPECT_EQ(vec_b.Capacity(), 2u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, MoveAssignRef_WithSpill_N2_to_N0) {
+ Vector<std::string, 2> vec_a{"hello", "world", "spill"};
+ VectorRef<std::string> ref{std::move(vec_a)};
+ Vector<std::string, 0> vec_b;
+ vec_b = std::move(ref);
+ EXPECT_EQ(vec_b.Length(), 3u);
+ EXPECT_EQ(vec_b.Capacity(), 3u);
+ EXPECT_EQ(vec_b[0], "hello");
+ EXPECT_EQ(vec_b[1], "world");
+ EXPECT_EQ(vec_b[2], "spill");
+ EXPECT_TRUE(AllExternallyHeld(vec_b));
+}
+
+TEST(TintVectorTest, MoveAssignRef_Self_NoSpill) {
+ Vector<std::string, 2> vec{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec)};
+ vec = std::move(ref);
+ EXPECT_EQ(vec.Length(), 2u);
+ EXPECT_EQ(vec.Capacity(), 2u);
+ EXPECT_EQ(vec[0], "hello");
+ EXPECT_EQ(vec[1], "world");
+ EXPECT_TRUE(AllInternallyHeld(vec));
+}
+
+TEST(TintVectorTest, MoveAssignRef_Self_WithSpill) {
+ Vector<std::string, 1> vec{"hello", "world"};
+ VectorRef<std::string> ref{std::move(vec)};
+ vec = std::move(ref);
+ EXPECT_EQ(vec.Length(), 2u);
+ EXPECT_EQ(vec.Capacity(), 2u);
+ EXPECT_EQ(vec[0], "hello");
+ EXPECT_EQ(vec[1], "world");
+ EXPECT_TRUE(AllExternallyHeld(vec));
+}
+
+TEST(TintVectorTest, RepeatMoveAssignRef_NoSpill) {
+ Vector<std::string, 3> vec_a{"hello", "world"};
+ Vector<std::string, 3> vec_b{"Ciao", "mondo"};
+ Vector<std::string, 3> vec_c{"Bonjour", "le", "monde"};
+ VectorRef<std::string> ref_a{std::move(vec_a)};
+ VectorRef<std::string> ref_b{std::move(vec_b)};
+ VectorRef<std::string> ref_c{std::move(vec_c)};
+ Vector<std::string, 3> vec;
+ vec = std::move(ref_a);
+ vec = std::move(ref_b);
+ vec = std::move(ref_c);
+ EXPECT_EQ(vec.Length(), 3u);
+ EXPECT_EQ(vec.Capacity(), 3u);
+ EXPECT_EQ(vec[0], "Bonjour");
+ EXPECT_EQ(vec[1], "le");
+ EXPECT_EQ(vec[2], "monde");
+ EXPECT_TRUE(AllInternallyHeld(vec));
+}
+
+TEST(TintVectorTest, RepeatMoveAssignRef_WithSpill) {
+ Vector<std::string, 1> vec_a{"hello", "world"};
+ Vector<std::string, 1> vec_b{"Ciao", "mondo"};
+ Vector<std::string, 1> vec_c{"bonjour", "le", "monde"};
+ VectorRef<std::string> ref_a{std::move(vec_a)};
+ VectorRef<std::string> ref_b{std::move(vec_b)};
+ VectorRef<std::string> ref_c{std::move(vec_c)};
+ Vector<std::string, 1> vec;
+ vec = std::move(ref_a);
+ vec = std::move(ref_b);
+ vec = std::move(ref_c);
+ EXPECT_EQ(vec.Length(), 3u);
+ EXPECT_EQ(vec.Capacity(), 3u);
+ EXPECT_EQ(vec[0], "bonjour");
+ EXPECT_EQ(vec[1], "le");
+ EXPECT_EQ(vec[2], "monde");
+ EXPECT_TRUE(AllExternallyHeld(vec));
+}
+
TEST(TintVectorTest, Index) {
Vector<std::string, 2> vec{"hello", "world"};
static_assert(!std::is_const_v<std::remove_reference_t<decltype(vec[0])>>);
@@ -1684,7 +1989,7 @@
TEST(TintVectorRefTest, Index) {
Vector<std::string, 2> vec{"one", "two"};
VectorRef<std::string> vec_ref(vec);
- static_assert(!std::is_const_v<std::remove_reference_t<decltype(vec_ref[0])>>);
+ static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref[0])>>);
EXPECT_EQ(vec_ref[0], "one");
EXPECT_EQ(vec_ref[1], "two");
}
@@ -1755,206 +2060,6 @@
EXPECT_EQ(vec_ref.end(), &vec[0] + 3);
}
-////////////////////////////////////////////////////////////////////////////////
-// TintVectorConstRefTest
-////////////////////////////////////////////////////////////////////////////////
-TEST(TintVectorConstRefTest, CopyVectorConstRef) {
- Vector<std::string, 1> vec_a{"one", "two"};
- ConstVectorRef<std::string> vec_ref_a(vec_a);
- ConstVectorRef<std::string> vec_ref_b(vec_ref_a);
- Vector<std::string, 2> vec_b(vec_ref_b);
- EXPECT_EQ(vec_b[0], "one");
- EXPECT_EQ(vec_b[1], "two");
- EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
-}
-
-TEST(TintVectorConstRefTest, CopyVectorConstRef_Upcast) {
- C2a c2a;
- C2b c2b;
- Vector<C1*, 1> vec_a{&c2a, &c2b};
- ConstVectorRef<C1*> vec_ref_a(vec_a);
- ConstVectorRef<C0*> vec_ref_b(vec_ref_a); // Up-cast
- Vector<C0*, 2> vec_b(vec_ref_b);
- EXPECT_EQ(vec_b[0], &c2a);
- EXPECT_EQ(vec_b[1], &c2b);
- EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
-}
-
-TEST(TintVectorConstRefTest, CopyVectorConstRef_AddConst) {
- C2a c2a;
- C2b c2b;
- Vector<C1*, 1> vec_a{&c2a, &c2b};
- ConstVectorRef<C1*> vec_ref_a(vec_a);
- ConstVectorRef<const C1*> vec_ref_b(vec_ref_a); // Up-cast
- Vector<const C1*, 2> vec_b(vec_ref_b);
- EXPECT_EQ(vec_b[0], &c2a);
- EXPECT_EQ(vec_b[1], &c2b);
- EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
-}
-
-TEST(TintVectorConstRefTest, CopyVectorConstRef_UpcastAndAddConst) {
- C2a c2a;
- C2b c2b;
- Vector<C1*, 1> vec_a{&c2a, &c2b};
- ConstVectorRef<C1*> vec_ref_a(vec_a);
- ConstVectorRef<const C0*> vec_ref_b(vec_ref_a); // Up-cast
- Vector<const C0*, 2> vec_b(vec_ref_b);
- EXPECT_EQ(vec_b[0], &c2a);
- EXPECT_EQ(vec_b[1], &c2b);
- EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
-}
-
-TEST(TintVectorConstRefTest, CopyVector) {
- Vector<std::string, 1> vec_a{"one", "two"};
- ConstVectorRef<std::string> vec_ref(vec_a);
- Vector<std::string, 2> vec_b(vec_ref);
- EXPECT_EQ(vec_b[0], "one");
- EXPECT_EQ(vec_b[1], "two");
- EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
-}
-
-TEST(TintVectorConstRefTest, CopyVector_Upcast) {
- C2a c2a;
- C2b c2b;
- Vector<C1*, 1> vec_a{&c2a, &c2b};
- ConstVectorRef<C0*> vec_ref(vec_a);
- EXPECT_EQ(vec_ref[0], &c2a);
- EXPECT_EQ(vec_ref[1], &c2b);
- Vector<C0*, 2> vec_b(vec_ref);
- EXPECT_EQ(vec_b[0], &c2a);
- EXPECT_EQ(vec_b[1], &c2b);
- EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
-}
-
-TEST(TintVectorConstRefTest, CopyVector_AddConst) {
- C2a c2a;
- C2b c2b;
- Vector<C1*, 1> vec_a{&c2a, &c2b};
- ConstVectorRef<const C1*> vec_ref(vec_a);
- EXPECT_EQ(vec_ref[0], &c2a);
- EXPECT_EQ(vec_ref[1], &c2b);
- Vector<const C1*, 2> vec_b(vec_ref);
- EXPECT_EQ(vec_b[0], &c2a);
- EXPECT_EQ(vec_b[1], &c2b);
- EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
-}
-
-TEST(TintVectorConstRefTest, CopyVectorRef_Upcast) {
- C2a c2a;
- C2b c2b;
- Vector<C1*, 1> vec_a{&c2a, &c2b};
- VectorRef<C1*> vec_ref_a(vec_a);
- ConstVectorRef<C0*> vec_ref_b(vec_ref_a);
- EXPECT_EQ(vec_ref_b[0], &c2a);
- EXPECT_EQ(vec_ref_b[1], &c2b);
- Vector<C0*, 2> vec_b(vec_ref_b);
- EXPECT_EQ(vec_b[0], &c2a);
- EXPECT_EQ(vec_b[1], &c2b);
- EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
-}
-
-TEST(TintVectorConstRefTest, CopyVectorRef_AddConst) {
- C2a c2a;
- C2b c2b;
- Vector<C1*, 1> vec_a{&c2a, &c2b};
- VectorRef<C1*> vec_ref_a(vec_a);
- ConstVectorRef<const C1*> vec_ref_b(vec_ref_a);
- EXPECT_EQ(vec_ref_b[0], &c2a);
- EXPECT_EQ(vec_ref_b[1], &c2b);
- Vector<const C1*, 2> vec_b(vec_ref_b);
- EXPECT_EQ(vec_b[0], &c2a);
- EXPECT_EQ(vec_b[1], &c2b);
- EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
-}
-
-TEST(TintVectorConstRefTest, CopyVectorRef_UpcastAndAddConst) {
- C2a c2a;
- C2b c2b;
- Vector<C1*, 1> vec_a{&c2a, &c2b};
- VectorRef<C1*> vec_ref_a(vec_a);
- ConstVectorRef<const C0*> vec_ref_b(vec_ref_a);
- EXPECT_EQ(vec_ref_b[0], &c2a);
- EXPECT_EQ(vec_ref_b[1], &c2b);
- Vector<const C0*, 2> vec_b(vec_ref_b);
- EXPECT_EQ(vec_b[0], &c2a);
- EXPECT_EQ(vec_b[1], &c2b);
- EXPECT_TRUE(AllInternallyHeld(vec_b)); // Copied, not moved
-}
-
-TEST(TintVectorConstRefTest, Index) {
- Vector<std::string, 2> vec{"one", "two"};
- ConstVectorRef<std::string> vec_ref(vec);
- static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref[0])>>);
- EXPECT_EQ(vec_ref[0], "one");
- EXPECT_EQ(vec_ref[1], "two");
-}
-
-TEST(TintVectorConstRefTest, ConstIndex) {
- Vector<std::string, 2> vec{"one", "two"};
- const ConstVectorRef<std::string> vec_ref(vec);
- static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref[0])>>);
- EXPECT_EQ(vec_ref[0], "one");
- EXPECT_EQ(vec_ref[1], "two");
-}
-
-TEST(TintVectorConstRefTest, Length) {
- Vector<std::string, 2> vec{"one", "two", "three"};
- ConstVectorRef<std::string> vec_ref(vec);
- EXPECT_EQ(vec_ref.Length(), 3u);
-}
-
-TEST(TintVectorConstRefTest, Capacity) {
- Vector<std::string, 5> vec{"one", "two", "three"};
- ConstVectorRef<std::string> vec_ref(vec);
- EXPECT_EQ(vec_ref.Capacity(), 5u);
-}
-
-TEST(TintVectorConstRefTest, IsEmpty) {
- Vector<std::string, 1> vec;
- ConstVectorRef<std::string> vec_ref(vec);
- EXPECT_TRUE(vec_ref.IsEmpty());
- vec.Push("one");
- EXPECT_FALSE(vec_ref.IsEmpty());
- vec.Pop();
- EXPECT_TRUE(vec_ref.IsEmpty());
-}
-
-TEST(TintVectorConstRefTest, FrontBack) {
- Vector<std::string, 3> vec{"front", "mid", "back"};
- ConstVectorRef<std::string> vec_ref(vec);
- static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref.Front())>>);
- static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref.Back())>>);
- EXPECT_EQ(vec_ref.Front(), "front");
- EXPECT_EQ(vec_ref.Back(), "back");
-}
-
-TEST(TintVectorConstRefTest, ConstFrontBack) {
- Vector<std::string, 3> vec{"front", "mid", "back"};
- const ConstVectorRef<std::string> vec_ref(vec);
- static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref.Front())>>);
- static_assert(std::is_const_v<std::remove_reference_t<decltype(vec_ref.Back())>>);
- EXPECT_EQ(vec_ref.Front(), "front");
- EXPECT_EQ(vec_ref.Back(), "back");
-}
-
-TEST(TintVectorConstRefTest, BeginEnd) {
- Vector<std::string, 3> vec{"front", "mid", "back"};
- ConstVectorRef<std::string> vec_ref(vec);
- static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec_ref.begin())>>);
- static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec_ref.end())>>);
- EXPECT_EQ(vec_ref.begin(), &vec[0]);
- EXPECT_EQ(vec_ref.end(), &vec[0] + 3);
-}
-
-TEST(TintVectorConstRefTest, ConstBeginEnd) {
- Vector<std::string, 3> vec{"front", "mid", "back"};
- const ConstVectorRef<std::string> vec_ref(vec);
- static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec_ref.begin())>>);
- static_assert(std::is_const_v<std::remove_reference_t<decltype(*vec_ref.end())>>);
- EXPECT_EQ(vec_ref.begin(), &vec[0]);
- EXPECT_EQ(vec_ref.end(), &vec[0] + 3);
-}
-
} // namespace
} // namespace tint::utils
diff --git a/src/tint/val/hlsl.cc b/src/tint/val/hlsl.cc
index f1cfb05..eabbe68 100644
--- a/src/tint/val/hlsl.cc
+++ b/src/tint/val/hlsl.cc
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <string>
+
#include "src/tint/val/val.h"
#include "src/tint/utils/io/command.h"
@@ -31,7 +33,8 @@
Result HlslUsingDXC(const std::string& dxc_path,
const std::string& source,
- const EntryPointList& entry_points) {
+ const EntryPointList& entry_points,
+ bool require_16bit_types) {
Result result;
auto dxc = utils::Command(dxc_path);
@@ -41,11 +44,14 @@
return result;
}
+ // Native 16-bit types, e.g. float16_t, require SM6.2. Otherwise we use SM6.0.
+ const char* shader_model_version = require_16bit_types ? "6_2" : "6_0";
+
utils::TmpFile file;
file << source;
for (auto ep : entry_points) {
- const char* profile = "";
+ const char* stage_prefix = "";
switch (ep.second) {
case ast::PipelineStage::kNone:
@@ -53,24 +59,26 @@
result.failed = true;
return result;
case ast::PipelineStage::kVertex:
- profile = "-T vs_6_0";
+ stage_prefix = "vs";
break;
case ast::PipelineStage::kFragment:
- profile = "-T ps_6_0";
+ stage_prefix = "ps";
break;
case ast::PipelineStage::kCompute:
- profile = "-T cs_6_0";
+ stage_prefix = "cs";
break;
}
// Match Dawn's compile flags
// See dawn\src\dawn_native\d3d12\RenderPipelineD3D12.cpp
// and dawn_native\d3d12\ShaderModuleD3D12.cpp (GetDXCArguments)
- auto res = dxc(profile,
- "-E " + ep.first, // Entry point
- "/Zpr", // D3DCOMPILE_PACK_MATRIX_ROW_MAJOR
- "/Gis", // D3DCOMPILE_IEEE_STRICTNESS
- file.Path());
+ auto res = dxc(
+ "-T " + std::string(stage_prefix) + "_" + std::string(shader_model_version), // Profile
+ "-E " + ep.first, // Entry point
+ "/Zpr", // D3DCOMPILE_PACK_MATRIX_ROW_MAJOR
+ "/Gis", // D3DCOMPILE_IEEE_STRICTNESS
+ require_16bit_types ? "-enable-16bit-types" : "", // Enable 16-bit if required
+ file.Path());
if (!res.out.empty()) {
if (!result.output.empty()) {
result.output += "\n";
diff --git a/src/tint/val/val.h b/src/tint/val/val.h
index dae6fca..02ffc78 100644
--- a/src/tint/val/val.h
+++ b/src/tint/val/val.h
@@ -49,7 +49,8 @@
/// @return the result of the compile
Result HlslUsingDXC(const std::string& dxc_path,
const std::string& source,
- const EntryPointList& entry_points);
+ const EntryPointList& entry_points,
+ bool require_16bit_types);
#ifdef _WIN32
/// Hlsl attempts to compile the shader with FXC, verifying that the shader
diff --git a/src/tint/writer/append_vector.cc b/src/tint/writer/append_vector.cc
index d6eb017..527560e 100644
--- a/src/tint/writer/append_vector.cc
+++ b/src/tint/writer/append_vector.cc
@@ -150,9 +150,8 @@
}
auto* constructor_ast = b->Construct(
- packed_ast_ty, utils::ToStdVector(utils::Transform(packed, [&](const sem::Expression* expr) {
- return expr->Declaration();
- })));
+ packed_ast_ty,
+ utils::Transform(packed, [&](const sem::Expression* expr) { return expr->Declaration(); }));
auto* constructor_target = b->create<sem::TypeConstructor>(
packed_sem_ty,
utils::Transform(packed,
diff --git a/src/tint/writer/append_vector_test.cc b/src/tint/writer/append_vector_test.cc
index b4ab0c7..a8608f9 100644
--- a/src/tint/writer/append_vector_test.cc
+++ b/src/tint/writer/append_vector_test.cc
@@ -41,7 +41,7 @@
auto* vec_123 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_123, nullptr);
- ASSERT_EQ(vec_123->args.size(), 3u);
+ ASSERT_EQ(vec_123->args.Length(), 3u);
EXPECT_EQ(vec_123->args[0], scalar_1);
EXPECT_EQ(vec_123->args[1], scalar_2);
EXPECT_EQ(vec_123->args[2], scalar_3);
@@ -81,13 +81,13 @@
auto* vec_123 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_123, nullptr);
- ASSERT_EQ(vec_123->args.size(), 3u);
+ ASSERT_EQ(vec_123->args.Length(), 3u);
EXPECT_EQ(vec_123->args[0], scalar_1);
EXPECT_EQ(vec_123->args[1], scalar_2);
auto* u32_to_i32 = vec_123->args[2]->As<ast::CallExpression>();
ASSERT_NE(u32_to_i32, nullptr);
EXPECT_TRUE(u32_to_i32->target.type->Is<ast::I32>());
- ASSERT_EQ(u32_to_i32->args.size(), 1u);
+ ASSERT_EQ(u32_to_i32->args.Length(), 1u);
EXPECT_EQ(u32_to_i32->args[0], scalar_3);
auto* call = Sem().Get<sem::Call>(vec_123);
@@ -127,19 +127,19 @@
auto* vec_123 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_123, nullptr);
- ASSERT_EQ(vec_123->args.size(), 2u);
+ ASSERT_EQ(vec_123->args.Length(), 2u);
auto* v2u32_to_v2i32 = vec_123->args[0]->As<ast::CallExpression>();
ASSERT_NE(v2u32_to_v2i32, nullptr);
ASSERT_TRUE(v2u32_to_v2i32->target.type->Is<ast::Vector>());
EXPECT_EQ(v2u32_to_v2i32->target.type->As<ast::Vector>()->width, 2u);
EXPECT_TRUE(v2u32_to_v2i32->target.type->As<ast::Vector>()->type->Is<ast::I32>());
- EXPECT_EQ(v2u32_to_v2i32->args.size(), 1u);
+ EXPECT_EQ(v2u32_to_v2i32->args.Length(), 1u);
EXPECT_EQ(v2u32_to_v2i32->args[0], uvec_12);
auto* u32_to_i32 = vec_123->args[1]->As<ast::CallExpression>();
ASSERT_NE(u32_to_i32, nullptr);
EXPECT_TRUE(u32_to_i32->target.type->Is<ast::I32>());
- ASSERT_EQ(u32_to_i32->args.size(), 1u);
+ ASSERT_EQ(u32_to_i32->args.Length(), 1u);
EXPECT_EQ(u32_to_i32->args[0], scalar_3);
auto* call = Sem().Get<sem::Call>(vec_123);
@@ -175,13 +175,13 @@
auto* vec_123 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_123, nullptr);
- ASSERT_EQ(vec_123->args.size(), 3u);
+ ASSERT_EQ(vec_123->args.Length(), 3u);
EXPECT_EQ(vec_123->args[0], scalar_1);
EXPECT_EQ(vec_123->args[1], scalar_2);
auto* f32_to_i32 = vec_123->args[2]->As<ast::CallExpression>();
ASSERT_NE(f32_to_i32, nullptr);
EXPECT_TRUE(f32_to_i32->target.type->Is<ast::I32>());
- ASSERT_EQ(f32_to_i32->args.size(), 1u);
+ ASSERT_EQ(f32_to_i32->args.Length(), 1u);
EXPECT_EQ(f32_to_i32->args[0], scalar_3);
auto* call = Sem().Get<sem::Call>(vec_123);
@@ -220,7 +220,7 @@
auto* vec_1234 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_1234, nullptr);
- ASSERT_EQ(vec_1234->args.size(), 4u);
+ ASSERT_EQ(vec_1234->args.Length(), 4u);
EXPECT_EQ(vec_1234->args[0], scalar_1);
EXPECT_EQ(vec_1234->args[1], scalar_2);
EXPECT_EQ(vec_1234->args[2], scalar_3);
@@ -262,7 +262,7 @@
auto* vec_123 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_123, nullptr);
- ASSERT_EQ(vec_123->args.size(), 2u);
+ ASSERT_EQ(vec_123->args.Length(), 2u);
EXPECT_EQ(vec_123->args[0], vec_12);
EXPECT_EQ(vec_123->args[1], scalar_3);
@@ -300,7 +300,7 @@
auto* vec_123 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_123, nullptr);
- ASSERT_EQ(vec_123->args.size(), 3u);
+ ASSERT_EQ(vec_123->args.Length(), 3u);
EXPECT_EQ(vec_123->args[0], scalar_1);
EXPECT_EQ(vec_123->args[1], scalar_2);
EXPECT_EQ(vec_123->args[2], scalar_3);
@@ -340,7 +340,7 @@
auto* vec_123 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_123, nullptr);
- ASSERT_EQ(vec_123->args.size(), 2u);
+ ASSERT_EQ(vec_123->args.Length(), 2u);
EXPECT_EQ(vec_123->args[0], vec_12);
EXPECT_EQ(vec_123->args[1], scalar_3);
@@ -377,12 +377,12 @@
auto* vec_123 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_123, nullptr);
- ASSERT_EQ(vec_123->args.size(), 2u);
+ ASSERT_EQ(vec_123->args.Length(), 2u);
EXPECT_EQ(vec_123->args[0], vec_12);
auto* f32_to_i32 = vec_123->args[1]->As<ast::CallExpression>();
ASSERT_NE(f32_to_i32, nullptr);
EXPECT_TRUE(f32_to_i32->target.type->Is<ast::I32>());
- ASSERT_EQ(f32_to_i32->args.size(), 1u);
+ ASSERT_EQ(f32_to_i32->args.Length(), 1u);
EXPECT_EQ(f32_to_i32->args[0], scalar_3);
auto* call = Sem().Get<sem::Call>(vec_123);
@@ -418,7 +418,7 @@
auto* vec_123 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_123, nullptr);
- ASSERT_EQ(vec_123->args.size(), 2u);
+ ASSERT_EQ(vec_123->args.Length(), 2u);
EXPECT_EQ(vec_123->args[0], vec_12);
EXPECT_EQ(vec_123->args[1], scalar_3);
@@ -453,7 +453,7 @@
auto* vec_0004 = As<ast::CallExpression>(append->Declaration());
ASSERT_NE(vec_0004, nullptr);
- ASSERT_EQ(vec_0004->args.size(), 4u);
+ ASSERT_EQ(vec_0004->args.Length(), 4u);
for (size_t i = 0; i < 3; i++) {
auto* literal = As<ast::IntLiteralExpression>(vec_0004->args[i]);
ASSERT_NE(literal, nullptr);
diff --git a/src/tint/writer/flatten_bindings_test.cc b/src/tint/writer/flatten_bindings_test.cc
index ae01abd..be5fb42 100644
--- a/src/tint/writer/flatten_bindings_test.cc
+++ b/src/tint/writer/flatten_bindings_test.cc
@@ -28,7 +28,6 @@
TEST_F(FlattenBindingsTest, NoBindings) {
ProgramBuilder b;
- b.WrapInFunction();
resolver::Resolver resolver(&b);
@@ -44,7 +43,6 @@
b.GlobalVar("a", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
b.GlobalVar("b", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 1));
b.GlobalVar("c", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 2));
- b.WrapInFunction();
resolver::Resolver resolver(&b);
diff --git a/src/tint/writer/generate_external_texture_bindings_test.cc b/src/tint/writer/generate_external_texture_bindings_test.cc
index 292b2ea..ee3fc47 100644
--- a/src/tint/writer/generate_external_texture_bindings_test.cc
+++ b/src/tint/writer/generate_external_texture_bindings_test.cc
@@ -27,7 +27,6 @@
TEST_F(GenerateExternalTextureBindingsTest, None) {
ProgramBuilder b;
- b.WrapInFunction();
tint::Program program(std::move(b));
ASSERT_TRUE(program.IsValid());
@@ -38,7 +37,6 @@
TEST_F(GenerateExternalTextureBindingsTest, One) {
ProgramBuilder b;
b.GlobalVar("v0", b.ty.external_texture(), b.GroupAndBinding(0, 0));
- b.WrapInFunction();
tint::Program program(std::move(b));
ASSERT_TRUE(program.IsValid());
@@ -56,7 +54,6 @@
ProgramBuilder b;
b.GlobalVar("v0", b.ty.external_texture(), b.GroupAndBinding(0, 0));
b.GlobalVar("v1", b.ty.external_texture(), b.GroupAndBinding(0, 1));
- b.WrapInFunction();
tint::Program program(std::move(b));
ASSERT_TRUE(program.IsValid());
@@ -80,7 +77,6 @@
ProgramBuilder b;
b.GlobalVar("v0", b.ty.external_texture(), b.GroupAndBinding(0, 0));
b.GlobalVar("v1", b.ty.external_texture(), b.GroupAndBinding(1, 0));
- b.WrapInFunction();
tint::Program program(std::move(b));
ASSERT_TRUE(program.IsValid());
@@ -107,7 +103,6 @@
b.GlobalVar("v2", b.ty.i32(), b.GroupAndBinding(0, 2), kUniform);
b.GlobalVar("v3", b.ty.external_texture(), b.GroupAndBinding(0, 3));
b.GlobalVar("v4", b.ty.i32(), b.GroupAndBinding(0, 4), kUniform);
- b.WrapInFunction();
tint::Program program(std::move(b));
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index 4c513be..c66e174 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -70,6 +70,7 @@
#include "src/tint/utils/defer.h"
#include "src/tint/utils/map.h"
#include "src/tint/utils/scoped_assignment.h"
+#include "src/tint/utils/string.h"
#include "src/tint/writer/append_vector.h"
#include "src/tint/writer/float_to_string.h"
#include "src/tint/writer/generate_external_texture_bindings.h"
@@ -272,8 +273,8 @@
auto* mod = builder_.Sem().Module();
for (auto* decl : mod->DependencyOrderedDeclarations()) {
- if (decl->Is<ast::Alias>()) {
- continue; // Ignore aliases.
+ if (decl->IsAnyOf<ast::Alias, ast::StaticAssert>()) {
+ continue; // These are not emitted.
}
if (auto* global = decl->As<ast::Variable>()) {
@@ -686,7 +687,7 @@
return true;
}
-bool GeneratorImpl::EmitStatements(const ast::StatementList& stmts) {
+bool GeneratorImpl::EmitStatements(utils::VectorRef<const ast::Statement*> stmts) {
for (auto* s : stmts) {
if (!EmitStatement(s)) {
return false;
@@ -695,7 +696,7 @@
return true;
}
-bool GeneratorImpl::EmitStatementsWithIndent(const ast::StatementList& stmts) {
+bool GeneratorImpl::EmitStatementsWithIndent(utils::VectorRef<const ast::Statement*> stmts) {
ScopedIndent si(this);
return EmitStatements(stmts);
}
@@ -892,7 +893,7 @@
out << name;
{
ScopedParen sp(out);
- for (size_t i = 0; i < expr->args.size(); i++) {
+ for (size_t i = 0; i < expr->args.Length(); i++) {
auto* arg = expr->args[i];
if (i > 0) {
out << ", ";
@@ -1204,97 +1205,51 @@
bool GeneratorImpl::EmitModfCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Builtin* builtin) {
- if (expr->args.size() == 1) {
- return CallBuiltinHelper(
- out, expr, builtin, [&](TextBuffer* b, const std::vector<std::string>& params) {
- // Emit the builtin return type unique to this overload. This does not
- // exist in the AST, so it will not be generated in Generate().
- if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) {
+ TINT_ASSERT(Writer, expr->args.Length() == 1);
+ return CallBuiltinHelper(
+ out, expr, builtin, [&](TextBuffer* b, const std::vector<std::string>& params) {
+ // Emit the builtin return type unique to this overload. This does not
+ // exist in the AST, so it will not be generated in Generate().
+ if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) {
+ return false;
+ }
+
+ {
+ auto l = line(b);
+ if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
+ ast::Access::kUndefined, "")) {
return false;
}
-
- {
- auto l = line(b);
- if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
- ast::Access::kUndefined, "")) {
- return false;
- }
- l << " result;";
- }
- line(b) << "result.fract = modf(" << params[0] << ", result.whole);";
- line(b) << "return result;";
- return true;
- });
- }
-
- // DEPRECATED
- out << "modf";
- ScopedParen sp(out);
- if (!EmitExpression(out, expr->args[0])) {
- return false;
- }
- out << ", ";
- if (!EmitExpression(out, expr->args[1])) {
- return false;
- }
- return true;
+ l << " result;";
+ }
+ line(b) << "result.fract = modf(" << params[0] << ", result.whole);";
+ line(b) << "return result;";
+ return true;
+ });
}
bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Builtin* builtin) {
- if (expr->args.size() == 1) {
- return CallBuiltinHelper(
- out, expr, builtin, [&](TextBuffer* b, const std::vector<std::string>& params) {
- // Emit the builtin return type unique to this overload. This does not
- // exist in the AST, so it will not be generated in Generate().
- if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) {
- return false;
- }
-
- {
- auto l = line(b);
- if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
- ast::Access::kUndefined, "")) {
- return false;
- }
- l << " result;";
- }
- line(b) << "result.sig = frexp(" << params[0] << ", result.exp);";
- line(b) << "return result;";
- return true;
- });
- }
- // DEPRECATED
- // Exponent is an integer in WGSL, but HLSL wants a float.
- // We need to make the call with a temporary float, and then cast.
+ TINT_ASSERT(Writer, expr->args.Length() == 1);
return CallBuiltinHelper(
out, expr, builtin, [&](TextBuffer* b, const std::vector<std::string>& params) {
- auto* significand_ty = builtin->Parameters()[0]->Type();
- auto significand = params[0];
- auto* exponent_ty = builtin->Parameters()[1]->Type();
- auto exponent = params[1];
-
- std::string width;
- if (auto* vec = significand_ty->As<sem::Vector>()) {
- width = std::to_string(vec->Width());
+ // Emit the builtin return type unique to this overload. This does not
+ // exist in the AST, so it will not be generated in Generate().
+ if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) {
+ return false;
}
- // Exponent is an integer, which HLSL does not have an overload for.
- // We need to cast from a float.
- line(b) << "float" << width << " float_exp;";
- line(b) << "float" << width << " significand = frexp(" << significand
- << ", float_exp);";
{
auto l = line(b);
- l << exponent << " = ";
- if (!EmitType(l, exponent_ty->UnwrapPtr(), ast::StorageClass::kNone,
+ if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
ast::Access::kUndefined, "")) {
return false;
}
- l << "(float_exp);";
+ l << " result;";
}
- line(b) << "return significand;";
+ line(b) << "result.sig = frexp(" << params[0] << ", result.exp);";
+ line(b) << "return result;";
return true;
});
}
@@ -1745,7 +1700,7 @@
return false;
}
out << ":";
- if (selector == stmt->selectors.back()) {
+ if (selector == stmt->selectors.Back()) {
out << " {";
}
}
@@ -1846,7 +1801,7 @@
return false;
}
} else {
- if (!EmitStatementsWithIndent({stmt->else_statement})) {
+ if (!EmitStatementsWithIndent(utils::Vector{stmt->else_statement})) {
return false;
}
}
@@ -1936,6 +1891,11 @@
case ast::StorageClass::kIn:
case ast::StorageClass::kOut:
return EmitIOVariable(sem);
+ case ast::StorageClass::kPushConstant:
+ diagnostics_.add_error(
+ diag::System::Writer,
+ "unhandled storage class " + utils::ToString(sem->StorageClass()));
+ return false;
default: {
TINT_ICE(Writer, diagnostics_)
<< "unhandled storage class " << sem->StorageClass();
@@ -2096,8 +2056,9 @@
return true;
}
-void GeneratorImpl::EmitInterpolationQualifiers(std::ostream& out,
- const ast::AttributeList& attributes) {
+void GeneratorImpl::EmitInterpolationQualifiers(
+ std::ostream& out,
+ utils::VectorRef<const ast::Attribute*> attributes) {
for (auto* attr : attributes) {
if (auto* interpolate = attr->As<ast::InterpolateAttribute>()) {
switch (interpolate->type) {
@@ -2121,8 +2082,9 @@
}
}
-bool GeneratorImpl::EmitAttributes(std::ostream& out, const ast::AttributeList& attributes) {
- if (attributes.empty()) {
+bool GeneratorImpl::EmitAttributes(std::ostream& out,
+ utils::VectorRef<const ast::Attribute*> attributes) {
+ if (attributes.IsEmpty()) {
return true;
}
bool first = true;
@@ -2644,69 +2606,53 @@
}
bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) {
- if (auto* a = stmt->As<ast::AssignmentStatement>()) {
- return EmitAssign(a);
- }
- if (auto* b = stmt->As<ast::BlockStatement>()) {
- return EmitBlock(b);
- }
- if (auto* b = stmt->As<ast::BreakStatement>()) {
- return EmitBreak(b);
- }
- if (auto* c = stmt->As<ast::CallStatement>()) {
- auto out = line();
- if (!EmitCall(out, c->expr)) {
- return false;
- }
- out << ";";
- return true;
- }
- if (auto* c = stmt->As<ast::ContinueStatement>()) {
- return EmitContinue(c);
- }
- if (auto* d = stmt->As<ast::DiscardStatement>()) {
- return EmitDiscard(d);
- }
- if (stmt->As<ast::FallthroughStatement>()) {
- line() << "/* fallthrough */";
- return true;
- }
- if (auto* i = stmt->As<ast::IfStatement>()) {
- return EmitIf(i);
- }
- if (auto* l = stmt->As<ast::LoopStatement>()) {
- return EmitLoop(l);
- }
- if (auto* l = stmt->As<ast::ForLoopStatement>()) {
- return EmitForLoop(l);
- }
- if (auto* l = stmt->As<ast::WhileStatement>()) {
- return EmitWhile(l);
- }
- if (auto* r = stmt->As<ast::ReturnStatement>()) {
- return EmitReturn(r);
- }
- if (auto* s = stmt->As<ast::SwitchStatement>()) {
- return EmitSwitch(s);
- }
- if (auto* v = stmt->As<ast::VariableDeclStatement>()) {
- return Switch(
- v->variable, //
- [&](const ast::Var* var) { return EmitVar(var); },
- [&](const ast::Let* let) { return EmitLet(let); },
- [&](const ast::Const*) {
- return true; // Constants are embedded at their use
- },
- [&](Default) { //
- TINT_ICE(Writer, diagnostics_)
- << "unknown variable type: " << v->variable->TypeInfo().name;
+ return Switch(
+ stmt, //
+ [&](const ast::AssignmentStatement* a) { return EmitAssign(a); },
+ [&](const ast::BlockStatement* b) { return EmitBlock(b); },
+ [&](const ast::BreakStatement* b) { return EmitBreak(b); },
+ [&](const ast::CallStatement* c) {
+ auto out = line();
+ if (!EmitCall(out, c->expr)) {
return false;
- });
- }
-
- diagnostics_.add_error(diag::System::Writer,
- "unknown statement type: " + std::string(stmt->TypeInfo().name));
- return false;
+ }
+ out << ";";
+ return true;
+ },
+ [&](const ast::ContinueStatement* c) { return EmitContinue(c); },
+ [&](const ast::DiscardStatement* d) { return EmitDiscard(d); },
+ [&](const ast::FallthroughStatement*) {
+ line() << "/* fallthrough */";
+ return true;
+ },
+ [&](const ast::IfStatement* i) { return EmitIf(i); },
+ [&](const ast::LoopStatement* l) { return EmitLoop(l); },
+ [&](const ast::ForLoopStatement* l) { return EmitForLoop(l); },
+ [&](const ast::WhileStatement* l) { return EmitWhile(l); },
+ [&](const ast::ReturnStatement* r) { return EmitReturn(r); },
+ [&](const ast::SwitchStatement* s) { return EmitSwitch(s); },
+ [&](const ast::VariableDeclStatement* v) {
+ return Switch(
+ v->variable, //
+ [&](const ast::Var* var) { return EmitVar(var); },
+ [&](const ast::Let* let) { return EmitLet(let); },
+ [&](const ast::Const*) {
+ return true; // Constants are embedded at their use
+ },
+ [&](Default) { //
+ TINT_ICE(Writer, diagnostics_)
+ << "unknown variable type: " << v->variable->TypeInfo().name;
+ return false;
+ });
+ },
+ [&](const ast::StaticAssert*) {
+ return true; // Not emitted
+ },
+ [&](Default) {
+ diagnostics_.add_error(diag::System::Writer,
+ "unknown statement type: " + std::string(stmt->TypeInfo().name));
+ return false;
+ });
}
bool GeneratorImpl::EmitSwitch(const ast::SwitchStatement* stmt) {
diff --git a/src/tint/writer/glsl/generator_impl.h b/src/tint/writer/glsl/generator_impl.h
index 86be974..502df8b 100644
--- a/src/tint/writer/glsl/generator_impl.h
+++ b/src/tint/writer/glsl/generator_impl.h
@@ -126,11 +126,11 @@
/// Emits a list of statements
/// @param stmts the statement list
/// @returns true if the statements were emitted successfully
- bool EmitStatements(const ast::StatementList& stmts);
+ bool EmitStatements(utils::VectorRef<const ast::Statement*> stmts);
/// Emits a list of statements with an indentation
/// @param stmts the statement list
/// @returns true if the statements were emitted successfully
- bool EmitStatementsWithIndent(const ast::StatementList& stmts);
+ bool EmitStatementsWithIndent(utils::VectorRef<const ast::Statement*> stmts);
/// Handles a block statement
/// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully
@@ -329,12 +329,13 @@
/// Handles emitting interpolation qualifiers
/// @param out the output of the expression stream
/// @param attrs the attributes
- void EmitInterpolationQualifiers(std::ostream& out, const ast::AttributeList& attrs);
+ void EmitInterpolationQualifiers(std::ostream& out,
+ utils::VectorRef<const ast::Attribute*> attrs);
/// Handles emitting attributes
/// @param out the output of the expression stream
/// @param attrs the attributes
/// @returns true if the attributes were emitted
- bool EmitAttributes(std::ostream& out, const ast::AttributeList& attrs);
+ bool EmitAttributes(std::ostream& out, utils::VectorRef<const ast::Attribute*> attrs);
/// Handles emitting the entry point function
/// @param func the entry point
/// @returns true if the entry point function was emitted
diff --git a/src/tint/writer/glsl/generator_impl_binary_test.cc b/src/tint/writer/glsl/generator_impl_binary_test.cc
index c1a0fa9..2a4994a 100644
--- a/src/tint/writer/glsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/glsl/generator_impl_binary_test.cc
@@ -668,7 +668,7 @@
Block(Return(1_i)),
Else(If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("b"), Expr("c")),
Block(Return(2_i)), Else(Block(Return(3_i))))));
- Func("func", {}, ty.i32(), {WrapInStatement(expr)});
+ Func("func", utils::Empty, ty.i32(), utils::Vector{WrapInStatement(expr)});
GeneratorImpl& gen = Build();
@@ -704,7 +704,7 @@
ast::BinaryOp::kLogicalOr,
create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
Expr("c")));
- Func("func", {}, ty.bool_(), {WrapInStatement(expr)});
+ Func("func", utils::Empty, ty.bool_(), utils::Vector{WrapInStatement(expr)});
GeneratorImpl& gen = Build();
@@ -788,26 +788,25 @@
// foo(a && b, c || d, (a || c) && (b || d))
Func("foo",
- {
+ utils::Vector{
Param(Sym(), ty.bool_()),
Param(Sym(), ty.bool_()),
Param(Sym(), ty.bool_()),
},
- ty.void_(), ast::StatementList{}, ast::AttributeList{});
+ ty.void_(), utils::Empty, utils::Empty);
GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
- ast::ExpressionList params;
- params.push_back(
- create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")));
- params.push_back(
- create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("c"), Expr("d")));
- params.push_back(create<ast::BinaryExpression>(
- ast::BinaryOp::kLogicalAnd,
- create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("c")),
- create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("b"), Expr("d"))));
+ utils::Vector params{
+ create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
+ create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("c"), Expr("d")),
+ create<ast::BinaryExpression>(
+ ast::BinaryOp::kLogicalAnd,
+ create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("c")),
+ create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("b"), Expr("d"))),
+ };
auto* expr = CallStmt(Call("foo", params));
WrapInFunction(expr);
diff --git a/src/tint/writer/glsl/generator_impl_builtin_test.cc b/src/tint/writer/glsl/generator_impl_builtin_test.cc
index ad75046..b8161e2 100644
--- a/src/tint/writer/glsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/glsl/generator_impl_builtin_test.cc
@@ -214,8 +214,11 @@
auto* call = GenerateCall(param.builtin, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled builtin";
- Func("func", {}, ty.void_(), {CallStmt(call)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(call),
+ },
+ utils::Vector{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
GeneratorImpl& gen = Build();
@@ -409,7 +412,7 @@
EXPECT_EQ(out.str(), "((a) * (b) + (c))");
}
-TEST_F(GlslGeneratorImplTest_Builtin, Modf_Scalar) {
+TEST_F(GlslGeneratorImplTest_Builtin, Modf_Scalar_f32) {
auto* call = Call("modf", 1_f);
WrapInFunction(CallStmt(call));
@@ -442,7 +445,43 @@
)");
}
-TEST_F(GlslGeneratorImplTest_Builtin, Modf_Vector) {
+TEST_F(GlslGeneratorImplTest_Builtin, Modf_Scalar_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("modf", 1_h);
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+#extension GL_AMD_gpu_shader_half_float : require
+
+struct modf_result_f16 {
+ float16_t fract;
+ float16_t whole;
+};
+
+modf_result_f16 tint_modf(float16_t param_0) {
+ modf_result_f16 result;
+ result.fract = modf(param_0, result.whole);
+ return result;
+}
+
+
+void test_function() {
+ tint_modf(1.0hf);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ test_function();
+ return;
+}
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_Builtin, Modf_Vector_f32) {
auto* call = Call("modf", vec3<f32>());
WrapInFunction(CallStmt(call));
@@ -475,7 +514,43 @@
)");
}
-TEST_F(GlslGeneratorImplTest_Builtin, Frexp_Scalar_i32) {
+TEST_F(GlslGeneratorImplTest_Builtin, Modf_Vector_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("modf", vec3<f16>());
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+#extension GL_AMD_gpu_shader_half_float : require
+
+struct modf_result_vec3_f16 {
+ f16vec3 fract;
+ f16vec3 whole;
+};
+
+modf_result_vec3_f16 tint_modf(f16vec3 param_0) {
+ modf_result_vec3_f16 result;
+ result.fract = modf(param_0, result.whole);
+ return result;
+}
+
+
+void test_function() {
+ tint_modf(f16vec3(0.0hf));
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ test_function();
+ return;
+}
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_Builtin, Frexp_Scalar_f32) {
auto* call = Call("frexp", 1_f);
WrapInFunction(CallStmt(call));
@@ -502,7 +577,42 @@
)"));
}
-TEST_F(GlslGeneratorImplTest_Builtin, Frexp_Vector_i32) {
+TEST_F(GlslGeneratorImplTest_Builtin, Frexp_Scalar_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("frexp", 1_h);
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_THAT(gen.result(), HasSubstr(R"(#version 310 es
+#extension GL_AMD_gpu_shader_half_float : require
+
+struct frexp_result_f16 {
+ float16_t sig;
+ int exp;
+};
+
+frexp_result_f16 tint_frexp(float16_t param_0) {
+ frexp_result_f16 result;
+ result.sig = frexp(param_0, result.exp);
+ return result;
+}
+
+
+void test_function() {
+ tint_frexp(1.0hf);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ test_function();
+ return;
+)"));
+}
+
+TEST_F(GlslGeneratorImplTest_Builtin, Frexp_Vector_f32) {
auto* call = Call("frexp", vec3<f32>());
WrapInFunction(CallStmt(call));
@@ -534,6 +644,42 @@
)"));
}
+TEST_F(GlslGeneratorImplTest_Builtin, Frexp_Vector_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("frexp", vec3<f16>());
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_THAT(gen.result(), HasSubstr(R"(#version 310 es
+#extension GL_AMD_gpu_shader_half_float : require
+
+struct frexp_result_vec3_f16 {
+ f16vec3 sig;
+ ivec3 exp;
+};
+
+frexp_result_vec3_f16 tint_frexp(f16vec3 param_0) {
+ frexp_result_vec3_f16 result;
+ result.sig = frexp(param_0, result.exp);
+ return result;
+}
+
+
+void test_function() {
+ tint_frexp(f16vec3(0.0hf));
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ test_function();
+ return;
+}
+)"));
+}
+
TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Scalar_f32) {
auto* val = Var("val", ty.f32());
auto* call = Call("degrees", val);
@@ -1019,8 +1165,11 @@
}
TEST_F(GlslGeneratorImplTest_Builtin, StorageBarrier) {
- Func("main", {}, ty.void_(), {CallStmt(Call("storageBarrier"))},
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("storageBarrier")),
+ },
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -1039,8 +1188,11 @@
}
TEST_F(GlslGeneratorImplTest_Builtin, WorkgroupBarrier) {
- Func("main", {}, ty.void_(), {CallStmt(Call("workgroupBarrier"))},
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("workgroupBarrier")),
+ },
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/writer/glsl/generator_impl_builtin_texture_test.cc b/src/tint/writer/glsl/generator_impl_builtin_texture_test.cc
index 42db16b..8a22798 100644
--- a/src/tint/writer/glsl/generator_impl_builtin_texture_test.cc
+++ b/src/tint/writer/glsl/generator_impl_builtin_texture_test.cc
@@ -278,7 +278,8 @@
auto* call = Call(param.function, param.args(this));
auto* stmt = CallStmt(call);
- Func("main", {}, ty.void_(), {stmt}, {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(), utils::Vector{stmt},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/glsl/generator_impl_call_test.cc b/src/tint/writer/glsl/generator_impl_call_test.cc
index d1866ea..d264896 100644
--- a/src/tint/writer/glsl/generator_impl_call_test.cc
+++ b/src/tint/writer/glsl/generator_impl_call_test.cc
@@ -23,7 +23,7 @@
using GlslGeneratorImplTest_Call = TestHelper;
TEST_F(GlslGeneratorImplTest_Call, EmitExpression_Call_WithoutParams) {
- Func("my_func", {}, ty.f32(), {Return(1.23_f)});
+ Func("my_func", utils::Empty, ty.f32(), utils::Vector{Return(1.23_f)});
auto* call = Call("my_func");
WrapInFunction(call);
@@ -37,11 +37,11 @@
TEST_F(GlslGeneratorImplTest_Call, EmitExpression_Call_WithParams) {
Func("my_func",
- {
+ utils::Vector{
Param(Sym(), ty.f32()),
Param(Sym(), ty.f32()),
},
- ty.f32(), {Return(1.23_f)});
+ ty.f32(), utils::Vector{Return(1.23_f)});
GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
@@ -57,11 +57,11 @@
TEST_F(GlslGeneratorImplTest_Call, EmitStatement_Call) {
Func("my_func",
- {
+ utils::Vector{
Param(Sym(), ty.f32()),
Param(Sym(), ty.f32()),
},
- ty.void_(), ast::StatementList{}, ast::AttributeList{});
+ ty.void_(), utils::Empty, utils::Empty);
GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
diff --git a/src/tint/writer/glsl/generator_impl_case_test.cc b/src/tint/writer/glsl/generator_impl_case_test.cc
index 02d1665..1f60781 100644
--- a/src/tint/writer/glsl/generator_impl_case_test.cc
+++ b/src/tint/writer/glsl/generator_impl_case_test.cc
@@ -69,7 +69,13 @@
}
TEST_F(GlslGeneratorImplTest_Case, Emit_Case_MultipleSelectors) {
- auto* s = Switch(1_i, Case({Expr(5_i), Expr(6_i)}, Block(create<ast::BreakStatement>())),
+ auto* s = Switch(1_i,
+ Case(
+ utils::Vector{
+ Expr(5_i),
+ Expr(6_i),
+ },
+ Block(create<ast::BreakStatement>())),
DefaultCase());
WrapInFunction(s);
diff --git a/src/tint/writer/glsl/generator_impl_constructor_test.cc b/src/tint/writer/glsl/generator_impl_constructor_test.cc
index 20d6b07..5b65c2b 100644
--- a/src/tint/writer/glsl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_constructor_test.cc
@@ -396,7 +396,7 @@
}
TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct) {
- auto* str = Structure("S", {
+ auto* str = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
Member("c", ty.vec3<i32>()),
@@ -411,7 +411,7 @@
}
TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct_Empty) {
- auto* str = Structure("S", {
+ auto* str = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
Member("c", ty.vec3<i32>()),
diff --git a/src/tint/writer/glsl/generator_impl_function_test.cc b/src/tint/writer/glsl/generator_impl_function_test.cc
index d1f7a5e..cc01e5d 100644
--- a/src/tint/writer/glsl/generator_impl_function_test.cc
+++ b/src/tint/writer/glsl/generator_impl_function_test.cc
@@ -28,8 +28,8 @@
using GlslGeneratorImplTest_Function = TestHelper;
TEST_F(GlslGeneratorImplTest_Function, Emit_Function) {
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -48,8 +48,8 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Function_Name_Collision) {
- Func("centroid", {}, ty.void_(),
- {
+ Func("centroid", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -65,12 +65,12 @@
TEST_F(GlslGeneratorImplTest_Function, Emit_Function_WithParams) {
Func("my_func",
- {
+ utils::Vector{
Param("a", ty.f32()),
Param("b", ty.i32()),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
});
@@ -89,8 +89,8 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_NoReturn_Void) {
- Func("func", {}, ty.void_(), {/* no explicit return */},
- {
+ Func("func", utils::Empty, ty.void_(), utils::Empty /* no explicit return */,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -110,8 +110,8 @@
// fn f(foo : ptr<function, f32>) -> f32 {
// return *foo;
// }
- Func("f", {Param("foo", ty.pointer<f32>(ast::StorageClass::kFunction))}, ty.f32(),
- {Return(Deref("foo"))});
+ Func("f", utils::Vector{Param("foo", ty.pointer<f32>(ast::StorageClass::kFunction))}, ty.f32(),
+ utils::Vector{Return(Deref("foo"))});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -127,17 +127,17 @@
// return foo;
// }
Func("frag_main",
- {
- Param("foo", ty.f32(), {Location(0)}),
+ utils::Vector{
+ Param("foo", ty.f32(), utils::Vector{Location(0)}),
},
ty.f32(),
- {
+ utils::Vector{
Return("foo"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(1),
});
@@ -165,19 +165,20 @@
// fn frag_main(@position(0) coord : vec4<f32>) -> @frag_depth f32 {
// return coord.x;
// }
- auto* coord_in = Param("coord", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)});
+ auto* coord_in =
+ Param("coord", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)});
Func("frag_main",
- {
+ utils::Vector{
coord_in,
},
ty.f32(),
- {
+ utils::Vector{
Return(MemberAccessor("coord", "x")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Builtin(ast::BuiltinValue::kFragDepth),
});
@@ -214,24 +215,25 @@
// const p = inputs.pos;
// }
auto* interface_struct = Structure(
- "Interface", {
- Member("pos", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)}),
- Member("col1", ty.f32(), {Location(1)}),
- Member("col2", ty.f32(), {Location(2)}),
- });
+ "Interface",
+ utils::Vector{
+ Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
+ Member("col1", ty.f32(), utils::Vector{Location(1)}),
+ Member("col2", ty.f32(), utils::Vector{Location(2)}),
+ });
- Func("vert_main", {}, ty.Of(interface_struct),
- {Return(Construct(ty.Of(interface_struct), Construct(ty.vec4<f32>()), Expr(0.5_f),
- Expr(0.25_f)))},
- {Stage(ast::PipelineStage::kVertex)});
+ Func("vert_main", utils::Empty, ty.Of(interface_struct),
+ utils::Vector{Return(Construct(ty.Of(interface_struct), Construct(ty.vec4<f32>()),
+ Expr(0.5_f), Expr(0.25_f)))},
+ utils::Vector{Stage(ast::PipelineStage::kVertex)});
- Func("frag_main", {Param("inputs", ty.Of(interface_struct))}, ty.void_(),
- {
+ Func("frag_main", utils::Vector{Param("inputs", ty.Of(interface_struct))}, ty.void_(),
+ utils::Vector{
Decl(Let("r", ty.f32(), MemberAccessor("inputs", "col1"))),
Decl(Let("g", ty.f32(), MemberAccessor("inputs", "col2"))),
Decl(Let("p", ty.vec4<f32>(), MemberAccessor("inputs", "pos"))),
},
- {Stage(ast::PipelineStage::kFragment)});
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -297,17 +299,17 @@
"VertexOutput",
{Member("pos", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)})});
- Func("foo", {Param("x", ty.f32())}, ty.Of(vertex_output_struct),
+ Func("foo", utils::Vector{Param("x", ty.f32())}, ty.Of(vertex_output_struct),
{Return(Construct(ty.Of(vertex_output_struct),
Construct(ty.vec4<f32>(), "x", "x", "x", Expr(1_f))))},
{});
- Func("vert_main1", {}, ty.Of(vertex_output_struct),
+ Func("vert_main1", utils::Empty, ty.Of(vertex_output_struct),
{Return(Construct(ty.Of(vertex_output_struct),
Expr(Call("foo", Expr(0.5_f)))))},
{Stage(ast::PipelineStage::kVertex)});
- Func("vert_main2", {}, ty.Of(vertex_output_struct),
+ Func("vert_main2", utils::Empty, ty.Of(vertex_output_struct),
{Return(Construct(ty.Of(vertex_output_struct),
Expr(Call("foo", Expr(0.25_f)))))},
{Stage(ast::PipelineStage::kVertex)});
@@ -348,30 +350,30 @@
#endif
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_Uniform) {
- auto* ubo_ty = Structure("UBO", {Member("coord", ty.vec4<f32>())});
+ auto* ubo_ty = Structure("UBO", utils::Vector{Member("coord", ty.vec4<f32>())});
auto* ubo = GlobalVar("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
Func("sub_func",
- {
+ utils::Vector{
Param("param", ty.f32()),
},
ty.f32(),
- {
+ utils::Vector{
Return(MemberAccessor(MemberAccessor(ubo, "coord"), "x")),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -401,10 +403,10 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_UniformStruct) {
- auto* s = Structure("Uniforms", {Member("coord", ty.vec4<f32>())});
+ auto* s = Structure("Uniforms", utils::Vector{Member("coord", ty.vec4<f32>())});
GlobalVar("uniforms", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
@@ -412,12 +414,12 @@
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -443,25 +445,25 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_RW_StorageBuffer_Read) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -493,25 +495,25 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_RO_StorageBuffer_Read) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -544,23 +546,23 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_WO_StorageBuffer_Store) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -592,23 +594,23 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_StorageBuffer_Store) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -640,26 +642,26 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
- auto* s = Structure("S", {Member("x", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
- Func("sub_func", {Param("param", ty.f32())}, ty.f32(),
- {
+ Func("sub_func", utils::Vector{Param("param", ty.f32())}, ty.f32(),
+ utils::Vector{
Return(MemberAccessor("coord", "x")),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -689,26 +691,26 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_StorageBuffer) {
- auto* s = Structure("S", {Member("x", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
- Func("sub_func", {Param("param", ty.f32())}, ty.f32(),
- {
+ Func("sub_func", utils::Vector{Param("param", ty.f32())}, ty.f32(),
+ utils::Vector{
Return(MemberAccessor("coord", "x")),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -743,8 +745,8 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithNameCollision) {
- Func("centroid", {}, ty.void_(), {},
- {
+ Func("centroid", utils::Empty, ty.void_(), {},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -765,11 +767,11 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute) {
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -787,8 +789,8 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Literal) {
- Func("main", {}, ty.void_(), {},
- {
+ Func("main", utils::Empty, ty.void_(), {},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(2_i, 4_i, 6_i),
});
@@ -809,8 +811,8 @@
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
- Func("main", {}, ty.void_(), {},
- {
+ Func("main", utils::Empty, ty.void_(), {},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize("width", "height", "depth"),
});
@@ -829,11 +831,11 @@
TEST_F(GlslGeneratorImplTest_Function,
Emit_Attribute_EntryPoint_Compute_WithWorkgroup_OverridableConst) {
- Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
- Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
- Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
- Func("main", {}, ty.void_(), {},
- {
+ Override("width", ty.i32(), Construct(ty.i32(), 2_i), utils::Vector{Id(7u)});
+ Override("height", ty.i32(), Construct(ty.i32(), 3_i), utils::Vector{Id(8u)});
+ Override("depth", ty.i32(), Construct(ty.i32(), 4_i), utils::Vector{Id(9u)});
+ Func("main", utils::Empty, ty.void_(), {},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize("width", "height", "depth"),
});
@@ -863,8 +865,8 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Function_WithArrayParams) {
- Func("my_func", {Param("a", ty.array<f32, 5>())}, ty.void_(),
- {
+ Func("my_func", utils::Vector{Param("a", ty.array<f32, 5>())}, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -881,8 +883,8 @@
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Function_WithArrayReturn) {
- Func("my_func", {}, ty.array<f32, 5>(),
- {
+ Func("my_func", utils::Empty, ty.array<f32, 5>(),
+ utils::Vector{
Return(Construct(ty.array<f32, 5>())),
});
@@ -917,10 +919,10 @@
// return;
// }
- auto* s = Structure("Data", {Member("d", ty.f32())});
+ auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -928,12 +930,12 @@
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
- Func("a", {}, ty.void_(),
- {
+ Func("a", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -942,12 +944,12 @@
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
- Func("b", {}, ty.void_(),
- {
+ Func("b", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
index 875d211..ba6dc43 100644
--- a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
@@ -86,22 +86,19 @@
template <typename BASE>
class GlslGeneratorImplTest_MemberAccessorBase : public BASE {
public:
- void SetupStorageBuffer(ast::StructMemberList members) {
+ void SetupStorageBuffer(utils::VectorRef<const ast::StructMember*> members) {
ProgramBuilder& b = *this;
auto* s = b.Structure("Data", members);
b.GlobalVar("data", b.ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- b.create<ast::BindingAttribute>(0u),
- b.create<ast::GroupAttribute>(1u),
- });
+ b.GroupAndBinding(1u, 0u));
}
- void SetupFunction(ast::StatementList statements) {
+ void SetupFunction(utils::VectorRef<const ast::Statement*> statements) {
ProgramBuilder& b = *this;
- b.Func("main", {}, b.ty.void_(), statements,
- {
+ b.Func("main", utils::Empty, b.ty.void_(), statements,
+ utils::Vector<const ast::Attribute*, 1>{
b.Stage(ast::PipelineStage::kFragment),
});
}
@@ -114,7 +111,7 @@
GlslGeneratorImplTest_MemberAccessorBase<TestParamHelper<T>>;
TEST_F(GlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
- auto* s = Structure("Data", {Member("mem", ty.f32())});
+ auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("str", "mem");
@@ -165,12 +162,12 @@
auto p = GetParam();
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("a", ty.i32()),
Member("b", p.member_type(ty)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone, MemberAccessor("data", "b"))),
});
@@ -216,12 +213,12 @@
auto p = GetParam();
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("a", ty.i32()),
Member("b", p.member_type(ty)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("value", p.member_type(ty), ast::StorageClass::kNone,
Construct(p.member_type(ty)))),
Assign(MemberAccessor("data", "b"), Expr("value")),
@@ -265,13 +262,13 @@
// var<storage> data : Data;
// data.a = mat2x3<f32>();
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("a", ty.i32()),
Member("b", ty.mat2x3<f32>()),
});
- SetupFunction({
- Assign(MemberAccessor("data", "b"), Construct(ty.mat2x3<f32>(), ast::ExpressionList{})),
+ SetupFunction(utils::Vector{
+ Assign(MemberAccessor("data", "b"), Construct(ty.mat2x3<f32>())),
});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -310,12 +307,12 @@
// var<storage> data : Data;
// data.a[2i][1i];
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("z", ty.f32()),
Member("a", ty.mat4x3<f32>()),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
IndexAccessor(IndexAccessor(MemberAccessor("data", "a"), 2_i), 1_i))),
});
@@ -356,12 +353,12 @@
// var<storage> data : Data;
// data.a[2];
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("z", ty.f32()),
Member("a", ty.array<i32, 5>(4)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
IndexAccessor(MemberAccessor("data", "a"), 2_i))),
});
@@ -402,14 +399,17 @@
// var<storage> data : Data;
// data.a[(2i + 4i) - 3i];
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("z", ty.f32()),
Member("a", ty.array<i32, 5>(4)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
+ Decl(Var("a", nullptr, Expr(2_i))),
+ Decl(Var("b", nullptr, Expr(4_i))),
+ Decl(Var("c", nullptr, Expr(3_i))),
Decl(Var("x", nullptr, ast::StorageClass::kNone,
- IndexAccessor(MemberAccessor("data", "a"), Sub(Add(2_i, 4_i), 3_i)))),
+ IndexAccessor(MemberAccessor("data", "a"), Sub(Add("a", "b"), "c")))),
});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -429,7 +429,10 @@
int a[5];
} data;
void tint_symbol() {
- int x = data.a[((2 + 4) - 3)];
+ int a = 2;
+ int b = 4;
+ int c = 3;
+ int x = data.a[((a + b) - c)];
}
void main() {
@@ -447,12 +450,12 @@
// var<storage> data : Data;
// data.a[2i] = 2i;
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("z", ty.f32()),
Member("a", ty.array<i32, 5>(4)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Assign(IndexAccessor(MemberAccessor("data", "a"), 2_i), 2_i),
});
@@ -496,16 +499,16 @@
// var<storage> data : Pre;
// data.c[2i].b
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"))),
});
@@ -553,16 +556,16 @@
// var<storage> data : Pre;
// data.c[2i].b.xy
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
MemberAccessor(
MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "xy"))),
@@ -612,16 +615,16 @@
// var<storage> data : Pre;
// data.c[2i].b.g
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
MemberAccessor(
MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "g"))),
@@ -670,16 +673,16 @@
// var<storage> data : Pre;
// data.c[2i].b[1i]
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
IndexAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
1_i))),
@@ -728,16 +731,16 @@
// var<storage> data : Pre;
// data.c[2i].b = vec3<f32>(1.f, 2.f, 3.f);
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Assign(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
vec3<f32>(1_f, 2_f, 3_f)),
});
@@ -785,16 +788,16 @@
// var<storage> data : Pre;
// data.c[2i].b.y = 1.f;
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<i32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Assign(MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
"y"),
Expr(1_f)),
diff --git a/src/tint/writer/glsl/generator_impl_module_constant_test.cc b/src/tint/writer/glsl/generator_impl_module_constant_test.cc
index fa269da..44cbb53 100644
--- a/src/tint/writer/glsl/generator_impl_module_constant_test.cc
+++ b/src/tint/writer/glsl/generator_impl_module_constant_test.cc
@@ -34,7 +34,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AInt) {
auto* var = GlobalConst("G", nullptr, Expr(1_a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -51,7 +54,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AFloat) {
auto* var = GlobalConst("G", nullptr, Expr(1._a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -68,7 +74,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_i32) {
auto* var = GlobalConst("G", nullptr, Expr(1_i));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -85,7 +94,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_u32) {
auto* var = GlobalConst("G", nullptr, Expr(1_u));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -102,7 +114,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_f32) {
auto* var = GlobalConst("G", nullptr, Expr(1_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -121,7 +136,10 @@
Enable(ast::Extension::kF16);
auto* var = GlobalConst("G", nullptr, Expr(1_h));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -139,7 +157,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AInt) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -156,7 +177,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AFloat) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -173,7 +197,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_f32) {
auto* var = GlobalConst("G", nullptr, vec3<f32>(1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -192,7 +219,10 @@
Enable(ast::Extension::kF16);
auto* var = GlobalConst("G", nullptr, vec3<f16>(1_h, 2_h, 3_h));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -211,7 +241,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_AFloat) {
auto* var = GlobalConst("G", nullptr,
Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -228,7 +261,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_f32) {
auto* var = GlobalConst("G", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -247,7 +283,10 @@
Enable(ast::Extension::kF16);
auto* var = GlobalConst("G", nullptr, mat2x3<f16>(1_h, 2_h, 3_h, 4_h, 5_h, 6_h));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -265,7 +304,10 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_f32) {
auto* var = GlobalConst("G", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -286,7 +328,10 @@
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", nullptr, Expr(var))),
+ });
GeneratorImpl& gen = Build();
@@ -303,7 +348,7 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_Override) {
auto* var = Override("pos", ty.f32(), Expr(3_f),
- ast::AttributeList{
+ utils::Vector{
Id(23),
});
@@ -319,7 +364,7 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_Override_NoConstructor) {
auto* var = Override("pos", ty.f32(), nullptr,
- ast::AttributeList{
+ utils::Vector{
Id(23),
});
@@ -335,7 +380,7 @@
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_Override_NoId) {
auto* a = Override("a", ty.f32(), Expr(3_f),
- ast::AttributeList{
+ utils::Vector{
Id(0),
});
auto* b = Override("b", ty.f32(), Expr(2_f));
diff --git a/src/tint/writer/glsl/generator_impl_return_test.cc b/src/tint/writer/glsl/generator_impl_return_test.cc
index 59df385..28bbf51 100644
--- a/src/tint/writer/glsl/generator_impl_return_test.cc
+++ b/src/tint/writer/glsl/generator_impl_return_test.cc
@@ -35,7 +35,7 @@
TEST_F(GlslGeneratorImplTest_Return, Emit_ReturnWithValue) {
auto* r = Return(123_i);
- Func("f", {}, ty.i32(), {r});
+ Func("f", utils::Empty, ty.i32(), utils::Vector{r});
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
index ae1b0ba..c2a4ff2 100644
--- a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
@@ -25,19 +25,19 @@
using GlslSanitizerTest = TestHelper;
TEST_F(GlslSanitizerTest, Call_ArrayLength) {
- auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -65,22 +65,22 @@
}
TEST_F(GlslSanitizerTest, Call_ArrayLength_OtherMembersInStruct) {
- auto* s = Structure("my_struct", {
+ auto* s = Structure("my_struct", utils::Vector{
Member(0, "z", ty.f32()),
Member(4, "a", ty.array<f32>(4)),
});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -110,9 +110,9 @@
}
TEST_F(GlslSanitizerTest, Call_ArrayLength_ViaLets) {
- auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
@@ -120,13 +120,13 @@
auto* p = Let("p", nullptr, AddressOf("b"));
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(p),
Decl(p2),
Decl(Var("len", ty.u32(), ast::StorageClass::kNone, Call("arrayLength", p2))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -157,12 +157,12 @@
TEST_F(GlslSanitizerTest, PromoteArrayInitializerToConstVar) {
auto* array_init = array<i32, 4>(1_i, 2_i, 3_i, 4_i);
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("idx", nullptr, Expr(3_i))),
Decl(Var("pos", ty.i32(), IndexAccessor(array_init, "idx"))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -189,7 +189,7 @@
}
TEST_F(GlslSanitizerTest, PromoteStructInitializerToConstVar) {
- auto* str = Structure("S", {
+ auto* str = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.vec3<f32>()),
Member("c", ty.i32()),
@@ -198,11 +198,11 @@
auto* struct_access = MemberAccessor(struct_init, "b");
auto* pos = Var("pos", ty.vec3<f32>(), ast::StorageClass::kNone, struct_access);
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(pos),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -241,13 +241,13 @@
auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), AddressOf(v));
auto* x = Var("x", ty.i32(), ast::StorageClass::kNone, Deref(p));
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(v),
Decl(p),
Decl(x),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -287,15 +287,15 @@
AddressOf(IndexAccessor(Deref(mp), 2_i)));
auto* v = Var("v", ty.vec4<f32>(), ast::StorageClass::kNone, Deref(vp));
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(a),
Decl(ap),
Decl(mp),
Decl(vp),
Decl(v),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
diff --git a/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc b/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
index 7a13b66..0323d74 100644
--- a/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
@@ -29,14 +29,14 @@
// @align(256) louie : f32;
// };
// @group(0) @binding(0) var<storage, read_write> nephews : Nephews;
- auto* nephews =
- ctx->Structure("Nephews", {
- ctx->Member("huey", ctx->ty.f32(), {ctx->MemberAlign(256)}),
- ctx->Member("dewey", ctx->ty.f32(), {ctx->MemberAlign(256)}),
- ctx->Member("louie", ctx->ty.f32(), {ctx->MemberAlign(256)}),
- });
+ auto* nephews = ctx->Structure(
+ "Nephews", utils::Vector{
+ ctx->Member("huey", ctx->ty.f32(), utils::Vector{ctx->MemberAlign(256)}),
+ ctx->Member("dewey", ctx->ty.f32(), utils::Vector{ctx->MemberAlign(256)}),
+ ctx->Member("louie", ctx->ty.f32(), utils::Vector{ctx->MemberAlign(256)}),
+ });
ctx->GlobalVar("nephews", ctx->ty.Of(nephews), ast::StorageClass::kStorage,
- ast::AttributeList{
+ utils::Vector{
ctx->create<ast::BindingAttribute>(0u),
ctx->create<ast::GroupAttribute>(0u),
});
diff --git a/src/tint/writer/glsl/generator_impl_switch_test.cc b/src/tint/writer/glsl/generator_impl_switch_test.cc
index c8957be..c2db3b5 100644
--- a/src/tint/writer/glsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/glsl/generator_impl_switch_test.cc
@@ -25,18 +25,18 @@
GlobalVar("cond", ty.i32(), ast::StorageClass::kPrivate);
auto* def_body = Block(create<ast::BreakStatement>());
- auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
+ auto* def = create<ast::CaseStatement>(utils::Empty, def_body);
- ast::CaseSelectorList case_val;
- case_val.push_back(Expr(5_i));
+ utils::Vector case_val{Expr(5_i)};
auto* case_body = Block(create<ast::BreakStatement>());
auto* case_stmt = create<ast::CaseStatement>(case_val, case_body);
- ast::CaseStatementList body;
- body.push_back(case_stmt);
- body.push_back(def);
+ utils::Vector body{
+ case_stmt,
+ def,
+ };
auto* cond = Expr("cond");
auto* s = create<ast::SwitchStatement>(cond, body);
diff --git a/src/tint/writer/glsl/generator_impl_test.cc b/src/tint/writer/glsl/generator_impl_test.cc
index f45d0d0..919d684 100644
--- a/src/tint/writer/glsl/generator_impl_test.cc
+++ b/src/tint/writer/glsl/generator_impl_test.cc
@@ -29,7 +29,7 @@
}
TEST_F(GlslGeneratorImplTest, Generate) {
- Func("my_func", {}, ty.void_(), {});
+ Func("my_func", utils::Empty, ty.void_(), utils::Empty);
GeneratorImpl& gen = Build();
@@ -43,7 +43,7 @@
}
TEST_F(GlslGeneratorImplTest, GenerateDesktop) {
- Func("my_func", {}, ty.void_(), {});
+ Func("my_func", utils::Empty, ty.void_(), utils::Empty);
GeneratorImpl& gen = Build(Version(Version::Standard::kDesktop, 4, 4));
@@ -58,13 +58,13 @@
TEST_F(GlslGeneratorImplTest, GenerateSampleIndexES) {
GlobalVar("gl_SampleID", ty.i32(),
- ast::AttributeList{
+ utils::Vector{
Builtin(ast::BuiltinValue::kSampleIndex),
Disable(ast::DisabledValidation::kIgnoreStorageClass),
},
ast::StorageClass::kIn);
- Func("my_func", {}, ty.i32(),
- {
+ Func("my_func", utils::Empty, ty.i32(),
+ utils::Vector{
Return(Expr("gl_SampleID")),
});
@@ -83,13 +83,13 @@
TEST_F(GlslGeneratorImplTest, GenerateSampleIndexDesktop) {
GlobalVar("gl_SampleID", ty.i32(),
- ast::AttributeList{
+ utils::Vector{
Builtin(ast::BuiltinValue::kSampleIndex),
Disable(ast::DisabledValidation::kIgnoreStorageClass),
},
ast::StorageClass::kIn);
- Func("my_func", {}, ty.i32(),
- {
+ Func("my_func", utils::Empty, ty.i32(),
+ utils::Vector{
Return(Expr("gl_SampleID")),
});
diff --git a/src/tint/writer/glsl/generator_impl_type_test.cc b/src/tint/writer/glsl/generator_impl_type_test.cc
index 1c4cb03..aa2afab 100644
--- a/src/tint/writer/glsl/generator_impl_type_test.cc
+++ b/src/tint/writer/glsl/generator_impl_type_test.cc
@@ -158,7 +158,7 @@
}
TEST_F(GlslGeneratorImplTest_Type, EmitType_StructDecl) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
@@ -178,7 +178,7 @@
}
TEST_F(GlslGeneratorImplTest_Type, EmitType_Struct) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
@@ -194,7 +194,7 @@
}
TEST_F(GlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("double", ty.i32()),
Member("float", ty.f32()),
});
@@ -211,9 +211,9 @@
}
TEST_F(GlslGeneratorImplTest_Type, EmitType_Struct_WithOffsetAttributes) {
- auto* s = Structure("S", {
- Member("a", ty.i32(), {MemberOffset(0)}),
- Member("b", ty.f32(), {MemberOffset(8)}),
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.i32(), utils::Vector{MemberOffset(0)}),
+ Member("b", ty.f32(), utils::Vector{MemberOffset(8)}),
});
GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
@@ -313,13 +313,18 @@
auto* t = ty.depth_texture(params.dim);
GlobalVar("tex", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("textureDimensions", "tex")),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
GeneratorImpl& gen = Build();
@@ -340,13 +345,18 @@
auto* t = ty.depth_multisampled_texture(ast::TextureDimension::k2d);
GlobalVar("tex", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("textureDimensions", "tex")),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
GeneratorImpl& gen = Build();
@@ -383,13 +393,18 @@
auto* t = ty.sampled_texture(params.dim, datatype);
GlobalVar("tex", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("textureDimensions", "tex")),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
GeneratorImpl& gen = Build();
@@ -517,13 +532,18 @@
auto* t = ty.storage_texture(params.dim, params.imgfmt, ast::Access::kWrite);
GlobalVar("tex", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("textureDimensions", "tex")),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc b/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
index 8e653b5..4ea5779 100644
--- a/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
@@ -23,7 +23,7 @@
using GlslGeneratorImplTest_UniformBuffer = TestHelper;
TEST_F(GlslGeneratorImplTest_UniformBuffer, Simple) {
- auto* simple = Structure("Simple", {Member("member", ty.f32())});
+ auto* simple = Structure("Simple", utils::Vector{Member("member", ty.f32())});
GlobalVar("simple", ty.Of(simple), ast::StorageClass::kUniform, GroupAndBinding(0, 0));
GeneratorImpl& gen = Build();
@@ -43,7 +43,7 @@
}
TEST_F(GlslGeneratorImplTest_UniformBuffer, Simple_Desktop) {
- auto* simple = Structure("Simple", {Member("member", ty.f32())});
+ auto* simple = Structure("Simple", utils::Vector{Member("member", ty.f32())});
GlobalVar("simple", ty.Of(simple), ast::StorageClass::kUniform, GroupAndBinding(0, 0));
GeneratorImpl& gen = Build(Version(Version::Standard::kDesktop, 4, 4));
diff --git a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
index 873afc1..1ad1c55 100644
--- a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
@@ -66,7 +66,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AInt) {
auto* C = Const("C", nullptr, Expr(1_a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -83,7 +87,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AFloat) {
auto* C = Const("C", nullptr, Expr(1._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -100,7 +108,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_i32) {
auto* C = Const("C", nullptr, Expr(1_i));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -117,7 +129,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_u32) {
auto* C = Const("C", nullptr, Expr(1_u));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -134,7 +150,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_f32) {
auto* C = Const("C", nullptr, Expr(1_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -153,7 +173,11 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, Expr(1_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -171,7 +195,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AInt) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -188,7 +216,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AFloat) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -205,7 +237,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_f32) {
auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -224,7 +260,11 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, vec3<f16>(1_h, 2_h, 3_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -243,7 +283,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
auto* C =
Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -260,7 +304,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_f32) {
auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -279,7 +327,11 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, mat2x3<f16>(1_h, 2_h, 3_h, 4_h, 5_h, 6_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -297,7 +349,11 @@
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_f32) {
auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -318,7 +374,11 @@
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc b/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
index 1d96441..9b39fda 100644
--- a/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
+++ b/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
@@ -29,8 +29,8 @@
TEST_F(GlslGeneratorImplTest_WorkgroupVar, Basic) {
GlobalVar("wg", ty.f32(), ast::StorageClass::kWorkgroup);
- Func("main", {}, ty.void_(), {Assign("wg", 1.2_f)},
- {
+ Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -45,8 +45,8 @@
GlobalVar("wg", ty.Of(alias), ast::StorageClass::kWorkgroup);
- Func("main", {}, ty.void_(), {Assign("wg", 1.2_f)},
- {
+ Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index d106804..444746c 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -72,6 +72,7 @@
#include "src/tint/utils/defer.h"
#include "src/tint/utils/map.h"
#include "src/tint/utils/scoped_assignment.h"
+#include "src/tint/utils/string.h"
#include "src/tint/writer/append_vector.h"
#include "src/tint/writer/float_to_string.h"
#include "src/tint/writer/generate_external_texture_bindings.h"
@@ -274,12 +275,8 @@
auto* mod = builder_.Sem().Module();
for (auto* decl : mod->DependencyOrderedDeclarations()) {
- if (decl->Is<ast::Alias>()) {
- continue; // Ignore aliases.
- }
- if (decl->Is<ast::Enable>()) {
- // Currently we don't have to do anything for using a extension in HLSL.
- continue;
+ if (decl->IsAnyOf<ast::Alias, ast::Enable, ast::StaticAssert>()) {
+ continue; // These are not emitted.
}
// Emit a new line between declarations if the type of declaration has
@@ -920,7 +917,7 @@
return true;
}
-bool GeneratorImpl::EmitStatements(const ast::StatementList& stmts) {
+bool GeneratorImpl::EmitStatements(utils::VectorRef<const ast::Statement*> stmts) {
for (auto* s : stmts) {
if (!EmitStatement(s)) {
return false;
@@ -929,7 +926,7 @@
return true;
}
-bool GeneratorImpl::EmitStatementsWithIndent(const ast::StatementList& stmts) {
+bool GeneratorImpl::EmitStatementsWithIndent(utils::VectorRef<const ast::Statement*> stmts) {
ScopedIndent si(this);
return EmitStatements(stmts);
}
@@ -1663,7 +1660,7 @@
{
ScopedParen sp(pre);
- for (size_t i = 0; i < expr->args.size(); i++) {
+ for (size_t i = 0; i < expr->args.Length(); i++) {
auto* arg = expr->args[i];
if (i > 0) {
pre << ", ";
@@ -1858,16 +1855,15 @@
return false;
}
- line(b) << "float" << width << " whole;";
- line(b) << "float" << width << " fract = modf(" << in << ", whole);";
{
auto l = line(b);
if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
ast::Access::kUndefined, "")) {
return false;
}
- l << " result = {fract, whole};";
+ l << " result;";
}
+ line(b) << "result.fract = modf(" << params[0] << ", result.whole);";
line(b) << "return result;";
return true;
});
@@ -1892,8 +1888,15 @@
return false;
}
- line(b) << "float" << width << " exp;";
- line(b) << "float" << width << " sig = frexp(" << in << ", exp);";
+ std::string member_type;
+ if (Is<sem::F16>(sem::Type::DeepestElementOf(ty))) {
+ member_type = width.empty() ? "float16_t" : ("vector<float16_t, " + width + ">");
+ } else {
+ member_type = "float" + width;
+ }
+
+ line(b) << member_type << " exp;";
+ line(b) << member_type << " sig = frexp(" << in << ", exp);";
{
auto l = line(b);
if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
@@ -2571,7 +2574,7 @@
return false;
}
out << ":";
- if (selector == stmt->selectors.back()) {
+ if (selector == stmt->selectors.Back()) {
out << " {";
}
}
@@ -2686,7 +2689,7 @@
return false;
}
} else {
- if (!EmitStatementsWithIndent({stmt->else_statement})) {
+ if (!EmitStatementsWithIndent(utils::Vector{stmt->else_statement})) {
return false;
}
}
@@ -2849,6 +2852,11 @@
return EmitPrivateVariable(sem);
case ast::StorageClass::kWorkgroup:
return EmitWorkgroupVariable(sem);
+ case ast::StorageClass::kPushConstant:
+ diagnostics_.add_error(
+ diag::System::Writer,
+ "unhandled storage class " + utils::ToString(sem->StorageClass()));
+ return false;
default: {
TINT_ICE(Writer, diagnostics_)
<< "unhandled storage class " << sem->StorageClass();
@@ -2863,6 +2871,7 @@
[&](Default) {
TINT_ICE(Writer, diagnostics_)
<< "unhandled global variable type " << global->TypeInfo().name;
+
return false;
});
}
@@ -3639,6 +3648,9 @@
return false;
});
},
+ [&](const ast::StaticAssert*) {
+ return true; // Not emitted
+ },
[&](Default) { //
diagnostics_.add_error(diag::System::Writer,
"unknown statement type: " + std::string(stmt->TypeInfo().name));
@@ -3647,7 +3659,7 @@
}
bool GeneratorImpl::EmitDefaultOnlySwitch(const ast::SwitchStatement* stmt) {
- TINT_ASSERT(Writer, stmt->body.size() == 1 && stmt->body[0]->IsDefault());
+ TINT_ASSERT(Writer, stmt->body.Length() == 1 && stmt->body[0]->IsDefault());
// FXC fails to compile a switch with just a default case, ignoring the
// default case body. We work around this here by emitting the default case
@@ -3680,7 +3692,7 @@
bool GeneratorImpl::EmitSwitch(const ast::SwitchStatement* stmt) {
// BUG(crbug.com/tint/1188): work around default-only switches
- if (stmt->body.size() == 1 && stmt->body[0]->IsDefault()) {
+ if (stmt->body.Length() == 1 && stmt->body[0]->IsDefault()) {
return EmitDefaultOnlySwitch(stmt);
}
@@ -3695,7 +3707,7 @@
{
ScopedIndent si(this);
- for (size_t i = 0; i < stmt->body.size(); i++) {
+ for (size_t i = 0; i < stmt->body.Length(); i++) {
if (!EmitCase(stmt, i)) {
return false;
}
diff --git a/src/tint/writer/hlsl/generator_impl.h b/src/tint/writer/hlsl/generator_impl.h
index a282451..78680c8 100644
--- a/src/tint/writer/hlsl/generator_impl.h
+++ b/src/tint/writer/hlsl/generator_impl.h
@@ -112,11 +112,11 @@
/// Emits a list of statements
/// @param stmts the statement list
/// @returns true if the statements were emitted successfully
- bool EmitStatements(const ast::StatementList& stmts);
+ bool EmitStatements(utils::VectorRef<const ast::Statement*> stmts);
/// Emits a list of statements with an indentation
/// @param stmts the statement list
/// @returns true if the statements were emitted successfully
- bool EmitStatementsWithIndent(const ast::StatementList& stmts);
+ bool EmitStatementsWithIndent(utils::VectorRef<const ast::Statement*> stmts);
/// Handles a block statement
/// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully
diff --git a/src/tint/writer/hlsl/generator_impl_assign_test.cc b/src/tint/writer/hlsl/generator_impl_assign_test.cc
index 57e65a9..a01903e 100644
--- a/src/tint/writer/hlsl/generator_impl_assign_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_assign_test.cc
@@ -22,8 +22,8 @@
using HlslGeneratorImplTest_Assign = TestHelper;
TEST_F(HlslGeneratorImplTest_Assign, Emit_Assign) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("lhs", ty.i32())),
Decl(Var("rhs", ty.i32())),
Assign("lhs", "rhs"),
@@ -42,8 +42,8 @@
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_LetIndex) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("lhs", ty.vec3<f32>())),
Decl(Var("rhs", ty.f32())),
Decl(Let("index", ty.u32(), Expr(0_u))),
@@ -68,8 +68,8 @@
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_ConstIndex) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("lhs", ty.vec3<f32>())),
Decl(Var("rhs", ty.f32())),
Decl(Const("index", ty.u32(), Expr(0_u))),
@@ -89,8 +89,8 @@
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_DynamicIndex) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("lhs", ty.vec3<f32>())),
Decl(Var("rhs", ty.f32())),
Decl(Var("index", ty.u32())),
@@ -115,8 +115,8 @@
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_LetIndex) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("lhs", ty.mat4x2<f32>())),
Decl(Var("rhs", ty.vec2<f32>())),
Decl(Let("index", ty.u32(), Expr(0_u))),
@@ -146,8 +146,8 @@
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_ConstIndex) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("lhs", ty.mat4x2<f32>())),
Decl(Var("rhs", ty.vec2<f32>())),
Decl(Const("index", ty.u32(), Expr(0_u))),
@@ -167,8 +167,8 @@
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_DynamicIndex) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("lhs", ty.mat4x2<f32>())),
Decl(Var("rhs", ty.vec2<f32>())),
Decl(Var("index", ty.u32())),
@@ -198,8 +198,8 @@
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_LetIndex) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("lhs", ty.mat4x2<f32>())),
Decl(Var("rhs", ty.f32())),
Decl(Let("index", ty.u32(), Expr(0_u))),
@@ -237,8 +237,8 @@
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_ConstIndex) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("lhs", ty.mat4x2<f32>())),
Decl(Var("rhs", ty.f32())),
Decl(Const("index", ty.u32(), Expr(0_u))),
@@ -258,8 +258,8 @@
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_DynamicIndex) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("lhs", ty.mat4x2<f32>())),
Decl(Var("rhs", ty.f32())),
Decl(Var("index", ty.u32())),
diff --git a/src/tint/writer/hlsl/generator_impl_binary_test.cc b/src/tint/writer/hlsl/generator_impl_binary_test.cc
index 7836abc..d5f70fb 100644
--- a/src/tint/writer/hlsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_binary_test.cc
@@ -483,7 +483,7 @@
Block(Return(1_i)),
Else(If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("b"), Expr("c")),
Block(Return(2_i)), Else(Block(Return(3_i))))));
- Func("func", {}, ty.i32(), {WrapInStatement(expr)});
+ Func("func", utils::Empty, ty.i32(), utils::Vector{WrapInStatement(expr)});
GeneratorImpl& gen = Build();
@@ -519,7 +519,7 @@
ast::BinaryOp::kLogicalOr,
create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
Expr("c")));
- Func("func", {}, ty.bool_(), {WrapInStatement(expr)});
+ Func("func", utils::Empty, ty.bool_(), utils::Vector{WrapInStatement(expr)});
GeneratorImpl& gen = Build();
@@ -603,26 +603,25 @@
// foo(a && b, c || d, (a || c) && (b || d))
Func("foo",
- {
+ utils::Vector{
Param(Sym(), ty.bool_()),
Param(Sym(), ty.bool_()),
Param(Sym(), ty.bool_()),
},
- ty.void_(), ast::StatementList{}, ast::AttributeList{});
+ ty.void_(), utils::Empty, utils::Empty);
GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
- ast::ExpressionList params;
- params.push_back(
- create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")));
- params.push_back(
- create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("c"), Expr("d")));
- params.push_back(create<ast::BinaryExpression>(
- ast::BinaryOp::kLogicalAnd,
- create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("c")),
- create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("b"), Expr("d"))));
+ utils::Vector params{
+ create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
+ create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("c"), Expr("d")),
+ create<ast::BinaryExpression>(
+ ast::BinaryOp::kLogicalAnd,
+ create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("c")),
+ create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("b"), Expr("d"))),
+ };
auto* expr = CallStmt(Call("foo", params));
WrapInFunction(expr);
@@ -676,8 +675,8 @@
testing::Values(Params{Params::Type::Div}, Params{Params::Type::Mod}));
TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_i32) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.i32())),
Decl(Let("r", nullptr, Op("a", 0_i))),
});
@@ -694,8 +693,8 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_u32) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.u32())),
Decl(Let("r", nullptr, Op("a", 0_u))),
});
@@ -712,8 +711,8 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_vec_by_vec_i32) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", nullptr, vec4<i32>(100_i, 100_i, 100_i, 100_i))),
Decl(Let("r", nullptr, Op("a", vec4<i32>(50_i, 0_i, 25_i, 0_i)))),
});
@@ -730,8 +729,8 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_vec_by_scalar_i32) {
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", nullptr, vec4<i32>(100_i, 100_i, 100_i, 100_i))),
Decl(Let("r", nullptr, Op("a", 0_i))),
});
@@ -748,8 +747,8 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_i32) {
- Func("fn", {Param("b", ty.i32())}, ty.void_(),
- {
+ Func("fn", utils::Vector{Param("b", ty.i32())}, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.i32())),
Decl(Let("r", nullptr, Op("a", "b"))),
});
@@ -766,8 +765,8 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_u32) {
- Func("fn", {Param("b", ty.u32())}, ty.void_(),
- {
+ Func("fn", utils::Vector{Param("b", ty.u32())}, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.u32())),
Decl(Let("r", nullptr, Op("a", "b"))),
});
@@ -784,8 +783,8 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_vec_by_vec_i32) {
- Func("fn", {Param("b", ty.vec3<i32>())}, ty.void_(),
- {
+ Func("fn", utils::Vector{Param("b", ty.vec3<i32>())}, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.vec3<i32>())),
Decl(Let("r", nullptr, Op("a", "b"))),
});
@@ -802,8 +801,8 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_vec_by_scalar_i32) {
- Func("fn", {Param("b", ty.i32())}, ty.void_(),
- {
+ Func("fn", utils::Vector{Param("b", ty.i32())}, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.vec3<i32>())),
Decl(Let("r", nullptr, Op("a", "b"))),
});
@@ -820,13 +819,13 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_i32) {
- Func("zero", {}, ty.i32(),
- {
+ Func("zero", utils::Empty, ty.i32(),
+ utils::Vector{
Return(Expr(0_i)),
});
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.i32())),
Decl(Let("r", nullptr, Op("a", Call("zero")))),
});
@@ -851,13 +850,13 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_u32) {
- Func("zero", {}, ty.u32(),
- {
+ Func("zero", utils::Empty, ty.u32(),
+ utils::Vector{
Return(Expr(0_u)),
});
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.u32())),
Decl(Let("r", nullptr, Op("a", Call("zero")))),
});
@@ -882,13 +881,13 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_vec_by_vec_i32) {
- Func("zero", {}, ty.vec3<i32>(),
- {
+ Func("zero", utils::Empty, ty.vec3<i32>(),
+ utils::Vector{
Return(vec3<i32>(0_i, 0_i, 0_i)),
});
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.vec3<i32>())),
Decl(Let("r", nullptr, Op("a", Call("zero")))),
});
@@ -913,13 +912,13 @@
}
TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_vec_by_scalar_i32) {
- Func("zero", {}, ty.i32(),
- {
+ Func("zero", utils::Empty, ty.i32(),
+ utils::Vector{
Return(0_i),
});
- Func("fn", {}, ty.void_(),
- {
+ Func("fn", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("a", ty.vec3<i32>())),
Decl(Let("r", nullptr, Op("a", Call("zero")))),
});
diff --git a/src/tint/writer/hlsl/generator_impl_builtin_test.cc b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
index c87d60d..3f9cfa7 100644
--- a/src/tint/writer/hlsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
@@ -214,8 +214,11 @@
auto* call = GenerateCall(param.builtin, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled builtin";
- Func("func", {}, ty.void_(), {CallStmt(call)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(call),
+ },
+ utils::Vector{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
GeneratorImpl& gen = Build();
@@ -374,7 +377,7 @@
EXPECT_EQ(out.str(), "(bool2(true, false) ? int2(3, 4) : int2(1, 2))");
}
-TEST_F(HlslGeneratorImplTest_Builtin, Modf_Scalar) {
+TEST_F(HlslGeneratorImplTest_Builtin, Modf_Scalar_f32) {
auto* call = Call("modf", 1_f);
WrapInFunction(CallStmt(call));
@@ -386,9 +389,8 @@
float whole;
};
modf_result tint_modf(float param_0) {
- float whole;
- float fract = modf(param_0, whole);
- modf_result result = {fract, whole};
+ modf_result result;
+ result.fract = modf(param_0, result.whole);
return result;
}
@@ -400,7 +402,34 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Builtin, Modf_Vector) {
+TEST_F(HlslGeneratorImplTest_Builtin, Modf_Scalar_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("modf", 1_h);
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(struct modf_result_f16 {
+ float16_t fract;
+ float16_t whole;
+};
+modf_result_f16 tint_modf(float16_t param_0) {
+ modf_result_f16 result;
+ result.fract = modf(param_0, result.whole);
+ return result;
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+ tint_modf(float16_t(1.0h));
+ return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, Modf_Vector_f32) {
auto* call = Call("modf", vec3<f32>());
WrapInFunction(CallStmt(call));
@@ -412,9 +441,8 @@
float3 whole;
};
modf_result_vec3 tint_modf(float3 param_0) {
- float3 whole;
- float3 fract = modf(param_0, whole);
- modf_result_vec3 result = {fract, whole};
+ modf_result_vec3 result;
+ result.fract = modf(param_0, result.whole);
return result;
}
@@ -426,7 +454,34 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Builtin, Frexp_Scalar_i32) {
+TEST_F(HlslGeneratorImplTest_Builtin, Modf_Vector_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("modf", vec3<f16>());
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(struct modf_result_vec3_f16 {
+ vector<float16_t, 3> fract;
+ vector<float16_t, 3> whole;
+};
+modf_result_vec3_f16 tint_modf(vector<float16_t, 3> param_0) {
+ modf_result_vec3_f16 result;
+ result.fract = modf(param_0, result.whole);
+ return result;
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+ tint_modf((float16_t(0.0h)).xxx);
+ return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, Frexp_Scalar_f32) {
auto* call = Call("frexp", 1_f);
WrapInFunction(CallStmt(call));
@@ -452,7 +507,35 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Builtin, Frexp_Vector_i32) {
+TEST_F(HlslGeneratorImplTest_Builtin, Frexp_Scalar_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("frexp", 1_h);
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(struct frexp_result_f16 {
+ float16_t sig;
+ int exp;
+};
+frexp_result_f16 tint_frexp(float16_t param_0) {
+ float16_t exp;
+ float16_t sig = frexp(param_0, exp);
+ frexp_result_f16 result = {sig, int(exp)};
+ return result;
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+ tint_frexp(float16_t(1.0h));
+ return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, Frexp_Vector_f32) {
auto* call = Call("frexp", vec3<f32>());
WrapInFunction(CallStmt(call));
@@ -478,6 +561,34 @@
)");
}
+TEST_F(HlslGeneratorImplTest_Builtin, Frexp_Vector_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("frexp", vec3<f16>());
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(struct frexp_result_vec3_f16 {
+ vector<float16_t, 3> sig;
+ int3 exp;
+};
+frexp_result_vec3_f16 tint_frexp(vector<float16_t, 3> param_0) {
+ vector<float16_t, 3> exp;
+ vector<float16_t, 3> sig = frexp(param_0, exp);
+ frexp_result_vec3_f16 result = {sig, int3(exp)};
+ return result;
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+ tint_frexp((float16_t(0.0h)).xxx);
+ return;
+}
+)");
+}
+
TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Scalar_f32) {
auto* val = Var("val", ty.f32());
auto* call = Call("degrees", val);
@@ -879,8 +990,11 @@
}
TEST_F(HlslGeneratorImplTest_Builtin, StorageBarrier) {
- Func("main", {}, ty.void_(), {CallStmt(Call("storageBarrier"))},
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("storageBarrier")),
+ },
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -897,8 +1011,11 @@
}
TEST_F(HlslGeneratorImplTest_Builtin, WorkgroupBarrier) {
- Func("main", {}, ty.void_(), {CallStmt(Call("workgroupBarrier"))},
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("workgroupBarrier")),
+ },
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/writer/hlsl/generator_impl_builtin_texture_test.cc b/src/tint/writer/hlsl/generator_impl_builtin_texture_test.cc
index 371cc1d..b996b70 100644
--- a/src/tint/writer/hlsl/generator_impl_builtin_texture_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_builtin_texture_test.cc
@@ -370,7 +370,8 @@
auto* call = Call(param.function, param.args(this));
auto* stmt = CallStmt(call);
- Func("main", {}, ty.void_(), {stmt}, {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(), utils::Vector{stmt},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/hlsl/generator_impl_call_test.cc b/src/tint/writer/hlsl/generator_impl_call_test.cc
index fc41a81..82fb926 100644
--- a/src/tint/writer/hlsl/generator_impl_call_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_call_test.cc
@@ -23,7 +23,7 @@
using HlslGeneratorImplTest_Call = TestHelper;
TEST_F(HlslGeneratorImplTest_Call, EmitExpression_Call_WithoutParams) {
- Func("my_func", {}, ty.f32(), {Return(1.23_f)});
+ Func("my_func", utils::Empty, ty.f32(), utils::Vector{Return(1.23_f)});
auto* call = Call("my_func");
WrapInFunction(call);
@@ -37,11 +37,11 @@
TEST_F(HlslGeneratorImplTest_Call, EmitExpression_Call_WithParams) {
Func("my_func",
- {
+ utils::Vector{
Param(Sym(), ty.f32()),
Param(Sym(), ty.f32()),
},
- ty.f32(), {Return(1.23_f)});
+ ty.f32(), utils::Vector{Return(1.23_f)});
GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
@@ -57,11 +57,11 @@
TEST_F(HlslGeneratorImplTest_Call, EmitStatement_Call) {
Func("my_func",
- {
+ utils::Vector{
Param(Sym(), ty.f32()),
Param(Sym(), ty.f32()),
},
- ty.void_(), ast::StatementList{}, ast::AttributeList{});
+ ty.void_(), utils::Empty, utils::Empty);
GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
diff --git a/src/tint/writer/hlsl/generator_impl_case_test.cc b/src/tint/writer/hlsl/generator_impl_case_test.cc
index 5c7e427..c55f14b 100644
--- a/src/tint/writer/hlsl/generator_impl_case_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_case_test.cc
@@ -75,8 +75,9 @@
}
TEST_F(HlslGeneratorImplTest_Case, Emit_Case_MultipleSelectors) {
- auto* s = Switch(1_i, Case({Expr(5_i), Expr(6_i)}, Block(create<ast::BreakStatement>())),
- DefaultCase());
+ auto* s =
+ Switch(1_i, Case(utils::Vector{Expr(5_i), Expr(6_i)}, Block(create<ast::BreakStatement>())),
+ DefaultCase());
WrapInFunction(s);
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_constructor_test.cc b/src/tint/writer/hlsl/generator_impl_constructor_test.cc
index f8b9357..bb708db 100644
--- a/src/tint/writer/hlsl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_constructor_test.cc
@@ -416,7 +416,7 @@
}
TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct) {
- auto* str = Structure("S", {
+ auto* str = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
Member("c", ty.vec3<i32>()),
@@ -431,7 +431,7 @@
}
TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct_Empty) {
- auto* str = Structure("S", {
+ auto* str = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
Member("c", ty.vec3<i32>()),
diff --git a/src/tint/writer/hlsl/generator_impl_function_test.cc b/src/tint/writer/hlsl/generator_impl_function_test.cc
index 9314fb8..7e1ce60 100644
--- a/src/tint/writer/hlsl/generator_impl_function_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_function_test.cc
@@ -28,8 +28,8 @@
using HlslGeneratorImplTest_Function = TestHelper;
TEST_F(HlslGeneratorImplTest_Function, Emit_Function) {
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -45,8 +45,8 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_Name_Collision) {
- Func("GeometryShader", {}, ty.void_(),
- {
+ Func("GeometryShader", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -62,12 +62,12 @@
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithParams) {
Func("my_func",
- {
+ utils::Vector{
Param("a", ty.f32()),
Param("b", ty.i32()),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
});
@@ -83,8 +83,8 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_NoReturn_Void) {
- Func("main", {}, ty.void_(), {/* no explicit return */},
- {
+ Func("main", utils::Empty, ty.void_(), utils::Empty /* no explicit return */,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -101,8 +101,8 @@
// fn f(foo : ptr<function, f32>) -> f32 {
// return *foo;
// }
- Func("f", {Param("foo", ty.pointer<f32>(ast::StorageClass::kFunction))}, ty.f32(),
- {Return(Deref("foo"))});
+ Func("f", utils::Vector{Param("foo", ty.pointer<f32>(ast::StorageClass::kFunction))}, ty.f32(),
+ utils::Vector{Return(Deref("foo"))});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -117,15 +117,15 @@
// fn frag_main(@location(0) foo : f32) -> @location(1) f32 {
// return foo;
// }
- auto* foo_in = Param("foo", ty.f32(), {Location(0)});
- Func("frag_main", {foo_in}, ty.f32(),
- {
+ auto* foo_in = Param("foo", ty.f32(), utils::Vector{Location(0)});
+ Func("frag_main", utils::Vector{foo_in}, ty.f32(),
+ utils::Vector{
Return("foo"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(1),
});
@@ -156,15 +156,16 @@
// fn frag_main(@position(0) coord : vec4<f32>) -> @frag_depth f32 {
// return coord.x;
// }
- auto* coord_in = Param("coord", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)});
- Func("frag_main", {coord_in}, ty.f32(),
- {
+ auto* coord_in =
+ Param("coord", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)});
+ Func("frag_main", utils::Vector{coord_in}, ty.f32(),
+ utils::Vector{
Return(MemberAccessor("coord", "x")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Builtin(ast::BuiltinValue::kFragDepth),
});
@@ -206,24 +207,27 @@
// const p = inputs.pos;
// }
auto* interface_struct = Structure(
- "Interface", {
- Member("pos", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)}),
- Member("col1", ty.f32(), {Location(1)}),
- Member("col2", ty.f32(), {Location(2)}),
- });
+ "Interface",
+ utils::Vector{
+ Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
+ Member("col1", ty.f32(), utils::Vector{Location(1)}),
+ Member("col2", ty.f32(), utils::Vector{Location(2)}),
+ });
- Func("vert_main", {}, ty.Of(interface_struct),
- {Return(Construct(ty.Of(interface_struct), Construct(ty.vec4<f32>()), Expr(0.5_f),
- Expr(0.25_f)))},
- {Stage(ast::PipelineStage::kVertex)});
+ Func("vert_main", utils::Empty, ty.Of(interface_struct),
+ utils::Vector{
+ Return(Construct(ty.Of(interface_struct), Construct(ty.vec4<f32>()), Expr(0.5_f),
+ Expr(0.25_f))),
+ },
+ utils::Vector{Stage(ast::PipelineStage::kVertex)});
- Func("frag_main", {Param("inputs", ty.Of(interface_struct))}, ty.void_(),
- {
+ Func("frag_main", utils::Vector{Param("inputs", ty.Of(interface_struct))}, ty.void_(),
+ utils::Vector{
Decl(Let("r", ty.f32(), MemberAccessor("inputs", "col1"))),
Decl(Let("g", ty.f32(), MemberAccessor("inputs", "col2"))),
Decl(Let("p", ty.vec4<f32>(), MemberAccessor("inputs", "pos"))),
},
- {Stage(ast::PipelineStage::kFragment)});
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -286,19 +290,29 @@
// fn vert_main2() -> VertexOutput {
// return foo(0.25);
// }
- auto* vertex_output_struct = Structure(
- "VertexOutput", {Member("pos", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)})});
+ auto* vertex_output_struct =
+ Structure("VertexOutput",
+ utils::Vector{Member("pos", ty.vec4<f32>(),
+ utils::Vector{Builtin(ast::BuiltinValue::kPosition)})});
- Func("foo", {Param("x", ty.f32())}, ty.Of(vertex_output_struct),
- {Return(Construct(ty.Of(vertex_output_struct),
- Construct(ty.vec4<f32>(), "x", "x", "x", Expr(1_f))))},
- {});
+ Func("foo", utils::Vector{Param("x", ty.f32())}, ty.Of(vertex_output_struct),
+ utils::Vector{
+ Return(Construct(ty.Of(vertex_output_struct),
+ Construct(ty.vec4<f32>(), "x", "x", "x", Expr(1_f)))),
+ },
+ utils::Empty);
- Func("vert_main1", {}, ty.Of(vertex_output_struct), {Return(Call("foo", Expr(0.5_f)))},
- {Stage(ast::PipelineStage::kVertex)});
+ Func("vert_main1", utils::Empty, ty.Of(vertex_output_struct),
+ utils::Vector{
+ Return(Call("foo", Expr(0.5_f))),
+ },
+ utils::Vector{Stage(ast::PipelineStage::kVertex)});
- Func("vert_main2", {}, ty.Of(vertex_output_struct), {Return(Call("foo", Expr(0.25_f)))},
- {Stage(ast::PipelineStage::kVertex)});
+ Func("vert_main2", utils::Empty, ty.Of(vertex_output_struct),
+ utils::Vector{
+ Return(Call("foo", Expr(0.25_f))),
+ },
+ utils::Vector{Stage(ast::PipelineStage::kVertex)});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -345,30 +359,30 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_Uniform) {
- auto* ubo_ty = Structure("UBO", {Member("coord", ty.vec4<f32>())});
+ auto* ubo_ty = Structure("UBO", utils::Vector{Member("coord", ty.vec4<f32>())});
auto* ubo = GlobalVar("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
Func("sub_func",
- {
+ utils::Vector{
Param("param", ty.f32()),
},
ty.f32(),
- {
+ utils::Vector{
Return(MemberAccessor(MemberAccessor(ubo, "coord"), "x")),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -391,10 +405,10 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_UniformStruct) {
- auto* s = Structure("Uniforms", {Member("coord", ty.vec4<f32>())});
+ auto* s = Structure("Uniforms", utils::Vector{Member("coord", ty.vec4<f32>())});
GlobalVar("uniforms", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
@@ -402,12 +416,12 @@
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -426,25 +440,25 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_RW_StorageBuffer_Read) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -462,25 +476,25 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_RO_StorageBuffer_Read) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -498,23 +512,23 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_WO_StorageBuffer_Store) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -532,23 +546,23 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_StorageBuffer_Store) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -566,30 +580,30 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
- auto* s = Structure("S", {Member("x", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
Func("sub_func",
- {
+ utils::Vector{
Param("param", ty.f32()),
},
ty.f32(),
- {
+ utils::Vector{
Return(MemberAccessor("coord", "x")),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -612,30 +626,30 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_StorageBuffer) {
- auto* s = Structure("S", {Member("x", ty.f32())});
+ auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(1u),
});
Func("sub_func",
- {
+ utils::Vector{
Param("param", ty.f32()),
},
ty.f32(),
- {
+ utils::Vector{
Return(MemberAccessor("coord", "x")),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -657,8 +671,8 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithNameCollision) {
- Func("GeometryShader", {}, ty.void_(), {},
- {
+ Func("GeometryShader", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -672,11 +686,11 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute) {
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ utils::Vector{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
GeneratorImpl& gen = Build();
@@ -689,8 +703,8 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Literal) {
- Func("main", {}, ty.void_(), {},
- {
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(2_i, 4_i, 6_i),
});
@@ -709,8 +723,8 @@
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
- Func("main", {}, ty.void_(), {},
- {
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize("width", "height", "depth"),
});
@@ -727,11 +741,11 @@
TEST_F(HlslGeneratorImplTest_Function,
Emit_Attribute_EntryPoint_Compute_WithWorkgroup_OverridableConst) {
- Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
- Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
- Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
- Func("main", {}, ty.void_(), {},
- {
+ Override("width", ty.i32(), Construct(ty.i32(), 2_i), utils::Vector{Id(7u)});
+ Override("height", ty.i32(), Construct(ty.i32(), 3_i), utils::Vector{Id(8u)});
+ Override("depth", ty.i32(), Construct(ty.i32(), 4_i), utils::Vector{Id(9u)});
+ Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize("width", "height", "depth"),
});
@@ -761,11 +775,11 @@
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithArrayParams) {
Func("my_func",
- {
+ utils::Vector{
Param("a", ty.array<f32, 5>()),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
});
@@ -779,8 +793,8 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithArrayReturn) {
- Func("my_func", {}, ty.array<f32, 5>(),
- {
+ Func("my_func", utils::Empty, ty.array<f32, 5>(),
+ utils::Vector{
Return(Construct(ty.array<f32, 5>())),
});
@@ -795,8 +809,8 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithDiscardAndVoidReturn) {
- Func("my_func", {Param("a", ty.i32())}, ty.void_(),
- {
+ Func("my_func", utils::Vector{Param("a", ty.i32())}, ty.void_(),
+ utils::Vector{
If(Equal("a", 0_i), //
Block(create<ast::DiscardStatement>())),
Return(),
@@ -815,8 +829,8 @@
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithDiscardAndNonVoidReturn) {
- Func("my_func", {Param("a", ty.i32())}, ty.i32(),
- {
+ Func("my_func", utils::Vector{Param("a", ty.i32())}, ty.i32(),
+ utils::Vector{
If(Equal("a", 0_i), //
Block(create<ast::DiscardStatement>())),
Return(42_i),
@@ -857,10 +871,10 @@
// return;
// }
- auto* s = Structure("Data", {Member("d", ty.f32())});
+ auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -868,12 +882,12 @@
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
- Func("a", {}, ty.void_(),
- {
+ Func("a", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -882,12 +896,12 @@
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
- Func("b", {}, ty.void_(),
- {
+ Func("b", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
index 8149b7f..a0068b9 100644
--- a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -86,24 +86,20 @@
template <typename BASE>
class HlslGeneratorImplTest_MemberAccessorBase : public BASE {
public:
- void SetupStorageBuffer(ast::StructMemberList members) {
+ void SetupStorageBuffer(utils::VectorRef<const ast::StructMember*> members) {
ProgramBuilder& b = *this;
-
auto* s = b.Structure("Data", members);
b.GlobalVar("data", b.ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- b.create<ast::BindingAttribute>(0u),
- b.create<ast::GroupAttribute>(1u),
- });
+ b.GroupAndBinding(1, 0));
}
- void SetupFunction(ast::StatementList statements) {
+ void SetupFunction(utils::VectorRef<const ast::Statement*> statements) {
ProgramBuilder& b = *this;
- b.Func("main", {}, b.ty.void_(), statements,
- {
- b.Stage(ast::PipelineStage::kFragment),
- });
+ utils::Vector attrs{
+ b.Stage(ast::PipelineStage::kFragment),
+ };
+ b.Func("main", utils::Empty, b.ty.void_(), std::move(statements), std::move(attrs));
}
};
@@ -114,7 +110,7 @@
HlslGeneratorImplTest_MemberAccessorBase<TestParamHelper<T>>;
TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
- auto* s = Structure("Data", {Member("mem", ty.f32())});
+ auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("str", "mem");
@@ -160,12 +156,12 @@
auto p = GetParam();
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("a", ty.i32()),
Member("b", p.member_type(ty)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone, MemberAccessor("data", "b"))),
});
@@ -231,12 +227,12 @@
auto p = GetParam();
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("a", ty.i32()),
Member("b", p.member_type(ty)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("value", p.member_type(ty), ast::StorageClass::kNone,
Construct(p.member_type(ty)))),
Assign(MemberAccessor("data", "b"), Expr("value")),
@@ -316,13 +312,13 @@
// var<storage> data : Data;
// data.a = mat2x3<f32>();
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("a", ty.i32()),
Member("b", ty.mat2x3<f32>()),
});
- SetupFunction({
- Assign(MemberAccessor("data", "b"), Construct(ty.mat2x3<f32>(), ast::ExpressionList{})),
+ SetupFunction(utils::Vector{
+ Assign(MemberAccessor("data", "b"), Construct(ty.mat2x3<f32>())),
});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -352,12 +348,12 @@
// var<storage> data : Data;
// data.a[2i][1i];
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("z", ty.f32()),
Member("a", ty.mat4x3<f32>()),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
IndexAccessor(IndexAccessor(MemberAccessor("data", "a"), 2_i), 1_i))),
});
@@ -384,12 +380,12 @@
// var<storage> data : Data;
// data.a[2];
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("z", ty.f32()),
Member("a", ty.array<i32, 5>(4)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
IndexAccessor(MemberAccessor("data", "a"), 2_i))),
});
@@ -416,14 +412,17 @@
// var<storage> data : Data;
// data.a[(2i + 4i) - 3i];
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("z", ty.f32()),
Member("a", ty.array<i32, 5>(4)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
+ Decl(Var("a", nullptr, Expr(2_i))),
+ Decl(Var("b", nullptr, Expr(4_i))),
+ Decl(Var("c", nullptr, Expr(3_i))),
Decl(Var("x", nullptr, ast::StorageClass::kNone,
- IndexAccessor(MemberAccessor("data", "a"), Sub(Add(2_i, Expr(4_i)), Expr(3_i))))),
+ IndexAccessor(MemberAccessor("data", "a"), Sub(Add("a", "b"), "c")))),
});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -433,7 +432,10 @@
R"(RWByteAddressBuffer data : register(u0, space1);
void main() {
- int x = asint(data.Load((4u + (4u * uint(((2 + 4) - 3))))));
+ int a = 2;
+ int b = 4;
+ int c = 3;
+ int x = asint(data.Load((4u + (4u * uint(((a + b) - c))))));
return;
}
)";
@@ -447,12 +449,12 @@
// var<storage> data : Data;
// data.a[2] = 2;
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("z", ty.f32()),
Member("a", ty.array<i32, 5>(4)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Assign(IndexAccessor(MemberAccessor("data", "a"), 2_i), 2_i),
});
@@ -482,16 +484,16 @@
// var<storage> data : Pre;
// data.c[2].b
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"))),
});
@@ -522,16 +524,16 @@
// var<storage> data : Pre;
// data.c[2].b.xy
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
MemberAccessor(
MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "xy"))),
@@ -564,16 +566,16 @@
// var<storage> data : Pre;
// data.c[2].b.g
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
MemberAccessor(
MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "g"))),
@@ -605,16 +607,16 @@
// var<storage> data : Pre;
// data.c[2].b[1]
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Decl(Var("x", nullptr, ast::StorageClass::kNone,
IndexAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
1_i))),
@@ -646,16 +648,16 @@
// var<storage> data : Pre;
// data.c[2].b = vec3<f32>(1_f, 2_f, 3_f);
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Assign(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
vec3<f32>(1_f, 2_f, 3_f)),
});
@@ -686,16 +688,16 @@
// var<storage> data : Pre;
// data.c[2].b.y = 1.f;
- auto* inner = Structure("Inner", {
+ auto* inner = Structure("Inner", utils::Vector{
Member("a", ty.vec3<i32>()),
Member("b", ty.vec3<f32>()),
});
- SetupStorageBuffer({
+ SetupStorageBuffer(utils::Vector{
Member("c", ty.array(ty.Of(inner), 4_u, 32)),
});
- SetupFunction({
+ SetupFunction(utils::Vector{
Assign(MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
"y"),
Expr(1_f)),
diff --git a/src/tint/writer/hlsl/generator_impl_module_constant_test.cc b/src/tint/writer/hlsl/generator_impl_module_constant_test.cc
index 9dc9acb..7296d13 100644
--- a/src/tint/writer/hlsl/generator_impl_module_constant_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_module_constant_test.cc
@@ -24,7 +24,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AInt) {
auto* var = GlobalConst("G", nullptr, Expr(1_a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -38,7 +38,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AFloat) {
auto* var = GlobalConst("G", nullptr, Expr(1._a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -52,7 +52,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_i32) {
auto* var = GlobalConst("G", nullptr, Expr(1_i));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -66,7 +66,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_u32) {
auto* var = GlobalConst("G", nullptr, Expr(1_u));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -80,7 +80,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_f32) {
auto* var = GlobalConst("G", nullptr, Expr(1_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -96,7 +96,7 @@
Enable(ast::Extension::kF16);
auto* var = GlobalConst("G", nullptr, Expr(1_h));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -110,7 +110,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AInt) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -124,7 +124,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AFloat) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -138,7 +138,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_f32) {
auto* var = GlobalConst("G", nullptr, vec3<f32>(1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -154,7 +154,7 @@
Enable(ast::Extension::kF16);
auto* var = GlobalConst("G", nullptr, vec3<f16>(1_h, 2_h, 3_h));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -169,7 +169,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_AFloat) {
auto* var = GlobalConst("G", nullptr,
Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -183,7 +183,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_f32) {
auto* var = GlobalConst("G", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -199,7 +199,7 @@
Enable(ast::Extension::kF16);
auto* var = GlobalConst("G", nullptr, mat2x3<f16>(1_h, 2_h, 3_h, 4_h, 5_h, 6_h));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -213,7 +213,7 @@
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_f32) {
auto* var = GlobalConst("G", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -231,7 +231,7 @@
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -244,7 +244,7 @@
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_Override) {
- auto* var = Override("pos", ty.f32(), Expr(3_f), {Id(23)});
+ auto* var = Override("pos", ty.f32(), Expr(3_f), utils::Vector{Id(23)});
GeneratorImpl& gen = Build();
@@ -257,7 +257,7 @@
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_Override_NoConstructor) {
- auto* var = Override("pos", ty.f32(), nullptr, {Id(23)});
+ auto* var = Override("pos", ty.f32(), nullptr, utils::Vector{Id(23)});
GeneratorImpl& gen = Build();
@@ -270,7 +270,7 @@
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_Override_NoId) {
- auto* a = Override("a", ty.f32(), Expr(3_f), {Id(0)});
+ auto* a = Override("a", ty.f32(), Expr(3_f), utils::Vector{Id(0)});
auto* b = Override("b", ty.f32(), Expr(2_f));
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_return_test.cc b/src/tint/writer/hlsl/generator_impl_return_test.cc
index 1813645..91b4159 100644
--- a/src/tint/writer/hlsl/generator_impl_return_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_return_test.cc
@@ -35,7 +35,7 @@
TEST_F(HlslGeneratorImplTest_Return, Emit_ReturnWithValue) {
auto* r = Return(123_i);
- Func("f", {}, ty.i32(), {r});
+ Func("f", utils::Empty, ty.i32(), utils::Vector{r});
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
index 3bb1cec..3d0785a 100644
--- a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
@@ -25,19 +25,19 @@
using HlslSanitizerTest = TestHelper;
TEST_F(HlslSanitizerTest, Call_ArrayLength) {
- auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -60,22 +60,22 @@
}
TEST_F(HlslSanitizerTest, Call_ArrayLength_OtherMembersInStruct) {
- auto* s = Structure("my_struct", {
+ auto* s = Structure("my_struct", utils::Vector{
Member(0, "z", ty.f32()),
Member(4, "a", ty.array<f32>(4)),
});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -99,9 +99,9 @@
}
TEST_F(HlslSanitizerTest, Call_ArrayLength_ViaLets) {
- auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
@@ -109,13 +109,13 @@
auto* p = Let("p", nullptr, AddressOf("b"));
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(p),
Decl(p2),
Decl(Var("len", ty.u32(), ast::StorageClass::kNone, Call("arrayLength", p2))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -139,25 +139,25 @@
}
TEST_F(HlslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniform) {
- auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
GlobalVar("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(2u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
Add(Call("arrayLength", AddressOf(MemberAccessor("b", "a"))),
Call("arrayLength", AddressOf(MemberAccessor("c", "a")))))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -189,12 +189,12 @@
TEST_F(HlslSanitizerTest, PromoteArrayInitializerToConstVar) {
auto* array_init = array<i32, 4>(1_i, 2_i, 3_i, 4_i);
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("idx", nullptr, Expr(3_i))),
Decl(Var("pos", ty.i32(), IndexAccessor(array_init, "idx"))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -214,7 +214,7 @@
}
TEST_F(HlslSanitizerTest, PromoteStructInitializerToConstVar) {
- auto* str = Structure("S", {
+ auto* str = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.vec3<f32>()),
Member("c", ty.i32()),
@@ -223,11 +223,11 @@
auto* struct_access = MemberAccessor(struct_init, "b");
auto* pos = Var("pos", ty.vec3<f32>(), ast::StorageClass::kNone, struct_access);
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(pos),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -259,13 +259,13 @@
auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), AddressOf(v));
auto* x = Var("x", ty.i32(), ast::StorageClass::kNone, Deref(p));
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(v),
Decl(p),
Decl(x),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -298,15 +298,15 @@
AddressOf(IndexAccessor(Deref(mp), 2_i)));
auto* v = Var("v", ty.vec4<f32>(), ast::StorageClass::kNone, Deref(vp));
- Func("main", {}, ty.void_(),
- {
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(a),
Decl(ap),
Decl(mp),
Decl(vp),
Decl(v),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
diff --git a/src/tint/writer/hlsl/generator_impl_static_assert_test.cc b/src/tint/writer/hlsl/generator_impl_static_assert_test.cc
new file mode 100644
index 0000000..8ae5dd8
--- /dev/null
+++ b/src/tint/writer/hlsl/generator_impl_static_assert_test.cc
@@ -0,0 +1,47 @@
+// Copyright 2022 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/writer/hlsl/test_helper.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::writer::hlsl {
+namespace {
+
+using HlslGeneratorImplTest = TestHelper;
+
+TEST_F(HlslGeneratorImplTest, Emit_GlobalStaticAssert) {
+ GlobalStaticAssert(true);
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ // static asserts are not emitted
+ EXPECT_EQ(gen.result(), "");
+}
+
+TEST_F(HlslGeneratorImplTest, Emit_FunctionStaticAssert) {
+ Func("f", utils::Empty, ty.void_(), utils::Vector{StaticAssert(true)});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ // static asserts are not emitted
+ EXPECT_EQ(gen.result(), R"(void f() {
+}
+)");
+}
+
+} // namespace
+} // namespace tint::writer::hlsl
diff --git a/src/tint/writer/hlsl/generator_impl_type_test.cc b/src/tint/writer/hlsl/generator_impl_type_test.cc
index 991c5c0..4e443d5 100644
--- a/src/tint/writer/hlsl/generator_impl_type_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_type_test.cc
@@ -154,7 +154,7 @@
}
TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
@@ -173,12 +173,12 @@
}
TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl_OmittedIfStorageBuffer) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -190,7 +190,7 @@
}
TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
@@ -206,7 +206,7 @@
}
TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("double", ty.i32()),
Member("float", ty.f32()),
});
@@ -223,9 +223,9 @@
}
TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_WithOffsetAttributes) {
- auto* s = Structure("S", {
- Member("a", ty.i32(), {MemberOffset(0)}),
- Member("b", ty.f32(), {MemberOffset(8)}),
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.i32(), utils::Vector{MemberOffset(0)}),
+ Member("b", ty.f32(), utils::Vector{MemberOffset(8)}),
});
GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
@@ -312,13 +312,18 @@
auto* t = ty.depth_texture(params.dim);
GlobalVar("tex", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("textureDimensions", "tex")),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
GeneratorImpl& gen = Build();
@@ -342,13 +347,18 @@
auto* t = ty.depth_multisampled_texture(ast::TextureDimension::k2d);
GlobalVar("tex", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("textureDimensions", "tex")),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
GeneratorImpl& gen = Build();
@@ -385,13 +395,18 @@
auto* t = ty.sampled_texture(params.dim, datatype);
GlobalVar("tex", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("textureDimensions", "tex")),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
GeneratorImpl& gen = Build();
@@ -519,10 +534,18 @@
auto* t = ty.storage_texture(params.dim, params.imgfmt, ast::Access::kWrite);
- GlobalVar("tex", t, ast::AttributeList{GroupAndBinding(2, 1)});
+ GlobalVar("tex", t,
+ utils::Vector{
+ GroupAndBinding(2, 1),
+ });
- Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call("textureDimensions", "tex")),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
index 9a741bc..db8fb77 100644
--- a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
@@ -66,7 +66,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AInt) {
auto* C = Const("C", nullptr, Expr(1_a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -80,7 +84,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AFloat) {
auto* C = Const("C", nullptr, Expr(1._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -94,7 +102,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_i32) {
auto* C = Const("C", nullptr, Expr(1_i));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -108,7 +120,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_u32) {
auto* C = Const("C", nullptr, Expr(1_u));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -122,7 +138,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_f32) {
auto* C = Const("C", nullptr, Expr(1_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -138,7 +158,11 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, Expr(1_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -152,7 +176,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AInt) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -166,7 +194,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AFloat) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -180,7 +212,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_f32) {
auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -196,7 +232,11 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, vec3<f16>(1_h, 2_h, 3_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -211,7 +251,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
auto* C =
Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -225,7 +269,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_f32) {
auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -241,7 +289,11 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, mat2x3<f16>(1_h, 2_h, 3_h, 4_h, 5_h, 6_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -255,7 +307,11 @@
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_f32) {
auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -273,7 +329,11 @@
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc b/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
index 5de44b1..9e8be01 100644
--- a/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
@@ -29,8 +29,8 @@
TEST_F(HlslGeneratorImplTest_WorkgroupVar, Basic) {
GlobalVar("wg", ty.f32(), ast::StorageClass::kWorkgroup);
- Func("main", {}, ty.void_(), {Assign("wg", 1.2_f)},
- {
+ Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -45,8 +45,8 @@
GlobalVar("wg", ty.Of(alias), ast::StorageClass::kWorkgroup);
- Func("main", {}, ty.void_(), {Assign("wg", 1.2_f)},
- {
+ Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc
index 3c1525f..602ec71 100644
--- a/src/tint/writer/msl/generator_impl.cc
+++ b/src/tint/writer/msl/generator_impl.cc
@@ -286,6 +286,9 @@
// Do nothing for enabling extension in MSL
return true;
},
+ [&](const ast::StaticAssert*) {
+ return true; // Not emitted
+ },
[&](Default) {
// These are pushed into the entry point by sanitizer transforms.
TINT_ICE(Writer, diagnostics_) << "unhandled type: " << decl->TypeInfo().name;
@@ -804,7 +807,7 @@
out << name;
{
ScopedParen sp(out);
- for (size_t i = 0; i < expr->args.size(); i++) {
+ for (size_t i = 0; i < expr->args.Length(); i++) {
auto* arg = expr->args[i];
if (i > 0) {
out << ", ";
@@ -1305,9 +1308,9 @@
return false;
}
- line(b) << "float" << width << " whole;";
- line(b) << "float" << width << " fract = modf(" << in << ", whole);";
- line(b) << "return {fract, whole};";
+ line(b) << StructName(builtin->ReturnType()->As<sem::Struct>()) << " result;";
+ line(b) << "result.fract = modf(" << in << ", result.whole);";
+ line(b) << "return result;";
return true;
});
}
@@ -1331,9 +1334,9 @@
return false;
}
- line(b) << "int" << width << " exp;";
- line(b) << "float" << width << " sig = frexp(" << in << ", exp);";
- line(b) << "return {sig, exp};";
+ line(b) << StructName(builtin->ReturnType()->As<sem::Struct>()) << " result;";
+ line(b) << "result.sig = frexp(" << in << ", result.exp);";
+ line(b) << "return result;";
return true;
});
}
@@ -1524,7 +1527,7 @@
return false;
}
out << ":";
- if (selector == stmt->selectors.back()) {
+ if (selector == stmt->selectors.Back()) {
out << " {";
}
}
@@ -1695,7 +1698,7 @@
return true;
},
[&](const sem::Struct* s) {
- out << "{";
+ out << program_->Symbols().NameFor(s->Name()) << "{";
TINT_DEFER(out << "}");
if (constant->AllZero()) {
@@ -2268,7 +2271,7 @@
return false;
}
} else {
- if (!EmitStatementsWithIndent({stmt->else_statement})) {
+ if (!EmitStatementsWithIndent(utils::Vector{stmt->else_statement})) {
return false;
}
}
@@ -2419,6 +2422,9 @@
return false;
});
},
+ [&](const ast::StaticAssert*) {
+ return true; // Not emitted
+ },
[&](Default) {
diagnostics_.add_error(diag::System::Writer,
"unknown statement type: " + std::string(stmt->TypeInfo().name));
@@ -2426,7 +2432,7 @@
});
}
-bool GeneratorImpl::EmitStatements(const ast::StatementList& stmts) {
+bool GeneratorImpl::EmitStatements(utils::VectorRef<const ast::Statement*> stmts) {
for (auto* s : stmts) {
if (!EmitStatement(s)) {
return false;
@@ -2435,7 +2441,7 @@
return true;
}
-bool GeneratorImpl::EmitStatementsWithIndent(const ast::StatementList& stmts) {
+bool GeneratorImpl::EmitStatementsWithIndent(utils::VectorRef<const ast::Statement*> stmts) {
ScopedIndent si(this);
return EmitStatements(stmts);
}
diff --git a/src/tint/writer/msl/generator_impl.h b/src/tint/writer/msl/generator_impl.h
index 137b365..72ee42c 100644
--- a/src/tint/writer/msl/generator_impl.h
+++ b/src/tint/writer/msl/generator_impl.h
@@ -294,11 +294,11 @@
/// Emits a list of statements
/// @param stmts the statement list
/// @returns true if the statements were emitted successfully
- bool EmitStatements(const ast::StatementList& stmts);
+ bool EmitStatements(utils::VectorRef<const ast::Statement*> stmts);
/// Emits a list of statements with an indentation
/// @param stmts the statement list
/// @returns true if the statements were emitted successfully
- bool EmitStatementsWithIndent(const ast::StatementList& stmts);
+ bool EmitStatementsWithIndent(utils::VectorRef<const ast::Statement*> stmts);
/// Handles generating a switch statement
/// @param stmt the statement to emit
/// @returns true if the statement was emitted
diff --git a/src/tint/writer/msl/generator_impl_builtin_test.cc b/src/tint/writer/msl/generator_impl_builtin_test.cc
index c8fab4b..9f75691 100644
--- a/src/tint/writer/msl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/msl/generator_impl_builtin_test.cc
@@ -234,8 +234,8 @@
auto* call = GenerateCall(param.builtin, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled builtin";
- Func("func", {}, ty.void_(), {Ignore(call)},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{Ignore(call)},
+ utils::Vector{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
GeneratorImpl& gen = Build();
@@ -405,6 +405,246 @@
EXPECT_EQ(out.str(), "threadgroup_barrier(mem_flags::mem_threadgroup)");
}
+TEST_F(MslGeneratorImplTest, Modf_Scalar_f32) {
+ auto* call = Call("modf", 1_f);
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+struct modf_result {
+ float fract;
+ float whole;
+};
+modf_result tint_modf(float param_0) {
+ modf_result result;
+ result.fract = modf(param_0, result.whole);
+ return result;
+}
+
+kernel void test_function() {
+ tint_modf(1.0f);
+ return;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Modf_Scalar_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("modf", 1_h);
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+struct modf_result_f16 {
+ half fract;
+ half whole;
+};
+modf_result_f16 tint_modf(half param_0) {
+ modf_result_f16 result;
+ result.fract = modf(param_0, result.whole);
+ return result;
+}
+
+kernel void test_function() {
+ tint_modf(1.0h);
+ return;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Modf_Vector_f32) {
+ auto* call = Call("modf", vec3<f32>());
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+struct modf_result_vec3 {
+ float3 fract;
+ float3 whole;
+};
+modf_result_vec3 tint_modf(float3 param_0) {
+ modf_result_vec3 result;
+ result.fract = modf(param_0, result.whole);
+ return result;
+}
+
+kernel void test_function() {
+ tint_modf(float3(0.0f));
+ return;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Modf_Vector_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("modf", vec3<f16>());
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+struct modf_result_vec3_f16 {
+ half3 fract;
+ half3 whole;
+};
+modf_result_vec3_f16 tint_modf(half3 param_0) {
+ modf_result_vec3_f16 result;
+ result.fract = modf(param_0, result.whole);
+ return result;
+}
+
+kernel void test_function() {
+ tint_modf(half3(0.0h));
+ return;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Frexp_Scalar_f32) {
+ auto* call = Call("frexp", 1_f);
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+struct frexp_result {
+ float sig;
+ int exp;
+};
+frexp_result tint_frexp(float param_0) {
+ frexp_result result;
+ result.sig = frexp(param_0, result.exp);
+ return result;
+}
+
+kernel void test_function() {
+ tint_frexp(1.0f);
+ return;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Frexp_Scalar_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("frexp", 1_h);
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+struct frexp_result_f16 {
+ half sig;
+ int exp;
+};
+frexp_result_f16 tint_frexp(half param_0) {
+ frexp_result_f16 result;
+ result.sig = frexp(param_0, result.exp);
+ return result;
+}
+
+kernel void test_function() {
+ tint_frexp(1.0h);
+ return;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Frexp_Vector_f32) {
+ auto* call = Call("frexp", vec3<f32>());
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+struct frexp_result_vec3 {
+ float3 sig;
+ int3 exp;
+};
+frexp_result_vec3 tint_frexp(float3 param_0) {
+ frexp_result_vec3 result;
+ result.sig = frexp(param_0, result.exp);
+ return result;
+}
+
+kernel void test_function() {
+ tint_frexp(float3(0.0f));
+ return;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Frexp_Vector_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* call = Call("frexp", vec3<f16>());
+ WrapInFunction(CallStmt(call));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+struct frexp_result_vec3_f16 {
+ half3 sig;
+ int3 exp;
+};
+frexp_result_vec3_f16 tint_frexp(half3 param_0) {
+ frexp_result_vec3_f16 result;
+ result.sig = frexp(param_0, result.exp);
+ return result;
+}
+
+kernel void test_function() {
+ tint_frexp(half3(0.0h));
+ return;
+}
+
+)");
+}
+
TEST_F(MslGeneratorImplTest, Degrees_Scalar_f32) {
auto* val = Var("val", ty.f32());
auto* call = Call("degrees", val);
@@ -662,11 +902,11 @@
}
TEST_F(MslGeneratorImplTest, Ignore) {
- Func("f", {Param("a", ty.i32()), Param("b", ty.i32()), Param("c", ty.i32())}, ty.i32(),
- {Return(Mul(Add("a", "b"), "c"))});
+ Func("f", utils::Vector{Param("a", ty.i32()), Param("b", ty.i32()), Param("c", ty.i32())},
+ ty.i32(), utils::Vector{Return(Mul(Add("a", "b"), "c"))});
- Func("func", {}, ty.void_(), {CallStmt(Call("f", 1_i, 2_i, 3_i))},
- {
+ Func("func", utils::Empty, ty.void_(), utils::Vector{CallStmt(Call("f", 1_i, 2_i, 3_i))},
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/writer/msl/generator_impl_builtin_texture_test.cc b/src/tint/writer/msl/generator_impl_builtin_texture_test.cc
index 20813fa..dd4a92f 100644
--- a/src/tint/writer/msl/generator_impl_builtin_texture_test.cc
+++ b/src/tint/writer/msl/generator_impl_builtin_texture_test.cc
@@ -280,7 +280,8 @@
auto* call = Call(Expr(param.function), param.args(this));
auto* stmt = CallStmt(call);
- Func("main", {}, ty.void_(), {stmt}, {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(), utils::Vector{stmt},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_call_test.cc b/src/tint/writer/msl/generator_impl_call_test.cc
index c7f3a02..1011ebd 100644
--- a/src/tint/writer/msl/generator_impl_call_test.cc
+++ b/src/tint/writer/msl/generator_impl_call_test.cc
@@ -23,7 +23,7 @@
using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitExpression_Call_WithoutParams) {
- Func("my_func", {}, ty.f32(), {Return(1.23_f)});
+ Func("my_func", utils::Empty, ty.f32(), utils::Vector{Return(1.23_f)});
auto* call = Call("my_func");
WrapInFunction(call);
@@ -37,11 +37,14 @@
TEST_F(MslGeneratorImplTest, EmitExpression_Call_WithParams) {
Func("my_func",
- {
+ utils::Vector{
Param(Sym(), ty.f32()),
Param(Sym(), ty.f32()),
},
- ty.f32(), {Return(1.23_f)});
+ ty.f32(),
+ utils::Vector{
+ Return(1.23_f),
+ });
GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
@@ -57,11 +60,11 @@
TEST_F(MslGeneratorImplTest, EmitStatement_Call) {
Func("my_func",
- {
+ utils::Vector{
Param(Sym(), ty.f32()),
Param(Sym(), ty.f32()),
},
- ty.void_(), ast::StatementList{}, ast::AttributeList{});
+ ty.void_(), utils::Empty, utils::Empty);
GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
diff --git a/src/tint/writer/msl/generator_impl_case_test.cc b/src/tint/writer/msl/generator_impl_case_test.cc
index 8fc1bc9..250d67d 100644
--- a/src/tint/writer/msl/generator_impl_case_test.cc
+++ b/src/tint/writer/msl/generator_impl_case_test.cc
@@ -69,7 +69,13 @@
}
TEST_F(MslGeneratorImplTest, Emit_Case_MultipleSelectors) {
- auto* s = Switch(1_i, Case({Expr(5_i), Expr(6_i)}, Block(create<ast::BreakStatement>())),
+ auto* s = Switch(1_i,
+ Case(
+ utils::Vector{
+ Expr(5_i),
+ Expr(6_i),
+ },
+ Block(create<ast::BreakStatement>())),
DefaultCase());
WrapInFunction(s);
diff --git a/src/tint/writer/msl/generator_impl_constructor_test.cc b/src/tint/writer/msl/generator_impl_constructor_test.cc
index 14fc4a5..b0bbbea 100644
--- a/src/tint/writer/msl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/msl/generator_impl_constructor_test.cc
@@ -387,7 +387,7 @@
}
TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Struct) {
- auto* str = Structure("S", {
+ auto* str = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
Member("c", ty.vec3<i32>()),
@@ -402,7 +402,7 @@
}
TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Struct_Empty) {
- auto* str = Structure("S", {
+ auto* str = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
Member("c", ty.vec3<i32>()),
diff --git a/src/tint/writer/msl/generator_impl_function_test.cc b/src/tint/writer/msl/generator_impl_function_test.cc
index c3f926d..0f891a2 100644
--- a/src/tint/writer/msl/generator_impl_function_test.cc
+++ b/src/tint/writer/msl/generator_impl_function_test.cc
@@ -24,8 +24,8 @@
using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Emit_Function) {
- Func("my_func", {}, ty.void_(),
- {
+ Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -46,12 +46,12 @@
TEST_F(MslGeneratorImplTest, Emit_Function_WithParams) {
Func("my_func",
- {
+ utils::Vector{
Param("a", ty.f32()),
Param("b", ty.i32()),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
});
@@ -71,8 +71,8 @@
}
TEST_F(MslGeneratorImplTest, Emit_Attribute_EntryPoint_NoReturn_Void) {
- Func("main", {}, ty.void_(), {/* no explicit return */},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(), {/* no explicit return */},
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
GeneratorImpl& gen = Build();
@@ -91,15 +91,15 @@
// fn frag_main(@location(0) foo : f32) -> @location(1) f32 {
// return foo;
// }
- auto* foo_in = Param("foo", ty.f32(), {Location(0)});
- Func("frag_main", {foo_in}, ty.f32(),
- {
+ auto* foo_in = Param("foo", ty.f32(), utils::Vector{Location(0)});
+ Func("frag_main", utils::Vector{foo_in}, ty.f32(),
+ utils::Vector{
Return("foo"),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(1),
});
@@ -135,15 +135,16 @@
// fn frag_main(@position(0) coord : vec4<f32>) -> @frag_depth f32 {
// return coord.x;
// }
- auto* coord_in = Param("coord", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)});
- Func("frag_main", {coord_in}, ty.f32(),
- {
+ auto* coord_in =
+ Param("coord", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)});
+ Func("frag_main", utils::Vector{coord_in}, ty.f32(),
+ utils::Vector{
Return(MemberAccessor("coord", "x")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Builtin(ast::BuiltinValue::kFragDepth),
});
@@ -185,23 +186,24 @@
// const g = colors.col2;
// }
auto* interface_struct = Structure(
- "Interface", {
- Member("col1", ty.f32(), {Location(1)}),
- Member("col2", ty.f32(), {Location(2)}),
- Member("pos", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)}),
- });
+ "Interface",
+ utils::Vector{
+ Member("col1", ty.f32(), utils::Vector{Location(1)}),
+ Member("col2", ty.f32(), utils::Vector{Location(2)}),
+ Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
+ });
- Func("vert_main", {}, ty.Of(interface_struct),
- {Return(Construct(ty.Of(interface_struct), Expr(0.5_f), Expr(0.25_f),
- Construct(ty.vec4<f32>())))},
- {Stage(ast::PipelineStage::kVertex)});
+ Func("vert_main", utils::Empty, ty.Of(interface_struct),
+ utils::Vector{Return(Construct(ty.Of(interface_struct), Expr(0.5_f), Expr(0.25_f),
+ Construct(ty.vec4<f32>())))},
+ utils::Vector{Stage(ast::PipelineStage::kVertex)});
- Func("frag_main", {Param("colors", ty.Of(interface_struct))}, ty.void_(),
- {
+ Func("frag_main", utils::Vector{Param("colors", ty.Of(interface_struct))}, ty.void_(),
+ utils::Vector{
WrapInStatement(Let("r", ty.f32(), MemberAccessor("colors", "col1"))),
WrapInStatement(Let("g", ty.f32(), MemberAccessor("colors", "col2"))),
},
- {Stage(ast::PipelineStage::kFragment)});
+ utils::Vector{Stage(ast::PipelineStage::kFragment)});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -222,7 +224,7 @@
};
Interface vert_main_inner() {
- Interface const tint_symbol_3 = {.col1=0.5f, .col2=0.25f, .pos=float4(0.0f)};
+ Interface const tint_symbol_3 = Interface{.col1=0.5f, .col2=0.25f, .pos=float4(0.0f)};
return tint_symbol_3;
}
@@ -268,18 +270,23 @@
// return foo(0.25);
// }
auto* vertex_output_struct = Structure(
- "VertexOutput", {Member("pos", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)})});
+ "VertexOutput",
+ utils::Vector{
+ Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
+ });
- Func("foo", {Param("x", ty.f32())}, ty.Of(vertex_output_struct),
- {
+ Func("foo", utils::Vector{Param("x", ty.f32())}, ty.Of(vertex_output_struct),
+ utils::Vector{
Return(Construct(ty.Of(vertex_output_struct),
Construct(ty.vec4<f32>(), "x", "x", "x", Expr(1_f)))),
});
- Func("vert_main1", {}, ty.Of(vertex_output_struct), {Return(Expr(Call("foo", Expr(0.5_f))))},
- {Stage(ast::PipelineStage::kVertex)});
+ Func("vert_main1", utils::Empty, ty.Of(vertex_output_struct),
+ utils::Vector{Return(Expr(Call("foo", Expr(0.5_f))))},
+ utils::Vector{Stage(ast::PipelineStage::kVertex)});
- Func("vert_main2", {}, ty.Of(vertex_output_struct), {Return(Expr(Call("foo", Expr(0.25_f))))},
- {Stage(ast::PipelineStage::kVertex)});
+ Func("vert_main2", utils::Empty, ty.Of(vertex_output_struct),
+ utils::Vector{Return(Expr(Call("foo", Expr(0.25_f))))},
+ utils::Vector{Stage(ast::PipelineStage::kVertex)});
GeneratorImpl& gen = SanitizeAndBuild();
@@ -330,25 +337,22 @@
}
TEST_F(MslGeneratorImplTest, Emit_FunctionAttribute_EntryPoint_With_RW_StorageBuffer) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0u),
- create<ast::GroupAttribute>(0u),
- });
+ GroupAndBinding(0, 0));
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -372,25 +376,22 @@
}
TEST_F(MslGeneratorImplTest, Emit_FunctionAttribute_EntryPoint_With_RO_StorageBuffer) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0u),
- create<ast::GroupAttribute>(0u),
- });
+ GroupAndBinding(0, 0));
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -414,30 +415,26 @@
}
TEST_F(MslGeneratorImplTest, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
- auto* ubo_ty = Structure("UBO", {Member("coord", ty.vec4<f32>())});
- auto* ubo = GlobalVar("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0u),
- create<ast::GroupAttribute>(0u),
- });
+ auto* ubo_ty = Structure("UBO", utils::Vector{Member("coord", ty.vec4<f32>())});
+ auto* ubo = GlobalVar("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform, GroupAndBinding(0, 0));
Func("sub_func",
- {
+ utils::Vector{
Param("param", ty.f32()),
},
ty.f32(),
- {
+ utils::Vector{
Return(MemberAccessor(MemberAccessor(ubo, "coord"), "x")),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -464,34 +461,31 @@
}
TEST_F(MslGeneratorImplTest, Emit_FunctionAttribute_Called_By_EntryPoint_With_RW_StorageBuffer) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0u),
- create<ast::GroupAttribute>(0u),
- });
+ GroupAndBinding(0, 0));
Func("sub_func",
- {
+ utils::Vector{
Param("param", ty.f32()),
},
ty.f32(),
- {
+ utils::Vector{
Return(MemberAccessor("coord", "b")),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -519,34 +513,31 @@
}
TEST_F(MslGeneratorImplTest, Emit_FunctionAttribute_Called_By_EntryPoint_With_RO_StorageBuffer) {
- auto* s = Structure("Data", {
+ auto* s = Structure("Data", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0u),
- create<ast::GroupAttribute>(0u),
- });
+ GroupAndBinding(0, 0));
Func("sub_func",
- {
+ utils::Vector{
Param("param", ty.f32()),
},
ty.f32(),
- {
+ utils::Vector{
Return(MemberAccessor("coord", "b")),
});
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
- Func("frag_main", {}, ty.void_(),
- {
+ Func("frag_main", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -575,11 +566,11 @@
TEST_F(MslGeneratorImplTest, Emit_Function_WithArrayParams) {
Func("my_func",
- {
+ utils::Vector{
Param("a", ty.array<f32, 5>()),
},
ty.void_(),
- {
+ utils::Vector{
Return(),
});
@@ -612,8 +603,8 @@
}
TEST_F(MslGeneratorImplTest, Emit_Function_WithArrayReturn) {
- Func("my_func", {}, ty.array<f32, 5>(),
- {
+ Func("my_func", utils::Empty, ty.array<f32, 5>(),
+ utils::Vector{
Return(Construct(ty.array<f32, 5>())),
});
@@ -663,23 +654,20 @@
// return;
// }
- auto* s = Structure("Data", {Member("d", ty.f32())});
+ auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0u),
- create<ast::GroupAttribute>(0u),
- });
+ GroupAndBinding(0, 0));
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
- Func("a", {}, ty.void_(),
- {
+ Func("a", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -688,8 +676,12 @@
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
- Func("b", {}, ty.void_(), {Decl(var), Return()},
- {
+ Func("b", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(var),
+ Return(),
+ },
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/writer/msl/generator_impl_loop_test.cc b/src/tint/writer/msl/generator_impl_loop_test.cc
index 50b69d0..7c84db0 100644
--- a/src/tint/writer/msl/generator_impl_loop_test.cc
+++ b/src/tint/writer/msl/generator_impl_loop_test.cc
@@ -40,7 +40,7 @@
}
TEST_F(MslGeneratorImplTest, Emit_LoopWithContinuing) {
- Func("a_statement", {}, ty.void_(), {});
+ Func("a_statement", {}, ty.void_(), utils::Empty);
auto* body = Block(create<ast::DiscardStatement>());
auto* continuing = Block(CallStmt(Call("a_statement")));
@@ -62,7 +62,7 @@
}
TEST_F(MslGeneratorImplTest, Emit_LoopNestedWithContinuing) {
- Func("a_statement", {}, ty.void_(), {});
+ Func("a_statement", {}, ty.void_(), utils::Empty);
GlobalVar("lhs", ty.f32(), ast::StorageClass::kPrivate);
GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
@@ -181,7 +181,7 @@
// return;
// }
- Func("f", {Param("i", ty.i32())}, ty.void_(), {});
+ Func("f", utils::Vector{Param("i", ty.i32())}, ty.void_(), utils::Empty);
auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
@@ -257,7 +257,7 @@
// return;
// }
- Func("f", {Param("i", ty.i32())}, ty.void_(), {});
+ Func("f", utils::Vector{Param("i", ty.i32())}, ty.void_(), utils::Empty);
auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
@@ -286,7 +286,7 @@
// return;
// }
- Func("a_statement", {}, ty.void_(), {});
+ Func("a_statement", {}, ty.void_(), utils::Empty);
auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1_i)),
Block(CallStmt(Call("a_statement"))));
@@ -312,7 +312,7 @@
// return;
// }
- Func("f", {Param("i", ty.i32())}, ty.void_(), {});
+ Func("f", utils::Vector{Param("i", ty.i32())}, ty.void_(), utils::Empty);
auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
diff --git a/src/tint/writer/msl/generator_impl_member_accessor_test.cc b/src/tint/writer/msl/generator_impl_member_accessor_test.cc
index 96824a1..e189910 100644
--- a/src/tint/writer/msl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/msl/generator_impl_member_accessor_test.cc
@@ -20,7 +20,7 @@
using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor) {
- GlobalVar("str", ty.Of(Structure("my_str", {Member("mem", ty.f32())})),
+ GlobalVar("str", ty.Of(Structure("my_str", utils::Vector{Member("mem", ty.f32())})),
ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("str", "mem");
WrapInFunction(expr);
diff --git a/src/tint/writer/msl/generator_impl_module_constant_test.cc b/src/tint/writer/msl/generator_impl_module_constant_test.cc
index 4834b3d..054a0f4 100644
--- a/src/tint/writer/msl/generator_impl_module_constant_test.cc
+++ b/src/tint/writer/msl/generator_impl_module_constant_test.cc
@@ -24,7 +24,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_AInt) {
auto* var = GlobalConst("G", nullptr, Expr(1_a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -42,7 +42,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_AFloat) {
auto* var = GlobalConst("G", nullptr, Expr(1._a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -60,7 +60,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_i32) {
auto* var = GlobalConst("G", nullptr, Expr(1_i));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -78,7 +78,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_u32) {
auto* var = GlobalConst("G", nullptr, Expr(1_u));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -96,7 +96,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_f32) {
auto* var = GlobalConst("G", nullptr, Expr(1_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -116,7 +116,7 @@
Enable(ast::Extension::kF16);
auto* var = GlobalConst("G", nullptr, Expr(1_h));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -134,7 +134,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_AInt) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -152,7 +152,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_AFloat) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -170,7 +170,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_f32) {
auto* var = GlobalConst("G", nullptr, vec3<f32>(1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -190,7 +190,7 @@
Enable(ast::Extension::kF16);
auto* var = GlobalConst("G", nullptr, vec3<f16>(1_h, 2_h, 3_h));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -209,7 +209,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_mat2x3_AFloat) {
auto* var = GlobalConst("G", nullptr,
Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -227,7 +227,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_mat2x3_f32) {
auto* var = GlobalConst("G", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -247,7 +247,7 @@
Enable(ast::Extension::kF16);
auto* var = GlobalConst("G", nullptr, mat2x3<f16>(1_h, 2_h, 3_h, 4_h, 5_h, 6_h));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -265,7 +265,7 @@
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_arr_f32) {
auto* var = GlobalConst("G", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -300,7 +300,7 @@
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
- Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
@@ -331,7 +331,7 @@
TEST_F(MslGeneratorImplTest, Emit_Override) {
auto* var = Override("pos", ty.f32(), Expr(3_f),
- ast::AttributeList{
+ utils::Vector{
Id(23),
});
@@ -343,7 +343,7 @@
TEST_F(MslGeneratorImplTest, Emit_Override_NoId) {
auto* var_a = Override("a", ty.f32(), nullptr,
- ast::AttributeList{
+ utils::Vector{
Id(0),
});
auto* var_b = Override("b", ty.f32(), nullptr);
diff --git a/src/tint/writer/msl/generator_impl_return_test.cc b/src/tint/writer/msl/generator_impl_return_test.cc
index 1443209..c9c3de7 100644
--- a/src/tint/writer/msl/generator_impl_return_test.cc
+++ b/src/tint/writer/msl/generator_impl_return_test.cc
@@ -35,7 +35,7 @@
TEST_F(MslGeneratorImplTest, Emit_ReturnWithValue) {
auto* r = Return(123_i);
- Func("f", {}, ty.i32(), {r});
+ Func("f", utils::Empty, ty.i32(), utils::Vector{r});
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_sanitizer_test.cc b/src/tint/writer/msl/generator_impl_sanitizer_test.cc
index 1514373..62ada06 100644
--- a/src/tint/writer/msl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/msl/generator_impl_sanitizer_test.cc
@@ -26,19 +26,19 @@
using MslSanitizerTest = TestHelper;
TEST_F(MslSanitizerTest, Call_ArrayLength) {
- auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -81,22 +81,22 @@
}
TEST_F(MslSanitizerTest, Call_ArrayLength_OtherMembersInStruct) {
- auto* s = Structure("my_struct", {
+ auto* s = Structure("my_struct", utils::Vector{
Member(0, "z", ty.f32()),
Member(4, "a", ty.array<f32>(4)),
});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -141,9 +141,9 @@
}
TEST_F(MslSanitizerTest, Call_ArrayLength_ViaLets) {
- auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
@@ -151,13 +151,13 @@
auto* p = Let("p", nullptr, AddressOf("b"));
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(p),
Decl(p2),
Decl(Var("len", ty.u32(), ast::StorageClass::kNone, Call("arrayLength", p2))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -201,25 +201,25 @@
}
TEST_F(MslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniform) {
- auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(0u),
});
GlobalVar("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(2u),
create<ast::GroupAttribute>(0u),
});
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
Add(Call("arrayLength", AddressOf(MemberAccessor("b", "a"))),
Call("arrayLength", AddressOf(MemberAccessor("c", "a")))))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -266,25 +266,25 @@
}
TEST_F(MslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniformMissingBinding) {
- auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(0u),
});
GlobalVar("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(2u),
create<ast::GroupAttribute>(0u),
});
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
Add(Call("arrayLength", AddressOf(MemberAccessor("b", "a"))),
Call("arrayLength", AddressOf(MemberAccessor("c", "a")))))),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
diff --git a/src/tint/writer/msl/generator_impl_static_assert_test.cc b/src/tint/writer/msl/generator_impl_static_assert_test.cc
new file mode 100644
index 0000000..5b8ca3f
--- /dev/null
+++ b/src/tint/writer/msl/generator_impl_static_assert_test.cc
@@ -0,0 +1,54 @@
+// Copyright 2022 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/writer/msl/test_helper.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::writer::msl {
+namespace {
+
+using MslGeneratorImplTest = TestHelper;
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalStaticAssert) {
+ GlobalStaticAssert(true);
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ // static asserts are not emitted
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_FunctionStaticAssert) {
+ Func("f", utils::Empty, ty.void_(), utils::Vector{StaticAssert(true)});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ // static asserts are not emitted
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+}
+
+)");
+}
+
+} // namespace
+} // namespace tint::writer::msl
diff --git a/src/tint/writer/msl/generator_impl_switch_test.cc b/src/tint/writer/msl/generator_impl_switch_test.cc
index ce8087b..b327f34 100644
--- a/src/tint/writer/msl/generator_impl_switch_test.cc
+++ b/src/tint/writer/msl/generator_impl_switch_test.cc
@@ -25,19 +25,15 @@
auto* cond = Var("cond", ty.i32());
auto* def_body = Block(create<ast::BreakStatement>());
- auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
+ auto* def = create<ast::CaseStatement>(utils::Empty, def_body);
- ast::CaseSelectorList case_val;
- case_val.push_back(Expr(5_i));
+ utils::Vector case_val{Expr(5_i)};
auto* case_body = Block(create<ast::BreakStatement>());
auto* case_stmt = create<ast::CaseStatement>(case_val, case_body);
- ast::CaseStatementList body;
- body.push_back(case_stmt);
- body.push_back(def);
-
+ utils::Vector body{case_stmt, def};
auto* s = create<ast::SwitchStatement>(Expr(cond), body);
WrapInFunction(cond, s);
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_test.cc b/src/tint/writer/msl/generator_impl_test.cc
index 45010b2..63c56b0 100644
--- a/src/tint/writer/msl/generator_impl_test.cc
+++ b/src/tint/writer/msl/generator_impl_test.cc
@@ -32,8 +32,8 @@
}
TEST_F(MslGeneratorImplTest, Generate) {
- Func("my_func", {}, ty.void_(), {},
- {
+ Func("my_func", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -86,10 +86,17 @@
MslBuiltinData{ast::BuiltinValue::kPointSize, "point_size"}));
TEST_F(MslGeneratorImplTest, HasInvariantAttribute_True) {
- auto* out = Structure("Out", {Member("pos", ty.vec4<f32>(),
- {Builtin(ast::BuiltinValue::kPosition), Invariant()})});
- Func("vert_main", {}, ty.Of(out), {Return(Construct(ty.Of(out)))},
- {Stage(ast::PipelineStage::kVertex)});
+ auto* out = Structure("Out", utils::Vector{
+ Member("pos", ty.vec4<f32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ Invariant(),
+ }),
+ });
+ Func("vert_main", utils::Empty, ty.Of(out), utils::Vector{Return(Construct(ty.Of(out)))},
+ utils::Vector{
+ Stage(ast::PipelineStage::kVertex),
+ });
GeneratorImpl& gen = Build();
@@ -110,17 +117,23 @@
};
vertex Out vert_main() {
- return {};
+ return Out{};
}
)");
}
TEST_F(MslGeneratorImplTest, HasInvariantAttribute_False) {
- auto* out =
- Structure("Out", {Member("pos", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)})});
- Func("vert_main", {}, ty.Of(out), {Return(Construct(ty.Of(out)))},
- {Stage(ast::PipelineStage::kVertex)});
+ auto* out = Structure("Out", utils::Vector{
+ Member("pos", ty.vec4<f32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ }),
+ });
+ Func("vert_main", utils::Empty, ty.Of(out), utils::Vector{Return(Construct(ty.Of(out)))},
+ utils::Vector{
+ Stage(ast::PipelineStage::kVertex),
+ });
GeneratorImpl& gen = Build();
@@ -134,7 +147,7 @@
};
vertex Out vert_main() {
- return {};
+ return Out{};
}
)");
@@ -142,8 +155,11 @@
TEST_F(MslGeneratorImplTest, WorkgroupMatrix) {
GlobalVar("m", ty.mat2x2<f32>(), ast::StorageClass::kWorkgroup);
- Func("comp_main", {}, ty.void_(), {Decl(Let("x", nullptr, Expr("m")))},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ Func("comp_main", utils::Empty, ty.void_(), utils::Vector{Decl(Let("x", nullptr, Expr("m")))},
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(1_i),
+ });
GeneratorImpl& gen = SanitizeAndBuild();
@@ -179,8 +195,11 @@
TEST_F(MslGeneratorImplTest, WorkgroupMatrixInArray) {
GlobalVar("m", ty.array(ty.mat2x2<f32>(), 4_i), ast::StorageClass::kWorkgroup);
- Func("comp_main", {}, ty.void_(), {Decl(Let("x", nullptr, Expr("m")))},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ Func("comp_main", utils::Empty, ty.void_(), utils::Vector{Decl(Let("x", nullptr, Expr("m")))},
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(1_i),
+ });
GeneratorImpl& gen = SanitizeAndBuild();
@@ -229,16 +248,19 @@
}
TEST_F(MslGeneratorImplTest, WorkgroupMatrixInStruct) {
- Structure("S1", {
+ Structure("S1", utils::Vector{
Member("m1", ty.mat2x2<f32>()),
Member("m2", ty.mat4x4<f32>()),
});
- Structure("S2", {
+ Structure("S2", utils::Vector{
Member("s", ty.type_name("S1")),
});
GlobalVar("s", ty.type_name("S2"), ast::StorageClass::kWorkgroup);
- Func("comp_main", {}, ty.void_(), {Decl(Let("x", nullptr, Expr("s")))},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ Func("comp_main", utils::Empty, ty.void_(), utils::Vector{Decl(Let("x", nullptr, Expr("s")))},
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(1_i),
+ });
GeneratorImpl& gen = SanitizeAndBuild();
@@ -261,7 +283,7 @@
void comp_main_inner(uint local_invocation_index, threadgroup S2* const tint_symbol_1) {
{
- S2 const tint_symbol = {};
+ S2 const tint_symbol = S2{};
*(tint_symbol_1) = tint_symbol;
}
threadgroup_barrier(mem_flags::mem_threadgroup);
@@ -292,29 +314,41 @@
GlobalVar("m7", ty.mat4x2<f32>(), ast::StorageClass::kWorkgroup);
GlobalVar("m8", ty.mat4x3<f32>(), ast::StorageClass::kWorkgroup);
GlobalVar("m9", ty.mat4x4<f32>(), ast::StorageClass::kWorkgroup);
- Func("main1", {}, ty.void_(),
- {
+ Func("main1", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("a1", nullptr, Expr("m1"))),
Decl(Let("a2", nullptr, Expr("m2"))),
Decl(Let("a3", nullptr, Expr("m3"))),
},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
- Func("main2", {}, ty.void_(),
- {
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(1_i),
+ });
+ Func("main2", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("a1", nullptr, Expr("m4"))),
Decl(Let("a2", nullptr, Expr("m5"))),
Decl(Let("a3", nullptr, Expr("m6"))),
},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
- Func("main3", {}, ty.void_(),
- {
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(1_i),
+ });
+ Func("main3", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("a1", nullptr, Expr("m7"))),
Decl(Let("a2", nullptr, Expr("m8"))),
Decl(Let("a3", nullptr, Expr("m9"))),
},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
- Func("main4_no_usages", {}, ty.void_(), {},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(1_i),
+ });
+ Func("main4_no_usages", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kCompute),
+ WorkgroupSize(1_i),
+ });
GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/msl/generator_impl_type_test.cc b/src/tint/writer/msl/generator_impl_type_test.cc
index 4ed5a76..a3e85a5 100644
--- a/src/tint/writer/msl/generator_impl_type_test.cc
+++ b/src/tint/writer/msl/generator_impl_type_test.cc
@@ -221,7 +221,7 @@
}
TEST_F(MslGeneratorImplTest, EmitType_Struct) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
@@ -234,7 +234,7 @@
}
TEST_F(MslGeneratorImplTest, EmitType_StructDecl) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
@@ -252,37 +252,38 @@
}
TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_NonComposites) {
- auto* s = Structure("S", {
- Member("a", ty.i32(), {MemberSize(32)}),
- Member("b", ty.f32(), {MemberAlign(128), MemberSize(128)}),
- Member("c", ty.vec2<f32>()),
- Member("d", ty.u32()),
- Member("e", ty.vec3<f32>()),
- Member("f", ty.u32()),
- Member("g", ty.vec4<f32>()),
- Member("h", ty.u32()),
- Member("i", ty.mat2x2<f32>()),
- Member("j", ty.u32()),
- Member("k", ty.mat2x3<f32>()),
- Member("l", ty.u32()),
- Member("m", ty.mat2x4<f32>()),
- Member("n", ty.u32()),
- Member("o", ty.mat3x2<f32>()),
- Member("p", ty.u32()),
- Member("q", ty.mat3x3<f32>()),
- Member("r", ty.u32()),
- Member("s", ty.mat3x4<f32>()),
- Member("t", ty.u32()),
- Member("u", ty.mat4x2<f32>()),
- Member("v", ty.u32()),
- Member("w", ty.mat4x3<f32>()),
- Member("x", ty.u32()),
- Member("y", ty.mat4x4<f32>()),
- Member("z", ty.f32()),
- });
+ auto* s =
+ Structure("S", utils::Vector{
+ Member("a", ty.i32(), utils::Vector{MemberSize(32)}),
+ Member("b", ty.f32(), utils::Vector{MemberAlign(128), MemberSize(128)}),
+ Member("c", ty.vec2<f32>()),
+ Member("d", ty.u32()),
+ Member("e", ty.vec3<f32>()),
+ Member("f", ty.u32()),
+ Member("g", ty.vec4<f32>()),
+ Member("h", ty.u32()),
+ Member("i", ty.mat2x2<f32>()),
+ Member("j", ty.u32()),
+ Member("k", ty.mat2x3<f32>()),
+ Member("l", ty.u32()),
+ Member("m", ty.mat2x4<f32>()),
+ Member("n", ty.u32()),
+ Member("o", ty.mat3x2<f32>()),
+ Member("p", ty.u32()),
+ Member("q", ty.mat3x3<f32>()),
+ Member("r", ty.u32()),
+ Member("s", ty.mat3x4<f32>()),
+ Member("t", ty.u32()),
+ Member("u", ty.mat4x2<f32>()),
+ Member("v", ty.u32()),
+ Member("w", ty.mat4x3<f32>()),
+ Member("x", ty.u32()),
+ Member("y", ty.mat4x4<f32>()),
+ Member("z", ty.f32()),
+ });
GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -371,18 +372,18 @@
TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_Structures) {
// inner_x: size(1024), align(512)
- auto* inner_x = Structure("inner_x", {
+ auto* inner_x = Structure("inner_x", utils::Vector{
Member("a", ty.i32()),
- Member("b", ty.f32(), {MemberAlign(512)}),
+ Member("b", ty.f32(), utils::Vector{MemberAlign(512)}),
});
// inner_y: size(516), align(4)
- auto* inner_y = Structure("inner_y", {
- Member("a", ty.i32(), {MemberSize(512)}),
+ auto* inner_y = Structure("inner_y", utils::Vector{
+ Member("a", ty.i32(), utils::Vector{MemberSize(512)}),
Member("b", ty.f32()),
});
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.Of(inner_x)),
Member("c", ty.f32()),
@@ -391,7 +392,7 @@
});
GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -461,9 +462,9 @@
TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) {
// inner: size(1024), align(512)
- auto* inner = Structure("inner", {
+ auto* inner = Structure("inner", utils::Vector{
Member("a", ty.i32()),
- Member("b", ty.f32(), {MemberAlign(512)}),
+ Member("b", ty.f32(), utils::Vector{MemberAlign(512)}),
});
// array_x: size(28), align(4)
@@ -475,7 +476,7 @@
// array_z: size(4), align(4)
auto* array_z = ty.array<f32>();
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", array_x),
Member("c", ty.f32()),
@@ -485,7 +486,7 @@
});
GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -564,14 +565,14 @@
// array: size(64), align(16)
auto* array = ty.array(ty.vec3<f32>(), 4_u);
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", array),
Member("c", ty.i32()),
});
GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -603,39 +604,39 @@
}
TEST_F(MslGeneratorImplTest, AttemptTintPadSymbolCollision) {
- auto* s =
- Structure("S", {
- // uses symbols tint_pad_[0..9] and tint_pad_[20..35]
- Member("tint_pad_2", ty.i32(), {MemberSize(32)}),
- Member("tint_pad_20", ty.f32(), {MemberAlign(128), MemberSize(128)}),
- Member("tint_pad_33", ty.vec2<f32>()),
- Member("tint_pad_1", ty.u32()),
- Member("tint_pad_3", ty.vec3<f32>()),
- Member("tint_pad_7", ty.u32()),
- Member("tint_pad_25", ty.vec4<f32>()),
- Member("tint_pad_5", ty.u32()),
- Member("tint_pad_27", ty.mat2x2<f32>()),
- Member("tint_pad_24", ty.u32()),
- Member("tint_pad_23", ty.mat2x3<f32>()),
- Member("tint_pad", ty.u32()),
- Member("tint_pad_8", ty.mat2x4<f32>()),
- Member("tint_pad_26", ty.u32()),
- Member("tint_pad_29", ty.mat3x2<f32>()),
- Member("tint_pad_6", ty.u32()),
- Member("tint_pad_22", ty.mat3x3<f32>()),
- Member("tint_pad_32", ty.u32()),
- Member("tint_pad_34", ty.mat3x4<f32>()),
- Member("tint_pad_35", ty.u32()),
- Member("tint_pad_30", ty.mat4x2<f32>()),
- Member("tint_pad_9", ty.u32()),
- Member("tint_pad_31", ty.mat4x3<f32>()),
- Member("tint_pad_28", ty.u32()),
- Member("tint_pad_4", ty.mat4x4<f32>()),
- Member("tint_pad_21", ty.f32()),
- });
+ auto* s = Structure(
+ "S", utils::Vector{
+ // uses symbols tint_pad_[0..9] and tint_pad_[20..35]
+ Member("tint_pad_2", ty.i32(), utils::Vector{MemberSize(32)}),
+ Member("tint_pad_20", ty.f32(), utils::Vector{MemberAlign(128), MemberSize(128)}),
+ Member("tint_pad_33", ty.vec2<f32>()),
+ Member("tint_pad_1", ty.u32()),
+ Member("tint_pad_3", ty.vec3<f32>()),
+ Member("tint_pad_7", ty.u32()),
+ Member("tint_pad_25", ty.vec4<f32>()),
+ Member("tint_pad_5", ty.u32()),
+ Member("tint_pad_27", ty.mat2x2<f32>()),
+ Member("tint_pad_24", ty.u32()),
+ Member("tint_pad_23", ty.mat2x3<f32>()),
+ Member("tint_pad", ty.u32()),
+ Member("tint_pad_8", ty.mat2x4<f32>()),
+ Member("tint_pad_26", ty.u32()),
+ Member("tint_pad_29", ty.mat3x2<f32>()),
+ Member("tint_pad_6", ty.u32()),
+ Member("tint_pad_22", ty.mat3x3<f32>()),
+ Member("tint_pad_32", ty.u32()),
+ Member("tint_pad_34", ty.mat3x4<f32>()),
+ Member("tint_pad_35", ty.u32()),
+ Member("tint_pad_30", ty.mat4x2<f32>()),
+ Member("tint_pad_9", ty.u32()),
+ Member("tint_pad_31", ty.mat4x3<f32>()),
+ Member("tint_pad_28", ty.u32()),
+ Member("tint_pad_4", ty.mat4x4<f32>()),
+ Member("tint_pad_21", ty.f32()),
+ });
GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -690,13 +691,13 @@
}
TEST_F(MslGeneratorImplTest, EmitType_Struct_WithAttribute) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -863,7 +864,7 @@
auto* s = ty.storage_texture(params.dim, ast::TexelFormat::kR32Float, ast::Access::kWrite);
GlobalVar("test_var", s,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
diff --git a/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
index 10c5b3d..726e634 100644
--- a/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
@@ -66,7 +66,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_AInt) {
auto* C = Const("C", nullptr, Expr(1_a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -84,7 +84,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_AFloat) {
auto* C = Const("C", nullptr, Expr(1._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -102,7 +102,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_i32) {
auto* C = Const("C", nullptr, Expr(1_i));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -120,7 +120,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_u32) {
auto* C = Const("C", nullptr, Expr(1_u));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -138,7 +138,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_f32) {
auto* C = Const("C", nullptr, Expr(1_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -158,7 +158,7 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, Expr(1_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -176,7 +176,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AInt) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -194,7 +194,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AFloat) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -212,7 +212,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_f32) {
auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -232,7 +232,7 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, vec3<f16>(1_h, 2_h, 3_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -251,7 +251,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
auto* C =
Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -269,7 +269,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_f32) {
auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -289,7 +289,7 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, mat2x3<f16>(1_h, 2_h, 3_h, 4_h, 5_h, 6_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -307,7 +307,7 @@
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_f32) {
auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -342,7 +342,7 @@
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
@@ -385,7 +385,7 @@
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Struct) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.f32()),
});
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index 488cbf8..933b562 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -2464,7 +2464,7 @@
}
// Runtime array must be the last member in the structure
params.push_back(
- Operand(uint32_t(type->As<sem::Struct>()->Declaration()->members.size() - 1)));
+ Operand(uint32_t(type->As<sem::Struct>()->Declaration()->members.Length() - 1)));
if (!push_function_inst(spv::Op::OpArrayLength, params)) {
return 0;
@@ -3486,7 +3486,7 @@
// if (cond) {} else {break;}
// }
auto is_just_a_break = [](const ast::BlockStatement* block) {
- return block && (block->statements.size() == 1) &&
+ return block && (block->statements.Length() == 1) &&
block->Last()->Is<ast::BreakStatement>();
};
if (is_just_a_break(stmt->body) && stmt->else_statement == nullptr) {
@@ -3576,7 +3576,7 @@
// source. Each fallthrough goes to the next case entry, so is a forward
// branch, otherwise the branch is to the merge block which comes after
// the switch statement.
- for (uint32_t i = 0; i < body.size(); i++) {
+ for (uint32_t i = 0; i < body.Length(); i++) {
auto* item = body[i];
if (item->IsDefault()) {
@@ -3591,7 +3591,7 @@
}
if (LastIsFallthrough(item->body)) {
- if (i == (body.size() - 1)) {
+ if (i == (body.Length() - 1)) {
// This case is caught by Resolver validation
TINT_UNREACHABLE(Writer, builder_.Diagnostics());
return false;
@@ -3723,12 +3723,8 @@
bool Builder::GenerateStatement(const ast::Statement* stmt) {
return Switch(
stmt, [&](const ast::AssignmentStatement* a) { return GenerateAssignStatement(a); },
- [&](const ast::BlockStatement* b) { //
- return GenerateBlockStatement(b);
- },
- [&](const ast::BreakStatement* b) { //
- return GenerateBreakStatement(b);
- },
+ [&](const ast::BlockStatement* b) { return GenerateBlockStatement(b); },
+ [&](const ast::BreakStatement* b) { return GenerateBreakStatement(b); },
[&](const ast::CallStatement* c) { return GenerateCallExpression(c->expr) != 0; },
[&](const ast::ContinueStatement* c) { return GenerateContinueStatement(c); },
[&](const ast::DiscardStatement* d) { return GenerateDiscardStatement(d); },
@@ -3736,19 +3732,14 @@
// Do nothing here, the fallthrough gets handled by the switch code.
return true;
},
- [&](const ast::IfStatement* i) { //
- return GenerateIfStatement(i);
- },
- [&](const ast::LoopStatement* l) { //
- return GenerateLoopStatement(l);
- },
- [&](const ast::ReturnStatement* r) { //
- return GenerateReturnStatement(r);
- },
- [&](const ast::SwitchStatement* s) { //
- return GenerateSwitchStatement(s);
- },
+ [&](const ast::IfStatement* i) { return GenerateIfStatement(i); },
+ [&](const ast::LoopStatement* l) { return GenerateLoopStatement(l); },
+ [&](const ast::ReturnStatement* r) { return GenerateReturnStatement(r); },
+ [&](const ast::SwitchStatement* s) { return GenerateSwitchStatement(s); },
[&](const ast::VariableDeclStatement* v) { return GenerateVariableDeclStatement(v); },
+ [&](const ast::StaticAssert*) {
+ return true; // Not emitted
+ },
[&](Default) {
error_ = "Unknown statement: " + std::string(stmt->TypeInfo().name);
return false;
@@ -4121,6 +4112,8 @@
return SpvStorageClassUniform;
case ast::StorageClass::kWorkgroup:
return SpvStorageClassWorkgroup;
+ case ast::StorageClass::kPushConstant:
+ return SpvStorageClassPushConstant;
case ast::StorageClass::kHandle:
return SpvStorageClassUniformConstant;
case ast::StorageClass::kStorage:
diff --git a/src/tint/writer/spirv/builder_accessor_expression_test.cc b/src/tint/writer/spirv/builder_accessor_expression_test.cc
index 23dc783..0c0dc3f 100644
--- a/src/tint/writer/spirv/builder_accessor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_accessor_expression_test.cc
@@ -162,10 +162,10 @@
TEST_F(BuilderTest, Const_IndexAccessor_Vector2) {
// let ary : vec3<i32>(1, 2, 3);
- // var x = ary[1i + 2i];
+ // var x = ary[1i + 1i];
auto* ary = Let("ary", nullptr, vec3<i32>(1_i, 2_i, 3_i));
- auto* x = Var("x", nullptr, IndexAccessor(ary, Add(1_i, 2_i)));
+ auto* x = Var("x", nullptr, IndexAccessor(ary, Add(1_i, 1_i)));
WrapInFunction(ary, x);
spirv::Builder& b = SanitizeAndBuild();
@@ -180,14 +180,14 @@
%8 = OpConstant %6 2
%9 = OpConstant %6 3
%10 = OpConstantComposite %5 %7 %8 %9
-%14 = OpTypePointer Function %6
-%15 = OpConstantNull %6
+%13 = OpTypePointer Function %6
+%14 = OpConstantNull %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%13 = OpVariable %14 Function %15
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%12 = OpVariable %13 Function %14
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%11 = OpIAdd %6 %7 %8
-%12 = OpVectorExtractDynamic %6 %10 %11
-OpStore %13 %12
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%11 = OpCompositeExtract %6 %10 2
+OpStore %12 %11
OpReturn
)");
@@ -196,10 +196,10 @@
TEST_F(BuilderTest, Runtime_IndexAccessor_Vector2) {
// var ary : vec3<f32>;
- // var x = ary[1i + 2i];
+ // var x = ary[1i + 1i];
auto* ary = Var("ary", ty.vec3<f32>());
- auto* x = Var("x", nullptr, IndexAccessor(ary, Add(1_i, 2_i)));
+ auto* x = Var("x", nullptr, IndexAccessor(ary, Add(1_i, 1_i)));
WrapInFunction(ary, x);
spirv::Builder& b = SanitizeAndBuild();
@@ -213,18 +213,16 @@
%6 = OpTypePointer Function %7
%9 = OpConstantNull %7
%10 = OpTypeInt 32 1
-%11 = OpConstant %10 1
-%12 = OpConstant %10 2
-%14 = OpTypePointer Function %8
-%18 = OpConstantNull %8
+%11 = OpConstant %10 2
+%12 = OpTypePointer Function %8
+%16 = OpConstantNull %8
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
-%17 = OpVariable %14 Function %18
+%15 = OpVariable %12 Function %16
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpIAdd %10 %11 %12
-%15 = OpAccessChain %14 %5 %13
-%16 = OpLoad %8 %15
-OpStore %17 %16
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+%14 = OpLoad %8 %13
+OpStore %15 %14
OpReturn
)");
@@ -902,7 +900,7 @@
// var ident : my_struct
// ident.b
- auto* s = Structure("my_struct", {
+ auto* s = Structure("my_struct", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.f32()),
});
@@ -947,12 +945,12 @@
//
// var ident : my_struct
// ident.inner.a
- auto* inner_struct = Structure("Inner", {
+ auto* inner_struct = Structure("Inner", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.f32()),
});
- auto* s_type = Structure("my_struct", {Member("inner", ty.Of(inner_struct))});
+ auto* s_type = Structure("my_struct", utils::Vector{Member("inner", ty.Of(inner_struct))});
auto* var = Var("ident", ty.Of(s_type));
auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "b");
@@ -993,7 +991,7 @@
// let ident : my_struct = my_struct();
// ident.b
- auto* s = Structure("my_struct", {
+ auto* s = Structure("my_struct", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.f32()),
});
@@ -1032,12 +1030,12 @@
//
// let ident : my_struct = my_struct();
// ident.inner.a
- auto* inner_struct = Structure("Inner", {
+ auto* inner_struct = Structure("Inner", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.f32()),
});
- auto* s_type = Structure("my_struct", {Member("inner", ty.Of(inner_struct))});
+ auto* s_type = Structure("my_struct", utils::Vector{Member("inner", ty.Of(inner_struct))});
auto* var = Let("ident", ty.Of(s_type),
Construct(ty.Of(s_type), Construct(ty.Of(inner_struct), 0_f, 0_f)));
@@ -1077,13 +1075,13 @@
//
// var ident : my_struct
// ident.inner.a
- auto* inner_struct = Structure("Inner", {
+ auto* inner_struct = Structure("Inner", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.f32()),
});
auto* alias = Alias("Alias", ty.Of(inner_struct));
- auto* s_type = Structure("Outer", {Member("inner", ty.Of(alias))});
+ auto* s_type = Structure("Outer", utils::Vector{Member("inner", ty.Of(alias))});
auto* var = Var("ident", ty.Of(s_type));
auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "a");
@@ -1125,12 +1123,12 @@
//
// var ident : my_struct
// ident.inner.a = 2.0f;
- auto* inner_struct = Structure("Inner", {
+ auto* inner_struct = Structure("Inner", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.f32()),
});
- auto* s_type = Structure("my_struct", {Member("inner", ty.Of(inner_struct))});
+ auto* s_type = Structure("my_struct", utils::Vector{Member("inner", ty.Of(inner_struct))});
auto* var = Var("ident", ty.Of(s_type));
auto* expr = Assign(MemberAccessor(MemberAccessor("ident", "inner"), "a"), Expr(2_f));
@@ -1174,12 +1172,12 @@
// var ident : my_struct
// var store : f32 = ident.inner.a
- auto* inner_struct = Structure("Inner", {
+ auto* inner_struct = Structure("Inner", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.f32()),
});
- auto* s_type = Structure("my_struct", {Member("inner", ty.Of(inner_struct))});
+ auto* s_type = Structure("my_struct", utils::Vector{Member("inner", ty.Of(inner_struct))});
auto* var = Var("ident", ty.Of(s_type));
auto* store = Var("store", ty.f32());
@@ -1385,11 +1383,11 @@
// var index : array<A, 2u>
// index[0i].foo[2i].bar.baz.yx
- auto* c_type = Structure("C", {Member("baz", ty.vec3<f32>())});
+ auto* c_type = Structure("C", utils::Vector{Member("baz", ty.vec3<f32>())});
- auto* b_type = Structure("B", {Member("bar", ty.Of(c_type))});
+ auto* b_type = Structure("B", utils::Vector{Member("bar", ty.Of(c_type))});
auto* b_ary_type = ty.array(ty.Of(b_type), 3_u);
- auto* a_type = Structure("A", {Member("foo", b_ary_type)});
+ auto* a_type = Structure("A", utils::Vector{Member("foo", b_ary_type)});
auto* a_ary_type = ty.array(ty.Of(a_type), 2_u);
auto* var = Var("index", a_ary_type);
diff --git a/src/tint/writer/spirv/builder_assign_test.cc b/src/tint/writer/spirv/builder_assign_test.cc
index 526ede8..be30dc7 100644
--- a/src/tint/writer/spirv/builder_assign_test.cc
+++ b/src/tint/writer/spirv/builder_assign_test.cc
@@ -172,7 +172,7 @@
// var ident : my_struct
// ident.b = 4.0;
- auto* s = Structure("my_struct", {
+ auto* s = Structure("my_struct", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.f32()),
});
diff --git a/src/tint/writer/spirv/builder_binary_expression_test.cc b/src/tint/writer/spirv/builder_binary_expression_test.cc
index 9a2709e..922473e 100644
--- a/src/tint/writer/spirv/builder_binary_expression_test.cc
+++ b/src/tint/writer/spirv/builder_binary_expression_test.cc
@@ -1219,30 +1219,48 @@
enum class Type { f32, f16, i32, u32 };
static const ast::Expression* MakeVectorExpr(ProgramBuilder* builder, Type type) {
+ auto name = builder->Symbols().New();
switch (type) {
case Type::f32:
- return builder->vec3<f32>(1_f, 1_f, 1_f);
+ builder->GlobalVar(name, builder->ty.vec3<f32>(), builder->vec3<f32>(1_f, 1_f, 1_f),
+ ast::StorageClass::kPrivate);
+ break;
case Type::f16:
- return builder->vec3<f16>(1_h, 1_h, 1_h);
+ builder->GlobalVar(name, builder->ty.vec3<f16>(), builder->vec3<f16>(1_h, 1_h, 1_h),
+ ast::StorageClass::kPrivate);
+ break;
case Type::i32:
- return builder->vec3<i32>(1_i, 1_i, 1_i);
+ builder->GlobalVar(name, builder->ty.vec3<i32>(), builder->vec3<i32>(1_i, 1_i, 1_i),
+ ast::StorageClass::kPrivate);
+ break;
case Type::u32:
- return builder->vec3<u32>(1_u, 1_u, 1_u);
+ builder->GlobalVar(name, builder->ty.vec3<u32>(), builder->vec3<u32>(1_u, 1_u, 1_u),
+ ast::StorageClass::kPrivate);
+ break;
}
- return nullptr;
+ return builder->Expr(name);
}
static const ast::Expression* MakeScalarExpr(ProgramBuilder* builder, Type type) {
+ auto name = builder->Symbols().New();
switch (type) {
case Type::f32:
- return builder->Expr(1_f);
+ builder->GlobalVar(name, builder->ty.f32(), builder->Expr(1_f),
+ ast::StorageClass::kPrivate);
+ break;
case Type::f16:
- return builder->Expr(1_h);
+ builder->GlobalVar(name, builder->ty.f16(), builder->Expr(1_h),
+ ast::StorageClass::kPrivate);
+ break;
case Type::i32:
- return builder->Expr(1_i);
+ builder->GlobalVar(name, builder->ty.i32(), builder->Expr(1_i),
+ ast::StorageClass::kPrivate);
+ break;
case Type::u32:
- return builder->Expr(1_u);
+ builder->GlobalVar(name, builder->ty.u32(), builder->Expr(1_u),
+ ast::StorageClass::kPrivate);
+ break;
}
- return nullptr;
+ return builder->Expr(name);
}
static std::string OpTypeDecl(Type type) {
switch (type) {
@@ -1310,26 +1328,33 @@
spirv::Builder& b = Build();
ASSERT_TRUE(b.Build()) << b.error();
-
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
-OpEntryPoint GLCompute %3 "test_function"
-OpExecutionMode %3 LocalSize 1 1 1
-OpName %3 "test_function"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = )" + op_type_decl + R"(
-%5 = OpTypeVector %6 3
-%7 = OpConstant %6 )" + constant_value +
+OpEntryPoint GLCompute %11 "test_function"
+OpExecutionMode %11 LocalSize 1 1 1
+OpName %5 "tint_symbol"
+OpName %7 "tint_symbol_1"
+OpName %11 "test_function"
+%2 = )" + op_type_decl + R"(
+%1 = OpTypeVector %2 3
+%3 = OpConstant %2 )" + constant_value +
R"(
-%8 = OpConstantComposite %5 %7 %7 %7
-%11 = OpTypePointer Function %5
-%12 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%10 = OpVariable %11 Function %12
-%13 = OpCompositeConstruct %5 %7 %7 %7
-%9 = )" + param.name + R"( %5 %8 %13
+%4 = OpConstantComposite %1 %3 %3 %3
+%6 = OpTypePointer Private %1
+%5 = OpVariable %6 Private %4
+%8 = OpTypePointer Private %2
+%7 = OpVariable %8 Private %3
+%10 = OpTypeVoid
+%9 = OpTypeFunction %10
+%17 = OpTypePointer Function %1
+%18 = OpConstantNull %1
+%11 = OpFunction %10 None %9
+%12 = OpLabel
+%16 = OpVariable %17 Function %18
+%13 = OpLoad %1 %5
+%14 = OpLoad %2 %7
+%19 = OpCompositeConstruct %1 %14 %14 %14
+%15 = )" + param.name + R"( %1 %13 %19
OpReturn
OpFunctionEnd
)");
@@ -1355,26 +1380,33 @@
spirv::Builder& b = Build();
ASSERT_TRUE(b.Build()) << b.error();
-
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
-OpEntryPoint GLCompute %3 "test_function"
-OpExecutionMode %3 LocalSize 1 1 1
-OpName %3 "test_function"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%5 = )" + op_type_decl + R"(
-%6 = OpConstant %5 )" + constant_value +
+OpEntryPoint GLCompute %11 "test_function"
+OpExecutionMode %11 LocalSize 1 1 1
+OpName %3 "tint_symbol"
+OpName %7 "tint_symbol_1"
+OpName %11 "test_function"
+%1 = )" + op_type_decl + R"(
+%2 = OpConstant %1 )" + constant_value +
R"(
-%7 = OpTypeVector %5 3
-%8 = OpConstantComposite %7 %6 %6 %6
-%11 = OpTypePointer Function %7
-%12 = OpConstantNull %7
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%10 = OpVariable %11 Function %12
-%13 = OpCompositeConstruct %7 %6 %6 %6
-%9 = )" + param.name + R"( %7 %13 %8
+%4 = OpTypePointer Private %1
+%3 = OpVariable %4 Private %2
+%5 = OpTypeVector %1 3
+%6 = OpConstantComposite %5 %2 %2 %2
+%8 = OpTypePointer Private %5
+%7 = OpVariable %8 Private %6
+%10 = OpTypeVoid
+%9 = OpTypeFunction %10
+%17 = OpTypePointer Function %5
+%18 = OpConstantNull %5
+%11 = OpFunction %10 None %9
+%12 = OpLabel
+%16 = OpVariable %17 Function %18
+%13 = OpLoad %1 %3
+%14 = OpLoad %5 %7
+%19 = OpCompositeConstruct %5 %13 %13 %13
+%15 = )" + param.name + R"( %5 %19 %14
OpReturn
OpFunctionEnd
)");
@@ -1428,22 +1460,29 @@
spirv::Builder& b = Build();
ASSERT_TRUE(b.Build()) << b.error();
-
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
-OpEntryPoint GLCompute %3 "test_function"
-OpExecutionMode %3 LocalSize 1 1 1
-OpName %3 "test_function"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = )" + op_type_decl + R"(
-%5 = OpTypeVector %6 3
-%7 = OpConstant %6 )" + constant_value +
+OpEntryPoint GLCompute %11 "test_function"
+OpExecutionMode %11 LocalSize 1 1 1
+OpName %5 "tint_symbol"
+OpName %7 "tint_symbol_1"
+OpName %11 "test_function"
+%2 = )" + op_type_decl + R"(
+%1 = OpTypeVector %2 3
+%3 = OpConstant %2 )" + constant_value +
R"(
-%8 = OpConstantComposite %5 %7 %7 %7
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%9 = OpVectorTimesScalar %5 %8 %7
+%4 = OpConstantComposite %1 %3 %3 %3
+%6 = OpTypePointer Private %1
+%5 = OpVariable %6 Private %4
+%8 = OpTypePointer Private %2
+%7 = OpVariable %8 Private %3
+%10 = OpTypeVoid
+%9 = OpTypeFunction %10
+%11 = OpFunction %10 None %9
+%12 = OpLabel
+%13 = OpLoad %1 %5
+%14 = OpLoad %2 %7
+%15 = OpVectorTimesScalar %1 %13 %14
OpReturn
OpFunctionEnd
)");
@@ -1469,22 +1508,29 @@
spirv::Builder& b = Build();
ASSERT_TRUE(b.Build()) << b.error();
-
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
-OpEntryPoint GLCompute %3 "test_function"
-OpExecutionMode %3 LocalSize 1 1 1
-OpName %3 "test_function"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%5 = )" + op_type_decl + R"(
-%6 = OpConstant %5 )" + constant_value +
+OpEntryPoint GLCompute %11 "test_function"
+OpExecutionMode %11 LocalSize 1 1 1
+OpName %3 "tint_symbol"
+OpName %7 "tint_symbol_1"
+OpName %11 "test_function"
+%1 = )" + op_type_decl + R"(
+%2 = OpConstant %1 )" + constant_value +
R"(
-%7 = OpTypeVector %5 3
-%8 = OpConstantComposite %7 %6 %6 %6
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%9 = OpVectorTimesScalar %7 %8 %6
+%4 = OpTypePointer Private %1
+%3 = OpVariable %4 Private %2
+%5 = OpTypeVector %1 3
+%6 = OpConstantComposite %5 %2 %2 %2
+%8 = OpTypePointer Private %5
+%7 = OpVariable %8 Private %6
+%10 = OpTypeVoid
+%9 = OpTypeFunction %10
+%11 = OpFunction %10 None %9
+%12 = OpLabel
+%13 = OpLoad %1 %3
+%14 = OpLoad %5 %7
+%15 = OpVectorTimesScalar %5 %14 %13
OpReturn
OpFunctionEnd
)");
@@ -1502,22 +1548,31 @@
enum class Type { f32, f16 };
static const ast::Expression* MakeMat3x4Expr(ProgramBuilder* builder, Type type) {
+ auto name = builder->Symbols().New();
switch (type) {
case Type::f32:
- return builder->mat3x4<f32>();
+ builder->GlobalVar(name, builder->ty.mat3x4<f32>(), builder->mat3x4<f32>(),
+ ast::StorageClass::kPrivate);
+ break;
case Type::f16:
- return builder->mat3x4<f16>();
+ builder->GlobalVar(name, builder->ty.mat3x4<f16>(), builder->mat3x4<f16>(),
+ ast::StorageClass::kPrivate);
+ break;
}
- return nullptr;
+ return builder->Expr(name);
}
static const ast::Expression* MakeMat4x3Expr(ProgramBuilder* builder, Type type) {
+ auto name = builder->Symbols().New();
switch (type) {
case Type::f32:
- return builder->mat4x3<f32>();
+ builder->GlobalVar(name, builder->ty.mat4x3<f32>(), builder->mat4x3<f32>(),
+ ast::StorageClass::kPrivate);
+ break;
case Type::f16:
- return builder->mat4x3<f16>();
+ builder->GlobalVar(name, builder->ty.mat4x3<f16>(), builder->mat4x3<f16>(),
+ ast::StorageClass::kPrivate);
}
- return nullptr;
+ return builder->Expr(name);
}
static std::string OpTypeDecl(Type type) {
switch (type) {
@@ -1567,30 +1622,36 @@
spirv::Builder& b = Build();
ASSERT_TRUE(b.Build()) << b.error();
-
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
-OpEntryPoint GLCompute %3 "test_function"
-OpExecutionMode %3 LocalSize 1 1 1
-OpName %3 "test_function"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = )" + op_type_decl + R"(
-%6 = OpTypeVector %7 4
-%5 = OpTypeMatrix %6 3
-%8 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%10 = OpCompositeExtract %6 %8 0
-%11 = OpCompositeExtract %6 %8 0
-%12 = )" + param.name + R"( %6 %10 %11
-%13 = OpCompositeExtract %6 %8 1
-%14 = OpCompositeExtract %6 %8 1
-%15 = )" + param.name + R"( %6 %13 %14
-%16 = OpCompositeExtract %6 %8 2
-%17 = OpCompositeExtract %6 %8 2
-%18 = )" + param.name + R"( %6 %16 %17
-%19 = OpCompositeConstruct %5 %12 %15 %18
+OpEntryPoint GLCompute %10 "test_function"
+OpExecutionMode %10 LocalSize 1 1 1
+OpName %5 "tint_symbol"
+OpName %7 "tint_symbol_1"
+OpName %10 "test_function"
+%3 = )" + op_type_decl + R"(
+%2 = OpTypeVector %3 4
+%1 = OpTypeMatrix %2 3
+%4 = OpConstantNull %1
+%6 = OpTypePointer Private %1
+%5 = OpVariable %6 Private %4
+%7 = OpVariable %6 Private %4
+%9 = OpTypeVoid
+%8 = OpTypeFunction %9
+%10 = OpFunction %9 None %8
+%11 = OpLabel
+%12 = OpLoad %1 %5
+%13 = OpLoad %1 %7
+%15 = OpCompositeExtract %2 %12 0
+%16 = OpCompositeExtract %2 %13 0
+%17 = )" + param.name + R"( %2 %15 %16
+%18 = OpCompositeExtract %2 %12 1
+%19 = OpCompositeExtract %2 %13 1
+%20 = )" + param.name + R"( %2 %18 %19
+%21 = OpCompositeExtract %2 %12 2
+%22 = OpCompositeExtract %2 %13 2
+%23 = )" + param.name + R"( %2 %21 %22
+%24 = OpCompositeConstruct %1 %17 %20 %23
OpReturn
OpFunctionEnd
)");
@@ -1624,25 +1685,32 @@
spirv::Builder& b = Build();
ASSERT_TRUE(b.Build()) << b.error();
-
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
-OpEntryPoint GLCompute %3 "test_function"
-OpExecutionMode %3 LocalSize 1 1 1
-OpName %3 "test_function"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = )" + op_type_decl + R"(
-%6 = OpTypeVector %7 4
-%5 = OpTypeMatrix %6 3
-%8 = OpConstantNull %5
-%10 = OpTypeVector %7 3
-%9 = OpTypeMatrix %10 4
-%11 = OpConstantNull %9
-%13 = OpTypeMatrix %6 4
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%12 = OpMatrixTimesMatrix %13 %8 %11
+OpEntryPoint GLCompute %14 "test_function"
+OpExecutionMode %14 LocalSize 1 1 1
+OpName %5 "tint_symbol"
+OpName %10 "tint_symbol_1"
+OpName %14 "test_function"
+%3 = )" + op_type_decl + R"(
+%2 = OpTypeVector %3 4
+%1 = OpTypeMatrix %2 3
+%4 = OpConstantNull %1
+%6 = OpTypePointer Private %1
+%5 = OpVariable %6 Private %4
+%8 = OpTypeVector %3 3
+%7 = OpTypeMatrix %8 4
+%9 = OpConstantNull %7
+%11 = OpTypePointer Private %7
+%10 = OpVariable %11 Private %9
+%13 = OpTypeVoid
+%12 = OpTypeFunction %13
+%19 = OpTypeMatrix %2 4
+%14 = OpFunction %13 None %12
+%15 = OpLabel
+%16 = OpLoad %1 %5
+%17 = OpLoad %7 %10
+%18 = OpMatrixTimesMatrix %19 %16 %17
OpReturn
OpFunctionEnd
)");
diff --git a/src/tint/writer/spirv/builder_builtin_test.cc b/src/tint/writer/spirv/builder_builtin_test.cc
index cb93784..52254d2 100644
--- a/src/tint/writer/spirv/builder_builtin_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_test.cc
@@ -44,13 +44,13 @@
auto* t = ty.depth_texture(ast::TextureDimension::k2d);
auto* tex = GlobalVar("texture", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
auto* sampler = GlobalVar("sampler", s,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(0u),
});
@@ -58,8 +58,16 @@
auto* expr1 = Call("textureSampleCompare", "texture", "sampler", vec2<f32>(1_f, 2_f), 2_f);
auto* expr2 = Call("textureSampleCompare", "texture", "sampler", vec2<f32>(1_f, 2_f), 2_f);
- Func("f1", {}, ty.void_(), {CallStmt(expr1)}, {});
- Func("f2", {}, ty.void_(), {CallStmt(expr2)}, {});
+ Func("f1", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(expr1),
+ },
+ utils::Empty);
+ Func("f2", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(expr2),
+ },
+ utils::Empty);
spirv::Builder& b = Build();
@@ -100,8 +108,8 @@
TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad_f32) {
auto* var = GlobalVar("ident", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call("round", "ident");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -136,8 +144,8 @@
auto* var = GlobalVar("ident", ty.f16(), ast::StorageClass::kPrivate);
auto* expr = Call("round", "ident");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -175,8 +183,8 @@
auto param = GetParam();
auto* var = GlobalVar("v", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -201,8 +209,8 @@
auto param = GetParam();
auto* var = GlobalVar("v", ty.vec3<bool>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -236,8 +244,8 @@
auto* bool_v3 = GlobalVar("bool_v3", ty.vec3<bool>(), ast::StorageClass::kPrivate);
auto* expr = Call("select", "v3", "v3", "bool_v3");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -275,19 +283,21 @@
namespace array_builtin_tests {
TEST_F(BuiltinBuilderTest, Call_ArrayLength) {
- auto* s = Structure("my_struct", {Member("a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{
+ Member("a", ty.array<f32>(4)),
+ });
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
auto* expr = Call("arrayLength", AddressOf(MemberAccessor("b", "a")));
- Func("a_func", {}, ty.void_(),
- ast::StatementList{
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(expr),
},
- ast::AttributeList{
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -319,22 +329,22 @@
}
TEST_F(BuiltinBuilderTest, Call_ArrayLength_OtherMembersInStruct) {
- auto* s = Structure("my_struct", {
+ auto* s = Structure("my_struct", utils::Vector{
Member("z", ty.f32()),
Member(4, "a", ty.array<f32>(4)),
});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
auto* expr = Call("arrayLength", AddressOf(MemberAccessor("b", "a")));
- Func("a_func", {}, ty.void_(),
- ast::StatementList{
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(expr),
},
- ast::AttributeList{
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -366,9 +376,11 @@
}
TEST_F(BuiltinBuilderTest, Call_ArrayLength_ViaLets) {
- auto* s = Structure("my_struct", {Member("a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{
+ Member("a", ty.array<f32>(4)),
+ });
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
@@ -377,13 +389,13 @@
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
auto* expr = Call("arrayLength", p2);
- Func("a_func", {}, ty.void_(),
- ast::StatementList{
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(p),
Decl(p2),
CallStmt(expr),
},
- ast::AttributeList{
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -426,9 +438,11 @@
// let p3 = &((*p).a);
// arrayLength(&*p3);
// }
- auto* s = Structure("my_struct", {Member("a", ty.array<f32>(4))});
+ auto* s = Structure("my_struct", utils::Vector{
+ Member("a", ty.array<f32>(4)),
+ });
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
@@ -438,14 +452,14 @@
auto* p3 = Let("p3", nullptr, AddressOf(MemberAccessor(Deref(p2), "a")));
auto* expr = Call("arrayLength", AddressOf(Deref(p3)));
- Func("a_func", {}, ty.void_(),
- ast::StatementList{
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(p),
Decl(p2),
Decl(p3),
CallStmt(expr),
},
- ast::AttributeList{
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -487,8 +501,8 @@
// Use a variable to prevent the function being evaluated as constant.
auto* scalar = Var("a", nullptr, Expr(1_f));
auto* expr = Call(param.name, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -528,8 +542,8 @@
// Use a variable to prevent the function being evaluated as constant.
auto* scalar = Var("a", nullptr, Expr(1_h));
auto* expr = Call(param.name, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -568,8 +582,8 @@
// Use a variable to prevent the function being evaluated as constant.
auto* vec = Var("a", nullptr, vec2<f32>(1_f, 1_f));
auto* expr = Call(param.name, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -612,8 +626,8 @@
// Use a variable to prevent the function being evaluated as constant.
auto* vec = Var("a", nullptr, vec2<f16>(1_h, 1_h));
auto* expr = Call(param.name, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -678,8 +692,8 @@
TEST_F(BuiltinBuilderTest, Call_Length_Scalar_f32) {
auto* scalar = Var("a", nullptr, Expr(1_f));
auto* expr = Call("length", scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -715,8 +729,8 @@
auto* scalar = Var("a", nullptr, Expr(1_h));
auto* expr = Call("length", scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -750,8 +764,8 @@
TEST_F(BuiltinBuilderTest, Call_Length_Vector_f32) {
auto* vec = Var("a", nullptr, vec2<f32>(1_f, 1_f));
auto* expr = Call("length", vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -789,8 +803,8 @@
auto* vec = Var("a", nullptr, vec2<f16>(1_h, 1_h));
auto* expr = Call("length", vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -826,8 +840,8 @@
TEST_F(BuiltinBuilderTest, Call_Normalize_f32) {
auto* vec = Var("a", nullptr, vec2<f32>(1_f, 1_f));
auto* expr = Call("normalize", vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -865,8 +879,8 @@
auto* vec = Var("a", nullptr, vec2<f16>(1_h, 1_h));
auto* expr = Call("normalize", vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -904,8 +918,8 @@
auto param = GetParam();
auto* scalar = Var("scalar", nullptr, Expr(1_f));
auto* expr = Call(param.name, scalar, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -945,8 +959,8 @@
auto param = GetParam();
auto* scalar = Var("scalar", nullptr, Expr(1_h));
auto* expr = Call(param.name, scalar, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -984,8 +998,8 @@
auto param = GetParam();
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
auto* expr = Call(param.name, vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1027,8 +1041,8 @@
auto param = GetParam();
auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
auto* expr = Call(param.name, vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1075,8 +1089,8 @@
TEST_F(BuiltinBuilderTest, Call_Reflect_Vector_f32) {
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
auto* expr = Call("reflect", vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1115,8 +1129,8 @@
auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
auto* expr = Call("reflect", vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1153,8 +1167,8 @@
TEST_F(BuiltinBuilderTest, Call_Distance_Scalar_f32) {
auto* scalar = Var("scalar", nullptr, Expr(1_f));
auto* expr = Call("distance", scalar, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -1191,8 +1205,8 @@
auto* scalar = Var("scalar", nullptr, Expr(1_h));
auto* expr = Call("distance", scalar, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -1227,8 +1241,8 @@
TEST_F(BuiltinBuilderTest, Call_Distance_Vector_f32) {
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
auto* expr = Call("distance", vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1267,8 +1281,8 @@
auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
auto* expr = Call("distance", vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1305,8 +1319,8 @@
TEST_F(BuiltinBuilderTest, Call_Cross_f32) {
auto* vec = Var("vec", nullptr, vec3<f32>(1_f, 1_f, 1_f));
auto* expr = Call("cross", vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1345,8 +1359,8 @@
auto* vec = Var("vec", nullptr, vec3<f16>(1_h, 1_h, 1_h));
auto* expr = Call("cross", vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1385,8 +1399,8 @@
auto param = GetParam();
auto* scalar = Var("scalar", nullptr, Expr(1_f));
auto* expr = Call(param.name, scalar, scalar, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -1427,8 +1441,8 @@
auto param = GetParam();
auto* scalar = Var("scalar", nullptr, Expr(1_h));
auto* expr = Call(param.name, scalar, scalar, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -1467,8 +1481,8 @@
auto param = GetParam();
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
auto* expr = Call(param.name, vec, vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1511,8 +1525,8 @@
auto param = GetParam();
auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
auto* expr = Call(param.name, vec, vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1560,8 +1574,8 @@
TEST_F(BuiltinBuilderTest, Call_FaceForward_Vector_f32) {
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
auto* expr = Call("faceForward", vec, vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1601,8 +1615,8 @@
auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
auto* expr = Call("faceForward", vec, vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1637,11 +1651,17 @@
EXPECT_EQ(got, expect);
}
-TEST_F(BuiltinBuilderTest, Call_Modf) {
+TEST_F(BuiltinBuilderTest, Call_Modf_f32) {
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 2_f));
auto* expr = Call("modf", vec);
- Func("a_func", {}, ty.void_(), {Decl(vec), CallStmt(expr)},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(vec),
+ CallStmt(expr),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = Build();
@@ -1683,11 +1703,75 @@
Validate(b);
}
-TEST_F(BuiltinBuilderTest, Call_Frexp) {
+TEST_F(BuiltinBuilderTest, Call_Modf_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 2_h));
+ auto* expr = Call("modf", vec);
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(vec),
+ CallStmt(expr),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
+
+ spirv::Builder& b = Build();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+ auto got = DumpBuilder(b);
+ auto* expect = R"(OpCapability Shader
+OpCapability Float16
+OpCapability UniformAndStorageBuffer16BitAccess
+OpCapability StorageBuffer16BitAccess
+OpCapability StorageInputOutput16
+%15 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %3 "a_func"
+OpExecutionMode %3 OriginUpperLeft
+OpName %3 "a_func"
+OpName %10 "vec"
+OpName %14 "__modf_result_vec2_f16"
+OpMemberName %14 0 "fract"
+OpMemberName %14 1 "whole"
+OpMemberDecorate %14 0 Offset 0
+OpMemberDecorate %14 1 Offset 4
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstant %6 0x1p+1
+%9 = OpConstantComposite %5 %7 %8
+%11 = OpTypePointer Function %5
+%12 = OpConstantNull %5
+%14 = OpTypeStruct %5 %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%10 = OpVariable %11 Function %12
+OpStore %10 %9
+%16 = OpLoad %5 %10
+%13 = OpExtInst %14 %15 ModfStruct %16
+OpReturn
+OpFunctionEnd
+)";
+ EXPECT_EQ(expect, got);
+
+ Validate(b);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Frexp_f32) {
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 2_f));
auto* expr = Call("frexp", vec);
- Func("a_func", {}, ty.void_(), {Decl(vec), CallStmt(expr)},
- {Stage(ast::PipelineStage::kFragment)});
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(vec),
+ CallStmt(expr),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = Build();
@@ -1731,6 +1815,66 @@
Validate(b);
}
+TEST_F(BuiltinBuilderTest, Call_Frexp_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 2_h));
+ auto* expr = Call("frexp", vec);
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(vec),
+ CallStmt(expr),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
+
+ spirv::Builder& b = Build();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+ auto got = DumpBuilder(b);
+ auto* expect = R"(OpCapability Shader
+OpCapability Float16
+OpCapability UniformAndStorageBuffer16BitAccess
+OpCapability StorageBuffer16BitAccess
+OpCapability StorageInputOutput16
+%17 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %3 "a_func"
+OpExecutionMode %3 OriginUpperLeft
+OpName %3 "a_func"
+OpName %10 "vec"
+OpName %14 "__frexp_result_vec2_f16"
+OpMemberName %14 0 "sig"
+OpMemberName %14 1 "exp"
+OpMemberDecorate %14 0 Offset 0
+OpMemberDecorate %14 1 Offset 8
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstant %6 0x1p+1
+%9 = OpConstantComposite %5 %7 %8
+%11 = OpTypePointer Function %5
+%12 = OpConstantNull %5
+%16 = OpTypeInt 32 1
+%15 = OpTypeVector %16 2
+%14 = OpTypeStruct %5 %15
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%10 = OpVariable %11 Function %12
+OpStore %10 %9
+%18 = OpLoad %5 %10
+%13 = OpExtInst %14 %17 FrexpStruct %18
+OpReturn
+OpFunctionEnd
+)";
+ EXPECT_EQ(expect, got);
+
+ Validate(b);
+}
+
} // namespace float_builtin_tests
// Tests for Numeric builtins with all integer parameter
@@ -1741,8 +1885,8 @@
auto param = GetParam();
auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -1771,8 +1915,8 @@
auto param = GetParam();
auto* var = GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -1802,8 +1946,8 @@
auto param = GetParam();
auto* var = GlobalVar("v", ty.u32(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -1832,8 +1976,8 @@
auto param = GetParam();
auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -1868,8 +2012,8 @@
auto param = GetParam();
auto* scalar = Var("scalar", nullptr, Expr(1_i));
auto* expr = Call(param.name, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -1906,8 +2050,8 @@
auto param = GetParam();
auto* vec = Var("vec", nullptr, vec2<i32>(1_i, 1_i));
auto* expr = Call(param.name, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -1950,8 +2094,8 @@
TEST_F(Builtin_Builder_Abs_Uint_Test, Call_Scalar) {
auto* scalar = Var("scalar", nullptr, Expr(1_u));
auto* expr = Call("abs", scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -1983,8 +2127,8 @@
TEST_F(Builtin_Builder_Abs_Uint_Test, Call_Vector) {
auto* scalar = Var("scalar", nullptr, vec2<u32>(1_u, 1_u));
auto* expr = Call("abs", scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -2020,8 +2164,8 @@
auto param = GetParam();
auto* scalar = Var("scalar", nullptr, Expr(1_i));
auto* expr = Call(param.name, scalar, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -2059,8 +2203,8 @@
auto param = GetParam();
auto* vec = Var("vec", nullptr, vec2<i32>(1_i, 1_i));
auto* expr = Call(param.name, vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -2104,8 +2248,8 @@
auto param = GetParam();
auto* scalar = Var("scalar", nullptr, Expr(1_u));
auto* expr = Call(param.name, scalar, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -2143,8 +2287,8 @@
auto param = GetParam();
auto* vec = Var("vec", nullptr, vec2<u32>(1_u, 1_u));
auto* expr = Call(param.name, vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -2188,8 +2332,8 @@
auto param = GetParam();
auto* scalar = Var("scalar", nullptr, Expr(1_i));
auto* expr = Call(param.name, scalar, scalar, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -2228,8 +2372,8 @@
auto param = GetParam();
auto* vec = Var("vec", nullptr, vec2<i32>(1_i, 1_i));
auto* expr = Call(param.name, vec, vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -2274,8 +2418,8 @@
auto param = GetParam();
auto* scalar = Var("scalar", nullptr, Expr(1_u));
auto* expr = Call(param.name, scalar, scalar, scalar);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(scalar),
Assign(Phony(), expr),
});
@@ -2314,8 +2458,8 @@
auto param = GetParam();
auto* vec = Var("vec", nullptr, vec2<u32>(1_u, 1_u));
auto* expr = Call(param.name, vec, vec, vec);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(vec),
Assign(Phony(), expr),
});
@@ -2703,8 +2847,8 @@
TEST_F(BuiltinBuilderTest, Call_Determinant_f32) {
auto* var = GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("determinant", "var");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -2740,8 +2884,8 @@
auto* var = GlobalVar("var", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
auto* expr = Call("determinant", "var");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -2775,8 +2919,8 @@
TEST_F(BuiltinBuilderTest, Call_Transpose_f32) {
auto* var = GlobalVar("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("transpose", "var");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -2813,8 +2957,8 @@
auto* var = GlobalVar("var", ty.mat2x3<f16>(), ast::StorageClass::kPrivate);
auto* expr = Call("transpose", "var");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -2854,8 +2998,8 @@
TEST_F(BuiltinBuilderTest, Call_Dot_F32) {
auto* var = GlobalVar("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "v", "v");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -2885,8 +3029,8 @@
auto* var = GlobalVar("v", ty.vec3<f16>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "v", "v");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -2914,8 +3058,8 @@
TEST_F(BuiltinBuilderTest, Call_Dot_U32) {
auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "v", "v");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -2953,8 +3097,8 @@
TEST_F(BuiltinBuilderTest, Call_Dot_I32) {
auto* var = GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "v", "v");
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Assign(Phony(), expr),
});
@@ -2999,8 +3143,13 @@
auto param = GetParam();
auto* var = GlobalVar("v", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
- auto* func =
- Func("func", {}, ty.void_(), {CallStmt(expr)}, {Stage(ast::PipelineStage::kFragment)});
+ auto* func = Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(expr),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = Build();
@@ -3027,8 +3176,13 @@
auto param = GetParam();
auto* var = GlobalVar("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
- auto* func =
- Func("func", {}, ty.void_(), {CallStmt(expr)}, {Stage(ast::PipelineStage::kFragment)});
+ auto* func = Func("func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(expr),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = Build();
@@ -3086,22 +3240,24 @@
// let u : u32 = atomicLoad(&b.u);
// let i : i32 = atomicLoad(&b.i);
// }
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("u", ty.atomic<u32>()),
Member("i", ty.atomic<i32>()),
});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- ast::StatementList{
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("u", ty.u32(), Call("atomicLoad", AddressOf(MemberAccessor("b", "u"))))),
Decl(Let("i", ty.i32(), Call("atomicLoad", AddressOf(MemberAccessor("b", "i"))))),
},
- ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -3150,24 +3306,26 @@
// atomicStore(&b.u, u);
// atomicStore(&b.i, i);
// }
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("u", ty.atomic<u32>()),
Member("i", ty.atomic<i32>()),
});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- ast::StatementList{
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("u", nullptr, Expr(1_u))),
Decl(Var("i", nullptr, Expr(2_i))),
CallStmt(Call("atomicStore", AddressOf(MemberAccessor("b", "u")), "u")),
CallStmt(Call("atomicStore", AddressOf(MemberAccessor("b", "i")), "i")),
},
- ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -3223,22 +3381,24 @@
// var v = 10;
// let x : i32 = atomicOP(&b.v, v);
// }
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("v", ty.atomic<i32>()),
});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- ast::StatementList{
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("v", nullptr, Expr(10_i))),
Decl(Let("x", ty.i32(),
Call(GetParam().name, AddressOf(MemberAccessor("b", "v")), "v"))),
},
- ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -3296,22 +3456,24 @@
// var v = 10u;
// let x : u32 = atomicOP(&b.v, v);
// }
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("v", ty.atomic<u32>()),
});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- ast::StatementList{
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("v", nullptr, Expr(10_u))),
Decl(Let("x", ty.u32(),
Call(GetParam().name, AddressOf(MemberAccessor("b", "v")), "v"))),
},
- ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -3370,18 +3532,18 @@
// let r : u32 = atomicExchange(&b.u, u);
// let s : i32 = atomicExchange(&b.i, i);
// }
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("u", ty.atomic<u32>()),
Member("i", ty.atomic<i32>()),
});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- ast::StatementList{
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Var("u", nullptr, Expr(10_u))),
Decl(Var("i", nullptr, Expr(10_i))),
Decl(Let("r", ty.u32(),
@@ -3389,7 +3551,9 @@
Decl(Let("s", ty.i32(),
Call("atomicExchange", AddressOf(MemberAccessor("b", "i")), "i"))),
},
- ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -3446,18 +3610,18 @@
// let u = atomicCompareExchangeWeak(&b.u, 10u, 20u);
// let i = atomicCompareExchangeWeak(&b.i, 10, 10);
// }
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("u", ty.atomic<u32>()),
Member("i", ty.atomic<i32>()),
});
GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
- Func("a_func", {}, ty.void_(),
- ast::StatementList{
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(Let("u", nullptr,
Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "u")), 10_u,
20_u))),
@@ -3465,7 +3629,9 @@
Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "i")), 10_i,
20_i))),
},
- ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -3523,7 +3689,10 @@
bool pack4 = param.name == "pack4x8snorm" || param.name == "pack4x8unorm";
auto* call = pack4 ? Call(param.name, vec4<f32>(1_f, 1_f, 1_f, 1_f))
: Call(param.name, vec2<f32>(1_f, 1_f));
- auto* func = Func("a_func", {}, ty.void_(), {CallStmt(call)});
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(call),
+ });
spirv::Builder& b = Build();
@@ -3590,7 +3759,10 @@
auto param = GetParam();
bool pack4 = param.name == "unpack4x8snorm" || param.name == "unpack4x8unorm";
- auto* func = Func("a_func", {}, ty.void_(), {CallStmt(Call(param.name, 1_u))});
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ CallStmt(Call(param.name, 1_u)),
+ });
spirv::Builder& b = Build();
@@ -3651,11 +3823,11 @@
namespace synchronization_builtin_tests {
TEST_F(BuiltinBuilderTest, Call_WorkgroupBarrier) {
- Func("f", {}, ty.void_(),
- ast::StatementList{
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call("workgroupBarrier")),
},
- ast::AttributeList{
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -3685,11 +3857,11 @@
}
TEST_F(BuiltinBuilderTest, Call_StorageBarrier) {
- Func("f", {}, ty.void_(),
- ast::StatementList{
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
CallStmt(Call("storageBarrier")),
},
- ast::AttributeList{
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/writer/spirv/builder_builtin_texture_test.cc b/src/tint/writer/spirv/builder_builtin_texture_test.cc
index ea81211..b5fcc9c 100644
--- a/src/tint/writer/spirv/builder_builtin_texture_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_texture_test.cc
@@ -3684,7 +3684,10 @@
auto* call = Call(param.function, param.args(this));
auto* stmt = CallStmt(call);
- Func("func", {}, ty.void_(), {stmt}, {Stage(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{stmt},
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = Build();
@@ -3710,7 +3713,10 @@
auto* call = Call(param.function, param.args(this));
auto* stmt = CallStmt(call);
- Func("main", {}, ty.void_(), {stmt}, {Stage(ast::PipelineStage::kFragment)});
+ Func("main", utils::Empty, ty.void_(), utils::Vector{stmt},
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = Build();
@@ -3730,8 +3736,10 @@
auto* call = Call(param.function, param.args(this));
auto* stmt = CallStmt(call);
- Func("func", {}, ty.void_(), {stmt},
- {create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
+ Func("func", utils::Empty, ty.void_(), utils::Vector{stmt},
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/builder_call_test.cc b/src/tint/writer/spirv/builder_call_test.cc
index 73bc4fd..a0631ea 100644
--- a/src/tint/writer/spirv/builder_call_test.cc
+++ b/src/tint/writer/spirv/builder_call_test.cc
@@ -26,12 +26,13 @@
TEST_F(BuilderTest, Expression_Call) {
auto* a_func = Func("a_func",
- {
+ utils::Vector{
Param("a", ty.f32()),
Param("b", ty.f32()),
},
- ty.f32(), {Return(Add("a", "b"))});
- auto* func = Func("main", {}, ty.void_(), {Assign(Phony(), Call("a_func", 1_f, 1_f))});
+ ty.f32(), utils::Vector{Return(Add("a", "b"))});
+ auto* func = Func("main", utils::Empty, ty.void_(),
+ utils::Vector{Assign(Phony(), Call("a_func", 1_f, 1_f))});
spirv::Builder& b = Build();
@@ -64,13 +65,14 @@
TEST_F(BuilderTest, Statement_Call) {
auto* a_func = Func("a_func",
- {
+ utils::Vector{
Param("a", ty.f32()),
Param("b", ty.f32()),
},
- ty.f32(), {Return(Add("a", "b"))});
+ ty.f32(), utils::Vector{Return(Add("a", "b"))});
- auto* func = Func("main", {}, ty.void_(), {CallStmt(Call("a_func", 1_f, 1_f))});
+ auto* func =
+ Func("main", utils::Empty, ty.void_(), utils::Vector{CallStmt(Call("a_func", 1_f, 1_f))});
spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/builder_constructor_expression_test.cc b/src/tint/writer/spirv/builder_constructor_expression_test.cc
index 7fc7ac6..3ae4f65 100644
--- a/src/tint/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_constructor_expression_test.cc
@@ -3635,11 +3635,7 @@
TEST_F(SpvBuilderConstructorTest, CommonInitializer_TwoVectors) {
auto* v1 = vec3<f32>(2_f, 2_f, 2_f);
auto* v2 = vec3<f32>(2_f, 2_f, 2_f);
- ast::StatementList stmts = {
- WrapInStatement(v1),
- WrapInStatement(v2),
- };
- WrapInFunction(stmts);
+ WrapInFunction(WrapInStatement(v1), WrapInStatement(v2));
spirv::Builder& b = Build();
@@ -3657,11 +3653,7 @@
TEST_F(SpvBuilderConstructorTest, CommonInitializer_TwoArrays) {
auto* a1 = array<f32, 3>(2_f, 2_f, 2_f);
auto* a2 = array<f32, 3>(2_f, 2_f, 2_f);
- ast::StatementList stmts = {
- WrapInStatement(a1),
- WrapInStatement(a2),
- };
- WrapInFunction(stmts);
+ WrapInFunction(WrapInStatement(a1), WrapInStatement(a2));
spirv::Builder& b = Build();
@@ -3684,11 +3676,7 @@
// crbug.com/tint/777
auto* a1 = array<f32, 2>(1_f, 2_f);
auto* a2 = vec2<f32>(1_f, 2_f);
- ast::StatementList stmts = {
- WrapInStatement(a1),
- WrapInStatement(a2),
- };
- WrapInFunction(stmts);
+ WrapInFunction(WrapInStatement(a1), WrapInStatement(a2));
spirv::Builder& b = Build();
b.push_function(Function{});
@@ -3708,7 +3696,7 @@
}
TEST_F(SpvBuilderConstructorTest, Type_Struct) {
- auto* s = Structure("my_struct", {
+ auto* s = Structure("my_struct", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.vec3<f32>()),
});
@@ -3898,7 +3886,7 @@
}
TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Struct) {
- auto* s = Structure("my_struct", {Member("a", ty.f32())});
+ auto* s = Structure("my_struct", utils::Vector{Member("a", ty.f32())});
auto* t = Construct(ty.Of(s));
WrapInFunction(t);
@@ -4546,7 +4534,7 @@
}
TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Struct) {
- auto* s = Structure("my_struct", {
+ auto* s = Structure("my_struct", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.vec3<f32>()),
});
@@ -4561,7 +4549,7 @@
}
TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Struct_WithIdentSubExpression) {
- auto* s = Structure("my_struct", {
+ auto* s = Structure("my_struct", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.vec3<f32>()),
});
diff --git a/src/tint/writer/spirv/builder_entry_point_test.cc b/src/tint/writer/spirv/builder_entry_point_test.cc
index 2c10ab3..ea36e35 100644
--- a/src/tint/writer/spirv/builder_entry_point_test.cc
+++ b/src/tint/writer/spirv/builder_entry_point_test.cc
@@ -42,12 +42,18 @@
// @location(1) loc1 : f32) {
// var col : f32 = (coord.x * loc1);
// }
- auto* coord = Param("coord", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)});
- auto* loc1 = Param("loc1", ty.f32(), {Location(1u)});
+ auto* coord = Param("coord", ty.vec4<f32>(),
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ });
+ auto* loc1 = Param("loc1", ty.f32(),
+ utils::Vector{
+ Location(1u),
+ });
auto* mul = Mul(Expr(MemberAccessor("coord", "x")), Expr("loc1"));
auto* col = Var("col", ty.f32(), ast::StorageClass::kNone, mul);
- Func("frag_main", {coord, loc1}, ty.void_(), {WrapInStatement(col)},
- {
+ Func("frag_main", utils::Vector{coord, loc1}, ty.void_(), utils::Vector{WrapInStatement(col)},
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -112,18 +118,24 @@
// }
// return 1.0;
// }
- auto* loc_in = Param("loc_in", ty.u32(), {Location(0), Flat()});
+ auto* loc_in = Param("loc_in", ty.u32(),
+ utils::Vector{
+ Location(0),
+ Flat(),
+ });
auto* cond =
create<ast::BinaryExpression>(ast::BinaryOp::kGreaterThan, Expr("loc_in"), Expr(10_u));
- Func("frag_main", {loc_in}, ty.f32(),
- {
+ Func("frag_main", utils::Vector{loc_in}, ty.f32(),
+ utils::Vector{
If(cond, Block(Return(0.5_f))),
Return(1_f),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {Location(0)});
+ utils::Vector{
+ Location(0),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -197,21 +209,27 @@
// }
auto* interface = Structure(
- "Interface", {
- Member("value", ty.f32(), {Location(1u)}),
- Member("pos", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)}),
- });
+ "Interface",
+ utils::Vector{
+ Member("value", ty.f32(), utils::Vector{Location(1u)}),
+ Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
+ });
auto* vert_retval = Construct(ty.Of(interface), 42_f, Construct(ty.vec4<f32>()));
- Func("vert_main", {}, ty.Of(interface), {Return(vert_retval)},
- {Stage(ast::PipelineStage::kVertex)});
+ Func("vert_main", utils::Empty, ty.Of(interface), utils::Vector{Return(vert_retval)},
+ utils::Vector{
+ Stage(ast::PipelineStage::kVertex),
+ });
auto* frag_inputs = Param("inputs", ty.Of(interface));
- Func("frag_main", {frag_inputs}, ty.f32(),
- {
+ Func("frag_main", utils::Vector{frag_inputs}, ty.f32(),
+ utils::Vector{
Return(MemberAccessor(Expr("inputs"), "value")),
},
- {Stage(ast::PipelineStage::kFragment)}, {Builtin(ast::BuiltinValue::kFragDepth)});
+ utils::Vector{Stage(ast::PipelineStage::kFragment)},
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kFragDepth),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -302,8 +320,13 @@
}
TEST_F(BuilderTest, SampleIndex_SampleRateShadingCapability) {
- Func("main", {Param("sample_index", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)})},
- ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+ Func("main",
+ utils::Vector{Param("sample_index", ty.u32(),
+ utils::Vector{Builtin(ast::BuiltinValue::kSampleIndex)})},
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
spirv::Builder& b = SanitizeAndBuild();
diff --git a/src/tint/writer/spirv/builder_function_attribute_test.cc b/src/tint/writer/spirv/builder_function_attribute_test.cc
index ab1fa0b..449b75d 100644
--- a/src/tint/writer/spirv/builder_function_attribute_test.cc
+++ b/src/tint/writer/spirv/builder_function_attribute_test.cc
@@ -25,8 +25,8 @@
using BuilderTest = TestHelper;
TEST_F(BuilderTest, Attribute_Stage) {
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -52,22 +52,22 @@
const ast::Variable* var = nullptr;
const ast::Type* ret_type = nullptr;
- ast::AttributeList ret_type_attrs;
- ast::StatementList body;
+ utils::Vector<const ast::Attribute*, 2> ret_type_attrs;
+ utils::Vector<const ast::Statement*, 2> body;
if (params.stage == ast::PipelineStage::kVertex) {
ret_type = ty.vec4<f32>();
- ret_type_attrs.push_back(Builtin(ast::BuiltinValue::kPosition));
- body.push_back(Return(Construct(ty.vec4<f32>())));
+ ret_type_attrs.Push(Builtin(ast::BuiltinValue::kPosition));
+ body.Push(Return(Construct(ty.vec4<f32>())));
} else {
ret_type = ty.void_();
}
- auto deco_list = ast::AttributeList{Stage(params.stage)};
+ utils::Vector<const ast::Attribute*, 2> deco_list{Stage(params.stage)};
if (params.stage == ast::PipelineStage::kCompute) {
- deco_list.push_back(WorkgroupSize(1_i));
+ deco_list.Push(WorkgroupSize(1_i));
}
- auto* func = Func("main", {}, ret_type, body, deco_list, ret_type_attrs);
+ auto* func = Func("main", utils::Empty, ret_type, body, deco_list, ret_type_attrs);
spirv::Builder& b = Build();
@@ -91,8 +91,8 @@
FunctionStageData{ast::PipelineStage::kCompute, SpvExecutionModelGLCompute}));
TEST_F(BuilderTest, Decoration_ExecutionMode_Fragment_OriginUpperLeft) {
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -105,8 +105,8 @@
}
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Default) {
- auto* func =
- Func("main", {}, ty.void_(), {}, {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
spirv::Builder& b = Build();
@@ -117,8 +117,8 @@
}
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Literals) {
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
WorkgroupSize(2_i, 4_i, 6_i),
Stage(ast::PipelineStage::kCompute),
});
@@ -135,8 +135,8 @@
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
WorkgroupSize("width", "height", "depth"),
Stage(ast::PipelineStage::kCompute),
});
@@ -150,11 +150,11 @@
}
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_OverridableConst) {
- Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
- Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
- Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ Override("width", ty.i32(), Construct(ty.i32(), 2_i), utils::Vector{Id(7u)});
+ Override("height", ty.i32(), Construct(ty.i32(), 3_i), utils::Vector{Id(8u)});
+ Override("depth", ty.i32(), Construct(ty.i32(), 4_i), utils::Vector{Id(9u)});
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
WorkgroupSize("width", "height", "depth"),
Stage(ast::PipelineStage::kCompute),
});
@@ -180,10 +180,10 @@
}
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_LiteralAndConst) {
- Override("height", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
+ Override("height", ty.i32(), Construct(ty.i32(), 2_i), utils::Vector{Id(7u)});
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 3_i));
- auto* func = Func("main", {}, ty.void_(), {},
- {
+ auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
WorkgroupSize(4_i, "height", "depth"),
Stage(ast::PipelineStage::kCompute),
});
@@ -207,13 +207,13 @@
}
TEST_F(BuilderTest, Decoration_ExecutionMode_MultipleFragment) {
- auto* func1 = Func("main1", {}, ty.void_(), {},
- {
+ auto* func1 = Func("main1", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
- auto* func2 = Func("main2", {}, ty.void_(), {},
- {
+ auto* func2 = Func("main2", utils::Empty, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -242,14 +242,14 @@
}
TEST_F(BuilderTest, Decoration_ExecutionMode_FragDepth) {
- Func("main", {}, ty.f32(),
- {
+ Func("main", utils::Empty, ty.f32(),
+ utils::Vector{
Return(Expr(1_f)),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Builtin(ast::BuiltinValue::kFragDepth),
});
diff --git a/src/tint/writer/spirv/builder_function_test.cc b/src/tint/writer/spirv/builder_function_test.cc
index 91fa71a..7cbd442 100644
--- a/src/tint/writer/spirv/builder_function_test.cc
+++ b/src/tint/writer/spirv/builder_function_test.cc
@@ -24,7 +24,7 @@
using BuilderTest = TestHelper;
TEST_F(BuilderTest, Function_Empty) {
- Func("a_func", {}, ty.void_(), {});
+ Func("a_func", utils::Empty, ty.void_(), utils::Empty);
spirv::Builder& b = Build();
@@ -41,8 +41,8 @@
}
TEST_F(BuilderTest, Function_Terminator_Return) {
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -63,7 +63,7 @@
TEST_F(BuilderTest, Function_Terminator_ReturnValue) {
GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
- Func("a_func", {}, ty.f32(), {Return("a")}, {});
+ Func("a_func", utils::Empty, ty.f32(), utils::Vector{Return("a")}, utils::Empty);
spirv::Builder& b = Build();
@@ -88,8 +88,8 @@
}
TEST_F(BuilderTest, Function_Terminator_Discard) {
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
create<ast::DiscardStatement>(),
});
@@ -109,11 +109,11 @@
TEST_F(BuilderTest, Function_WithParams) {
Func("a_func",
- {
+ utils::Vector{
Param("a", ty.f32()),
Param("b", ty.i32()),
},
- ty.f32(), {Return("a")}, {});
+ ty.f32(), utils::Vector{Return("a")}, utils::Empty);
spirv::Builder& b = Build();
@@ -135,8 +135,8 @@
}
TEST_F(BuilderTest, Function_WithBody) {
- Func("a_func", {}, ty.void_(),
- {
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -155,7 +155,7 @@
}
TEST_F(BuilderTest, FunctionType) {
- Func("a_func", {}, ty.void_(), {}, {});
+ Func("a_func", utils::Empty, ty.void_(), utils::Empty, utils::Empty);
spirv::Builder& b = Build();
@@ -167,8 +167,8 @@
}
TEST_F(BuilderTest, FunctionType_DeDuplicate) {
- auto* func1 = Func("a_func", {}, ty.void_(), {}, {});
- auto* func2 = Func("b_func", {}, ty.void_(), {}, {});
+ auto* func1 = Func("a_func", utils::Empty, ty.void_(), utils::Empty, utils::Empty);
+ auto* func2 = Func("b_func", utils::Empty, ty.void_(), utils::Empty, utils::Empty);
spirv::Builder& b = Build();
@@ -196,10 +196,10 @@
// return;
// }
- auto* s = Structure("Data", {Member("d", ty.f32())});
+ auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -207,23 +207,23 @@
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
- Func("a", {}, ty.void_(),
- {
+ Func("a", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ utils::Vector{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
}
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
- Func("b", {}, ty.void_(),
- {
+ Func("b", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
+ utils::Vector{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
}
spirv::Builder& b = SanitizeAndBuild();
diff --git a/src/tint/writer/spirv/builder_function_variable_test.cc b/src/tint/writer/spirv/builder_function_variable_test.cc
index 4a7026a..4045f4c 100644
--- a/src/tint/writer/spirv/builder_function_variable_test.cc
+++ b/src/tint/writer/spirv/builder_function_variable_test.cc
@@ -73,32 +73,34 @@
}
TEST_F(BuilderTest, FunctionVar_WithNonConstantConstructor) {
- auto* init = vec2<f32>(1_f, Add(3_f, 3_f));
+ auto* a = Let("a", nullptr, Expr(3_f));
+ auto* init = vec2<f32>(1_f, Add(Expr("a"), 3_f));
auto* v = Var("var", ty.vec2<f32>(), ast::StorageClass::kNone, init);
- WrapInFunction(v);
+ WrapInFunction(a, v);
spirv::Builder& b = Build();
b.push_function(Function{});
+ EXPECT_TRUE(b.GenerateFunctionVariable(a)) << b.error();
EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %7 "var"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
-%1 = OpTypeVector %2 2
-%3 = OpConstant %2 1
-%4 = OpConstant %2 3
-%8 = OpTypePointer Function %1
-%9 = OpConstantNull %1
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+%2 = OpConstant %1 3
+%3 = OpTypeVector %1 2
+%4 = OpConstant %1 1
+%8 = OpTypePointer Function %3
+%9 = OpConstantNull %3
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
R"(%7 = OpVariable %8 Function %9
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%5 = OpFAdd %2 %4 %4
-%6 = OpCompositeConstruct %1 %3 %5
+ R"(%5 = OpFAdd %1 %2 %2
+%6 = OpCompositeConstruct %3 %4 %5
OpStore %7 %6
)");
}
diff --git a/src/tint/writer/spirv/builder_global_variable_test.cc b/src/tint/writer/spirv/builder_global_variable_test.cc
index 5d1a5b0..e14a017 100644
--- a/src/tint/writer/spirv/builder_global_variable_test.cc
+++ b/src/tint/writer/spirv/builder_global_variable_test.cc
@@ -235,7 +235,7 @@
TEST_F(BuilderTest, GlobalVar_WithBindingAndGroup) {
auto* v =
GlobalVar("var", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone, nullptr,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(2u),
create<ast::GroupAttribute>(3u),
});
@@ -256,7 +256,7 @@
TEST_F(BuilderTest, GlobalVar_Override_Bool) {
auto* v = Override("var", ty.bool_(), Expr(true),
- ast::AttributeList{
+ utils::Vector{
Id(1200),
});
@@ -274,7 +274,7 @@
TEST_F(BuilderTest, GlobalVar_Override_Bool_ZeroValue) {
auto* v = Override("var", ty.bool_(), Construct<bool>(),
- ast::AttributeList{
+ utils::Vector{
Id(1200),
});
@@ -292,7 +292,7 @@
TEST_F(BuilderTest, GlobalVar_Override_Bool_NoConstructor) {
auto* v = Override("var", ty.bool_(), nullptr,
- ast::AttributeList{
+ utils::Vector{
Id(1200),
});
@@ -310,7 +310,7 @@
TEST_F(BuilderTest, GlobalVar_Override_Scalar) {
auto* v = Override("var", ty.f32(), Expr(2_f),
- ast::AttributeList{
+ utils::Vector{
Id(0),
});
@@ -328,7 +328,7 @@
TEST_F(BuilderTest, GlobalVar_Override_Scalar_ZeroValue) {
auto* v = Override("var", ty.f32(), Construct<f32>(),
- ast::AttributeList{
+ utils::Vector{
Id(0),
});
@@ -346,7 +346,7 @@
TEST_F(BuilderTest, GlobalVar_Override_Scalar_F32_NoConstructor) {
auto* v = Override("var", ty.f32(), nullptr,
- ast::AttributeList{
+ utils::Vector{
Id(0),
});
@@ -364,7 +364,7 @@
TEST_F(BuilderTest, GlobalVar_Override_Scalar_I32_NoConstructor) {
auto* v = Override("var", ty.i32(), nullptr,
- ast::AttributeList{
+ utils::Vector{
Id(0),
});
@@ -382,7 +382,7 @@
TEST_F(BuilderTest, GlobalVar_Override_Scalar_U32_NoConstructor) {
auto* v = Override("var", ty.u32(), nullptr,
- ast::AttributeList{
+ utils::Vector{
Id(0),
});
@@ -400,7 +400,7 @@
TEST_F(BuilderTest, GlobalVar_Override_NoId) {
auto* var_a = Override("a", ty.bool_(), Expr(true),
- ast::AttributeList{
+ utils::Vector{
Id(0),
});
auto* var_b = Override("b", ty.bool_(), Expr(false));
@@ -474,13 +474,13 @@
// };
// var b<storage, read> : A
- auto* A = Structure("A", {
+ auto* A = Structure("A", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.i32()),
});
GlobalVar("b", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -518,10 +518,10 @@
// type B = A;
// var b<storage, read> : B
- auto* A = Structure("A", {Member("a", ty.i32())});
+ auto* A = Structure("A", utils::Vector{Member("a", ty.i32())});
auto* B = Alias("B", ty.Of(A));
GlobalVar("b", ty.Of(B), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -557,10 +557,10 @@
// type B = A;
// var<storage, read> b : B
- auto* A = Structure("A", {Member("a", ty.i32())});
+ auto* A = Structure("A", utils::Vector{Member("a", ty.i32())});
auto* B = Alias("B", ty.Of(A));
GlobalVar("b", ty.Of(B), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -596,14 +596,14 @@
// var<storage, read> b : A
// var<storage, read_write> c : A
- auto* A = Structure("A", {Member("a", ty.i32())});
+ auto* A = Structure("A", utils::Vector{Member("a", ty.i32())});
GlobalVar("b", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::GroupAttribute>(0u),
create<ast::BindingAttribute>(0u),
});
GlobalVar("c", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::GroupAttribute>(1u),
create<ast::BindingAttribute>(0u),
});
@@ -644,7 +644,7 @@
ast::Access::kWrite);
auto* var_a = GlobalVar("a", type,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -675,7 +675,7 @@
auto* type_a = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
ast::Access::kReadWrite);
auto* var_a = GlobalVar("a", type_a, ast::StorageClass::kNone,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -683,7 +683,7 @@
auto* type_b = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
ast::Access::kWrite);
auto* var_b = GlobalVar("b", type_b, ast::StorageClass::kNone,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(0u),
});
@@ -718,7 +718,7 @@
auto* type_array = ty.array<f32, 16>();
auto* var_array = GlobalVar("b", type_array, ast::StorageClass::kWorkgroup);
- auto* type_struct = Structure("C", {
+ auto* type_struct = Structure("C", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.i32()),
});
diff --git a/src/tint/writer/spirv/builder_if_test.cc b/src/tint/writer/spirv/builder_if_test.cc
index 391be43..6705cce 100644
--- a/src/tint/writer/spirv/builder_if_test.cc
+++ b/src/tint/writer/spirv/builder_if_test.cc
@@ -434,7 +434,10 @@
// return;
// }
- auto* fn = Func("f", {}, ty.void_(), {If(true, Block(Return()))});
+ auto* fn = Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ If(true, Block(Return())),
+ });
spirv::Builder& b = Build();
@@ -460,8 +463,8 @@
// }
// return true;
- auto* fn = Func("f", {}, ty.bool_(),
- {
+ auto* fn = Func("f", utils::Empty, ty.bool_(),
+ utils::Vector{
If(true, Block(Return(false))),
Return(true),
});
@@ -491,8 +494,8 @@
// return true;
// }
- auto* fn = Func("f", {}, ty.bool_(),
- {
+ auto* fn = Func("f", utils::Empty, ty.bool_(),
+ utils::Vector{
If(true, //
Block(Return(true)), //
Else(Block(Return(true)))),
@@ -530,8 +533,8 @@
// }
// return true;
- auto* fn = Func("f", {}, ty.bool_(),
- {
+ auto* fn = Func("f", utils::Empty, ty.bool_(),
+ utils::Vector{
If(true, Block(Block(Block(Block(Return(false)))))),
Return(true),
});
@@ -560,7 +563,10 @@
// }
auto* var = GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
- auto* fn = Func("f", {}, ty.void_(), {If("a", Block())});
+ auto* fn = Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ If("a", Block()),
+ });
spirv::Builder& b = Build();
@@ -592,7 +598,7 @@
// }
auto* if_stmt = If(false, Block(), Else(If(true, Block(Return()))));
- auto* fn = Func("f", {}, ty.void_(), {if_stmt});
+ auto* fn = Func("f", utils::Empty, ty.void_(), utils::Vector{if_stmt});
spirv::Builder& b = Build();
@@ -630,7 +636,10 @@
// }
auto* if_stmt = If(false, Block(), Else(If(true, Block(Break()))));
- auto* fn = Func("f", {}, ty.void_(), {Loop(Block(if_stmt))});
+ auto* fn = Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Loop(Block(if_stmt)),
+ });
spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/builder_return_test.cc b/src/tint/writer/spirv/builder_return_test.cc
index 0027311..825529e 100644
--- a/src/tint/writer/spirv/builder_return_test.cc
+++ b/src/tint/writer/spirv/builder_return_test.cc
@@ -40,7 +40,7 @@
auto* val = vec3<f32>(1_f, 1_f, 3_f);
auto* ret = Return(val);
- Func("test", {}, ty.vec3<f32>(), {ret}, {});
+ Func("test", utils::Empty, ty.vec3<f32>(), utils::Vector{ret}, utils::Empty);
spirv::Builder& b = Build();
@@ -63,7 +63,7 @@
auto* var = Var("param", ty.f32());
auto* ret = Return(var);
- Func("test", {}, ty.f32(), {Decl(var), ret}, {});
+ Func("test", utils::Empty, ty.f32(), utils::Vector{Decl(var), ret}, utils::Empty);
spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/builder_static_assert_test.cc b/src/tint/writer/spirv/builder_static_assert_test.cc
new file mode 100644
index 0000000..c6d6a51
--- /dev/null
+++ b/src/tint/writer/spirv/builder_static_assert_test.cc
@@ -0,0 +1,54 @@
+// Copyright 2022 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/ast/fallthrough_statement.h"
+#include "src/tint/writer/spirv/spv_dump.h"
+#include "src/tint/writer/spirv/test_helper.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::writer::spirv {
+namespace {
+
+using BuilderTest = TestHelper;
+
+TEST_F(BuilderTest, GlobalStaticAssert) {
+ GlobalStaticAssert(true);
+
+ spirv::Builder& b = Build();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ // static asserts are not emitted
+ EXPECT_EQ(DumpInstructions(b.types()), "");
+ EXPECT_EQ(b.functions().size(), 0u);
+}
+
+TEST_F(BuilderTest, FunctionStaticAssert) {
+ Func("f", utils::Empty, ty.void_(), utils::Vector{StaticAssert(true)});
+
+ spirv::Builder& b = Build();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ // static asserts are not emitted
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+)");
+}
+
+} // namespace
+} // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/builder_switch_test.cc b/src/tint/writer/spirv/builder_switch_test.cc
index 3c905b6..c2f526e 100644
--- a/src/tint/writer/spirv/builder_switch_test.cc
+++ b/src/tint/writer/spirv/builder_switch_test.cc
@@ -60,8 +60,8 @@
auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Switch("a", //
Case(Expr(1_i), Block(Assign("v", 1_i))), //
Case(Expr(2_i), Block(Assign("v", 2_i))), //
@@ -117,8 +117,8 @@
auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* a = GlobalVar("a", ty.u32(), ast::StorageClass::kPrivate);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Switch("a", //
Case(Expr(1_u), Block(Assign("v", 1_i))), //
Case(Expr(2_u), Block(Assign("v", 2_i))), //
@@ -174,8 +174,8 @@
auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Switch("a", //
DefaultCase(Block(Assign("v", 1_i)))), //
});
@@ -224,13 +224,13 @@
auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
- auto* func = Func("a_func", {}, ty.void_(),
- {
- Switch(Expr("a"), //
- Case(Expr(1_i), //
- Block(Assign("v", 1_i))), //
- Case({Expr(2_i), Expr(3_i)}, //
- Block(Assign("v", 2_i))), //
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Switch(Expr("a"), //
+ Case(Expr(1_i), //
+ Block(Assign("v", 1_i))), //
+ Case(utils::Vector{Expr(2_i), Expr(3_i)}, //
+ Block(Assign("v", 2_i))), //
DefaultCase(Block(Assign("v", 3_i)))),
});
@@ -287,8 +287,8 @@
auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Switch(Expr("a"), //
Case(Expr(1_i), //
Block(Assign("v", 1_i), Fallthrough())), //
@@ -349,8 +349,8 @@
auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
- auto* func = Func("a_func", {}, ty.void_(),
- {
+ auto* func = Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
Switch("a", //
Case(Expr(1_i), //
Block( //
@@ -412,8 +412,8 @@
// }
// }
- auto* fn = Func("f", {}, ty.i32(),
- {
+ auto* fn = Func("f", utils::Empty, ty.i32(),
+ utils::Vector{
Switch(1_i, //
Case(Expr(1_i), Block(Return(1_i))), //
Case(Expr(2_i), Block(Fallthrough())), //
diff --git a/src/tint/writer/spirv/builder_type_test.cc b/src/tint/writer/spirv/builder_type_test.cc
index d0003c8..58fc174 100644
--- a/src/tint/writer/spirv/builder_type_test.cc
+++ b/src/tint/writer/spirv/builder_type_test.cc
@@ -27,9 +27,9 @@
TEST_F(BuilderTest_Type, GenerateRuntimeArray) {
auto* ary = ty.array(ty.i32());
- auto* str = Structure("S", {Member("x", ary)});
+ auto* str = Structure("S", utils::Vector{Member("x", ary)});
GlobalVar("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -47,9 +47,9 @@
TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) {
auto* ary = ty.array(ty.i32());
- auto* str = Structure("S", {Member("x", ary)});
+ auto* str = Structure("S", utils::Vector{Member("x", ary)});
GlobalVar("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -323,7 +323,7 @@
}
TEST_F(BuilderTest_Type, GenerateStruct) {
- auto* s = Structure("my_struct", {Member("a", ty.f32())});
+ auto* s = Structure("my_struct", utils::Vector{Member("a", ty.f32())});
spirv::Builder& b = Build();
@@ -340,9 +340,9 @@
}
TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.f32()),
- Member("b", ty.f32(), {MemberAlign(8)}),
+ Member("b", ty.f32(), utils::Vector{MemberAlign(8)}),
});
spirv::Builder& b = Build();
@@ -364,7 +364,7 @@
}
TEST_F(BuilderTest_Type, GenerateStruct_NonLayout_Matrix) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.mat2x2<f32>()),
Member("b", ty.mat2x3<f32>()),
Member("c", ty.mat4x4<f32>()),
@@ -404,7 +404,7 @@
TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutMatrix) {
// We have to infer layout for matrix when it also has an offset.
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.mat2x2<f32>()),
Member("b", ty.mat2x3<f32>()),
Member("c", ty.mat4x4<f32>()),
@@ -450,7 +450,7 @@
auto* arr_arr_mat2x3 = ty.array(ty.mat2x3<f32>(), 1_u); // Doubly nested array
auto* rtarr_mat4x4 = ty.array(ty.mat4x4<f32>()); // Runtime array
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", arr_mat2x2),
Member("b", arr_arr_mat2x3),
Member("c", rtarr_mat4x4),
@@ -843,7 +843,7 @@
ast::Access::kWrite);
GlobalVar("test_var", s,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -862,7 +862,7 @@
ast::Access::kWrite);
GlobalVar("test_var", s,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -881,7 +881,7 @@
ast::Access::kWrite);
GlobalVar("test_var", s,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -900,7 +900,7 @@
ast::Access::kWrite);
GlobalVar("test_var", s,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -919,7 +919,7 @@
ast::Access::kWrite);
GlobalVar("test_var", s,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -938,7 +938,7 @@
ast::Access::kWrite);
GlobalVar("test_var", s,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -957,7 +957,7 @@
ast::Access::kWrite);
GlobalVar("test_var", s,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
diff --git a/src/tint/writer/spirv/generator_impl.cc b/src/tint/writer/spirv/generator_impl.cc
index a435fb8..8586562 100644
--- a/src/tint/writer/spirv/generator_impl.cc
+++ b/src/tint/writer/spirv/generator_impl.cc
@@ -26,6 +26,7 @@
#include "src/tint/transform/for_loop_to_loop.h"
#include "src/tint/transform/manager.h"
#include "src/tint/transform/promote_side_effects_to_decl.h"
+#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/remove_unreachable_statements.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/unshadow.h"
@@ -75,6 +76,7 @@
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::UnwindDiscardFunctions>();
manager.Add<transform::SimplifyPointers>(); // Required for arrayLength()
+ manager.Add<transform::RemovePhonies>();
manager.Add<transform::VectorizeScalarMatrixConstructors>();
manager.Add<transform::ForLoopToLoop>(); // Must come after
manager.Add<transform::WhileToLoop>(); // ZeroInitWorkgroupMemory
diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc
index f3129c0..efc9601 100644
--- a/src/tint/writer/wgsl/generator_impl.cc
+++ b/src/tint/writer/wgsl/generator_impl.cc
@@ -67,7 +67,7 @@
return false;
}
}
- if (!program_->AST().Enables().empty()) {
+ if (!program_->AST().Enables().IsEmpty()) {
line();
}
// Generate global declarations in the order they appear in the module.
@@ -80,13 +80,14 @@
[&](const ast::TypeDecl* td) { return EmitTypeDecl(td); },
[&](const ast::Function* func) { return EmitFunction(func); },
[&](const ast::Variable* var) { return EmitVariable(line(), var); },
+ [&](const ast::StaticAssert* sa) { return EmitStaticAssert(sa); },
[&](Default) {
TINT_UNREACHABLE(Writer, diagnostics_);
return false;
})) {
return false;
}
- if (decl != program_->AST().GlobalDeclarations().back()) {
+ if (decl != program_->AST().GlobalDeclarations().Back()) {
line();
}
}
@@ -281,7 +282,7 @@
}
bool GeneratorImpl::EmitFunction(const ast::Function* func) {
- if (func->attributes.size()) {
+ if (func->attributes.Length()) {
if (!EmitAttributes(line(), func->attributes)) {
return false;
}
@@ -297,7 +298,7 @@
}
first = false;
- if (!v->attributes.empty()) {
+ if (!v->attributes.IsEmpty()) {
if (!EmitAttributes(out, v->attributes)) {
return false;
}
@@ -313,10 +314,10 @@
out << ")";
- if (!func->return_type->Is<ast::Void>() || !func->return_type_attributes.empty()) {
+ if (!func->return_type->Is<ast::Void>() || !func->return_type_attributes.IsEmpty()) {
out << " -> ";
- if (!func->return_type_attributes.empty()) {
+ if (!func->return_type_attributes.IsEmpty()) {
if (!EmitAttributes(out, func->return_type_attributes)) {
return false;
}
@@ -582,7 +583,7 @@
}
bool GeneratorImpl::EmitStructType(const ast::Struct* str) {
- if (str->attributes.size()) {
+ if (str->attributes.Length()) {
if (!EmitAttributes(line(), str->attributes)) {
return false;
}
@@ -614,15 +615,15 @@
// Offset attributes no longer exist in the WGSL spec, but are emitted
// by the SPIR-V reader and are consumed by the Resolver(). These should not
// be emitted, but instead struct padding fields should be emitted.
- ast::AttributeList attributes_sanitized;
- attributes_sanitized.reserve(mem->attributes.size());
+ utils::Vector<const ast::Attribute*, 4> attributes_sanitized;
+ attributes_sanitized.Reserve(mem->attributes.Length());
for (auto* attr : mem->attributes) {
if (!attr->Is<ast::StructMemberOffsetAttribute>()) {
- attributes_sanitized.emplace_back(attr);
+ attributes_sanitized.Push(attr);
}
}
- if (!attributes_sanitized.empty()) {
+ if (!attributes_sanitized.IsEmpty()) {
if (!EmitAttributes(line(), attributes_sanitized)) {
return false;
}
@@ -642,7 +643,7 @@
}
bool GeneratorImpl::EmitVariable(std::ostream& out, const ast::Variable* v) {
- if (!v->attributes.empty()) {
+ if (!v->attributes.IsEmpty()) {
if (!EmitAttributes(out, v->attributes)) {
return false;
}
@@ -707,7 +708,8 @@
return true;
}
-bool GeneratorImpl::EmitAttributes(std::ostream& out, const ast::AttributeList& attrs) {
+bool GeneratorImpl::EmitAttributes(std::ostream& out,
+ utils::VectorRef<const ast::Attribute*> attrs) {
bool first = true;
for (auto* attr : attrs) {
if (!first) {
@@ -945,6 +947,7 @@
[&](const ast::ForLoopStatement* l) { return EmitForLoop(l); },
[&](const ast::WhileStatement* l) { return EmitWhile(l); },
[&](const ast::ReturnStatement* r) { return EmitReturn(r); },
+ [&](const ast::StaticAssert* s) { return EmitStaticAssert(s); },
[&](const ast::SwitchStatement* s) { return EmitSwitch(s); },
[&](const ast::VariableDeclStatement* v) { return EmitVariable(line(), v->variable); },
[&](Default) {
@@ -954,7 +957,7 @@
});
}
-bool GeneratorImpl::EmitStatements(const ast::StatementList& stmts) {
+bool GeneratorImpl::EmitStatements(utils::VectorRef<const ast::Statement*> stmts) {
for (auto* s : stmts) {
if (!EmitStatement(s)) {
return false;
@@ -963,7 +966,7 @@
return true;
}
-bool GeneratorImpl::EmitStatementsWithIndent(const ast::StatementList& stmts) {
+bool GeneratorImpl::EmitStatementsWithIndent(utils::VectorRef<const ast::Statement*> stmts) {
ScopedIndent si(this);
return EmitStatements(stmts);
}
@@ -1243,6 +1246,16 @@
return true;
}
+bool GeneratorImpl::EmitStaticAssert(const ast::StaticAssert* stmt) {
+ auto out = line();
+ out << "static_assert ";
+ if (!EmitExpression(out, stmt->condition)) {
+ return false;
+ }
+ out << ";";
+ return true;
+}
+
bool GeneratorImpl::EmitSwitch(const ast::SwitchStatement* stmt) {
{
auto out = line();
diff --git a/src/tint/writer/wgsl/generator_impl.h b/src/tint/writer/wgsl/generator_impl.h
index 8ceeab2..f4fc467 100644
--- a/src/tint/writer/wgsl/generator_impl.h
+++ b/src/tint/writer/wgsl/generator_impl.h
@@ -165,6 +165,10 @@
/// @param stmt the statement to emit
/// @returns true if the statement was successfully emitted
bool EmitReturn(const ast::ReturnStatement* stmt);
+ /// Handles static assertion statements
+ /// @param stmt the statement to emit
+ /// @returns true if the statement was successfully emitted
+ bool EmitStaticAssert(const ast::StaticAssert* stmt);
/// Handles statement
/// @param stmt the statement to emit
/// @returns true if the statement was emitted
@@ -172,11 +176,11 @@
/// Handles a statement list
/// @param stmts the statements to emit
/// @returns true if the statements were emitted
- bool EmitStatements(const ast::StatementList& stmts);
+ bool EmitStatements(utils::VectorRef<const ast::Statement*> stmts);
/// Handles a statement list with an increased indentation
/// @param stmts the statements to emit
/// @returns true if the statements were emitted
- bool EmitStatementsWithIndent(const ast::StatementList& stmts);
+ bool EmitStatementsWithIndent(utils::VectorRef<const ast::Statement*> stmts);
/// Handles generating a switch statement
/// @param stmt the statement to emit
/// @returns true if the statement was emitted
@@ -214,7 +218,7 @@
/// @param out the output of the expression stream
/// @param attrs the attribute list
/// @returns true if the attributes were emitted
- bool EmitAttributes(std::ostream& out, const ast::AttributeList& attrs);
+ bool EmitAttributes(std::ostream& out, utils::VectorRef<const ast::Attribute*> attrs);
};
} // namespace tint::writer::wgsl
diff --git a/src/tint/writer/wgsl/generator_impl_alias_type_test.cc b/src/tint/writer/wgsl/generator_impl_alias_type_test.cc
index 92a6868..dd0584d 100644
--- a/src/tint/writer/wgsl/generator_impl_alias_type_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_alias_type_test.cc
@@ -30,7 +30,7 @@
}
TEST_F(WgslGeneratorImplTest, EmitTypeDecl_Struct) {
- auto* s = Structure("A", {
+ auto* s = Structure("A", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.i32()),
});
@@ -50,7 +50,7 @@
}
TEST_F(WgslGeneratorImplTest, EmitAlias_ToStruct) {
- auto* s = Structure("A", {
+ auto* s = Structure("A", utils::Vector{
Member("a", ty.f32()),
Member("b", ty.i32()),
});
diff --git a/src/tint/writer/wgsl/generator_impl_call_test.cc b/src/tint/writer/wgsl/generator_impl_call_test.cc
index 24f7e4b..4746be2 100644
--- a/src/tint/writer/wgsl/generator_impl_call_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_call_test.cc
@@ -23,7 +23,10 @@
using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithoutParams) {
- Func("my_func", {}, ty.f32(), {Return(1.23_f)});
+ Func("my_func", utils::Empty, ty.f32(),
+ utils::Vector{
+ Return(1.23_f),
+ });
auto* call = Call("my_func");
WrapInFunction(call);
@@ -37,11 +40,14 @@
TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithParams) {
Func("my_func",
- {
+ utils::Vector{
Param(Sym(), ty.f32()),
Param(Sym(), ty.f32()),
},
- ty.f32(), {Return(1.23_f)});
+ ty.f32(),
+ utils::Vector{
+ Return(1.23_f),
+ });
GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
@@ -57,11 +63,11 @@
TEST_F(WgslGeneratorImplTest, EmitStatement_Call) {
Func("my_func",
- {
+ utils::Vector{
Param(Sym(), ty.f32()),
Param(Sym(), ty.f32()),
},
- ty.void_(), ast::StatementList{}, ast::AttributeList{});
+ ty.void_(), utils::Empty, utils::Empty);
GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
diff --git a/src/tint/writer/wgsl/generator_impl_case_test.cc b/src/tint/writer/wgsl/generator_impl_case_test.cc
index c12997e..6d59970 100644
--- a/src/tint/writer/wgsl/generator_impl_case_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_case_test.cc
@@ -37,7 +37,13 @@
}
TEST_F(WgslGeneratorImplTest, Emit_Case_MultipleSelectors) {
- auto* s = Switch(1_i, Case({Expr(5_i), Expr(6_i)}, Block(create<ast::BreakStatement>())),
+ auto* s = Switch(1_i,
+ Case(
+ utils::Vector{
+ Expr(5_i),
+ Expr(6_i),
+ },
+ Block(create<ast::BreakStatement>())),
DefaultCase());
WrapInFunction(s);
diff --git a/src/tint/writer/wgsl/generator_impl_function_test.cc b/src/tint/writer/wgsl/generator_impl_function_test.cc
index a7dab7a..9e9c3a3 100644
--- a/src/tint/writer/wgsl/generator_impl_function_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_function_test.cc
@@ -25,8 +25,8 @@
using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Function) {
- auto* func = Func("my_func", {}, ty.void_(),
- {
+ auto* func = Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
Return(),
});
@@ -42,8 +42,13 @@
}
TEST_F(WgslGeneratorImplTest, Emit_Function_WithParams) {
- auto* func = Func("my_func", {Param("a", ty.f32()), Param("b", ty.i32())}, ty.void_(),
- {
+ auto* func = Func("my_func",
+ utils::Vector{
+ Param("a", ty.f32()),
+ Param("b", ty.i32()),
+ },
+ ty.void_(),
+ utils::Vector{
Return(),
});
@@ -59,8 +64,11 @@
}
TEST_F(WgslGeneratorImplTest, Emit_Function_WithAttribute_WorkgroupSize) {
- auto* func = Func("my_func", {}, ty.void_(), {Return()},
- {
+ auto* func = Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Return(),
+ },
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(2_i, 4_i, 6_i),
});
@@ -79,8 +87,11 @@
TEST_F(WgslGeneratorImplTest, Emit_Function_WithAttribute_WorkgroupSize_WithIdent) {
GlobalConst("height", ty.i32(), Expr(2_i));
- auto* func = Func("my_func", {}, ty.void_(), {Return()},
- {
+ auto* func = Func("my_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Return(),
+ },
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(2_i, "height"),
});
@@ -99,10 +110,16 @@
TEST_F(WgslGeneratorImplTest, Emit_Function_EntryPoint_Parameters) {
auto* vec4 = ty.vec4<f32>();
- auto* coord = Param("coord", vec4, {Builtin(ast::BuiltinValue::kPosition)});
- auto* loc1 = Param("loc1", ty.f32(), {Location(1u)});
- auto* func = Func("frag_main", {coord, loc1}, ty.void_(), {},
- {
+ auto* coord = Param("coord", vec4,
+ utils::Vector{
+ Builtin(ast::BuiltinValue::kPosition),
+ });
+ auto* loc1 = Param("loc1", ty.f32(),
+ utils::Vector{
+ Location(1u),
+ });
+ auto* func = Func("frag_main", utils::Vector{coord, loc1}, ty.void_(), utils::Empty,
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
});
@@ -118,14 +135,14 @@
}
TEST_F(WgslGeneratorImplTest, Emit_Function_EntryPoint_ReturnValue) {
- auto* func = Func("frag_main", {}, ty.f32(),
- {
+ auto* func = Func("frag_main", utils::Empty, ty.f32(),
+ utils::Vector{
Return(1_f),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kFragment),
},
- {
+ utils::Vector{
Location(1u),
});
@@ -158,10 +175,12 @@
// return;
// }
- auto* s = Structure("Data", {Member("d", ty.f32())});
+ auto* s = Structure("Data", utils::Vector{
+ Member("d", ty.f32()),
+ });
GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -169,12 +188,12 @@
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
- Func("a", {}, ty.void_(),
- {
+ Func("a", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -183,12 +202,12 @@
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
- Func("b", {}, ty.void_(),
- {
+ Func("b", utils::Empty, ty.void_(),
+ utils::Vector{
Decl(var),
Return(),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
diff --git a/src/tint/writer/wgsl/generator_impl_global_decl_test.cc b/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
index ef9e11c..04f520a 100644
--- a/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
@@ -47,25 +47,29 @@
TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
GlobalVar("a0", ty.f32(), ast::StorageClass::kPrivate);
- auto* s0 = Structure("S0", {Member("a", ty.i32())});
+ auto* s0 = Structure("S0", utils::Vector{
+ Member("a", ty.i32()),
+ });
Func("func", {}, ty.f32(),
- {
+ utils::Vector{
Return("a0"),
},
- {});
+ utils::Empty);
GlobalVar("a1", ty.f32(), ast::StorageClass::kPrivate);
- auto* s1 = Structure("S1", {Member("a", ty.i32())});
+ auto* s1 = Structure("S1", utils::Vector{
+ Member("a", ty.i32()),
+ });
Func("main", {}, ty.void_(),
- {
+ utils::Vector{
Decl(Var("s0", ty.Of(s0))),
Decl(Var("s1", ty.Of(s1))),
Assign("a1", Call("func")),
},
- {
+ utils::Vector{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize(1_i),
});
@@ -102,7 +106,7 @@
TEST_F(WgslGeneratorImplTest, Emit_Global_Sampler) {
GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler),
- ast::AttributeList{
+ utils::Vector{
create<ast::GroupAttribute>(0u),
create<ast::BindingAttribute>(0u),
});
@@ -118,7 +122,7 @@
TEST_F(WgslGeneratorImplTest, Emit_Global_Texture) {
auto* st = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
GlobalVar("t", st,
- ast::AttributeList{
+ utils::Vector{
create<ast::GroupAttribute>(0u),
create<ast::BindingAttribute>(0u),
});
@@ -148,7 +152,10 @@
TEST_F(WgslGeneratorImplTest, Emit_OverridableConstants) {
Override("a", ty.f32(), nullptr);
- Override("b", ty.f32(), nullptr, {Id(7u)});
+ Override("b", ty.f32(), nullptr,
+ utils::Vector{
+ Id(7u),
+ });
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc b/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
index 34760ba..7386cd0 100644
--- a/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
@@ -20,7 +20,7 @@
using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) {
- auto* s = Structure("Data", {Member("mem", ty.f32())});
+ auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("str", "mem");
@@ -34,7 +34,7 @@
}
TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor_OfDref) {
- auto* s = Structure("Data", {Member("mem", ty.f32())});
+ auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
auto* p = Let("p", nullptr, AddressOf("str"));
diff --git a/src/tint/writer/wgsl/generator_impl_return_test.cc b/src/tint/writer/wgsl/generator_impl_return_test.cc
index ed1027d..fbbf9de 100644
--- a/src/tint/writer/wgsl/generator_impl_return_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_return_test.cc
@@ -35,7 +35,7 @@
TEST_F(WgslGeneratorImplTest, Emit_ReturnWithValue) {
auto* r = Return(123_i);
- Func("f", {}, ty.i32(), {r});
+ Func("f", utils::Empty, ty.i32(), utils::Vector{r});
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_static_assert_test.cc b/src/tint/writer/wgsl/generator_impl_static_assert_test.cc
new file mode 100644
index 0000000..9e7a1c0
--- /dev/null
+++ b/src/tint/writer/wgsl/generator_impl_static_assert_test.cc
@@ -0,0 +1,47 @@
+// Copyright 2022 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/writer/wgsl/test_helper.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::writer::wgsl {
+namespace {
+
+using WgslGeneratorImplTest = TestHelper;
+
+TEST_F(WgslGeneratorImplTest, Emit_GlobalStaticAssert) {
+ GlobalStaticAssert(true);
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(static_assert true;
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_FunctionStaticAssert) {
+ Func("f", utils::Empty, ty.void_(), utils::Vector{StaticAssert(true)});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ static_assert true;
+}
+)");
+}
+
+} // namespace
+} // namespace tint::writer::wgsl
diff --git a/src/tint/writer/wgsl/generator_impl_switch_test.cc b/src/tint/writer/wgsl/generator_impl_switch_test.cc
index 141a5d7..491660e 100644
--- a/src/tint/writer/wgsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_switch_test.cc
@@ -25,18 +25,18 @@
GlobalVar("cond", ty.i32(), ast::StorageClass::kPrivate);
auto* def_body = Block(create<ast::BreakStatement>());
- auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
+ auto* def = create<ast::CaseStatement>(utils::Empty, def_body);
- ast::CaseSelectorList case_val;
- case_val.push_back(Expr(5_i));
+ utils::Vector case_val{Expr(5_i)};
auto* case_body = Block(create<ast::BreakStatement>());
auto* case_stmt = create<ast::CaseStatement>(case_val, case_body);
- ast::CaseStatementList body;
- body.push_back(case_stmt);
- body.push_back(def);
+ utils::Vector body{
+ case_stmt,
+ def,
+ };
auto* cond = Expr("cond");
auto* s = create<ast::SwitchStatement>(cond, body);
diff --git a/src/tint/writer/wgsl/generator_impl_type_test.cc b/src/tint/writer/wgsl/generator_impl_type_test.cc
index 9536b5b..a86c2a0 100644
--- a/src/tint/writer/wgsl/generator_impl_type_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_type_test.cc
@@ -162,7 +162,7 @@
}
TEST_F(WgslGeneratorImplTest, EmitType_Struct) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
Member("b", ty.f32()),
});
@@ -177,9 +177,9 @@
}
TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl) {
- auto* s = Structure("S", {
- Member("a", ty.i32(), {MemberOffset(8)}),
- Member("b", ty.f32(), {MemberOffset(16)}),
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.i32(), utils::Vector{MemberOffset(8)}),
+ Member("b", ty.f32(), utils::Vector{MemberOffset(16)}),
});
GeneratorImpl& gen = Build();
@@ -197,10 +197,11 @@
}
TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl_WithSymbolCollisions) {
- auto* s = Structure("S", {
- Member("tint_0_padding", ty.i32(), {MemberOffset(8)}),
- Member("tint_2_padding", ty.f32(), {MemberOffset(16)}),
- });
+ auto* s =
+ Structure("S", utils::Vector{
+ Member("tint_0_padding", ty.i32(), utils::Vector{MemberOffset(8)}),
+ Member("tint_2_padding", ty.f32(), utils::Vector{MemberOffset(16)}),
+ });
GeneratorImpl& gen = Build();
@@ -217,9 +218,9 @@
}
TEST_F(WgslGeneratorImplTest, EmitType_StructAlignDecl) {
- auto* s = Structure("S", {
- Member("a", ty.i32(), {MemberAlign(8)}),
- Member("b", ty.f32(), {MemberAlign(16)}),
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.i32(), utils::Vector{MemberAlign(8)}),
+ Member("b", ty.f32(), utils::Vector{MemberAlign(16)}),
});
GeneratorImpl& gen = Build();
@@ -235,9 +236,9 @@
}
TEST_F(WgslGeneratorImplTest, EmitType_StructSizeDecl) {
- auto* s = Structure("S", {
- Member("a", ty.i32(), {MemberSize(16)}),
- Member("b", ty.f32(), {MemberSize(32)}),
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.i32(), utils::Vector{MemberSize(16)}),
+ Member("b", ty.f32(), utils::Vector{MemberSize(32)}),
});
GeneratorImpl& gen = Build();
@@ -253,9 +254,9 @@
}
TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithAttribute) {
- auto* s = Structure("S", {
+ auto* s = Structure("S", utils::Vector{
Member("a", ty.i32()),
- Member("b", ty.f32(), {MemberAlign(8)}),
+ Member("b", ty.f32(), utils::Vector{MemberAlign(8)}),
});
GeneratorImpl& gen = Build();
@@ -270,9 +271,11 @@
}
TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithEntryPointAttributes) {
- auto* s = Structure("S", ast::StructMemberList{
- Member("a", ty.u32(), {Builtin(ast::BuiltinValue::kVertexIndex)}),
- Member("b", ty.f32(), {Location(2u)})});
+ auto* s = Structure(
+ "S", utils::Vector{
+ Member("a", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kVertexIndex)}),
+ Member("b", ty.f32(), utils::Vector{Location(2u)}),
+ });
GeneratorImpl& gen = Build();
@@ -460,7 +463,7 @@
auto* t = ty.storage_texture(param.dim, param.fmt, param.access);
GlobalVar("g", t,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(1u),
create<ast::GroupAttribute>(2u),
});
diff --git a/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
index abfe4fec..1d5e4d4 100644
--- a/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
@@ -52,7 +52,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_AInt) {
auto* C = Const("C", nullptr, Expr(1_a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -67,7 +71,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_AFloat) {
auto* C = Const("C", nullptr, Expr(1._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -82,7 +90,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_i32) {
auto* C = Const("C", nullptr, Expr(1_i));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -97,7 +109,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_u32) {
auto* C = Const("C", nullptr, Expr(1_u));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -112,7 +128,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_f32) {
auto* C = Const("C", nullptr, Expr(1_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -129,7 +149,11 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, Expr(1_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -146,7 +170,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AInt) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -161,7 +189,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AFloat) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -176,7 +208,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_f32) {
auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -193,7 +229,11 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, vec3<f16>(1_h, 2_h, 3_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -211,7 +251,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
auto* C =
Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -226,7 +270,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_f32) {
auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -243,7 +291,11 @@
Enable(ast::Extension::kF16);
auto* C = Const("C", nullptr, mat2x3<f16>(1_h, 2_h, 3_h, 4_h, 5_h, 6_h));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -260,7 +312,11 @@
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_f32) {
auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
@@ -279,7 +335,11 @@
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
- Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+ Func("f", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(C),
+ Decl(Let("l", nullptr, Expr(C))),
+ });
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_variable_test.cc b/src/tint/writer/wgsl/generator_impl_variable_test.cc
index a058bc7..78e518e 100644
--- a/src/tint/writer/wgsl/generator_impl_variable_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_variable_test.cc
@@ -42,9 +42,9 @@
}
TEST_F(WgslGeneratorImplTest, EmitVariable_Access_Read) {
- auto* s = Structure("S", {Member("a", ty.i32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.i32())});
auto* v = GlobalVar("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -57,9 +57,9 @@
}
TEST_F(WgslGeneratorImplTest, EmitVariable_Access_ReadWrite) {
- auto* s = Structure("S", {Member("a", ty.i32())});
+ auto* s = Structure("S", utils::Vector{Member("a", ty.i32())});
auto* v = GlobalVar("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
+ utils::Vector{
create<ast::BindingAttribute>(0u),
create<ast::GroupAttribute>(0u),
});
@@ -74,7 +74,7 @@
TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated) {
auto* v =
GlobalVar("a", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone, nullptr,
- ast::AttributeList{
+ utils::Vector{
create<ast::GroupAttribute>(1u),
create<ast::BindingAttribute>(2u),
});