MSL: Support argument buffers and image swizzling.

Change aux buffer to swizzle buffer.
There is no good reason to expand the aux buffer, so name it
appropriately.

Make the code cleaner by emitting a straight pointer to uint rather than
a dummy struct which only contains a single unsized array member anyways.

This will also end up being very similar to how we implement swizzle
buffers for argument buffers.

Do not use implied binding if it overflows int32_t.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0be765e..d1fc028 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -267,7 +267,7 @@
 
 if (SPIRV_CROSS_SHARED)
 	set(spirv-cross-abi-major 0)
-	set(spirv-cross-abi-minor 7)
+	set(spirv-cross-abi-minor 8)
 	set(spirv-cross-abi-patch 0)
 	set(SPIRV_CROSS_VERSION ${spirv-cross-abi-major}.${spirv-cross-abi-minor}.${spirv-cross-abi-patch})
 	set(SPIRV_CROSS_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/lib)
diff --git a/reference/opt/shaders-msl/comp/force-recompile-hooks.swizzle.comp b/reference/opt/shaders-msl/comp/force-recompile-hooks.swizzle.comp
index c06d8ba..2d9d423 100644
--- a/reference/opt/shaders-msl/comp/force-recompile-hooks.swizzle.comp
+++ b/reference/opt/shaders-msl/comp/force-recompile-hooks.swizzle.comp
@@ -5,11 +5,6 @@
 
 using namespace metal;
 
-struct spvAux
-{
-    uint swizzleConst[1];
-};
-
 enum class spvSwizzle : uint
 {
     none = 0,
@@ -130,9 +125,9 @@
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-kernel void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
+kernel void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
 {
-    constant uint32_t& fooSwzl = spvAuxBuffer.swizzleConst[0];
+    constant uint32_t& fooSwzl = spvSwizzleConstants[0];
     bar.write(spvTextureSwizzle(foo.sample(fooSmplr, float2(1.0), level(0.0)), fooSwzl), uint2(int2(0)));
 }
 
diff --git a/reference/opt/shaders-msl/frag/array-of-texture-swizzle.msl2.argument.discrete.swizzle.frag b/reference/opt/shaders-msl/frag/array-of-texture-swizzle.msl2.argument.discrete.swizzle.frag
new file mode 100644
index 0000000..b8e8f9d
--- /dev/null
+++ b/reference/opt/shaders-msl/frag/array-of-texture-swizzle.msl2.argument.discrete.swizzle.frag
@@ -0,0 +1,156 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct spvDescriptorSetBuffer0
+{
+    constant uint* spvSwizzleConstants [[id(0)]];
+    array<texture2d<float>, 4> uSampler0 [[id(1)]];
+    array<sampler, 4> uSampler0Smplr [[id(5)]];
+};
+
+struct main0_out
+{
+    float4 FragColor [[color(0)]];
+};
+
+struct main0_in
+{
+    float2 vUV [[user(locn0)]];
+};
+
+enum class spvSwizzle : uint
+{
+    none = 0,
+    zero,
+    one,
+    red,
+    green,
+    blue,
+    alpha
+};
+
+template<typename T> struct spvRemoveReference { typedef T type; };
+template<typename T> struct spvRemoveReference<thread T&> { typedef T type; };
+template<typename T> struct spvRemoveReference<thread T&&> { typedef T type; };
+template<typename T> inline constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type& x)
+{
+    return static_cast<thread T&&>(x);
+}
+template<typename T> inline constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type&& x)
+{
+    return static_cast<thread T&&>(x);
+}
+
+template<typename T>
+inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
+{
+    switch (s)
+    {
+        case spvSwizzle::none:
+            return c;
+        case spvSwizzle::zero:
+            return 0;
+        case spvSwizzle::one:
+            return 1;
+        case spvSwizzle::red:
+            return x.r;
+        case spvSwizzle::green:
+            return x.g;
+        case spvSwizzle::blue:
+            return x.b;
+        case spvSwizzle::alpha:
+            return x.a;
+    }
+}
+
+// Wrapper function that swizzles texture samples and fetches.
+template<typename T>
+inline vec<T, 4> spvTextureSwizzle(vec<T, 4> x, uint s)
+{
+    if (!s)
+        return x;
+    return vec<T, 4>(spvGetSwizzle(x, x.r, spvSwizzle((s >> 0) & 0xFF)), spvGetSwizzle(x, x.g, spvSwizzle((s >> 8) & 0xFF)), spvGetSwizzle(x, x.b, spvSwizzle((s >> 16) & 0xFF)), spvGetSwizzle(x, x.a, spvSwizzle((s >> 24) & 0xFF)));
+}
+
+template<typename T>
+inline T spvTextureSwizzle(T x, uint s)
+{
+    return spvTextureSwizzle(vec<T, 4>(x, 0, 0, 1), s).x;
+}
+
+// Wrapper function that swizzles texture gathers.
+template<typename T, typename Tex, typename... Ts>
+inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
+{
+    if (sw)
+    {
+        switch (spvSwizzle((sw >> (uint(c) * 8)) & 0xFF))
+        {
+            case spvSwizzle::none:
+                break;
+            case spvSwizzle::zero:
+                return vec<T, 4>(0, 0, 0, 0);
+            case spvSwizzle::one:
+                return vec<T, 4>(1, 1, 1, 1);
+            case spvSwizzle::red:
+                return t.gather(s, spvForward<Ts>(params)..., component::x);
+            case spvSwizzle::green:
+                return t.gather(s, spvForward<Ts>(params)..., component::y);
+            case spvSwizzle::blue:
+                return t.gather(s, spvForward<Ts>(params)..., component::z);
+            case spvSwizzle::alpha:
+                return t.gather(s, spvForward<Ts>(params)..., component::w);
+        }
+    }
+    switch (c)
+    {
+        case component::x:
+            return t.gather(s, spvForward<Ts>(params)..., component::x);
+        case component::y:
+            return t.gather(s, spvForward<Ts>(params)..., component::y);
+        case component::z:
+            return t.gather(s, spvForward<Ts>(params)..., component::z);
+        case component::w:
+            return t.gather(s, spvForward<Ts>(params)..., component::w);
+    }
+}
+
+// Wrapper function that swizzles depth texture gathers.
+template<typename T, typename Tex, typename... Ts>
+inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw) 
+{
+    if (sw)
+    {
+        switch (spvSwizzle(sw & 0xFF))
+        {
+            case spvSwizzle::none:
+            case spvSwizzle::red:
+                break;
+            case spvSwizzle::zero:
+            case spvSwizzle::green:
+            case spvSwizzle::blue:
+            case spvSwizzle::alpha:
+                return vec<T, 4>(0, 0, 0, 0);
+            case spvSwizzle::one:
+                return vec<T, 4>(1, 1, 1, 1);
+        }
+    }
+    return t.gather_compare(s, spvForward<Ts>(params)...);
+}
+
+fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], constant uint* spvSwizzleConstants [[buffer(30)]], texture2d<float> uSampler1 [[texture(0)]], sampler uSampler1Smplr [[sampler(0)]])
+{
+    main0_out out = {};
+    constant uint32_t* spvDescriptorSet0_uSampler0Swzl = &spvDescriptorSet0.spvSwizzleConstants[1];
+    constant uint32_t& uSampler1Swzl = spvSwizzleConstants[0];
+    out.FragColor = spvTextureSwizzle(spvDescriptorSet0.uSampler0[2].sample(spvDescriptorSet0.uSampler0Smplr[2], in.vUV), spvDescriptorSet0_uSampler0Swzl[2]);
+    out.FragColor += spvTextureSwizzle(uSampler1.sample(uSampler1Smplr, in.vUV), uSampler1Swzl);
+    out.FragColor += spvTextureSwizzle(spvDescriptorSet0.uSampler0[1].sample(spvDescriptorSet0.uSampler0Smplr[1], in.vUV), spvDescriptorSet0_uSampler0Swzl[1]);
+    out.FragColor += spvTextureSwizzle(uSampler1.sample(uSampler1Smplr, in.vUV), uSampler1Swzl);
+    return out;
+}
+
diff --git a/reference/opt/shaders-msl/frag/array-of-texture-swizzle.msl2.swizzle.frag b/reference/opt/shaders-msl/frag/array-of-texture-swizzle.msl2.swizzle.frag
index 9a03e1f..8e97cab 100644
--- a/reference/opt/shaders-msl/frag/array-of-texture-swizzle.msl2.swizzle.frag
+++ b/reference/opt/shaders-msl/frag/array-of-texture-swizzle.msl2.swizzle.frag
@@ -5,11 +5,6 @@
 
 using namespace metal;
 
