Resolver::IsStorable() Handle AccessControl types
Also: Clean up tests.
Change-Id: Ib22bd742b4e3cab55ee078d634ea7aee9a5b8d58
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/45243
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/resolver/is_storeable_test.cc b/src/resolver/is_storeable_test.cc
index e11d539..7f40f0f 100644
--- a/src/resolver/is_storeable_test.cc
+++ b/src/resolver/is_storeable_test.cc
@@ -16,6 +16,7 @@
#include "gmock/gmock.h"
#include "src/resolver/resolver_test_helper.h"
+#include "src/type/access_control_type.h"
namespace tint {
namespace resolver {
@@ -24,112 +25,106 @@
using ResolverIsStorableTest = ResolverTest;
TEST_F(ResolverIsStorableTest, Void) {
- auto* void_ty = ty.void_();
-
- EXPECT_FALSE(r()->IsStorable(void_ty));
+ EXPECT_FALSE(r()->IsStorable(ty.void_()));
}
TEST_F(ResolverIsStorableTest, Scalar) {
- auto* bool_ = ty.bool_();
- auto* i32 = ty.i32();
- auto* u32 = ty.u32();
- auto* f32 = ty.f32();
-
- EXPECT_TRUE(r()->IsStorable(bool_));
- EXPECT_TRUE(r()->IsStorable(i32));
- EXPECT_TRUE(r()->IsStorable(u32));
- EXPECT_TRUE(r()->IsStorable(f32));
+ EXPECT_TRUE(r()->IsStorable(ty.bool_()));
+ EXPECT_TRUE(r()->IsStorable(ty.i32()));
+ EXPECT_TRUE(r()->IsStorable(ty.u32()));
+ EXPECT_TRUE(r()->IsStorable(ty.f32()));
}
TEST_F(ResolverIsStorableTest, Vector) {
- auto* vec2_i32 = ty.vec2<int>();
- auto* vec3_i32 = ty.vec3<int>();
- auto* vec4_i32 = ty.vec4<int>();
- auto* vec2_u32 = ty.vec2<unsigned>();
- auto* vec3_u32 = ty.vec3<unsigned>();
- auto* vec4_u32 = ty.vec4<unsigned>();
- auto* vec2_f32 = ty.vec2<float>();
- auto* vec3_f32 = ty.vec3<float>();
- auto* vec4_f32 = ty.vec4<float>();
-
- EXPECT_TRUE(r()->IsStorable(vec2_i32));
- EXPECT_TRUE(r()->IsStorable(vec3_i32));
- EXPECT_TRUE(r()->IsStorable(vec4_i32));
- EXPECT_TRUE(r()->IsStorable(vec2_u32));
- EXPECT_TRUE(r()->IsStorable(vec3_u32));
- EXPECT_TRUE(r()->IsStorable(vec4_u32));
- EXPECT_TRUE(r()->IsStorable(vec2_f32));
- EXPECT_TRUE(r()->IsStorable(vec3_f32));
- EXPECT_TRUE(r()->IsStorable(vec4_f32));
+ EXPECT_TRUE(r()->IsStorable(ty.vec2<i32>()));
+ EXPECT_TRUE(r()->IsStorable(ty.vec3<i32>()));
+ EXPECT_TRUE(r()->IsStorable(ty.vec4<i32>()));
+ EXPECT_TRUE(r()->IsStorable(ty.vec2<unsigned>()));
+ EXPECT_TRUE(r()->IsStorable(ty.vec3<unsigned>()));
+ EXPECT_TRUE(r()->IsStorable(ty.vec4<unsigned>()));
+ EXPECT_TRUE(r()->IsStorable(ty.vec2<float>()));
+ EXPECT_TRUE(r()->IsStorable(ty.vec3<float>()));
+ EXPECT_TRUE(r()->IsStorable(ty.vec4<float>()));
}
TEST_F(ResolverIsStorableTest, Matrix) {
- auto* mat2x2 = ty.mat2x2<float>();
- auto* mat2x3 = ty.mat2x3<float>();
- auto* mat2x4 = ty.mat2x4<float>();
- auto* mat3x2 = ty.mat3x2<float>();
- auto* mat3x3 = ty.mat3x3<float>();
- auto* mat3x4 = ty.mat3x4<float>();
- auto* mat4x2 = ty.mat4x2<float>();
- auto* mat4x3 = ty.mat4x3<float>();
- auto* mat4x4 = ty.mat4x4<float>();
-
- EXPECT_TRUE(r()->IsStorable(mat2x2));
- EXPECT_TRUE(r()->IsStorable(mat2x3));
- EXPECT_TRUE(r()->IsStorable(mat2x4));
- EXPECT_TRUE(r()->IsStorable(mat3x2));
- EXPECT_TRUE(r()->IsStorable(mat3x3));
- EXPECT_TRUE(r()->IsStorable(mat3x4));
- EXPECT_TRUE(r()->IsStorable(mat4x2));
- EXPECT_TRUE(r()->IsStorable(mat4x3));
- EXPECT_TRUE(r()->IsStorable(mat4x4));
+ EXPECT_TRUE(r()->IsStorable(ty.mat2x2<float>()));
+ EXPECT_TRUE(r()->IsStorable(ty.mat2x3<float>()));
+ EXPECT_TRUE(r()->IsStorable(ty.mat2x4<float>()));
+ EXPECT_TRUE(r()->IsStorable(ty.mat3x2<float>()));
+ EXPECT_TRUE(r()->IsStorable(ty.mat3x3<float>()));
+ EXPECT_TRUE(r()->IsStorable(ty.mat3x4<float>()));
+ EXPECT_TRUE(r()->IsStorable(ty.mat4x2<float>()));
+ EXPECT_TRUE(r()->IsStorable(ty.mat4x3<float>()));
+ EXPECT_TRUE(r()->IsStorable(ty.mat4x4<float>()));
}
TEST_F(ResolverIsStorableTest, Pointer) {
- auto* ptr_ty = ty.pointer<int>(ast::StorageClass::kPrivate);
-
- EXPECT_FALSE(r()->IsStorable(ptr_ty));
+ EXPECT_FALSE(r()->IsStorable(ty.pointer<i32>(ast::StorageClass::kPrivate)));
}
TEST_F(ResolverIsStorableTest, AliasVoid) {
- auto* alias = ty.alias("myalias", ty.void_());
-
- EXPECT_FALSE(r()->IsStorable(alias));
+ EXPECT_FALSE(r()->IsStorable(ty.alias("a", ty.void_())));
}
TEST_F(ResolverIsStorableTest, AliasI32) {
- auto* alias = ty.alias("myalias", ty.i32());
+ EXPECT_TRUE(r()->IsStorable(ty.alias("a", ty.i32())));
+}
- EXPECT_TRUE(r()->IsStorable(alias));
+TEST_F(ResolverIsStorableTest, AccessControlVoid) {
+ EXPECT_FALSE(r()->IsStorable(
+ create<type::AccessControl>(ast::AccessControl::kReadOnly, ty.void_())));
+}
+
+TEST_F(ResolverIsStorableTest, AccessControlI32) {
+ EXPECT_TRUE(r()->IsStorable(
+ create<type::AccessControl>(ast::AccessControl::kReadOnly, ty.i32())));
}
TEST_F(ResolverIsStorableTest, ArraySizedOfStorable) {
- auto* arr = ty.array(ty.i32(), 5);
-
- EXPECT_TRUE(r()->IsStorable(arr));
+ EXPECT_TRUE(r()->IsStorable(ty.array(ty.i32(), 5)));
}
TEST_F(ResolverIsStorableTest, ArrayUnsizedOfStorable) {
- auto* arr = ty.array<int>();
-
- EXPECT_TRUE(r()->IsStorable(arr));
+ EXPECT_TRUE(r()->IsStorable(ty.array<i32>()));
}
TEST_F(ResolverIsStorableTest, Struct_AllMembersStorable) {
- ast::StructMemberList members{Member("a", ty.i32()), Member("b", ty.f32())};
- auto* s = create<ast::Struct>(Source{}, members, ast::DecorationList{});
- auto* s_ty = ty.struct_("mystruct", s);
-
- EXPECT_TRUE(r()->IsStorable(s_ty));
+ EXPECT_TRUE(r()->IsStorable(Structure("S", {
+ Member("a", ty.i32()),
+ Member("b", ty.f32()),
+ })));
}
TEST_F(ResolverIsStorableTest, Struct_SomeMembersNonStorable) {
- auto* ptr_ty = ty.pointer<int>(ast::StorageClass::kPrivate);
- ast::StructMemberList members{Member("a", ty.i32()), Member("b", ptr_ty)};
- auto* s = create<ast::Struct>(Source{}, members, ast::DecorationList{});
- auto* s_ty = ty.struct_("mystruct", s);
+ auto* ptr_ty = ty.pointer<i32>(ast::StorageClass::kPrivate);
+ EXPECT_FALSE(r()->IsStorable(Structure("S", {
+ Member("a", ty.i32()),
+ Member("b", ptr_ty),
+ })));
+}
- EXPECT_FALSE(r()->IsStorable(s_ty));
+TEST_F(ResolverIsStorableTest, Struct_NestedStorable) {
+ auto* storable = Structure("S", {
+ Member("a", ty.i32()),
+ Member("b", ty.f32()),
+ });
+ EXPECT_TRUE(r()->IsStorable(Structure("S", {
+ Member("a", ty.i32()),
+ Member("b", storable),
+ })));
+}
+
+TEST_F(ResolverIsStorableTest, Struct_NestedNonStorable) {
+ auto* ptr_ty = ty.pointer<i32>(ast::StorageClass::kPrivate);
+ auto* non_storable = Structure("nonstorable", {
+ Member("a", ty.i32()),
+ Member("b", ptr_ty),
+ });
+ EXPECT_FALSE(r()->IsStorable(Structure("S", {
+ Member("a", ty.i32()),
+ Member("b", non_storable),
+ })));
}
} // namespace
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index d0e24d9..a412be2 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -109,28 +109,24 @@
return result;
}
+// https://gpuweb.github.io/gpuweb/wgsl.html#storable-types
bool Resolver::IsStorable(type::Type* type) {
- if (type == nullptr) {
- return false;
- }
+ type = type->UnwrapIfNeeded();
if (type->is_scalar() || type->Is<type::Vector>() ||
type->Is<type::Matrix>()) {
return true;
}
- if (type::Array* array_type = type->As<type::Array>()) {
- return IsStorable(array_type->type());
+ if (type::Array* arr = type->As<type::Array>()) {
+ return IsStorable(arr->type());
}
- if (type::Struct* struct_type = type->As<type::Struct>()) {
- for (const auto* member : struct_type->impl()->members()) {
+ if (type::Struct* str = type->As<type::Struct>()) {
+ for (const auto* member : str->impl()->members()) {
if (!IsStorable(member->type())) {
return false;
}
}
return true;
}
- if (type::Alias* alias_type = type->As<type::Alias>()) {
- return IsStorable(alias_type->type());
- }
return false;
}