writer/wgsl: Fix all tests that had unreachable AST nodes

By making nodes reachable, the resolver has now caught a whole lot of additional problems, which have been fixed in this CL.

Some of these broken tests were attempting to use private and workgroup variables as function-scope declarations.
This is not legal, and these have been moved to module-scope variables.

Bug: tint:469
Change-Id: If5e812da3f62f096e344c50782ab0f465ae74ea3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48224
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Ben Clayton 2021-04-19 14:40:49 +00:00 committed by Commit Bot service account
parent 8198d57ff2
commit f4d3949c78
26 changed files with 293 additions and 320 deletions

View File

@ -21,11 +21,10 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitExpression_ArrayAccessor) { TEST_F(WgslGeneratorImplTest, ArrayAccessor) {
auto* idx = Expr(5); Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
auto* ary = Expr("ary"); auto* expr = IndexAccessor("ary", 5);
WrapInFunction(expr);
auto* expr = create<ast::ArrayAccessorExpression>(ary, idx);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -33,18 +32,6 @@ TEST_F(WgslGeneratorImplTest, EmitExpression_ArrayAccessor) {
EXPECT_EQ(gen.result(), "ary[5]"); EXPECT_EQ(gen.result(), "ary[5]");
} }
TEST_F(WgslGeneratorImplTest, EmitArrayAccessor) {
auto* ary = Expr("ary");
auto* idx = Expr("idx");
auto* expr = create<ast::ArrayAccessorExpression>(ary, idx);
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitArrayAccessor(expr)) << gen.error();
EXPECT_EQ(gen.result(), "ary[idx]");
}
} // namespace } // namespace
} // namespace wgsl } // namespace wgsl
} // namespace writer } // namespace writer

View File

@ -22,9 +22,10 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Assign) { TEST_F(WgslGeneratorImplTest, Emit_Assign) {
auto* lhs = Expr("lhs"); Global("lhs", ty.i32(), ast::StorageClass::kPrivate);
auto* rhs = Expr("rhs"); Global("rhs", ty.i32(), ast::StorageClass::kPrivate);
auto* assign = create<ast::AssignmentStatement>(lhs, rhs); auto* assign = create<ast::AssignmentStatement>(Expr("lhs"), Expr("rhs"));
WrapInFunction(assign);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -35,6 +35,7 @@ TEST_P(WgslBinaryTest, Emit) {
auto* right = Expr("right"); auto* right = Expr("right");
auto* expr = create<ast::BinaryExpression>(params.op, left, right); auto* expr = create<ast::BinaryExpression>(params.op, left, right);
WrapInFunction(expr);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -22,13 +22,13 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitExpression_Bitcast) { TEST_F(WgslGeneratorImplTest, EmitExpression_Bitcast) {
auto* id = Expr("id"); auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr(1));
auto* bitcast = create<ast::BitcastExpression>(ty.f32(), id); WrapInFunction(bitcast);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitExpression(bitcast)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(bitcast)) << gen.error();
EXPECT_EQ(gen.result(), "bitcast<f32>(id)"); EXPECT_EQ(gen.result(), "bitcast<f32>(1)");
} }
} // namespace } // namespace

View File

@ -22,9 +22,8 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Block) { TEST_F(WgslGeneratorImplTest, Emit_Block) {
auto* b = create<ast::BlockStatement>(ast::StatementList{ auto* b = Block(create<ast::DiscardStatement>());
create<ast::DiscardStatement>(), WrapInFunction(b);
});
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -38,9 +37,9 @@ TEST_F(WgslGeneratorImplTest, Emit_Block) {
} }
TEST_F(WgslGeneratorImplTest, Emit_Block_WithoutNewline) { TEST_F(WgslGeneratorImplTest, Emit_Block_WithoutNewline) {
auto* b = create<ast::BlockStatement>(ast::StatementList{ auto* b = Block(create<ast::DiscardStatement>());
create<ast::DiscardStatement>(), WrapInFunction(b);
});
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
gen.increment_indent(); gen.increment_indent();

View File

@ -23,6 +23,7 @@ using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Break) { TEST_F(WgslGeneratorImplTest, Emit_Break) {
auto* b = create<ast::BreakStatement>(); auto* b = create<ast::BreakStatement>();
WrapInFunction(Loop(Block(b)));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -23,8 +23,11 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithoutParams) { TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithoutParams) {
auto* id = Expr("my_func"); Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{},
auto* call = create<ast::CallExpression>(id, ast::ExpressionList{}); ast::DecorationList{});
auto* call = Call("my_func");
WrapInFunction(call);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -33,9 +36,13 @@ TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithoutParams) {
} }
TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithParams) { TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithParams) {
auto* id = Expr("my_func"); Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{},
auto* call = create<ast::CallExpression>( ast::DecorationList{});
id, ast::ExpressionList{Expr("param1"), Expr("param2")}); Global("param1", ty.f32(), ast::StorageClass::kPrivate);
Global("param2", ty.f32(), ast::StorageClass::kPrivate);
auto* call = Call("my_func", "param1", "param2");
WrapInFunction(call);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -44,15 +51,19 @@ TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithParams) {
} }
TEST_F(WgslGeneratorImplTest, EmitStatement_Call) { TEST_F(WgslGeneratorImplTest, EmitStatement_Call) {
auto* id = Expr("my_func"); Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{},
ast::DecorationList{});
Global("param1", ty.f32(), ast::StorageClass::kPrivate);
Global("param2", ty.f32(), ast::StorageClass::kPrivate);
auto* call = create<ast::CallStatement>(create<ast::CallExpression>( auto* call = Call("my_func", "param1", "param2");
id, ast::ExpressionList{Expr("param1"), Expr("param2")})); auto* stmt = create<ast::CallStatement>(call);
WrapInFunction(stmt);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(call)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
EXPECT_EQ(gen.result(), " my_func(param1, param2);\n"); EXPECT_EQ(gen.result(), " my_func(param1, param2);\n");
} }

View File

