#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 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;
  thread tint_array<int4, 4>* dst;
  thread tint_array<tint_array<tint_array<int, 2>, 3>, 4>* dst_nested;
};

#define TINT_ISOLATE_UB(VOLATILE_NAME) \
  volatile bool VOLATILE_NAME = true; \
  if (VOLATILE_NAME)

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) = tint_array<int4, 4>{int4(1), int4(2), int4(3), int4(3)};
  (*tint_module_vars.dst) = src_param;
  (*tint_module_vars.dst) = ret_arr();
  tint_array<int4, 4> const src_let = tint_array<int4, 4>{};
  (*tint_module_vars.dst) = src_let;
  (*tint_module_vars.dst) = src_function;
  (*tint_module_vars.dst) = (*tint_module_vars.src_private);
  (*tint_module_vars.dst) = (*tint_module_vars.src_workgroup);
  (*tint_module_vars.dst) = ret_struct_arr().arr;
  (*tint_module_vars.dst) = (*tint_module_vars.src_uniform).arr;
  (*tint_module_vars.dst) = (*tint_module_vars.src_storage).arr;
  tint_array<tint_array<tint_array<int, 2>, 3>, 4> src_nested = {};
  (*tint_module_vars.dst_nested) = src_nested;
}

void tint_symbol_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
  {
    uint v = 0u;
    v = tint_local_index;
    TINT_ISOLATE_UB(tint_volatile_true) 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 a = tint_array<int4, 4>{};
  foo(a, 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)]]) {
  thread tint_array<int4, 4> src_private = {};
  thread tint_array<int4, 4> dst = {};
  thread tint_array<tint_array<tint_array<int, 2>, 3>, 4> dst_nested = {};
  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);
}
