[ast] Add AccessControlType.

This CL adds the AST for an AccessControlType. This type contains an
access control (ReadOnly, WriteOnly, or ReadWrite) along with another
type pointer.

Bug: tint:208 tint:108
Change-Id: I2eed03f8760239f7e71dc2edd4a19a7c1661746e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/31060
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: David Neto <dneto@google.com>
This commit is contained in:
dan sinclair 2020-10-27 18:50:59 +00:00 committed by Commit Bot service account
parent ebe97f3ce1
commit bfd81096a5
22 changed files with 263 additions and 0 deletions

View File

@ -319,6 +319,8 @@ source_set("libtint_core_src") {
"src/ast/struct_member_offset_decoration.h", "src/ast/struct_member_offset_decoration.h",
"src/ast/switch_statement.cc", "src/ast/switch_statement.cc",
"src/ast/switch_statement.h", "src/ast/switch_statement.h",
"src/ast/type/access_control_type.cc",
"src/ast/type/access_control_type.h",
"src/ast/type/alias_type.cc", "src/ast/type/alias_type.cc",
"src/ast/type/alias_type.h", "src/ast/type/alias_type.h",
"src/ast/type/array_type.cc", "src/ast/type/array_type.cc",
@ -740,6 +742,7 @@ source_set("tint_unittests_core_src") {
"src/ast/struct_member_test.cc", "src/ast/struct_member_test.cc",
"src/ast/struct_test.cc", "src/ast/struct_test.cc",
"src/ast/switch_statement_test.cc", "src/ast/switch_statement_test.cc",
"src/ast/type/access_control_type_test.cc",
"src/ast/type/alias_type_test.cc", "src/ast/type/alias_type_test.cc",
"src/ast/type/array_type_test.cc", "src/ast/type/array_type_test.cc",
"src/ast/type/bool_type_test.cc", "src/ast/type/bool_type_test.cc",

View File

@ -142,6 +142,8 @@ set(TINT_LIB_SRCS
ast/switch_statement.h ast/switch_statement.h
ast/type_constructor_expression.h ast/type_constructor_expression.h
ast/type_constructor_expression.cc ast/type_constructor_expression.cc
ast/type/access_control_type.cc
ast/type/access_control_type.h
ast/type/alias_type.cc ast/type/alias_type.cc
ast/type/alias_type.h ast/type/alias_type.h
ast/type/array_type.cc ast/type/array_type.cc
@ -350,6 +352,7 @@ set(TINT_TEST_SRCS
ast/struct_member_offset_decoration_test.cc ast/struct_member_offset_decoration_test.cc
ast/struct_test.cc ast/struct_test.cc
ast/switch_statement_test.cc ast/switch_statement_test.cc
ast/type/access_control_type_test.cc
ast/type/alias_type_test.cc ast/type/alias_type_test.cc
ast/type/array_type_test.cc ast/type/array_type_test.cc
ast/type/bool_type_test.cc ast/type/bool_type_test.cc

View File

@ -0,0 +1,57 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/type/access_control_type.h"
#include <assert.h>
namespace tint {
namespace ast {
namespace type {
AccessControlType::AccessControlType(AccessControl access, Type* subtype)
: access_(access), subtype_(subtype) {
assert(subtype_);
assert(!subtype_->IsAccessControl());
}
AccessControlType::~AccessControlType() = default;
bool AccessControlType::IsAccessControl() const {
return true;
}
std::string AccessControlType::type_name() const {
std::string name = "__access_control_";
switch (access_) {
case AccessControl::kReadOnly:
name += "read_only";
break;
case AccessControl::kWriteOnly:
name += "write_only";
break;
case AccessControl::kReadWrite:
name += "read_write";
break;
}
return name + subtype_->type_name();
}
uint64_t AccessControlType::MinBufferBindingSize() const {
return subtype_->MinBufferBindingSize();
}
} // namespace type
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,74 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_TYPE_ACCESS_CONTROL_TYPE_H_
#define SRC_AST_TYPE_ACCESS_CONTROL_TYPE_H_
#include "src/ast/type/type.h"
namespace tint {
namespace ast {
namespace type {
/// The access control settings
enum class AccessControl {
/// Read only
kReadOnly = 0,
/// Write only
kWriteOnly,
/// Read write
kReadWrite
};
/// An access control type. Holds an access setting and pointer to another type.
class AccessControlType : public Type {
public:
/// Constructor
/// @param access the access control setting
/// @param subtype the access controlled type
AccessControlType(AccessControl access, Type* subtype);
/// Move constructor
AccessControlType(AccessControlType&&) = default;
~AccessControlType() override;
/// @returns true if the type is an access control type
bool IsAccessControl() const override;
/// @returns true if the access control is read only
bool IsReadOnly() const { return access_ == AccessControl::kReadOnly; }
/// @returns true if the access control is write only
bool IsWriteOnly() const { return access_ == AccessControl::kWriteOnly; }
/// @returns true if the access control is read/write
bool IsReadWrite() const { return access_ == AccessControl::kReadWrite; }
/// @returns the subtype type
Type* type() const { return subtype_; }
/// @returns the name for this type
std::string type_name() const override;
/// @returns minimum size required for this type, in bytes.
/// 0 for non-host shareable types.
uint64_t MinBufferBindingSize() const override;
private:
AccessControl access_ = AccessControl::kReadOnly;
Type* subtype_ = nullptr;
};
} // namespace type
} // namespace ast
} // namespace tint
#endif // SRC_AST_TYPE_ACCESS_CONTROL_TYPE_H_

View File

@ -0,0 +1,89 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/type/access_control_type.h"
#include "gtest/gtest.h"
#include "src/ast/storage_class.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/pointer_type.h"
#include "src/ast/type/u32_type.h"
namespace tint {
namespace ast {
namespace type {
namespace {
using AccessControlTypeTest = testing::Test;
TEST_F(AccessControlTypeTest, Create) {
U32Type u32;
AccessControlType a{AccessControl::kReadWrite, &u32};
EXPECT_TRUE(a.IsReadWrite());
EXPECT_EQ(a.type(), &u32);
}
TEST_F(AccessControlTypeTest, Is) {
I32Type i32;
AccessControlType at{AccessControl::kReadOnly, &i32};
EXPECT_TRUE(at.IsAccessControl());
EXPECT_FALSE(at.IsAlias());
EXPECT_FALSE(at.IsArray());
EXPECT_FALSE(at.IsBool());
EXPECT_FALSE(at.IsF32());
EXPECT_FALSE(at.IsI32());
EXPECT_FALSE(at.IsMatrix());
EXPECT_FALSE(at.IsPointer());
EXPECT_FALSE(at.IsSampler());
EXPECT_FALSE(at.IsStruct());
EXPECT_FALSE(at.IsTexture());
EXPECT_FALSE(at.IsU32());
EXPECT_FALSE(at.IsVector());
}
TEST_F(AccessControlTypeTest, AccessRead) {
I32Type i32;
AccessControlType at{AccessControl::kReadOnly, &i32};
EXPECT_TRUE(at.IsReadOnly());
EXPECT_FALSE(at.IsWriteOnly());
EXPECT_FALSE(at.IsReadWrite());
EXPECT_EQ(at.type_name(), "__access_control_read_only__i32");
}
TEST_F(AccessControlTypeTest, AccessWrite) {
I32Type i32;
AccessControlType at{AccessControl::kWriteOnly, &i32};
EXPECT_FALSE(at.IsReadOnly());
EXPECT_TRUE(at.IsWriteOnly());
EXPECT_FALSE(at.IsReadWrite());
EXPECT_EQ(at.type_name(), "__access_control_write_only__i32");
}
TEST_F(AccessControlTypeTest, AccessReadWrite) {
I32Type i32;
AccessControlType at{AccessControl::kReadWrite, &i32};
EXPECT_FALSE(at.IsReadOnly());
EXPECT_FALSE(at.IsWriteOnly());
EXPECT_TRUE(at.IsReadWrite());
EXPECT_EQ(at.type_name(), "__access_control_read_write__i32");
}
} // namespace
} // namespace type
} // namespace ast
} // namespace tint

View File

@ -38,6 +38,7 @@ TEST_F(AliasTypeTest, Is) {
I32Type i32; I32Type i32;
AliasType at{"a", &i32}; AliasType at{"a", &i32};
EXPECT_FALSE(at.IsAccessControl());
EXPECT_TRUE(at.IsAlias()); EXPECT_TRUE(at.IsAlias());
EXPECT_FALSE(at.IsArray()); EXPECT_FALSE(at.IsArray());
EXPECT_FALSE(at.IsBool()); EXPECT_FALSE(at.IsBool());

View File

@ -48,6 +48,7 @@ TEST_F(ArrayTypeTest, Is) {
I32Type i32; I32Type i32;
ArrayType arr{&i32, 3}; ArrayType arr{&i32, 3};
EXPECT_FALSE(arr.IsAccessControl());
EXPECT_FALSE(arr.IsAlias()); EXPECT_FALSE(arr.IsAlias());
EXPECT_TRUE(arr.IsArray()); EXPECT_TRUE(arr.IsArray());
EXPECT_FALSE(arr.IsBool()); EXPECT_FALSE(arr.IsBool());

View File

@ -25,6 +25,7 @@ using BoolTypeTest = testing::Test;
TEST_F(BoolTypeTest, Is) { TEST_F(BoolTypeTest, Is) {
BoolType b; BoolType b;
EXPECT_FALSE(b.IsAccessControl());
EXPECT_FALSE(b.IsAlias()); EXPECT_FALSE(b.IsAlias());
EXPECT_FALSE(b.IsArray()); EXPECT_FALSE(b.IsArray());
EXPECT_TRUE(b.IsBool()); EXPECT_TRUE(b.IsBool());

View File

@ -25,6 +25,7 @@ using DepthTextureTypeTest = testing::Test;
TEST_F(DepthTextureTypeTest, Is) { TEST_F(DepthTextureTypeTest, Is) {
DepthTextureType d(TextureDimension::kCube); DepthTextureType d(TextureDimension::kCube);
EXPECT_FALSE(d.IsAccessControl());
EXPECT_FALSE(d.IsAlias()); EXPECT_FALSE(d.IsAlias());
EXPECT_FALSE(d.IsArray()); EXPECT_FALSE(d.IsArray());
EXPECT_FALSE(d.IsBool()); EXPECT_FALSE(d.IsBool());

View File

@ -25,6 +25,7 @@ using F32TypeTest = testing::Test;
TEST_F(F32TypeTest, Is) { TEST_F(F32TypeTest, Is) {
F32Type f; F32Type f;
EXPECT_FALSE(f.IsAccessControl());
EXPECT_FALSE(f.IsAlias()); EXPECT_FALSE(f.IsAlias());
EXPECT_FALSE(f.IsArray()); EXPECT_FALSE(f.IsArray());
EXPECT_FALSE(f.IsBool()); EXPECT_FALSE(f.IsBool());

View File

@ -25,6 +25,7 @@ using I32TypeTest = testing::Test;
TEST_F(I32TypeTest, Is) { TEST_F(I32TypeTest, Is) {
I32Type i; I32Type i;
EXPECT_FALSE(i.IsAccessControl());
EXPECT_FALSE(i.IsAlias()); EXPECT_FALSE(i.IsAlias());
EXPECT_FALSE(i.IsArray()); EXPECT_FALSE(i.IsArray());
EXPECT_FALSE(i.IsBool()); EXPECT_FALSE(i.IsBool());

View File

@ -35,6 +35,7 @@ TEST_F(MatrixTypeTest, Creation) {
TEST_F(MatrixTypeTest, Is) { TEST_F(MatrixTypeTest, Is) {
I32Type i32; I32Type i32;
MatrixType m{&i32, 2, 3}; MatrixType m{&i32, 2, 3};
EXPECT_FALSE(m.IsAccessControl());
EXPECT_FALSE(m.IsAlias()); EXPECT_FALSE(m.IsAlias());
EXPECT_FALSE(m.IsArray()); EXPECT_FALSE(m.IsArray());
EXPECT_FALSE(m.IsBool()); EXPECT_FALSE(m.IsBool());

View File

@ -27,6 +27,7 @@ using MultisampledTextureTypeTest = testing::Test;
TEST_F(MultisampledTextureTypeTest, Is) { TEST_F(MultisampledTextureTypeTest, Is) {
F32Type f32; F32Type f32;
MultisampledTextureType s(TextureDimension::kCube, &f32); MultisampledTextureType s(TextureDimension::kCube, &f32);
EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias()); EXPECT_FALSE(s.IsAlias());
EXPECT_FALSE(s.IsArray()); EXPECT_FALSE(s.IsArray());
EXPECT_FALSE(s.IsBool()); EXPECT_FALSE(s.IsBool());

View File

@ -34,6 +34,7 @@ TEST_F(PointerTypeTest, Creation) {
TEST_F(PointerTypeTest, Is) { TEST_F(PointerTypeTest, Is) {
I32Type i32; I32Type i32;
PointerType p{&i32, StorageClass::kFunction}; PointerType p{&i32, StorageClass::kFunction};
EXPECT_FALSE(p.IsAccessControl());
EXPECT_FALSE(p.IsAlias()); EXPECT_FALSE(p.IsAlias());
EXPECT_FALSE(p.IsArray()); EXPECT_FALSE(p.IsArray());
EXPECT_FALSE(p.IsBool()); EXPECT_FALSE(p.IsBool());

View File

@ -27,6 +27,7 @@ using SampledTextureTypeTest = testing::Test;
TEST_F(SampledTextureTypeTest, Is) { TEST_F(SampledTextureTypeTest, Is) {
F32Type f32; F32Type f32;
SampledTextureType s(TextureDimension::kCube, &f32); SampledTextureType s(TextureDimension::kCube, &f32);
EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias()); EXPECT_FALSE(s.IsAlias());
EXPECT_FALSE(s.IsArray()); EXPECT_FALSE(s.IsArray());
EXPECT_FALSE(s.IsBool()); EXPECT_FALSE(s.IsBool());

View File

@ -36,6 +36,7 @@ TEST_F(SamplerTypeTest, Creation_ComparisonSampler) {
TEST_F(SamplerTypeTest, Is) { TEST_F(SamplerTypeTest, Is) {
SamplerType s{SamplerKind::kSampler}; SamplerType s{SamplerKind::kSampler};
EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias()); EXPECT_FALSE(s.IsAlias());
EXPECT_FALSE(s.IsArray()); EXPECT_FALSE(s.IsArray());
EXPECT_FALSE(s.IsBool()); EXPECT_FALSE(s.IsBool());

View File

@ -29,6 +29,7 @@ using StorageTextureTypeTest = testing::Test;
TEST_F(StorageTextureTypeTest, Is) { TEST_F(StorageTextureTypeTest, Is) {
StorageTextureType s(TextureDimension::k2dArray, StorageAccess::kRead, StorageTextureType s(TextureDimension::k2dArray, StorageAccess::kRead,
ImageFormat::kRgba32Float); ImageFormat::kRgba32Float);
EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias()); EXPECT_FALSE(s.IsAlias());
EXPECT_FALSE(s.IsArray()); EXPECT_FALSE(s.IsArray());
EXPECT_FALSE(s.IsBool()); EXPECT_FALSE(s.IsBool());

View File

@ -36,6 +36,7 @@ TEST_F(StructTypeTest, Creation) {
TEST_F(StructTypeTest, Is) { TEST_F(StructTypeTest, Is) {
auto impl = std::make_unique<Struct>(); auto impl = std::make_unique<Struct>();
StructType s{"S", std::move(impl)}; StructType s{"S", std::move(impl)};
EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias()); EXPECT_FALSE(s.IsAlias());
EXPECT_FALSE(s.IsArray()); EXPECT_FALSE(s.IsArray());
EXPECT_FALSE(s.IsBool()); EXPECT_FALSE(s.IsBool());

View File

@ -16,6 +16,7 @@
#include <assert.h> #include <assert.h>
#include "src/ast/type/access_control_type.h"
#include "src/ast/type/alias_type.h" #include "src/ast/type/alias_type.h"
#include "src/ast/type/array_type.h" #include "src/ast/type/array_type.h"
#include "src/ast/type/bool_type.h" #include "src/ast/type/bool_type.h"
@ -57,6 +58,10 @@ Type* Type::UnwrapAliasPtrAlias() {
return UnwrapAliasesIfNeeded()->UnwrapPtrIfNeeded()->UnwrapAliasesIfNeeded(); return UnwrapAliasesIfNeeded()->UnwrapPtrIfNeeded()->UnwrapAliasesIfNeeded();
} }
bool Type::IsAccessControl() const {
return false;
}
bool Type::IsAlias() const { bool Type::IsAlias() const {
return false; return false;
} }
@ -157,6 +162,11 @@ bool Type::is_integer_scalar_or_vector() {
return is_unsigned_scalar_or_vector() || is_signed_scalar_or_vector(); return is_unsigned_scalar_or_vector() || is_signed_scalar_or_vector();
} }
const AccessControlType* Type::AsAccessControl() const {
assert(IsAccessControl());
return static_cast<const AccessControlType*>(this);
}
const AliasType* Type::AsAlias() const { const AliasType* Type::AsAlias() const {
assert(IsAlias()); assert(IsAlias());
return static_cast<const AliasType*>(this); return static_cast<const AliasType*>(this);
@ -222,6 +232,11 @@ const VoidType* Type::AsVoid() const {
return static_cast<const VoidType*>(this); return static_cast<const VoidType*>(this);
} }
AccessControlType* Type::AsAccessControl() {
assert(IsAccessControl());
return static_cast<AccessControlType*>(this);
}
AliasType* Type::AsAlias() { AliasType* Type::AsAlias() {
assert(IsAlias()); assert(IsAlias());
return static_cast<AliasType*>(this); return static_cast<AliasType*>(this);

View File

@ -21,6 +21,7 @@ namespace tint {
namespace ast { namespace ast {
namespace type { namespace type {
class AccessControlType;
class AliasType; class AliasType;
class ArrayType; class ArrayType;
class BoolType; class BoolType;
@ -42,6 +43,8 @@ class Type {
Type(Type&&) = default; Type(Type&&) = default;
virtual ~Type(); virtual ~Type();
/// @returns true if the type is an access control type
virtual bool IsAccessControl() const;
/// @returns true if the type is an alias type /// @returns true if the type is an alias type
virtual bool IsAlias() const; virtual bool IsAlias() const;
/// @returns true if the type is an array type /// @returns true if the type is an array type
@ -117,6 +120,8 @@ class Type {
/// @returns true if this type is an integer scalar or vector /// @returns true if this type is an integer scalar or vector
bool is_integer_scalar_or_vector(); bool is_integer_scalar_or_vector();
/// @returns the type as an access control type
const AccessControlType* AsAccessControl() const;
/// @returns the type as an alias type /// @returns the type as an alias type
const AliasType* AsAlias() const; const AliasType* AsAlias() const;
/// @returns the type as an array type /// @returns the type as an array type
@ -144,6 +149,8 @@ class Type {
/// @returns the type as a void type /// @returns the type as a void type
const VoidType* AsVoid() const; const VoidType* AsVoid() const;
/// @returns the type as an access control type
AccessControlType* AsAccessControl();
/// @returns the type as an alias type /// @returns the type as an alias type
AliasType* AsAlias(); AliasType* AsAlias();
/// @returns the type as an array type /// @returns the type as an array type

View File

@ -25,6 +25,7 @@ using U32TypeTest = testing::Test;
TEST_F(U32TypeTest, Is) { TEST_F(U32TypeTest, Is) {
U32Type u; U32Type u;
EXPECT_FALSE(u.IsAccessControl());
EXPECT_FALSE(u.IsAlias()); EXPECT_FALSE(u.IsAlias());
EXPECT_FALSE(u.IsArray()); EXPECT_FALSE(u.IsArray());
EXPECT_FALSE(u.IsBool()); EXPECT_FALSE(u.IsBool());

View File

@ -34,6 +34,7 @@ TEST_F(VectorTypeTest, Creation) {
TEST_F(VectorTypeTest, Is) { TEST_F(VectorTypeTest, Is) {
I32Type i32; I32Type i32;
VectorType v{&i32, 4}; VectorType v{&i32, 4};
EXPECT_FALSE(v.IsAccessControl());
EXPECT_FALSE(v.IsAlias()); EXPECT_FALSE(v.IsAlias());
EXPECT_FALSE(v.IsArray()); EXPECT_FALSE(v.IsArray());
EXPECT_FALSE(v.IsBool()); EXPECT_FALSE(v.IsBool());