Add optional access to ptr<>
This also completes the work to resolve the access controls for each
storage type.
Fixed: tint:846
Change-Id: Iab24057ec14620a2978ec63c4a91ba12d1bc6e9b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/53381
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index 14f4b7d..712e092 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -307,8 +307,12 @@
}
if (auto* t = ty->As<ast::Pointer>()) {
if (auto* el = Type(t->type())) {
+ auto access = t->access();
+ if (access == ast::kUndefined) {
+ access = DefaultAccessForStorageClass(t->storage_class());
+ }
return builder_->create<sem::Pointer>(const_cast<sem::Type*>(el),
- t->storage_class());
+ t->storage_class(), access);
}
return nullptr;
}
@@ -477,11 +481,17 @@
}
}
+ auto access = var->declared_access();
+ if (access == ast::Access::kUndefined) {
+ access = DefaultAccessForStorageClass(storage_class);
+ }
+
auto* type = storage_type;
if (!var->is_const()) {
// Variable declaration. Unlike `let`, `var` has storage.
// Variables are always of a reference type to the declared storage type.
- type = builder_->create<sem::Reference>(storage_type, storage_class);
+ type =
+ builder_->create<sem::Reference>(storage_type, storage_class, access);
}
if (rhs_type && !ValidateVariableConstructor(var, storage_type, type_name,
@@ -489,15 +499,6 @@
return nullptr;
}
- auto access = var->declared_access();
- if (access == ast::Access::kUndefined &&
- storage_class == ast::StorageClass::kStorage) {
- // https://gpuweb.github.io/gpuweb/wgsl/#access-mode-defaults
- // For the storage storage class, the access mode is optional, and defaults
- // to read.
- access = ast::Access::kRead;
- }
-
auto* info = variable_infos_.Create(var, const_cast<sem::Type*>(type),
type_name, storage_class, access);
variable_to_info_.emplace(var, info);
@@ -505,6 +506,21 @@
return info;
}
+ast::AccessControl Resolver::DefaultAccessForStorageClass(
+ ast::StorageClass storage_class) {
+ // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
+ switch (storage_class) {
+ case ast::StorageClass::kStorage:
+ return ast::Access::kRead;
+ case ast::StorageClass::kUniform:
+ case ast::StorageClass::kUniformConstant:
+ return ast::Access::kRead;
+ default:
+ break;
+ }
+ return ast::Access::kReadWrite;
+}
+
bool Resolver::ValidateVariableConstructor(const ast::Variable* var,
const sem::Type* storage_type,
const std::string& type_name,
@@ -1603,7 +1619,8 @@
// If we're extracting from a reference, we return a reference.
if (auto* ref = res->As<sem::Reference>()) {
- ret = builder_->create<sem::Reference>(ret, ref->StorageClass());
+ ret = builder_->create<sem::Reference>(ret, ref->StorageClass(),
+ ref->Access());
}
SetType(expr, ret);
@@ -1959,7 +1976,8 @@
// If we're extracting from a reference, we return a reference.
if (auto* ref = structure->As<sem::Reference>()) {
- ret = builder_->create<sem::Reference>(ret, ref->StorageClass());
+ ret = builder_->create<sem::Reference>(ret, ref->StorageClass(),
+ ref->Access());
}
builder_->Sem().Add(expr, builder_->create<sem::StructMemberAccess>(
@@ -2028,7 +2046,8 @@
ret = vec->type();
// If we're extracting from a reference, we return a reference.
if (auto* ref = structure->As<sem::Reference>()) {
- ret = builder_->create<sem::Reference>(ret, ref->StorageClass());
+ ret = builder_->create<sem::Reference>(ret, ref->StorageClass(),
+ ref->Access());
}
} else {
// The vector will have a number of components equal to the length of
@@ -2291,8 +2310,8 @@
case ast::UnaryOp::kAddressOf:
if (auto* ref = expr_type->As<sem::Reference>()) {
- type = builder_->create<sem::Pointer>(ref->StoreType(),
- ref->StorageClass());
+ type = builder_->create<sem::Pointer>(
+ ref->StoreType(), ref->StorageClass(), ref->Access());
} else {
diagnostics_.add_error("cannot take the address of expression",
unary->expr()->source());
@@ -2302,8 +2321,8 @@
case ast::UnaryOp::kIndirection:
if (auto* ptr = expr_type->As<sem::Pointer>()) {
- type = builder_->create<sem::Reference>(ptr->StoreType(),
- ptr->StorageClass());
+ type = builder_->create<sem::Reference>(
+ ptr->StoreType(), ptr->StorageClass(), ptr->Access());
} else {
diagnostics_.add_error("cannot dereference expression of type '" +
TypeNameOf(unary->expr()) + "'",