transform/shader_io: Generate a wrapper function

This is a major reworking of this transform. The old transform code
was getting unwieldy, with part of the complication coming from the
handling of multiple return statements. By generating a wrapper
function instead, we can avoid a lot of this complexity.

The original entry point function is stripped of all shader IO
attributes (as well as `stage` and `workgroup_size`), but the body is
left unmodified. A new entry point wrapper function is introduced
which calls the original function, packing/unpacking the shader inputs
as necessary, and propagates the result to the corresponding shader
outputs.

The new code has been refactored to use a state object with the
different parts of the transform split into separate functions, which
makes it much more manageable.

Fixed: tint:1076
Bug: tint:920
Change-Id: I3490a0ea7a3509a4e198ce730e476516649d8d96
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/60521
Auto-Submit: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/test/shader_io/compute_input_builtins.wgsl.expected.hlsl b/test/shader_io/compute_input_builtins.wgsl.expected.hlsl
index 8473e6c..cb71cd9 100644
--- a/test/shader_io/compute_input_builtins.wgsl.expected.hlsl
+++ b/test/shader_io/compute_input_builtins.wgsl.expected.hlsl
@@ -5,12 +5,12 @@
   uint3 workgroup_id : SV_GroupID;
 };
 
+void main_inner(uint3 local_invocation_id, uint local_invocation_index, uint3 global_invocation_id, uint3 workgroup_id) {
+  const uint foo = (((local_invocation_id.x + local_invocation_index) + global_invocation_id.x) + workgroup_id.x);
+}
+
 [numthreads(1, 1, 1)]
 void main(tint_symbol_1 tint_symbol) {
-  const uint3 local_invocation_id = tint_symbol.local_invocation_id;
-  const uint local_invocation_index = tint_symbol.local_invocation_index;
-  const uint3 global_invocation_id = tint_symbol.global_invocation_id;
-  const uint3 workgroup_id = tint_symbol.workgroup_id;
-  const uint foo = (((local_invocation_id.x + local_invocation_index) + global_invocation_id.x) + workgroup_id.x);
+  main_inner(tint_symbol.local_invocation_id, tint_symbol.local_invocation_index, tint_symbol.global_invocation_id, tint_symbol.workgroup_id);
   return;
 }
diff --git a/test/shader_io/compute_input_builtins.wgsl.expected.msl b/test/shader_io/compute_input_builtins.wgsl.expected.msl
index 2774a3d..60095f3 100644
--- a/test/shader_io/compute_input_builtins.wgsl.expected.msl
+++ b/test/shader_io/compute_input_builtins.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
-kernel void tint_symbol(uint3 local_invocation_id [[thread_position_in_threadgroup]], uint local_invocation_index [[thread_index_in_threadgroup]], uint3 global_invocation_id [[thread_position_in_grid]], uint3 workgroup_id [[threadgroup_position_in_grid]]) {
+void tint_symbol_inner(uint3 local_invocation_id, uint local_invocation_index, uint3 global_invocation_id, uint3 workgroup_id) {
   uint const foo = (((local_invocation_id.x + local_invocation_index) + global_invocation_id.x) + workgroup_id.x);
+}
+
+kernel void tint_symbol(uint3 local_invocation_id [[thread_position_in_threadgroup]], uint local_invocation_index [[thread_index_in_threadgroup]], uint3 global_invocation_id [[thread_position_in_grid]], uint3 workgroup_id [[threadgroup_position_in_grid]]) {
+  tint_symbol_inner(local_invocation_id, local_invocation_index, global_invocation_id, workgroup_id);
   return;
 }
 
diff --git a/test/shader_io/compute_input_builtins_struct.wgsl.expected.hlsl b/test/shader_io/compute_input_builtins_struct.wgsl.expected.hlsl
index 42d74ab..8e00493 100644
--- a/test/shader_io/compute_input_builtins_struct.wgsl.expected.hlsl
+++ b/test/shader_io/compute_input_builtins_struct.wgsl.expected.hlsl
@@ -11,9 +11,13 @@
   uint3 workgroup_id : SV_GroupID;
 };
 
+void main_inner(ComputeInputs inputs) {
+  const uint foo = (((inputs.local_invocation_id.x + inputs.local_invocation_index) + inputs.global_invocation_id.x) + inputs.workgroup_id.x);
+}
+
 [numthreads(1, 1, 1)]
 void main(tint_symbol_1 tint_symbol) {
-  const ComputeInputs inputs = {tint_symbol.local_invocation_id, tint_symbol.local_invocation_index, tint_symbol.global_invocation_id, tint_symbol.workgroup_id};
-  const uint foo = (((inputs.local_invocation_id.x + inputs.local_invocation_index) + inputs.global_invocation_id.x) + inputs.workgroup_id.x);
+  const ComputeInputs tint_symbol_2 = {tint_symbol.local_invocation_id, tint_symbol.local_invocation_index, tint_symbol.global_invocation_id, tint_symbol.workgroup_id};
+  main_inner(tint_symbol_2);
   return;
 }
diff --git a/test/shader_io/compute_input_builtins_struct.wgsl.expected.msl b/test/shader_io/compute_input_builtins_struct.wgsl.expected.msl
index 9a16f1b..56db89c 100644
--- a/test/shader_io/compute_input_builtins_struct.wgsl.expected.msl
+++ b/test/shader_io/compute_input_builtins_struct.wgsl.expected.msl
@@ -8,9 +8,13 @@
   uint3 workgroup_id;
 };
 
-kernel void tint_symbol(uint3 tint_symbol_2 [[thread_position_in_threadgroup]], uint tint_symbol_3 [[thread_index_in_threadgroup]], uint3 tint_symbol_4 [[thread_position_in_grid]], uint3 tint_symbol_5 [[threadgroup_position_in_grid]]) {
-  ComputeInputs const inputs = {.local_invocation_id=tint_symbol_2, .local_invocation_index=tint_symbol_3, .global_invocation_id=tint_symbol_4, .workgroup_id=tint_symbol_5};
+void tint_symbol_inner(ComputeInputs inputs) {
   uint const foo = (((inputs.local_invocation_id.x + inputs.local_invocation_index) + inputs.global_invocation_id.x) + inputs.workgroup_id.x);
+}
+
+kernel void tint_symbol(uint3 local_invocation_id [[thread_position_in_threadgroup]], uint local_invocation_index [[thread_index_in_threadgroup]], uint3 global_invocation_id [[thread_position_in_grid]], uint3 workgroup_id [[threadgroup_position_in_grid]]) {
+  ComputeInputs const tint_symbol_1 = {.local_invocation_id=local_invocation_id, .local_invocation_index=local_invocation_index, .global_invocation_id=global_invocation_id, .workgroup_id=workgroup_id};
+  tint_symbol_inner(tint_symbol_1);
   return;
 }
 
diff --git a/test/shader_io/compute_input_mixed.wgsl.expected.hlsl b/test/shader_io/compute_input_mixed.wgsl.expected.hlsl
index 4527317..e72a9d2 100644
--- a/test/shader_io/compute_input_mixed.wgsl.expected.hlsl
+++ b/test/shader_io/compute_input_mixed.wgsl.expected.hlsl
@@ -11,12 +11,14 @@
   uint3 workgroup_id : SV_GroupID;
 };
 
+void main_inner(ComputeInputs0 inputs0, uint local_invocation_index, uint3 global_invocation_id, ComputeInputs1 inputs1) {
+  const uint foo = (((inputs0.local_invocation_id.x + local_invocation_index) + global_invocation_id.x) + inputs1.workgroup_id.x);
+}
+
 [numthreads(1, 1, 1)]
 void main(tint_symbol_1 tint_symbol) {
-  const ComputeInputs0 inputs0 = {tint_symbol.local_invocation_id};
-  const uint local_invocation_index = tint_symbol.local_invocation_index;
-  const uint3 global_invocation_id = tint_symbol.global_invocation_id;
-  const ComputeInputs1 inputs1 = {tint_symbol.workgroup_id};
-  const uint foo = (((inputs0.local_invocation_id.x + local_invocation_index) + global_invocation_id.x) + inputs1.workgroup_id.x);
+  const ComputeInputs0 tint_symbol_2 = {tint_symbol.local_invocation_id};
+  const ComputeInputs1 tint_symbol_3 = {tint_symbol.workgroup_id};
+  main_inner(tint_symbol_2, tint_symbol.local_invocation_index, tint_symbol.global_invocation_id, tint_symbol_3);
   return;
 }
diff --git a/test/shader_io/compute_input_mixed.wgsl.expected.msl b/test/shader_io/compute_input_mixed.wgsl.expected.msl
index fe6293b..65ca123 100644
--- a/test/shader_io/compute_input_mixed.wgsl.expected.msl
+++ b/test/shader_io/compute_input_mixed.wgsl.expected.msl
@@ -8,10 +8,14 @@
   uint3 workgroup_id;
 };
 
-kernel void tint_symbol(uint3 tint_symbol_2 [[thread_position_in_threadgroup]], uint local_invocation_index [[thread_index_in_threadgroup]], uint3 global_invocation_id [[thread_position_in_grid]], uint3 tint_symbol_3 [[threadgroup_position_in_grid]]) {
-  ComputeInputs0 const inputs0 = {.local_invocation_id=tint_symbol_2};
-  ComputeInputs1 const inputs1 = {.workgroup_id=tint_symbol_3};
+void tint_symbol_inner(ComputeInputs0 inputs0, uint local_invocation_index, uint3 global_invocation_id, ComputeInputs1 inputs1) {
   uint const foo = (((inputs0.local_invocation_id.x + local_invocation_index) + global_invocation_id.x) + inputs1.workgroup_id.x);
+}
+
+kernel void tint_symbol(uint3 local_invocation_id [[thread_position_in_threadgroup]], uint local_invocation_index [[thread_index_in_threadgroup]], uint3 global_invocation_id [[thread_position_in_grid]], uint3 workgroup_id [[threadgroup_position_in_grid]]) {
+  ComputeInputs0 const tint_symbol_1 = {.local_invocation_id=local_invocation_id};
+  ComputeInputs1 const tint_symbol_2 = {.workgroup_id=workgroup_id};
+  tint_symbol_inner(tint_symbol_1, local_invocation_index, global_invocation_id, tint_symbol_2);
   return;
 }
 
diff --git a/test/shader_io/fragment_input_builtins.wgsl.expected.hlsl b/test/shader_io/fragment_input_builtins.wgsl.expected.hlsl
index b40247e..cc5f201 100644
--- a/test/shader_io/fragment_input_builtins.wgsl.expected.hlsl
+++ b/test/shader_io/fragment_input_builtins.wgsl.expected.hlsl
@@ -5,14 +5,14 @@
   uint sample_mask : SV_Coverage;
 };
 
