[wgsl-reader] Add stride support.
This CL adds stride support to the WGSL reader.
Bug: tint:178
Change-Id: Id6b5163438e562a371255ad3fb992d0a716543e7
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/26040
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 2a9b4c9..b3fca96 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -686,8 +686,10 @@
// | VEC3 LESS_THAN type_decl GREATER_THAN
// | VEC4 LESS_THAN type_decl GREATER_THAN
// | PTR LESS_THAN storage_class, type_decl GREATER_THAN
-// | ARRAY LESS_THAN type_decl COMMA INT_LITERAL GREATER_THAN
-// | ARRAY LESS_THAN type_decl GREATER_THAN
+// | array_decoration_list? ARRAY LESS_THAN type_decl COMMA
+// INT_LITERAL GREATER_THAN
+// | array_decoration_list? ARRAY LESS_THAN type_decl
+// GREATER_THAN
// | MAT2x2 LESS_THAN type_decl GREATER_THAN
// | MAT2x3 LESS_THAN type_decl GREATER_THAN
// | MAT2x4 LESS_THAN type_decl GREATER_THAN
@@ -730,8 +732,20 @@
if (t.IsPtr()) {
return type_decl_pointer(t);
}
+
+ auto deco = array_decoration_list();
+ if (has_error()) {
+ return nullptr;
+ }
+ if (deco != 0) {
+ t = peek();
+ }
+ if (deco != 0 && !t.IsArray()) {
+ set_error(t, "found array decoration but no array");
+ return nullptr;
+ }
if (t.IsArray()) {
- return type_decl_array(t);
+ return type_decl_array(t, deco);
}
if (t.IsMat2x2() || t.IsMat2x3() || t.IsMat2x4() || t.IsMat3x2() ||
t.IsMat3x3() || t.IsMat3x4() || t.IsMat4x2() || t.IsMat4x3() ||
@@ -815,7 +829,7 @@
std::make_unique<ast::type::VectorType>(subtype, count));
}
-ast::type::Type* ParserImpl::type_decl_array(Token t) {
+ast::type::Type* ParserImpl::type_decl_array(Token t, uint32_t stride) {
next(); // Consume the peek
t = next();
@@ -852,8 +866,50 @@
return nullptr;
}
- return ctx_.type_mgr().Get(
- std::make_unique<ast::type::ArrayType>(subtype, size));
+ auto ty = std::make_unique<ast::type::ArrayType>(subtype, size);
+ if (stride != 0) {
+ ty->set_array_stride(stride);
+ }
+ return ctx_.type_mgr().Get(std::move(ty));
+}
+
+// array_decoration_list
+// : ATTR_LEFT (array_decoration COMMA)* array_decoration ATTR_RIGHT
+// array_decoration
+// : STRIDE INT_LITERAL
+//
+// As there is currently only one decoration I'm combining these for now.
+// we can split apart later if needed.
+uint32_t ParserImpl::array_decoration_list() {
+ auto t = peek();
+ if (!t.IsAttrLeft()) {
+ return 0;
+ }
+ t = peek(1);
+ if (!t.IsStride()) {
+ return 0;
+ }
+
+ next(); // consume the peek of [[
+ next(); // consume the peek of stride
+
+ t = next();
+ if (!t.IsSintLiteral()) {
+ set_error(t, "missing value for stride decoration");
+ return 0;
+ }
+ if (t.to_i32() < 0) {
+ set_error(t, "invalid stride value: " + t.to_str());
+ return 0;
+ }
+
+ uint32_t stride = static_cast<uint32_t>(t.to_i32());
+ t = next();
+ if (!t.IsAttrRight()) {
+ set_error(t, "missing ]] for array decoration");
+ return 0;
+ }
+ return stride;
}
ast::type::Type* ParserImpl::type_decl_matrix(Token t) {
@@ -985,16 +1041,16 @@
if (!t.IsAttrLeft())
return ast::StructDecoration::kNone;
- next(); // Consume the peek
-
- auto deco = struct_decoration();
+ auto deco = struct_decoration(peek(1));
if (has_error())
return ast::StructDecoration::kNone;
if (deco == ast::StructDecoration::kNone) {
- set_error(peek(), "unknown struct decoration");
- return ast::StructDecoration::kNone;
+ return deco;
}
+ next(); // Consume the peek of [[
+ next(); // Consume the peek from the struct_decoration
+
t = next();
if (!t.IsAttrRight()) {
set_error(t, "missing ]] for struct decoration");
@@ -1006,10 +1062,8 @@
// struct_decoration
// : BLOCK
-ast::StructDecoration ParserImpl::struct_decoration() {
- auto t = peek();
+ast::StructDecoration ParserImpl::struct_decoration(Token t) {
if (t.IsBlock()) {
- next(); // Consume the peek
return ast::StructDecoration::kBlock;
}
return ast::StructDecoration::kNone;