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>
This commit is contained in:
Ben Clayton 2021-03-18 16:39:54 +00:00 committed by Commit Bot service account
parent 097c75ae3e
commit a63145a923
2 changed files with 75 additions and 84 deletions

View File

@ -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<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

View File

@ -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::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;
}