-void main(tint_symbol_1 tint_symbol) {
-  const float4 position = tint_symbol.position;
-  const bool front_facing = tint_symbol.front_facing;
-  const uint sample_index = tint_symbol.sample_index;
-  const uint sample_mask = tint_symbol.sample_mask;
+void main_inner(float4 position, bool front_facing, uint sample_index, uint sample_mask) {
   if (front_facing) {
     const float4 foo = position;
     const uint bar = (sample_index + sample_mask);
   }
+}
+
+void main(tint_symbol_1 tint_symbol) {
+  main_inner(tint_symbol.position, tint_symbol.front_facing, tint_symbol.sample_index, tint_symbol.sample_mask);
   return;
 }
diff --git a/test/shader_io/fragment_input_builtins.wgsl.expected.msl b/test/shader_io/fragment_input_builtins.wgsl.expected.msl
index 4204e5e..fea0205 100644
--- a/test/shader_io/fragment_input_builtins.wgsl.expected.msl
+++ b/test/shader_io/fragment_input_builtins.wgsl.expected.msl
@@ -1,11 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
-fragment void tint_symbol(float4 position [[position]], bool front_facing [[front_facing]], uint sample_index [[sample_id]], uint sample_mask [[sample_mask]]) {
+void tint_symbol_inner(float4 position, bool front_facing, uint sample_index, uint sample_mask) {
   if (front_facing) {
     float4 const foo = position;
     uint const bar = (sample_index + sample_mask);
   }
+}
+
+fragment void tint_symbol(float4 position [[position]], bool front_facing [[front_facing]], uint sample_index [[sample_id]], uint sample_mask [[sample_mask]]) {
+  tint_symbol_inner(position, front_facing, sample_index, sample_mask);
   return;
 }
 
diff --git a/test/shader_io/fragment_input_builtins_struct.wgsl.expected.hlsl b/test/shader_io/fragment_input_builtins_struct.wgsl.expected.hlsl
index df29a00..6f38a1f 100644
--- a/test/shader_io/fragment_input_builtins_struct.wgsl.expected.hlsl
+++ b/test/shader_io/fragment_input_builtins_struct.wgsl.expected.hlsl
@@ -11,11 +11,15 @@
   uint sample_mask : SV_Coverage;
 };
 
-void main(tint_symbol_1 tint_symbol) {
-  const FragmentInputs inputs = {tint_symbol.position, tint_symbol.front_facing, tint_symbol.sample_index, tint_symbol.sample_mask};
+void main_inner(FragmentInputs inputs) {
   if (inputs.front_facing) {
     const float4 foo = inputs.position;
     const uint bar = (inputs.sample_index + inputs.sample_mask);
   }
+}
+
+void main(tint_symbol_1 tint_symbol) {
+  const FragmentInputs tint_symbol_2 = {tint_symbol.position, tint_symbol.front_facing, tint_symbol.sample_index, tint_symbol.sample_mask};
+  main_inner(tint_symbol_2);
   return;
 }
diff --git a/test/shader_io/fragment_input_builtins_struct.wgsl.expected.msl b/test/shader_io/fragment_input_builtins_struct.wgsl.expected.msl
index 284dbe5..4915bec 100644
--- a/test/shader_io/fragment_input_builtins_struct.wgsl.expected.msl
+++ b/test/shader_io/fragment_input_builtins_struct.wgsl.expected.msl
@@ -8,12 +8,16 @@
   uint sample_mask;
 };
 
-fragment void tint_symbol(float4 tint_symbol_2 [[position]], bool tint_symbol_3 [[front_facing]], uint tint_symbol_4 [[sample_id]], uint tint_symbol_5 [[sample_mask]]) {
-  FragmentInputs const inputs = {.position=tint_symbol_2, .front_facing=tint_symbol_3, .sample_index=tint_symbol_4, .sample_mask=tint_symbol_5};
+void tint_symbol_inner(FragmentInputs inputs) {
   if (inputs.front_facing) {
     float4 const foo = inputs.position;
     uint const bar = (inputs.sample_index + inputs.sample_mask);
   }
+}
+
+fragment void tint_symbol(float4 position [[position]], bool front_facing [[front_facing]], uint sample_index [[sample_id]], uint sample_mask [[sample_mask]]) {
+  FragmentInputs const tint_symbol_1 = {.position=position, .front_facing=front_facing, .sample_index=sample_index, .sample_mask=sample_mask};
+  tint_symbol_inner(tint_symbol_1);
   return;
 }
 
diff --git a/test/shader_io/fragment_input_locations.wgsl.expected.hlsl b/test/shader_io/fragment_input_locations.wgsl.expected.hlsl
index 8590130..5b6022e 100644
--- a/test/shader_io/fragment_input_locations.wgsl.expected.hlsl
+++ b/test/shader_io/fragment_input_locations.wgsl.expected.hlsl
@@ -5,14 +5,14 @@
   float4 loc3 : TEXCOORD3;
 };
 
-void main(tint_symbol_1 tint_symbol) {
-  const int loc0 = tint_symbol.loc0;
-  const uint loc1 = tint_symbol.loc1;
-  const float loc2 = tint_symbol.loc2;
-  const float4 loc3 = tint_symbol.loc3;
+void main_inner(int loc0, uint loc1, float loc2, float4 loc3) {
   const int i = loc0;
   const uint u = loc1;
   const float f = loc2;
   const float4 v = loc3;
+}
+
+void main(tint_symbol_1 tint_symbol) {
+  main_inner(tint_symbol.loc0, tint_symbol.loc1, tint_symbol.loc2, tint_symbol.loc3);
   return;
 }
diff --git a/test/shader_io/fragment_input_locations.wgsl.expected.msl b/test/shader_io/fragment_input_locations.wgsl.expected.msl
index c8014ad..f73afbe 100644
--- a/test/shader_io/fragment_input_locations.wgsl.expected.msl
+++ b/test/shader_io/fragment_input_locations.wgsl.expected.msl
@@ -8,15 +8,15 @@
   float4 loc3 [[user(locn3)]];
 };
 
-fragment void tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
-  int const loc0 = tint_symbol_1.loc0;
-  uint const loc1 = tint_symbol_1.loc1;
-  float const loc2 = tint_symbol_1.loc2;
-  float4 const loc3 = tint_symbol_1.loc3;
+void tint_symbol_inner(int loc0, uint loc1, float loc2, float4 loc3) {
   int const i = loc0;
   uint const u = loc1;
   float const f = loc2;
   float4 const v = loc3;
+}
+
+fragment void tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
+  tint_symbol_inner(tint_symbol_1.loc0, tint_symbol_1.loc1, tint_symbol_1.loc2, tint_symbol_1.loc3);
   return;
 }
 
diff --git a/test/shader_io/fragment_input_locations_struct.wgsl.expected.hlsl b/test/shader_io/fragment_input_locations_struct.wgsl.expected.hlsl
index 9aa01ec..bea6f96 100644
--- a/test/shader_io/fragment_input_locations_struct.wgsl.expected.hlsl
+++ b/test/shader_io/fragment_input_locations_struct.wgsl.expected.hlsl
@@ -11,11 +11,15 @@
   float4 loc3 : TEXCOORD3;
 };
 
-void main(tint_symbol_1 tint_symbol) {
-  const FragmentInputs inputs = {tint_symbol.loc0, tint_symbol.loc1, tint_symbol.loc2, tint_symbol.loc3};
+void main_inner(FragmentInputs inputs) {
   const int i = inputs.loc0;
   const uint u = inputs.loc1;
   const float f = inputs.loc2;
   const float4 v = inputs.loc3;
+}
+
+void main(tint_symbol_1 tint_symbol) {
+  const FragmentInputs tint_symbol_2 = {tint_symbol.loc0, tint_symbol.loc1, tint_symbol.loc2, tint_symbol.loc3};
+  main_inner(tint_symbol_2);
   return;
 }
diff --git a/test/shader_io/fragment_input_locations_struct.wgsl.expected.msl b/test/shader_io/fragment_input_locations_struct.wgsl.expected.msl
index 19145f5..bddd084 100644
--- a/test/shader_io/fragment_input_locations_struct.wgsl.expected.msl
+++ b/test/shader_io/fragment_input_locations_struct.wgsl.expected.msl
@@ -14,12 +14,16 @@
   float4 loc3 [[user(locn3)]];
 };
 
-fragment void tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
-  FragmentInputs const inputs = {.loc0=tint_symbol_1.loc0, .loc1=tint_symbol_1.loc1, .loc2=tint_symbol_1.loc2, .loc3=tint_symbol_1.loc3};
+void tint_symbol_inner(FragmentInputs inputs) {
   int const i = inputs.loc0;
   uint const u = inputs.loc1;
   float const f = inputs.loc2;
   float4 const v = inputs.loc3;
+}
+
+fragment void tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
+  FragmentInputs const tint_symbol_3 = {.loc0=tint_symbol_1.loc0, .loc1=tint_symbol_1.loc1, .loc2=tint_symbol_1.loc2, .loc3=tint_symbol_1.loc3};
+  tint_symbol_inner(tint_symbol_3);
   return;
 }
 
diff --git a/test/shader_io/fragment_input_mixed.wgsl.expected.hlsl b/test/shader_io/fragment_input_mixed.wgsl.expected.hlsl
index bd63b41..569a409 100644
--- a/test/shader_io/fragment_input_mixed.wgsl.expected.hlsl
+++ b/test/shader_io/fragment_input_mixed.wgsl.expected.hlsl
@@ -17,13 +17,7 @@
   uint sample_mask : SV_Coverage;
 };
 
-void main(tint_symbol_1 tint_symbol) {
-  const FragmentInputs0 inputs0 = {tint_symbol.position, tint_symbol.loc0};
-  const bool front_facing = tint_symbol.front_facing;
-  const uint loc1 = tint_symbol.loc1;
-  const uint sample_index = tint_symbol.sample_index;
-  const FragmentInputs1 inputs1 = {tint_symbol.loc3, tint_symbol.sample_mask};
-  const float loc2 = tint_symbol.loc2;
+void main_inner(FragmentInputs0 inputs0, bool front_facing, uint loc1, uint sample_index, FragmentInputs1 inputs1, float loc2) {
   if (front_facing) {
     const float4 foo = inputs0.position;
     const uint bar = (sample_index + inputs1.sample_mask);
@@ -32,5 +26,11 @@
     const float f = loc2;
     const float4 v = inputs1.loc3;
   }
+}
+
+void main(tint_symbol_1 tint_symbol) {
+  const FragmentInputs0 tint_symbol_2 = {tint_symbol.position, tint_symbol.loc0};
+  const FragmentInputs1 tint_symbol_3 = {tint_symbol.loc3, tint_symbol.sample_mask};
+  main_inner(tint_symbol_2, tint_symbol.front_facing, tint_symbol.loc1, tint_symbol.sample_index, tint_symbol_3, tint_symbol.loc2);
   return;
 }
diff --git a/test/shader_io/fragment_input_mixed.wgsl.expected.msl b/test/shader_io/fragment_input_mixed.wgsl.expected.msl
index 9b3a13a..1d3f36a 100644
--- a/test/shader_io/fragment_input_mixed.wgsl.expected.msl
+++ b/test/shader_io/fragment_input_mixed.wgsl.expected.msl
@@ -9,18 +9,14 @@
   float4 loc3;
   uint sample_mask;
 };