-struct spvAux
-{
-    uint swizzleConst[1];
-};
-
 struct main0_out
 {
     float4 FragColor [[color(0)]];
@@ -140,10 +135,10 @@
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-fragment main0_out main0(main0_in in [[stage_in]], constant spvAux& spvAuxBuffer [[buffer(30)]], array<texture2d<float>, 4> uSampler [[texture(0)]], array<sampler, 4> uSamplerSmplr [[sampler(0)]])
+fragment main0_out main0(main0_in in [[stage_in]], constant uint* spvSwizzleConstants [[buffer(30)]], array<texture2d<float>, 4> uSampler [[texture(0)]], array<sampler, 4> uSamplerSmplr [[sampler(0)]])
 {
     main0_out out = {};
-    constant uint32_t* uSamplerSwzl = &spvAuxBuffer.swizzleConst[0];
+    constant uint32_t* uSamplerSwzl = &spvSwizzleConstants[0];
     out.FragColor = spvTextureSwizzle(uSampler[2].sample(uSamplerSmplr[2], in.vUV), uSamplerSwzl[2]);
     out.FragColor += spvTextureSwizzle(uSampler[1].sample(uSamplerSmplr[1], in.vUV), uSamplerSwzl[1]);
     return out;
diff --git a/reference/shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag b/reference/shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag
index ea433e1..68445b7 100644
--- a/reference/shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag
+++ b/reference/shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag
@@ -5,11 +5,6 @@
 
 using namespace metal;
 
-struct spvAux
-{
-    uint swizzleConst[1];
-};
-
 // Returns 2D texture coords corresponding to 1D texel buffer coords
 uint2 spvTexelBufferCoord(uint tc)
 {
@@ -136,18 +131,18 @@
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-fragment void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSamp [[sampler(0)]], sampler tex2dSamp [[sampler(1)]], sampler tex3dSamp [[sampler(2)]], sampler texCubeSamp [[sampler(3)]], sampler tex2dArraySamp [[sampler(4)]], sampler texCubeArraySamp [[sampler(5)]], sampler depth2dSamp [[sampler(7)]], sampler depthCubeSamp [[sampler(8)]], sampler depth2dArraySamp [[sampler(9)]], sampler depthCubeArraySamp [[sampler(10)]])
+fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSamp [[sampler(0)]], sampler tex2dSamp [[sampler(1)]], sampler tex3dSamp [[sampler(2)]], sampler texCubeSamp [[sampler(3)]], sampler tex2dArraySamp [[sampler(4)]], sampler texCubeArraySamp [[sampler(5)]], sampler depth2dSamp [[sampler(7)]], sampler depthCubeSamp [[sampler(8)]], sampler depth2dArraySamp [[sampler(9)]], sampler depthCubeArraySamp [[sampler(10)]])
 {
-    constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
-    constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];
-    constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2];
-    constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3];
-    constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4];
-    constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5];
-    constant uint32_t& depth2dSwzl = spvAuxBuffer.swizzleConst[7];
-    constant uint32_t& depthCubeSwzl = spvAuxBuffer.swizzleConst[8];
-    constant uint32_t& depth2dArraySwzl = spvAuxBuffer.swizzleConst[9];
-    constant uint32_t& depthCubeArraySwzl = spvAuxBuffer.swizzleConst[10];
+    constant uint32_t& tex1dSwzl = spvSwizzleConstants[0];
+    constant uint32_t& tex2dSwzl = spvSwizzleConstants[1];
+    constant uint32_t& tex3dSwzl = spvSwizzleConstants[2];
+    constant uint32_t& texCubeSwzl = spvSwizzleConstants[3];
+    constant uint32_t& tex2dArraySwzl = spvSwizzleConstants[4];
+    constant uint32_t& texCubeArraySwzl = spvSwizzleConstants[5];
+    constant uint32_t& depth2dSwzl = spvSwizzleConstants[7];
+    constant uint32_t& depthCubeSwzl = spvSwizzleConstants[8];
+    constant uint32_t& depth2dArraySwzl = spvSwizzleConstants[9];
+    constant uint32_t& depthCubeArraySwzl = spvSwizzleConstants[10];
     float4 c = spvTextureSwizzle(tex1d.sample(tex1dSamp, 0.0), tex1dSwzl);
     c = spvTextureSwizzle(tex2d.sample(tex2dSamp, float2(0.0)), tex2dSwzl);
     c = spvTextureSwizzle(tex3d.sample(tex3dSamp, float3(0.0)), tex3dSwzl);
diff --git a/reference/shaders-msl-no-opt/frag/texture-access-int.swizzle.frag b/reference/shaders-msl-no-opt/frag/texture-access-int.swizzle.frag
index 997d5b5..3f854e7 100644
--- a/reference/shaders-msl-no-opt/frag/texture-access-int.swizzle.frag
+++ b/reference/shaders-msl-no-opt/frag/texture-access-int.swizzle.frag
@@ -5,11 +5,6 @@
 
 using namespace metal;
 
