From a63145a923f44a389b55dd7fc00665c79843ab85 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Thu, 18 Mar 2021 16:39:54 +0000 Subject: [PATCH] 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 Reviewed-by: David Neto --- src/resolver/is_storeable_test.cc | 143 ++++++++++++++---------------- src/resolver/resolver.cc | 16 ++-- 2 files changed, 75 insertions(+), 84 deletions(-) diff --git a/src/resolver/is_storeable_test.cc b/src/resolver/is_storeable_test.cc index e11d5396bd..7f40f0fe34 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 @@ namespace { 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(); - auto* vec3_i32 = ty.vec3(); - auto* vec4_i32 = ty.vec4(); - auto* vec2_u32 = ty.vec2(); - auto* vec3_u32 = ty.vec3(); - auto* vec4_u32 = ty.vec4(); - auto* vec2_f32 = ty.vec2(); - auto* vec3_f32 = ty.vec3(); - auto* vec4_f32 = ty.vec4(); - - 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())); + EXPECT_TRUE(r()->IsStorable(ty.vec3())); + EXPECT_TRUE(r()->IsStorable(ty.vec4())); + EXPECT_TRUE(r()->IsStorable(ty.vec2())); + EXPECT_TRUE(r()->IsStorable(ty.vec3())); + EXPECT_TRUE(r()->IsStorable(ty.vec4())); + EXPECT_TRUE(r()->IsStorable(ty.vec2())); + EXPECT_TRUE(r()->IsStorable(ty.vec3())); + EXPECT_TRUE(r()->IsStorable(ty.vec4())); } TEST_F(ResolverIsStorableTest, Matrix) { - auto* mat2x2 = ty.mat2x2(); - auto* mat2x3 = ty.mat2x3(); - auto* mat2x4 = ty.mat2x4(); - auto* mat3x2 = ty.mat3x2(); - auto* mat3x3 = ty.mat3x3(); - auto* mat3x4 = ty.mat3x4(); - auto* mat4x2 = ty.mat4x2(); - auto* mat4x3 = ty.mat4x3(); - auto* mat4x4 = ty.mat4x4(); - - 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())); + EXPECT_TRUE(r()->IsStorable(ty.mat2x3())); + EXPECT_TRUE(r()->IsStorable(ty.mat2x4())); + EXPECT_TRUE(r()->IsStorable(ty.mat3x2())); + EXPECT_TRUE(r()->IsStorable(ty.mat3x3())); + EXPECT_TRUE(r()->IsStorable(ty.mat3x4())); + EXPECT_TRUE(r()->IsStorable(ty.mat4x2())); + EXPECT_TRUE(r()->IsStorable(ty.mat4x3())); + EXPECT_TRUE(r()->IsStorable(ty.mat4x4())); } TEST_F(ResolverIsStorableTest, Pointer) { - auto* ptr_ty = ty.pointer(ast::StorageClass::kPrivate); - - EXPECT_FALSE(r()->IsStorable(ptr_ty)); + EXPECT_FALSE(r()->IsStorable(ty.pointer(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(ast::AccessControl::kReadOnly, ty.void_()))); +} + +TEST_F(ResolverIsStorableTest, AccessControlI32) { + EXPECT_TRUE(r()->IsStorable( + create(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(); - - EXPECT_TRUE(r()->IsStorable(arr)); + EXPECT_TRUE(r()->IsStorable(ty.array())); } TEST_F(ResolverIsStorableTest, Struct_AllMembersStorable) { - ast::StructMemberList members{Member("a", ty.i32()), Member("b", ty.f32())}; - auto* s = create(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(ast::StorageClass::kPrivate); - ast::StructMemberList members{Member("a", ty.i32()), Member("b", ptr_ty)}; - auto* s = create(Source{}, members, ast::DecorationList{}); - auto* s_ty = ty.struct_("mystruct", s); + auto* ptr_ty = ty.pointer(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(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 d0e24d90e4..a412be29ce 100644 --- a/src/resolver/resolver.cc +++ b/src/resolver/resolver.cc @@ -109,28 +109,24 @@ bool Resolver::Resolve() { 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->Is()) { return true; } - if (type::Array* array_type = type->As()) { - return IsStorable(array_type->type()); + if (type::Array* arr = type->As()) { + return IsStorable(arr->type()); } - if (type::Struct* struct_type = type->As()) { - for (const auto* member : struct_type->impl()->members()) { + if (type::Struct* str = type->As()) { + for (const auto* member : str->impl()->members()) { if (!IsStorable(member->type())) { return false; } } return true; } - if (type::Alias* alias_type = type->As()) { - return IsStorable(alias_type->type()); - } return false; }