-struct tint_symbol_4 {
+struct tint_symbol_2 {
   int loc0 [[user(locn0)]];
   uint loc1 [[user(locn1)]];
   float loc2 [[user(locn2)]];
   float4 loc3 [[user(locn3)]];
 };
 
-fragment void tint_symbol(float4 tint_symbol_2 [[position]], bool front_facing [[front_facing]], uint sample_index [[sample_id]], uint tint_symbol_3 [[sample_mask]], tint_symbol_4 tint_symbol_1 [[stage_in]]) {
-  FragmentInputs0 const inputs0 = {.position=tint_symbol_2, .loc0=tint_symbol_1.loc0};
-  uint const loc1 = tint_symbol_1.loc1;
-  FragmentInputs1 const inputs1 = {.loc3=tint_symbol_1.loc3, .sample_mask=tint_symbol_3};
-  float const loc2 = tint_symbol_1.loc2;
+void tint_symbol_inner(FragmentInputs0 inputs0, bool front_facing, uint loc1, uint sample_index, FragmentInputs1 inputs1, float loc2) {
   if (front_facing) {
     float4 const foo = inputs0.position;
     uint const bar = (sample_index + inputs1.sample_mask);
@@ -29,6 +25,12 @@
     float const f = loc2;
     float4 const v = inputs1.loc3;
   }
+}
+
+fragment void tint_symbol(float4 position [[position]], bool front_facing [[front_facing]], uint sample_index [[sample_id]], uint sample_mask [[sample_mask]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
+  FragmentInputs0 const tint_symbol_3 = {.position=position, .loc0=tint_symbol_1.loc0};
+  FragmentInputs1 const tint_symbol_4 = {.loc3=tint_symbol_1.loc3, .sample_mask=sample_mask};
+  tint_symbol_inner(tint_symbol_3, front_facing, tint_symbol_1.loc1, sample_index, tint_symbol_4, tint_symbol_1.loc2);
   return;
 }
 
diff --git a/test/shader_io/fragment_output_builtins.wgsl.expected.hlsl b/test/shader_io/fragment_output_builtins.wgsl.expected.hlsl
index a24d9cf..2b972d7 100644
--- a/test/shader_io/fragment_output_builtins.wgsl.expected.hlsl
+++ b/test/shader_io/fragment_output_builtins.wgsl.expected.hlsl
@@ -2,16 +2,28 @@
   float value : SV_Depth;
 };
 
+float main1_inner() {
+  return 1.0f;
+}
+
 tint_symbol main1() {
-  const tint_symbol tint_symbol_2 = {1.0f};
-  return tint_symbol_2;
+  const float inner_result = main1_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
 
 struct tint_symbol_1 {
   uint value : SV_Coverage;
 };
 
+uint main2_inner() {
+  return 1u;
+}
+
 tint_symbol_1 main2() {
-  const tint_symbol_1 tint_symbol_3 = {1u};
-  return tint_symbol_3;
+  const uint inner_result_1 = main2_inner();
+  tint_symbol_1 wrapper_result_1 = (tint_symbol_1)0;
+  wrapper_result_1.value = inner_result_1;
+  return wrapper_result_1;
 }
diff --git a/test/shader_io/fragment_output_builtins.wgsl.expected.msl b/test/shader_io/fragment_output_builtins.wgsl.expected.msl
index 8129f66..97d6904 100644
--- a/test/shader_io/fragment_output_builtins.wgsl.expected.msl
+++ b/test/shader_io/fragment_output_builtins.wgsl.expected.msl
@@ -8,13 +8,25 @@
   uint value [[sample_mask]];
 };
 
+float main1_inner() {
+  return 1.0f;
+}
+
 fragment tint_symbol main1() {
-  tint_symbol const tint_symbol_2 = {.value=1.0f};
-  return tint_symbol_2;
+  float const inner_result = main1_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+uint main2_inner() {
+  return 1u;
 }
 
 fragment tint_symbol_1 main2() {
-  tint_symbol_1 const tint_symbol_3 = {.value=1u};
-  return tint_symbol_3;
+  uint const inner_result_1 = main2_inner();
+  tint_symbol_1 wrapper_result_1 = {};
+  wrapper_result_1.value = inner_result_1;
+  return wrapper_result_1;
 }
 
diff --git a/test/shader_io/fragment_output_builtins_struct.wgsl.expected.hlsl b/test/shader_io/fragment_output_builtins_struct.wgsl.expected.hlsl
index 889bdb9..2d2e660 100644
--- a/test/shader_io/fragment_output_builtins_struct.wgsl.expected.hlsl
+++ b/test/shader_io/fragment_output_builtins_struct.wgsl.expected.hlsl
@@ -7,8 +7,15 @@
   uint sample_mask : SV_Coverage;
 };
 
-tint_symbol main() {
+FragmentOutputs main_inner() {
   const FragmentOutputs tint_symbol_1 = {1.0f, 1u};
-  const tint_symbol tint_symbol_2 = {tint_symbol_1.frag_depth, tint_symbol_1.sample_mask};
-  return tint_symbol_2;
+  return tint_symbol_1;
+}
+
+tint_symbol main() {
+  const FragmentOutputs inner_result = main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.frag_depth = inner_result.frag_depth;
+  wrapper_result.sample_mask = inner_result.sample_mask;
+  return wrapper_result;
 }
diff --git a/test/shader_io/fragment_output_builtins_struct.wgsl.expected.msl b/test/shader_io/fragment_output_builtins_struct.wgsl.expected.msl
index 851c83b..65de6df 100644
--- a/test/shader_io/fragment_output_builtins_struct.wgsl.expected.msl
+++ b/test/shader_io/fragment_output_builtins_struct.wgsl.expected.msl
@@ -10,9 +10,16 @@
   uint sample_mask [[sample_mask]];
 };
 
-fragment tint_symbol_1 tint_symbol() {
+FragmentOutputs tint_symbol_inner() {
   FragmentOutputs const tint_symbol_2 = {.frag_depth=1.0f, .sample_mask=1u};
-  tint_symbol_1 const tint_symbol_3 = {.frag_depth=tint_symbol_2.frag_depth, .sample_mask=tint_symbol_2.sample_mask};
-  return tint_symbol_3;
+  return tint_symbol_2;
+}
+
+fragment tint_symbol_1 tint_symbol() {
+  FragmentOutputs const inner_result = tint_symbol_inner();
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.frag_depth = inner_result.frag_depth;
+  wrapper_result.sample_mask = inner_result.sample_mask;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/fragment_output_locations.wgsl.expected.hlsl b/test/shader_io/fragment_output_locations.wgsl.expected.hlsl
index 551dbce..0a9e48f 100644
--- a/test/shader_io/fragment_output_locations.wgsl.expected.hlsl
+++ b/test/shader_io/fragment_output_locations.wgsl.expected.hlsl
@@ -2,34 +2,58 @@
   int value : SV_Target0;
 };
 
+int main0_inner() {
+  return 1;
+}
+
 tint_symbol main0() {
-  const tint_symbol tint_symbol_4 = {1};
-  return tint_symbol_4;
+  const int inner_result = main0_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
 
 struct tint_symbol_1 {
   uint value : SV_Target1;
 };
 
+uint main1_inner() {
+  return 1u;
+}
+
 tint_symbol_1 main1() {
-  const tint_symbol_1 tint_symbol_5 = {1u};
-  return tint_symbol_5;
+  const uint inner_result_1 = main1_inner();
+  tint_symbol_1 wrapper_result_1 = (tint_symbol_1)0;
+  wrapper_result_1.value = inner_result_1;
+  return wrapper_result_1;
 }
 
 struct tint_symbol_2 {
   float value : SV_Target2;
 };
 
+float main2_inner() {
+  return 1.0f;
+}
+
 tint_symbol_2 main2() {
-  const tint_symbol_2 tint_symbol_6 = {1.0f};
-  return tint_symbol_6;
+  const float inner_result_2 = main2_inner();
+  tint_symbol_2 wrapper_result_2 = (tint_symbol_2)0;
+  wrapper_result_2.value = inner_result_2;
+  return wrapper_result_2;
 }
 
 struct tint_symbol_3 {
   float4 value : SV_Target3;
 };
 
+float4 main3_inner() {
+  return float4(1.0f, 2.0f, 3.0f, 4.0f);
+}
+
 tint_symbol_3 main3() {
-  const tint_symbol_3 tint_symbol_7 = {float4(1.0f, 2.0f, 3.0f, 4.0f)};
-  return tint_symbol_7;
+  const float4 inner_result_3 = main3_inner();
+  tint_symbol_3 wrapper_result_3 = (tint_symbol_3)0;
+  wrapper_result_3.value = inner_result_3;
+  return wrapper_result_3;
 }
diff --git a/test/shader_io/fragment_output_locations.wgsl.expected.msl b/test/shader_io/fragment_output_locations.wgsl.expected.msl
index fed3dca..03ba9bb 100644
--- a/test/shader_io/fragment_output_locations.wgsl.expected.msl
+++ b/test/shader_io/fragment_output_locations.wgsl.expected.msl
@@ -14,23 +14,47 @@
   float4 value [[color(3)]];
 };
 
+int main0_inner() {
+  return 1;
+}
+
 fragment tint_symbol main0() {
-  tint_symbol const tint_symbol_4 = {.value=1};
-  return tint_symbol_4;
+  int const inner_result = main0_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+uint main1_inner() {
+  return 1u;
 }
 
 fragment tint_symbol_1 main1() {
-  tint_symbol_1 const tint_symbol_5 = {.value=1u};
-  return tint_symbol_5;
+  uint const inner_result_1 = main1_inner();
+  tint_symbol_1 wrapper_result_1 = {};
+  wrapper_result_1.value = inner_result_1;
+  return wrapper_result_1;
+}
+
+float main2_inner() {
+  return 1.0f;
 }
 
 fragment tint_symbol_2 main2() {
-  tint_symbol_2 const tint_symbol_6 = {.value=1.0f};
-  return tint_symbol_6;
+  float const inner_result_2 = main2_inner();
+  tint_symbol_2 wrapper_result_2 = {};
+  wrapper_result_2.value = inner_result_2;
+  return wrapper_result_2;
+}
+
+float4 main3_inner() {
+  return float4(1.0f, 2.0f, 3.0f, 4.0f);
 }
 
 fragment tint_symbol_3 main3() {
-  tint_symbol_3 const tint_symbol_7 = {.value=float4(1.0f, 2.0f, 3.0f, 4.0f)};
-  return tint_symbol_7;
+  float4 const inner_result_3 = main3_inner();
+  tint_symbol_3 wrapper_result_3 = {};
+  wrapper_result_3.value = inner_result_3;
+  return wrapper_result_3;
 }
 
diff --git a/test/shader_io/fragment_output_locations_struct.wgsl.expected.hlsl b/test/shader_io/fragment_output_locations_struct.wgsl.expected.hlsl
index 460f4a3..09216c3 100644
--- a/test/shader_io/fragment_output_locations_struct.wgsl.expected.hlsl
+++ b/test/shader_io/fragment_output_locations_struct.wgsl.expected.hlsl
@@ -11,8 +11,17 @@
   float4 loc3 : SV_Target3;
 };
 
-tint_symbol main() {
+FragmentOutputs main_inner() {
   const FragmentOutputs tint_symbol_1 = {1, 1u, 1.0f, float4(1.0f, 2.0f, 3.0f, 4.0f)};
-  const tint_symbol tint_symbol_2 = {tint_symbol_1.loc0, tint_symbol_1.loc1, tint_symbol_1.loc2, tint_symbol_1.loc3};
-  return tint_symbol_2;
+  return tint_symbol_1;
+}
+
+tint_symbol main() {
+  const FragmentOutputs inner_result = main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.loc0 = inner_result.loc0;
+  wrapper_result.loc1 = inner_result.loc1;
+  wrapper_result.loc2 = inner_result.loc2;
+  wrapper_result.loc3 = inner_result.loc3;
+  return wrapper_result;
 }
diff --git a/test/shader_io/fragment_output_locations_struct.wgsl.expected.msl b/test/shader_io/fragment_output_locations_struct.wgsl.expected.msl
index e4e75cb..6cfad1a 100644
--- a/test/shader_io/fragment_output_locations_struct.wgsl.expected.msl
+++ b/test/shader_io/fragment_output_locations_struct.wgsl.expected.msl
@@ -14,9 +14,18 @@
   float4 loc3 [[color(3)]];
 };
 
-fragment tint_symbol_1 tint_symbol() {
+FragmentOutputs tint_symbol_inner() {
   FragmentOutputs const tint_symbol_2 = {.loc0=1, .loc1=1u, .loc2=1.0f, .loc3=float4(1.0f, 2.0f, 3.0f, 4.0f)};
-  tint_symbol_1 const tint_symbol_3 = {.loc0=tint_symbol_2.loc0, .loc1=tint_symbol_2.loc1, .loc2=tint_symbol_2.loc2, .loc3=tint_symbol_2.loc3};
-  return tint_symbol_3;
+  return tint_symbol_2;
+}
+
+fragment tint_symbol_1 tint_symbol() {
+  FragmentOutputs const inner_result = tint_symbol_inner();
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.loc0 = inner_result.loc0;
+  wrapper_result.loc1 = inner_result.loc1;
+  wrapper_result.loc2 = inner_result.loc2;
+  wrapper_result.loc3 = inner_result.loc3;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/fragment_output_mixed.wgsl.expected.hlsl b/test/shader_io/fragment_output_mixed.wgsl.expected.hlsl
index 9bc3fa2..8658875 100644
--- a/test/shader_io/fragment_output_mixed.wgsl.expected.hlsl
+++ b/test/shader_io/fragment_output_mixed.wgsl.expected.hlsl
@@ -15,8 +15,19 @@
   uint sample_mask : SV_Coverage;
 };
 
-tint_symbol main() {
+FragmentOutputs main_inner() {
   const FragmentOutputs tint_symbol_1 = {1, 2.0f, 1u, 1.0f, 2u, float4(1.0f, 2.0f, 3.0f, 4.0f)};
-  const tint_symbol tint_symbol_2 = {tint_symbol_1.loc0, tint_symbol_1.loc1, tint_symbol_1.loc2, tint_symbol_1.loc3, tint_symbol_1.frag_depth, tint_symbol_1.sample_mask};
-  return tint_symbol_2;
+  return tint_symbol_1;
+}
+
+tint_symbol main() {
+  const FragmentOutputs inner_result = main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.loc0 = inner_result.loc0;
+  wrapper_result.frag_depth = inner_result.frag_depth;
+  wrapper_result.loc1 = inner_result.loc1;
+  wrapper_result.loc2 = inner_result.loc2;
+  wrapper_result.sample_mask = inner_result.sample_mask;
+  wrapper_result.loc3 = inner_result.loc3;
+  return wrapper_result;
 }
diff --git a/test/shader_io/fragment_output_mixed.wgsl.expected.msl b/test/shader_io/fragment_output_mixed.wgsl.expected.msl
index 665936b..c7d2a13 100644
--- a/test/shader_io/fragment_output_mixed.wgsl.expected.msl
+++ b/test/shader_io/fragment_output_mixed.wgsl.expected.msl
@@ -18,9 +18,20 @@
   uint sample_mask [[sample_mask]];
 };
 
-fragment tint_symbol_1 tint_symbol() {
+FragmentOutputs tint_symbol_inner() {
   FragmentOutputs const tint_symbol_2 = {.loc0=1, .frag_depth=2.0f, .loc1=1u, .loc2=1.0f, .sample_mask=2u, .loc3=float4(1.0f, 2.0f, 3.0f, 4.0f)};
-  tint_symbol_1 const tint_symbol_3 = {.loc0=tint_symbol_2.loc0, .loc1=tint_symbol_2.loc1, .loc2=tint_symbol_2.loc2, .loc3=tint_symbol_2.loc3, .frag_depth=tint_symbol_2.frag_depth, .sample_mask=tint_symbol_2.sample_mask};
-  return tint_symbol_3;
+  return tint_symbol_2;
+}
+
+fragment tint_symbol_1 tint_symbol() {
+  FragmentOutputs const inner_result = tint_symbol_inner();
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.loc0 = inner_result.loc0;
+  wrapper_result.frag_depth = inner_result.frag_depth;
+  wrapper_result.loc1 = inner_result.loc1;
+  wrapper_result.loc2 = inner_result.loc2;
+  wrapper_result.sample_mask = inner_result.sample_mask;
+  wrapper_result.loc3 = inner_result.loc3;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/interpolate_input_parameters.wgsl.expected.hlsl b/test/shader_io/interpolate_input_parameters.wgsl.expected.hlsl
index e653990..bb78da9 100644
--- a/test/shader_io/interpolate_input_parameters.wgsl.expected.hlsl
+++ b/test/shader_io/interpolate_input_parameters.wgsl.expected.hlsl
@@ -9,14 +9,10 @@
   noperspective sample float linear_sample : TEXCOORD7;
 };
 
+void main_inner(float none, float flat, float perspective_center, float perspective_centroid, float perspective_sample, float linear_center, float linear_centroid, float linear_sample) {
+}
+
 void main(tint_symbol_1 tint_symbol) {
-  const float none = tint_symbol.none;
-  const float flat = tint_symbol.flat;
-  const float perspective_center = tint_symbol.perspective_center;
-  const float perspective_centroid = tint_symbol.perspective_centroid;
-  const float perspective_sample = tint_symbol.perspective_sample;
-  const float linear_center = tint_symbol.linear_center;
-  const float linear_centroid = tint_symbol.linear_centroid;
-  const float linear_sample = tint_symbol.linear_sample;
+  main_inner(tint_symbol.none, tint_symbol.flat, tint_symbol.perspective_center, tint_symbol.perspective_centroid, tint_symbol.perspective_sample, tint_symbol.linear_center, tint_symbol.linear_centroid, tint_symbol.linear_sample);
   return;
 }
diff --git a/test/shader_io/interpolate_input_parameters.wgsl.expected.msl b/test/shader_io/interpolate_input_parameters.wgsl.expected.msl
index ff19572..d460bb0 100644
--- a/test/shader_io/interpolate_input_parameters.wgsl.expected.msl
+++ b/test/shader_io/interpolate_input_parameters.wgsl.expected.msl
@@ -12,15 +12,11 @@
   float linear_sample [[user(locn7)]] [[sample_no_perspective]];
 };
 
+void tint_symbol_inner(float none, float flat, float perspective_center, float perspective_centroid, float perspective_sample, float linear_center, float linear_centroid, float linear_sample) {
+}
+
 fragment void tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
-  float const none = tint_symbol_1.none;
-  float const flat = tint_symbol_1.flat;
-  float const perspective_center = tint_symbol_1.perspective_center;
-  float const perspective_centroid = tint_symbol_1.perspective_centroid;
-  float const perspective_sample = tint_symbol_1.perspective_sample;
-  float const linear_center = tint_symbol_1.linear_center;
-  float const linear_centroid = tint_symbol_1.linear_centroid;
-  float const linear_sample = tint_symbol_1.linear_sample;
+  tint_symbol_inner(tint_symbol_1.none, tint_symbol_1.flat, tint_symbol_1.perspective_center, tint_symbol_1.perspective_centroid, tint_symbol_1.perspective_sample, tint_symbol_1.linear_center, tint_symbol_1.linear_centroid, tint_symbol_1.linear_sample);
   return;
 }
 
diff --git a/test/shader_io/interpolate_input_struct.wgsl.expected.hlsl b/test/shader_io/interpolate_input_struct.wgsl.expected.hlsl
index 694807b..cfc7acd 100644
--- a/test/shader_io/interpolate_input_struct.wgsl.expected.hlsl
+++ b/test/shader_io/interpolate_input_struct.wgsl.expected.hlsl
@@ -19,7 +19,11 @@
   noperspective sample float linear_sample : TEXCOORD7;
 };
 
+void main_inner(In tint_symbol) {
+}
+
 void main(tint_symbol_2 tint_symbol_1) {
-  const In tint_symbol = {tint_symbol_1.none, tint_symbol_1.flat, tint_symbol_1.perspective_center, tint_symbol_1.perspective_centroid, tint_symbol_1.perspective_sample, tint_symbol_1.linear_center, tint_symbol_1.linear_centroid, tint_symbol_1.linear_sample};
+  const In tint_symbol_3 = {tint_symbol_1.none, tint_symbol_1.flat, tint_symbol_1.perspective_center, tint_symbol_1.perspective_centroid, tint_symbol_1.perspective_sample, tint_symbol_1.linear_center, tint_symbol_1.linear_centroid, tint_symbol_1.linear_sample};
+  main_inner(tint_symbol_3);
   return;
 }
diff --git a/test/shader_io/interpolate_input_struct.wgsl.expected.msl b/test/shader_io/interpolate_input_struct.wgsl.expected.msl
index 285f608..edc350f 100644
--- a/test/shader_io/interpolate_input_struct.wgsl.expected.msl
+++ b/test/shader_io/interpolate_input_struct.wgsl.expected.msl
@@ -22,8 +22,12 @@
   float linear_sample [[user(locn7)]] [[sample_no_perspective]];
 };
 
+void tint_symbol_inner(In in) {
+}
+
 fragment void tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
-  In const in = {.none=tint_symbol_1.none, .flat=tint_symbol_1.flat, .perspective_center=tint_symbol_1.perspective_center, .perspective_centroid=tint_symbol_1.perspective_centroid, .perspective_sample=tint_symbol_1.perspective_sample, .linear_center=tint_symbol_1.linear_center, .linear_centroid=tint_symbol_1.linear_centroid, .linear_sample=tint_symbol_1.linear_sample};
+  In const tint_symbol_3 = {.none=tint_symbol_1.none, .flat=tint_symbol_1.flat, .perspective_center=tint_symbol_1.perspective_center, .perspective_centroid=tint_symbol_1.perspective_centroid, .perspective_sample=tint_symbol_1.perspective_sample, .linear_center=tint_symbol_1.linear_center, .linear_centroid=tint_symbol_1.linear_centroid, .linear_sample=tint_symbol_1.linear_sample};
+  tint_symbol_inner(tint_symbol_3);
   return;
 }
 