-struct spvAux
-{
-    uint swizzleConst[1];
-};
-
 // Returns 2D texture coords corresponding to 1D texel buffer coords
 uint2 spvTexelBufferCoord(uint tc)
 {
@@ -136,14 +131,14 @@
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-fragment void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<int> tex1d [[texture(0)]], texture2d<int> tex2d [[texture(1)]], texture3d<int> tex3d [[texture(2)]], texturecube<int> texCube [[texture(3)]], texture2d_array<int> tex2dArray [[texture(4)]], texturecube_array<int> texCubeArray [[texture(5)]], texture2d<int> texBuffer [[texture(6)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]])
+fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d<int> tex1d [[texture(0)]], texture2d<int> tex2d [[texture(1)]], texture3d<int> tex3d [[texture(2)]], texturecube<int> texCube [[texture(3)]], texture2d_array<int> tex2dArray [[texture(4)]], texturecube_array<int> texCubeArray [[texture(5)]], texture2d<int> texBuffer [[texture(6)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]])
 {
-    constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
-    constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];
-    constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2];
-    constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3];
-    constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4];
-    constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5];
+    constant uint32_t& tex1dSwzl = spvSwizzleConstants[0];
+    constant uint32_t& tex2dSwzl = spvSwizzleConstants[1];
+    constant uint32_t& tex3dSwzl = spvSwizzleConstants[2];
+    constant uint32_t& texCubeSwzl = spvSwizzleConstants[3];
+    constant uint32_t& tex2dArraySwzl = spvSwizzleConstants[4];
+    constant uint32_t& texCubeArraySwzl = spvSwizzleConstants[5];
     float4 c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl));
     c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), tex2dSwzl));
     c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), tex3dSwzl));
diff --git a/reference/shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag b/reference/shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag
index 076dcc1..01a5ae6 100644
--- a/reference/shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag
+++ b/reference/shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag
@@ -5,11 +5,6 @@
 
 using namespace metal;
 
-struct spvAux
-{
-    uint swizzleConst[1];
-};
-
 // Returns 2D texture coords corresponding to 1D texel buffer coords
 uint2 spvTexelBufferCoord(uint tc)
 {
@@ -183,18 +178,18 @@
     return c;
 }
 
-fragment void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depth2dArraySmplr [[sampler(9)]], sampler depthCubeArraySmplr [[sampler(10)]])
+fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depth2dArraySmplr [[sampler(9)]], sampler depthCubeArraySmplr [[sampler(10)]])
 {
-    constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
-    constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];
-    constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2];
-    constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3];
-    constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4];
-    constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5];
-    constant uint32_t& depth2dSwzl = spvAuxBuffer.swizzleConst[7];
-    constant uint32_t& depthCubeSwzl = spvAuxBuffer.swizzleConst[8];
-    constant uint32_t& depth2dArraySwzl = spvAuxBuffer.swizzleConst[9];
-    constant uint32_t& depthCubeArraySwzl = spvAuxBuffer.swizzleConst[10];
+    constant uint32_t& tex1dSwzl = spvSwizzleConstants[0];
+    constant uint32_t& tex2dSwzl = spvSwizzleConstants[1];
+    constant uint32_t& tex3dSwzl = spvSwizzleConstants[2];
+    constant uint32_t& texCubeSwzl = spvSwizzleConstants[3];
+    constant uint32_t& tex2dArraySwzl = spvSwizzleConstants[4];
+    constant uint32_t& texCubeArraySwzl = spvSwizzleConstants[5];
+    constant uint32_t& depth2dSwzl = spvSwizzleConstants[7];
+    constant uint32_t& depthCubeSwzl = spvSwizzleConstants[8];
+    constant uint32_t& depth2dArraySwzl = spvSwizzleConstants[9];
+    constant uint32_t& depthCubeArraySwzl = spvSwizzleConstants[10];
     float4 c = doSwizzle(tex1d, tex1dSmplr, tex1dSwzl, tex2d, tex2dSmplr, tex2dSwzl, tex3d, tex3dSmplr, tex3dSwzl, texCube, texCubeSmplr, texCubeSwzl, tex2dArray, tex2dArraySmplr, tex2dArraySwzl, texCubeArray, texCubeArraySmplr, texCubeArraySwzl, depth2d, depth2dSmplr, depth2dSwzl, depthCube, depthCubeSmplr, depthCubeSwzl, depth2dArray, depth2dArraySmplr, depth2dArraySwzl, depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, texBuffer);
 }
 
diff --git a/reference/shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag b/reference/shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag
index 81ffec7..5a3013b 100644
--- a/reference/shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag
+++ b/reference/shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag
@@ -5,11 +5,6 @@
 
 using namespace metal;
 
-struct spvAux
-{
-    uint swizzleConst[1];
-};
-
 // Returns 2D texture coords corresponding to 1D texel buffer coords
 uint2 spvTexelBufferCoord(uint tc)
 {
@@ -136,14 +131,14 @@
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-fragment void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<uint> tex1d [[texture(0)]], texture2d<uint> tex2d [[texture(1)]], texture3d<uint> tex3d [[texture(2)]], texturecube<uint> texCube [[texture(3)]], texture2d_array<uint> tex2dArray [[texture(4)]], texturecube_array<uint> texCubeArray [[texture(5)]], texture2d<uint> texBuffer [[texture(6)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]])
+fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d<uint> tex1d [[texture(0)]], texture2d<uint> tex2d [[texture(1)]], texture3d<uint> tex3d [[texture(2)]], texturecube<uint> texCube [[texture(3)]], texture2d_array<uint> tex2dArray [[texture(4)]], texturecube_array<uint> texCubeArray [[texture(5)]], texture2d<uint> texBuffer [[texture(6)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]])
 {
-    constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
-    constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];
-    constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2];
-    constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3];
-    constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4];
-    constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5];
+    constant uint32_t& tex1dSwzl = spvSwizzleConstants[0];
+    constant uint32_t& tex2dSwzl = spvSwizzleConstants[1];
+    constant uint32_t& tex3dSwzl = spvSwizzleConstants[2];
+    constant uint32_t& texCubeSwzl = spvSwizzleConstants[3];
+    constant uint32_t& tex2dArraySwzl = spvSwizzleConstants[4];
+    constant uint32_t& texCubeArraySwzl = spvSwizzleConstants[5];
     float4 c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl));
     c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), tex2dSwzl));
     c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), tex3dSwzl));
diff --git a/reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag b/reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag
index 98ab50e..befee5b 100644
--- a/reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag
+++ b/reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag
@@ -5,11 +5,6 @@
 
 using namespace metal;
 
-struct spvAux
-{
-    uint swizzleConst[1];
-};
-
 // Returns 2D texture coords corresponding to 1D texel buffer coords
 uint2 spvTexelBufferCoord(uint tc)
 {
@@ -136,18 +131,18 @@
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-fragment void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depth2dArraySmplr [[sampler(9)]], sampler depthCubeArraySmplr [[sampler(10)]])
+fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depth2dArraySmplr [[sampler(9)]], sampler depthCubeArraySmplr [[sampler(10)]])
 {
-    constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
-    constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];
-    constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2];
-    constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3];
-    constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4];
-    constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5];
-    constant uint32_t& depth2dSwzl = spvAuxBuffer.swizzleConst[7];
-    constant uint32_t& depthCubeSwzl = spvAuxBuffer.swizzleConst[8];
-    constant uint32_t& depth2dArraySwzl = spvAuxBuffer.swizzleConst[9];
-    constant uint32_t& depthCubeArraySwzl = spvAuxBuffer.swizzleConst[10];
+    constant uint32_t& tex1dSwzl = spvSwizzleConstants[0];
+    constant uint32_t& tex2dSwzl = spvSwizzleConstants[1];
+    constant uint32_t& tex3dSwzl = spvSwizzleConstants[2];
+    constant uint32_t& texCubeSwzl = spvSwizzleConstants[3];
+    constant uint32_t& tex2dArraySwzl = spvSwizzleConstants[4];
+    constant uint32_t& texCubeArraySwzl = spvSwizzleConstants[5];
+    constant uint32_t& depth2dSwzl = spvSwizzleConstants[7];
+    constant uint32_t& depthCubeSwzl = spvSwizzleConstants[8];
+    constant uint32_t& depth2dArraySwzl = spvSwizzleConstants[9];
+    constant uint32_t& depthCubeArraySwzl = spvSwizzleConstants[10];
     float4 c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl);
     c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), tex2dSwzl);
     c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), tex3dSwzl);
