Convert size attribute to expressions.

This CL updates the size attribute to parse expressions.

Bug: tint:1633
Change-Id: Ia12650848e7041faa53013d195f4313b8d3e9969
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/103320
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Auto-Submit: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
dan sinclair
2022-10-14 18:27:35 +00:00
committed by Dawn LUCI CQ
parent 18bcdebc02
commit 308c55d9e0
11 changed files with 143 additions and 34 deletions

View File

@@ -3551,13 +3551,16 @@ Maybe<const ast::Attribute*> ParserImpl::attribute() {
if (t == "size") {
const char* use = "size attribute";
return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use);
if (val.errored) {
auto expr = expression();
if (expr.errored) {
return Failure::kErrored;
}
if (!expr.matched) {
return add_error(peek(), "expected size expression");
}
match(Token::Type::kComma);
return builder_.MemberSize(t.source(), AInt(val.value));
return builder_.MemberSize(t.source(), expr.value);
});
}

View File

@@ -862,17 +862,9 @@ struct S { @align(fn) i : i32, };
}
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeInvaldValue) {
EXPECT("struct S { @size(x) i : i32, };",
R"(test.wgsl:1:18 error: expected signed integer literal for size attribute
struct S { @size(x) i : i32, };
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclStructMemberSizeNegativeValue) {
EXPECT("struct S { @size(-2) i : i32, };",
R"(test.wgsl:1:18 error: size attribute must be positive
struct S { @size(-2) i : i32, };
EXPECT("struct S { @size(if) i : i32, };",
R"(test.wgsl:1:18 error: expected size expression
struct S { @size(if) i : i32, };
^^
)");
}

View File

@@ -71,12 +71,12 @@ TEST_F(ParserImplTest, StructBodyDecl_InvalidAlign) {
TEST_F(ParserImplTest, StructBodyDecl_InvalidSize) {
auto p = parser(R"(
{
@size(nan) a : i32,
@size(if) a : i32,
})");
auto m = p->expect_struct_body_decl();
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(m.errored);
EXPECT_EQ(p->error(), "3:9: expected signed integer literal for size attribute");
EXPECT_EQ(p->error(), "3:9: expected size expression");
}
TEST_F(ParserImplTest, StructBodyDecl_MissingClosingBracket) {

View File

@@ -39,12 +39,12 @@ TEST_F(ParserImplTest, AttributeDecl_Single) {
}
TEST_F(ParserImplTest, AttributeDecl_InvalidAttribute) {
auto p = parser("@size(nan)");
auto p = parser("@size(if)");
auto attrs = p->attribute_list();
EXPECT_TRUE(p->has_error()) << p->error();
EXPECT_TRUE(attrs.errored);
EXPECT_FALSE(attrs.matched);
EXPECT_EQ(p->error(), "1:7: expected signed integer literal for size attribute");
EXPECT_EQ(p->error(), "1:7: expected size expression");
}
} // namespace

View File

@@ -23,7 +23,7 @@ TEST_F(ParserImplTest, Attribute_Size) {
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr);
ASSERT_FALSE(p->has_error());
ASSERT_FALSE(p->has_error()) << p->error();
auto* member_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(member_attr, nullptr);
@@ -34,13 +34,39 @@ TEST_F(ParserImplTest, Attribute_Size) {
EXPECT_EQ(o->expr->As<ast::IntLiteralExpression>()->value, 4u);
}
TEST_F(ParserImplTest, Attribute_Size_Expression) {
auto p = parser("size(4 + 5)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr);
ASSERT_FALSE(p->has_error()) << p->error();
auto* member_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(member_attr, nullptr);
ASSERT_TRUE(member_attr->Is<ast::StructMemberSizeAttribute>());
auto* o = member_attr->As<ast::StructMemberSizeAttribute>();
ASSERT_TRUE(o->expr->Is<ast::BinaryExpression>());
auto* expr = o->expr->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kAdd, expr->op);
auto* v = expr->lhs->As<ast::IntLiteralExpression>();
ASSERT_NE(nullptr, v);
EXPECT_EQ(v->value, 4u);
v = expr->rhs->As<ast::IntLiteralExpression>();
ASSERT_NE(nullptr, v);
EXPECT_EQ(v->value, 5u);
}
TEST_F(ParserImplTest, Attribute_Size_TrailingComma) {
auto p = parser("size(4,)");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr);
ASSERT_FALSE(p->has_error());
ASSERT_FALSE(p->has_error()) << p->error();
auto* member_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(member_attr, nullptr);
@@ -78,17 +104,17 @@ TEST_F(ParserImplTest, Attribute_Size_MissingValue) {
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:6: expected signed integer literal for size attribute");
EXPECT_EQ(p->error(), "1:6: expected size expression");
}
TEST_F(ParserImplTest, Attribute_Size_MissingInvalid) {
auto p = parser("size(nan)");
auto p = parser("size(if)");
auto attr = p->attribute();
EXPECT_FALSE(attr.matched);
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:6: expected signed integer literal for size attribute");
EXPECT_EQ(p->error(), "1:6: expected size expression");
}
TEST_F(ParserImplTest, Attribute_Align) {

View File

@@ -115,14 +115,14 @@ TEST_F(ParserImplTest, StructMember_ParsesWithMultipleattributes) {
}
TEST_F(ParserImplTest, StructMember_InvalidAttribute) {
auto p = parser("@size(nan) a : i32,");
auto p = parser("@size(if) a : i32,");
auto m = p->expect_struct_member();
ASSERT_TRUE(m.errored);
ASSERT_EQ(m.value, nullptr);
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:7: expected signed integer literal for size attribute");
EXPECT_EQ(p->error(), "1:7: expected size expression");
}
} // namespace