tint/reader: Parse arrays with no type / size
Bug: tint:1628 Change-Id: Ieb3c07e7dae6fd1e5acf4dd4819312092e5b5bf5 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97586 Reviewed-by: David Neto <dneto@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
86329e286b
commit
6835c8df3e
|
@ -1175,33 +1175,40 @@ Expect<const ast::Type*> ParserImpl::expect_type_decl_vector(const Token& t) {
|
|||
Expect<const ast::Type*> ParserImpl::expect_type_decl_array(const Token& t) {
|
||||
const char* use = "array declaration";
|
||||
|
||||
const ast::Expression* size = nullptr;
|
||||
struct TypeAndSize {
|
||||
const ast::Type* type = nullptr;
|
||||
const ast::Expression* size = nullptr;
|
||||
};
|
||||
|
||||
auto subtype = expect_lt_gt_block(use, [&]() -> Expect<const ast::Type*> {
|
||||
if (!peek_is(Token::Type::kLessThan)) {
|
||||
return builder_.ty.array(make_source_range_from(t.source()), nullptr, nullptr);
|
||||
}
|
||||
|
||||
auto type_size = expect_lt_gt_block(use, [&]() -> Expect<TypeAndSize> {
|
||||
auto type = expect_type(use);
|
||||
if (type.errored) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
|
||||
if (match(Token::Type::kComma)) {
|
||||
auto expr = primary_expression();
|
||||
if (expr.errored) {
|
||||
return Failure::kErrored;
|
||||
} else if (!expr.matched) {
|
||||
return add_error(peek(), "expected array size expression");
|
||||
}
|
||||
|
||||
size = std::move(expr.value);
|
||||
if (!match(Token::Type::kComma)) {
|
||||
return TypeAndSize{type.value, nullptr};
|
||||
}
|
||||
|
||||
return type.value;
|
||||
auto size = primary_expression();
|
||||
if (size.errored) {
|
||||
return Failure::kErrored;
|
||||
} else if (!size.matched) {
|
||||
return add_error(peek(), "expected array size expression");
|
||||
}
|
||||
|
||||
return TypeAndSize{type.value, size.value};
|
||||
});
|
||||
|
||||
if (subtype.errored) {
|
||||
if (type_size.errored) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
|
||||
return builder_.ty.array(make_source_range_from(t.source()), subtype.value, size);
|
||||
return builder_.ty.array(make_source_range_from(t.source()), type_size->type, type_size->size);
|
||||
}
|
||||
|
||||
Expect<const ast::Type*> ParserImpl::expect_type_decl_matrix(const Token& t) {
|
||||
|
|
|
@ -603,8 +603,9 @@ let i : vec2<i32> = vec2<i32>(1., 2.;
|
|||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclLetBadConstLiteral) {
|
||||
EXPECT("let i : vec2<i32> = vec2<i32>(!);",
|
||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
|
||||
EXPECT(
|
||||
"let i : vec2<i32> = vec2<i32>(!);",
|
||||
R"(test.wgsl:1:1 warning: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
|
||||
let i : vec2<i32> = vec2<i32>(!);
|
||||
^^^
|
||||
|
||||
|
@ -821,14 +822,6 @@ type meow = f32
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayMissingLessThan) {
|
||||
EXPECT("var i : array;",
|
||||
R"(test.wgsl:1:14 error: expected '<' for array declaration
|
||||
var i : array;
|
||||
^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarArrayMissingGreaterThan) {
|
||||
EXPECT("var i : array<u32, 3;",
|
||||
R"(test.wgsl:1:21 error: expected '>' for array declaration
|
||||
|
|
|
@ -501,6 +501,22 @@ TEST_F(ParserImplTest, TypeDecl_Array_Runtime_Vec) {
|
|||
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Array_InferTypeAndSize) {
|
||||
auto p = parser("array");
|
||||
auto t = p->type_decl();
|
||||
EXPECT_TRUE(t.matched);
|
||||
EXPECT_FALSE(t.errored);
|
||||
ASSERT_NE(t.value, nullptr) << p->error();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_TRUE(t.value->Is<ast::Array>());
|
||||
|
||||
auto* a = t.value->As<ast::Array>();
|
||||
EXPECT_FALSE(a->IsRuntimeArray());
|
||||
EXPECT_EQ(a->type, nullptr);
|
||||
EXPECT_EQ(a->count, nullptr);
|
||||
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 6u}}));
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Array_BadSize) {
|
||||
auto p = parser("array<f32, !>");
|
||||
auto t = p->type_decl();
|
||||
|
@ -521,16 +537,6 @@ TEST_F(ParserImplTest, TypeDecl_Array_MissingSize) {
|
|||
ASSERT_EQ(p->error(), "1:11: expected array size expression");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Array_MissingLessThan) {
|
||||
auto p = parser("array f32>");
|
||||
auto t = p->type_decl();
|
||||
EXPECT_TRUE(t.errored);
|
||||
EXPECT_FALSE(t.matched);
|
||||
ASSERT_EQ(t.value, nullptr);
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(p->error(), "1:7: expected '<' for array declaration");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, TypeDecl_Array_MissingGreaterThan) {
|
||||
auto p = parser("array<f32");
|
||||
auto t = p->type_decl();
|
||||
|
|
Loading…
Reference in New Issue