diff --git a/reference/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag b/reference/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag
index e99cd69..aa3aae2 100644
--- a/reference/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag
+++ b/reference/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag
@@ -5,11 +5,6 @@
 
 using namespace metal;
 
-struct spvAux
-{
-    uint swizzleConst[1];
-};
-
 struct main0_out
 {
     float4 fragColor [[color(0)]];
@@ -188,19 +183,19 @@
     return c;
 }
 
-fragment main0_out main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex3dSmplr [[sampler(2)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depthCubeArraySmplr [[sampler(10)]], sampler defaultSampler [[sampler(11)]], sampler shadowSampler [[sampler(12)]])
+fragment main0_out main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex3dSmplr [[sampler(2)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depthCubeArraySmplr [[sampler(10)]], sampler defaultSampler [[sampler(11)]], sampler shadowSampler [[sampler(12)]])
 {
     main0_out out = {};
-    constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
-    constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];
-    constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2];
-    constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3];
-    constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4];
-    constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5];
-    constant uint32_t& depth2dSwzl = spvAuxBuffer.swizzleConst[7];
-    constant uint32_t& depthCubeSwzl = spvAuxBuffer.swizzleConst[8];
-    constant uint32_t& depth2dArraySwzl = spvAuxBuffer.swizzleConst[9];
-    constant uint32_t& depthCubeArraySwzl = spvAuxBuffer.swizzleConst[10];
+    constant uint32_t& tex1dSwzl = spvSwizzleConstants[0];
+    constant uint32_t& tex2dSwzl = spvSwizzleConstants[1];
+    constant uint32_t& tex3dSwzl = spvSwizzleConstants[2];
+    constant uint32_t& texCubeSwzl = spvSwizzleConstants[3];
+    constant uint32_t& tex2dArraySwzl = spvSwizzleConstants[4];
+    constant uint32_t& texCubeArraySwzl = spvSwizzleConstants[5];
+    constant uint32_t& depth2dSwzl = spvSwizzleConstants[7];
+    constant uint32_t& depthCubeSwzl = spvSwizzleConstants[8];
+    constant uint32_t& depth2dArraySwzl = spvSwizzleConstants[9];
+    constant uint32_t& depthCubeArraySwzl = spvSwizzleConstants[10];
     out.fragColor = do_samples(tex1d, tex1dSmplr, tex1dSwzl, tex2d, tex2dSwzl, tex3d, tex3dSmplr, tex3dSwzl, texCube, texCubeSwzl, tex2dArray, tex2dArraySmplr, tex2dArraySwzl, texCubeArray, texCubeArraySmplr, texCubeArraySwzl, texBuffer, depth2d, depth2dSmplr, depth2dSwzl, depthCube, depthCubeSmplr, depthCubeSwzl, depth2dArray, depth2dArraySwzl, depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, defaultSampler, shadowSampler);
     return out;
 }
diff --git a/reference/shaders-msl/comp/force-recompile-hooks.swizzle.comp b/reference/shaders-msl/comp/force-recompile-hooks.swizzle.comp
index d8b4af7..b784940 100644
--- a/reference/shaders-msl/comp/force-recompile-hooks.swizzle.comp
+++ b/reference/shaders-msl/comp/force-recompile-hooks.swizzle.comp
@@ -5,11 +5,6 @@
 
 using namespace metal;
 
