#include <metal_stdlib>
using namespace metal;
template<typename T, size_t N>
struct tint_array {
  const constant T& operator[](size_t i) const constant { return elements[i]; }
  device T& operator[](size_t i) device { return elements[i]; }
  const device T& operator[](size_t i) const device { return elements[i]; }
  thread T& operator[](size_t i) thread { return elements[i]; }
  const thread T& operator[](size_t i) const thread { return elements[i]; }
  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
  T elements[N];
};

struct S {
  tint_array<int4, 4> arr;
};
struct S_nested {
  tint_array<tint_array<tint_array<int, 2>, 3>, 4> arr;
};
struct tint_module_vars_struct {
  thread tint_array<int4, 4>* src_private;
  threadgroup tint_array<int4, 4>* src_workgroup;
  const constant S* src_uniform;
  device S* src_storage;
  device S* dst;
  device S_nested* dst_nested;
};
struct tint_symbol_2 {
  tint_array<int4, 4> tint_symbol_1;
};

tint_array<int4, 4> ret_arr() {
  return tint_array<int4, 4>{};
}
S ret_struct_arr() {
  return S{};
}
void foo(tint_array<int4, 4> src_param, tint_module_vars_struct tint_module_vars) {
  tint_array<int4, 4> src_function = {};
  (*tint_module_vars.dst).arr = tint_array<int4, 4>{int4(1), int4(2), int4(3), int4(3)};
  (*tint_module_vars.dst).arr = src_param;
  (*tint_module_vars.dst).arr = ret_arr();
  tint_array<int4, 4> const src_let = tint_array<int4, 4>{};
  (*tint_module_vars.dst).arr = src_let;
  (*tint_module_vars.dst).arr = src_function;
  (*tint_module_vars.dst).arr = (*tint_module_vars.src_private);
  (*tint_module_vars.dst).arr = (*tint_module_vars.src_workgroup);
  (*tint_module_vars.dst).arr = ret_struct_arr().arr;
  (*tint_module_vars.dst).arr = (*tint_module_vars.src_uniform).arr;
  (*tint_module_vars.dst).arr = (*tint_module_vars.src_storage).arr;
  tint_array<tint_array<tint_array<int, 2>, 3>, 4> src_nested = {};
  (*tint_module_vars.dst_nested).arr = src_nested;
}
void tint_symbol_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
  {
    uint v = 0u;
    v = tint_local_index;
    while(true) {
      uint const v_1 = v;
      if ((v_1 >= 4u)) {
        break;
      }
      (*tint_module_vars.src_workgroup)[v_1] = int4(0);
      v = (v_1 + 1u);
      continue;
    }
  }
  threadgroup_barrier(mem_flags::mem_threadgroup);
  tint_array<int4, 4> const ary = tint_array<int4, 4>{};
  foo(ary, tint_module_vars);
}
kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_2* v_2 [[threadgroup(0)]], const constant S* src_uniform [[buffer(0)]], device S* src_storage [[buffer(1)]], device S* dst [[buffer(2)]], device S_nested* dst_nested [[buffer(3)]]) {
  thread tint_array<int4, 4> src_private = {};
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.src_private=(&src_private), .src_workgroup=(&(*v_2).tint_symbol_1), .src_uniform=src_uniform, .src_storage=src_storage, .dst=dst, .dst_nested=dst_nested};
  tint_symbol_inner(tint_local_index, tint_module_vars);
}
