tint/transform: Remove use of StorageClass on parameter
Parameters don't have storage classes or access qualifiers. This was
just (ab)using the fact that a parameter uses the same AST type as a
'var'.
Also simplify the parameter disable validation logic.
Bug: tint:1582
Change-Id: Ic218078a410f991e7956e6cb23621a94a69b75a3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/93603
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/transform/calculate_array_length.cc b/src/tint/transform/calculate_array_length.cc
index 9cf1175..acf55a6 100644
--- a/src/tint/transform/calculate_array_length.cc
+++ b/src/tint/transform/calculate_array_length.cc
@@ -23,6 +23,7 @@
#include "src/tint/sem/block_statement.h"
#include "src/tint/sem/call.h"
#include "src/tint/sem/function.h"
+#include "src/tint/sem/reference.h"
#include "src/tint/sem/statement.h"
#include "src/tint/sem/struct.h"
#include "src/tint/sem/variable.h"
@@ -89,22 +90,20 @@
// get_buffer_size_intrinsic() emits the function decorated with
// BufferSizeIntrinsic that is transformed by the HLSL writer into a call to
// [RW]ByteAddressBuffer.GetDimensions().
- std::unordered_map<const sem::Type*, Symbol> buffer_size_intrinsics;
- auto get_buffer_size_intrinsic = [&](const sem::Type* buffer_type) {
+ std::unordered_map<const sem::Reference*, Symbol> buffer_size_intrinsics;
+ auto get_buffer_size_intrinsic = [&](const sem::Reference* buffer_type) {
return utils::GetOrCreate(buffer_size_intrinsics, buffer_type, [&] {
auto name = ctx.dst->Sym();
auto* type = CreateASTTypeFor(ctx, buffer_type);
auto* disable_validation =
- ctx.dst->Disable(ast::DisabledValidation::kIgnoreConstructibleFunctionParameter);
+ ctx.dst->Disable(ast::DisabledValidation::kFunctionParameter);
ctx.dst->AST().AddFunction(ctx.dst->create<ast::Function>(
name,
ast::ParameterList{
- // Note: The buffer parameter requires the kStorage StorageClass
- // in order for HLSL to emit this as a ByteAddressBuffer.
- ctx.dst->create<ast::Variable>(ctx.dst->Sym("buffer"),
- ast::StorageClass::kStorage,
- ast::Access::kUndefined, type, true, false,
- nullptr, ast::AttributeList{disable_validation}),
+ ctx.dst->Param("buffer",
+ ctx.dst->ty.pointer(type, buffer_type->StorageClass(),
+ buffer_type->Access()),
+ {disable_validation}),
ctx.dst->Param("result", ctx.dst->ty.pointer(ctx.dst->ty.u32(),
ast::StorageClass::kFunction)),
},
@@ -128,10 +127,10 @@
if (builtin->Type() == sem::BuiltinType::kArrayLength) {
// We're dealing with an arrayLength() call
- // A runtime-sized array can only appear as the store type of a
- // variable, or the last element of a structure (which cannot itself
- // be nested). Given that we require SimplifyPointers, we can assume
- // that the arrayLength() call has one of two forms:
+ // A runtime-sized array can only appear as the store type of a variable, or the
+ // last element of a structure (which cannot itself be nested). Given that we
+ // require SimplifyPointers, we can assume that the arrayLength() call has one
+ // of two forms:
// arrayLength(&struct_var.array_member)
// arrayLength(&array_var)
auto* arg = call_expr->args[0];
@@ -152,10 +151,9 @@
break;
}
auto* storage_buffer_var = storage_buffer_sem->Variable();
- auto* storage_buffer_type = storage_buffer_sem->Type()->UnwrapRef();
+ auto* storage_buffer_type = storage_buffer_sem->Type()->As<sem::Reference>();
- // Generate BufferSizeIntrinsic for this storage type if we haven't
- // already
+ // Generate BufferSizeIntrinsic for this storage type if we haven't already
auto buffer_size = get_buffer_size_intrinsic(storage_buffer_type);
// Find the current statement block
@@ -177,7 +175,7 @@
// BufferSizeIntrinsic(X, ARGS...) is
// translated to:
// X.GetDimensions(ARGS..) by the writer
- buffer_size, ctx.Clone(storage_buffer_expr),
+ buffer_size, ctx.dst->AddressOf(ctx.Clone(storage_buffer_expr)),
ctx.dst->AddressOf(
ctx.dst->Expr(buffer_size_result->variable->symbol))));
@@ -188,22 +186,26 @@
auto name = ctx.dst->Sym();
const ast::Expression* total_size =
ctx.dst->Expr(buffer_size_result->variable);
- const sem::Array* array_type = nullptr;
- if (auto* str = storage_buffer_type->As<sem::Struct>()) {
- // The variable is a struct, so subtract the byte offset of
- // the array member.
- auto* array_member_sem = str->Members().back();
- array_type = array_member_sem->Type()->As<sem::Array>();
- total_size =
- ctx.dst->Sub(total_size, u32(array_member_sem->Offset()));
- } else if (auto* arr = storage_buffer_type->As<sem::Array>()) {
- array_type = arr;
- } else {
+
+ const sem::Array* array_type = Switch(
+ storage_buffer_type->StoreType(),
+ [&](const sem::Struct* str) {
+ // The variable is a struct, so subtract the byte offset of
+ // the array member.
+ auto* array_member_sem = str->Members().back();
+ total_size =
+ ctx.dst->Sub(total_size, u32(array_member_sem->Offset()));
+ return array_member_sem->Type()->As<sem::Array>();
+ },
+ [&](const sem::Array* arr) { return arr; });
+
+ if (!array_type) {
TINT_ICE(Transform, ctx.dst->Diagnostics())
<< "expected form of arrayLength argument to be "
"&array_var or &struct_var.array_member";
return name;
}
+
uint32_t array_stride = array_type->Size();
auto* array_length_var = ctx.dst->Decl(
ctx.dst->Let(name, ctx.dst->ty.u32(),