-struct spvAux
-{
-    uint swizzleConst[1];
-};
-
 enum class spvSwizzle : uint
 {
     none = 0,
@@ -130,9 +125,9 @@
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-kernel void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
+kernel void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
 {
-    constant uint32_t& fooSwzl = spvAuxBuffer.swizzleConst[0];
+    constant uint32_t& fooSwzl = spvSwizzleConstants[0];
     float4 a = spvTextureSwizzle(foo.sample(fooSmplr, float2(1.0), level(0.0)), fooSwzl);
     bar.write(a, uint2(int2(0)));
 }
diff --git a/reference/shaders-msl/frag/array-of-texture-swizzle.msl2.argument.discrete.swizzle.frag b/reference/shaders-msl/frag/array-of-texture-swizzle.msl2.argument.discrete.swizzle.frag
new file mode 100644
index 0000000..5e749b3
--- /dev/null
+++ b/reference/shaders-msl/frag/array-of-texture-swizzle.msl2.argument.discrete.swizzle.frag
@@ -0,0 +1,171 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct spvDescriptorSetBuffer0
+{
+    constant uint* spvSwizzleConstants [[id(0)]];
+    array<texture2d<float>, 4> uSampler0 [[id(1)]];
+    array<sampler, 4> uSampler0Smplr [[id(5)]];
+};
+
+struct main0_out
+{
+    float4 FragColor [[color(0)]];
+};
+
+struct main0_in
+{
+    float2 vUV [[user(locn0)]];
+};
+
+enum class spvSwizzle : uint
+{
+    none = 0,
+    zero,
+    one,
+    red,
+    green,
+    blue,
+    alpha
+};
+
+template<typename T> struct spvRemoveReference { typedef T type; };
+template<typename T> struct spvRemoveReference<thread T&> { typedef T type; };
+template<typename T> struct spvRemoveReference<thread T&&> { typedef T type; };
+template<typename T> inline constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type& x)
+{
+    return static_cast<thread T&&>(x);
+}
+template<typename T> inline constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type&& x)
+{
+    return static_cast<thread T&&>(x);
+}
+
+template<typename T>
+inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
+{
+    switch (s)
+    {
+        case spvSwizzle::none:
+            return c;
+        case spvSwizzle::zero:
+            return 0;
+        case spvSwizzle::one:
+            return 1;
+        case spvSwizzle::red:
+            return x.r;
+        case spvSwizzle::green:
+            return x.g;
+        case spvSwizzle::blue:
+            return x.b;
+        case spvSwizzle::alpha:
+            return x.a;
+    }
+}
+
+// Wrapper function that swizzles texture samples and fetches.
+template<typename T>
+inline vec<T, 4> spvTextureSwizzle(vec<T, 4> x, uint s)
+{
+    if (!s)
+        return x;
+    return vec<T, 4>(spvGetSwizzle(x, x.r, spvSwizzle((s >> 0) & 0xFF)), spvGetSwizzle(x, x.g, spvSwizzle((s >> 8) & 0xFF)), spvGetSwizzle(x, x.b, spvSwizzle((s >> 16) & 0xFF)), spvGetSwizzle(x, x.a, spvSwizzle((s >> 24) & 0xFF)));
+}
+
+template<typename T>
+inline T spvTextureSwizzle(T x, uint s)
+{
+    return spvTextureSwizzle(vec<T, 4>(x, 0, 0, 1), s).x;
+}
+
+// Wrapper function that swizzles texture gathers.
+template<typename T, typename Tex, typename... Ts>
+inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
+{
+    if (sw)
+    {
+        switch (spvSwizzle((sw >> (uint(c) * 8)) & 0xFF))
+        {
+            case spvSwizzle::none:
+                break;
+            case spvSwizzle::zero:
+                return vec<T, 4>(0, 0, 0, 0);
+            case spvSwizzle::one:
+                return vec<T, 4>(1, 1, 1, 1);
+            case spvSwizzle::red:
+                return t.gather(s, spvForward<Ts>(params)..., component::x);
+            case spvSwizzle::green:
+                return t.gather(s, spvForward<Ts>(params)..., component::y);
+            case spvSwizzle::blue:
+                return t.gather(s, spvForward<Ts>(params)..., component::z);
+            case spvSwizzle::alpha:
+                return t.gather(s, spvForward<Ts>(params)..., component::w);
+        }
+    }
+    switch (c)
+    {
+        case component::x:
+            return t.gather(s, spvForward<Ts>(params)..., component::x);
+        case component::y:
+            return t.gather(s, spvForward<Ts>(params)..., component::y);
+        case component::z:
+            return t.gather(s, spvForward<Ts>(params)..., component::z);
+        case component::w:
+            return t.gather(s, spvForward<Ts>(params)..., component::w);
+    }
+}
+
+// Wrapper function that swizzles depth texture gathers.
+template<typename T, typename Tex, typename... Ts>
+inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw) 
+{
+    if (sw)
+    {
+        switch (spvSwizzle(sw & 0xFF))
+        {
+            case spvSwizzle::none:
+            case spvSwizzle::red:
+                break;
+            case spvSwizzle::zero:
+            case spvSwizzle::green:
+            case spvSwizzle::blue:
+            case spvSwizzle::alpha:
+                return vec<T, 4>(0, 0, 0, 0);
+            case spvSwizzle::one:
+                return vec<T, 4>(1, 1, 1, 1);
+        }
+    }
+    return t.gather_compare(s, spvForward<Ts>(params)...);
+}
+
+float4 sample_in_func_1(thread const array<texture2d<float>, 4> uSampler0, thread const array<sampler, 4> uSampler0Smplr, constant uint32_t* uSampler0Swzl, thread float2& vUV)
+{
+    return spvTextureSwizzle(uSampler0[2].sample(uSampler0Smplr[2], vUV), uSampler0Swzl[2]);
+}
+
+float4 sample_in_func_2(thread float2& vUV, thread texture2d<float> uSampler1, thread const sampler uSampler1Smplr, constant uint32_t& uSampler1Swzl)
+{
+    return spvTextureSwizzle(uSampler1.sample(uSampler1Smplr, vUV), uSampler1Swzl);
+}
+
+float4 sample_single_in_func(thread const texture2d<float> s, thread const sampler sSmplr, constant uint32_t& sSwzl, thread float2& vUV)
+{
+    return spvTextureSwizzle(s.sample(sSmplr, vUV), sSwzl);
+}
+
+fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], constant uint* spvSwizzleConstants [[buffer(30)]], texture2d<float> uSampler1 [[texture(0)]], sampler uSampler1Smplr [[sampler(0)]])
+{
+    main0_out out = {};
+    constant uint32_t* spvDescriptorSet0_uSampler0Swzl = &spvDescriptorSet0.spvSwizzleConstants[1];
+    constant uint32_t& uSampler1Swzl = spvSwizzleConstants[0];
+    out.FragColor = sample_in_func_1(spvDescriptorSet0.uSampler0, spvDescriptorSet0.uSampler0Smplr, spvDescriptorSet0_uSampler0Swzl, in.vUV);
+    out.FragColor += sample_in_func_2(in.vUV, uSampler1, uSampler1Smplr, uSampler1Swzl);
+    out.FragColor += sample_single_in_func(spvDescriptorSet0.uSampler0[1], spvDescriptorSet0.uSampler0Smplr[1], spvDescriptorSet0_uSampler0Swzl[1], in.vUV);
+    out.FragColor += sample_single_in_func(uSampler1, uSampler1Smplr, uSampler1Swzl, in.vUV);
+    return out;
+}
+
diff --git a/reference/shaders-msl/frag/array-of-texture-swizzle.msl2.swizzle.frag b/reference/shaders-msl/frag/array-of-texture-swizzle.msl2.swizzle.frag
index 39d059c..0e4972c 100644
--- a/reference/shaders-msl/frag/array-of-texture-swizzle.msl2.swizzle.frag
+++ b/reference/shaders-msl/frag/array-of-texture-swizzle.msl2.swizzle.frag
@@ -5,11 +5,6 @@
 
 using namespace metal;
 
-struct spvAux
-{
-    uint swizzleConst[1];
-};
-
 struct main0_out
 {
     float4 FragColor [[color(0)]];
@@ -150,10 +145,10 @@
     return spvTextureSwizzle(s.sample(sSmplr, vUV), sSwzl);
 }
 
-fragment main0_out main0(main0_in in [[stage_in]], constant spvAux& spvAuxBuffer [[buffer(30)]], array<texture2d<float>, 4> uSampler [[texture(0)]], array<sampler, 4> uSamplerSmplr [[sampler(0)]])
+fragment main0_out main0(main0_in in [[stage_in]], constant uint* spvSwizzleConstants [[buffer(30)]], array<texture2d<float>, 4> uSampler [[texture(0)]], array<sampler, 4> uSamplerSmplr [[sampler(0)]])
 {
     main0_out out = {};
-    constant uint32_t* uSamplerSwzl = &spvAuxBuffer.swizzleConst[0];
+    constant uint32_t* uSamplerSwzl = &spvSwizzleConstants[0];
     out.FragColor = sample_in_func(uSampler, uSamplerSmplr, uSamplerSwzl, in.vUV);
     out.FragColor += sample_single_in_func(uSampler[1], uSamplerSmplr[1], uSamplerSwzl[1], in.vUV);
     return out;
diff --git a/shaders-msl/frag/array-of-texture-swizzle.msl2.argument.discrete.swizzle.frag b/shaders-msl/frag/array-of-texture-swizzle.msl2.argument.discrete.swizzle.frag
new file mode 100644
index 0000000..556cc9c
--- /dev/null
+++ b/shaders-msl/frag/array-of-texture-swizzle.msl2.argument.discrete.swizzle.frag
@@ -0,0 +1,31 @@
+#version 450
+
+layout(set = 0, binding = 1) uniform sampler2D uSampler0[4];
+layout(set = 2, binding = 0) uniform sampler2D uSampler1;
+layout(set = 1, binding = 4) uniform sampler2D uSamp;
+layout(location = 0) in vec2 vUV;
+
+layout(location = 0) out vec4 FragColor;
+
+vec4 sample_in_func_1()
+{
+	return texture(uSampler0[2], vUV);
+}
+
+vec4 sample_in_func_2()
+{
+	return texture(uSampler1, vUV);
+}
+
+vec4 sample_single_in_func(sampler2D s)
+{
+	return texture(s, vUV);
+}
+
+void main()
+{
+	FragColor = sample_in_func_1();
+	FragColor += sample_in_func_2();
+	FragColor += sample_single_in_func(uSampler0[1]);
+	FragColor += sample_single_in_func(uSampler1);
+}
diff --git a/spirv_cross_c.cpp b/spirv_cross_c.cpp
index 7d77754..92d622a 100644
--- a/spirv_cross_c.cpp
+++ b/spirv_cross_c.cpp
@@ -474,8 +474,8 @@
 		options->msl.texel_buffer_texture_width = value;
 		break;
 
-	case SPVC_COMPILER_OPTION_MSL_AUX_BUFFER_INDEX:
-		options->msl.aux_buffer_index = value;
+	case SPVC_COMPILER_OPTION_MSL_SWIZZLE_BUFFER_INDEX:
+		options->msl.swizzle_buffer_index = value;
 		break;
 
 	case SPVC_COMPILER_OPTION_MSL_INDIRECT_PARAMS_BUFFER_INDEX:
@@ -726,7 +726,7 @@
 #endif
 }
 