@ -22,12 +22,11 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Case) { TEST_F(WgslGeneratorImplTest, Emit_Case) {
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* body = Block(create<ast::BreakStatement>());
create<ast::BreakStatement>(),
});
ast::CaseSelectorList lit; ast::CaseSelectorList lit;
lit.push_back(create<ast::SintLiteral>(ty.i32(), 5)); lit.push_back(Literal(5));
auto* c = create<ast::CaseStatement>(lit, body); auto* c = create<ast::CaseStatement>(lit, body);
WrapInFunction(c);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -41,13 +40,12 @@ TEST_F(WgslGeneratorImplTest, Emit_Case) {
} }
TEST_F(WgslGeneratorImplTest, Emit_Case_MultipleSelectors) { TEST_F(WgslGeneratorImplTest, Emit_Case_MultipleSelectors) {
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* body = Block(create<ast::BreakStatement>());
create<ast::BreakStatement>(),
});
ast::CaseSelectorList lit; ast::CaseSelectorList lit;
lit.push_back(create<ast::SintLiteral>(ty.i32(), 5)); lit.push_back(Literal(5));
lit.push_back(create<ast::SintLiteral>(ty.i32(), 6)); lit.push_back(Literal(6));
auto* c = create<ast::CaseStatement>(lit, body); auto* c = create<ast::CaseStatement>(lit, body);
WrapInFunction(c);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -61,10 +59,9 @@ TEST_F(WgslGeneratorImplTest, Emit_Case_MultipleSelectors) {
} }
TEST_F(WgslGeneratorImplTest, Emit_Case_Default) { TEST_F(WgslGeneratorImplTest, Emit_Case_Default) {
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* body = Block(create<ast::BreakStatement>());
create<ast::BreakStatement>(),
});
auto* c = create<ast::CaseStatement>(ast::CaseSelectorList{}, body); auto* c = create<ast::CaseStatement>(ast::CaseSelectorList{}, body);
WrapInFunction(c);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -21,13 +21,24 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitExpression_Cast) { TEST_F(WgslGeneratorImplTest, EmitExpression_Cast_Scalar) {
auto* cast = Construct<f32>("id"); auto* cast = Construct<f32>(1);
WrapInFunction(cast);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitExpression(cast)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(cast)) << gen.error();
EXPECT_EQ(gen.result(), "f32(id)"); EXPECT_EQ(gen.result(), "f32(1)");
}
TEST_F(WgslGeneratorImplTest, EmitExpression_Cast_Vector) {
auto* cast = vec3<f32>(vec3<i32>(1, 2, 3));
WrapInFunction(cast);
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitExpression(cast)) << gen.error();
EXPECT_EQ(gen.result(), "vec3<f32>(vec3<i32>(1, 2, 3))");
} }
} // namespace } // namespace

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "gmock/gmock.h"
#include "src/writer/wgsl/test_helper.h" #include "src/writer/wgsl/test_helper.h"
namespace tint { namespace tint {
@ -19,112 +20,114 @@ namespace writer {
namespace wgsl { namespace wgsl {
namespace { namespace {
using ::testing::HasSubstr;
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitConstructor_Bool) { TEST_F(WgslGeneratorImplTest, EmitConstructor_Bool) {
auto* expr = Expr(false); WrapInFunction(Expr(false));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), "false"); EXPECT_THAT(gen.result(), HasSubstr("false"));
} }
TEST_F(WgslGeneratorImplTest, EmitConstructor_Int) { TEST_F(WgslGeneratorImplTest, EmitConstructor_Int) {
auto* expr = Expr(-12345); WrapInFunction(Expr(-12345));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), "-12345"); EXPECT_THAT(gen.result(), HasSubstr("-12345"));
} }
TEST_F(WgslGeneratorImplTest, EmitConstructor_UInt) { TEST_F(WgslGeneratorImplTest, EmitConstructor_UInt) {
auto* expr = Expr(56779u); WrapInFunction(Expr(56779u));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), "56779u"); EXPECT_THAT(gen.result(), HasSubstr("56779u"));
} }
TEST_F(WgslGeneratorImplTest, EmitConstructor_Float) { TEST_F(WgslGeneratorImplTest, EmitConstructor_Float) {
// Use a number close to 1<<30 but whose decimal representation ends in 0. // Use a number close to 1<<30 but whose decimal representation ends in 0.
auto* expr = Expr(static_cast<float>((1 << 30) - 4)); WrapInFunction(Expr(static_cast<float>((1 << 30) - 4)));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), "1073741824.0"); EXPECT_THAT(gen.result(), HasSubstr("1073741824.0"));
} }
TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Float) { TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Float) {
auto* expr = Construct<f32>(Expr(-1.2e-5f)); WrapInFunction(Construct<f32>(Expr(-1.2e-5f)));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), "f32(-0.000012)"); EXPECT_THAT(gen.result(), HasSubstr("f32(-0.000012)"));
} }
TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Bool) { TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Bool) {
auto* expr = Construct<bool>(true); WrapInFunction(Construct<bool>(true));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), "bool(true)"); EXPECT_THAT(gen.result(), HasSubstr("bool(true)"));
} }
TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Int) { TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Int) {
auto* expr = Construct<i32>(-12345); WrapInFunction(Construct<i32>(-12345));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), "i32(-12345)"); EXPECT_THAT(gen.result(), HasSubstr("i32(-12345)"));
} }
TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Uint) { TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Uint) {
auto* expr = Construct<u32>(12345u); WrapInFunction(Construct<u32>(12345u));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), "u32(12345u)"); EXPECT_THAT(gen.result(), HasSubstr("u32(12345u)"));
} }
TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Vec) { TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Vec) {
auto* expr = vec3<f32>(1.f, 2.f, 3.f); WrapInFunction(vec3<f32>(1.f, 2.f, 3.f));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), "vec3<f32>(1.0, 2.0, 3.0)"); EXPECT_THAT(gen.result(), HasSubstr("vec3<f32>(1.0, 2.0, 3.0)"));
} }
TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Mat) { TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Mat) {
auto* expr = Construct(ty.mat2x3<f32>(), vec2<f32>(1.0f, 2.0f), WrapInFunction(
vec2<f32>(3.0f, 4.0f), vec2<f32>(5.0f, 6.0f)); mat2x3<f32>(vec3<f32>(1.f, 2.f, 3.f), vec3<f32>(3.f, 4.f, 5.f)));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), EXPECT_THAT(gen.result(), HasSubstr("mat2x3<f32>(vec3<f32>(1.0, 2.0, 3.0), "
"mat2x3<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0), " "vec3<f32>(3.0, 4.0, 5.0))"));
"vec2<f32>(5.0, 6.0))");
} }
TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Array) { TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Array) {
auto* expr = array(ty.vec3<f32>(), 3, vec3<f32>(1.f, 2.f, 3.f), WrapInFunction(
vec3<f32>(4.f, 5.f, 6.f), vec3<f32>(7.f, 8.f, 9.f)); Construct(ty.array(ty.vec3<f32>(), 3), vec3<f32>(1.0f, 2.0f, 3.0f),
vec3<f32>(4.0f, 5.0f, 6.0f), vec3<f32>(7.0f, 8.0f, 9.0f)));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructor(expr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), EXPECT_THAT(gen.result(),
"array<vec3<f32>, 3>(vec3<f32>(1.0, 2.0, 3.0), " HasSubstr("array<vec3<f32>, 3>(vec3<f32>(1.0, 2.0, 3.0), "
"vec3<f32>(4.0, 5.0, 6.0), vec3<f32>(7.0, 8.0, 9.0))"); "vec3<f32>(4.0, 5.0, 6.0), vec3<f32>(7.0, 8.0, 9.0))"));
} }
} // namespace } // namespace

