#pragma clang diagnostic ignored "-Wmissing-prototypes"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

template<typename T>
struct spvDescriptor
{
    T value;
};

template<typename T>
struct spvDescriptorArray
{
    spvDescriptorArray(const device spvDescriptor<T>* ptr_) : ptr(&ptr_->value) {}
    spvDescriptorArray(const device void *ptr_) : spvDescriptorArray(static_cast<const device spvDescriptor<T>*>(ptr_)) {}
    const device T& operator [] (size_t i) const { return ptr[i]; }
    const device T* ptr;
};

struct D
{
    float data_d[1];
};

struct A
{
    float data_a[1];
};

struct spvDescriptorSetBuffer0
{
    spvDescriptor<device D *> d [[id(0)]][1] /* unsized array hack */;
    // Overlapping binding: spvDescriptor<device A *> a [[id(0)]][1] /* unsized array hack */;
};

kernel void main0(device spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]])
{
    spvDescriptorArray<device D*> d {spvDescriptorSet0.d};
    spvDescriptorArray<device A*> a {reinterpret_cast<spvDescriptor<device A *> const device *>(&spvDescriptorSet0.d)};

    d[gl_WorkGroupID.x]->data_d[0] = a[gl_WorkGroupID.x]->data_a[0];
}