-spvc_bool spvc_compiler_msl_needs_aux_buffer(spvc_compiler compiler)
+spvc_bool spvc_compiler_msl_needs_swizzle_buffer(spvc_compiler compiler)
 {
 #if SPIRV_CROSS_C_API_MSL
 	if (compiler->backend != SPVC_BACKEND_MSL)
@@ -736,13 +736,18 @@
 	}
 
 	auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
-	return msl.needs_aux_buffer() ? SPVC_TRUE : SPVC_FALSE;
+	return msl.needs_swizzle_buffer() ? SPVC_TRUE : SPVC_FALSE;
 #else
 	compiler->context->report_error("MSL function used on a non-MSL backend.");
 	return SPVC_FALSE;
 #endif
 }
 
+spvc_bool spvc_compiler_msl_needs_aux_buffer(spvc_compiler compiler)
+{
+	return spvc_compiler_msl_needs_swizzle_buffer(compiler);
+}
+
 spvc_bool spvc_compiler_msl_needs_output_buffer(spvc_compiler compiler)
 {
 #if SPIRV_CROSS_C_API_MSL
diff --git a/spirv_cross_c.h b/spirv_cross_c.h
index 9e10d07..b03e60e 100644
--- a/spirv_cross_c.h
+++ b/spirv_cross_c.h
@@ -33,7 +33,7 @@
 /* Bumped if ABI or API breaks backwards compatibility. */
 #define SPVC_C_API_VERSION_MAJOR 0
 /* Bumped if APIs or enumerations are added in a backwards compatible way. */
-#define SPVC_C_API_VERSION_MINOR 7
+#define SPVC_C_API_VERSION_MINOR 8
 /* Bumped if internal implementation details change. */
 #define SPVC_C_API_VERSION_PATCH 0
 
@@ -290,9 +290,12 @@
 
 #define SPVC_MSL_PUSH_CONSTANT_DESC_SET (~(0u))
 #define SPVC_MSL_PUSH_CONSTANT_BINDING (0)
+#define SPVC_MSL_SWIZZLE_BUFFER_BINDING (~(1u))
+
+/* Obsolete. Sticks around for backwards compatibility. */
 #define SPVC_MSL_AUX_BUFFER_STRUCT_VERSION 1
 
-/* Runtime check for incompatibility. */
+/* Runtime check for incompatibility. Obsolete. */
 SPVC_PUBLIC_API unsigned spvc_msl_get_aux_buffer_struct_version(void);
 
 /* Maps to C++ API. */
@@ -407,7 +410,11 @@
 
 	SPVC_COMPILER_OPTION_MSL_VERSION = 17 | SPVC_COMPILER_OPTION_MSL_BIT,
 	SPVC_COMPILER_OPTION_MSL_TEXEL_BUFFER_TEXTURE_WIDTH = 18 | SPVC_COMPILER_OPTION_MSL_BIT,
+
+	/* Obsolete, use SWIZZLE_BUFFER_INDEX instead. */
 	SPVC_COMPILER_OPTION_MSL_AUX_BUFFER_INDEX = 19 | SPVC_COMPILER_OPTION_MSL_BIT,
+	SPVC_COMPILER_OPTION_MSL_SWIZZLE_BUFFER_INDEX = 19 | SPVC_COMPILER_OPTION_MSL_BIT,
+
 	SPVC_COMPILER_OPTION_MSL_INDIRECT_PARAMS_BUFFER_INDEX = 20 | SPVC_COMPILER_OPTION_MSL_BIT,
 	SPVC_COMPILER_OPTION_MSL_SHADER_OUTPUT_BUFFER_INDEX = 21 | SPVC_COMPILER_OPTION_MSL_BIT,
 	SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_OUTPUT_BUFFER_INDEX = 22 | SPVC_COMPILER_OPTION_MSL_BIT,
@@ -505,7 +512,11 @@
  * Maps to C++ API.
  */
 SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_rasterization_disabled(spvc_compiler compiler);
+
+/* Obsolete. Renamed to needs_swizzle_buffer. */
 SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_aux_buffer(spvc_compiler compiler);
+SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_swizzle_buffer(spvc_compiler compiler);
+
 SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_output_buffer(spvc_compiler compiler);
 SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_patch_output_buffer(spvc_compiler compiler);
 SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_input_threadgroup_mem(spvc_compiler compiler);
diff --git a/spirv_msl.cpp b/spirv_msl.cpp
index c4c75a2..1d57cce 100644
--- a/spirv_msl.cpp
+++ b/spirv_msl.cpp
@@ -28,8 +28,6 @@
 static const uint32_t k_unknown_location = ~0u;
 static const uint32_t k_unknown_component = ~0u;
 
-static const uint32_t k_aux_mbr_idx_swizzle_const = 0u;
-
 CompilerMSL::CompilerMSL(std::vector<uint32_t> spirv_)
     : CompilerGLSL(move(spirv_))
 {
@@ -387,14 +385,13 @@
 		}
 	}
 