View File

@ -23,6 +23,7 @@ using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Continue) { TEST_F(WgslGeneratorImplTest, Emit_Continue) {
auto* c = create<ast::ContinueStatement>(); auto* c = create<ast::ContinueStatement>();
WrapInFunction(Loop(Block(c)));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -22,13 +22,14 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Discard) { TEST_F(WgslGeneratorImplTest, Emit_Discard) {
auto* k = create<ast::DiscardStatement>(); auto* stmt = create<ast::DiscardStatement>();
WrapInFunction(stmt);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(k)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
EXPECT_EQ(gen.result(), " discard;\n"); EXPECT_EQ(gen.result(), " discard;\n");
} }

View File

@ -59,19 +59,15 @@ TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_UnusedFunction) {
} }
TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_UnusedVariable) { TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_UnusedVariable) {
auto* global_unused = Global("global_unused", ty.f32(), ast::StorageClass::kPrivate);
Global("global_unused", ty.f32(), ast::StorageClass::kInput);
create<ast::VariableDeclStatement>(global_unused);
auto* global_used = Global("global_used", ty.f32(), ast::StorageClass::kPrivate);
Global("global_used", ty.f32(), ast::StorageClass::kInput);
create<ast::VariableDeclStatement>(global_used);
Func("main", ast::VariableList{}, ty.void_(), Func("main", {}, ty.void_(),
ast::StatementList{ {
create<ast::AssignmentStatement>(Expr("global_used"), Expr(1.f)), create<ast::AssignmentStatement>(Expr("global_used"), Expr(1.f)),
}, },
ast::DecorationList{ {
create<ast::StageDecoration>(ast::PipelineStage::kCompute), create<ast::StageDecoration>(ast::PipelineStage::kCompute),
}); });
@ -82,7 +78,7 @@ TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_UnusedVariable) {
ASSERT_TRUE( ASSERT_TRUE(
gen.GenerateEntryPoint(tint::ast::PipelineStage::kCompute, "main")) gen.GenerateEntryPoint(tint::ast::PipelineStage::kCompute, "main"))
<< gen.error(); << gen.error();
EXPECT_EQ(gen.result(), R"( var<in> global_used : f32; EXPECT_EQ(gen.result(), R"( var<private> global_used : f32;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -92,39 +88,26 @@ TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_UnusedVariable) {
} }
TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_GlobalsInterleaved) { TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_GlobalsInterleaved) {
auto* global0 = Global("a0", ty.f32(), ast::StorageClass::kInput); Global("a0", ty.f32(), ast::StorageClass::kPrivate);
create<ast::VariableDeclStatement>(global0);
auto* str0 = create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32())}, auto* s0 = Structure("S0", {Member("a", ty.i32())});
ast::DecorationList{});
auto* s0 = ty.struct_("S0", str0);
AST().AddConstructedType(s0);
Func("func", ast::VariableList{}, ty.f32(), Func("func", {}, ty.f32(),
ast::StatementList{ {
create<ast::ReturnStatement>(Expr("a0")), Return("a0"),
});
Global("a1", ty.f32(), ast::StorageClass::kOutput);
auto* s1 = Structure("S1", {Member("a", ty.i32())});
Func("main", {}, ty.void_(),
{
Decl(Var("s0", s0, ast::StorageClass::kFunction)),
Decl(Var("s1", s1, ast::StorageClass::kFunction)),
create<ast::AssignmentStatement>(Expr("a1"), Call("func")),
}, },
ast::DecorationList{}); {
auto* global1 = Global("a1", ty.f32(), ast::StorageClass::kOutput);
create<ast::VariableDeclStatement>(global1);
auto* str1 = create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32())},
ast::DecorationList{});
auto* s1 = ty.struct_("S1", str1);
AST().AddConstructedType(s1);
auto* call_func = Call("func");
Func("main", ast::VariableList{}, ty.void_(),
ast::StatementList{
create<ast::VariableDeclStatement>(
Var("s0", s0, ast::StorageClass::kFunction)),
create<ast::VariableDeclStatement>(
Var("s1", s1, ast::StorageClass::kFunction)),
create<ast::AssignmentStatement>(Expr("a1"), Expr(call_func)),
},
ast::DecorationList{
create<ast::StageDecoration>(ast::PipelineStage::kCompute), create<ast::StageDecoration>(ast::PipelineStage::kCompute),
}); });
@ -135,7 +118,7 @@ TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_GlobalsInterleaved) {
ASSERT_TRUE( ASSERT_TRUE(
gen.GenerateEntryPoint(tint::ast::PipelineStage::kCompute, "main")) gen.GenerateEntryPoint(tint::ast::PipelineStage::kCompute, "main"))
<< gen.error(); << gen.error();
EXPECT_EQ(gen.result(), R"( var<in> a0 : f32; EXPECT_EQ(gen.result(), R"( var<private> a0 : f32;
struct S0 { struct S0 {
a : i32; a : i32;

View File

@ -23,6 +23,7 @@ using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Fallthrough) { TEST_F(WgslGeneratorImplTest, Emit_Fallthrough) {
auto* f = create<ast::FallthroughStatement>(); auto* f = create<ast::FallthroughStatement>();
WrapInFunction(f);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -27,10 +27,9 @@ using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_GlobalDeclAfterFunction) { TEST_F(WgslGeneratorImplTest, Emit_GlobalDeclAfterFunction) {
auto* func_var = Var("a", ty.f32(), ast::StorageClass::kFunction); auto* func_var = Var("a", ty.f32(), ast::StorageClass::kFunction);
WrapInFunction(create<ast::VariableDeclStatement>(func_var)); WrapInFunction(func_var);
auto* global_var = Global("a", ty.f32(), ast::StorageClass::kInput); Global("a", ty.f32(), ast::StorageClass::kPrivate);
create<ast::VariableDeclStatement>(global_var);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -42,18 +41,14 @@ TEST_F(WgslGeneratorImplTest, Emit_GlobalDeclAfterFunction) {
var a : f32; var a : f32;
} }
var<in> a : f32; var<private> a : f32;
)"); )");
} }
TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) { TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
auto* global0 = Global("a0", ty.f32(), ast::StorageClass::kInput); Global("a0", ty.f32(), ast::StorageClass::kPrivate);
create<ast::VariableDeclStatement>(global0);
auto* str0 = create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32())}, auto* s0 = Structure("S0", {Member("a", ty.i32())});
ast::DecorationList{});
auto* s0 = ty.struct_("S0", str0);
AST().AddConstructedType(s0);
Func("func", ast::VariableList{}, ty.f32(), Func("func", ast::VariableList{}, ty.f32(),
ast::StatementList{ ast::StatementList{
@ -61,23 +56,15 @@ TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
}, },
ast::DecorationList{}); ast::DecorationList{});
auto* global1 = Global("a1", ty.f32(), ast::StorageClass::kOutput); Global("a1", ty.f32(), ast::StorageClass::kOutput);
create<ast::VariableDeclStatement>(global1);
auto* str1 = create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32())}, auto* s1 = Structure("S1", {Member("a", ty.i32())});
ast::DecorationList{});
auto* s1 = ty.struct_("S1", str1);
AST().AddConstructedType(s1);
auto* call_func = Call("func");
Func("main", ast::VariableList{}, ty.void_(), Func("main", ast::VariableList{}, ty.void_(),
ast::StatementList{ ast::StatementList{
create<ast::VariableDeclStatement>( Decl(Var("s0", s0, ast::StorageClass::kFunction)),
Var("s0", s0, ast::StorageClass::kFunction)), Decl(Var("s1", s1, ast::StorageClass::kFunction)),
create<ast::VariableDeclStatement>( create<ast::AssignmentStatement>(Expr("a1"), Call("func")),
Var("s1", s1, ast::StorageClass::kFunction)),
create<ast::AssignmentStatement>(Expr("a1"), Expr(call_func)),
}, },
ast::DecorationList{ ast::DecorationList{
create<ast::StageDecoration>(ast::PipelineStage::kCompute), create<ast::StageDecoration>(ast::PipelineStage::kCompute),
@ -88,7 +75,7 @@ TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.Generate(nullptr)) << gen.error(); ASSERT_TRUE(gen.Generate(nullptr)) << gen.error();
EXPECT_EQ(gen.result(), R"( var<in> a0 : f32; EXPECT_EQ(gen.result(), R"( var<private> a0 : f32;
struct S0 { struct S0 {
a : i32; a : i32;

View File

@ -23,6 +23,7 @@ using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitIdentifierExpression_Single) { TEST_F(WgslGeneratorImplTest, EmitIdentifierExpression_Single) {
auto* i = Expr("glsl"); auto* i = Expr("glsl");
WrapInFunction(i);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -22,11 +22,12 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_If) { TEST_F(WgslGeneratorImplTest, Emit_If) {
Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* cond = Expr("cond"); auto* cond = Expr("cond");
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* body = Block(Return());
create<ast::DiscardStatement>(), auto* i = If(cond, body);
}); WrapInFunction(i);
auto* i = create<ast::IfStatement>(cond, body, ast::ElseStatementList{});
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -34,23 +35,24 @@ TEST_F(WgslGeneratorImplTest, Emit_If) {
ASSERT_TRUE(gen.EmitStatement(i)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
EXPECT_EQ(gen.result(), R"( if (cond) { EXPECT_EQ(gen.result(), R"( if (cond) {
discard; return;
} }
)"); )");
} }
TEST_F(WgslGeneratorImplTest, Emit_IfWithElseIf) { TEST_F(WgslGeneratorImplTest, Emit_IfWithElseIf) {
auto* else_body = create<ast::BlockStatement>(ast::StatementList{ Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
create<ast::DiscardStatement>(), Global("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
});
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* else_cond = Expr("else_cond");
create<ast::DiscardStatement>(), auto* else_body = Block(Return());
});
auto* i = create<ast::IfStatement>( auto* cond = Expr("cond");
Expr("cond"), body, auto* body = Block(Return());
ast::ElseStatementList{ auto* i = If(
create<ast::ElseStatement>(Expr("else_cond"), else_body)}); cond, body,
ast::ElseStatementList{create<ast::ElseStatement>(else_cond, else_body)});
WrapInFunction(i);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -58,25 +60,24 @@ TEST_F(WgslGeneratorImplTest, Emit_IfWithElseIf) {
ASSERT_TRUE(gen.EmitStatement(i)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
EXPECT_EQ(gen.result(), R"( if (cond) { EXPECT_EQ(gen.result(), R"( if (cond) {
discard; return;
} elseif (else_cond) { } elseif (else_cond) {
discard; return;
} }
)"); )");
} }
TEST_F(WgslGeneratorImplTest, Emit_IfWithElse) { TEST_F(WgslGeneratorImplTest, Emit_IfWithElse) {
auto* else_body = create<ast::BlockStatement>(ast::StatementList{ Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
create<ast::DiscardStatement>(),
}); auto* else_body = Block(Return());
auto* cond = Expr("cond"); auto* cond = Expr("cond");
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* body = Block(Return());
create<ast::DiscardStatement>(), auto* i = If(
});
auto* i = create<ast::IfStatement>(
cond, body, cond, body,
ast::ElseStatementList{create<ast::ElseStatement>(nullptr, else_body)}); ast::ElseStatementList{create<ast::ElseStatement>(nullptr, else_body)});
WrapInFunction(i);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -84,31 +85,31 @@ TEST_F(WgslGeneratorImplTest, Emit_IfWithElse) {
ASSERT_TRUE(gen.EmitStatement(i)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
EXPECT_EQ(gen.result(), R"( if (cond) { EXPECT_EQ(gen.result(), R"( if (cond) {
discard; return;
} else { } else {
discard; return;
} }
)"); )");
} }
TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) { TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) {
auto* else_body = create<ast::BlockStatement>(ast::StatementList{ Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
create<ast::DiscardStatement>(), Global("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
});
auto* else_body_2 = create<ast::BlockStatement>(ast::StatementList{ auto* else_cond = Expr("else_cond");
create<ast::DiscardStatement>(),
});
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* else_body = Block(Return());
create<ast::DiscardStatement>(),
}); auto* else_body_2 = Block(Return());
auto* i = create<ast::IfStatement>(
Expr("cond"), body, auto* cond = Expr("cond");
auto* body = Block(Return());
auto* i = If(cond, body,
ast::ElseStatementList{ ast::ElseStatementList{
create<ast::ElseStatement>(Expr("else_cond"), else_body), create<ast::ElseStatement>(else_cond, else_body),
create<ast::ElseStatement>(nullptr, else_body_2), create<ast::ElseStatement>(nullptr, else_body_2),
}); });
WrapInFunction(i);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -116,11 +117,11 @@ TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) {
ASSERT_TRUE(gen.EmitStatement(i)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(i)) << gen.error();
EXPECT_EQ(gen.result(), R"( if (cond) { EXPECT_EQ(gen.result(), R"( if (cond) {
discard; return;
} elseif (else_cond) { } elseif (else_cond) {
discard; return;
} else { } else {
discard; return;
} }
)"); )");
} }

View File

@ -22,10 +22,11 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Loop) { TEST_F(WgslGeneratorImplTest, Emit_Loop) {
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* body = Block(create<ast::DiscardStatement>());
create<ast::DiscardStatement>(), auto* continuing = Block();
}); auto* l = create<ast::LoopStatement>(body, continuing);
auto* l = create<ast::LoopStatement>(body, nullptr);
WrapInFunction(l);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -39,14 +40,12 @@ TEST_F(WgslGeneratorImplTest, Emit_Loop) {
} }
TEST_F(WgslGeneratorImplTest, Emit_LoopWithContinuing) { TEST_F(WgslGeneratorImplTest, Emit_LoopWithContinuing) {
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* body = Block(create<ast::DiscardStatement>());
create<ast::DiscardStatement>(), auto* continuing = Block(Return());
});
auto* continuing = create<ast::BlockStatement>(ast::StatementList{
create<ast::DiscardStatement>(),
});
auto* l = create<ast::LoopStatement>(body, continuing); auto* l = create<ast::LoopStatement>(body, continuing);
WrapInFunction(l);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
gen.increment_indent(); gen.increment_indent();
@ -56,7 +55,7 @@ TEST_F(WgslGeneratorImplTest, Emit_LoopWithContinuing) {
discard; discard;
continuing { continuing {
discard; return;
} }
} }
)"); )");

