#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 {
  /* 0x0000 */ tint_array<int4, 4> arr;
};

struct S_nested {
  /* 0x0000 */ 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(2)]], device S* dst [[buffer(1)]], 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);
}