diff --git a/test/shader_io/interpolate_integers.wgsl.expected.hlsl b/test/shader_io/interpolate_integers.wgsl.expected.hlsl
index 9dd38a9..905b792 100644
--- a/test/shader_io/interpolate_integers.wgsl.expected.hlsl
+++ b/test/shader_io/interpolate_integers.wgsl.expected.hlsl
@@ -13,25 +13,41 @@
   float4 pos : SV_Position;
 };
 
-tint_symbol vert_main() {
-  const Interface tint_symbol_1 = (Interface)0;
-  const tint_symbol tint_symbol_5 = {tint_symbol_1.i, tint_symbol_1.u, tint_symbol_1.vi, tint_symbol_1.vu, tint_symbol_1.pos};
-  return tint_symbol_5;
+Interface vert_main_inner() {
+  const Interface tint_symbol_4 = (Interface)0;
+  return tint_symbol_4;
 }
 
-struct tint_symbol_3 {
+tint_symbol vert_main() {
+  const Interface inner_result = vert_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.i = inner_result.i;
+  wrapper_result.u = inner_result.u;
+  wrapper_result.vi = inner_result.vi;
+  wrapper_result.vu = inner_result.vu;
+  wrapper_result.pos = inner_result.pos;
+  return wrapper_result;
+}
+
+struct tint_symbol_2 {
   int i : TEXCOORD0;
   uint u : TEXCOORD1;
   int4 vi : TEXCOORD2;
   uint4 vu : TEXCOORD3;
   float4 pos : SV_Position;
 };
-struct tint_symbol_4 {
+struct tint_symbol_3 {
   int value : SV_Target0;
 };
 
-tint_symbol_4 frag_main(tint_symbol_3 tint_symbol_2) {
-  const Interface inputs = {tint_symbol_2.i, tint_symbol_2.u, tint_symbol_2.vi, tint_symbol_2.vu, tint_symbol_2.pos};
-  const tint_symbol_4 tint_symbol_6 = {inputs.i};
-  return tint_symbol_6;
+int frag_main_inner(Interface inputs) {
+  return inputs.i;
+}
+
+tint_symbol_3 frag_main(tint_symbol_2 tint_symbol_1) {
+  const Interface tint_symbol_5 = {tint_symbol_1.i, tint_symbol_1.u, tint_symbol_1.vi, tint_symbol_1.vu, tint_symbol_1.pos};
+  const int inner_result_1 = frag_main_inner(tint_symbol_5);
+  tint_symbol_3 wrapper_result_1 = (tint_symbol_3)0;
+  wrapper_result_1.value = inner_result_1;
+  return wrapper_result_1;
 }
diff --git a/test/shader_io/interpolate_integers.wgsl.expected.msl b/test/shader_io/interpolate_integers.wgsl.expected.msl
index 4fb8d3a..420daa7 100644
--- a/test/shader_io/interpolate_integers.wgsl.expected.msl
+++ b/test/shader_io/interpolate_integers.wgsl.expected.msl
@@ -15,25 +15,41 @@
   uint4 vu [[user(locn3)]];
   float4 pos [[position]];
 };
-struct tint_symbol_4 {
+struct tint_symbol_2 {
   int i [[user(locn0)]];
   uint u [[user(locn1)]];
   int4 vi [[user(locn2)]];
   uint4 vu [[user(locn3)]];
 };
-struct tint_symbol_5 {
+struct tint_symbol_3 {
   int value [[color(0)]];
 };
 
-vertex tint_symbol vert_main() {
-  Interface const tint_symbol_1 = {};
-  tint_symbol const tint_symbol_6 = {.i=tint_symbol_1.i, .u=tint_symbol_1.u, .vi=tint_symbol_1.vi, .vu=tint_symbol_1.vu, .pos=tint_symbol_1.pos};
-  return tint_symbol_6;
+Interface vert_main_inner() {
+  Interface const tint_symbol_4 = {};
+  return tint_symbol_4;
 }
 
-fragment tint_symbol_5 frag_main(float4 tint_symbol_3 [[position]], tint_symbol_4 tint_symbol_2 [[stage_in]]) {
-  Interface const inputs = {.i=tint_symbol_2.i, .u=tint_symbol_2.u, .vi=tint_symbol_2.vi, .vu=tint_symbol_2.vu, .pos=tint_symbol_3};
-  tint_symbol_5 const tint_symbol_7 = {.value=inputs.i};
-  return tint_symbol_7;
+vertex tint_symbol vert_main() {
+  Interface const inner_result = vert_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.i = inner_result.i;
+  wrapper_result.u = inner_result.u;
+  wrapper_result.vi = inner_result.vi;
+  wrapper_result.vu = inner_result.vu;
+  wrapper_result.pos = inner_result.pos;
+  return wrapper_result;
+}
+
+int frag_main_inner(Interface inputs) {
+  return inputs.i;
+}
+
+fragment tint_symbol_3 frag_main(float4 pos [[position]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
+  Interface const tint_symbol_5 = {.i=tint_symbol_1.i, .u=tint_symbol_1.u, .vi=tint_symbol_1.vi, .vu=tint_symbol_1.vu, .pos=pos};
+  int const inner_result_1 = frag_main_inner(tint_symbol_5);
+  tint_symbol_3 wrapper_result_1 = {};
+  wrapper_result_1.value = inner_result_1;
+  return wrapper_result_1;
 }
 
diff --git a/test/shader_io/interpolate_return_struct.wgsl.expected.hlsl b/test/shader_io/interpolate_return_struct.wgsl.expected.hlsl
index 064119f..1929097 100644
--- a/test/shader_io/interpolate_return_struct.wgsl.expected.hlsl
+++ b/test/shader_io/interpolate_return_struct.wgsl.expected.hlsl
@@ -21,8 +21,22 @@
   float4 pos : SV_Position;
 };
 
-tint_symbol main() {
+Out main_inner() {
   const Out tint_symbol_1 = (Out)0;
-  const tint_symbol tint_symbol_2 = {tint_symbol_1.none, tint_symbol_1.flat, tint_symbol_1.perspective_center, tint_symbol_1.perspective_centroid, tint_symbol_1.perspective_sample, tint_symbol_1.linear_center, tint_symbol_1.linear_centroid, tint_symbol_1.linear_sample, tint_symbol_1.pos};
-  return tint_symbol_2;
+  return tint_symbol_1;
+}
+
+tint_symbol main() {
+  const Out inner_result = main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.pos = inner_result.pos;
+  wrapper_result.none = inner_result.none;
+  wrapper_result.flat = inner_result.flat;
+  wrapper_result.perspective_center = inner_result.perspective_center;
+  wrapper_result.perspective_centroid = inner_result.perspective_centroid;
+  wrapper_result.perspective_sample = inner_result.perspective_sample;
+  wrapper_result.linear_center = inner_result.linear_center;
+  wrapper_result.linear_centroid = inner_result.linear_centroid;
+  wrapper_result.linear_sample = inner_result.linear_sample;
+  return wrapper_result;
 }
diff --git a/test/shader_io/interpolate_return_struct.wgsl.expected.msl b/test/shader_io/interpolate_return_struct.wgsl.expected.msl
index 5cb0df6..afac16e 100644
--- a/test/shader_io/interpolate_return_struct.wgsl.expected.msl
+++ b/test/shader_io/interpolate_return_struct.wgsl.expected.msl
@@ -24,9 +24,23 @@
   float4 pos [[position]];
 };
 
-vertex tint_symbol_1 tint_symbol() {
+Out tint_symbol_inner() {
   Out const tint_symbol_2 = {};
-  tint_symbol_1 const tint_symbol_3 = {.none=tint_symbol_2.none, .flat=tint_symbol_2.flat, .perspective_center=tint_symbol_2.perspective_center, .perspective_centroid=tint_symbol_2.perspective_centroid, .perspective_sample=tint_symbol_2.perspective_sample, .linear_center=tint_symbol_2.linear_center, .linear_centroid=tint_symbol_2.linear_centroid, .linear_sample=tint_symbol_2.linear_sample, .pos=tint_symbol_2.pos};
-  return tint_symbol_3;
+  return tint_symbol_2;
+}
+
+vertex tint_symbol_1 tint_symbol() {
+  Out const inner_result = tint_symbol_inner();
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.pos = inner_result.pos;
+  wrapper_result.none = inner_result.none;
+  wrapper_result.flat = inner_result.flat;
+  wrapper_result.perspective_center = inner_result.perspective_center;
+  wrapper_result.perspective_centroid = inner_result.perspective_centroid;
+  wrapper_result.perspective_sample = inner_result.perspective_sample;
+  wrapper_result.linear_center = inner_result.linear_center;
+  wrapper_result.linear_centroid = inner_result.linear_centroid;
+  wrapper_result.linear_sample = inner_result.linear_sample;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/invariant.wgsl.expected.hlsl b/test/shader_io/invariant.wgsl.expected.hlsl
index 4597e8d..63c6c9a 100644
--- a/test/shader_io/invariant.wgsl.expected.hlsl
+++ b/test/shader_io/invariant.wgsl.expected.hlsl
@@ -2,7 +2,13 @@
   precise float4 value : SV_Position;
 };
 
+float4 main_inner() {
+  return float4(0.0f, 0.0f, 0.0f, 0.0f);
+}
+
 tint_symbol main() {
-  const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)};
-  return tint_symbol_1;
+  const float4 inner_result = main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
diff --git a/test/shader_io/invariant.wgsl.expected.msl b/test/shader_io/invariant.wgsl.expected.msl
index 5543bd0..c9eb97e 100644
--- a/test/shader_io/invariant.wgsl.expected.msl
+++ b/test/shader_io/invariant.wgsl.expected.msl
@@ -5,8 +5,14 @@
   float4 value [[position]] [[invariant]];
 };
 
+float4 tint_symbol_inner() {
+  return float4();
+}
+
 vertex tint_symbol_1 tint_symbol() {
-  tint_symbol_1 const tint_symbol_2 = {.value=float4()};
-  return tint_symbol_2;
+  float4 const inner_result = tint_symbol_inner();
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/invariant_struct_member.wgsl.expected.hlsl b/test/shader_io/invariant_struct_member.wgsl.expected.hlsl
index 9090f0e..b99e552 100644
--- a/test/shader_io/invariant_struct_member.wgsl.expected.hlsl
+++ b/test/shader_io/invariant_struct_member.wgsl.expected.hlsl
@@ -5,8 +5,14 @@
   precise float4 pos : SV_Position;
 };
 
-tint_symbol main() {
+Out main_inner() {
   const Out tint_symbol_1 = (Out)0;
-  const tint_symbol tint_symbol_2 = {tint_symbol_1.pos};
-  return tint_symbol_2;
+  return tint_symbol_1;
+}
+
+tint_symbol main() {
+  const Out inner_result = main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.pos = inner_result.pos;
+  return wrapper_result;
 }
diff --git a/test/shader_io/invariant_struct_member.wgsl.expected.msl b/test/shader_io/invariant_struct_member.wgsl.expected.msl
index 545642e..a2c44a7d 100644
--- a/test/shader_io/invariant_struct_member.wgsl.expected.msl
+++ b/test/shader_io/invariant_struct_member.wgsl.expected.msl
@@ -8,9 +8,15 @@
   float4 pos [[position]] [[invariant]];
 };
 
-vertex tint_symbol_1 tint_symbol() {
+Out tint_symbol_inner() {
   Out const tint_symbol_2 = {};
-  tint_symbol_1 const tint_symbol_3 = {.pos=tint_symbol_2.pos};
-  return tint_symbol_3;
+  return tint_symbol_2;
+}
+
+vertex tint_symbol_1 tint_symbol() {
+  Out const inner_result = tint_symbol_inner();
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.pos = inner_result.pos;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/shared_struct_different_stages.wgsl.expected.hlsl b/test/shader_io/shared_struct_different_stages.wgsl.expected.hlsl
index 2adabe5..6bb2f0a 100644
--- a/test/shader_io/shared_struct_different_stages.wgsl.expected.hlsl
+++ b/test/shader_io/shared_struct_different_stages.wgsl.expected.hlsl
@@ -9,21 +9,33 @@
   float4 pos : SV_Position;
 };
 
-tint_symbol vert_main() {
-  const Interface tint_symbol_1 = {0.400000006f, 0.600000024f, float4(0.0f, 0.0f, 0.0f, 0.0f)};
-  const tint_symbol tint_symbol_4 = {tint_symbol_1.col1, tint_symbol_1.col2, tint_symbol_1.pos};
-  return tint_symbol_4;
+Interface vert_main_inner() {
+  const Interface tint_symbol_3 = {0.400000006f, 0.600000024f, float4(0.0f, 0.0f, 0.0f, 0.0f)};
+  return tint_symbol_3;
 }
 
-struct tint_symbol_3 {
+tint_symbol vert_main() {
+  const Interface inner_result = vert_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.col1 = inner_result.col1;
+  wrapper_result.col2 = inner_result.col2;
+  wrapper_result.pos = inner_result.pos;
+  return wrapper_result;
+}
+
+struct tint_symbol_2 {
   float col1 : TEXCOORD1;
   float col2 : TEXCOORD2;
   float4 pos : SV_Position;
 };
 
-void frag_main(tint_symbol_3 tint_symbol_2) {
-  const Interface colors = {tint_symbol_2.col1, tint_symbol_2.col2, tint_symbol_2.pos};
+void frag_main_inner(Interface colors) {
   const float r = colors.col1;
   const float g = colors.col2;
+}
+
+void frag_main(tint_symbol_2 tint_symbol_1) {
+  const Interface tint_symbol_4 = {tint_symbol_1.col1, tint_symbol_1.col2, tint_symbol_1.pos};
+  frag_main_inner(tint_symbol_4);
   return;
 }
diff --git a/test/shader_io/shared_struct_different_stages.wgsl.expected.msl b/test/shader_io/shared_struct_different_stages.wgsl.expected.msl
index f51829c..c4388b7 100644
--- a/test/shader_io/shared_struct_different_stages.wgsl.expected.msl
+++ b/test/shader_io/shared_struct_different_stages.wgsl.expected.msl
@@ -11,21 +11,33 @@
   float col2 [[user(locn2)]];
   float4 pos [[position]];
 };
-struct tint_symbol_4 {
+struct tint_symbol_2 {
   float col1 [[user(locn1)]];
   float col2 [[user(locn2)]];
 };
 
-vertex tint_symbol vert_main() {
-  Interface const tint_symbol_1 = {.col1=0.400000006f, .col2=0.600000024f, .pos=float4()};
-  tint_symbol const tint_symbol_5 = {.col1=tint_symbol_1.col1, .col2=tint_symbol_1.col2, .pos=tint_symbol_1.pos};
-  return tint_symbol_5;
+Interface vert_main_inner() {
+  Interface const tint_symbol_3 = {.col1=0.400000006f, .col2=0.600000024f, .pos=float4()};
+  return tint_symbol_3;
 }
 
-fragment void frag_main(float4 tint_symbol_3 [[position]], tint_symbol_4 tint_symbol_2 [[stage_in]]) {
-  Interface const colors = {.col1=tint_symbol_2.col1, .col2=tint_symbol_2.col2, .pos=tint_symbol_3};
+vertex tint_symbol vert_main() {
+  Interface const inner_result = vert_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.col1 = inner_result.col1;
+  wrapper_result.col2 = inner_result.col2;
+  wrapper_result.pos = inner_result.pos;
+  return wrapper_result;
+}
+
+void frag_main_inner(Interface colors) {
   float const r = colors.col1;
   float const g = colors.col2;
+}
+
+fragment void frag_main(float4 pos [[position]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
+  Interface const tint_symbol_4 = {.col1=tint_symbol_1.col1, .col2=tint_symbol_1.col2, .pos=pos};
+  frag_main_inner(tint_symbol_4);
   return;
 }
 
diff --git a/test/shader_io/shared_struct_helper_function.wgsl.expected.hlsl b/test/shader_io/shared_struct_helper_function.wgsl.expected.hlsl
index 8e85183..8ee4d8e 100644
--- a/test/shader_io/shared_struct_helper_function.wgsl.expected.hlsl
+++ b/test/shader_io/shared_struct_helper_function.wgsl.expected.hlsl
@@ -4,8 +4,8 @@
 };
 
 VertexOutput foo(float x) {
-  const VertexOutput tint_symbol_4 = {float4(x, x, x, 1.0f), 42};
-  return tint_symbol_4;
+  const VertexOutput tint_symbol_2 = {float4(x, x, x, 1.0f), 42};
+  return tint_symbol_2;
 }
 
 struct tint_symbol {
@@ -13,19 +13,31 @@
   float4 pos : SV_Position;
 };
 
-tint_symbol vert_main1() {
-  const VertexOutput tint_symbol_1 = foo(0.5f);
-  const tint_symbol tint_symbol_5 = {tint_symbol_1.loc0, tint_symbol_1.pos};
-  return tint_symbol_5;
+VertexOutput vert_main1_inner() {
+  return foo(0.5f);
 }
 
-struct tint_symbol_2 {
+tint_symbol vert_main1() {
+  const VertexOutput inner_result = vert_main1_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.pos = inner_result.pos;
+  wrapper_result.loc0 = inner_result.loc0;
+  return wrapper_result;
+}
+
+struct tint_symbol_1 {
   int loc0 : TEXCOORD0;
   float4 pos : SV_Position;
 };
 
-tint_symbol_2 vert_main2() {
-  const VertexOutput tint_symbol_3 = foo(0.25f);
-  const tint_symbol_2 tint_symbol_6 = {tint_symbol_3.loc0, tint_symbol_3.pos};
-  return tint_symbol_6;
+VertexOutput vert_main2_inner() {
+  return foo(0.25f);
+}
+
+tint_symbol_1 vert_main2() {
+  const VertexOutput inner_result_1 = vert_main2_inner();
+  tint_symbol_1 wrapper_result_1 = (tint_symbol_1)0;
+  wrapper_result_1.pos = inner_result_1.pos;
+  wrapper_result_1.loc0 = inner_result_1.loc0;
+  return wrapper_result_1;
 }
diff --git a/test/shader_io/shared_struct_helper_function.wgsl.expected.msl b/test/shader_io/shared_struct_helper_function.wgsl.expected.msl
index 8131dfe..b07dab7 100644
--- a/test/shader_io/shared_struct_helper_function.wgsl.expected.msl
+++ b/test/shader_io/shared_struct_helper_function.wgsl.expected.msl
@@ -9,25 +9,37 @@
   int loc0 [[user(locn0)]];
   float4 pos [[position]];
 };
-struct tint_symbol_2 {
+struct tint_symbol_1 {
   int loc0 [[user(locn0)]];
   float4 pos [[position]];
 };
 
 VertexOutput foo(float x) {
-  VertexOutput const tint_symbol_4 = {.pos=float4(x, x, x, 1.0f), .loc0=42};
-  return tint_symbol_4;
+  VertexOutput const tint_symbol_2 = {.pos=float4(x, x, x, 1.0f), .loc0=42};
+  return tint_symbol_2;
+}
+
+VertexOutput vert_main1_inner() {
+  return foo(0.5f);
 }
 
 vertex tint_symbol vert_main1() {
-  VertexOutput const tint_symbol_1 = foo(0.5f);
-  tint_symbol const tint_symbol_5 = {.loc0=tint_symbol_1.loc0, .pos=tint_symbol_1.pos};
-  return tint_symbol_5;
+  VertexOutput const inner_result = vert_main1_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.pos = inner_result.pos;
+  wrapper_result.loc0 = inner_result.loc0;
+  return wrapper_result;
 }
 
-vertex tint_symbol_2 vert_main2() {
-  VertexOutput const tint_symbol_3 = foo(0.25f);
-  tint_symbol_2 const tint_symbol_6 = {.loc0=tint_symbol_3.loc0, .pos=tint_symbol_3.pos};
-  return tint_symbol_6;
+VertexOutput vert_main2_inner() {
+  return foo(0.25f);
+}
+
+vertex tint_symbol_1 vert_main2() {
+  VertexOutput const inner_result_1 = vert_main2_inner();
+  tint_symbol_1 wrapper_result_1 = {};
+  wrapper_result_1.pos = inner_result_1.pos;
+  wrapper_result_1.loc0 = inner_result_1.loc0;
+  return wrapper_result_1;
 }
 
diff --git a/test/shader_io/shared_struct_storage_buffer.wgsl.expected.hlsl b/test/shader_io/shared_struct_storage_buffer.wgsl.expected.hlsl
index c06b40f..788f1f9 100644
--- a/test/shader_io/shared_struct_storage_buffer.wgsl.expected.hlsl
+++ b/test/shader_io/shared_struct_storage_buffer.wgsl.expected.hlsl
@@ -18,11 +18,15 @@
   buffer.Store4((offset + 128u), asuint(value.v));
 }
 
-void frag_main(tint_symbol_1 tint_symbol) {
-  const S input = {tint_symbol.f, tint_symbol.u, tint_symbol.v};
+void frag_main_inner(S input) {
   const float f = input.f;
   const uint u = input.u;
   const float4 v = input.v;
   tint_symbol_2(output, 0u, input);
+}
+
+void frag_main(tint_symbol_1 tint_symbol) {
+  const S tint_symbol_6 = {tint_symbol.f, tint_symbol.u, tint_symbol.v};
+  frag_main_inner(tint_symbol_6);
   return;
 }
diff --git a/test/shader_io/shared_struct_storage_buffer.wgsl.expected.msl b/test/shader_io/shared_struct_storage_buffer.wgsl.expected.msl
index 17fece7..b4d0a25 100644
--- a/test/shader_io/shared_struct_storage_buffer.wgsl.expected.msl
+++ b/test/shader_io/shared_struct_storage_buffer.wgsl.expected.msl
@@ -8,17 +8,21 @@
   /* 0x0080 */ packed_float4 v;
   /* 0x0090 */ int8_t tint_pad_1[112];
 };
-struct tint_symbol_2 {
+struct tint_symbol_1 {
   float f [[user(locn0)]];
   uint u [[user(locn1)]];
 };
 
-fragment void frag_main(float4 tint_symbol_1 [[position]], tint_symbol_2 tint_symbol [[stage_in]], device S& output [[buffer(0)]]) {
-  S const input = {.f=tint_symbol.f, .u=tint_symbol.u, .v=tint_symbol_1};
+void frag_main_inner(device S& output, S input) {
   float const f = input.f;
   uint const u = input.u;
   float4 const v = input.v;
   output = input;
+}
+
+fragment void frag_main(float4 v [[position]], tint_symbol_1 tint_symbol [[stage_in]], device S& output [[buffer(0)]]) {
+  S const tint_symbol_2 = {.f=tint_symbol.f, .u=tint_symbol.u, .v=v};
+  frag_main_inner(output, tint_symbol_2);
   return;
 }
 
diff --git a/test/shader_io/vertex_input_builtins.wgsl.expected.hlsl b/test/shader_io/vertex_input_builtins.wgsl.expected.hlsl
index 8a9ad02..9917425 100644
--- a/test/shader_io/vertex_input_builtins.wgsl.expected.hlsl
+++ b/test/shader_io/vertex_input_builtins.wgsl.expected.hlsl
@@ -6,10 +6,14 @@
   float4 value : SV_Position;
 };
 
-tint_symbol_2 main(tint_symbol_1 tint_symbol) {
-  const uint vertex_index = tint_symbol.vertex_index;
-  const uint instance_index = tint_symbol.instance_index;
+float4 main_inner(uint vertex_index, uint instance_index) {
   const uint foo = (vertex_index + instance_index);
-  const tint_symbol_2 tint_symbol_3 = {float4(0.0f, 0.0f, 0.0f, 0.0f)};
-  return tint_symbol_3;
+  return float4(0.0f, 0.0f, 0.0f, 0.0f);
+}
+
+tint_symbol_2 main(tint_symbol_1 tint_symbol) {
+  const float4 inner_result = main_inner(tint_symbol.vertex_index, tint_symbol.instance_index);
+  tint_symbol_2 wrapper_result = (tint_symbol_2)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
diff --git a/test/shader_io/vertex_input_builtins.wgsl.expected.msl b/test/shader_io/vertex_input_builtins.wgsl.expected.msl
index f3cff19..1ef825b 100644
--- a/test/shader_io/vertex_input_builtins.wgsl.expected.msl
+++ b/test/shader_io/vertex_input_builtins.wgsl.expected.msl
@@ -1,13 +1,19 @@
 #include <metal_stdlib>
 
 using namespace metal;
-struct tint_symbol_2 {
+struct tint_symbol_1 {
   float4 value [[position]];
 };
 
-vertex tint_symbol_2 tint_symbol(uint vertex_index [[vertex_id]], uint instance_index [[instance_id]]) {
+float4 tint_symbol_inner(uint vertex_index, uint instance_index) {
   uint const foo = (vertex_index + instance_index);
-  tint_symbol_2 const tint_symbol_3 = {.value=float4()};
-  return tint_symbol_3;
+  return float4();
+}
+
+vertex tint_symbol_1 tint_symbol(uint vertex_index [[vertex_id]], uint instance_index [[instance_id]]) {
+  float4 const inner_result = tint_symbol_inner(vertex_index, instance_index);
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/vertex_input_builtins_struct.wgsl.expected.hlsl b/test/shader_io/vertex_input_builtins_struct.wgsl.expected.hlsl
index cce7374..87f19d6 100644
--- a/test/shader_io/vertex_input_builtins_struct.wgsl.expected.hlsl
+++ b/test/shader_io/vertex_input_builtins_struct.wgsl.expected.hlsl
@@ -10,9 +10,15 @@
   float4 value : SV_Position;
 };
 
-tint_symbol_2 main(tint_symbol_1 tint_symbol) {
-  const VertexInputs inputs = {tint_symbol.vertex_index, tint_symbol.instance_index};
+float4 main_inner(VertexInputs inputs) {
   const uint foo = (inputs.vertex_index + inputs.instance_index);
-  const tint_symbol_2 tint_symbol_3 = {float4(0.0f, 0.0f, 0.0f, 0.0f)};
-  return tint_symbol_3;
+  return float4(0.0f, 0.0f, 0.0f, 0.0f);
+}
+
+tint_symbol_2 main(tint_symbol_1 tint_symbol) {
+  const VertexInputs tint_symbol_3 = {tint_symbol.vertex_index, tint_symbol.instance_index};
+  const float4 inner_result = main_inner(tint_symbol_3);
+  tint_symbol_2 wrapper_result = (tint_symbol_2)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
diff --git a/test/shader_io/vertex_input_builtins_struct.wgsl.expected.msl b/test/shader_io/vertex_input_builtins_struct.wgsl.expected.msl
index c973c83..bd97441 100644
--- a/test/shader_io/vertex_input_builtins_struct.wgsl.expected.msl
+++ b/test/shader_io/vertex_input_builtins_struct.wgsl.expected.msl
@@ -5,14 +5,20 @@
   uint vertex_index;
   uint instance_index;
 };
-struct tint_symbol_4 {
+struct tint_symbol_1 {
   float4 value [[position]];
 };
 
-vertex tint_symbol_4 tint_symbol(uint tint_symbol_2 [[vertex_id]], uint tint_symbol_3 [[instance_id]]) {
-  VertexInputs const inputs = {.vertex_index=tint_symbol_2, .instance_index=tint_symbol_3};
+float4 tint_symbol_inner(VertexInputs inputs) {
   uint const foo = (inputs.vertex_index + inputs.instance_index);
-  tint_symbol_4 const tint_symbol_5 = {.value=float4()};
-  return tint_symbol_5;
+  return float4();
+}
+
+vertex tint_symbol_1 tint_symbol(uint vertex_index [[vertex_id]], uint instance_index [[instance_id]]) {
+  VertexInputs const tint_symbol_2 = {.vertex_index=vertex_index, .instance_index=instance_index};
+  float4 const inner_result = tint_symbol_inner(tint_symbol_2);
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/vertex_input_locations.wgsl.expected.hlsl b/test/shader_io/vertex_input_locations.wgsl.expected.hlsl
index e604ee9..94c8220 100644
--- a/test/shader_io/vertex_input_locations.wgsl.expected.hlsl
+++ b/test/shader_io/vertex_input_locations.wgsl.expected.hlsl
@@ -8,15 +8,17 @@
   float4 value : SV_Position;
 };
 
-tint_symbol_2 main(tint_symbol_1 tint_symbol) {
-  const int loc0 = tint_symbol.loc0;
-  const uint loc1 = tint_symbol.loc1;
-  const float loc2 = tint_symbol.loc2;
-  const float4 loc3 = tint_symbol.loc3;
+float4 main_inner(int loc0, uint loc1, float loc2, float4 loc3) {
   const int i = loc0;
   const uint u = loc1;
   const float f = loc2;
   const float4 v = loc3;
-  const tint_symbol_2 tint_symbol_3 = {float4(0.0f, 0.0f, 0.0f, 0.0f)};
-  return tint_symbol_3;
+  return float4(0.0f, 0.0f, 0.0f, 0.0f);
+}
+
+tint_symbol_2 main(tint_symbol_1 tint_symbol) {
+  const float4 inner_result = main_inner(tint_symbol.loc0, tint_symbol.loc1, tint_symbol.loc2, tint_symbol.loc3);
+  tint_symbol_2 wrapper_result = (tint_symbol_2)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
diff --git a/test/shader_io/vertex_input_locations.wgsl.expected.msl b/test/shader_io/vertex_input_locations.wgsl.expected.msl
index 4055450..a7e8658 100644
--- a/test/shader_io/vertex_input_locations.wgsl.expected.msl
+++ b/test/shader_io/vertex_input_locations.wgsl.expected.msl
@@ -11,16 +11,18 @@
   float4 value [[position]];
 };
 
-vertex tint_symbol_3 tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
-  int const loc0 = tint_symbol_1.loc0;
-  uint const loc1 = tint_symbol_1.loc1;
-  float const loc2 = tint_symbol_1.loc2;
-  float4 const loc3 = tint_symbol_1.loc3;
+float4 tint_symbol_inner(int loc0, uint loc1, float loc2, float4 loc3) {
   int const i = loc0;
   uint const u = loc1;
   float const f = loc2;
   float4 const v = loc3;
-  tint_symbol_3 const tint_symbol_4 = {.value=float4()};
-  return tint_symbol_4;
+  return float4();
+}
+
+vertex tint_symbol_3 tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
+  float4 const inner_result = tint_symbol_inner(tint_symbol_1.loc0, tint_symbol_1.loc1, tint_symbol_1.loc2, tint_symbol_1.loc3);
+  tint_symbol_3 wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/vertex_input_locations_struct.wgsl.expected.hlsl b/test/shader_io/vertex_input_locations_struct.wgsl.expected.hlsl
index f94ffc2..733014d 100644
--- a/test/shader_io/vertex_input_locations_struct.wgsl.expected.hlsl
+++ b/test/shader_io/vertex_input_locations_struct.wgsl.expected.hlsl
@@ -14,12 +14,18 @@
   float4 value : SV_Position;
 };
 
-tint_symbol_2 main(tint_symbol_1 tint_symbol) {
-  const VertexInputs inputs = {tint_symbol.loc0, tint_symbol.loc1, tint_symbol.loc2, tint_symbol.loc3};
+float4 main_inner(VertexInputs inputs) {
   const int i = inputs.loc0;
   const uint u = inputs.loc1;
   const float f = inputs.loc2;
   const float4 v = inputs.loc3;
-  const tint_symbol_2 tint_symbol_3 = {float4(0.0f, 0.0f, 0.0f, 0.0f)};
-  return tint_symbol_3;
+  return float4(0.0f, 0.0f, 0.0f, 0.0f);
+}
+
+tint_symbol_2 main(tint_symbol_1 tint_symbol) {
+  const VertexInputs tint_symbol_3 = {tint_symbol.loc0, tint_symbol.loc1, tint_symbol.loc2, tint_symbol.loc3};
+  const float4 inner_result = main_inner(tint_symbol_3);
+  tint_symbol_2 wrapper_result = (tint_symbol_2)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
diff --git a/test/shader_io/vertex_input_locations_struct.wgsl.expected.msl b/test/shader_io/vertex_input_locations_struct.wgsl.expected.msl
index 7b033dc..c85b7f9 100644
--- a/test/shader_io/vertex_input_locations_struct.wgsl.expected.msl
+++ b/test/shader_io/vertex_input_locations_struct.wgsl.expected.msl
@@ -17,13 +17,19 @@
   float4 value [[position]];
 };
 
-vertex tint_symbol_3 tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
-  VertexInputs const inputs = {.loc0=tint_symbol_1.loc0, .loc1=tint_symbol_1.loc1, .loc2=tint_symbol_1.loc2, .loc3=tint_symbol_1.loc3};
+float4 tint_symbol_inner(VertexInputs inputs) {
   int const i = inputs.loc0;
   uint const u = inputs.loc1;
   float const f = inputs.loc2;
   float4 const v = inputs.loc3;
-  tint_symbol_3 const tint_symbol_4 = {.value=float4()};
-  return tint_symbol_4;
+  return float4();
+}
+
+vertex tint_symbol_3 tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
+  VertexInputs const tint_symbol_4 = {.loc0=tint_symbol_1.loc0, .loc1=tint_symbol_1.loc1, .loc2=tint_symbol_1.loc2, .loc3=tint_symbol_1.loc3};
+  float4 const inner_result = tint_symbol_inner(tint_symbol_4);
+  tint_symbol_3 wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/vertex_input_mixed.wgsl.expected.hlsl b/test/shader_io/vertex_input_mixed.wgsl.expected.hlsl
index 4b37ed7..916f00f 100644
--- a/test/shader_io/vertex_input_mixed.wgsl.expected.hlsl
+++ b/test/shader_io/vertex_input_mixed.wgsl.expected.hlsl
@@ -18,16 +18,20 @@
   float4 value : SV_Position;
 };
 
-tint_symbol_2 main(tint_symbol_1 tint_symbol) {
-  const VertexInputs0 inputs0 = {tint_symbol.vertex_index, tint_symbol.loc0};
-  const uint loc1 = tint_symbol.loc1;
-  const uint instance_index = tint_symbol.instance_index;
-  const VertexInputs1 inputs1 = {tint_symbol.loc2, tint_symbol.loc3};
+float4 main_inner(VertexInputs0 inputs0, uint loc1, uint instance_index, VertexInputs1 inputs1) {
   const uint foo = (inputs0.vertex_index + instance_index);
   const int i = inputs0.loc0;
   const uint u = loc1;
   const float f = inputs1.loc2;
   const float4 v = inputs1.loc3;
-  const tint_symbol_2 tint_symbol_3 = {float4(0.0f, 0.0f, 0.0f, 0.0f)};
-  return tint_symbol_3;
+  return float4(0.0f, 0.0f, 0.0f, 0.0f);
+}
+
+tint_symbol_2 main(tint_symbol_1 tint_symbol) {
+  const VertexInputs0 tint_symbol_3 = {tint_symbol.vertex_index, tint_symbol.loc0};
+  const VertexInputs1 tint_symbol_4 = {tint_symbol.loc2, tint_symbol.loc3};
+  const float4 inner_result = main_inner(tint_symbol_3, tint_symbol.loc1, tint_symbol.instance_index, tint_symbol_4);
+  tint_symbol_2 wrapper_result = (tint_symbol_2)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
diff --git a/test/shader_io/vertex_input_mixed.wgsl.expected.msl b/test/shader_io/vertex_input_mixed.wgsl.expected.msl
index 9c1e813..07dd9b9 100644
--- a/test/shader_io/vertex_input_mixed.wgsl.expected.msl
+++ b/test/shader_io/vertex_input_mixed.wgsl.expected.msl
@@ -9,26 +9,31 @@
   float loc2;
   float4 loc3;
 };
-struct tint_symbol_3 {
+struct tint_symbol_2 {
   int loc0 [[attribute(0)]];
   uint loc1 [[attribute(1)]];
   float loc2 [[attribute(2)]];
   float4 loc3 [[attribute(3)]];
 };
-struct tint_symbol_4 {
+struct tint_symbol_3 {
   float4 value [[position]];
 };
 
-vertex tint_symbol_4 tint_symbol(uint tint_symbol_2 [[vertex_id]], uint instance_index [[instance_id]], tint_symbol_3 tint_symbol_1 [[stage_in]]) {
-  VertexInputs0 const inputs0 = {.vertex_index=tint_symbol_2, .loc0=tint_symbol_1.loc0};
-  uint const loc1 = tint_symbol_1.loc1;
-  VertexInputs1 const inputs1 = {.loc2=tint_symbol_1.loc2, .loc3=tint_symbol_1.loc3};
+float4 tint_symbol_inner(VertexInputs0 inputs0, uint loc1, uint instance_index, VertexInputs1 inputs1) {
   uint const foo = (inputs0.vertex_index + instance_index);
   int const i = inputs0.loc0;
   uint const u = loc1;
   float const f = inputs1.loc2;
   float4 const v = inputs1.loc3;
-  tint_symbol_4 const tint_symbol_5 = {.value=float4()};
-  return tint_symbol_5;
+  return float4();
+}
+
+vertex tint_symbol_3 tint_symbol(uint vertex_index [[vertex_id]], uint instance_index [[instance_id]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
+  VertexInputs0 const tint_symbol_4 = {.vertex_index=vertex_index, .loc0=tint_symbol_1.loc0};
+  VertexInputs1 const tint_symbol_5 = {.loc2=tint_symbol_1.loc2, .loc3=tint_symbol_1.loc3};
+  float4 const inner_result = tint_symbol_inner(tint_symbol_4, tint_symbol_1.loc1, instance_index, tint_symbol_5);
+  tint_symbol_3 wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/vertex_output_builtins.wgsl.expected.hlsl b/test/shader_io/vertex_output_builtins.wgsl.expected.hlsl
index 5a48b14..d08b5d5 100644
--- a/test/shader_io/vertex_output_builtins.wgsl.expected.hlsl
+++ b/test/shader_io/vertex_output_builtins.wgsl.expected.hlsl
@@ -2,7 +2,13 @@
   float4 value : SV_Position;
 };
 
+float4 main_inner() {
+  return float4(1.0f, 2.0f, 3.0f, 4.0f);
+}
+
 tint_symbol main() {
-  const tint_symbol tint_symbol_1 = {float4(1.0f, 2.0f, 3.0f, 4.0f)};
-  return tint_symbol_1;
+  const float4 inner_result = main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
diff --git a/test/shader_io/vertex_output_builtins.wgsl.expected.msl b/test/shader_io/vertex_output_builtins.wgsl.expected.msl
index 1bc7c1c..37e950f 100644
--- a/test/shader_io/vertex_output_builtins.wgsl.expected.msl
+++ b/test/shader_io/vertex_output_builtins.wgsl.expected.msl
@@ -5,8 +5,14 @@
   float4 value [[position]];
 };
 
+float4 tint_symbol_inner() {
+  return float4(1.0f, 2.0f, 3.0f, 4.0f);
+}
+
 vertex tint_symbol_1 tint_symbol() {
-  tint_symbol_1 const tint_symbol_2 = {.value=float4(1.0f, 2.0f, 3.0f, 4.0f)};
-  return tint_symbol_2;
+  float4 const inner_result = tint_symbol_inner();
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/vertex_output_builtins_struct.wgsl.expected.hlsl b/test/shader_io/vertex_output_builtins_struct.wgsl.expected.hlsl
index 064dd8a..eeaba96 100644
--- a/test/shader_io/vertex_output_builtins_struct.wgsl.expected.hlsl
+++ b/test/shader_io/vertex_output_builtins_struct.wgsl.expected.hlsl
@@ -5,8 +5,14 @@
   float4 position : SV_Position;
 };
 
-tint_symbol main() {
+VertexOutputs main_inner() {
   const VertexOutputs tint_symbol_1 = {float4(1.0f, 2.0f, 3.0f, 4.0f)};
-  const tint_symbol tint_symbol_2 = {tint_symbol_1.position};
-  return tint_symbol_2;
+  return tint_symbol_1;
+}
+
+tint_symbol main() {
+  const VertexOutputs inner_result = main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.position = inner_result.position;
+  return wrapper_result;
 }
diff --git a/test/shader_io/vertex_output_builtins_struct.wgsl.expected.msl b/test/shader_io/vertex_output_builtins_struct.wgsl.expected.msl
index 24ea7ac..d077ccc7 100644
--- a/test/shader_io/vertex_output_builtins_struct.wgsl.expected.msl
+++ b/test/shader_io/vertex_output_builtins_struct.wgsl.expected.msl
@@ -8,9 +8,15 @@
   float4 position [[position]];
 };
 
-vertex tint_symbol_1 tint_symbol() {
+VertexOutputs tint_symbol_inner() {
   VertexOutputs const tint_symbol_2 = {.position=float4(1.0f, 2.0f, 3.0f, 4.0f)};
-  tint_symbol_1 const tint_symbol_3 = {.position=tint_symbol_2.position};
-  return tint_symbol_3;
+  return tint_symbol_2;
+}
+
+vertex tint_symbol_1 tint_symbol() {
+  VertexOutputs const inner_result = tint_symbol_inner();
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.position = inner_result.position;
+  return wrapper_result;
 }
 
diff --git a/test/shader_io/vertex_output_locations_struct.wgsl.expected.hlsl b/test/shader_io/vertex_output_locations_struct.wgsl.expected.hlsl
index 4d62928..301487d 100644
--- a/test/shader_io/vertex_output_locations_struct.wgsl.expected.hlsl
+++ b/test/shader_io/vertex_output_locations_struct.wgsl.expected.hlsl
@@ -13,8 +13,18 @@
   float4 position : SV_Position;
 };
 
-tint_symbol main() {
+VertexOutputs main_inner() {
   const VertexOutputs tint_symbol_1 = {1, 1u, 1.0f, float4(1.0f, 2.0f, 3.0f, 4.0f), float4(0.0f, 0.0f, 0.0f, 0.0f)};
-  const tint_symbol tint_symbol_2 = {tint_symbol_1.loc0, tint_symbol_1.loc1, tint_symbol_1.loc2, tint_symbol_1.loc3, tint_symbol_1.position};
-  return tint_symbol_2;
+  return tint_symbol_1;
+}
+
+tint_symbol main() {
+  const VertexOutputs inner_result = main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.loc0 = inner_result.loc0;
+  wrapper_result.loc1 = inner_result.loc1;
+  wrapper_result.loc2 = inner_result.loc2;
+  wrapper_result.loc3 = inner_result.loc3;
+  wrapper_result.position = inner_result.position;
+  return wrapper_result;
 }
diff --git a/test/shader_io/vertex_output_locations_struct.wgsl.expected.msl b/test/shader_io/vertex_output_locations_struct.wgsl.expected.msl
index b56fad9..40d177a 100644
--- a/test/shader_io/vertex_output_locations_struct.wgsl.expected.msl
+++ b/test/shader_io/vertex_output_locations_struct.wgsl.expected.msl
@@ -16,9 +16,19 @@
   float4 position [[position]];
 };
 
-vertex tint_symbol_1 tint_symbol() {
+VertexOutputs tint_symbol_inner() {
   VertexOutputs const tint_symbol_2 = {.loc0=1, .loc1=1u, .loc2=1.0f, .loc3=float4(1.0f, 2.0f, 3.0f, 4.0f), .position=float4()};
-  tint_symbol_1 const tint_symbol_3 = {.loc0=tint_symbol_2.loc0, .loc1=tint_symbol_2.loc1, .loc2=tint_symbol_2.loc2, .loc3=tint_symbol_2.loc3, .position=tint_symbol_2.position};
-  return tint_symbol_3;
+  return tint_symbol_2;
+}
+
+vertex tint_symbol_1 tint_symbol() {
+  VertexOutputs const inner_result = tint_symbol_inner();
+  tint_symbol_1 wrapper_result = {};
+  wrapper_result.loc0 = inner_result.loc0;
+  wrapper_result.loc1 = inner_result.loc1;
+  wrapper_result.loc2 = inner_result.loc2;
+  wrapper_result.loc3 = inner_result.loc3;
+  wrapper_result.position = inner_result.position;
+  return wrapper_result;
 }