View File

@ -22,10 +22,11 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) { TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) {
auto* str = Expr("str"); auto* s = Structure("Data", {Member("mem", ty.f32())});
auto* mem = Expr("mem"); Global("str", s, ast::StorageClass::kPrivate);
auto* expr = create<ast::MemberAccessorExpression>(str, mem); auto* expr = MemberAccessor("str", "mem");
WrapInFunction(expr);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -22,7 +22,8 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Return) { TEST_F(WgslGeneratorImplTest, Emit_Return) {
auto* r = create<ast::ReturnStatement>(); auto* r = Return();
WrapInFunction(r);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -33,15 +34,15 @@ TEST_F(WgslGeneratorImplTest, Emit_Return) {
} }
TEST_F(WgslGeneratorImplTest, Emit_ReturnWithValue) { TEST_F(WgslGeneratorImplTest, Emit_ReturnWithValue) {
auto* expr = Expr("expr"); auto* r = Return(123);
auto* r = create<ast::ReturnStatement>(expr); Func("f", {}, ty.i32(), {r});
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(r)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(r)) << gen.error();
EXPECT_EQ(gen.result(), " return expr;\n"); EXPECT_EQ(gen.result(), " return 123;\n");
} }
} // namespace } // namespace

View File

@ -22,17 +22,15 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Switch) { TEST_F(WgslGeneratorImplTest, Emit_Switch) {
auto* def_body = create<ast::BlockStatement>(ast::StatementList{ Global("cond", ty.i32(), ast::StorageClass::kPrivate);
create<ast::BreakStatement>(),
}); auto* def_body = Block(create<ast::BreakStatement>());
auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body); auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
ast::CaseSelectorList case_val; ast::CaseSelectorList case_val;
case_val.push_back(create<ast::SintLiteral>(ty.i32(), 5)); case_val.push_back(Literal(5));
auto* case_body = create<ast::BlockStatement>(ast::StatementList{ auto* case_body = Block(create<ast::BreakStatement>());
create<ast::BreakStatement>(),
});
auto* case_stmt = create<ast::CaseStatement>(case_val, case_body); auto* case_stmt = create<ast::CaseStatement>(case_val, case_body);
@ -42,6 +40,7 @@ TEST_F(WgslGeneratorImplTest, Emit_Switch) {
auto* cond = Expr("cond"); auto* cond = Expr("cond");
auto* s = create<ast::SwitchStatement>(cond, body); auto* s = create<ast::SwitchStatement>(cond, body);
WrapInFunction(s);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -46,7 +46,7 @@ using WgslBuiltinConversionTest = TestParamHelper<WgslBuiltinData>;
TEST_P(WgslBuiltinConversionTest, Emit) { TEST_P(WgslBuiltinConversionTest, Emit) {
auto params = GetParam(); auto params = GetParam();
auto* var = Global("a", ty.f32(), ast::StorageClass::kInput, nullptr, auto* var = Global("a", ty.f32(), ast::StorageClass::kPrivate, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BuiltinDecoration>(params.builtin), create<ast::BuiltinDecoration>(params.builtin),
}); });

View File

@ -28,6 +28,7 @@ using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitType_Alias) { TEST_F(WgslGeneratorImplTest, EmitType_Alias) {
auto* alias = ty.alias("alias", ty.f32()); auto* alias = ty.alias("alias", ty.f32());
AST().AddConstructedType(alias);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -37,6 +38,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_Alias) {
TEST_F(WgslGeneratorImplTest, EmitType_Array) { TEST_F(WgslGeneratorImplTest, EmitType_Array) {
auto* arr = ty.array<bool, 4>(); auto* arr = ty.array<bool, 4>();
AST().AddConstructedType(ty.alias("make_type_reachable", arr));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -48,11 +50,12 @@ TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_Read) {
auto* s = Structure("S", {Member("a", ty.i32())}, auto* s = Structure("S", {Member("a", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
type::AccessControl a(ast::AccessControl::kReadOnly, s); auto* a = ty.access(ast::AccessControl::kReadOnly, s);
AST().AddConstructedType(ty.alias("make_type_reachable", a));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&a)) << gen.error(); ASSERT_TRUE(gen.EmitType(a)) << gen.error();
EXPECT_EQ(gen.result(), "[[access(read)]] S"); EXPECT_EQ(gen.result(), "[[access(read)]] S");
} }
@ -60,50 +63,55 @@ TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_ReadWrite) {
auto* s = Structure("S", {Member("a", ty.i32())}, auto* s = Structure("S", {Member("a", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
type::AccessControl a(ast::AccessControl::kReadWrite, s); auto* a = ty.access(ast::AccessControl::kReadWrite, s);
AST().AddConstructedType(ty.alias("make_type_reachable", a));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&a)) << gen.error(); ASSERT_TRUE(gen.EmitType(a)) << gen.error();
EXPECT_EQ(gen.result(), "[[access(read_write)]] S"); EXPECT_EQ(gen.result(), "[[access(read_write)]] S");
} }
TEST_F(WgslGeneratorImplTest, EmitType_Array_Decoration) { TEST_F(WgslGeneratorImplTest, EmitType_Array_Decoration) {
type::Array a(ty.bool_(), 4, auto* a = create<type::Array>(ty.bool_(), 4,
ast::DecorationList{ ast::DecorationList{
create<ast::StrideDecoration>(16u), create<ast::StrideDecoration>(16u),
}); });
AST().AddConstructedType(ty.alias("make_type_reachable", a));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&a)) << gen.error(); ASSERT_TRUE(gen.EmitType(a)) << gen.error();
EXPECT_EQ(gen.result(), "[[stride(16)]] array<bool, 4>"); EXPECT_EQ(gen.result(), "[[stride(16)]] array<bool, 4>");
} }
TEST_F(WgslGeneratorImplTest, EmitType_Array_MultipleDecorations) { TEST_F(WgslGeneratorImplTest, EmitType_Array_MultipleDecorations) {
type::Array a(ty.bool_(), 4, auto* a = create<type::Array>(ty.bool_(), 4,
ast::DecorationList{ ast::DecorationList{
create<ast::StrideDecoration>(16u), create<ast::StrideDecoration>(16u),
create<ast::StrideDecoration>(32u), create<ast::StrideDecoration>(32u),
}); });
AST().AddConstructedType(ty.alias("make_type_reachable", a));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&a)) << gen.error(); ASSERT_TRUE(gen.EmitType(a)) << gen.error();
EXPECT_EQ(gen.result(), "[[stride(16)]] [[stride(32)]] array<bool, 4>"); EXPECT_EQ(gen.result(), "[[stride(16)]] [[stride(32)]] array<bool, 4>");
} }
TEST_F(WgslGeneratorImplTest, EmitType_RuntimeArray) { TEST_F(WgslGeneratorImplTest, EmitType_RuntimeArray) {
type::Array a(ty.bool_(), 0, ast::DecorationList{}); auto* a = create<type::Array>(ty.bool_(), 0, ast::DecorationList{});
AST().AddConstructedType(ty.alias("make_type_reachable", a));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&a)) << gen.error(); ASSERT_TRUE(gen.EmitType(a)) << gen.error();
EXPECT_EQ(gen.result(), "array<bool>"); EXPECT_EQ(gen.result(), "array<bool>");
} }
TEST_F(WgslGeneratorImplTest, EmitType_Bool) { TEST_F(WgslGeneratorImplTest, EmitType_Bool) {
auto* bool_ = ty.bool_(); auto* bool_ = ty.bool_();
AST().AddConstructedType(ty.alias("make_type_reachable", bool_));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -113,6 +121,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_Bool) {
TEST_F(WgslGeneratorImplTest, EmitType_F32) { TEST_F(WgslGeneratorImplTest, EmitType_F32) {
auto* f32 = ty.f32(); auto* f32 = ty.f32();
AST().AddConstructedType(ty.alias("make_type_reachable", f32));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -122,6 +131,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_F32) {
TEST_F(WgslGeneratorImplTest, EmitType_I32) { TEST_F(WgslGeneratorImplTest, EmitType_I32) {
auto* i32 = ty.i32(); auto* i32 = ty.i32();
AST().AddConstructedType(ty.alias("make_type_reachable", i32));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -131,6 +141,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_I32) {
TEST_F(WgslGeneratorImplTest, EmitType_Matrix) { TEST_F(WgslGeneratorImplTest, EmitType_Matrix) {
auto* mat2x3 = ty.mat2x3<f32>(); auto* mat2x3 = ty.mat2x3<f32>();
AST().AddConstructedType(ty.alias("make_type_reachable", mat2x3));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -139,11 +150,12 @@ TEST_F(WgslGeneratorImplTest, EmitType_Matrix) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_Pointer) { TEST_F(WgslGeneratorImplTest, EmitType_Pointer) {
type::Pointer p(ty.f32(), ast::StorageClass::kWorkgroup); auto* p = create<type::Pointer>(ty.f32(), ast::StorageClass::kWorkgroup);
AST().AddConstructedType(ty.alias("make_type_reachable", p));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&p)) << gen.error(); ASSERT_TRUE(gen.EmitType(p)) << gen.error();
EXPECT_EQ(gen.result(), "ptr<workgroup, f32>"); EXPECT_EQ(gen.result(), "ptr<workgroup, f32>");
} }
@ -283,6 +295,7 @@ struct S {
TEST_F(WgslGeneratorImplTest, EmitType_U32) { TEST_F(WgslGeneratorImplTest, EmitType_U32) {
auto* u32 = ty.u32(); auto* u32 = ty.u32();
AST().AddConstructedType(ty.alias("make_type_reachable", u32));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -292,6 +305,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_U32) {
TEST_F(WgslGeneratorImplTest, EmitType_Vector) { TEST_F(WgslGeneratorImplTest, EmitType_Vector) {
auto* vec3 = ty.vec3<f32>(); auto* vec3 = ty.vec3<f32>();
AST().AddConstructedType(ty.alias("make_type_reachable", vec3));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -299,15 +313,6 @@ TEST_F(WgslGeneratorImplTest, EmitType_Vector) {
EXPECT_EQ(gen.result(), "vec3<f32>"); EXPECT_EQ(gen.result(), "vec3<f32>");
} }
TEST_F(WgslGeneratorImplTest, EmitType_Void) {
auto* void_ = ty.void_();
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(void_)) << gen.error();
EXPECT_EQ(gen.result(), "void");
}
struct TextureData { struct TextureData {
type::TextureDimension dim; type::TextureDimension dim;
const char* name; const char* name;
@ -321,11 +326,12 @@ using WgslGenerator_DepthTextureTest = TestParamHelper<TextureData>;
TEST_P(WgslGenerator_DepthTextureTest, EmitType_DepthTexture) { TEST_P(WgslGenerator_DepthTextureTest, EmitType_DepthTexture) {
auto param = GetParam(); auto param = GetParam();
type::DepthTexture d(param.dim); auto* d = create<type::DepthTexture>(param.dim);
AST().AddConstructedType(ty.alias("make_type_reachable", d));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&d)) << gen.error(); ASSERT_TRUE(gen.EmitType(d)) << gen.error();
EXPECT_EQ(gen.result(), param.name); EXPECT_EQ(gen.result(), param.name);
} }
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
@ -342,33 +348,36 @@ using WgslGenerator_SampledTextureTest = TestParamHelper<TextureData>;
TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_F32) { TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_F32) {
auto param = GetParam(); auto param = GetParam();
type::SampledTexture t(param.dim, ty.f32()); auto* t = create<type::SampledTexture>(param.dim, ty.f32());
AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&t)) << gen.error(); ASSERT_TRUE(gen.EmitType(t)) << gen.error();
EXPECT_EQ(gen.result(), std::string(param.name) + "<f32>"); EXPECT_EQ(gen.result(), std::string(param.name) + "<f32>");
} }
TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_I32) { TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_I32) {
auto param = GetParam(); auto param = GetParam();
type::SampledTexture t(param.dim, ty.i32()); auto* t = create<type::SampledTexture>(param.dim, ty.i32());
AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&t)) << gen.error(); ASSERT_TRUE(gen.EmitType(t)) << gen.error();
EXPECT_EQ(gen.result(), std::string(param.name) + "<i32>"); EXPECT_EQ(gen.result(), std::string(param.name) + "<i32>");
} }
TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_U32) { TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_U32) {
auto param = GetParam(); auto param = GetParam();
type::SampledTexture t(param.dim, ty.u32()); auto* t = create<type::SampledTexture>(param.dim, ty.u32());
AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&t)) << gen.error(); ASSERT_TRUE(gen.EmitType(t)) << gen.error();
EXPECT_EQ(gen.result(), std::string(param.name) + "<u32>"); EXPECT_EQ(gen.result(), std::string(param.name) + "<u32>");
} }
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
@ -386,33 +395,36 @@ using WgslGenerator_MultiampledTextureTest = TestParamHelper<TextureData>;
TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_F32) { TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_F32) {
auto param = GetParam(); auto param = GetParam();
type::MultisampledTexture t(param.dim, ty.f32()); auto* t = create<type::MultisampledTexture>(param.dim, ty.f32());
AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&t)) << gen.error(); ASSERT_TRUE(gen.EmitType(t)) << gen.error();
EXPECT_EQ(gen.result(), std::string(param.name) + "<f32>"); EXPECT_EQ(gen.result(), std::string(param.name) + "<f32>");
} }
TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_I32) { TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_I32) {
auto param = GetParam(); auto param = GetParam();
type::MultisampledTexture t(param.dim, ty.i32()); auto* t = create<type::MultisampledTexture>(param.dim, ty.i32());
AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&t)) << gen.error(); ASSERT_TRUE(gen.EmitType(t)) << gen.error();
EXPECT_EQ(gen.result(), std::string(param.name) + "<i32>"); EXPECT_EQ(gen.result(), std::string(param.name) + "<i32>");
} }
TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_U32) { TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_U32) {
auto param = GetParam(); auto param = GetParam();
type::MultisampledTexture t(param.dim, ty.u32()); auto* t = create<type::MultisampledTexture>(param.dim, ty.u32());
AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&t)) << gen.error(); ASSERT_TRUE(gen.EmitType(t)) << gen.error();
EXPECT_EQ(gen.result(), std::string(param.name) + "<u32>"); EXPECT_EQ(gen.result(), std::string(param.name) + "<u32>");
} }
INSTANTIATE_TEST_SUITE_P(WgslGeneratorImplTest, INSTANTIATE_TEST_SUITE_P(WgslGeneratorImplTest,
@ -437,7 +449,7 @@ TEST_P(WgslGenerator_StorageTextureTest, EmitType_StorageTexture) {
auto* subtype = type::StorageTexture::SubtypeFor(param.fmt, Types()); auto* subtype = type::StorageTexture::SubtypeFor(param.fmt, Types());
auto* t = create<type::StorageTexture>(param.dim, param.fmt, subtype); auto* t = create<type::StorageTexture>(param.dim, param.fmt, subtype);
auto* ac = create<type::AccessControl>(param.access, t); auto* ac = ty.access(param.access, t);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -540,20 +552,22 @@ INSTANTIATE_TEST_SUITE_P(
ImageFormatData{type::ImageFormat::kRgba32Float, "rgba32float"})); ImageFormatData{type::ImageFormat::kRgba32Float, "rgba32float"}));
TEST_F(WgslGeneratorImplTest, EmitType_Sampler) { TEST_F(WgslGeneratorImplTest, EmitType_Sampler) {
type::Sampler sampler(type::SamplerKind::kSampler); auto* sampler = create<type::Sampler>(type::SamplerKind::kSampler);
AST().AddConstructedType(ty.alias("make_type_reachable", sampler));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&sampler)) << gen.error(); ASSERT_TRUE(gen.EmitType(sampler)) << gen.error();
EXPECT_EQ(gen.result(), "sampler"); EXPECT_EQ(gen.result(), "sampler");
} }
TEST_F(WgslGeneratorImplTest, EmitType_SamplerComparison) { TEST_F(WgslGeneratorImplTest, EmitType_SamplerComparison) {
type::Sampler sampler(type::SamplerKind::kComparisonSampler); auto* sampler = create<type::Sampler>(type::SamplerKind::kComparisonSampler);
AST().AddConstructedType(ty.alias("make_type_reachable", sampler));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&sampler)) << gen.error(); ASSERT_TRUE(gen.EmitType(sampler)) << gen.error();
EXPECT_EQ(gen.result(), "sampler_comparison"); EXPECT_EQ(gen.result(), "sampler_comparison");
} }

