validator: add IsStorable helper function

Bug: tint:419
Change-Id: Ib15aa819a032d8412fb3bc162b29a02c331f56b8
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/37960
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: David Neto <dneto@google.com>
Auto-Submit: David Neto <dneto@google.com>
This commit is contained in:
David Neto 2021-01-18 19:45:24 +00:00 committed by Commit Bot service account
parent d7335fa974
commit 20f4d1daca
3 changed files with 115 additions and 0 deletions

View File

@ -29,8 +29,10 @@
#include "src/ast/switch_statement.h"
#include "src/ast/type/array_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h"
#include "src/ast/type/struct_type.h"
#include "src/ast/type/u32_type.h"
#include "src/ast/type/vector_type.h"
#include "src/ast/type/void_type.h"
#include "src/ast/uint_literal.h"
#include "src/ast/variable_decl_statement.h"
@ -506,4 +508,29 @@ bool ValidatorImpl::ValidateIdentifier(const ast::IdentifierExpression* ident) {
return true;
}
bool ValidatorImpl::IsStorable(ast::type::Type* type) {
if (type == nullptr) {
return false;
}
if (type->is_scalar() || type->Is<ast::type::Vector>() ||
type->Is<ast::type::Matrix>()) {
return true;
}
if (ast::type::Array* array_type = type->As<ast::type::Array>()) {
return IsStorable(array_type->type());
}
if (ast::type::Struct* struct_type = type->As<ast::type::Struct>()) {
for (const auto* member : struct_type->impl()->members()) {
if (!IsStorable(member->type())) {
return false;
}
}
return true;
}
if (ast::type::Alias* alias_type = type->As<ast::type::Alias>()) {
return IsStorable(alias_type->type());
}
return false;
}
} // namespace tint

View File

@ -17,6 +17,7 @@
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "src/ast/assignment_statement.h"
@ -147,6 +148,12 @@ class ValidatorImpl {
bool ValidateConstructedTypes(
const std::vector<ast::type::Type*>& constructed_types);
/// Returns true if the given type is storable. This uses and
/// updates `storable_` and `not_storable_`.
/// @param type the given type
/// @returns true if the given type is storable.
bool IsStorable(ast::type::Type* type);
private:
const ast::Module& module_;
diag::List diags_;

View File

@ -579,5 +579,86 @@ TEST_F(ValidatorTest, VariableDeclNoConstructor_Pass) {
EXPECT_TRUE(v()->ValidateStatements(body)) << v()->error();
}
TEST_F(ValidatorTest, IsStorable_Void) {
EXPECT_FALSE(v()->IsStorable(ty.void_));
}
TEST_F(ValidatorTest, IsStorable_Scalar) {
EXPECT_TRUE(v()->IsStorable(ty.bool_));
EXPECT_TRUE(v()->IsStorable(ty.i32));
EXPECT_TRUE(v()->IsStorable(ty.u32));
EXPECT_TRUE(v()->IsStorable(ty.f32));
}
TEST_F(ValidatorTest, IsStorable_Vector) {
EXPECT_TRUE(v()->IsStorable(ty.vec2<int>()));
EXPECT_TRUE(v()->IsStorable(ty.vec3<int>()));
EXPECT_TRUE(v()->IsStorable(ty.vec4<int>()));
EXPECT_TRUE(v()->IsStorable(ty.vec2<unsigned>()));
EXPECT_TRUE(v()->IsStorable(ty.vec3<unsigned>()));
EXPECT_TRUE(v()->IsStorable(ty.vec4<unsigned>()));
EXPECT_TRUE(v()->IsStorable(ty.vec2<float>()));
EXPECT_TRUE(v()->IsStorable(ty.vec3<float>()));
EXPECT_TRUE(v()->IsStorable(ty.vec4<float>()));
}
TEST_F(ValidatorTest, IsStorable_Matrix) {
EXPECT_TRUE(v()->IsStorable(ty.mat2x2<float>()));
EXPECT_TRUE(v()->IsStorable(ty.mat2x3<float>()));
EXPECT_TRUE(v()->IsStorable(ty.mat2x4<float>()));
EXPECT_TRUE(v()->IsStorable(ty.mat3x2<float>()));
EXPECT_TRUE(v()->IsStorable(ty.mat3x3<float>()));
EXPECT_TRUE(v()->IsStorable(ty.mat3x4<float>()));
EXPECT_TRUE(v()->IsStorable(ty.mat4x2<float>()));
EXPECT_TRUE(v()->IsStorable(ty.mat4x3<float>()));
EXPECT_TRUE(v()->IsStorable(ty.mat4x4<float>()));
}
TEST_F(ValidatorTest, IsStorable_Pointer) {
auto* ptr_ty = ty.pointer<int>(ast::StorageClass::kPrivate);
EXPECT_FALSE(v()->IsStorable(ptr_ty));
}
TEST_F(ValidatorTest, IsStorable_AliasVoid) {
auto* alias = ty.alias("myalias", ty.void_);
EXPECT_FALSE(v()->IsStorable(alias));
}
TEST_F(ValidatorTest, IsStorable_AliasI32) {
auto* alias = ty.alias("myalias", ty.i32);
EXPECT_TRUE(v()->IsStorable(alias));
}
TEST_F(ValidatorTest, IsStorable_ArraySizedOfStorable) {
EXPECT_TRUE(v()->IsStorable(ty.array(ty.i32, 5)));
}
TEST_F(ValidatorTest, IsStorable_ArraySizedOfNonStorable) {
EXPECT_FALSE(v()->IsStorable(ty.array(ty.void_, 5)));
}
TEST_F(ValidatorTest, IsStorable_ArrayUnsizedOfStorable) {
EXPECT_TRUE(v()->IsStorable(ty.array<int>()));
}
TEST_F(ValidatorTest, IsStorable_ArrayUnsizedOfNonStorable) {
EXPECT_FALSE(v()->IsStorable(ty.array<void>()));
}
TEST_F(ValidatorTest, IsStorable_Struct_AllMembersStorable) {
ast::StructMemberList members{Member("a", ty.i32), Member("b", ty.f32)};
auto* s = create<ast::Struct>(Source{}, members, ast::StructDecorationList{});
auto* s_ty = ty.struct_("mystruct", s);
EXPECT_TRUE(v()->IsStorable(s_ty));
}
TEST_F(ValidatorTest, IsStorable_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::StructDecorationList{});
auto* s_ty = ty.struct_("mystruct", s);
EXPECT_FALSE(v()->IsStorable(s_ty));
}
} // namespace
} // namespace tint