[wgsl-reader][wgsl-writer] Update struct decorations to new syntax.
This CL updates the parsing of struct decorations to require ()'s around
parameters.
Bug: tint:238
Change-Id: Ia35ca5c260c3c57b5fc95788bd1aef07f75edc39
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/28600
Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com>
Commit-Queue: Sarah Mashayekhi <sarahmashay@google.com>
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index a85f7c7..5781a79 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -1641,7 +1641,7 @@
}
// struct_member_decoration
-// : OFFSET INT_LITERAL
+// : OFFSET PAREN_LEFT INT_LITERAL PAREN_RIGHT
std::unique_ptr<ast::StructMemberDecoration>
ParserImpl::struct_member_decoration() {
auto t = peek();
@@ -1651,6 +1651,12 @@
next(); // Consume the peek
t = next();
+ if (!t.IsParenLeft()) {
+ set_error(t, "missing ( for offset");
+ return nullptr;
+ }
+
+ t = next();
if (!t.IsSintLiteral()) {
set_error(t, "invalid value for offset decoration");
return nullptr;
@@ -1661,6 +1667,12 @@
return nullptr;
}
+ t = next();
+ if (!t.IsParenRight()) {
+ set_error(t, "missing ) for offset");
+ return nullptr;
+ }
+
return std::make_unique<ast::StructMemberOffsetDecoration>(val);
}
diff --git a/src/reader/wgsl/parser_impl_struct_body_decl_test.cc b/src/reader/wgsl/parser_impl_struct_body_decl_test.cc
index ecf29a9..93d0975 100644
--- a/src/reader/wgsl/parser_impl_struct_body_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_body_decl_test.cc
@@ -47,7 +47,7 @@
TEST_F(ParserImplTest, StructBodyDecl_InvalidMember) {
auto* p = parser(R"(
{
- [[offset nan]] a : i32;
+ [[offset(nan)]] a : i32;
})");
auto m = p->struct_body_decl();
ASSERT_TRUE(p->has_error());
diff --git a/src/reader/wgsl/parser_impl_struct_decl_test.cc b/src/reader/wgsl/parser_impl_struct_decl_test.cc
index bb91899..b1480e1 100644
--- a/src/reader/wgsl/parser_impl_struct_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_decl_test.cc
@@ -26,7 +26,7 @@
auto* p = parser(R"(
struct {
a : i32;
- [[offset 4 ]] b : f32;
+ [[offset(4)]] b : f32;
})");
auto s = p->struct_decl();
ASSERT_FALSE(p->has_error());
diff --git a/src/reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc b/src/reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc
index ea54e9c..9f57e0e 100644
--- a/src/reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc
@@ -37,7 +37,7 @@
}
TEST_F(ParserImplTest, StructMemberDecorationDecl_Single) {
- auto* p = parser("[[offset 4]]");
+ auto* p = parser("[[offset(4)]]");
auto deco = p->struct_member_decoration_decl();
ASSERT_FALSE(p->has_error());
ASSERT_EQ(deco.size(), 1u);
@@ -45,24 +45,24 @@
}
TEST_F(ParserImplTest, StructMemberDecorationDecl_HandlesDuplicate) {
- auto* p = parser("[[offset 2, offset 4]]");
+ auto* p = parser("[[offset(2), offset(4)]]");
auto deco = p->struct_member_decoration_decl();
ASSERT_TRUE(p->has_error()) << p->error();
- EXPECT_EQ(p->error(), "1:21: duplicate offset decoration found");
+ EXPECT_EQ(p->error(), "1:23: duplicate offset decoration found");
}
TEST_F(ParserImplTest, StructMemberDecorationDecl_InvalidDecoration) {
- auto* p = parser("[[offset nan]]");
+ auto* p = parser("[[offset(nan)]]");
auto deco = p->struct_member_decoration_decl();
ASSERT_TRUE(p->has_error()) << p->error();
EXPECT_EQ(p->error(), "1:10: invalid value for offset decoration");
}
TEST_F(ParserImplTest, StructMemberDecorationDecl_MissingClose) {
- auto* p = parser("[[offset 4");
+ auto* p = parser("[[offset(4)");
auto deco = p->struct_member_decoration_decl();
ASSERT_TRUE(p->has_error()) << p->error();
- EXPECT_EQ(p->error(), "1:11: missing ]] for struct member decoration");
+ EXPECT_EQ(p->error(), "1:12: missing ]] for struct member decoration");
}
} // namespace
diff --git a/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc b/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc
index 7be4bce..c01be53 100644
--- a/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc
@@ -23,7 +23,7 @@
namespace {
TEST_F(ParserImplTest, StructMemberDecoration_Offset) {
- auto* p = parser("offset 4");
+ auto* p = parser("offset(4)");
auto deco = p->struct_member_decoration();
ASSERT_NE(deco, nullptr);
ASSERT_FALSE(p->has_error());
@@ -33,16 +33,32 @@
EXPECT_EQ(o->offset(), 4u);
}
-TEST_F(ParserImplTest, StructMemberDecoration_Offset_MissingValue) {
- auto* p = parser("offset");
+TEST_F(ParserImplTest, StructMemberDecoration_Offset_MissingLeftParen) {
+ auto* p = parser("offset 4)");
auto deco = p->struct_member_decoration();
ASSERT_EQ(deco, nullptr);
ASSERT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:7: invalid value for offset decoration");
+ EXPECT_EQ(p->error(), "1:8: missing ( for offset");
+}
+
+TEST_F(ParserImplTest, StructMemberDecoration_Offset_MissingRightParen) {
+ auto* p = parser("offset(4");
+ auto deco = p->struct_member_decoration();
+ ASSERT_EQ(deco, nullptr);
+ ASSERT_TRUE(p->has_error());
+ EXPECT_EQ(p->error(), "1:9: missing ) for offset");
+}
+
+TEST_F(ParserImplTest, StructMemberDecoration_Offset_MissingValue) {
+ auto* p = parser("offset()");
+ auto deco = p->struct_member_decoration();
+ ASSERT_EQ(deco, nullptr);
+ ASSERT_TRUE(p->has_error());
+ EXPECT_EQ(p->error(), "1:8: invalid value for offset decoration");
}
TEST_F(ParserImplTest, StructMemberDecoration_Offset_MissingInvalid) {
- auto* p = parser("offset nan");
+ auto* p = parser("offset(nan)");
auto deco = p->struct_member_decoration();
ASSERT_EQ(deco, nullptr);
ASSERT_TRUE(p->has_error());
diff --git a/src/reader/wgsl/parser_impl_struct_member_test.cc b/src/reader/wgsl/parser_impl_struct_member_test.cc
index 49bc44c..7efe135 100644
--- a/src/reader/wgsl/parser_impl_struct_member_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_member_test.cc
@@ -40,7 +40,7 @@
TEST_F(ParserImplTest, StructMember_ParsesWithDecoration) {
auto* i32 = tm()->Get(std::make_unique<ast::type::I32Type>());
- auto* p = parser("[[offset 2]] a : i32;");
+ auto* p = parser("[[offset(2)]] a : i32;");
auto m = p->struct_member();
ASSERT_FALSE(p->has_error());
ASSERT_NE(m, nullptr);
@@ -53,7 +53,7 @@
}
TEST_F(ParserImplTest, StructMember_InvalidDecoration) {
- auto* p = parser("[[offset nan]] a : i32;");
+ auto* p = parser("[[offset(nan)]] a : i32;");
auto m = p->struct_member();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(m, nullptr);
@@ -61,11 +61,11 @@
}
TEST_F(ParserImplTest, StructMember_InvalidVariable) {
- auto* p = parser("[[offset 4]] a : B;");
+ auto* p = parser("[[offset(4)]] a : B;");
auto m = p->struct_member();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(m, nullptr);
- EXPECT_EQ(p->error(), "1:18: unknown type alias 'B'");
+ EXPECT_EQ(p->error(), "1:19: unknown type alias 'B'");
}
TEST_F(ParserImplTest, StructMember_MissingSemicolon) {
diff --git a/src/reader/wgsl/parser_impl_type_alias_test.cc b/src/reader/wgsl/parser_impl_type_alias_test.cc
index 2995881..d60360b 100644
--- a/src/reader/wgsl/parser_impl_type_alias_test.cc
+++ b/src/reader/wgsl/parser_impl_type_alias_test.cc
@@ -91,7 +91,8 @@
TEST_F(ParserImplTest, TypeDecl_Struct_WithStride) {
auto* p = parser(
- "type a = [[block]] struct { [[offset 0]] data: [[stride 4]] array<f32>; "
+ "type a = [[block]] struct { [[offset(0)]] data: [[stride 4]] "
+ "array<f32>; "
"}");
auto* t = p->type_alias();
ASSERT_FALSE(p->has_error());
diff --git a/src/writer/hlsl/generator_impl_member_accessor_test.cc b/src/writer/hlsl/generator_impl_member_accessor_test.cc
index 748b783..8f75a4a 100644
--- a/src/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -80,8 +80,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load) {
// struct Data {
- // [[offset 0]] a : i32;
- // [[offset 4]] b : f32;
+ // [[offset(0)]] a : i32;
+ // [[offset(4)]] b : f32;
// };
// var<storage_buffer> data : Data;
// data.b;
@@ -129,8 +129,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load_Int) {
// struct Data {
- // [[offset 0]] a : i32;
- // [[offset 4]] b : f32;
+ // [[offset(0)]] a : i32;
+ // [[offset(4)]] b : f32;
// };
// var<storage_buffer> data : Data;
// data.a;
@@ -177,8 +177,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Store_Matrix) {
// struct Data {
- // [[offset 0]] z : f32;
- // [[offset 4]] a : mat2x3<f32>;
+ // [[offset(0)]] z : f32;
+ // [[offset(4)]] a : mat2x3<f32>;
// };
// var<storage_buffer> data : Data;
// mat2x3<f32> b;
@@ -241,8 +241,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Store_Matrix_Empty) {
// struct Data {
- // [[offset 0]] z : f32;
- // [[offset 4]] a : mat2x3<f32>;
+ // [[offset(0)]] z : f32;
+ // [[offset(4)]] a : mat2x3<f32>;
// };
// var<storage_buffer> data : Data;
// data.a = mat2x3<f32>();
@@ -303,8 +303,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix) {
// struct Data {
- // [[offset 0]] z : f32;
- // [[offset 4]] a : mat3x2<f32>;
+ // [[offset(0)]] z : f32;
+ // [[offset(4)]] a : mat3x2<f32>;
// };
// var<storage_buffer> data : Data;
// data.a;
@@ -356,12 +356,12 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix_Nested) {
// struct Data {
- // [[offset 0]] z : f32;
- // [[offset 4]] a : mat2x3<f32;
+ // [[offset(0)]] z : f32;
+ // [[offset(4)]] a : mat2x3<f32;
// };
// struct Outer {
- // [[offset 0]] c : f32;
- // [[offset 4]] b : Data;
+ // [[offset(0)]] c : f32;
+ // [[offset(4)]] b : Data;
// };
// var<storage_buffer> data : Outer;
// data.b.a;
@@ -413,7 +413,7 @@
HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix_By3_Is_16_Bytes) {
// struct Data {
- // [[offset 4]] a : mat3x3<f32;
+ // [[offset(4)]] a : mat3x3<f32;
// };
// var<storage_buffer> data : Data;
// data.a;
@@ -460,8 +460,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix_Single_Element) {
// struct Data {
- // [[offset 0]] z : f32;
- // [[offset 16]] a : mat4x3<f32>;
+ // [[offset(0)]] z : f32;
+ // [[offset(16)]] a : mat4x3<f32>;
// };
// var<storage_buffer> data : Data;
// data.a[2][1];
@@ -516,7 +516,7 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_ArrayAccessor_StorageBuffer_Load_Int_FromArray) {
// struct Data {
- // [[offset 0]] a : [[stride 4]] array<i32, 5>;
+ // [[offset(0)]] a : [[stride 4]] array<i32, 5>;
// };
// var<storage_buffer> data : Data;
// data.a[2];
@@ -564,7 +564,7 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_ArrayAccessor_StorageBuffer_Load_Int_FromArray_ExprIdx) {
// struct Data {
- // [[offset 0]] a : [[stride 4]] array<i32, 5>;
+ // [[offset(0)]] a : [[stride 4]] array<i32, 5>;
// };
// var<storage_buffer> data : Data;
// data.a[(2 + 4) - 3];
@@ -620,8 +620,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Store) {
// struct Data {
- // [[offset 0]] a : i32;
- // [[offset 4]] b : f32;
+ // [[offset(0)]] a : i32;
+ // [[offset(4)]] b : f32;
// };
// var<storage_buffer> data : Data;
// data.b = 2.3f;
@@ -674,7 +674,7 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Store_ToArray) {
// struct Data {
- // [[offset 0]] a : [[stride 4]] array<i32, 5>;
+ // [[offset(0)]] a : [[stride 4]] array<i32, 5>;
// };
// var<storage_buffer> data : Data;
// data.a[2] = 2;
@@ -727,8 +727,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Store_Int) {
// struct Data {
- // [[offset 0]] a : i32;
- // [[offset 4]] b : f32;
+ // [[offset(0)]] a : i32;
+ // [[offset(4)]] b : f32;
// };
// var<storage_buffer> data : Data;
// data.a = 2;
@@ -781,8 +781,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load_Vec3) {
// struct Data {
- // [[offset 0]] a : vec3<i32>;
- // [[offset 16]] b : vec3<f32>;
+ // [[offset(0)]] a : vec3<i32>;
+ // [[offset(16)]] b : vec3<f32>;
// };
// var<storage_buffer> data : Data;
// data.b;
@@ -833,8 +833,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Store_Vec3) {
// struct Data {
- // [[offset 0]] a : vec3<i32>;
- // [[offset 16]] b : vec3<f32>;
+ // [[offset(0)]] a : vec3<i32>;
+ // [[offset(16)]] b : vec3<f32>;
// };
// var<storage_buffer> data : Data;
// data.b = vec3<f32>(2.3f, 1.2f, 0.2f);
@@ -903,8 +903,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel) {
// struct Data {
- // [[offset 0]] a : vec3<i32>;
- // [[offset 16]] b : vec3<f32>;
+ // [[offset(0)]] a : vec3<i32>;
+ // [[offset(16)]] b : vec3<f32>;
// };
// struct Pre {
// var c : [[stride 32]] array<Data, 4>;
@@ -976,8 +976,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel_Swizzle) {
// struct Data {
- // [[offset 0]] a : vec3<i32>;
- // [[offset 16]] b : vec3<f32>;
+ // [[offset(0)]] a : vec3<i32>;
+ // [[offset(16)]] b : vec3<f32>;
// };
// struct Pre {
// var c : [[stride 32]] array<Data, 4>;
@@ -1052,8 +1052,8 @@
HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel_Swizzle_SingleLetter) {
// struct Data {
- // [[offset 0]] a : vec3<i32>;
- // [[offset 16]] b : vec3<f32>;
+ // [[offset(0)]] a : vec3<i32>;
+ // [[offset(16)]] b : vec3<f32>;
// };
// struct Pre {
// var c : [[stride 32]] array<Data, 4>;
@@ -1127,8 +1127,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel_Index) {
// struct Data {
- // [[offset 0]] a : vec3<i32>;
- // [[offset 16]] b : vec3<f32>;
+ // [[offset(0)]] a : vec3<i32>;
+ // [[offset(16)]] b : vec3<f32>;
// };
// struct Pre {
// var c : [[stride 32]] array<Data, 4>;
@@ -1203,8 +1203,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Store_MultiLevel) {
// struct Data {
- // [[offset 0]] a : vec3<i32>;
- // [[offset 16]] b : vec3<f32>;
+ // [[offset(0)]] a : vec3<i32>;
+ // [[offset(16)]] b : vec3<f32>;
// };
// struct Pre {
// var c : [[stride 32]] array<Data, 4>;
@@ -1295,8 +1295,8 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor,
EmitExpression_MemberAccessor_StorageBuffer_Store_Swizzle_SingleLetter) {
// struct Data {
- // [[offset 0]] a : vec3<i32>;
- // [[offset 16]] b : vec3<f32>;
+ // [[offset(0)]] a : vec3<i32>;
+ // [[offset(16)]] b : vec3<f32>;
// };
// struct Pre {
// var c : [[stride 32]] array<Data, 4>;
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index c64a1b3..d13d1bb 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -633,7 +633,7 @@
// TODO(dsinclair): Split this out when we have more then one
assert(deco->IsOffset());
- out_ << "offset " << deco->AsOffset()->offset();
+ out_ << "offset(" << deco->AsOffset()->offset() << ")";
}
out_ << "]] ";
}
diff --git a/src/writer/wgsl/generator_impl_alias_type_test.cc b/src/writer/wgsl/generator_impl_alias_type_test.cc
index 8608f10..e0b04ff 100644
--- a/src/writer/wgsl/generator_impl_alias_type_test.cc
+++ b/src/writer/wgsl/generator_impl_alias_type_test.cc
@@ -62,7 +62,7 @@
ASSERT_TRUE(g.EmitAliasType(&alias)) << g.error();
EXPECT_EQ(g.result(), R"(type a = struct {
a : f32;
- [[offset 4]] b : i32;
+ [[offset(4)]] b : i32;
};
)");
}
diff --git a/src/writer/wgsl/generator_impl_type_test.cc b/src/writer/wgsl/generator_impl_type_test.cc
index fe09925..05aade7 100644
--- a/src/writer/wgsl/generator_impl_type_test.cc
+++ b/src/writer/wgsl/generator_impl_type_test.cc
@@ -143,7 +143,7 @@
ASSERT_TRUE(g.EmitType(&s)) << g.error();
EXPECT_EQ(g.result(), R"(struct {
a : i32;
- [[offset 4]] b : f32;
+ [[offset(4)]] b : f32;
})");
}
@@ -170,7 +170,7 @@
ASSERT_TRUE(g.EmitType(&s)) << g.error();
EXPECT_EQ(g.result(), R"([[block]] struct {
a : i32;
- [[offset 4]] b : f32;
+ [[offset(4)]] b : f32;
})");
}
diff --git a/test/compute_boids.wgsl b/test/compute_boids.wgsl
index 5752620..1cf7d3a 100644
--- a/test/compute_boids.wgsl
+++ b/test/compute_boids.wgsl
@@ -42,22 +42,22 @@
# compute shader
type Particle = [[block]] struct {
- [[offset 0]] pos : vec2<f32>;
- [[offset 8]] vel : vec2<f32>;
+ [[offset(0)]] pos : vec2<f32>;
+ [[offset(8)]] vel : vec2<f32>;
};
type SimParams = [[block]] struct {
- [[offset 0]] deltaT : f32;
- [[offset 4]] rule1Distance : f32;
- [[offset 8]] rule2Distance : f32;
- [[offset 12]] rule3Distance : f32;
- [[offset 16]] rule1Scale : f32;
- [[offset 20]] rule2Scale : f32;
- [[offset 24]] rule3Scale : f32;
+ [[offset(0)]] deltaT : f32;
+ [[offset(4)]] rule1Distance : f32;
+ [[offset(8)]] rule2Distance : f32;
+ [[offset(12)]] rule3Distance : f32;
+ [[offset(16)]] rule1Scale : f32;
+ [[offset(20)]] rule2Scale : f32;
+ [[offset(24)]] rule3Scale : f32;
};
type Particles = [[block]] struct {
- [[offset 0]] particles : [[stride 16]] array<Particle, 5>;
+ [[offset(0)]] particles : [[stride 16]] array<Particle, 5>;
};
[[binding 0, set 0]] var<uniform> params : SimParams;
diff --git a/test/cube.wgsl b/test/cube.wgsl
index 88dbd64..7ed1b2c 100644
--- a/test/cube.wgsl
+++ b/test/cube.wgsl
@@ -17,7 +17,7 @@
# Vertex shader
type Uniforms = [[block]] struct {
- [[offset 0]] modelViewProjectionMatrix : mat4x4<f32>;
+ [[offset(0)]] modelViewProjectionMatrix : mat4x4<f32>;
};
[[binding 0, set 0]] var<uniform> uniforms : Uniforms;