-	if (needs_aux_buffer_def)
+	if (needs_swizzle_buffer_def)
 	{
-		uint32_t offset = ir.increase_bound_by(5);
+		uint32_t offset = ir.increase_bound_by(4);
 		uint32_t type_id = offset;
-		uint32_t type_arr_id = offset + 1;
-		uint32_t struct_id = offset + 2;
-		uint32_t struct_ptr_id = offset + 3;
-		uint32_t var_id = offset + 4;
+		uint32_t type_ptr_id = offset + 1;
+		uint32_t type_ptr_ptr_id = offset + 2;
+		uint32_t var_id = offset + 3;
 
 		// Create a buffer to hold extra data, including the swizzle constants.
 		SPIRType uint_type;
@@ -402,36 +399,25 @@
 		uint_type.width = 32;
 		set<SPIRType>(type_id, uint_type);
 
-		SPIRType uint_type_arr = uint_type;
-		uint_type_arr.array.push_back(0);
-		uint_type_arr.array_size_literal.push_back(true);
-		uint_type_arr.parent_type = type_id;
-		set<SPIRType>(type_arr_id, uint_type_arr);
-		set_decoration(type_arr_id, DecorationArrayStride, 4);
+		SPIRType uint_type_pointer = uint_type;
+		uint_type_pointer.pointer = true;
+		uint_type_pointer.pointer_depth = 1;
+		uint_type_pointer.parent_type = type_id;
+		uint_type_pointer.storage = StorageClassUniform;
+		set<SPIRType>(type_ptr_id, uint_type_pointer);
+		set_decoration(type_ptr_id, DecorationArrayStride, 4);
 
-		SPIRType struct_type;
-		struct_type.basetype = SPIRType::Struct;
-		struct_type.member_types.push_back(type_arr_id);
-		auto &type = set<SPIRType>(struct_id, struct_type);
-		type.self = struct_id;
-		set_decoration(struct_id, DecorationBlock);
-		set_name(struct_id, "spvAux");
-		set_member_name(struct_id, k_aux_mbr_idx_swizzle_const, "swizzleConst");
-		set_member_decoration(struct_id, k_aux_mbr_idx_swizzle_const, DecorationOffset, 0);
+		SPIRType uint_type_pointer2 = uint_type_pointer;
+		uint_type_pointer2.pointer_depth++;
+		uint_type_pointer2.parent_type = type_ptr_id;
+		set<SPIRType>(type_ptr_ptr_id, uint_type_pointer2);
 
-		SPIRType struct_type_ptr = struct_type;
-		struct_type_ptr.pointer = true;
-		struct_type_ptr.parent_type = struct_id;
-		struct_type_ptr.storage = StorageClassUniform;
-		auto &ptr_type = set<SPIRType>(struct_ptr_id, struct_type_ptr);
-		ptr_type.self = struct_id;
-
-		set<SPIRVariable>(var_id, struct_ptr_id, StorageClassUniform);
-		set_name(var_id, "spvAuxBuffer");
+		set<SPIRVariable>(var_id, type_ptr_ptr_id, StorageClassUniformConstant);
+		set_name(var_id, "spvSwizzleConstants");
 		// This should never match anything.
 		set_decoration(var_id, DecorationDescriptorSet, 0xFFFFFFFE);
-		set_decoration(var_id, DecorationBinding, msl_options.aux_buffer_index);
-		aux_buffer_id = var_id;
+		set_decoration(var_id, DecorationBinding, msl_options.swizzle_buffer_index);
+		swizzle_buffer_id = var_id;
 	}
 }
 
@@ -678,8 +664,8 @@
 	fixup_image_load_store_access();
 
 	set_enabled_interface_variables(get_active_interface_variables());
-	if (aux_buffer_id)
-		active_interface_variables.insert(aux_buffer_id);
+	if (swizzle_buffer_id)
+		active_interface_variables.insert(swizzle_buffer_id);
 
 	// Create structs to hold input, output and uniform variables.
 	// Do output first to ensure out. is declared at top of entry function.
@@ -4960,7 +4946,7 @@
 		if (!is_gather)
 			farg_str += ")";
 		farg_str += ", " + to_swizzle_expression(img);
-		used_aux_buffer = true;
+		used_swizzle_buffer = true;
 	}
 
 	*p_forward = forward;
@@ -5051,8 +5037,17 @@
 
 		arg_str += ", " + to_sampler_expression(var_id ? var_id : id);
 	}
+
 	if (msl_options.swizzle_texture_samples && has_sampled_images && is_sampled_image_type(type))
-		arg_str += ", " + to_swizzle_expression(id);
+	{
+		// Need to check the base variable in case we need to apply a qualified alias.
+		uint32_t var_id = 0;
+		auto *sampler_var = maybe_get<SPIRVariable>(id);
+		if (sampler_var)
+			var_id = sampler_var->basevariable;
+
+		arg_str += ", " + to_swizzle_expression(var_id ? var_id : id);
+	}
 
 	return arg_str;
 }
@@ -5083,9 +5078,15 @@
 string CompilerMSL::to_swizzle_expression(uint32_t id)
 {
 	auto *combined = maybe_get<SPIRCombinedImageSampler>(id);
+
 	auto expr = to_expression(combined ? combined->image : id);
 	auto index = expr.find_first_of('[');
 
+	// If an image is part of an argument buffer translate this to a legal identifier.
+	for (auto &c : expr)
+		if (c == '.')
+			c = '_';
+
 	if (index == string::npos)
 		return expr + swizzle_name_suffix;
 	else
@@ -5738,7 +5739,8 @@
 			else
 				return "constant";
 		}
-		break;
+		else
+			return "constant";
 
 	case StorageClassFunction:
 	case StorageClassGeneric:
@@ -6020,7 +6022,10 @@
 			ep_args += " [[texture(" + convert_to_string(r.index) + ")]]";
 			break;
 		default:
-			SPIRV_CROSS_THROW("Unexpected resource type");
+			if (!ep_args.empty())
+				ep_args += ", ";
+			ep_args += type_to_glsl(type, var_id) + " " + r.name;
+			ep_args += " [[buffer(" + convert_to_string(r.index) + ")]]";
 			break;
 		}
 	}
@@ -6056,14 +6061,23 @@
 			{
 				auto &entry_func = this->get<SPIRFunction>(ir.default_entry_point);
 				entry_func.fixup_hooks_in.push_back([this, &type, &var, var_id]() {
-					auto &aux_type = expression_type(aux_buffer_id);
 					bool is_array_type = !type.array.empty();
 
-					// If we have an array of images, we need to be able to index into it, so take a pointer instead.
-					statement("constant uint32_t", is_array_type ? "* " : "& ", to_swizzle_expression(var_id),
-					          is_array_type ? " = &" : " = ", to_name(aux_buffer_id), ".",
-					          to_member_name(aux_type, k_aux_mbr_idx_swizzle_const), "[",
-					          convert_to_string(get_metal_resource_index(var, SPIRType::Image)), "];");
+					uint32_t desc_set = get_decoration(var_id, DecorationDescriptorSet);
+					if (descriptor_set_is_argument_buffer(desc_set))
+					{
+						statement("constant uint32_t", is_array_type ? "* " : "& ", to_swizzle_expression(var_id),
+						          is_array_type ? " = &" : " = ", to_name(argument_buffer_ids[desc_set]),
+						          ".spvSwizzleConstants", "[",
+						          convert_to_string(get_metal_resource_index(var, SPIRType::Image)), "];");
+					}
+					else
+					{
+						// If we have an array of images, we need to be able to index into it, so take a pointer instead.
+						statement("constant uint32_t", is_array_type ? "* " : "& ", to_swizzle_expression(var_id),
+						          is_array_type ? " = &" : " = ", to_name(swizzle_buffer_id), "[",
+						          convert_to_string(get_metal_resource_index(var, SPIRType::Image)), "];");
+					}
 				});
 			}
 		}
@@ -6230,20 +6244,23 @@
 		itr->second = true;
 		switch (basetype)
 		{
-		case SPIRType::Struct:
-			return itr->first.msl_buffer;
 		case SPIRType::Image:
 			return itr->first.msl_texture;
 		case SPIRType::Sampler:
 			return itr->first.msl_sampler;
 		default:
-			return 0;
+			return itr->first.msl_buffer;
 		}
 	}
 
 	// If there is no explicit mapping of bindings to MSL, use the declared binding.
 	if (has_decoration(var.self, DecorationBinding))
