writer/msl: Fix array type emission
Add a special-case for pointer-to-array types, where the * and the
variable name need to be enclosed in parentheses in between the array
element type and the size.
Move the `const` qualifier to before the array size.
Add E2E tests to cover all non-handle types used in various places.
Fixed: tint:822
Change-Id: I93b7d6867f92397aa47838ab2c94530b6e634617
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/51823
Auto-Submit: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 910850f..193e4e7 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -1314,8 +1314,8 @@
if (!EmitType(type, program_->Symbols().NameFor(v->symbol()))) {
return false;
}
- // Array name is output as part of the type
- if (!type->Is<sem::Array>()) {
+ // Parameter name is output as part of the type for arrays and pointers.
+ if (!type->Is<sem::Array>() && !type->Is<sem::Pointer>()) {
out_ << " " << program_->Symbols().NameFor(v->symbol());
}
}
@@ -1926,10 +1926,17 @@
default:
TINT_ICE(diagnostics_) << "unhandled storage class for pointer";
}
- if (!EmitType(ptr->StoreType(), "")) {
- return false;
+ if (ptr->StoreType()->Is<sem::Array>()) {
+ std::string inner = "(*" + name + ")";
+ if (!EmitType(ptr->StoreType(), inner)) {
+ return false;
+ }
+ } else {
+ if (!EmitType(ptr->StoreType(), "")) {
+ return false;
+ }
+ out_ << "* " << name;
}
- out_ << "*";
} else if (type->Is<sem::Sampler>()) {
out_ << "sampler";
} else if (auto* str = type->As<sem::Struct>()) {
@@ -2201,14 +2208,17 @@
return false;
}
auto* type = var->Type()->UnwrapRef();
- if (!EmitType(type, program_->Symbols().NameFor(decl->symbol()))) {
+
+ std::string name = program_->Symbols().NameFor(decl->symbol());
+ if (decl->is_const()) {
+ name = "const " + name;
+ }
+ if (!EmitType(type, name)) {
return false;
}
- if (decl->is_const()) {
- out_ << " const";
- }
- if (!type->Is<sem::Array>()) {
- out_ << " " << program_->Symbols().NameFor(decl->symbol());
+ // Variable name is output as part of the type for arrays and pointers.
+ if (!type->Is<sem::Array>() && !type->Is<sem::Pointer>()) {
+ out_ << " " << name;
}
if (!skip_constructor) {
diff --git a/test/bug/tint/824.wgsl.expected.msl b/test/bug/tint/824.wgsl.expected.msl
index 9f1e787..fa3aabb 100644
--- a/test/bug/tint/824.wgsl.expected.msl
+++ b/test/bug/tint/824.wgsl.expected.msl
@@ -17,11 +17,11 @@
vertex tint_symbol_3 tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
uint const VertexIndex = tint_symbol_1.VertexIndex;
uint const InstanceIndex = tint_symbol_1.InstanceIndex;
- float2 zv[4] const = {float2(0.200000003f, 0.200000003f), float2(0.300000012f, 0.300000012f), float2(-0.100000001f, -0.100000001f), float2(1.100000024f, 1.100000024f)};
+ float2 const zv[4] = {float2(0.200000003f, 0.200000003f), float2(0.300000012f, 0.300000012f), float2(-0.100000001f, -0.100000001f), float2(1.100000024f, 1.100000024f)};
float const z = zv[InstanceIndex].x;
Output output = {};
output.Position = float4(0.5f, 0.5f, z, 1.0f);
- float4 colors[4] const = {float4(1.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(0.0f, 0.0f, 1.0f, 1.0f), float4(1.0f, 1.0f, 1.0f, 1.0f)};
+ float4 const colors[4] = {float4(1.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(0.0f, 0.0f, 1.0f, 1.0f), float4(1.0f, 1.0f, 1.0f, 1.0f)};
output.color = colors[InstanceIndex];
return {output.color, output.Position};
}
diff --git a/test/types/function_scope_declarations.wgsl b/test/types/function_scope_declarations.wgsl
new file mode 100644
index 0000000..f5a04a0
--- /dev/null
+++ b/test/types/function_scope_declarations.wgsl
@@ -0,0 +1,29 @@
+struct S {
+};
+
+[[stage(compute)]]
+fn main() {
+ var bool_var : bool = bool();
+ let bool_let : bool = bool();
+ var i32_var : i32 = i32();
+ let i32_let : i32 = i32();
+ var u32_var : u32 = u32();
+ let u32_let : u32 = u32();
+ var f32_var : f32 = f32();
+ let f32_let : f32 = f32();
+ var v2i32_var : vec2<i32> = vec2<i32>();
+ let v2i32_let : vec2<i32> = vec2<i32>();
+ var v3u32_var : vec3<u32> = vec3<u32>();
+ let v3u32_let : vec3<u32> = vec3<u32>();
+ var v4f32_var : vec4<f32> = vec4<f32>();
+ let v4f32_let : vec4<f32> = vec4<f32>();
+ var m2x3_var : mat2x3<f32> = mat2x3<f32>();
+ let m3x4_let : mat3x4<f32> = mat3x4<f32>();
+ var arr_var : array<f32, 4> = array<f32, 4>();
+ let arr_let : array<f32, 4> = array<f32, 4>();
+ var struct_var : S = S();
+ let struct_let : S = S();
+ let ptr_f32 : ptr<function, f32> = &f32_var;
+ let ptr_vec : ptr<function, vec4<f32>> = &v4f32_var;
+ let ptr_arr : ptr<function, array<f32, 4>> = &arr_var;
+}
diff --git a/test/types/function_scope_declarations.wgsl.expected.hlsl b/test/types/function_scope_declarations.wgsl.expected.hlsl
new file mode 100644
index 0000000..b3db42f
--- /dev/null
+++ b/test/types/function_scope_declarations.wgsl.expected.hlsl
@@ -0,0 +1 @@
+SKIP: Failed to generate: error: pointers not supported in HLSL
diff --git a/test/types/function_scope_declarations.wgsl.expected.msl b/test/types/function_scope_declarations.wgsl.expected.msl
new file mode 100644
index 0000000..8c0e766
--- /dev/null
+++ b/test/types/function_scope_declarations.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct S {
+};
+
+kernel void tint_symbol() {
+ bool bool_var = bool();
+ bool const bool_let = bool();
+ int i32_var = int();
+ int const i32_let = int();
+ uint u32_var = uint();
+ uint const u32_let = uint();
+ float f32_var = float();
+ float const f32_let = float();
+ int2 v2i32_var = int2();
+ int2 const v2i32_let = int2();
+ uint3 v3u32_var = uint3();
+ uint3 const v3u32_let = uint3();
+ float4 v4f32_var = float4();
+ float4 const v4f32_let = float4();
+ float2x3 m2x3_var = float2x3();
+ float3x4 const m3x4_let = float3x4();
+ float arr_var[4] = {};
+ float const arr_let[4] = {};
+ S struct_var = {};
+ S const struct_let = {};
+ thread float* const ptr_f32 = &(f32_var);
+ thread float4* const ptr_vec = &(v4f32_var);
+ thread float (*const ptr_arr)[4] = &(arr_var);
+ return;
+}
+
diff --git a/test/types/function_scope_declarations.wgsl.expected.spvasm b/test/types/function_scope_declarations.wgsl.expected.spvasm
new file mode 100644
index 0000000..d5fa434
--- /dev/null
+++ b/test/types/function_scope_declarations.wgsl.expected.spvasm
@@ -0,0 +1,82 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 52
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %bool_var "bool_var"
+ OpName %i32_var "i32_var"
+ OpName %u32_var "u32_var"
+ OpName %f32_var "f32_var"
+ OpName %v2i32_var "v2i32_var"
+ OpName %v3u32_var "v3u32_var"
+ OpName %v4f32_var "v4f32_var"
+ OpName %m2x3_var "m2x3_var"
+ OpName %arr_var "arr_var"
+ OpName %S "S"
+ OpName %struct_var "struct_var"
+ OpDecorate %_arr_float_uint_4 ArrayStride 4
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %bool = OpTypeBool
+ %6 = OpConstantNull %bool
+%_ptr_Function_bool = OpTypePointer Function %bool
+ %int = OpTypeInt 32 1
+ %10 = OpConstantNull %int
+%_ptr_Function_int = OpTypePointer Function %int
+ %uint = OpTypeInt 32 0
+ %14 = OpConstantNull %uint
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %float = OpTypeFloat 32
+ %18 = OpConstantNull %float
+%_ptr_Function_float = OpTypePointer Function %float
+ %v2int = OpTypeVector %int 2
+ %22 = OpConstantNull %v2int
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+ %v3uint = OpTypeVector %uint 3
+ %26 = OpConstantNull %v3uint
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+ %v4float = OpTypeVector %float 4
+ %30 = OpConstantNull %v4float
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %v3float = OpTypeVector %float 3
+%mat2v3float = OpTypeMatrix %v3float 2
+ %35 = OpConstantNull %mat2v3float
+%_ptr_Function_mat2v3float = OpTypePointer Function %mat2v3float
+%mat3v4float = OpTypeMatrix %v4float 3
+ %39 = OpConstantNull %mat3v4float
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+ %42 = OpConstantNull %_arr_float_uint_4
+%_ptr_Function__arr_float_uint_4 = OpTypePointer Function %_arr_float_uint_4
+ %S = OpTypeStruct
+ %46 = OpConstantNull %S
+%_ptr_Function_S = OpTypePointer Function %S
+ %main = OpFunction %void None %1
+ %4 = OpLabel
+ %bool_var = OpVariable %_ptr_Function_bool Function %6
+ %i32_var = OpVariable %_ptr_Function_int Function %10
+ %u32_var = OpVariable %_ptr_Function_uint Function %14
+ %f32_var = OpVariable %_ptr_Function_float Function %18
+ %v2i32_var = OpVariable %_ptr_Function_v2int Function %22
+ %v3u32_var = OpVariable %_ptr_Function_v3uint Function %26
+ %v4f32_var = OpVariable %_ptr_Function_v4float Function %30
+ %m2x3_var = OpVariable %_ptr_Function_mat2v3float Function %35
+ %arr_var = OpVariable %_ptr_Function__arr_float_uint_4 Function %42
+ %struct_var = OpVariable %_ptr_Function_S Function %46
+ OpStore %bool_var %6
+ OpStore %i32_var %10
+ OpStore %u32_var %14
+ OpStore %f32_var %18
+ OpStore %v2i32_var %22
+ OpStore %v3u32_var %26
+ OpStore %v4f32_var %30
+ OpStore %m2x3_var %35
+ OpStore %arr_var %42
+ OpStore %struct_var %46
+ OpReturn
+ OpFunctionEnd
diff --git a/test/types/function_scope_declarations.wgsl.expected.wgsl b/test/types/function_scope_declarations.wgsl.expected.wgsl
new file mode 100644
index 0000000..e806b19
--- /dev/null
+++ b/test/types/function_scope_declarations.wgsl.expected.wgsl
@@ -0,0 +1,29 @@
+struct S {
+};
+
+[[stage(compute)]]
+fn main() {
+ var bool_var : bool = bool();
+ let bool_let : bool = bool();
+ var i32_var : i32 = i32();
+ let i32_let : i32 = i32();
+ var u32_var : u32 = u32();
+ let u32_let : u32 = u32();
+ var f32_var : f32 = f32();
+ let f32_let : f32 = f32();
+ var v2i32_var : vec2<i32> = vec2<i32>();
+ let v2i32_let : vec2<i32> = vec2<i32>();
+ var v3u32_var : vec3<u32> = vec3<u32>();
+ let v3u32_let : vec3<u32> = vec3<u32>();
+ var v4f32_var : vec4<f32> = vec4<f32>();
+ let v4f32_let : vec4<f32> = vec4<f32>();
+ var m2x3_var : mat2x3<f32> = mat2x3<f32>();
+ let m3x4_let : mat3x4<f32> = mat3x4<f32>();
+ var arr_var : array<f32, 4> = array<f32, 4>();
+ let arr_let : array<f32, 4> = array<f32, 4>();
+ var struct_var : S = S();
+ let struct_let : S = S();
+ let ptr_f32 : ptr<function, f32> = &(f32_var);
+ let ptr_vec : ptr<function, vec4<f32>> = &(v4f32_var);
+ let ptr_arr : ptr<function, array<f32, 4>> = &(arr_var);
+}
diff --git a/test/types/module_scope_declarations.wgsl b/test/types/module_scope_declarations.wgsl
new file mode 100644
index 0000000..6be0c4a
--- /dev/null
+++ b/test/types/module_scope_declarations.wgsl
@@ -0,0 +1,27 @@
+struct S {
+};
+
+var<private> bool_var : bool = bool();
+let bool_let : bool = bool();
+var<private> i32_var : i32 = i32();
+let i32_let : i32 = i32();
+var<private> u32_var : u32 = u32();
+let u32_let : u32 = u32();
+var<private> f32_var : f32 = f32();
+let f32_let : f32 = f32();
+var<private> v2i32_var : vec2<i32> = vec2<i32>();
+let v2i32_let : vec2<i32> = vec2<i32>();
+var<private> v3u32_var : vec3<u32> = vec3<u32>();
+let v3u32_let : vec3<u32> = vec3<u32>();
+var<private> v4f32_var : vec4<f32> = vec4<f32>();
+let v4f32_let : vec4<f32> = vec4<f32>();
+var<private> m2x3_var : mat2x3<f32> = mat2x3<f32>();
+let m3x4_let : mat3x4<f32> = mat3x4<f32>();
+var<private> arr_var : array<f32, 4> = array<f32, 4>();
+let arr_let : array<f32, 4> = array<f32, 4>();
+var<private> struct_var : S = S();
+let struct_let : S = S();
+
+[[stage(compute)]]
+fn main() {
+}
diff --git a/test/types/module_scope_declarations.wgsl.expected.hlsl b/test/types/module_scope_declarations.wgsl.expected.hlsl
new file mode 100644
index 0000000..a0d6816
--- /dev/null
+++ b/test/types/module_scope_declarations.wgsl.expected.hlsl
@@ -0,0 +1,18 @@
+struct S {
+};
+
+static const bool bool_let = false;
+static const int i32_let = 0;
+static const uint u32_let = 0u;
+static const float f32_let = 0.0f;
+static const int2 v2i32_let = int2(0, 0);
+static const uint3 v3u32_let = uint3(0u, 0u, 0u);
+static const float4 v4f32_let = float4(0.0f, 0.0f, 0.0f, 0.0f);
+static const float3x4 m3x4_let = float3x4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
+static const float arr_let[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+static const S struct_let = {};
+[numthreads(1, 1, 1)]
+void main() {
+ return;
+}
+
diff --git a/test/types/module_scope_declarations.wgsl.expected.msl b/test/types/module_scope_declarations.wgsl.expected.msl
new file mode 100644
index 0000000..1b2d3db
--- /dev/null
+++ b/test/types/module_scope_declarations.wgsl.expected.msl
@@ -0,0 +1 @@
+SKIP: TINT_UNIMPLEMENTED crbug.com/tint/726: module-scope private and workgroup variables not yet implemented
diff --git a/test/types/module_scope_declarations.wgsl.expected.spvasm b/test/types/module_scope_declarations.wgsl.expected.spvasm
new file mode 100644
index 0000000..9d09d23
--- /dev/null
+++ b/test/types/module_scope_declarations.wgsl.expected.spvasm
@@ -0,0 +1,82 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 49
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %bool_var "bool_var"
+ OpName %bool_let "bool_let"
+ OpName %i32_var "i32_var"
+ OpName %i32_let "i32_let"
+ OpName %u32_var "u32_var"
+ OpName %u32_let "u32_let"
+ OpName %f32_var "f32_var"
+ OpName %f32_let "f32_let"
+ OpName %v2i32_var "v2i32_var"
+ OpName %v2i32_let "v2i32_let"
+ OpName %v3u32_var "v3u32_var"
+ OpName %v3u32_let "v3u32_let"
+ OpName %v4f32_var "v4f32_var"
+ OpName %v4f32_let "v4f32_let"
+ OpName %m2x3_var "m2x3_var"
+ OpName %m3x4_let "m3x4_let"
+ OpName %arr_var "arr_var"
+ OpName %arr_let "arr_let"
+ OpName %S "S"
+ OpName %struct_var "struct_var"
+ OpName %struct_let "struct_let"
+ OpName %main "main"
+ OpDecorate %_arr_float_uint_4 ArrayStride 4
+ %bool = OpTypeBool
+ %bool_let = OpConstantNull %bool
+%_ptr_Private_bool = OpTypePointer Private %bool
+ %bool_var = OpVariable %_ptr_Private_bool Private %bool_let
+ %int = OpTypeInt 32 1
+ %i32_let = OpConstantNull %int
+%_ptr_Private_int = OpTypePointer Private %int
+ %i32_var = OpVariable %_ptr_Private_int Private %i32_let
+ %uint = OpTypeInt 32 0
+ %u32_let = OpConstantNull %uint
+%_ptr_Private_uint = OpTypePointer Private %uint
+ %u32_var = OpVariable %_ptr_Private_uint Private %u32_let
+ %float = OpTypeFloat 32
+ %f32_let = OpConstantNull %float
+%_ptr_Private_float = OpTypePointer Private %float
+ %f32_var = OpVariable %_ptr_Private_float Private %f32_let
+ %v2int = OpTypeVector %int 2
+ %v2i32_let = OpConstantNull %v2int
+%_ptr_Private_v2int = OpTypePointer Private %v2int
+ %v2i32_var = OpVariable %_ptr_Private_v2int Private %v2i32_let
+ %v3uint = OpTypeVector %uint 3
+ %v3u32_let = OpConstantNull %v3uint
+%_ptr_Private_v3uint = OpTypePointer Private %v3uint
+ %v3u32_var = OpVariable %_ptr_Private_v3uint Private %v3u32_let
+ %v4float = OpTypeVector %float 4
+ %v4f32_let = OpConstantNull %v4float
+%_ptr_Private_v4float = OpTypePointer Private %v4float
+ %v4f32_var = OpVariable %_ptr_Private_v4float Private %v4f32_let
+ %v3float = OpTypeVector %float 3
+%mat2v3float = OpTypeMatrix %v3float 2
+ %31 = OpConstantNull %mat2v3float
+%_ptr_Private_mat2v3float = OpTypePointer Private %mat2v3float
+ %m2x3_var = OpVariable %_ptr_Private_mat2v3float Private %31
+%mat3v4float = OpTypeMatrix %v4float 3
+ %m3x4_let = OpConstantNull %mat3v4float
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+ %arr_let = OpConstantNull %_arr_float_uint_4
+%_ptr_Private__arr_float_uint_4 = OpTypePointer Private %_arr_float_uint_4
+ %arr_var = OpVariable %_ptr_Private__arr_float_uint_4 Private %arr_let
+ %S = OpTypeStruct
+ %struct_let = OpConstantNull %S
+%_ptr_Private_S = OpTypePointer Private %S
+ %struct_var = OpVariable %_ptr_Private_S Private %struct_let
+ %void = OpTypeVoid
+ %45 = OpTypeFunction %void
+ %main = OpFunction %void None %45
+ %48 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/types/module_scope_declarations.wgsl.expected.wgsl b/test/types/module_scope_declarations.wgsl.expected.wgsl
new file mode 100644
index 0000000..e6edc6e
--- /dev/null
+++ b/test/types/module_scope_declarations.wgsl.expected.wgsl
@@ -0,0 +1,46 @@
+struct S {
+};
+
+var<private> bool_var : bool = bool();
+
+let bool_let : bool = bool();
+
+var<private> i32_var : i32 = i32();
+
+let i32_let : i32 = i32();
+
+var<private> u32_var : u32 = u32();
+
+let u32_let : u32 = u32();
+
+var<private> f32_var : f32 = f32();
+
+let f32_let : f32 = f32();
+
+var<private> v2i32_var : vec2<i32> = vec2<i32>();
+
+let v2i32_let : vec2<i32> = vec2<i32>();
+
+var<private> v3u32_var : vec3<u32> = vec3<u32>();
+
+let v3u32_let : vec3<u32> = vec3<u32>();
+
+var<private> v4f32_var : vec4<f32> = vec4<f32>();
+
+let v4f32_let : vec4<f32> = vec4<f32>();
+
+var<private> m2x3_var : mat2x3<f32> = mat2x3<f32>();
+
+let m3x4_let : mat3x4<f32> = mat3x4<f32>();
+
+var<private> arr_var : array<f32, 4> = array<f32, 4>();
+
+let arr_let : array<f32, 4> = array<f32, 4>();
+
+var<private> struct_var : S = S();
+
+let struct_let : S = S();
+
+[[stage(compute)]]
+fn main() {
+}
diff --git a/test/types/parameters.wgsl b/test/types/parameters.wgsl
new file mode 100644
index 0000000..04082ff
--- /dev/null
+++ b/test/types/parameters.wgsl
@@ -0,0 +1,22 @@
+struct S {
+};
+
+fn foo(
+ param_bool : bool,
+ param_i32 : i32,
+ param_u32 : u32,
+ param_f32 : f32,
+ param_v2i32 : vec2<i32>,
+ param_v3u32 : vec3<u32>,
+ param_v4f32 : vec4<f32>,
+ param_m2x3 : mat2x3<f32>,
+ param_arr : array<f32, 4>,
+ param_struct : S,
+ param_ptr_f32 : ptr<function, f32>,
+ param_ptr_vec : ptr<function, vec4<f32>>,
+ param_ptr_arr : ptr<function, array<f32, 4>>,
+) {}
+
+[[stage(compute)]]
+fn main() {
+}
diff --git a/test/types/parameters.wgsl.expected.hlsl b/test/types/parameters.wgsl.expected.hlsl
new file mode 100644
index 0000000..b3db42f
--- /dev/null
+++ b/test/types/parameters.wgsl.expected.hlsl
@@ -0,0 +1 @@
+SKIP: Failed to generate: error: pointers not supported in HLSL
diff --git a/test/types/parameters.wgsl.expected.msl b/test/types/parameters.wgsl.expected.msl
new file mode 100644
index 0000000..9134d86
--- /dev/null
+++ b/test/types/parameters.wgsl.expected.msl
@@ -0,0 +1,13 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct S {
+};
+
+void foo(bool param_bool, int param_i32, uint param_u32, float param_f32, int2 param_v2i32, uint3 param_v3u32, float4 param_v4f32, float2x3 param_m2x3, float param_arr[4], S param_struct, thread float* param_ptr_f32, thread float4* param_ptr_vec, thread float (*param_ptr_arr)[4]) {
+}
+
+kernel void tint_symbol() {
+ return;
+}
+
diff --git a/test/types/parameters.wgsl.expected.spvasm b/test/types/parameters.wgsl.expected.spvasm
new file mode 100644
index 0000000..5edf8f0
--- /dev/null
+++ b/test/types/parameters.wgsl.expected.spvasm
@@ -0,0 +1,65 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 36
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %S "S"
+ OpName %foo "foo"
+ OpName %param_bool "param_bool"
+ OpName %param_i32 "param_i32"
+ OpName %param_u32 "param_u32"
+ OpName %param_f32 "param_f32"
+ OpName %param_v2i32 "param_v2i32"
+ OpName %param_v3u32 "param_v3u32"
+ OpName %param_v4f32 "param_v4f32"
+ OpName %param_m2x3 "param_m2x3"
+ OpName %param_arr "param_arr"
+ OpName %param_struct "param_struct"
+ OpName %param_ptr_f32 "param_ptr_f32"
+ OpName %param_ptr_vec "param_ptr_vec"
+ OpName %param_ptr_arr "param_ptr_arr"
+ OpName %main "main"
+ OpDecorate %_arr_float_uint_4 ArrayStride 4
+ %void = OpTypeVoid
+ %bool = OpTypeBool
+ %int = OpTypeInt 32 1
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2int = OpTypeVector %int 2
+ %v3uint = OpTypeVector %uint 3
+ %v4float = OpTypeVector %float 4
+ %v3float = OpTypeVector %float 3
+%mat2v3float = OpTypeMatrix %v3float 2
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+ %S = OpTypeStruct
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%_ptr_Function__arr_float_uint_4 = OpTypePointer Function %_arr_float_uint_4
+ %1 = OpTypeFunction %void %bool %int %uint %float %v2int %v3uint %v4float %mat2v3float %_arr_float_uint_4 %S %_ptr_Function_float %_ptr_Function_v4float %_ptr_Function__arr_float_uint_4
+ %33 = OpTypeFunction %void
+ %foo = OpFunction %void None %1
+ %param_bool = OpFunctionParameter %bool
+ %param_i32 = OpFunctionParameter %int
+ %param_u32 = OpFunctionParameter %uint
+ %param_f32 = OpFunctionParameter %float
+%param_v2i32 = OpFunctionParameter %v2int
+%param_v3u32 = OpFunctionParameter %v3uint
+%param_v4f32 = OpFunctionParameter %v4float
+ %param_m2x3 = OpFunctionParameter %mat2v3float
+ %param_arr = OpFunctionParameter %_arr_float_uint_4
+%param_struct = OpFunctionParameter %S
+%param_ptr_f32 = OpFunctionParameter %_ptr_Function_float
+%param_ptr_vec = OpFunctionParameter %_ptr_Function_v4float
+%param_ptr_arr = OpFunctionParameter %_ptr_Function__arr_float_uint_4
+ %32 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %main = OpFunction %void None %33
+ %35 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/types/parameters.wgsl.expected.wgsl b/test/types/parameters.wgsl.expected.wgsl
new file mode 100644
index 0000000..d06b2dd
--- /dev/null
+++ b/test/types/parameters.wgsl.expected.wgsl
@@ -0,0 +1,9 @@
+struct S {
+};
+
+fn foo(param_bool : bool, param_i32 : i32, param_u32 : u32, param_f32 : f32, param_v2i32 : vec2<i32>, param_v3u32 : vec3<u32>, param_v4f32 : vec4<f32>, param_m2x3 : mat2x3<f32>, param_arr : array<f32, 4>, param_struct : S, param_ptr_f32 : ptr<function, f32>, param_ptr_vec : ptr<function, vec4<f32>>, param_ptr_arr : ptr<function, array<f32, 4>>) {
+}
+
+[[stage(compute)]]
+fn main() {
+}
diff --git a/test/types/return_types.wgsl b/test/types/return_types.wgsl
new file mode 100644
index 0000000..2dc79af
--- /dev/null
+++ b/test/types/return_types.wgsl
@@ -0,0 +1,17 @@
+struct S {
+};
+
+fn ret_bool() -> bool { return bool(); }
+fn ret_i32() -> i32 { return i32(); }
+fn ret_u32() -> u32 { return u32(); }
+fn ret_f32() -> f32 { return f32(); }
+fn ret_v2i32() -> vec2<i32> { return vec2<i32>(); }
+fn ret_v3u32() -> vec3<u32> { return vec3<u32>(); }
+fn ret_v4f32() -> vec4<f32> { return vec4<f32>(); }
+fn ret_m2x3() -> mat2x3<f32> { return mat2x3<f32>(); }
+fn ret_arr() -> array<f32, 4> { return array<f32, 4>(); }
+fn ret_struct() -> S { return S(); }
+
+[[stage(compute)]]
+fn main() {
+}
diff --git a/test/types/return_types.wgsl.expected.hlsl b/test/types/return_types.wgsl.expected.hlsl
new file mode 100644
index 0000000..9c9d96e
--- /dev/null
+++ b/test/types/return_types.wgsl.expected.hlsl
@@ -0,0 +1 @@
+SKIP: crbug.com/tint/820: arrays as function return types
diff --git a/test/types/return_types.wgsl.expected.msl b/test/types/return_types.wgsl.expected.msl
new file mode 100644
index 0000000..9c9d96e
--- /dev/null
+++ b/test/types/return_types.wgsl.expected.msl
@@ -0,0 +1 @@
+SKIP: crbug.com/tint/820: arrays as function return types
diff --git a/test/types/return_types.wgsl.expected.spvasm b/test/types/return_types.wgsl.expected.spvasm
new file mode 100644
index 0000000..a13e80b
--- /dev/null
+++ b/test/types/return_types.wgsl.expected.spvasm
@@ -0,0 +1,100 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 57
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %ret_bool "ret_bool"
+ OpName %ret_i32 "ret_i32"
+ OpName %ret_u32 "ret_u32"
+ OpName %ret_f32 "ret_f32"
+ OpName %ret_v2i32 "ret_v2i32"
+ OpName %ret_v3u32 "ret_v3u32"
+ OpName %ret_v4f32 "ret_v4f32"
+ OpName %ret_m2x3 "ret_m2x3"
+ OpName %ret_arr "ret_arr"
+ OpName %S "S"
+ OpName %ret_struct "ret_struct"
+ OpName %main "main"
+ OpDecorate %_arr_float_uint_4 ArrayStride 4
+ %bool = OpTypeBool
+ %1 = OpTypeFunction %bool
+ %5 = OpConstantNull %bool
+ %int = OpTypeInt 32 1
+ %6 = OpTypeFunction %int
+ %10 = OpConstantNull %int
+ %uint = OpTypeInt 32 0
+ %11 = OpTypeFunction %uint
+ %15 = OpConstantNull %uint
+ %float = OpTypeFloat 32
+ %16 = OpTypeFunction %float
+ %20 = OpConstantNull %float
+ %v2int = OpTypeVector %int 2
+ %21 = OpTypeFunction %v2int
+ %25 = OpConstantNull %v2int
+ %v3uint = OpTypeVector %uint 3
+ %26 = OpTypeFunction %v3uint
+ %30 = OpConstantNull %v3uint
+ %v4float = OpTypeVector %float 4
+ %31 = OpTypeFunction %v4float
+ %35 = OpConstantNull %v4float
+ %v3float = OpTypeVector %float 3
+%mat2v3float = OpTypeMatrix %v3float 2
+ %36 = OpTypeFunction %mat2v3float
+ %41 = OpConstantNull %mat2v3float
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+ %42 = OpTypeFunction %_arr_float_uint_4
+ %47 = OpConstantNull %_arr_float_uint_4
+ %S = OpTypeStruct
+ %48 = OpTypeFunction %S
+ %52 = OpConstantNull %S
+ %void = OpTypeVoid
+ %53 = OpTypeFunction %void
+ %ret_bool = OpFunction %bool None %1
+ %4 = OpLabel
+ OpReturnValue %5
+ OpFunctionEnd
+ %ret_i32 = OpFunction %int None %6
+ %9 = OpLabel
+ OpReturnValue %10
+ OpFunctionEnd
+ %ret_u32 = OpFunction %uint None %11
+ %14 = OpLabel
+ OpReturnValue %15
+ OpFunctionEnd
+ %ret_f32 = OpFunction %float None %16
+ %19 = OpLabel
+ OpReturnValue %20
+ OpFunctionEnd
+ %ret_v2i32 = OpFunction %v2int None %21
+ %24 = OpLabel
+ OpReturnValue %25
+ OpFunctionEnd
+ %ret_v3u32 = OpFunction %v3uint None %26
+ %29 = OpLabel
+ OpReturnValue %30
+ OpFunctionEnd
+ %ret_v4f32 = OpFunction %v4float None %31
+ %34 = OpLabel
+ OpReturnValue %35
+ OpFunctionEnd
+ %ret_m2x3 = OpFunction %mat2v3float None %36
+ %40 = OpLabel
+ OpReturnValue %41
+ OpFunctionEnd
+ %ret_arr = OpFunction %_arr_float_uint_4 None %42
+ %46 = OpLabel
+ OpReturnValue %47
+ OpFunctionEnd
+ %ret_struct = OpFunction %S None %48
+ %51 = OpLabel
+ OpReturnValue %52
+ OpFunctionEnd
+ %main = OpFunction %void None %53
+ %56 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/types/return_types.wgsl.expected.wgsl b/test/types/return_types.wgsl.expected.wgsl
new file mode 100644
index 0000000..3507a99
--- /dev/null
+++ b/test/types/return_types.wgsl.expected.wgsl
@@ -0,0 +1,46 @@
+struct S {
+};
+
+fn ret_bool() -> bool {
+ return bool();
+}
+
+fn ret_i32() -> i32 {
+ return i32();
+}
+
+fn ret_u32() -> u32 {
+ return u32();
+}
+
+fn ret_f32() -> f32 {
+ return f32();
+}
+
+fn ret_v2i32() -> vec2<i32> {
+ return vec2<i32>();
+}
+
+fn ret_v3u32() -> vec3<u32> {
+ return vec3<u32>();
+}
+
+fn ret_v4f32() -> vec4<f32> {
+ return vec4<f32>();
+}
+
+fn ret_m2x3() -> mat2x3<f32> {
+ return mat2x3<f32>();
+}
+
+fn ret_arr() -> array<f32, 4> {
+ return array<f32, 4>();
+}
+
+fn ret_struct() -> S {
+ return S();
+}
+
+[[stage(compute)]]
+fn main() {
+}
diff --git a/test/types/struct_members.wgsl b/test/types/struct_members.wgsl
new file mode 100644
index 0000000..5850d30
--- /dev/null
+++ b/test/types/struct_members.wgsl
@@ -0,0 +1,20 @@
+struct S_inner {
+};
+
+struct S {
+ member_bool : bool;
+ member_i32 : i32;
+ member_u32 : u32;
+ member_f32 : f32;
+ member_v2i32 : vec2<i32>;
+ member_v3u32 : vec3<u32>;
+ member_v4f32 : vec4<f32>;
+ member_m2x3 : mat2x3<f32>;
+ member_arr : array<f32, 4>;
+ member_struct : S_inner;
+};
+
+[[stage(compute)]]
+fn main() {
+ let s : S = S();
+}
diff --git a/test/types/struct_members.wgsl.expected.hlsl b/test/types/struct_members.wgsl.expected.hlsl
new file mode 100644
index 0000000..f229075
--- /dev/null
+++ b/test/types/struct_members.wgsl.expected.hlsl
@@ -0,0 +1,21 @@
+struct S_inner {
+};
+struct S {
+ bool member_bool;
+ int member_i32;
+ uint member_u32;
+ float member_f32;
+ int2 member_v2i32;
+ uint3 member_v3u32;
+ float4 member_v4f32;
+ float2x3 member_m2x3;
+ float member_arr[4];
+ S_inner member_struct;
+};
+
+[numthreads(1, 1, 1)]
+void main() {
+ const S s = {false, 0, 0u, 0.0f, int2(0, 0), uint3(0u, 0u, 0u), float4(0.0f, 0.0f, 0.0f, 0.0f), float2x3(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f), {0.0f, 0.0f, 0.0f, 0.0f}, {}};
+ return;
+}
+
diff --git a/test/types/struct_members.wgsl.expected.msl b/test/types/struct_members.wgsl.expected.msl
new file mode 100644
index 0000000..8f7c579
--- /dev/null
+++ b/test/types/struct_members.wgsl.expected.msl
@@ -0,0 +1,23 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct S_inner {
+};
+struct S {
+ bool member_bool;
+ int member_i32;
+ uint member_u32;
+ float member_f32;
+ int2 member_v2i32;
+ uint3 member_v3u32;
+ float4 member_v4f32;
+ float2x3 member_m2x3;
+ float member_arr[4];
+ S_inner member_struct;
+};
+
+kernel void tint_symbol() {
+ S const s = {};
+ return;
+}
+
diff --git a/test/types/struct_members.wgsl.expected.spvasm b/test/types/struct_members.wgsl.expected.spvasm
new file mode 100644
index 0000000..b8fcce5
--- /dev/null
+++ b/test/types/struct_members.wgsl.expected.spvasm
@@ -0,0 +1,55 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 19
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %S "S"
+ OpMemberName %S 0 "member_bool"
+ OpMemberName %S 1 "member_i32"
+ OpMemberName %S 2 "member_u32"
+ OpMemberName %S 3 "member_f32"
+ OpMemberName %S 4 "member_v2i32"
+ OpMemberName %S 5 "member_v3u32"
+ OpMemberName %S 6 "member_v4f32"
+ OpMemberName %S 7 "member_m2x3"
+ OpMemberName %S 8 "member_arr"
+ OpMemberName %S 9 "member_struct"
+ OpName %S_inner "S_inner"
+ OpMemberDecorate %S 0 Offset 0
+ OpMemberDecorate %S 1 Offset 4
+ OpMemberDecorate %S 2 Offset 8
+ OpMemberDecorate %S 3 Offset 12
+ OpMemberDecorate %S 4 Offset 16
+ OpMemberDecorate %S 5 Offset 32
+ OpMemberDecorate %S 6 Offset 48
+ OpMemberDecorate %S 7 Offset 64
+ OpMemberDecorate %S 7 ColMajor
+ OpMemberDecorate %S 7 MatrixStride 16
+ OpMemberDecorate %S 8 Offset 96
+ OpDecorate %_arr_float_uint_4 ArrayStride 4
+ OpMemberDecorate %S 9 Offset 112
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %bool = OpTypeBool
+ %int = OpTypeInt 32 1
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2int = OpTypeVector %int 2
+ %v3uint = OpTypeVector %uint 3
+ %v4float = OpTypeVector %float 4
+ %v3float = OpTypeVector %float 3
+%mat2v3float = OpTypeMatrix %v3float 2
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+ %S_inner = OpTypeStruct
+ %S = OpTypeStruct %bool %int %uint %float %v2int %v3uint %v4float %mat2v3float %_arr_float_uint_4 %S_inner
+ %18 = OpConstantNull %S
+ %main = OpFunction %void None %1
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/types/struct_members.wgsl.expected.wgsl b/test/types/struct_members.wgsl.expected.wgsl
new file mode 100644
index 0000000..5850d30
--- /dev/null
+++ b/test/types/struct_members.wgsl.expected.wgsl
@@ -0,0 +1,20 @@
+struct S_inner {
+};
+
+struct S {
+ member_bool : bool;
+ member_i32 : i32;
+ member_u32 : u32;
+ member_f32 : f32;
+ member_v2i32 : vec2<i32>;
+ member_v3u32 : vec3<u32>;
+ member_v4f32 : vec4<f32>;
+ member_m2x3 : mat2x3<f32>;
+ member_arr : array<f32, 4>;
+ member_struct : S_inner;
+};
+
+[[stage(compute)]]
+fn main() {
+ let s : S = S();
+}