[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>
diff --git a/BUILD.gn b/BUILD.gn
index 6881312..103c941 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -319,6 +319,8 @@
"src/ast/struct_member_offset_decoration.h",
"src/ast/switch_statement.cc",
"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.h",
"src/ast/type/array_type.cc",
@@ -740,6 +742,7 @@
"src/ast/struct_member_test.cc",
"src/ast/struct_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/array_type_test.cc",
"src/ast/type/bool_type_test.cc",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 13a2937..7a04fc7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -142,6 +142,8 @@
ast/switch_statement.h
ast/type_constructor_expression.h
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.h
ast/type/array_type.cc
@@ -350,6 +352,7 @@
ast/struct_member_offset_decoration_test.cc
ast/struct_test.cc
ast/switch_statement_test.cc
+ ast/type/access_control_type_test.cc
ast/type/alias_type_test.cc
ast/type/array_type_test.cc
ast/type/bool_type_test.cc
diff --git a/src/ast/type/access_control_type.cc b/src/ast/type/access_control_type.cc
new file mode 100644
index 0000000..1abae24
--- /dev/null
+++ b/src/ast/type/access_control_type.cc
@@ -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
diff --git a/src/ast/type/access_control_type.h b/src/ast/type/access_control_type.h
new file mode 100644
index 0000000..5e696fd
--- /dev/null
+++ b/src/ast/type/access_control_type.h
@@ -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_
diff --git a/src/ast/type/access_control_type_test.cc b/src/ast/type/access_control_type_test.cc
new file mode 100644
index 0000000..0f31121
--- /dev/null
+++ b/src/ast/type/access_control_type_test.cc
@@ -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
diff --git a/src/ast/type/alias_type_test.cc b/src/ast/type/alias_type_test.cc
index ac021ae..76b547a 100644
--- a/src/ast/type/alias_type_test.cc
+++ b/src/ast/type/alias_type_test.cc
@@ -38,6 +38,7 @@
I32Type i32;
AliasType at{"a", &i32};
+ EXPECT_FALSE(at.IsAccessControl());
EXPECT_TRUE(at.IsAlias());
EXPECT_FALSE(at.IsArray());
EXPECT_FALSE(at.IsBool());
diff --git a/src/ast/type/array_type_test.cc b/src/ast/type/array_type_test.cc
index b76cb08..71b4343 100644
--- a/src/ast/type/array_type_test.cc
+++ b/src/ast/type/array_type_test.cc
@@ -48,6 +48,7 @@
I32Type i32;
ArrayType arr{&i32, 3};
+ EXPECT_FALSE(arr.IsAccessControl());
EXPECT_FALSE(arr.IsAlias());
EXPECT_TRUE(arr.IsArray());
EXPECT_FALSE(arr.IsBool());
diff --git a/src/ast/type/bool_type_test.cc b/src/ast/type/bool_type_test.cc
index f3cc966..4bcf482 100644
--- a/src/ast/type/bool_type_test.cc
+++ b/src/ast/type/bool_type_test.cc
@@ -25,6 +25,7 @@
TEST_F(BoolTypeTest, Is) {
BoolType b;
+ EXPECT_FALSE(b.IsAccessControl());
EXPECT_FALSE(b.IsAlias());
EXPECT_FALSE(b.IsArray());
EXPECT_TRUE(b.IsBool());
diff --git a/src/ast/type/depth_texture_type_test.cc b/src/ast/type/depth_texture_type_test.cc
index 6e79d41..e8b5d59 100644
--- a/src/ast/type/depth_texture_type_test.cc
+++ b/src/ast/type/depth_texture_type_test.cc
@@ -25,6 +25,7 @@
TEST_F(DepthTextureTypeTest, Is) {
DepthTextureType d(TextureDimension::kCube);
+ EXPECT_FALSE(d.IsAccessControl());
EXPECT_FALSE(d.IsAlias());
EXPECT_FALSE(d.IsArray());
EXPECT_FALSE(d.IsBool());
diff --git a/src/ast/type/f32_type_test.cc b/src/ast/type/f32_type_test.cc
index fc42b00..88bef62 100644
--- a/src/ast/type/f32_type_test.cc
+++ b/src/ast/type/f32_type_test.cc
@@ -25,6 +25,7 @@
TEST_F(F32TypeTest, Is) {
F32Type f;
+ EXPECT_FALSE(f.IsAccessControl());
EXPECT_FALSE(f.IsAlias());
EXPECT_FALSE(f.IsArray());
EXPECT_FALSE(f.IsBool());
diff --git a/src/ast/type/i32_type_test.cc b/src/ast/type/i32_type_test.cc
index f69958d..12e0795 100644
--- a/src/ast/type/i32_type_test.cc
+++ b/src/ast/type/i32_type_test.cc
@@ -25,6 +25,7 @@
TEST_F(I32TypeTest, Is) {
I32Type i;
+ EXPECT_FALSE(i.IsAccessControl());
EXPECT_FALSE(i.IsAlias());
EXPECT_FALSE(i.IsArray());
EXPECT_FALSE(i.IsBool());
diff --git a/src/ast/type/matrix_type_test.cc b/src/ast/type/matrix_type_test.cc
index c659e40..0ab07ac 100644
--- a/src/ast/type/matrix_type_test.cc
+++ b/src/ast/type/matrix_type_test.cc
@@ -35,6 +35,7 @@
TEST_F(MatrixTypeTest, Is) {
I32Type i32;
MatrixType m{&i32, 2, 3};
+ EXPECT_FALSE(m.IsAccessControl());
EXPECT_FALSE(m.IsAlias());
EXPECT_FALSE(m.IsArray());
EXPECT_FALSE(m.IsBool());
diff --git a/src/ast/type/multisampled_texture_type_test.cc b/src/ast/type/multisampled_texture_type_test.cc
index c50cef9..4d3d059 100644
--- a/src/ast/type/multisampled_texture_type_test.cc
+++ b/src/ast/type/multisampled_texture_type_test.cc
@@ -27,6 +27,7 @@
TEST_F(MultisampledTextureTypeTest, Is) {
F32Type f32;
MultisampledTextureType s(TextureDimension::kCube, &f32);
+ EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias());
EXPECT_FALSE(s.IsArray());
EXPECT_FALSE(s.IsBool());
diff --git a/src/ast/type/pointer_type_test.cc b/src/ast/type/pointer_type_test.cc
index 0d825f5..9f10ac9 100644
--- a/src/ast/type/pointer_type_test.cc
+++ b/src/ast/type/pointer_type_test.cc
@@ -34,6 +34,7 @@
TEST_F(PointerTypeTest, Is) {
I32Type i32;
PointerType p{&i32, StorageClass::kFunction};
+ EXPECT_FALSE(p.IsAccessControl());
EXPECT_FALSE(p.IsAlias());
EXPECT_FALSE(p.IsArray());
EXPECT_FALSE(p.IsBool());
diff --git a/src/ast/type/sampled_texture_type_test.cc b/src/ast/type/sampled_texture_type_test.cc
index ce10639..a464459 100644
--- a/src/ast/type/sampled_texture_type_test.cc
+++ b/src/ast/type/sampled_texture_type_test.cc
@@ -27,6 +27,7 @@
TEST_F(SampledTextureTypeTest, Is) {
F32Type f32;
SampledTextureType s(TextureDimension::kCube, &f32);
+ EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias());
EXPECT_FALSE(s.IsArray());
EXPECT_FALSE(s.IsBool());
diff --git a/src/ast/type/sampler_type_test.cc b/src/ast/type/sampler_type_test.cc
index 60921ed..34f835c 100644
--- a/src/ast/type/sampler_type_test.cc
+++ b/src/ast/type/sampler_type_test.cc
@@ -36,6 +36,7 @@
TEST_F(SamplerTypeTest, Is) {
SamplerType s{SamplerKind::kSampler};
+ EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias());
EXPECT_FALSE(s.IsArray());
EXPECT_FALSE(s.IsBool());
diff --git a/src/ast/type/storage_texture_type_test.cc b/src/ast/type/storage_texture_type_test.cc
index bc0f503..bbc999b 100644
--- a/src/ast/type/storage_texture_type_test.cc
+++ b/src/ast/type/storage_texture_type_test.cc
@@ -29,6 +29,7 @@
TEST_F(StorageTextureTypeTest, Is) {
StorageTextureType s(TextureDimension::k2dArray, StorageAccess::kRead,
ImageFormat::kRgba32Float);
+ EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias());
EXPECT_FALSE(s.IsArray());
EXPECT_FALSE(s.IsBool());
diff --git a/src/ast/type/struct_type_test.cc b/src/ast/type/struct_type_test.cc
index 3b11b4a..775c9e9 100644
--- a/src/ast/type/struct_type_test.cc
+++ b/src/ast/type/struct_type_test.cc
@@ -36,6 +36,7 @@
TEST_F(StructTypeTest, Is) {
auto impl = std::make_unique<Struct>();
StructType s{"S", std::move(impl)};
+ EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias());
EXPECT_FALSE(s.IsArray());
EXPECT_FALSE(s.IsBool());
diff --git a/src/ast/type/type.cc b/src/ast/type/type.cc
index ee8fa42..7f596af 100644
--- a/src/ast/type/type.cc
+++ b/src/ast/type/type.cc
@@ -16,6 +16,7 @@
#include <assert.h>
+#include "src/ast/type/access_control_type.h"
#include "src/ast/type/alias_type.h"
#include "src/ast/type/array_type.h"
#include "src/ast/type/bool_type.h"
@@ -57,6 +58,10 @@
return UnwrapAliasesIfNeeded()->UnwrapPtrIfNeeded()->UnwrapAliasesIfNeeded();
}
+bool Type::IsAccessControl() const {
+ return false;
+}
+
bool Type::IsAlias() const {
return false;
}
@@ -157,6 +162,11 @@
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 {
assert(IsAlias());
return static_cast<const AliasType*>(this);
@@ -222,6 +232,11 @@
return static_cast<const VoidType*>(this);
}
+AccessControlType* Type::AsAccessControl() {
+ assert(IsAccessControl());
+ return static_cast<AccessControlType*>(this);
+}
+
AliasType* Type::AsAlias() {
assert(IsAlias());
return static_cast<AliasType*>(this);
diff --git a/src/ast/type/type.h b/src/ast/type/type.h
index aabde8d..ff02f28 100644
--- a/src/ast/type/type.h
+++ b/src/ast/type/type.h
@@ -21,6 +21,7 @@
namespace ast {
namespace type {
+class AccessControlType;
class AliasType;
class ArrayType;
class BoolType;
@@ -42,6 +43,8 @@
Type(Type&&) = default;
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
virtual bool IsAlias() const;
/// @returns true if the type is an array type
@@ -117,6 +120,8 @@
/// @returns true if this type is an 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
const AliasType* AsAlias() const;
/// @returns the type as an array type
@@ -144,6 +149,8 @@
/// @returns the type as a void type
const VoidType* AsVoid() const;
+ /// @returns the type as an access control type
+ AccessControlType* AsAccessControl();
/// @returns the type as an alias type
AliasType* AsAlias();
/// @returns the type as an array type
diff --git a/src/ast/type/u32_type_test.cc b/src/ast/type/u32_type_test.cc
index 7c42772..ef0ff20 100644
--- a/src/ast/type/u32_type_test.cc
+++ b/src/ast/type/u32_type_test.cc
@@ -25,6 +25,7 @@
TEST_F(U32TypeTest, Is) {
U32Type u;
+ EXPECT_FALSE(u.IsAccessControl());
EXPECT_FALSE(u.IsAlias());
EXPECT_FALSE(u.IsArray());
EXPECT_FALSE(u.IsBool());
diff --git a/src/ast/type/vector_type_test.cc b/src/ast/type/vector_type_test.cc
index baa1342..1cc5390 100644
--- a/src/ast/type/vector_type_test.cc
+++ b/src/ast/type/vector_type_test.cc
@@ -34,6 +34,7 @@
TEST_F(VectorTypeTest, Is) {
I32Type i32;
VectorType v{&i32, 4};
+ EXPECT_FALSE(v.IsAccessControl());
EXPECT_FALSE(v.IsAlias());
EXPECT_FALSE(v.IsArray());
EXPECT_FALSE(v.IsBool());