View File

@ -31,8 +31,13 @@ using WgslUnaryOpTest = TestParamHelper<UnaryOpData>;
TEST_P(WgslUnaryOpTest, Emit) { TEST_P(WgslUnaryOpTest, Emit) {
auto params = GetParam(); auto params = GetParam();
auto* expr = Expr("expr"); auto* type = (params.op == ast::UnaryOp::kNot)
auto* op = create<ast::UnaryOpExpression>(params.op, expr); ? static_cast<type::Type*>(ty.bool_())
: static_cast<type::Type*>(ty.i32());
Global("expr", type, ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(params.op, Expr("expr"));
WrapInFunction(op);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -23,24 +23,6 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement) { TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement) {
auto* var = Var("a", ty.f32(), ast::StorageClass::kInput);
auto* stmt = create<ast::VariableDeclStatement>(var);
WrapInFunction(stmt);
GeneratorImpl& gen = Build();
gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
EXPECT_EQ(gen.result(), " var<in> a : f32;\n");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Function) {
// Variable declarations with Function storage class don't mention their
// storage class. Rely on defaulting.
// https://github.com/gpuweb/gpuweb/issues/654
auto* var = Var("a", ty.f32(), ast::StorageClass::kFunction); auto* var = Var("a", ty.f32(), ast::StorageClass::kFunction);
auto* stmt = create<ast::VariableDeclStatement>(var); auto* stmt = create<ast::VariableDeclStatement>(var);
@ -54,20 +36,6 @@ TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Function) {
EXPECT_EQ(gen.result(), " var a : f32;\n"); EXPECT_EQ(gen.result(), " var a : f32;\n");
} }
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
auto* var = Var("a", ty.f32(), ast::StorageClass::kPrivate);
auto* stmt = create<ast::VariableDeclStatement>(var);
WrapInFunction(stmt);
GeneratorImpl& gen = Build();
gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
EXPECT_EQ(gen.result(), " var<private> a : f32;\n");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_InferredType) { TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_InferredType) {
auto* var = Var("a", nullptr, ast::StorageClass::kFunction, Expr(123)); auto* var = Var("a", nullptr, ast::StorageClass::kFunction, Expr(123));

View File

@ -23,27 +23,27 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitVariable) { TEST_F(WgslGeneratorImplTest, EmitVariable) {
auto* v = Global("a", ty.f32(), ast::StorageClass::kInput); auto* v = Global("a", ty.f32(), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitVariable(v)) << gen.error(); ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
EXPECT_EQ(gen.result(), R"(var<in> a : f32; EXPECT_EQ(gen.result(), R"(var<private> a : f32;
)"); )");
} }
TEST_F(WgslGeneratorImplTest, EmitVariable_StorageClass) { TEST_F(WgslGeneratorImplTest, EmitVariable_StorageClass) {
auto* v = Global("a", ty.f32(), ast::StorageClass::kInput); auto* v = Global("a", ty.f32(), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitVariable(v)) << gen.error(); ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
EXPECT_EQ(gen.result(), R"(var<in> a : f32; EXPECT_EQ(gen.result(), R"(var<private> a : f32;
)"); )");
} }
TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated) { TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated) {
auto* v = Global("a", ty.f32(), ast::StorageClass::kInput, nullptr, auto* v = Global("a", ty.f32(), ast::StorageClass::kPrivate, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::LocationDecoration>(2), create<ast::LocationDecoration>(2),
}); });
@ -51,12 +51,12 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitVariable(v)) << gen.error(); ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
EXPECT_EQ(gen.result(), R"([[location(2)]] var<in> a : f32; EXPECT_EQ(gen.result(), R"([[location(2)]] var<private> a : f32;
)"); )");
} }
TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated_Multiple) { TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated_Multiple) {
auto* v = Global("a", ty.f32(), ast::StorageClass::kInput, nullptr, auto* v = Global("a", ty.f32(), ast::StorageClass::kPrivate, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BuiltinDecoration>(ast::Builtin::kPosition), create<ast::BuiltinDecoration>(ast::Builtin::kPosition),
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
@ -70,17 +70,17 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated_Multiple) {
ASSERT_TRUE(gen.EmitVariable(v)) << gen.error(); ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
EXPECT_EQ( EXPECT_EQ(
gen.result(), gen.result(),
R"([[builtin(position), binding(0), group(1), location(2), constant_id(42)]] var<in> a : f32; R"([[builtin(position), binding(0), group(1), location(2), constant_id(42)]] var<private> a : f32;
)"); )");
} }
TEST_F(WgslGeneratorImplTest, EmitVariable_Constructor) { TEST_F(WgslGeneratorImplTest, EmitVariable_Constructor) {
auto* v = Global("a", ty.f32(), ast::StorageClass::kInput, Expr(1.0f)); auto* v = Global("a", ty.f32(), ast::StorageClass::kPrivate, Expr(1.0f));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitVariable(v)) << gen.error(); ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
EXPECT_EQ(gen.result(), R"(var<in> a : f32 = 1.0; EXPECT_EQ(gen.result(), R"(var<private> a : f32 = 1.0;
)"); )");
} }