-		return get_decoration(var.self, DecorationBinding);
+	{
+		var_binding = get_decoration(var.self, DecorationBinding);
+		// Avoid emitting sentinel bindings.
+		if (var_binding < 0x80000000u)
+			return var_binding;
+	}
 
 	uint32_t binding_stride = 1;
 	auto &type = get<SPIRType>(var.basetype);
@@ -6254,10 +6271,6 @@
 	uint32_t resource_index;
 	switch (basetype)
 	{
-	case SPIRType::Struct:
-		resource_index = next_metal_resource_index_buffer;
-		next_metal_resource_index_buffer += binding_stride;
-		break;
 	case SPIRType::Image:
 		resource_index = next_metal_resource_index_texture;
 		next_metal_resource_index_texture += binding_stride;
@@ -6267,7 +6280,8 @@
 		next_metal_resource_index_sampler += binding_stride;
 		break;
 	default:
-		resource_index = 0;
+		resource_index = next_metal_resource_index_buffer;
+		next_metal_resource_index_buffer += binding_stride;
 		break;
 	}
 	return resource_index;
@@ -7764,7 +7778,7 @@
 	case OpImageDrefGather:
 		compiler.has_sampled_images =
 		    compiler.has_sampled_images || compiler.is_sampled_image_type(compiler.expression_type(args[2]));
-		compiler.needs_aux_buffer_def = compiler.needs_aux_buffer_def || compiler.has_sampled_images;
+		compiler.needs_swizzle_buffer_def = compiler.needs_swizzle_buffer_def || compiler.has_sampled_images;
 		break;
 	default:
 		break;
@@ -8227,6 +8241,8 @@
 	};
 	SmallVector<Resource> resources_in_set[kMaxArgumentBuffers];
 
+	bool set_needs_swizzle_buffer[kMaxArgumentBuffers] = {};
+
 	ir.for_each_typed_id<SPIRVariable>([&](uint32_t self, SPIRVariable &var) {
 		if ((var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant ||
 		     var.storage == StorageClassStorageBuffer) &&
@@ -8270,9 +8286,54 @@
 				resources_in_set[desc_set].push_back(
 				    { &var, to_name(var_id), type.basetype, get_metal_resource_index(var, type.basetype) });
 			}
+
+			// Check if this descriptor set needs a swizzle buffer.
+			if (needs_swizzle_buffer_def && is_sampled_image_type(type))
+				set_needs_swizzle_buffer[desc_set] = true;
 		}
 	});
 
+	if (needs_swizzle_buffer_def)
+	{
+		uint32_t swizzle_buffer_type_id = 0;
+
+		// We might have to add a swizzle buffer resource to the set.
+		for (uint32_t desc_set = 0; desc_set < kMaxArgumentBuffers; desc_set++)
+		{
+			if (!set_needs_swizzle_buffer[desc_set])
+				continue;
+
+			if (swizzle_buffer_type_id == 0)
+			{
+				uint32_t offset = ir.increase_bound_by(2);
+				uint32_t type_id = offset;
+				swizzle_buffer_type_id = offset + 1;
+
+				// Create a buffer to hold extra data, including the swizzle constants.
+				SPIRType uint_type;
+				uint_type.basetype = SPIRType::UInt;
+				uint_type.width = 32;
+				set<SPIRType>(type_id, uint_type);
+
+				SPIRType uint_type_pointer = uint_type;
+				uint_type_pointer.pointer = true;
+				uint_type_pointer.pointer_depth = 1;
+				uint_type_pointer.parent_type = type_id;
+				uint_type_pointer.storage = StorageClassUniform;
+				set<SPIRType>(swizzle_buffer_type_id, uint_type_pointer);
+				set_decoration(swizzle_buffer_type_id, DecorationArrayStride, 4);
+			}
+
+			uint32_t var_id = ir.increase_bound_by(1);
+			auto &var = set<SPIRVariable>(var_id, swizzle_buffer_type_id, StorageClassUniformConstant);
+			set_name(var_id, "spvSwizzleConstants");
+			set_decoration(var_id, DecorationDescriptorSet, desc_set);
+			set_decoration(var_id, DecorationBinding, kSwizzleBufferBinding);
+			resources_in_set[desc_set].push_back(
+			    { &var, to_name(var_id), SPIRType::UInt, get_metal_resource_index(var, SPIRType::UInt) });
+		}
+	}
+
 	for (uint32_t desc_set = 0; desc_set < kMaxArgumentBuffers; desc_set++)
 	{
 		auto &resources = resources_in_set[desc_set];
diff --git a/spirv_msl.hpp b/spirv_msl.hpp
index e10fd2b..6e7c83c 100644
--- a/spirv_msl.hpp
+++ b/spirv_msl.hpp
@@ -152,11 +152,11 @@
 // element to indicate the bindings for the push constants.
 static const uint32_t kPushConstBinding = 0;
 
-static const uint32_t kMaxArgumentBuffers = 8;
+// Special constant used in a MSLResourceBinding binding
+// element to indicate the buffer binding for swizzle buffers.
+static const uint32_t kSwizzleBufferBinding = ~(1u);
 
-// The current version of the aux buffer structure. It must be incremented any time a
-// new field is added to the aux buffer.
-#define SPIRV_CROSS_MSL_AUX_BUFFER_STRUCT_VERSION 1
+static const uint32_t kMaxArgumentBuffers = 8;
 
 // Decompiles SPIR-V to Metal Shading Language
 class CompilerMSL : public CompilerGLSL
@@ -174,7 +174,7 @@
 		Platform platform = macOS;
 		uint32_t msl_version = make_msl_version(1, 2);
 		uint32_t texel_buffer_texture_width = 4096; // Width of 2D Metal textures used as 1D texel buffers
-		uint32_t aux_buffer_index = 30;
+		uint32_t swizzle_buffer_index = 30;
 		uint32_t indirect_params_buffer_index = 29;
 		uint32_t shader_output_buffer_index = 28;
 		uint32_t shader_patch_output_buffer_index = 27;
@@ -243,10 +243,10 @@
 	}
 
 	// Provide feedback to calling API to allow it to pass an auxiliary
-	// buffer if the shader needs it.
-	bool needs_aux_buffer() const
+	// swizzle buffer if the shader needs it.
+	bool needs_swizzle_buffer() const
 	{
-		return used_aux_buffer;
+		return used_swizzle_buffer;
 	}
 
 	// Provide feedback to calling API to allow it to pass an output
@@ -486,7 +486,7 @@
 	uint32_t builtin_primitive_id_id = 0;
 	uint32_t builtin_subgroup_invocation_id_id = 0;
 	uint32_t builtin_subgroup_size_id = 0;
-	uint32_t aux_buffer_id = 0;
+	uint32_t swizzle_buffer_id = 0;
 
 	void bitcast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override;
 	void bitcast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) override;
@@ -524,8 +524,8 @@
 	bool needs_instance_idx_arg = false;
 	bool is_rasterization_disabled = false;
 	bool capture_output_to_buffer = false;
-	bool needs_aux_buffer_def = false;
-	bool used_aux_buffer = false;
+	bool needs_swizzle_buffer_def = false;
+	bool used_swizzle_buffer = false;
 	bool added_builtin_tess_level = false;
 	bool needs_subgroup_invocation_id = false;
 	std::string qual_pos_var_name;