[wgsl-reader] Fix struct constructor expressions

The parser was matching struct constructors as function calls.

Bug: tint:458
Change-Id: Ia98489e3a6d62eea2e423c6344b6e35b8f9649f0
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/39101
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
James Price 2021-01-27 21:49:06 +00:00 committed by Commit Bot service account
parent d5c0b8e851
commit 186af2f6ad
2 changed files with 59 additions and 1 deletions

View File

@ -2071,9 +2071,11 @@ Maybe<ast::Expression*> ParserImpl::primary_expression() {
return create<ast::BitcastExpression>(source, type.value, params.value);
}
if (match(Token::Type::kIdentifier))
if (t.IsIdentifier() && !get_constructed(t.to_str())) {
next();
return create<ast::IdentifierExpression>(
t.source(), builder_.Symbols().Register(t.to_str()));
}
auto type = type_decl();
if (type.errored)

View File

@ -136,6 +136,62 @@ TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_InvalidValue) {
EXPECT_EQ(p->error(), "1:5: unable to parse argument expression");
}
TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_StructConstructor_Empty) {
auto p = parser(R"(
struct S { a : i32; b : f32; };
S()
)");
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto e = p->primary_expression();
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::TypeConstructorExpression>());
auto* constructor = e->As<ast::TypeConstructorExpression>();
EXPECT_EQ(constructor->type(), p->get_constructed("S"));
auto values = constructor->values();
ASSERT_EQ(values.size(), 0u);
}
TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_StructConstructor_NotEmpty) {
auto p = parser(R"(
struct S { a : i32; b : f32; };
S(1u, 2.0)
)");
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto e = p->primary_expression();
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::TypeConstructorExpression>());
auto* constructor = e->As<ast::TypeConstructorExpression>();
EXPECT_EQ(constructor->type(), p->get_constructed("S"));
auto values = constructor->values();
ASSERT_EQ(values.size(), 2u);
ASSERT_TRUE(values[0]->Is<ast::ScalarConstructorExpression>());
auto* val0 = values[0]->As<ast::ScalarConstructorExpression>();
ASSERT_TRUE(val0->literal()->Is<ast::UintLiteral>());
EXPECT_EQ(val0->literal()->As<ast::UintLiteral>()->value(), 1u);
ASSERT_TRUE(values[1]->Is<ast::ScalarConstructorExpression>());
auto* val1 = values[1]->As<ast::ScalarConstructorExpression>();
ASSERT_TRUE(val1->literal()->Is<ast::FloatLiteral>());
EXPECT_EQ(val1->literal()->As<ast::FloatLiteral>()->value(), 2.f);
}
TEST_F(ParserImplTest, PrimaryExpression_ConstLiteral_True) {
auto p = parser("true");
auto e = p->primary_expression();