Merge remote-tracking branch 'aosp/master-ndk' into shaderc-update

Change-Id: Iaddebd733ccc713ab80ea21a7b287ab14d837df5
diff --git a/.appveyor.yml b/.appveyor.yml
index d5c7225..07e269b 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -7,7 +7,7 @@
 os: Visual Studio 2013
 
 platform:
-  - Any CPU
+  - x64
 
 configuration:
   - Debug
@@ -17,6 +17,13 @@
   only:
     - master
 
+# Travis advances the master-tot tag to current top of the tree after
+# each push into the master branch, because it relies on that tag to
+# upload build artifacts to the master-tot release. This will cause
+# double testing for each push on Appveyor: one for the push, one for
+# the tag advance. Disable testing tags.
+skip_tags: true
+
 clone_depth: 5
 
 matrix:
@@ -39,3 +46,45 @@
 test_script:
   - ctest -C %CONFIGURATION% --output-on-failure
   - cd ../Test && bash runtests
+  - cd ../build
+
+after_test:
+  # For debug build, the generated dll has a postfix "d" in its name.
+  - ps: >-
+      If ($env:configuration -Match "Debug") {
+        $env:SUFFIX="d"
+      } Else {
+        $env:SUFFIX=""
+      }
+  - cd install
+  # Zip all glslang artifacts for uploading and deploying
+  - 7z a glslang-master-windows-"%PLATFORM%"-"%CONFIGURATION%".zip
+    bin\glslangValidator.exe
+    include\glslang\*
+    include\SPIRV\*
+    lib\glslang%SUFFIX%.lib
+    lib\HLSL%SUFFIX%.lib
+    lib\OGLCompiler%SUFFIX%.lib
+    lib\OSDependent%SUFFIX%.lib
+    lib\SPIRV%SUFFIX%.lib
+    lib\SPVRemapper%SUFFIX%.lib
+    lib\SPIRV-Tools%SUFFIX%.lib
+    lib\SPIRV-Tools-opt%SUFFIX%.lib
+
+artifacts:
+  - path: build\install\*.zip
+    name: artifacts-zip
+
+deploy:
+  - provider: GitHub
+    auth_token:
+      secure: YglcSYdl0TylEa59H4K6lylBEDr586NAt2EMgZquSo+iuPrwgZQuJLPCoihSm9y6
+    release: master-tot
+    description: "Continuous build of the latest master branch by Appveyor and Travis CI"
+    artifact: artifacts-zip
+    draft: false
+    prerelease: false
+    force_update: true
+    on:
+      branch: master
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
diff --git a/.travis.yml b/.travis.yml
index 0237d25..4fe4b5e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,8 +11,11 @@
 dist: trusty
 
 env:
-  - GLSLANG_BUILD_TYPE=Release
-  - GLSLANG_BUILD_TYPE=Debug
+  global:
+    - secure: aGFrgzyKp+84hKrGkxVWg8cHV61uqrKEHT38gfSQK6+WS4GfLOyH83p7WnsEBb7AMhzU7LMNFdvOFr6+NaMpVnqRvc40CEG1Q+lNg9Pq9mhIZLowvDrfqTL9kQ+8Nbw5Q6/dg6CTvY7fvRfpfCEmKIUZBRkoKUuHeuM1uy3IupFcdNuL5bSYn3Beo+apSJginh9DI4BLDXFUgBzTRSLLyCX5g3cpaeGGOCr8quJlYx75W6HRck5g9SZuLtUoH9GFEV3l+ZEWB8noErW+J56L03bwNwFuuAh321evw++oQk5KFa8rlDvar3SJ3b1RHB8u/eq5DBYMyaK/fS8+Q7QbGr8diF/wDe68bKO7U9IhpNfExXmczCpExjHomW5TQv4rYdGhygPMfW97aIsPRYyNKcl4fkmb7NDrM8w0Jscdq2g5c2Kz0ItyZoBri/NXLwFQQjaVCs7Pf97TjuMA7mK0GJmDTRzi6SrDYlWMt5BQL3y0CCojyfLIRcTh0CQjQI29s97bLfQrYAxt9GNNFR+HTXRLLrkaAlJkPGEPwUywlSfEThnvHLesNxYqemolAYpQT4ithoL4GehGIHmaxsW295aKVhuRf8K9eBODNqrfblvM42UHhjntT+92ZnQ/Gkq80GqaMxnxi4PO5FyPIxt0r981b54YBkWi8YA4P7w5pNI=
+  matrix:
+    - GLSLANG_BUILD_TYPE=Release
+    - GLSLANG_BUILD_TYPE=Debug
 
 compiler:
   - clang
@@ -75,3 +78,46 @@
       ctest --output-on-failure &&
       cd ../Test && ./runtests;
     fi
+
+after_success:
+  # For debug build, the generated dll has a postfix "d" in its name.
+  - if [[ "${GLSLANG_BUILD_TYPE}" == "Debug" ]]; then
+      export SUFFIX="d";
+    else
+      export SUFFIX="";
+    fi
+  # Create tarball for deployment
+  - if [[ ${CC} == clang* && "${BUILD_NDK}" != "ON" ]]; then
+      cd ../build/install;
+      export TARBALL=glslang-master-${TRAVIS_OS_NAME}-${GLSLANG_BUILD_TYPE}.zip;
+      zip ${TARBALL}
+        bin/glslangValidator
+        include/glslang/*
+        include/SPIRV/*
+        lib/libglslang${SUFFIX}.a
+        lib/libHLSL${SUFFIX}.a
+        lib/libOGLCompiler${SUFFIX}.a
+        lib/libOSDependent${SUFFIX}.a
+        lib/libSPIRV${SUFFIX}.a
+        lib/libSPVRemapper${SUFFIX}.a
+        lib/libSPIRV-Tools${SUFFIX}.a
+        lib/libSPIRV-Tools-opt${SUFFIX}.a;
+    fi
+
+before_deploy:
+  # Tag the current top of the tree as "master-tot".
+  # Travis CI replies on the tag name to properly push to GitHub Releases.
+  - git config --global user.name "Travis CI"
+  - git config --global user.email "builds@travis-ci.org"
+  - git tag -f master-tot
+  - git push -q -f https://${glslangtoken}@github.com/KhronosGroup/glslang --tags
+
+deploy:
+  provider: releases
+  api_key: ${glslangtoken}
+  on:
+    branch: master
+    condition: ${CC} == clang* && ${BUILD_NDK} != ON
+  file: ${TARBALL}
+  skip_cleanup: true
+  overwrite: true
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0d453cc..9a869c2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,6 +9,14 @@
 # Adhere to GNU filesystem layout conventions
 include(GNUInstallDirs)
 
+option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
+
+set(LIB_TYPE STATIC)
+
+if(BUILD_SHARED_LIBS)
+    set(LIB_TYPE SHARED)
+endif()
+
 option(SKIP_GLSLANG_INSTALL "Skip installation" ${SKIP_GLSLANG_INSTALL})
 if(NOT ${SKIP_GLSLANG_INSTALL})
   set(ENABLE_GLSLANG_INSTALL ON)
@@ -94,9 +102,12 @@
 
 if(ENABLE_OPT)
     message(STATUS "optimizer enabled")
-    add_definitions(-DENABLE_OPT)
-elseif(ENABLE_HLSL)
-    message(STATUS "spirv-tools not linked - illegal SPIRV may be generated for HLSL")
+    add_definitions(-DENABLE_OPT=1)
+else()
+    if(ENABLE_HLSL)
+        message(STATUS "spirv-tools not linked - illegal SPIRV may be generated for HLSL")
+    endif()
+    add_definitions(-DENABLE_OPT=0)
 endif()
 
 add_subdirectory(glslang)
diff --git a/OGLCompilersDLL/InitializeDll.cpp b/OGLCompilersDLL/InitializeDll.cpp
index 2eb912c..abea910 100644
--- a/OGLCompilersDLL/InitializeDll.cpp
+++ b/OGLCompilersDLL/InitializeDll.cpp
@@ -38,13 +38,17 @@
 
 #include "InitializeDll.h"
 #include "../glslang/Include/InitializeGlobals.h"
-
 #include "../glslang/Public/ShaderLang.h"
+#include "../glslang/Include/PoolAlloc.h"
 
 namespace glslang {
 
 OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
 
+// Per-process initialization.
+// Needs to be called at least once before parsing, etc. is done.
+// Will also do thread initialization for the calling thread; other
+// threads will need to do that explicitly.
 bool InitProcess()
 {
     glslang::GetGlobalLock();
@@ -85,7 +89,9 @@
     return true;
 }
 
-
+// Per-thread scoped initialization.
+// Must be called at least once by each new thread sharing the
+// symbol tables, etc., needed to parse.
 bool InitThread()
 {
     //
@@ -99,17 +105,21 @@
     if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
         return true;
 
-    InitializeMemoryPools();
-
     if (! OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
         assert(0 && "InitThread(): Unable to set init flag.");
         return false;
     }
 
+    glslang::SetThreadPoolAllocator(nullptr);
+
     return true;
 }
 
-
+// Not necessary to call this: InitThread() is reentrant, and the need
+// to do per thread tear down has been removed.
+//
+// This is kept, with memory management removed, to satisfy any exiting
+// calls to it that rely on it.
 bool DetachThread()
 {
     bool success = true;
@@ -125,14 +135,18 @@
             assert(0 && "DetachThread(): Unable to clear init flag.");
             success = false;
         }
-
-        FreeGlobalPools();
-
     }
 
     return success;
 }
 
+// Not necessary to call this: InitProcess() is reentrant.
+//
+// This is kept, with memory management removed, to satisfy any exiting
+// calls to it that rely on it.
+//
+// Users of glslang should call shFinalize() or glslang::FinalizeProcess() for
+// process-scoped memory tear down.
 bool DetachProcess()
 {
     bool success = true;
@@ -140,12 +154,8 @@
     if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
         return true;
 
-    ShFinalize();
-
     success = DetachThread();
 
-    FreePoolIndex();
-
     OS_FreeTLSIndex(ThreadInitializeIndex);
     ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
 
diff --git a/OGLCompilersDLL/InitializeDll.h b/OGLCompilersDLL/InitializeDll.h
index 60b2b15..661cee4 100644
--- a/OGLCompilersDLL/InitializeDll.h
+++ b/OGLCompilersDLL/InitializeDll.h
@@ -40,8 +40,8 @@
 
 bool InitProcess();
 bool InitThread();
-bool DetachThread();
-bool DetachProcess();
+bool DetachThread();  // not called from standalone, perhaps other tools rely on parts of it
+bool DetachProcess(); // not called from standalone, perhaps other tools rely on parts of it
 
 } // end namespace glslang
 
diff --git a/README.md b/README.md
index 9d5efb5..402b4d6 100644
--- a/README.md
+++ b/README.md
@@ -49,22 +49,31 @@
 Building
 --------
 
+Instead of building manually, you can also download the binaries for your
+platform directly from the [master-tot release][master-tot-release] on GitHub.
+Those binaries are automatically uploaded by the buildbots after successful
+testing and they always reflect the current top of the tree of the master
+branch.
+
 ### Dependencies
 
+* A C++11 compiler.
+  (For MSVS: 2015 is recommended, 2013 is fully supported/tested, and 2010 support is attempted, but not tested.)
 * [CMake][cmake]: for generating compilation targets.
+* make: _Linux_, ninja is an alternative, if configured.
 * [Python 2.7][python]: for executing SPIRV-Tools scripts. (Optional if not using SPIRV-Tools.)
 * [bison][bison]: _optional_, but needed when changing the grammar (glslang.y).
 * [googletest][googletest]: _optional_, but should use if making any changes to glslang.
 
 ### Build steps
 
+The following steps assume a Bash shell. On Windows, that could be the Git Bash
+shell or some other shell of your choosing.
+
 #### 1) Check-Out this project 
 
 ```bash
 cd <parent of where you want glslang to be>
-# If using SSH
-git clone git@github.com:KhronosGroup/glslang.git
-# Or if using HTTPS
 git clone https://github.com/KhronosGroup/glslang.git
 ```
 
@@ -83,28 +92,27 @@
 ./update_glslang_sources.py
 ```
 
-For running the CMake GUI or Visual Studio with python dependencies, you will,
-in addition to python within the cygwin environment, need a Windows [python][python]
-installation, including selecting the `PATH` update.
-
 #### 3) Configure
 
-Assume the source directory is `$SOURCE_DIR` and
-the build directory is `$BUILD_DIR`:
-
-For building on Linux (assuming using the Ninja generator):
+Assume the source directory is `$SOURCE_DIR` and the build directory is
+`$BUILD_DIR`. First ensure the build directory exists, then navigate to it:
 
 ```bash
+mkdir -p $BUILD_DIR
 cd $BUILD_DIR
+```
 
-cmake -GNinja -DCMAKE_BUILD_TYPE={Debug|Release|RelWithDebInfo} \
-      -DCMAKE_INSTALL_PREFIX=`pwd`/install $SOURCE_DIR
+For building on Linux:
+
+```bash
+cmake -DCMAKE_BUILD_TYPE={Debug|Release|RelWithDebInfo} \
+      -DCMAKE_INSTALL_PREFIX="$(pwd)/install" $SOURCE_DIR
 ```
 
 For building on Windows:
 
 ```bash
-cmake $SOURCE_DIR -DCMAKE_INSTALL_PREFIX=`pwd`/install
+cmake $SOURCE_DIR -DCMAKE_INSTALL_PREFIX="$(pwd)/install"
 # The CMAKE_INSTALL_PREFIX part is for testing (explained later).
 ```
 
@@ -114,7 +122,7 @@
 
 ```bash
 # for Linux:
-ninja install
+make -j4 install
 
 # for Windows:
 cmake --build . --config {Release|Debug|MinSizeRel|RelWithDebInfo} \
@@ -233,8 +241,11 @@
 void FinalizeProcess();
 
 class TShader
+    setStrings(...);
+    setEnvInput(EShSourceHlsl or EShSourceGlsl, stage,  EShClientVulkan or EShClientOpenGL, 100);
+    setEnvClient(EShClientVulkan or EShClientOpenGL, EShTargetVulkan_1_0 or EShTargetVulkan_1_1 or EShTargetOpenGL_450);
+    setEnvTarget(EShTargetSpv, EShTargetSpv_1_0 or EShTargetSpv_1_3);
     bool parse(...);
-    void setStrings(...);
     const char* getInfoLog();
 
 class TProgram
@@ -318,3 +329,4 @@
 [bison]: https://www.gnu.org/software/bison/
 [googletest]: https://github.com/google/googletest
 [bison-gnu-win32]: http://gnuwin32.sourceforge.net/packages/bison.htm
+[master-tot-release]: https://github.com/KhronosGroup/glslang/releases/tag/master-tot
diff --git a/SPIRV/CMakeLists.txt b/SPIRV/CMakeLists.txt
index b1c0277..1e32e27 100755
--- a/SPIRV/CMakeLists.txt
+++ b/SPIRV/CMakeLists.txt
@@ -14,6 +14,7 @@
     bitutils.h
     spirv.hpp
     GLSL.std.450.h
+    GLSL.ext.EXT.h
     GLSL.ext.KHR.h
     GlslangToSpv.h
     hex_float.h
@@ -39,20 +40,25 @@
          GLSL.ext.NV.h)
 endif(ENABLE_NV_EXTENSIONS)
 
-add_library(SPIRV STATIC ${SOURCES} ${HEADERS})
+add_library(SPIRV ${LIB_TYPE} ${SOURCES} ${HEADERS})
 set_property(TARGET SPIRV PROPERTY FOLDER glslang)
 set_property(TARGET SPIRV PROPERTY POSITION_INDEPENDENT_CODE ON)
 
-add_library(SPVRemapper STATIC ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
+add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
 set_property(TARGET SPVRemapper PROPERTY FOLDER glslang)
 set_property(TARGET SPVRemapper PROPERTY POSITION_INDEPENDENT_CODE ON)
 
+if(WIN32 AND BUILD_SHARED_LIBS)
+    set_target_properties(SPIRV PROPERTIES PREFIX "")
+    set_target_properties(SPVRemapper PROPERTIES PREFIX "")
+endif()
+
 if(ENABLE_OPT)
     target_include_directories(SPIRV
         PRIVATE ${spirv-tools_SOURCE_DIR}/include
         PRIVATE ${spirv-tools_SOURCE_DIR}/source
     )
-    target_link_libraries(SPIRV glslang SPIRV-Tools-opt SPVRemapper)
+    target_link_libraries(SPIRV glslang SPIRV-Tools-opt)
 else()
     target_link_libraries(SPIRV glslang)
 endif(ENABLE_OPT)
diff --git a/SPIRV/GLSL.ext.AMD.h b/SPIRV/GLSL.ext.AMD.h
index 7e97be3..009d2f1 100644
--- a/SPIRV/GLSL.ext.AMD.h
+++ b/SPIRV/GLSL.ext.AMD.h
@@ -27,13 +27,8 @@
 #ifndef GLSLextAMD_H
 #define GLSLextAMD_H
 
-enum BuiltIn;
-enum Capability;
-enum Decoration;
-enum Op;
-
 static const int GLSLextAMDVersion = 100;
-static const int GLSLextAMDRevision = 6;
+static const int GLSLextAMDRevision = 7;
 
 // SPV_AMD_shader_ballot
 static const char* const E_SPV_AMD_shader_ballot = "SPV_AMD_shader_ballot";
@@ -104,14 +99,10 @@
 // SPV_AMD_shader_image_load_store_lod
 static const char* const E_SPV_AMD_shader_image_load_store_lod = "SPV_AMD_shader_image_load_store_lod";
 
-static const Capability CapabilityImageReadWriteLodAMD = static_cast<Capability>(5015);
-
 // SPV_AMD_shader_fragment_mask
 static const char* const E_SPV_AMD_shader_fragment_mask = "SPV_AMD_shader_fragment_mask";
 
-static const Capability CapabilityFragmentMaskAMD = static_cast<Capability>(5010);
-
-static const Op OpFragmentMaskFetchAMD = static_cast<Op>(5011);
-static const Op OpFragmentFetchAMD     = static_cast<Op>(5012);
+// SPV_AMD_gpu_shader_half_float_fetch
+static const char* const E_SPV_AMD_gpu_shader_half_float_fetch = "SPV_AMD_gpu_shader_half_float_fetch";
 
 #endif  // #ifndef GLSLextAMD_H
diff --git a/SPIRV/GLSL.ext.EXT.h b/SPIRV/GLSL.ext.EXT.h
new file mode 100644
index 0000000..c4a2430
--- /dev/null
+++ b/SPIRV/GLSL.ext.EXT.h
@@ -0,0 +1,37 @@
+/*
+** Copyright (c) 2014-2016 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and/or associated documentation files (the "Materials"),
+** to deal in the Materials without restriction, including without limitation
+** the rights to use, copy, modify, merge, publish, distribute, sublicense,
+** and/or sell copies of the Materials, and to permit persons to whom the
+** Materials are furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Materials.
+**
+** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
+** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
+** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
+** IN THE MATERIALS.
+*/
+
+#ifndef GLSLextEXT_H
+#define GLSLextEXT_H
+
+static const int GLSLextEXTVersion = 100;
+static const int GLSLextEXTRevision = 1;
+
+static const char* const E_SPV_EXT_shader_stencil_export        = "SPV_EXT_shader_stencil_export";
+static const char* const E_SPV_EXT_shader_viewport_index_layer  = "SPV_EXT_shader_viewport_index_layer";
+static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
+
+#endif  // #ifndef GLSLextEXT_H
diff --git a/SPIRV/GLSL.ext.KHR.h b/SPIRV/GLSL.ext.KHR.h
index 2eb10ae..d8ea9b6 100644
--- a/SPIRV/GLSL.ext.KHR.h
+++ b/SPIRV/GLSL.ext.KHR.h
@@ -27,10 +27,6 @@
 #ifndef GLSLextKHR_H
 #define GLSLextKHR_H
 
-enum BuiltIn;
-enum Op;
-enum Capability;
-
 static const int GLSLextKHRVersion = 100;
 static const int GLSLextKHRRevision = 2;
 
@@ -42,7 +38,5 @@
 static const char* const E_SPV_KHR_16bit_storage                = "SPV_KHR_16bit_storage";
 static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class";
 static const char* const E_SPV_KHR_post_depth_coverage          = "SPV_KHR_post_depth_coverage";
-static const char* const E_SPV_EXT_shader_stencil_export        = "SPV_EXT_shader_stencil_export";
-static const char* const E_SPV_EXT_shader_viewport_index_layer  = "SPV_EXT_shader_viewport_index_layer";
 
 #endif  // #ifndef GLSLextKHR_H
diff --git a/SPIRV/GLSL.ext.NV.h b/SPIRV/GLSL.ext.NV.h
index c01858b..148d4b4 100644
--- a/SPIRV/GLSL.ext.NV.h
+++ b/SPIRV/GLSL.ext.NV.h
@@ -51,4 +51,7 @@
 //SPV_NVX_multiview_per_view_attributes
 const char* const E_SPV_NVX_multiview_per_view_attributes = "SPV_NVX_multiview_per_view_attributes";
 
+//SPV_NV_shader_subgroup_partitioned
+const char* const E_SPV_NV_shader_subgroup_partitioned = "SPV_NV_shader_subgroup_partitioned";
+
 #endif  // #ifndef GLSLextNV_H
\ No newline at end of file
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index b0e51df..d2b2dee 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1,6 +1,7 @@
 //
 // Copyright (C) 2014-2016 LunarG, Inc.
 // Copyright (C) 2015-2016 Google, Inc.
+// Copyright (C) 2017 ARM Limited.
 //
 // All rights reserved.
 //
@@ -44,6 +45,7 @@
 namespace spv {
     #include "GLSL.std.450.h"
     #include "GLSL.ext.KHR.h"
+    #include "GLSL.ext.EXT.h"
 #ifdef AMD_EXTENSIONS
     #include "GLSL.ext.AMD.h"
 #endif
@@ -52,13 +54,12 @@
 #endif
 }
 
-#ifdef ENABLE_OPT
+#if ENABLE_OPT
     #include "spirv-tools/optimizer.hpp"
     #include "message.h"
-    #include "SPVRemapper.h"
 #endif
 
-#ifdef ENABLE_OPT
+#if ENABLE_OPT
 using namespace spvtools;
 #endif
 
@@ -78,11 +79,6 @@
 
 namespace {
 
-// For low-order part of the generator's magic number. Bump up
-// when there is a change in the style (e.g., if SSA form changes,
-// or a different instruction sequence to do something gets used).
-const int GeneratorVersion = 2;
-
 namespace {
 class SpecConstantOpModeGuard {
 public:
@@ -102,7 +98,14 @@
     spv::Builder* builder_;
     bool previous_flag_;
 };
-}
+
+struct OpDecorations {
+    spv::Decoration precision;
+    spv::Decoration noContraction;
+    spv::Decoration nonUniform;
+};
+
+} // namespace
 
 //
 // The main holder of information for translating glslang to SPIR-V.
@@ -111,7 +114,8 @@
 //
 class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
 public:
-    TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger, glslang::SpvOptions& options);
+    TGlslangToSpvTraverser(unsigned int spvVersion, const glslang::TIntermediate*, spv::SpvBuildLogger* logger,
+        glslang::SpvOptions& options);
     virtual ~TGlslangToSpvTraverser() { }
 
     bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*);
@@ -128,20 +132,27 @@
     void dumpSpv(std::vector<unsigned int>& out);
 
 protected:
+    TGlslangToSpvTraverser(TGlslangToSpvTraverser&);
+    TGlslangToSpvTraverser& operator=(TGlslangToSpvTraverser&);
+
     spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
     spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
+    spv::Decoration TranslateNonUniformDecoration(const glslang::TQualifier& qualifier);
     spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
     spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
-    spv::SelectionControlMask TranslateSelectionControl(glslang::TSelectionControl) const;
-    spv::LoopControlMask TranslateLoopControl(glslang::TLoopControl) const;
+    spv::SelectionControlMask TranslateSelectionControl(const glslang::TIntermSelection&) const;
+    spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const;
+    spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, unsigned int& dependencyLength) const;
     spv::StorageClass TranslateStorageClass(const glslang::TType&);
+    void addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType);
     spv::Id createSpvVariable(const glslang::TIntermSymbol*);
     spv::Id getSampledType(const glslang::TSampler&);
     spv::Id getInvertedSwizzleType(const glslang::TIntermTyped&);
     spv::Id createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped&, spv::Id parentResult);
     void convertSwizzle(const glslang::TIntermAggregate&, std::vector<unsigned>& swizzle);
     spv::Id convertGlslangToSpvType(const glslang::TType& type);
-    spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&);
+    spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&,
+        bool lastBufferBlockMember);
     bool filterMember(const glslang::TType& member);
     spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
                                           glslang::TLayoutPacking, const glslang::TQualifier&);
@@ -154,7 +165,8 @@
     glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
     int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
     int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
-    void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset, glslang::TLayoutPacking, glslang::TLayoutMatrix);
+    void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset,
+                            int& nextOffset, glslang::TLayoutPacking, glslang::TLayoutMatrix);
     void declareUseOfStructMember(const glslang::TTypeList& members, int glslangMember);
 
     bool isShaderEntryPoint(const glslang::TIntermAggregate* node);
@@ -169,28 +181,37 @@
     spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node);
     spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*);
 
-    spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true);
-    spv::Id createBinaryMatrixOperation(spv::Op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id left, spv::Id right);
-    spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
-    spv::Id createUnaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
-    spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id destTypeId, spv::Id operand, glslang::TBasicType typeProxy);
+    spv::Id createBinaryOperation(glslang::TOperator op, OpDecorations&, spv::Id typeId, spv::Id left, spv::Id right,
+                                  glslang::TBasicType typeProxy, bool reduceComparison = true);
+    spv::Id createBinaryMatrixOperation(spv::Op, OpDecorations&, spv::Id typeId, spv::Id left, spv::Id right);
+    spv::Id createUnaryOperation(glslang::TOperator op, OpDecorations&, spv::Id typeId, spv::Id operand,
+                                 glslang::TBasicType typeProxy);
+    spv::Id createUnaryMatrixOperation(spv::Op op, OpDecorations&, spv::Id typeId, spv::Id operand,
+                                       glslang::TBasicType typeProxy);
+    spv::Id createConversion(glslang::TOperator op, OpDecorations&, spv::Id destTypeId, spv::Id operand,
+                             glslang::TBasicType typeProxy);
+    spv::Id createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize);
     spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
     spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
     spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
     spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector<spv::Id>& operands);
+    spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
     spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
     spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId);
     spv::Id getSymbolId(const glslang::TIntermSymbol* node);
-    void addDecoration(spv::Id id, spv::Decoration dec);
-    void addDecoration(spv::Id id, spv::Decoration dec, unsigned value);
-    void addMemberDecoration(spv::Id id, int member, spv::Decoration dec);
-    void addMemberDecoration(spv::Id id, int member, spv::Decoration dec, unsigned value);
     spv::Id createSpvConstant(const glslang::TIntermTyped&);
     spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant);
     bool isTrivialLeaf(const glslang::TIntermTyped* node);
     bool isTrivial(const glslang::TIntermTyped* node);
     spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right);
+#ifdef AMD_EXTENSIONS
     spv::Id getExtBuiltins(const char* name);
+#endif
+    void addPre13Extension(const char* ext)
+    {
+        if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+            builder.addExtension(ext);
+    }
 
     glslang::SpvOptions& options;
     spv::Function* shaderEntry;
@@ -214,8 +235,10 @@
     std::unordered_set<int> rValueParameters;  // set of formal function parameters passed as rValues, rather than a pointer
     std::unordered_map<std::string, spv::Function*> functionMap;
     std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
-    std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper;  // for mapping glslang block indices to spv indices (e.g., due to hidden members)
+    // for mapping glslang block indices to spv indices (e.g., due to hidden members):
+    std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper;
     std::stack<bool> breakForLoop;  // false means break for switch
+    std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
 };
 
 //
@@ -423,6 +446,17 @@
         return spv::DecorationMax;
 }
 
+// If glslang type is nonUniform, return SPIR-V NonUniform decoration.
+spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glslang::TQualifier& qualifier)
+{
+    if (qualifier.isNonUniform()) {
+        builder.addExtension("SPV_EXT_descriptor_indexing");
+        builder.addCapability(spv::CapabilityShaderNonUniformEXT);
+        return spv::DecorationNonUniformEXT;
+    } else
+        return spv::DecorationMax;
+}
+
 // Translate a glslang built-in variable to a SPIR-V built in decoration.  Also generate
 // associated capabilities when required.  For some built-in variables, a capability
 // is generated only when using the variable in an executable instruction, but not when
@@ -484,7 +518,6 @@
         return spv::BuiltInSamplePosition;
 
     case glslang::EbvSampleMask:
-        builder.addCapability(spv::CapabilitySampleRateShading);
         return spv::BuiltInSampleMask;
 
     case glslang::EbvLayer:
@@ -505,17 +538,17 @@
     case glslang::EbvInstanceIndex:        return spv::BuiltInInstanceIndex;
 
     case glslang::EbvBaseVertex:
-        builder.addExtension(spv::E_SPV_KHR_shader_draw_parameters);
+        addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
         builder.addCapability(spv::CapabilityDrawParameters);
         return spv::BuiltInBaseVertex;
 
     case glslang::EbvBaseInstance:
-        builder.addExtension(spv::E_SPV_KHR_shader_draw_parameters);
+        addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
         builder.addCapability(spv::CapabilityDrawParameters);
         return spv::BuiltInBaseInstance;
 
     case glslang::EbvDrawId:
-        builder.addExtension(spv::E_SPV_KHR_shader_draw_parameters);
+        addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
         builder.addCapability(spv::CapabilityDrawParameters);
         return spv::BuiltInDrawIndex;
 
@@ -581,6 +614,46 @@
         builder.addCapability(spv::CapabilitySubgroupBallotKHR);
         return spv::BuiltInSubgroupLtMaskKHR;
 
+    case glslang::EbvNumSubgroups:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        return spv::BuiltInNumSubgroups;
+
+    case glslang::EbvSubgroupID:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        return spv::BuiltInSubgroupId;
+
+    case glslang::EbvSubgroupSize2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        return spv::BuiltInSubgroupSize;
+
+    case glslang::EbvSubgroupInvocation2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        return spv::BuiltInSubgroupLocalInvocationId;
+
+    case glslang::EbvSubgroupEqMask2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        return spv::BuiltInSubgroupEqMask;
+
+    case glslang::EbvSubgroupGeMask2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        return spv::BuiltInSubgroupGeMask;
+
+    case glslang::EbvSubgroupGtMask2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        return spv::BuiltInSubgroupGtMask;
+
+    case glslang::EbvSubgroupLeMask2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        return spv::BuiltInSubgroupLeMask;
+
+    case glslang::EbvSubgroupLtMask2:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        return spv::BuiltInSubgroupLtMask;
 #ifdef AMD_EXTENSIONS
     case glslang::EbvBaryCoordNoPersp:
         builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter);
@@ -612,12 +685,12 @@
 #endif
 
     case glslang::EbvDeviceIndex:
-        builder.addExtension(spv::E_SPV_KHR_device_group);
+        addPre13Extension(spv::E_SPV_KHR_device_group);
         builder.addCapability(spv::CapabilityDeviceGroup);
         return spv::BuiltInDeviceIndex;
 
     case glslang::EbvViewIndex:
-        builder.addExtension(spv::E_SPV_KHR_multiview);
+        addPre13Extension(spv::E_SPV_KHR_multiview);
         builder.addCapability(spv::CapabilityMultiView);
         return spv::BuiltInViewIndex;
 
@@ -652,6 +725,10 @@
             builder.addCapability(spv::CapabilityPerViewAttributesNV);
         }
         return spv::BuiltInViewportMaskPerViewNV;
+    case glslang::EbvFragFullyCoveredNV:
+        builder.addExtension(spv::E_SPV_EXT_fragment_fully_covered);
+        builder.addCapability(spv::CapabilityFragmentFullyCoveredEXT);
+        return spv::BuiltInFullyCoveredEXT;
 #endif 
     default:
         return spv::BuiltInMax;
@@ -746,26 +823,42 @@
     }
 }
 
-spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(glslang::TSelectionControl selectionControl) const
+spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(const glslang::TIntermSelection& selectionNode) const
 {
-    switch (selectionControl) {
-    case glslang::ESelectionControlNone:        return spv::SelectionControlMaskNone;
-    case glslang::ESelectionControlFlatten:     return spv::SelectionControlFlattenMask;
-    case glslang::ESelectionControlDontFlatten: return spv::SelectionControlDontFlattenMask;
-    default:                                    return spv::SelectionControlMaskNone;
-    }
+    if (selectionNode.getFlatten())
+        return spv::SelectionControlFlattenMask;
+    if (selectionNode.getDontFlatten())
+        return spv::SelectionControlDontFlattenMask;
+    return spv::SelectionControlMaskNone;
 }
 
-spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(glslang::TLoopControl loopControl) const
+spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const glslang::TIntermSwitch& switchNode) const
 {
-    switch (loopControl) {
-    case glslang::ELoopControlNone:       return spv::LoopControlMaskNone;
-    case glslang::ELoopControlUnroll:     return spv::LoopControlUnrollMask;
-    case glslang::ELoopControlDontUnroll: return spv::LoopControlDontUnrollMask;
-    // TODO: DependencyInfinite
-    // TODO: DependencyLength
-    default:                              return spv::LoopControlMaskNone;
+    if (switchNode.getFlatten())
+        return spv::SelectionControlFlattenMask;
+    if (switchNode.getDontFlatten())
+        return spv::SelectionControlDontFlattenMask;
+    return spv::SelectionControlMaskNone;
+}
+
+// return a non-0 dependency if the dependency argument must be set
+spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang::TIntermLoop& loopNode,
+    unsigned int& dependencyLength) const
+{
+    spv::LoopControlMask control = spv::LoopControlMaskNone;
+
+    if (loopNode.getDontUnroll())
+        control = control | spv::LoopControlDontUnrollMask;
+    if (loopNode.getUnroll())
+        control = control | spv::LoopControlUnrollMask;
+    if (unsigned(loopNode.getLoopDependency()) == glslang::TIntermLoop::dependencyInfinite)
+        control = control | spv::LoopControlDependencyInfiniteMask;
+    else if (loopNode.getLoopDependency() > 0) {
+        control = control | spv::LoopControlDependencyLengthMask;
+        dependencyLength = loopNode.getLoopDependency();
     }
+
+    return control;
 }
 
 // Translate glslang type to SPIR-V storage class.
@@ -785,7 +878,7 @@
     }
 
     if (glslangIntermediate->usingStorageBuffer() && type.getQualifier().storage == glslang::EvqBuffer) {
-        builder.addExtension(spv::E_SPV_KHR_storage_buffer_storage_class);
+        addPre13Extension(spv::E_SPV_KHR_storage_buffer_storage_class);
         return spv::StorageClassStorageBuffer;
     }
 
@@ -810,6 +903,42 @@
     return spv::StorageClassFunction;
 }
 
+// Add capabilities pertaining to how an array is indexed.
+void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType,
+                                                             const glslang::TType& indexType)
+{
+    if (indexType.getQualifier().isNonUniform()) {
+        // deal with an asserted non-uniform index
+        if (baseType.getBasicType() == glslang::EbtSampler) {
+            if (baseType.getQualifier().hasAttachment())
+                builder.addCapability(spv::CapabilityInputAttachmentArrayNonUniformIndexingEXT);
+            else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer)
+                builder.addCapability(spv::CapabilityStorageTexelBufferArrayNonUniformIndexingEXT);
+            else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer)
+                builder.addCapability(spv::CapabilityUniformTexelBufferArrayNonUniformIndexingEXT);
+            else if (baseType.isImage())
+                builder.addCapability(spv::CapabilityStorageImageArrayNonUniformIndexingEXT);
+            else if (baseType.isTexture())
+                builder.addCapability(spv::CapabilitySampledImageArrayNonUniformIndexingEXT);
+        } else if (baseType.getBasicType() == glslang::EbtBlock) {
+            if (baseType.getQualifier().storage == glslang::EvqBuffer)
+                builder.addCapability(spv::CapabilityStorageBufferArrayNonUniformIndexingEXT);
+            else if (baseType.getQualifier().storage == glslang::EvqUniform)
+                builder.addCapability(spv::CapabilityUniformBufferArrayNonUniformIndexingEXT);
+        }
+    } else {
+        // assume a dynamically uniform index
+        if (baseType.getBasicType() == glslang::EbtSampler) {
+            if (baseType.getQualifier().hasAttachment())
+                builder.addCapability(spv::CapabilityInputAttachmentArrayDynamicIndexingEXT);
+            else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer)
+                builder.addCapability(spv::CapabilityStorageTexelBufferArrayDynamicIndexingEXT);
+            else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer)
+                builder.addCapability(spv::CapabilityUniformTexelBufferArrayDynamicIndexingEXT);
+        }
+    }
+}
+
 // Return whether or not the given type is something that should be tied to a
 // descriptor set.
 bool IsDescriptorResource(const glslang::TType& type)
@@ -879,13 +1008,13 @@
 // Implement the TGlslangToSpvTraverser class.
 //
 
-TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate,
+TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const glslang::TIntermediate* glslangIntermediate,
                                                spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options)
     : TIntermTraverser(true, false, true),
       options(options),
       shaderEntry(nullptr), currentFunction(nullptr),
       sequenceDepth(0), logger(buildLogger),
-      builder((glslang::GetKhronosToolId() << 16) | GeneratorVersion, logger),
+      builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger),
       inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
       glslangIntermediate(glslangIntermediate)
 {
@@ -1128,6 +1257,38 @@
         else
             builder.setAccessChainLValue(id);
     }
+
+    // Process linkage-only nodes for any special additional interface work.
+    if (linkageOnly) {
+        if (glslangIntermediate->getHlslFunctionality1()) {
+            // Map implicit counter buffers to their originating buffers, which should have been
+            // seen by now, given earlier pruning of unused counters, and preservation of order
+            // of declaration.
+            if (symbol->getType().getQualifier().isUniformOrBuffer()) {
+                if (!glslangIntermediate->hasCounterBufferName(symbol->getName())) {
+                    // Save possible originating buffers for counter buffers, keyed by
+                    // making the potential counter-buffer name.
+                    std::string keyName = symbol->getName().c_str();
+                    keyName = glslangIntermediate->addCounterBufferName(keyName);
+                    counterOriginator[keyName] = symbol;
+                } else {
+                    // Handle a counter buffer, by finding the saved originating buffer.
+                    std::string keyName = symbol->getName().c_str();
+                    auto it = counterOriginator.find(keyName);
+                    if (it != counterOriginator.end()) {
+                        id = getSymbolId(it->second);
+                        if (id != spv::NoResult) {
+                            spv::Id counterId = getSymbolId(symbol);
+                            if (counterId != spv::NoResult) {
+                                builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
+                                builder.addDecorationId(id, spv::DecorationHlslCounterBufferGOOGLE, counterId);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
 }
 
 bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
@@ -1176,8 +1337,10 @@
                 spv::Id leftRValue = accessChainLoad(node->getLeft()->getType());
 
                 // do the operation
-                rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getOperationPrecision()),
-                                               TranslateNoContractionDecoration(node->getType().getQualifier()),
+                OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()),
+                                              TranslateNoContractionDecoration(node->getType().getQualifier()),
+                                              TranslateNonUniformDecoration(node->getType().getQualifier()) };
+                rValue = createBinaryOperation(node->getOp(), decorations,
                                                convertGlslangToSpvType(node->getType()), leftRValue, rValue,
                                                node->getType().getBasicType());
 
@@ -1252,6 +1415,8 @@
             node->getRight()->traverse(this);
             spv::Id index = accessChainLoad(node->getRight()->getType());
 
+            addIndirectionIndexCapabilities(node->getLeft()->getType(), node->getRight()->getType());
+
             // restore the saved access chain
             builder.setAccessChain(partial);
 
@@ -1304,8 +1469,10 @@
     spv::Id right = accessChainLoad(node->getRight()->getType());
 
     // get result
-    spv::Id result = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getOperationPrecision()),
-                                           TranslateNoContractionDecoration(node->getType().getQualifier()),
+    OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()),
+                                  TranslateNoContractionDecoration(node->getType().getQualifier()),
+                                  TranslateNonUniformDecoration(node->getType().getQualifier()) };
+    spv::Id result = createBinaryOperation(node->getOp(), decorations,
                                            convertGlslangToSpvType(node->getType()), left, right,
                                            node->getLeft()->getType().getBasicType());
 
@@ -1343,10 +1510,15 @@
     if (node->getOp() == glslang::EOpArrayLength) {
         // Quite special; won't want to evaluate the operand.
 
+        // Currently, the front-end does not allow .length() on an array until it is sized,
+        // except for the last block membeor of an SSBO.
+        // TODO: If this changes, link-time sized arrays might show up here, and need their
+        // size extracted.
+
         // Normal .length() would have been constant folded by the front-end.
         // So, this has to be block.lastMember.length().
         // SPV wants "block" and member number as the operands, go get them.
-        assert(node->getOperand()->getType().isRuntimeSizedArray());
+
         glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft();
         block->traverse(this);
         unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()->getConstArray()[0].getUConst();
@@ -1383,20 +1555,23 @@
     else
         operand = accessChainLoad(node->getOperand()->getType());
 
-    spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision());
-    spv::Decoration noContraction = TranslateNoContractionDecoration(node->getType().getQualifier());
+    OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()),
+                                  TranslateNoContractionDecoration(node->getType().getQualifier()),
+                                  TranslateNonUniformDecoration(node->getType().getQualifier()) };
 
     // it could be a conversion
     if (! result)
-        result = createConversion(node->getOp(), precision, noContraction, resultType(), operand, node->getOperand()->getBasicType());
+        result = createConversion(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType());
 
     // if not, then possibly an operation
     if (! result)
-        result = createUnaryOperation(node->getOp(), precision, noContraction, resultType(), operand, node->getOperand()->getBasicType());
+        result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType());
 
     if (result) {
-        if (invertedType)
-            result = createInvertedSwizzle(precision, *node->getOperand(), result);
+        if (invertedType) {
+            result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result);
+            builder.addDecoration(result, decorations.nonUniform);
+        }
 
         builder.clearAccessChain();
         builder.setAccessChainRValue(result);
@@ -1417,16 +1592,14 @@
                 one = builder.makeFloatConstant(1.0F);
             else if (node->getBasicType() == glslang::EbtDouble)
                 one = builder.makeDoubleConstant(1.0);
-#ifdef AMD_EXTENSIONS
             else if (node->getBasicType() == glslang::EbtFloat16)
                 one = builder.makeFloat16Constant(1.0F);
-#endif
-            else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64)
-                one = builder.makeInt64Constant(1);
-#ifdef AMD_EXTENSIONS
+            else if (node->getBasicType() == glslang::EbtInt8  || node->getBasicType() == glslang::EbtUint8)
+                one = builder.makeInt8Constant(1);
             else if (node->getBasicType() == glslang::EbtInt16 || node->getBasicType() == glslang::EbtUint16)
                 one = builder.makeInt16Constant(1);
-#endif
+            else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64)
+                one = builder.makeInt64Constant(1);
             else
                 one = builder.makeIntConstant(1);
             glslang::TOperator op;
@@ -1436,8 +1609,7 @@
             else
                 op = glslang::EOpSub;
 
-            spv::Id result = createBinaryOperation(op, precision,
-                                                   TranslateNoContractionDecoration(node->getType().getQualifier()),
+            spv::Id result = createBinaryOperation(op, decorations,
                                                    convertGlslangToSpvType(node->getType()), operand, one,
                                                    node->getType().getBasicType());
             assert(result != spv::NoResult);
@@ -1631,7 +1803,6 @@
     case glslang::EOpConstructBMat4x2:
     case glslang::EOpConstructBMat4x3:
     case glslang::EOpConstructBMat4x4:
-#ifdef AMD_EXTENSIONS
     case glslang::EOpConstructF16Mat2x2:
     case glslang::EOpConstructF16Mat2x3:
     case glslang::EOpConstructF16Mat2x4:
@@ -1641,7 +1812,6 @@
     case glslang::EOpConstructF16Mat4x2:
     case glslang::EOpConstructF16Mat4x3:
     case glslang::EOpConstructF16Mat4x4:
-#endif
         isMatrix = true;
         // fall through
     case glslang::EOpConstructFloat:
@@ -1652,16 +1822,30 @@
     case glslang::EOpConstructDVec2:
     case glslang::EOpConstructDVec3:
     case glslang::EOpConstructDVec4:
-#ifdef AMD_EXTENSIONS
     case glslang::EOpConstructFloat16:
     case glslang::EOpConstructF16Vec2:
     case glslang::EOpConstructF16Vec3:
     case glslang::EOpConstructF16Vec4:
-#endif
     case glslang::EOpConstructBool:
     case glslang::EOpConstructBVec2:
     case glslang::EOpConstructBVec3:
     case glslang::EOpConstructBVec4:
+    case glslang::EOpConstructInt8:
+    case glslang::EOpConstructI8Vec2:
+    case glslang::EOpConstructI8Vec3:
+    case glslang::EOpConstructI8Vec4:
+    case glslang::EOpConstructUint8:
+    case glslang::EOpConstructU8Vec2:
+    case glslang::EOpConstructU8Vec3:
+    case glslang::EOpConstructU8Vec4:
+    case glslang::EOpConstructInt16:
+    case glslang::EOpConstructI16Vec2:
+    case glslang::EOpConstructI16Vec3:
+    case glslang::EOpConstructI16Vec4:
+    case glslang::EOpConstructUint16:
+    case glslang::EOpConstructU16Vec2:
+    case glslang::EOpConstructU16Vec3:
+    case glslang::EOpConstructU16Vec4:
     case glslang::EOpConstructInt:
     case glslang::EOpConstructIVec2:
     case glslang::EOpConstructIVec3:
@@ -1678,16 +1862,6 @@
     case glslang::EOpConstructU64Vec2:
     case glslang::EOpConstructU64Vec3:
     case glslang::EOpConstructU64Vec4:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConstructInt16:
-    case glslang::EOpConstructI16Vec2:
-    case glslang::EOpConstructI16Vec3:
-    case glslang::EOpConstructI16Vec4:
-    case glslang::EOpConstructUint16:
-    case glslang::EOpConstructU16Vec2:
-    case glslang::EOpConstructU16Vec3:
-    case glslang::EOpConstructU16Vec4:
-#endif
     case glslang::EOpConstructStruct:
     case glslang::EOpConstructTextureSampler:
     {
@@ -1763,10 +1937,16 @@
     case glslang::EOpMemoryBarrierImage:
     case glslang::EOpMemoryBarrierShared:
     case glslang::EOpGroupMemoryBarrier:
+    case glslang::EOpDeviceMemoryBarrier:
     case glslang::EOpAllMemoryBarrierWithGroupSync:
-    case glslang::EOpGroupMemoryBarrierWithGroupSync:
+    case glslang::EOpDeviceMemoryBarrierWithGroupSync:
     case glslang::EOpWorkgroupMemoryBarrier:
     case glslang::EOpWorkgroupMemoryBarrierWithGroupSync:
+    case glslang::EOpSubgroupBarrier:
+    case glslang::EOpSubgroupMemoryBarrier:
+    case glslang::EOpSubgroupMemoryBarrierBuffer:
+    case glslang::EOpSubgroupMemoryBarrierImage:
+    case glslang::EOpSubgroupMemoryBarrierShared:
         noReturnValue = true;
         // These all have 0 operands and will naturally finish up in the code below for 0 operands
         break;
@@ -1817,7 +1997,10 @@
         spv::Id rightId = accessChainLoad(right->getType());
 
         builder.setLine(node->getLoc().line);
-        result = createBinaryOperation(binOp, precision, TranslateNoContractionDecoration(node->getType().getQualifier()),
+        OpDecorations decorations = { precision,
+                                      TranslateNoContractionDecoration(node->getType().getQualifier()),
+                                      TranslateNonUniformDecoration(node->getType().getQualifier()) };
+        result = createBinaryOperation(binOp, decorations,
                                        resultType(), leftId, rightId,
                                        left->getType().getBasicType(), reduceComparison);
 
@@ -1915,11 +2098,15 @@
             result = createNoArgOperation(node->getOp(), precision, resultType());
             break;
         case 1:
-            result = createUnaryOperation(
-                node->getOp(), precision,
-                TranslateNoContractionDecoration(node->getType().getQualifier()),
-                resultType(), operands.front(),
-                glslangOperands[0]->getAsTyped()->getBasicType());
+            {
+                OpDecorations decorations = { precision, 
+                                              TranslateNoContractionDecoration(node->getType().getQualifier()),
+                                              TranslateNonUniformDecoration(node->getType().getQualifier()) };
+                result = createUnaryOperation(
+                    node->getOp(), decorations,
+                    resultType(), operands.front(),
+                    glslangOperands[0]->getAsTyped()->getBasicType());
+            }
             break;
         default:
             result = createMiscOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
@@ -1953,18 +2140,29 @@
 // next layer copies r-values into memory to use the access-chain mechanism
 bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang::TIntermSelection* node)
 {
-    // See if it simple and safe to generate OpSelect instead of using control flow.
-    // Crucially, side effects must be avoided, and there are performance trade-offs.
-    // Return true if good idea (and safe) for OpSelect, false otherwise.
-    const auto selectPolicy = [&]() -> bool {
-        if ((!node->getType().isScalar() && !node->getType().isVector()) ||
-            node->getBasicType() == glslang::EbtVoid)
-            return false;
-
+    // See if it simple and safe, or required, to execute both sides.
+    // Crucially, side effects must be either semantically required or avoided,
+    // and there are performance trade-offs.
+    // Return true if required or a good idea (and safe) to execute both sides,
+    // false otherwise.
+    const auto bothSidesPolicy = [&]() -> bool {
+        // do we have both sides?
         if (node->getTrueBlock()  == nullptr ||
             node->getFalseBlock() == nullptr)
             return false;
 
+        // required? (unless we write additional code to look for side effects
+        // and make performance trade-offs if none are present)
+        if (!node->getShortCircuit())
+            return true;
+
+        // if not required to execute both, decide based on performance/practicality...
+
+        // see if OpSelect can handle it
+        if ((!node->getType().isScalar() && !node->getType().isVector()) ||
+            node->getBasicType() == glslang::EbtVoid)
+            return false;
+
         assert(node->getType() == node->getTrueBlock() ->getAsTyped()->getType() &&
                node->getType() == node->getFalseBlock()->getAsTyped()->getType());
 
@@ -1977,10 +2175,14 @@
                operandOkay(node->getFalseBlock()->getAsTyped());
     };
 
-    // Emit OpSelect for this selection.
-    const auto handleAsOpSelect = [&]() {
-        node->getCondition()->traverse(this);
-        spv::Id condition = accessChainLoad(node->getCondition()->getType());
+    spv::Id result = spv::NoResult; // upcoming result selecting between trueValue and falseValue
+    // emit the condition before doing anything with selection
+    node->getCondition()->traverse(this);
+    spv::Id condition = accessChainLoad(node->getCondition()->getType());
+
+    // Find a way of executing both sides and selecting the right result.
+    const auto executeBothSides = [&]() -> void {
+        // execute both sides
         node->getTrueBlock()->traverse(this);
         spv::Id trueValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
         node->getFalseBlock()->traverse(this);
@@ -1988,72 +2190,98 @@
 
         builder.setLine(node->getLoc().line);
 
-        // smear condition to vector, if necessary (AST is always scalar)
-        if (builder.isVector(trueValue))
-            condition = builder.smearScalar(spv::NoPrecision, condition, 
-                                            builder.makeVectorType(builder.makeBoolType(),
-                                                                   builder.getNumComponents(trueValue)));
+        // done if void
+        if (node->getBasicType() == glslang::EbtVoid)
+            return;
 
-        spv::Id select = builder.createTriOp(spv::OpSelect,
-                                             convertGlslangToSpvType(node->getType()), condition,
-                                                                     trueValue, falseValue);
-        builder.clearAccessChain();
-        builder.setAccessChainRValue(select);
+        // emit code to select between trueValue and falseValue
+
+        // see if OpSelect can handle it
+        if (node->getType().isScalar() || node->getType().isVector()) {
+            // Emit OpSelect for this selection.
+
+            // smear condition to vector, if necessary (AST is always scalar)
+            if (builder.isVector(trueValue))
+                condition = builder.smearScalar(spv::NoPrecision, condition, 
+                                                builder.makeVectorType(builder.makeBoolType(),
+                                                                       builder.getNumComponents(trueValue)));
+
+            // OpSelect
+            result = builder.createTriOp(spv::OpSelect,
+                                         convertGlslangToSpvType(node->getType()), condition,
+                                                                 trueValue, falseValue);
+
+            builder.clearAccessChain();
+            builder.setAccessChainRValue(result);
+        } else {
+            // We need control flow to select the result.
+            // TODO: Once SPIR-V OpSelect allows arbitrary types, eliminate this path.
+            result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
+
+            // Selection control:
+            const spv::SelectionControlMask control = TranslateSelectionControl(*node);
+
+            // make an "if" based on the value created by the condition
+            spv::Builder::If ifBuilder(condition, control, builder);
+
+            // emit the "then" statement
+            builder.createStore(trueValue, result);
+            ifBuilder.makeBeginElse();
+            // emit the "else" statement
+            builder.createStore(falseValue, result);
+
+            // finish off the control flow
+            ifBuilder.makeEndIf();
+
+            builder.clearAccessChain();
+            builder.setAccessChainLValue(result);
+        }
     };
 
-    // Try for OpSelect
+    // Execute the one side needed, as per the condition
+    const auto executeOneSide = [&]() {
+        // Always emit control flow.
+        if (node->getBasicType() != glslang::EbtVoid)
+            result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
 
-    if (selectPolicy()) {
+        // Selection control:
+        const spv::SelectionControlMask control = TranslateSelectionControl(*node);
+
+        // make an "if" based on the value created by the condition
+        spv::Builder::If ifBuilder(condition, control, builder);
+
+        // emit the "then" statement
+        if (node->getTrueBlock() != nullptr) {
+            node->getTrueBlock()->traverse(this);
+            if (result != spv::NoResult)
+                builder.createStore(accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()), result);
+        }
+
+        if (node->getFalseBlock() != nullptr) {
+            ifBuilder.makeBeginElse();
+            // emit the "else" statement
+            node->getFalseBlock()->traverse(this);
+            if (result != spv::NoResult)
+                builder.createStore(accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()), result);
+        }
+
+        // finish off the control flow
+        ifBuilder.makeEndIf();
+
+        if (result != spv::NoResult) {
+            builder.clearAccessChain();
+            builder.setAccessChainLValue(result);
+        }
+    };
+
+    // Try for OpSelect (or a requirement to execute both sides)
+    if (bothSidesPolicy()) {
         SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
         if (node->getType().getQualifier().isSpecConstant())
             spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
-
-        handleAsOpSelect();
-        return false;
-    }
-
-    // Instead, emit control flow...    
-    // Don't handle results as temporaries, because there will be two names
-    // and better to leave SSA to later passes.
-    spv::Id result = (node->getBasicType() == glslang::EbtVoid)
-                        ? spv::NoResult
-                        : builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
-
-    // emit the condition before doing anything with selection
-    node->getCondition()->traverse(this);
-
-    // Selection control:
-    const spv::SelectionControlMask control = TranslateSelectionControl(node->getSelectionControl());
-
-    // make an "if" based on the value created by the condition
-    spv::Builder::If ifBuilder(accessChainLoad(node->getCondition()->getType()), control, builder);
-
-    // emit the "then" statement
-    if (node->getTrueBlock() != nullptr) {
-        node->getTrueBlock()->traverse(this);
-        if (result != spv::NoResult)
-             builder.createStore(accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()), result);
-    }
-
-    if (node->getFalseBlock() != nullptr) {
-        ifBuilder.makeBeginElse();
-        // emit the "else" statement
-        node->getFalseBlock()->traverse(this);
-        if (result != spv::NoResult)
-            builder.createStore(accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()), result);
-    }
-
-    // finish off the control flow
-    ifBuilder.makeEndIf();
-
-    if (result != spv::NoResult) {
-        // GLSL only has r-values as the result of a :?, but
-        // if we have an l-value, that can be more efficient if it will
-        // become the base of a complex r-value expression, because the
-        // next layer copies r-values into memory to use the access-chain mechanism
-        builder.clearAccessChain();
-        builder.setAccessChainLValue(result);
-    }
+        executeBothSides();
+    } else
+        executeOneSide();
 
     return false;
 }
@@ -2065,7 +2293,7 @@
     spv::Id selector = accessChainLoad(node->getCondition()->getAsTyped()->getType());
 
     // Selection control:
-    const spv::SelectionControlMask control = TranslateSelectionControl(node->getSelectionControl());
+    const spv::SelectionControlMask control = TranslateSwitchControl(*node);
 
     // browse the children to sort out code segments
     int defaultSegment = -1;
@@ -2125,9 +2353,8 @@
     builder.createBranch(&blocks.head);
 
     // Loop control:
-    const spv::LoopControlMask control = TranslateLoopControl(node->getLoopControl());
-
-    // TODO: dependency length
+    unsigned int dependencyLength = glslang::TIntermLoop::dependencyInfinite;
+    const spv::LoopControlMask control = TranslateLoopControl(*node, dependencyLength);
 
     // Spec requires back edges to target header blocks, and every header block
     // must dominate its merge block.  Make a header block first to ensure these
@@ -2137,7 +2364,7 @@
     // including merges of its own.
     builder.setLine(node->getLoc().line);
     builder.setBuildPoint(&blocks.head);
-    builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control);
+    builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control, dependencyLength);
     if (node->testFirst() && node->getTest()) {
         spv::Block& test = builder.makeNewBlock();
         builder.createBranch(&test);
@@ -2248,25 +2475,23 @@
     spv::StorageClass storageClass = TranslateStorageClass(node->getType());
     spv::Id spvType = convertGlslangToSpvType(node->getType());
 
-#ifdef AMD_EXTENSIONS
     const bool contains16BitType = node->getType().containsBasicType(glslang::EbtFloat16) ||
                                    node->getType().containsBasicType(glslang::EbtInt16)   ||
                                    node->getType().containsBasicType(glslang::EbtUint16);
     if (contains16BitType) {
         if (storageClass == spv::StorageClassInput || storageClass == spv::StorageClassOutput) {
-            builder.addExtension(spv::E_SPV_KHR_16bit_storage);
+            addPre13Extension(spv::E_SPV_KHR_16bit_storage);
             builder.addCapability(spv::CapabilityStorageInputOutput16);
         } else if (storageClass == spv::StorageClassPushConstant) {
-            builder.addExtension(spv::E_SPV_KHR_16bit_storage);
+            addPre13Extension(spv::E_SPV_KHR_16bit_storage);
             builder.addCapability(spv::CapabilityStoragePushConstant16);
         } else if (storageClass == spv::StorageClassUniform) {
-            builder.addExtension(spv::E_SPV_KHR_16bit_storage);
+            addPre13Extension(spv::E_SPV_KHR_16bit_storage);
             builder.addCapability(spv::CapabilityStorageUniform16);
             if (node->getType().getQualifier().storage == glslang::EvqBuffer)
                 builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
         }
     }
-#endif
 
     const char* name = node->getName().c_str();
     if (glslang::IsAnonymous(name))
@@ -2280,6 +2505,12 @@
 {
     switch (sampler.type) {
         case glslang::EbtFloat:    return builder.makeFloatType(32);
+#ifdef AMD_EXTENSIONS
+        case glslang::EbtFloat16:
+            builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
+            builder.addCapability(spv::CapabilityFloat16ImageAMD);
+            return builder.makeFloatType(16);
+#endif
         case glslang::EbtInt:      return builder.makeIntType(32);
         case glslang::EbtUint:     return builder.makeUintType(32);
         default:
@@ -2322,13 +2553,14 @@
 // layout state rooted from the top-level type.
 spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type)
 {
-    return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier());
+    return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier(), false);
 }
 
 // Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
 // explicitLayout can be kept the same throughout the hierarchical recursive walk.
 // Mutually recursive with convertGlslangStructToSpvType().
-spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier)
+spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type,
+    glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier, bool lastBufferBlockMember)
 {
     spv::Id spvType = spv::NoResult;
 
@@ -2343,12 +2575,14 @@
     case glslang::EbtDouble:
         spvType = builder.makeFloatType(64);
         break;
-#ifdef AMD_EXTENSIONS
     case glslang::EbtFloat16:
-        builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
+        builder.addCapability(spv::CapabilityFloat16);
+#if AMD_EXTENSIONS
+        if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+            builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
+#endif
         spvType = builder.makeFloatType(16);
         break;
-#endif
     case glslang::EbtBool:
         // "transparent" bool doesn't exist in SPIR-V.  The GLSL convention is
         // a 32-bit int where non-0 means true.
@@ -2357,6 +2591,30 @@
         else
             spvType = builder.makeBoolType();
         break;
+   case glslang::EbtInt8:
+        builder.addCapability(spv::CapabilityInt8);
+        spvType = builder.makeIntType(8);
+        break;
+    case glslang::EbtUint8:
+        builder.addCapability(spv::CapabilityInt8);
+        spvType = builder.makeUintType(8);
+        break;
+   case glslang::EbtInt16:
+        builder.addCapability(spv::CapabilityInt16);
+#ifdef AMD_EXTENSIONS
+        if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+            builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
+#endif
+        spvType = builder.makeIntType(16);
+        break;
+    case glslang::EbtUint16:
+        builder.addCapability(spv::CapabilityInt16);
+#ifdef AMD_EXTENSIONS
+        if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+            builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
+#endif
+        spvType = builder.makeUintType(16);
+        break;
     case glslang::EbtInt:
         spvType = builder.makeIntType(32);
         break;
@@ -2369,16 +2627,6 @@
     case glslang::EbtUint64:
         spvType = builder.makeUintType(64);
         break;
-#ifdef AMD_EXTENSIONS
-    case glslang::EbtInt16:
-        builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
-        spvType = builder.makeIntType(16);
-        break;
-    case glslang::EbtUint16:
-        builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
-        spvType = builder.makeUintType(16);
-        break;
-#endif
     case glslang::EbtAtomicUint:
         builder.addCapability(spv::CapabilityAtomicStorage);
         spvType = builder.makeUintType(32);
@@ -2442,8 +2690,8 @@
                 // Use a dummy glslang type for querying internal strides of
                 // arrays of arrays, but using just a one-dimensional array.
                 glslang::TType simpleArrayType(type, 0); // deference type of the array
-                while (simpleArrayType.getArraySizes().getNumDims() > 1)
-                    simpleArrayType.getArraySizes().dereference();
+                while (simpleArrayType.getArraySizes()->getNumDims() > 1)
+                    simpleArrayType.getArraySizes()->dereference();
 
                 // Will compute the higher-order strides here, rather than making a whole
                 // pile of types and doing repetitive recursion on their contents.
@@ -2465,12 +2713,16 @@
                 stride = getArrayStride(type, explicitLayout, qualifier.layoutMatrix);
         }
 
-        // Do the outer dimension, which might not be known for a runtime-sized array
-        if (type.isRuntimeSizedArray()) {
-            spvType = builder.makeRuntimeArray(spvType);
-        } else {
-            assert(type.getOuterArraySize() > 0);
+        // Do the outer dimension, which might not be known for a runtime-sized array.
+        // (Unsized arrays that survive through linking will be runtime-sized arrays)
+        if (type.isSizedArray())
             spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride);
+        else {
+            if (!lastBufferBlockMember) {
+                builder.addExtension("SPV_EXT_descriptor_indexing");
+                builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);
+            }
+            spvType = builder.makeRuntimeArray(spvType);
         }
         if (stride > 0)
             builder.addDecoration(spvType, spv::DecorationArrayStride, stride);
@@ -2538,7 +2790,10 @@
                 memberQualifier.layoutLocation = qualifier.layoutLocation;
 
             // recurse
-            spvMembers.push_back(convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier));
+            bool lastBufferBlockMember = qualifier.storage == glslang::EvqBuffer &&
+                                         i == (int)glslangMembers->size() - 1;
+            spvMembers.push_back(
+                convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember));
         }
     }
 
@@ -2576,99 +2831,110 @@
         InheritQualifiers(memberQualifier, qualifier);
 
         // using -1 above to indicate a hidden member
-        if (member >= 0) {
-            builder.addMemberName(spvType, member, glslangMember.getFieldName().c_str());
-            addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangMember, memberQualifier.layoutMatrix));
-            addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangMember));
-            // Add interpolation and auxiliary storage decorations only to top-level members of Input and Output storage classes
-            if (type.getQualifier().storage == glslang::EvqVaryingIn ||
-                type.getQualifier().storage == glslang::EvqVaryingOut) {
-                if (type.getBasicType() == glslang::EbtBlock ||
-                    glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
-                    addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier));
-                    addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier));
-                }
+        if (member < 0)
+            continue;
+
+        builder.addMemberName(spvType, member, glslangMember.getFieldName().c_str());
+        builder.addMemberDecoration(spvType, member,
+                                    TranslateLayoutDecoration(glslangMember, memberQualifier.layoutMatrix));
+        builder.addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangMember));
+        // Add interpolation and auxiliary storage decorations only to
+        // top-level members of Input and Output storage classes
+        if (type.getQualifier().storage == glslang::EvqVaryingIn ||
+            type.getQualifier().storage == glslang::EvqVaryingOut) {
+            if (type.getBasicType() == glslang::EbtBlock ||
+                glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
+                builder.addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier));
+                builder.addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier));
             }
-            addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier));
+        }
+        builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier));
 
-            if (type.getBasicType() == glslang::EbtBlock &&
-                qualifier.storage == glslang::EvqBuffer) {
-                // Add memory decorations only to top-level members of shader storage block
-                std::vector<spv::Decoration> memory;
-                TranslateMemoryDecoration(memberQualifier, memory);
-                for (unsigned int i = 0; i < memory.size(); ++i)
-                    addMemberDecoration(spvType, member, memory[i]);
-            }
+        if (type.getBasicType() == glslang::EbtBlock &&
+            qualifier.storage == glslang::EvqBuffer) {
+            // Add memory decorations only to top-level members of shader storage block
+            std::vector<spv::Decoration> memory;
+            TranslateMemoryDecoration(memberQualifier, memory);
+            for (unsigned int i = 0; i < memory.size(); ++i)
+                builder.addMemberDecoration(spvType, member, memory[i]);
+        }
 
-            // Location assignment was already completed correctly by the front end,
-            // just track whether a member needs to be decorated.
-            // Ignore member locations if the container is an array, as that's
-            // ill-specified and decisions have been made to not allow this.
-            if (! type.isArray() && memberQualifier.hasLocation())
-                builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
+        // Location assignment was already completed correctly by the front end,
+        // just track whether a member needs to be decorated.
+        // Ignore member locations if the container is an array, as that's
+        // ill-specified and decisions have been made to not allow this.
+        if (! type.isArray() && memberQualifier.hasLocation())
+            builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
 
-            if (qualifier.hasLocation())      // track for upcoming inheritance
-                locationOffset += glslangIntermediate->computeTypeLocationSize(glslangMember);
+        if (qualifier.hasLocation())      // track for upcoming inheritance
+            locationOffset += glslangIntermediate->computeTypeLocationSize(
+                                            glslangMember, glslangIntermediate->getStage());
 
-            // component, XFB, others
-            if (glslangMember.getQualifier().hasComponent())
-                builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangMember.getQualifier().layoutComponent);
-            if (glslangMember.getQualifier().hasXfbOffset())
-                builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangMember.getQualifier().layoutXfbOffset);
-            else if (explicitLayout != glslang::ElpNone) {
-                // figure out what to do with offset, which is accumulating
-                int nextOffset;
-                updateMemberOffset(type, glslangMember, offset, nextOffset, explicitLayout, memberQualifier.layoutMatrix);
-                if (offset >= 0)
-                    builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset);
-                offset = nextOffset;
-            }
+        // component, XFB, others
+        if (glslangMember.getQualifier().hasComponent())
+            builder.addMemberDecoration(spvType, member, spv::DecorationComponent,
+                                        glslangMember.getQualifier().layoutComponent);
+        if (glslangMember.getQualifier().hasXfbOffset())
+            builder.addMemberDecoration(spvType, member, spv::DecorationOffset,
+                                        glslangMember.getQualifier().layoutXfbOffset);
+        else if (explicitLayout != glslang::ElpNone) {
+            // figure out what to do with offset, which is accumulating
+            int nextOffset;
+            updateMemberOffset(type, glslangMember, offset, nextOffset, explicitLayout, memberQualifier.layoutMatrix);
+            if (offset >= 0)
+                builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset);
+            offset = nextOffset;
+        }
 
-            if (glslangMember.isMatrix() && explicitLayout != glslang::ElpNone)
-                builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangMember, explicitLayout, memberQualifier.layoutMatrix));
+        if (glslangMember.isMatrix() && explicitLayout != glslang::ElpNone)
+            builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride,
+                                        getMatrixStride(glslangMember, explicitLayout, memberQualifier.layoutMatrix));
 
-            // built-in variable decorations
-            spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangMember.getQualifier().builtIn, true);
-            if (builtIn != spv::BuiltInMax)
-                addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
+        // built-in variable decorations
+        spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangMember.getQualifier().builtIn, true);
+        if (builtIn != spv::BuiltInMax)
+            builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
+
+        // nonuniform
+        builder.addMemberDecoration(spvType, member, TranslateNonUniformDecoration(glslangMember.getQualifier()));
+
+        if (glslangIntermediate->getHlslFunctionality1() && memberQualifier.semanticName != nullptr) {
+            builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
+            builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationHlslSemanticGOOGLE,
+                                        memberQualifier.semanticName);
+        }
 
 #ifdef NV_EXTENSIONS
-            if (builtIn == spv::BuiltInLayer) {
-                // SPV_NV_viewport_array2 extension
-                if (glslangMember.getQualifier().layoutViewportRelative){
-                    addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationViewportRelativeNV);
-                    builder.addCapability(spv::CapabilityShaderViewportMaskNV);
-                    builder.addExtension(spv::E_SPV_NV_viewport_array2);
-                }
-                if (glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset != -2048){
-                    addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationSecondaryViewportRelativeNV, glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset);
-                    builder.addCapability(spv::CapabilityShaderStereoViewNV);
-                    builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
-                }
+        if (builtIn == spv::BuiltInLayer) {
+            // SPV_NV_viewport_array2 extension
+            if (glslangMember.getQualifier().layoutViewportRelative){
+                builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationViewportRelativeNV);
+                builder.addCapability(spv::CapabilityShaderViewportMaskNV);
+                builder.addExtension(spv::E_SPV_NV_viewport_array2);
             }
-            if (glslangMember.getQualifier().layoutPassthrough) {
-                addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationPassthroughNV);
-                builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
-                builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
+            if (glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset != -2048){
+                builder.addMemberDecoration(spvType, member,
+                                            (spv::Decoration)spv::DecorationSecondaryViewportRelativeNV,
+                                            glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset);
+                builder.addCapability(spv::CapabilityShaderStereoViewNV);
+                builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
             }
-#endif
         }
+        if (glslangMember.getQualifier().layoutPassthrough) {
+            builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationPassthroughNV);
+            builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
+            builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
+        }
+#endif
     }
 
     // Decorate the structure
-    addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix));
-    addDecoration(spvType, TranslateBlockDecoration(type, glslangIntermediate->usingStorageBuffer()));
+    builder.addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix));
+    builder.addDecoration(spvType, TranslateBlockDecoration(type, glslangIntermediate->usingStorageBuffer()));
     if (type.getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
         builder.addCapability(spv::CapabilityGeometryStreams);
         builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
     }
-    if (glslangIntermediate->getXfbMode()) {
-        builder.addCapability(spv::CapabilityTransformFeedback);
-        if (type.getQualifier().hasXfbStride())
-            builder.addDecoration(spvType, spv::DecorationXfbStride, type.getQualifier().layoutXfbStride);
-        if (type.getQualifier().hasXfbBuffer())
-            builder.addDecoration(spvType, spv::DecorationXfbBuffer, type.getQualifier().layoutXfbBuffer);
-    }
 }
 
 // Turn the expression forming the array size into an id.
@@ -2699,7 +2965,8 @@
 spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
 {
     spv::Id nominalTypeId = builder.accessChainGetInferredType();
-    spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type), nominalTypeId);
+    spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
+                                               TranslateNonUniformDecoration(type.getQualifier()), nominalTypeId);
 
     // Need to convert to abstract types when necessary
     if (type.getBasicType() == glslang::EbtBool) {
@@ -2972,8 +3239,14 @@
 }
 
 // Does parameter need a place to keep writes, separate from the original?
+// Assumes called after originalParam(), which filters out block/buffer/opaque-based
+// qualifiers such that we should have only in/out/inout/constreadonly here.
 bool TGlslangToSpvTraverser::writableParam(glslang::TStorageQualifier qualifier)
 {
+    assert(qualifier == glslang::EvqIn ||
+           qualifier == glslang::EvqOut ||
+           qualifier == glslang::EvqInOut ||
+           qualifier == glslang::EvqConstReadOnly);
     return qualifier != glslang::EvqConstReadOnly;
 }
 
@@ -2984,7 +3257,7 @@
     if (implicitThisParam)                                                                     // implicit this
         return true;
     if (glslangIntermediate->getSource() == glslang::EShSourceHlsl)
-        return false;
+        return paramType.getBasicType() == glslang::EbtBlock;
     return paramType.containsOpaque() ||                                                       // sampler, etc.
            (paramType.getBasicType() == glslang::EbtBlock && qualifier == glslang::EvqBuffer); // SSBO
 }
@@ -3099,9 +3372,15 @@
 
     glslang::TSampler sampler = {};
     bool cubeCompare = false;
+#ifdef AMD_EXTENSIONS
+    bool f16ShadowCompare = false;
+#endif
     if (node.isTexture() || node.isImage()) {
         sampler = glslangArguments[0]->getAsTyped()->getType().getSampler();
         cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
+#ifdef AMD_EXTENSIONS
+        f16ShadowCompare = sampler.shadow && glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16;
+#endif
     }
 
     for (int i = 0; i < (int)glslangArguments.size(); ++i) {
@@ -3126,6 +3405,21 @@
             if ((sampler.ms && i == 3) || (! sampler.ms && i == 2))
                 lvalue = true;
             break;
+#ifdef AMD_EXTENSIONS
+        case glslang::EOpSparseTexture:
+            if (((cubeCompare || f16ShadowCompare) && i == 3) || (! (cubeCompare || f16ShadowCompare) && i == 2))
+                lvalue = true;
+            break;
+        case glslang::EOpSparseTextureClamp:
+            if (((cubeCompare || f16ShadowCompare) && i == 4) || (! (cubeCompare || f16ShadowCompare) && i == 3))
+                lvalue = true;
+            break;
+        case glslang::EOpSparseTextureLod:
+        case glslang::EOpSparseTextureOffset:
+            if  ((f16ShadowCompare && i == 4) || (! f16ShadowCompare && i == 3))
+                lvalue = true;
+            break;
+#else
         case glslang::EOpSparseTexture:
             if ((cubeCompare && i == 3) || (! cubeCompare && i == 2))
                 lvalue = true;
@@ -3139,6 +3433,7 @@
             if (i == 3)
                 lvalue = true;
             break;
+#endif
         case glslang::EOpSparseTextureFetch:
             if ((sampler.dim != glslang::EsdRect && i == 3) || (sampler.dim == glslang::EsdRect && i == 2))
                 lvalue = true;
@@ -3147,6 +3442,23 @@
             if ((sampler.dim != glslang::EsdRect && i == 4) || (sampler.dim == glslang::EsdRect && i == 3))
                 lvalue = true;
             break;
+#ifdef AMD_EXTENSIONS
+        case glslang::EOpSparseTextureLodOffset:
+        case glslang::EOpSparseTextureGrad:
+        case glslang::EOpSparseTextureOffsetClamp:
+            if ((f16ShadowCompare && i == 5) || (! f16ShadowCompare && i == 4))
+                lvalue = true;
+            break;
+        case glslang::EOpSparseTextureGradOffset:
+        case glslang::EOpSparseTextureGradClamp:
+            if ((f16ShadowCompare && i == 6) || (! f16ShadowCompare && i == 5))
+                lvalue = true;
+            break;
+        case glslang::EOpSparseTextureGradOffsetClamp:
+            if ((f16ShadowCompare && i == 7) || (! f16ShadowCompare && i == 6))
+                lvalue = true;
+            break;
+#else
         case glslang::EOpSparseTextureLodOffset:
         case glslang::EOpSparseTextureGrad:
         case glslang::EOpSparseTextureOffsetClamp:
@@ -3162,6 +3474,7 @@
             if (i == 6)
                 lvalue = true;
             break;
+#endif
         case glslang::EOpSparseTextureGather:
             if ((sampler.shadow && i == 3) || (! sampler.shadow && i == 2))
                 lvalue = true;
@@ -3211,11 +3524,15 @@
 
     builder.setLine(node->getLoc().line);
 
-    auto resultType = [&node,this]{ return convertGlslangToSpvType(node->getType()); };
-
     // Process a GLSL texturing op (will be SPV image)
     const glslang::TSampler sampler = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType().getSampler()
                                                              : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType().getSampler();
+#ifdef AMD_EXTENSIONS
+    bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate())
+                                ? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16
+                                : false;
+#endif
+
     std::vector<spv::Id> arguments;
     if (node->getAsAggregate())
         translateArguments(*node->getAsAggregate(), arguments);
@@ -3261,6 +3578,20 @@
         }
     }
 
+    int components = node->getType().getVectorSize();
+
+    if (node->getOp() == glslang::EOpTextureFetch) {
+        // These must produce 4 components, per SPIR-V spec.  We'll add a conversion constructor if needed.
+        // This will only happen through the HLSL path for operator[], so we do not have to handle e.g.
+        // the EOpTexture/Proj/Lod/etc family.  It would be harmless to do so, but would need more logic
+        // here around e.g. which ones return scalars or other types.
+        components = 4;
+    }
+
+    glslang::TType returnType(node->getType().getBasicType(), glslang::EvqTemporary, components);
+
+    auto resultType = [&returnType,this]{ return convertGlslangToSpvType(returnType); };
+
     // Check for image functions other than queries
     if (node->isImage()) {
         std::vector<spv::Id> operands;
@@ -3307,9 +3638,14 @@
             if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown)
                 builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
 
-            spv::Id result = builder.createOp(spv::OpImageRead, resultType(), operands);
-            builder.setPrecision(result, precision);
-            return result;
+            std::vector<spv::Id> result( 1, builder.createOp(spv::OpImageRead, resultType(), operands) );
+            builder.setPrecision(result[0], precision);
+
+            // If needed, add a conversion constructor to the proper size.
+            if (components != node->getType().getVectorSize())
+                result[0] = builder.createConstructor(precision, result, convertGlslangToSpvType(node->getType()));
+
+            return result[0];
 #ifdef AMD_EXTENSIONS
         } else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod) {
 #else
@@ -3440,6 +3776,9 @@
 #ifdef AMD_EXTENSIONS
         if (cracked.gather)
             ++nonBiasArgCount; // comp argument should be present when bias argument is present
+
+        if (f16ShadowCompare)
+            ++nonBiasArgCount;
 #endif
         if (cracked.offset)
             ++nonBiasArgCount;
@@ -3483,7 +3822,11 @@
     bool noImplicitLod = false;
 
     // sort out where Dref is coming from
+#ifdef AMD_EXTENSIONS
+    if (cubeCompare || f16ShadowCompare) {
+#else
     if (cubeCompare) {
+#endif
         params.Dref = arguments[2];
         ++extraArgs;
     } else if (sampler.shadow && cracked.gather) {
@@ -3583,7 +3926,14 @@
         }
     }
 
-    return builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params);
+    std::vector<spv::Id> result( 1, 
+        builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params)
+    );
+
+    if (components != node->getType().getVectorSize())
+        result[0] = builder.createConstructor(precision, result, convertGlslangToSpvType(node->getType()));
+
+    return result[0];
 }
 
 spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAggregate* node)
@@ -3615,8 +3965,8 @@
         glslangArgs[a]->traverse(this);
         argTypes.push_back(&paramType);
         // keep outputs and pass-by-originals as l-values, evaluate others as r-values
-        if (writableParam(qualifiers[a]) ||
-            originalParam(qualifiers[a], paramType, function->hasImplicitThis() && a == 0)) {
+        if (originalParam(qualifiers[a], paramType, function->hasImplicitThis() && a == 0) ||
+            writableParam(qualifiers[a])) {
             // save l-value
             lValues.push_back(builder.getAccessChain());
         } else {
@@ -3682,18 +4032,12 @@
 }
 
 // Translate AST operation to SPV operation, already having SPV-based operands/types.
-spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv::Decoration precision,
-                                                      spv::Decoration noContraction,
+spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpDecorations& decorations,
                                                       spv::Id typeId, spv::Id left, spv::Id right,
                                                       glslang::TBasicType typeProxy, bool reduceComparison)
 {
-#ifdef AMD_EXTENSIONS
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64 || typeProxy == glslang::EbtUint16;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#else
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
-#endif
+    bool isUnsigned = isTypeUnsignedInt(typeProxy);
+    bool isFloat = isTypeFloat(typeProxy);
     bool isBool = typeProxy == glslang::EbtBool;
 
     spv::Op binOp = spv::OpNop;
@@ -3825,15 +4169,16 @@
     if (binOp != spv::OpNop) {
         assert(comparison == false);
         if (builder.isMatrix(left) || builder.isMatrix(right))
-            return createBinaryMatrixOperation(binOp, precision, noContraction, typeId, left, right);
+            return createBinaryMatrixOperation(binOp, decorations, typeId, left, right);
 
         // No matrix involved; make both operands be the same number of components, if needed
         if (needMatchingVectors)
-            builder.promoteScalar(precision, left, right);
+            builder.promoteScalar(decorations.precision, left, right);
 
         spv::Id result = builder.createBinOp(binOp, typeId, left, right);
-        addDecoration(result, noContraction);
-        return builder.setPrecision(result, precision);
+        builder.addDecoration(result, decorations.noContraction);
+        builder.addDecoration(result, decorations.nonUniform);
+        return builder.setPrecision(result, decorations.precision);
     }
 
     if (! comparison)
@@ -3842,8 +4187,11 @@
     // Handle comparison instructions
 
     if (reduceComparison && (op == glslang::EOpEqual || op == glslang::EOpNotEqual)
-                         && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left)))
-        return builder.createCompositeCompare(precision, left, right, op == glslang::EOpEqual);
+                         && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) {
+        spv::Id result = builder.createCompositeCompare(decorations.precision, left, right, op == glslang::EOpEqual);
+        builder.addDecoration(result, decorations.nonUniform);
+        return result;
+    }
 
     switch (op) {
     case glslang::EOpLessThan:
@@ -3902,8 +4250,9 @@
 
     if (binOp != spv::OpNop) {
         spv::Id result = builder.createBinOp(binOp, typeId, left, right);
-        addDecoration(result, noContraction);
-        return builder.setPrecision(result, precision);
+        builder.addDecoration(result, decorations.noContraction);
+        builder.addDecoration(result, decorations.nonUniform);
+        return builder.setPrecision(result, decorations.precision);
     }
 
     return 0;
@@ -3923,7 +4272,8 @@
 //   matrix op scalar    op in {+, -, /}
 //   scalar op matrix    op in {+, -, /}
 //
-spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id left, spv::Id right)
+spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecorations& decorations, spv::Id typeId,
+                                                            spv::Id left, spv::Id right)
 {
     bool firstClass = true;
 
@@ -3932,7 +4282,8 @@
     case spv::OpFDiv:
         if (builder.isMatrix(left) && builder.isScalar(right)) {
             // turn matrix / scalar into a multiply...
-            right = builder.createBinOp(spv::OpFDiv, builder.getTypeId(right), builder.makeFloatConstant(1.0F), right);
+            spv::Id resultType = builder.getTypeId(right);
+            right = builder.createBinOp(spv::OpFDiv, resultType, builder.makeFpConstant(resultType, 1.0), right);
             op = spv::OpMatrixTimesScalar;
         } else
             firstClass = false;
@@ -3961,8 +4312,9 @@
 
     if (firstClass) {
         spv::Id result = builder.createBinOp(op, typeId, left, right);
-        addDecoration(result, noContraction);
-        return builder.setPrecision(result, precision);
+        builder.addDecoration(result, decorations.noContraction);
+        builder.addDecoration(result, decorations.nonUniform);
+        return builder.setPrecision(result, decorations.precision);
     }
 
     // Handle component-wise +, -, *, %, and / for all combinations of type.
@@ -3989,9 +4341,9 @@
         std::vector<spv::Id> results;
         spv::Id smearVec = spv::NoResult;
         if (builder.isScalar(left))
-            smearVec = builder.smearScalar(precision, left, vecType);
+            smearVec = builder.smearScalar(decorations.precision, left, vecType);
         else if (builder.isScalar(right))
-            smearVec = builder.smearScalar(precision, right, vecType);
+            smearVec = builder.smearScalar(decorations.precision, right, vecType);
 
         // do each vector op
         for (unsigned int c = 0; c < numCols; ++c) {
@@ -4000,12 +4352,15 @@
             spv::Id  leftVec =  leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec;
             spv::Id rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec;
             spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec);
-            addDecoration(result, noContraction);
-            results.push_back(builder.setPrecision(result, precision));
+            builder.addDecoration(result, decorations.noContraction);
+            builder.addDecoration(result, decorations.nonUniform);
+            results.push_back(builder.setPrecision(result, decorations.precision));
         }
 
         // put the pieces together
-        return  builder.setPrecision(builder.createCompositeConstruct(typeId, results), precision);
+        spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision);
+        builder.addDecoration(result, decorations.nonUniform);
+        return result;
     }
     default:
         assert(0);
@@ -4013,25 +4368,21 @@
     }
 }
 
-spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId,
+                                                     spv::Id operand, glslang::TBasicType typeProxy)
 {
     spv::Op unaryOp = spv::OpNop;
     int extBuiltins = -1;
     int libCall = -1;
-#ifdef AMD_EXTENSIONS
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64 || typeProxy == glslang::EbtUint16;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#else
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
-#endif
+    bool isUnsigned = isTypeUnsignedInt(typeProxy);
+    bool isFloat = isTypeFloat(typeProxy);
 
     switch (op) {
     case glslang::EOpNegative:
         if (isFloat) {
             unaryOp = spv::OpFNegate;
             if (builder.isMatrixType(typeId))
-                return createUnaryMatrixOperation(unaryOp, precision, noContraction, typeId, operand, typeProxy);
+                return createUnaryMatrixOperation(unaryOp, decorations, typeId, operand, typeProxy);
         } else
             unaryOp = spv::OpSNegate;
         break;
@@ -4161,12 +4512,10 @@
     case glslang::EOpDoubleBitsToUint64:
     case glslang::EOpInt64BitsToDouble:
     case glslang::EOpUint64BitsToDouble:
-#ifdef AMD_EXTENSIONS
     case glslang::EOpFloat16BitsToInt16:
     case glslang::EOpFloat16BitsToUint16:
     case glslang::EOpInt16BitsToFloat16:
     case glslang::EOpUint16BitsToFloat16:
-#endif
         unaryOp = spv::OpBitcast;
         break;
 
@@ -4211,10 +4560,12 @@
     case glslang::EOpUnpackInt2x32:
     case glslang::EOpPackUint2x32:
     case glslang::EOpUnpackUint2x32:
-        unaryOp = spv::OpBitcast;
-        break;
-
-#ifdef AMD_EXTENSIONS
+    case glslang::EOpPack16:
+    case glslang::EOpPack32:
+    case glslang::EOpPack64:
+    case glslang::EOpUnpack32:
+    case glslang::EOpUnpack16:
+    case glslang::EOpUnpack8:
     case glslang::EOpPackInt2x16:
     case glslang::EOpUnpackInt2x16:
     case glslang::EOpPackUint2x16:
@@ -4227,7 +4578,6 @@
     case glslang::EOpUnpackFloat2x16:
         unaryOp = spv::OpBitcast;
         break;
-#endif
 
     case glslang::EOpDPdx:
         unaryOp = spv::OpDPdx;
@@ -4293,7 +4643,7 @@
         // Handle all of the atomics in one place, in createAtomicOperation()
         std::vector<spv::Id> operands;
         operands.push_back(operand);
-        return createAtomicOperation(op, precision, typeId, operands, typeProxy);
+        return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy);
     }
 
     case glslang::EOpBitFieldReverse:
@@ -4342,7 +4692,45 @@
         operands.push_back(operand);
         return createInvocationsOperation(op, typeId, operands, typeProxy);
     }
-
+    case glslang::EOpSubgroupAll:
+    case glslang::EOpSubgroupAny:
+    case glslang::EOpSubgroupAllEqual:
+    case glslang::EOpSubgroupBroadcastFirst:
+    case glslang::EOpSubgroupBallot:
+    case glslang::EOpSubgroupInverseBallot:
+    case glslang::EOpSubgroupBallotBitCount:
+    case glslang::EOpSubgroupBallotInclusiveBitCount:
+    case glslang::EOpSubgroupBallotExclusiveBitCount:
+    case glslang::EOpSubgroupBallotFindLSB:
+    case glslang::EOpSubgroupBallotFindMSB:
+    case glslang::EOpSubgroupAdd:
+    case glslang::EOpSubgroupMul:
+    case glslang::EOpSubgroupMin:
+    case glslang::EOpSubgroupMax:
+    case glslang::EOpSubgroupAnd:
+    case glslang::EOpSubgroupOr:
+    case glslang::EOpSubgroupXor:
+    case glslang::EOpSubgroupInclusiveAdd:
+    case glslang::EOpSubgroupInclusiveMul:
+    case glslang::EOpSubgroupInclusiveMin:
+    case glslang::EOpSubgroupInclusiveMax:
+    case glslang::EOpSubgroupInclusiveAnd:
+    case glslang::EOpSubgroupInclusiveOr:
+    case glslang::EOpSubgroupInclusiveXor:
+    case glslang::EOpSubgroupExclusiveAdd:
+    case glslang::EOpSubgroupExclusiveMul:
+    case glslang::EOpSubgroupExclusiveMin:
+    case glslang::EOpSubgroupExclusiveMax:
+    case glslang::EOpSubgroupExclusiveAnd:
+    case glslang::EOpSubgroupExclusiveOr:
+    case glslang::EOpSubgroupExclusiveXor:
+    case glslang::EOpSubgroupQuadSwapHorizontal:
+    case glslang::EOpSubgroupQuadSwapVertical:
+    case glslang::EOpSubgroupQuadSwapDiagonal: {
+        std::vector<spv::Id> operands;
+        operands.push_back(operand);
+        return createSubgroupOperation(op, typeId, operands, typeProxy);
+    }
 #ifdef AMD_EXTENSIONS
     case glslang::EOpMbcnt:
         extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_ballot);
@@ -4359,7 +4747,13 @@
         libCall = spv::CubeFaceCoordAMD;
         break;
 #endif
-
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartition:
+        builder.addExtension(spv::E_SPV_NV_shader_subgroup_partitioned);
+        builder.addCapability(spv::CapabilityGroupNonUniformPartitionedNV);
+        unaryOp = spv::OpGroupNonUniformPartitionNV;
+        break;
+#endif
     default:
         return 0;
     }
@@ -4373,12 +4767,14 @@
         id = builder.createUnaryOp(unaryOp, typeId, operand);
     }
 
-    addDecoration(id, noContraction);
-    return builder.setPrecision(id, precision);
+    builder.addDecoration(id, decorations.noContraction);
+    builder.addDecoration(id, decorations.nonUniform);
+    return builder.setPrecision(id, decorations.precision);
 }
 
 // Create a unary operation on a matrix
-spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand, glslang::TBasicType /* typeProxy */)
+spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, OpDecorations& decorations, spv::Id typeId,
+                                                           spv::Id operand, glslang::TBasicType /* typeProxy */)
 {
     // Handle unary operations vector by vector.
     // The result type is the same type as the original type.
@@ -4400,40 +4796,162 @@
         indexes.push_back(c);
         spv::Id srcVec  = builder.createCompositeExtract(operand, srcVecType, indexes);
         spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec);
-        addDecoration(destVec, noContraction);
-        results.push_back(builder.setPrecision(destVec, precision));
+        builder.addDecoration(destVec, decorations.noContraction);
+        builder.addDecoration(destVec, decorations.nonUniform);
+        results.push_back(builder.setPrecision(destVec, decorations.precision));
     }
 
     // put the pieces together
-    return builder.setPrecision(builder.createCompositeConstruct(typeId, results), precision);
+    spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision);
+    builder.addDecoration(result, decorations.nonUniform);
+    return result;
 }
 
-spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id destType, spv::Id operand, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize)
+{
+    spv::Op convOp = spv::OpNop;
+    spv::Id type = 0;
+
+    spv::Id result = 0;
+
+    switch(op) {
+    case glslang::EOpConvInt8ToUint16:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvInt8ToUint:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(32);
+        break;
+    case glslang::EOpConvInt8ToUint64:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvInt16ToUint8:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvInt16ToUint:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(32);
+        break;
+    case glslang::EOpConvInt16ToUint64:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvIntToUint8:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvIntToUint16:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvIntToUint64:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvInt64ToUint8:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvInt64ToUint16:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvInt64ToUint:
+        convOp = spv::OpSConvert;
+        type   = builder.makeIntType(32);
+        break;
+    case glslang::EOpConvUint8ToInt16:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvUint8ToInt:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(32);
+        break;
+    case glslang::EOpConvUint8ToInt64:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvUint16ToInt8:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvUint16ToInt:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(32);
+        break;
+    case glslang::EOpConvUint16ToInt64:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvUintToInt8:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvUintToInt16:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvUintToInt64:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(64);
+        break;
+    case glslang::EOpConvUint64ToInt8:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(8);
+        break;
+    case glslang::EOpConvUint64ToInt16:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(16);
+        break;
+    case glslang::EOpConvUint64ToInt:
+        convOp = spv::OpUConvert;
+        type   = builder.makeIntType(32);
+        break;
+
+    default:
+        assert(false && "Default missing");
+        break;
+    }
+
+    if (vectorSize > 0)
+        type = builder.makeVectorType(type, vectorSize);
+
+    result = builder.createUnaryOp(convOp, type, operand);
+    return result;
+}
+
+spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecorations& decorations, spv::Id destType,
+                                                 spv::Id operand, glslang::TBasicType typeProxy)
 {
     spv::Op convOp = spv::OpNop;
     spv::Id zero = 0;
     spv::Id one = 0;
-    spv::Id type = 0;
 
     int vectorSize = builder.isVectorType(destType) ? builder.getNumTypeComponents(destType) : 0;
 
     switch (op) {
-    case glslang::EOpConvIntToBool:
-    case glslang::EOpConvUintToBool:
-    case glslang::EOpConvInt64ToBool:
-    case glslang::EOpConvUint64ToBool:
-#ifdef AMD_EXTENSIONS
+    case glslang::EOpConvInt8ToBool:
+    case glslang::EOpConvUint8ToBool:
+        zero = builder.makeUint8Constant(0);
+        zero = makeSmearedConstant(zero, vectorSize);
+        return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
     case glslang::EOpConvInt16ToBool:
     case glslang::EOpConvUint16ToBool:
-#endif
-        if (op == glslang::EOpConvInt64ToBool || op == glslang::EOpConvUint64ToBool)
-            zero = builder.makeUint64Constant(0);
-#ifdef AMD_EXTENSIONS
-        else if (op == glslang::EOpConvInt16ToBool || op == glslang::EOpConvUint16ToBool)
-            zero = builder.makeUint16Constant(0);
-#endif
-        else
-            zero = builder.makeUintConstant(0);
+        zero = builder.makeUint16Constant(0);
+        zero = makeSmearedConstant(zero, vectorSize);
+        return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
+    case glslang::EOpConvIntToBool:
+    case glslang::EOpConvUintToBool:
+        zero = builder.makeUintConstant(0);
+        zero = makeSmearedConstant(zero, vectorSize);
+        return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
+    case glslang::EOpConvInt64ToBool:
+    case glslang::EOpConvUint64ToBool:
+        zero = builder.makeUint64Constant(0);
         zero = makeSmearedConstant(zero, vectorSize);
         return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
 
@@ -4447,12 +4965,10 @@
         zero = makeSmearedConstant(zero, vectorSize);
         return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
 
-#ifdef AMD_EXTENSIONS
     case glslang::EOpConvFloat16ToBool:
         zero = builder.makeFloat16Constant(0.0F);
         zero = makeSmearedConstant(zero, vectorSize);
         return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
-#endif
 
     case glslang::EOpConvBoolToFloat:
         convOp = spv::OpSelect;
@@ -4466,34 +4982,45 @@
         one  = builder.makeDoubleConstant(1.0);
         break;
 
-#ifdef AMD_EXTENSIONS
     case glslang::EOpConvBoolToFloat16:
         convOp = spv::OpSelect;
         zero = builder.makeFloat16Constant(0.0F);
         one = builder.makeFloat16Constant(1.0F);
         break;
-#endif
+
+    case glslang::EOpConvBoolToInt8:
+        zero = builder.makeInt8Constant(0);
+        one  = builder.makeInt8Constant(1);
+        convOp = spv::OpSelect;
+        break;
+
+    case glslang::EOpConvBoolToUint8:
+        zero = builder.makeUint8Constant(0);
+        one  = builder.makeUint8Constant(1);
+        convOp = spv::OpSelect;
+        break;
+
+    case glslang::EOpConvBoolToInt16:
+        zero = builder.makeInt16Constant(0);
+        one  = builder.makeInt16Constant(1);
+        convOp = spv::OpSelect;
+        break;
+
+    case glslang::EOpConvBoolToUint16:
+        zero = builder.makeUint16Constant(0);
+        one  = builder.makeUint16Constant(1);
+        convOp = spv::OpSelect;
+        break;
 
     case glslang::EOpConvBoolToInt:
     case glslang::EOpConvBoolToInt64:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvBoolToInt16:
-#endif
         if (op == glslang::EOpConvBoolToInt64)
             zero = builder.makeInt64Constant(0);
-#ifdef AMD_EXTENSIONS
-        else if (op == glslang::EOpConvBoolToInt16)
-            zero = builder.makeInt16Constant(0);
-#endif
         else
             zero = builder.makeIntConstant(0);
 
         if (op == glslang::EOpConvBoolToInt64)
             one = builder.makeInt64Constant(1);
-#ifdef AMD_EXTENSIONS
-        else if (op == glslang::EOpConvBoolToInt16)
-            one = builder.makeInt16Constant(1);
-#endif
         else
             one = builder.makeIntConstant(1);
 
@@ -4502,104 +5029,94 @@
 
     case glslang::EOpConvBoolToUint:
     case glslang::EOpConvBoolToUint64:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvBoolToUint16:
-#endif
         if (op == glslang::EOpConvBoolToUint64)
             zero = builder.makeUint64Constant(0);
-#ifdef AMD_EXTENSIONS
-        else if (op == glslang::EOpConvBoolToUint16)
-            zero = builder.makeUint16Constant(0);
-#endif
         else
             zero = builder.makeUintConstant(0);
 
         if (op == glslang::EOpConvBoolToUint64)
             one = builder.makeUint64Constant(1);
-#ifdef AMD_EXTENSIONS
-        else if (op == glslang::EOpConvBoolToUint16)
-            one = builder.makeUint16Constant(1);
-#endif
         else
             one = builder.makeUintConstant(1);
 
         convOp = spv::OpSelect;
         break;
 
+    case glslang::EOpConvInt8ToFloat16:
+    case glslang::EOpConvInt8ToFloat:
+    case glslang::EOpConvInt8ToDouble:
+    case glslang::EOpConvInt16ToFloat16:
+    case glslang::EOpConvInt16ToFloat:
+    case glslang::EOpConvInt16ToDouble:
+    case glslang::EOpConvIntToFloat16:
     case glslang::EOpConvIntToFloat:
     case glslang::EOpConvIntToDouble:
     case glslang::EOpConvInt64ToFloat:
     case glslang::EOpConvInt64ToDouble:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvInt16ToFloat:
-    case glslang::EOpConvInt16ToDouble:
-    case glslang::EOpConvInt16ToFloat16:
-    case glslang::EOpConvIntToFloat16:
     case glslang::EOpConvInt64ToFloat16:
-#endif
         convOp = spv::OpConvertSToF;
         break;
 
+    case glslang::EOpConvUint8ToFloat16:
+    case glslang::EOpConvUint8ToFloat:
+    case glslang::EOpConvUint8ToDouble:
+    case glslang::EOpConvUint16ToFloat16:
+    case glslang::EOpConvUint16ToFloat:
+    case glslang::EOpConvUint16ToDouble:
+    case glslang::EOpConvUintToFloat16:
     case glslang::EOpConvUintToFloat:
     case glslang::EOpConvUintToDouble:
     case glslang::EOpConvUint64ToFloat:
     case glslang::EOpConvUint64ToDouble:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvUint16ToFloat:
-    case glslang::EOpConvUint16ToDouble:
-    case glslang::EOpConvUint16ToFloat16:
-    case glslang::EOpConvUintToFloat16:
     case glslang::EOpConvUint64ToFloat16:
-#endif
         convOp = spv::OpConvertUToF;
         break;
 
     case glslang::EOpConvDoubleToFloat:
     case glslang::EOpConvFloatToDouble:
-#ifdef AMD_EXTENSIONS
     case glslang::EOpConvDoubleToFloat16:
     case glslang::EOpConvFloat16ToDouble:
     case glslang::EOpConvFloatToFloat16:
     case glslang::EOpConvFloat16ToFloat:
-#endif
         convOp = spv::OpFConvert;
         if (builder.isMatrixType(destType))
-            return createUnaryMatrixOperation(convOp, precision, noContraction, destType, operand, typeProxy);
+            return createUnaryMatrixOperation(convOp, decorations, destType, operand, typeProxy);
         break;
 
-    case glslang::EOpConvFloatToInt:
-    case glslang::EOpConvDoubleToInt:
-    case glslang::EOpConvFloatToInt64:
-    case glslang::EOpConvDoubleToInt64:
-#ifdef AMD_EXTENSIONS
+    case glslang::EOpConvFloat16ToInt8:
+    case glslang::EOpConvFloatToInt8:
+    case glslang::EOpConvDoubleToInt8:
+    case glslang::EOpConvFloat16ToInt16:
     case glslang::EOpConvFloatToInt16:
     case glslang::EOpConvDoubleToInt16:
-    case glslang::EOpConvFloat16ToInt16:
     case glslang::EOpConvFloat16ToInt:
+    case glslang::EOpConvFloatToInt:
+    case glslang::EOpConvDoubleToInt:
     case glslang::EOpConvFloat16ToInt64:
-#endif
+    case glslang::EOpConvFloatToInt64:
+    case glslang::EOpConvDoubleToInt64:
         convOp = spv::OpConvertFToS;
         break;
 
+    case glslang::EOpConvUint8ToInt8:
+    case glslang::EOpConvInt8ToUint8:
+    case glslang::EOpConvUint16ToInt16:
+    case glslang::EOpConvInt16ToUint16:
     case glslang::EOpConvUintToInt:
     case glslang::EOpConvIntToUint:
     case glslang::EOpConvUint64ToInt64:
     case glslang::EOpConvInt64ToUint64:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvUint16ToInt16:
-    case glslang::EOpConvInt16ToUint16:
-#endif
         if (builder.isInSpecConstCodeGenMode()) {
             // Build zero scalar or vector for OpIAdd.
-            if (op == glslang::EOpConvUint64ToInt64 || op == glslang::EOpConvInt64ToUint64)
-                zero = builder.makeUint64Constant(0);
-#ifdef AMD_EXTENSIONS
-            else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16)
+            if(op == glslang::EOpConvUint8ToInt8 || op == glslang::EOpConvInt8ToUint8) {
+                zero = builder.makeUint8Constant(0);
+            } else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16) {
                 zero = builder.makeUint16Constant(0);
-#endif
-            else
+            } else if (op == glslang::EOpConvUint64ToInt64 || op == glslang::EOpConvInt64ToUint64) {
+                zero = builder.makeUint64Constant(0);
+            } else {
                 zero = builder.makeUintConstant(0);
-
+            }
             zero = makeSmearedConstant(zero, vectorSize);
             // Use OpIAdd, instead of OpBitcast to do the conversion when
             // generating for OpSpecConstantOp instruction.
@@ -4609,126 +5126,117 @@
         convOp = spv::OpBitcast;
         break;
 
+    case glslang::EOpConvFloat16ToUint8:
+    case glslang::EOpConvFloatToUint8:
+    case glslang::EOpConvDoubleToUint8:
+    case glslang::EOpConvFloat16ToUint16:
+    case glslang::EOpConvFloatToUint16:
+    case glslang::EOpConvDoubleToUint16:
+    case glslang::EOpConvFloat16ToUint:
     case glslang::EOpConvFloatToUint:
     case glslang::EOpConvDoubleToUint:
     case glslang::EOpConvFloatToUint64:
     case glslang::EOpConvDoubleToUint64:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvFloatToUint16:
-    case glslang::EOpConvDoubleToUint16:
-    case glslang::EOpConvFloat16ToUint16:
-    case glslang::EOpConvFloat16ToUint:
     case glslang::EOpConvFloat16ToUint64:
-#endif
         convOp = spv::OpConvertFToU;
         break;
 
-    case glslang::EOpConvIntToInt64:
-    case glslang::EOpConvInt64ToInt:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvIntToInt16:
+    case glslang::EOpConvInt8ToInt16:
+    case glslang::EOpConvInt8ToInt:
+    case glslang::EOpConvInt8ToInt64:
+    case glslang::EOpConvInt16ToInt8:
     case glslang::EOpConvInt16ToInt:
-    case glslang::EOpConvInt64ToInt16:
     case glslang::EOpConvInt16ToInt64:
-#endif
+    case glslang::EOpConvIntToInt8:
+    case glslang::EOpConvIntToInt16:
+    case glslang::EOpConvIntToInt64:
+    case glslang::EOpConvInt64ToInt8:
+    case glslang::EOpConvInt64ToInt16:
+    case glslang::EOpConvInt64ToInt:
         convOp = spv::OpSConvert;
         break;
 
-    case glslang::EOpConvUintToUint64:
-    case glslang::EOpConvUint64ToUint:
-#ifdef AMD_EXTENSIONS
-    case glslang::EOpConvUintToUint16:
+    case glslang::EOpConvUint8ToUint16:
+    case glslang::EOpConvUint8ToUint:
+    case glslang::EOpConvUint8ToUint64:
+    case glslang::EOpConvUint16ToUint8:
     case glslang::EOpConvUint16ToUint:
-    case glslang::EOpConvUint64ToUint16:
     case glslang::EOpConvUint16ToUint64:
-#endif
+    case glslang::EOpConvUintToUint8:
+    case glslang::EOpConvUintToUint16:
+    case glslang::EOpConvUintToUint64:
+    case glslang::EOpConvUint64ToUint8:
+    case glslang::EOpConvUint64ToUint16:
+    case glslang::EOpConvUint64ToUint:
         convOp = spv::OpUConvert;
         break;
 
-    case glslang::EOpConvIntToUint64:
-    case glslang::EOpConvInt64ToUint:
-    case glslang::EOpConvUint64ToInt:
-    case glslang::EOpConvUintToInt64:
-#ifdef AMD_EXTENSIONS
+    case glslang::EOpConvInt8ToUint16:
+    case glslang::EOpConvInt8ToUint:
+    case glslang::EOpConvInt8ToUint64:
+    case glslang::EOpConvInt16ToUint8:
     case glslang::EOpConvInt16ToUint:
-    case glslang::EOpConvUintToInt16:
     case glslang::EOpConvInt16ToUint64:
-    case glslang::EOpConvUint64ToInt16:
-    case glslang::EOpConvUint16ToInt:
+    case glslang::EOpConvIntToUint8:
     case glslang::EOpConvIntToUint16:
-    case glslang::EOpConvUint16ToInt64:
+    case glslang::EOpConvIntToUint64:
+    case glslang::EOpConvInt64ToUint8:
     case glslang::EOpConvInt64ToUint16:
-#endif
+    case glslang::EOpConvInt64ToUint:
+    case glslang::EOpConvUint8ToInt16:
+    case glslang::EOpConvUint8ToInt:
+    case glslang::EOpConvUint8ToInt64:
+    case glslang::EOpConvUint16ToInt8:
+    case glslang::EOpConvUint16ToInt:
+    case glslang::EOpConvUint16ToInt64:
+    case glslang::EOpConvUintToInt8:
+    case glslang::EOpConvUintToInt16:
+    case glslang::EOpConvUintToInt64:
+    case glslang::EOpConvUint64ToInt8:
+    case glslang::EOpConvUint64ToInt16:
+    case glslang::EOpConvUint64ToInt:
         // OpSConvert/OpUConvert + OpBitCast
-        switch (op) {
-        case glslang::EOpConvIntToUint64:
-#ifdef AMD_EXTENSIONS
-        case glslang::EOpConvInt16ToUint64:
-#endif
-            convOp = spv::OpSConvert;
-            type   = builder.makeIntType(64);
-            break;
-        case glslang::EOpConvInt64ToUint:
-#ifdef AMD_EXTENSIONS
-        case glslang::EOpConvInt16ToUint:
-#endif
-            convOp = spv::OpSConvert;
-            type   = builder.makeIntType(32);
-            break;
-        case glslang::EOpConvUint64ToInt:
-#ifdef AMD_EXTENSIONS
-        case glslang::EOpConvUint16ToInt:
-#endif
-            convOp = spv::OpUConvert;
-            type   = builder.makeUintType(32);
-            break;
-        case glslang::EOpConvUintToInt64:
-#ifdef AMD_EXTENSIONS
-        case glslang::EOpConvUint16ToInt64:
-#endif
-            convOp = spv::OpUConvert;
-            type   = builder.makeUintType(64);
-            break;
-#ifdef AMD_EXTENSIONS
-        case glslang::EOpConvUintToInt16:
-        case glslang::EOpConvUint64ToInt16:
-            convOp = spv::OpUConvert;
-            type   = builder.makeUintType(16);
-            break;
-        case glslang::EOpConvIntToUint16:
-        case glslang::EOpConvInt64ToUint16:
-            convOp = spv::OpSConvert;
-            type   = builder.makeIntType(16);
-            break;
-#endif
-        default:
-            assert(0);
-            break;
-        }
-
-        if (vectorSize > 0)
-            type = builder.makeVectorType(type, vectorSize);
-
-        operand = builder.createUnaryOp(convOp, type, operand);
+        operand = createConversionOperation(op, operand, vectorSize);
 
         if (builder.isInSpecConstCodeGenMode()) {
             // Build zero scalar or vector for OpIAdd.
-#ifdef AMD_EXTENSIONS
-            if (op == glslang::EOpConvIntToUint64 || op == glslang::EOpConvUintToInt64 ||
-                op == glslang::EOpConvInt16ToUint64 || op == glslang::EOpConvUint16ToInt64)
-                zero = builder.makeUint64Constant(0);
-            else if (op == glslang::EOpConvIntToUint16 || op == glslang::EOpConvUintToInt16 ||
-                     op == glslang::EOpConvInt64ToUint16 || op == glslang::EOpConvUint64ToInt16)
+            switch(op) {
+            case glslang::EOpConvInt16ToUint8:
+            case glslang::EOpConvIntToUint8:
+            case glslang::EOpConvInt64ToUint8:
+            case glslang::EOpConvUint16ToInt8:
+            case glslang::EOpConvUintToInt8:
+            case glslang::EOpConvUint64ToInt8:
+                zero = builder.makeUint8Constant(0);
+                break;
+            case glslang::EOpConvInt8ToUint16:
+            case glslang::EOpConvIntToUint16:
+            case glslang::EOpConvInt64ToUint16:
+            case glslang::EOpConvUint8ToInt16:
+            case glslang::EOpConvUintToInt16:
+            case glslang::EOpConvUint64ToInt16:
                 zero = builder.makeUint16Constant(0);
-            else
+                break;
+            case glslang::EOpConvInt8ToUint:
+            case glslang::EOpConvInt16ToUint:
+            case glslang::EOpConvInt64ToUint:
+            case glslang::EOpConvUint8ToInt:
+            case glslang::EOpConvUint16ToInt:
+            case glslang::EOpConvUint64ToInt:
                 zero = builder.makeUintConstant(0);
-#else
-            if (op == glslang::EOpConvIntToUint64 || op == glslang::EOpConvUintToInt64)
+                break;
+            case glslang::EOpConvInt8ToUint64:
+            case glslang::EOpConvInt16ToUint64:
+            case glslang::EOpConvIntToUint64:
+            case glslang::EOpConvUint8ToInt64:
+            case glslang::EOpConvUint16ToInt64:
+            case glslang::EOpConvUintToInt64:
                 zero = builder.makeUint64Constant(0);
-            else
-                zero = builder.makeUintConstant(0);
-#endif
-
+                break;
+            default:
+                assert(false && "Default missing");
+                break;
+            }
             zero = makeSmearedConstant(zero, vectorSize);
             // Use OpIAdd, instead of OpBitcast to do the conversion when
             // generating for OpSpecConstantOp instruction.
@@ -4752,7 +5260,9 @@
     } else
         result = builder.createUnaryOp(convOp, destType, operand);
 
-    return builder.setPrecision(result, precision);
+    result = builder.setPrecision(result, decorations.precision);
+    builder.addDecoration(result, decorations.nonUniform);
+    return result;
 }
 
 spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vectorSize)
@@ -4870,10 +5380,8 @@
 // Create group invocation operations.
 spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
 {
-#ifdef AMD_EXTENSIONS
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#endif
+    bool isUnsigned = isTypeUnsignedInt(typeProxy);
+    bool isFloat = isTypeFloat(typeProxy);
 
     spv::Op opCode = spv::OpNop;
     std::vector<spv::Id> spvGroupOperands;
@@ -5134,15 +5642,353 @@
     return builder.createCompositeConstruct(typeId, results);
 }
 
+// Create subgroup invocation operations.
+spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
+{
+    // Add the required capabilities.
+    switch (op) {
+    case glslang::EOpSubgroupElect:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        break;
+    case glslang::EOpSubgroupAll:
+    case glslang::EOpSubgroupAny:
+    case glslang::EOpSubgroupAllEqual:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformVote);
+        break;
+    case glslang::EOpSubgroupBroadcast:
+    case glslang::EOpSubgroupBroadcastFirst:
+    case glslang::EOpSubgroupBallot:
+    case glslang::EOpSubgroupInverseBallot:
+    case glslang::EOpSubgroupBallotBitExtract:
+    case glslang::EOpSubgroupBallotBitCount:
+    case glslang::EOpSubgroupBallotInclusiveBitCount:
+    case glslang::EOpSubgroupBallotExclusiveBitCount:
+    case glslang::EOpSubgroupBallotFindLSB:
+    case glslang::EOpSubgroupBallotFindMSB:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+        break;
+    case glslang::EOpSubgroupShuffle:
+    case glslang::EOpSubgroupShuffleXor:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformShuffle);
+        break;
+    case glslang::EOpSubgroupShuffleUp:
+    case glslang::EOpSubgroupShuffleDown:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformShuffleRelative);
+        break;
+    case glslang::EOpSubgroupAdd:
+    case glslang::EOpSubgroupMul:
+    case glslang::EOpSubgroupMin:
+    case glslang::EOpSubgroupMax:
+    case glslang::EOpSubgroupAnd:
+    case glslang::EOpSubgroupOr:
+    case glslang::EOpSubgroupXor:
+    case glslang::EOpSubgroupInclusiveAdd:
+    case glslang::EOpSubgroupInclusiveMul:
+    case glslang::EOpSubgroupInclusiveMin:
+    case glslang::EOpSubgroupInclusiveMax:
+    case glslang::EOpSubgroupInclusiveAnd:
+    case glslang::EOpSubgroupInclusiveOr:
+    case glslang::EOpSubgroupInclusiveXor:
+    case glslang::EOpSubgroupExclusiveAdd:
+    case glslang::EOpSubgroupExclusiveMul:
+    case glslang::EOpSubgroupExclusiveMin:
+    case glslang::EOpSubgroupExclusiveMax:
+    case glslang::EOpSubgroupExclusiveAnd:
+    case glslang::EOpSubgroupExclusiveOr:
+    case glslang::EOpSubgroupExclusiveXor:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformArithmetic);
+        break;
+    case glslang::EOpSubgroupClusteredAdd:
+    case glslang::EOpSubgroupClusteredMul:
+    case glslang::EOpSubgroupClusteredMin:
+    case glslang::EOpSubgroupClusteredMax:
+    case glslang::EOpSubgroupClusteredAnd:
+    case glslang::EOpSubgroupClusteredOr:
+    case glslang::EOpSubgroupClusteredXor:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformClustered);
+        break;
+    case glslang::EOpSubgroupQuadBroadcast:
+    case glslang::EOpSubgroupQuadSwapHorizontal:
+    case glslang::EOpSubgroupQuadSwapVertical:
+    case glslang::EOpSubgroupQuadSwapDiagonal:
+        builder.addCapability(spv::CapabilityGroupNonUniform);
+        builder.addCapability(spv::CapabilityGroupNonUniformQuad);
+        break;
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartitionedAdd:
+    case glslang::EOpSubgroupPartitionedMul:
+    case glslang::EOpSubgroupPartitionedMin:
+    case glslang::EOpSubgroupPartitionedMax:
+    case glslang::EOpSubgroupPartitionedAnd:
+    case glslang::EOpSubgroupPartitionedOr:
+    case glslang::EOpSubgroupPartitionedXor:
+    case glslang::EOpSubgroupPartitionedInclusiveAdd:
+    case glslang::EOpSubgroupPartitionedInclusiveMul:
+    case glslang::EOpSubgroupPartitionedInclusiveMin:
+    case glslang::EOpSubgroupPartitionedInclusiveMax:
+    case glslang::EOpSubgroupPartitionedInclusiveAnd:
+    case glslang::EOpSubgroupPartitionedInclusiveOr:
+    case glslang::EOpSubgroupPartitionedInclusiveXor:
+    case glslang::EOpSubgroupPartitionedExclusiveAdd:
+    case glslang::EOpSubgroupPartitionedExclusiveMul:
+    case glslang::EOpSubgroupPartitionedExclusiveMin:
+    case glslang::EOpSubgroupPartitionedExclusiveMax:
+    case glslang::EOpSubgroupPartitionedExclusiveAnd:
+    case glslang::EOpSubgroupPartitionedExclusiveOr:
+    case glslang::EOpSubgroupPartitionedExclusiveXor:
+        builder.addExtension(spv::E_SPV_NV_shader_subgroup_partitioned);
+        builder.addCapability(spv::CapabilityGroupNonUniformPartitionedNV);
+        break;
+#endif
+    default: assert(0 && "Unhandled subgroup operation!");
+    }
+
+    const bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
+    const bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
+    const bool isBool = typeProxy == glslang::EbtBool;
+
+    spv::Op opCode = spv::OpNop;
+
+    // Figure out which opcode to use.
+    switch (op) {
+    case glslang::EOpSubgroupElect:                   opCode = spv::OpGroupNonUniformElect; break;
+    case glslang::EOpSubgroupAll:                     opCode = spv::OpGroupNonUniformAll; break;
+    case glslang::EOpSubgroupAny:                     opCode = spv::OpGroupNonUniformAny; break;
+    case glslang::EOpSubgroupAllEqual:                opCode = spv::OpGroupNonUniformAllEqual; break;
+    case glslang::EOpSubgroupBroadcast:               opCode = spv::OpGroupNonUniformBroadcast; break;
+    case glslang::EOpSubgroupBroadcastFirst:          opCode = spv::OpGroupNonUniformBroadcastFirst; break;
+    case glslang::EOpSubgroupBallot:                  opCode = spv::OpGroupNonUniformBallot; break;
+    case glslang::EOpSubgroupInverseBallot:           opCode = spv::OpGroupNonUniformInverseBallot; break;
+    case glslang::EOpSubgroupBallotBitExtract:        opCode = spv::OpGroupNonUniformBallotBitExtract; break;
+    case glslang::EOpSubgroupBallotBitCount:
+    case glslang::EOpSubgroupBallotInclusiveBitCount:
+    case glslang::EOpSubgroupBallotExclusiveBitCount: opCode = spv::OpGroupNonUniformBallotBitCount; break;
+    case glslang::EOpSubgroupBallotFindLSB:           opCode = spv::OpGroupNonUniformBallotFindLSB; break;
+    case glslang::EOpSubgroupBallotFindMSB:           opCode = spv::OpGroupNonUniformBallotFindMSB; break;
+    case glslang::EOpSubgroupShuffle:                 opCode = spv::OpGroupNonUniformShuffle; break;
+    case glslang::EOpSubgroupShuffleXor:              opCode = spv::OpGroupNonUniformShuffleXor; break;
+    case glslang::EOpSubgroupShuffleUp:               opCode = spv::OpGroupNonUniformShuffleUp; break;
+    case glslang::EOpSubgroupShuffleDown:             opCode = spv::OpGroupNonUniformShuffleDown; break;
+    case glslang::EOpSubgroupAdd:
+    case glslang::EOpSubgroupInclusiveAdd:
+    case glslang::EOpSubgroupExclusiveAdd:
+    case glslang::EOpSubgroupClusteredAdd:
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartitionedAdd:
+    case glslang::EOpSubgroupPartitionedInclusiveAdd:
+    case glslang::EOpSubgroupPartitionedExclusiveAdd:
+#endif
+        if (isFloat) {
+            opCode = spv::OpGroupNonUniformFAdd;
+        } else {
+            opCode = spv::OpGroupNonUniformIAdd;
+        }
+        break;
+    case glslang::EOpSubgroupMul:
+    case glslang::EOpSubgroupInclusiveMul:
+    case glslang::EOpSubgroupExclusiveMul:
+    case glslang::EOpSubgroupClusteredMul:
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartitionedMul:
+    case glslang::EOpSubgroupPartitionedInclusiveMul:
+    case glslang::EOpSubgroupPartitionedExclusiveMul:
+#endif
+        if (isFloat) {
+            opCode = spv::OpGroupNonUniformFMul;
+        } else {
+            opCode = spv::OpGroupNonUniformIMul;
+        }
+        break;
+    case glslang::EOpSubgroupMin:
+    case glslang::EOpSubgroupInclusiveMin:
+    case glslang::EOpSubgroupExclusiveMin:
+    case glslang::EOpSubgroupClusteredMin:
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartitionedMin:
+    case glslang::EOpSubgroupPartitionedInclusiveMin:
+    case glslang::EOpSubgroupPartitionedExclusiveMin:
+#endif
+        if (isFloat) {
+            opCode = spv::OpGroupNonUniformFMin;
+        } else if (isUnsigned) {
+            opCode = spv::OpGroupNonUniformUMin;
+        } else {
+            opCode = spv::OpGroupNonUniformSMin;
+        }
+        break;
+    case glslang::EOpSubgroupMax:
+    case glslang::EOpSubgroupInclusiveMax:
+    case glslang::EOpSubgroupExclusiveMax:
+    case glslang::EOpSubgroupClusteredMax:
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartitionedMax:
+    case glslang::EOpSubgroupPartitionedInclusiveMax:
+    case glslang::EOpSubgroupPartitionedExclusiveMax:
+#endif
+        if (isFloat) {
+            opCode = spv::OpGroupNonUniformFMax;
+        } else if (isUnsigned) {
+            opCode = spv::OpGroupNonUniformUMax;
+        } else {
+            opCode = spv::OpGroupNonUniformSMax;
+        }
+        break;
+    case glslang::EOpSubgroupAnd:
+    case glslang::EOpSubgroupInclusiveAnd:
+    case glslang::EOpSubgroupExclusiveAnd:
+    case glslang::EOpSubgroupClusteredAnd:
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartitionedAnd:
+    case glslang::EOpSubgroupPartitionedInclusiveAnd:
+    case glslang::EOpSubgroupPartitionedExclusiveAnd:
+#endif
+        if (isBool) {
+            opCode = spv::OpGroupNonUniformLogicalAnd;
+        } else {
+            opCode = spv::OpGroupNonUniformBitwiseAnd;
+        }
+        break;
+    case glslang::EOpSubgroupOr:
+    case glslang::EOpSubgroupInclusiveOr:
+    case glslang::EOpSubgroupExclusiveOr:
+    case glslang::EOpSubgroupClusteredOr:
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartitionedOr:
+    case glslang::EOpSubgroupPartitionedInclusiveOr:
+    case glslang::EOpSubgroupPartitionedExclusiveOr:
+#endif
+        if (isBool) {
+            opCode = spv::OpGroupNonUniformLogicalOr;
+        } else {
+            opCode = spv::OpGroupNonUniformBitwiseOr;
+        }
+        break;
+    case glslang::EOpSubgroupXor:
+    case glslang::EOpSubgroupInclusiveXor:
+    case glslang::EOpSubgroupExclusiveXor:
+    case glslang::EOpSubgroupClusteredXor:
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartitionedXor:
+    case glslang::EOpSubgroupPartitionedInclusiveXor:
+    case glslang::EOpSubgroupPartitionedExclusiveXor:
+#endif
+        if (isBool) {
+            opCode = spv::OpGroupNonUniformLogicalXor;
+        } else {
+            opCode = spv::OpGroupNonUniformBitwiseXor;
+        }
+        break;
+    case glslang::EOpSubgroupQuadBroadcast:      opCode = spv::OpGroupNonUniformQuadBroadcast; break;
+    case glslang::EOpSubgroupQuadSwapHorizontal:
+    case glslang::EOpSubgroupQuadSwapVertical:
+    case glslang::EOpSubgroupQuadSwapDiagonal:   opCode = spv::OpGroupNonUniformQuadSwap; break;
+    default: assert(0 && "Unhandled subgroup operation!");
+    }
+
+    std::vector<spv::Id> spvGroupOperands;
+
+    // Every operation begins with the Execution Scope operand.
+    spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
+
+    // Next, for all operations that use a Group Operation, push that as an operand.
+    switch (op) {
+    default: break;
+    case glslang::EOpSubgroupBallotBitCount:
+    case glslang::EOpSubgroupAdd:
+    case glslang::EOpSubgroupMul:
+    case glslang::EOpSubgroupMin:
+    case glslang::EOpSubgroupMax:
+    case glslang::EOpSubgroupAnd:
+    case glslang::EOpSubgroupOr:
+    case glslang::EOpSubgroupXor:
+        spvGroupOperands.push_back(spv::GroupOperationReduce);
+        break;
+    case glslang::EOpSubgroupBallotInclusiveBitCount:
+    case glslang::EOpSubgroupInclusiveAdd:
+    case glslang::EOpSubgroupInclusiveMul:
+    case glslang::EOpSubgroupInclusiveMin:
+    case glslang::EOpSubgroupInclusiveMax:
+    case glslang::EOpSubgroupInclusiveAnd:
+    case glslang::EOpSubgroupInclusiveOr:
+    case glslang::EOpSubgroupInclusiveXor:
+        spvGroupOperands.push_back(spv::GroupOperationInclusiveScan);
+        break;
+    case glslang::EOpSubgroupBallotExclusiveBitCount:
+    case glslang::EOpSubgroupExclusiveAdd:
+    case glslang::EOpSubgroupExclusiveMul:
+    case glslang::EOpSubgroupExclusiveMin:
+    case glslang::EOpSubgroupExclusiveMax:
+    case glslang::EOpSubgroupExclusiveAnd:
+    case glslang::EOpSubgroupExclusiveOr:
+    case glslang::EOpSubgroupExclusiveXor:
+        spvGroupOperands.push_back(spv::GroupOperationExclusiveScan);
+        break;
+    case glslang::EOpSubgroupClusteredAdd:
+    case glslang::EOpSubgroupClusteredMul:
+    case glslang::EOpSubgroupClusteredMin:
+    case glslang::EOpSubgroupClusteredMax:
+    case glslang::EOpSubgroupClusteredAnd:
+    case glslang::EOpSubgroupClusteredOr:
+    case glslang::EOpSubgroupClusteredXor:
+        spvGroupOperands.push_back(spv::GroupOperationClusteredReduce);
+        break;
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartitionedAdd:
+    case glslang::EOpSubgroupPartitionedMul:
+    case glslang::EOpSubgroupPartitionedMin:
+    case glslang::EOpSubgroupPartitionedMax:
+    case glslang::EOpSubgroupPartitionedAnd:
+    case glslang::EOpSubgroupPartitionedOr:
+    case glslang::EOpSubgroupPartitionedXor:
+        spvGroupOperands.push_back(spv::GroupOperationPartitionedReduceNV);
+        break;
+    case glslang::EOpSubgroupPartitionedInclusiveAdd:
+    case glslang::EOpSubgroupPartitionedInclusiveMul:
+    case glslang::EOpSubgroupPartitionedInclusiveMin:
+    case glslang::EOpSubgroupPartitionedInclusiveMax:
+    case glslang::EOpSubgroupPartitionedInclusiveAnd:
+    case glslang::EOpSubgroupPartitionedInclusiveOr:
+    case glslang::EOpSubgroupPartitionedInclusiveXor:
+        spvGroupOperands.push_back(spv::GroupOperationPartitionedInclusiveScanNV);
+        break;
+    case glslang::EOpSubgroupPartitionedExclusiveAdd:
+    case glslang::EOpSubgroupPartitionedExclusiveMul:
+    case glslang::EOpSubgroupPartitionedExclusiveMin:
+    case glslang::EOpSubgroupPartitionedExclusiveMax:
+    case glslang::EOpSubgroupPartitionedExclusiveAnd:
+    case glslang::EOpSubgroupPartitionedExclusiveOr:
+    case glslang::EOpSubgroupPartitionedExclusiveXor:
+        spvGroupOperands.push_back(spv::GroupOperationPartitionedExclusiveScanNV);
+        break;
+#endif
+    }
+
+    // Push back the operands next.
+    for (auto opIt : operands) {
+        spvGroupOperands.push_back(opIt);
+    }
+
+    // Some opcodes have additional operands.
+    switch (op) {
+    default: break;
+    case glslang::EOpSubgroupQuadSwapHorizontal: spvGroupOperands.push_back(builder.makeUintConstant(0)); break;
+    case glslang::EOpSubgroupQuadSwapVertical:   spvGroupOperands.push_back(builder.makeUintConstant(1)); break;
+    case glslang::EOpSubgroupQuadSwapDiagonal:   spvGroupOperands.push_back(builder.makeUintConstant(2)); break;
+    }
+
+    return builder.createOp(opCode, typeId, spvGroupOperands);
+}
+
 spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
 {
-#ifdef AMD_EXTENSIONS
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64 || typeProxy == glslang::EbtUint16;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#else
-    bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
-#endif
+    bool isUnsigned = isTypeUnsignedInt(typeProxy);
+    bool isFloat = isTypeFloat(typeProxy);
 
     spv::Op opCode = spv::OpNop;
     int extBuiltins = -1;
@@ -5279,10 +6125,11 @@
             libCall = spv::GLSLstd450FrexpStruct;
             assert(builder.isPointerType(typeId1));
             typeId1 = builder.getContainedTypeId(typeId1);
-#ifdef AMD_EXTENSIONS
             int width = builder.getScalarTypeWidth(typeId1);
-#else
-            int width = 32;
+#ifdef AMD_EXTENSIONS
+            if (width == 16)
+                // Using 16-bit exp operand, enable extension SPV_AMD_gpu_shader_int16
+                builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
 #endif
             if (builder.getNumComponents(operands[0]) == 1)
                 frexpIntType = builder.makeIntegerType(width, true);
@@ -5299,6 +6146,45 @@
     case glslang::EOpReadInvocation:
         return createInvocationsOperation(op, typeId, operands, typeProxy);
 
+    case glslang::EOpSubgroupBroadcast:
+    case glslang::EOpSubgroupBallotBitExtract:
+    case glslang::EOpSubgroupShuffle:
+    case glslang::EOpSubgroupShuffleXor:
+    case glslang::EOpSubgroupShuffleUp:
+    case glslang::EOpSubgroupShuffleDown:
+    case glslang::EOpSubgroupClusteredAdd:
+    case glslang::EOpSubgroupClusteredMul:
+    case glslang::EOpSubgroupClusteredMin:
+    case glslang::EOpSubgroupClusteredMax:
+    case glslang::EOpSubgroupClusteredAnd:
+    case glslang::EOpSubgroupClusteredOr:
+    case glslang::EOpSubgroupClusteredXor:
+    case glslang::EOpSubgroupQuadBroadcast:
+#ifdef NV_EXTENSIONS
+    case glslang::EOpSubgroupPartitionedAdd:
+    case glslang::EOpSubgroupPartitionedMul:
+    case glslang::EOpSubgroupPartitionedMin:
+    case glslang::EOpSubgroupPartitionedMax:
+    case glslang::EOpSubgroupPartitionedAnd:
+    case glslang::EOpSubgroupPartitionedOr:
+    case glslang::EOpSubgroupPartitionedXor:
+    case glslang::EOpSubgroupPartitionedInclusiveAdd:
+    case glslang::EOpSubgroupPartitionedInclusiveMul:
+    case glslang::EOpSubgroupPartitionedInclusiveMin:
+    case glslang::EOpSubgroupPartitionedInclusiveMax:
+    case glslang::EOpSubgroupPartitionedInclusiveAnd:
+    case glslang::EOpSubgroupPartitionedInclusiveOr:
+    case glslang::EOpSubgroupPartitionedInclusiveXor:
+    case glslang::EOpSubgroupPartitionedExclusiveAdd:
+    case glslang::EOpSubgroupPartitionedExclusiveMul:
+    case glslang::EOpSubgroupPartitionedExclusiveMin:
+    case glslang::EOpSubgroupPartitionedExclusiveMax:
+    case glslang::EOpSubgroupPartitionedExclusiveAnd:
+    case glslang::EOpSubgroupPartitionedExclusiveOr:
+    case glslang::EOpSubgroupPartitionedExclusiveXor:
+#endif
+        return createSubgroupOperation(op, typeId, operands, typeProxy);
+
 #ifdef AMD_EXTENSIONS
     case glslang::EOpSwizzleInvocations:
         extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_ballot);
@@ -5431,41 +6317,90 @@
         builder.createNoResultOp(spv::OpEndPrimitive);
         return 0;
     case glslang::EOpBarrier:
-        builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeDevice, spv::MemorySemanticsMaskNone);
+        if (glslangIntermediate->getStage() == EShLangTessControl) {
+            builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeInvocation, spv::MemorySemanticsMaskNone);
+            // TODO: prefer the following, when available:
+            // builder.createControlBarrier(spv::ScopePatch, spv::ScopePatch,
+            //                                 spv::MemorySemanticsPatchMask |
+            //                                 spv::MemorySemanticsAcquireReleaseMask);
+        } else {
+            builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup,
+                                            spv::MemorySemanticsWorkgroupMemoryMask |
+                                            spv::MemorySemanticsAcquireReleaseMask);
+        }
         return 0;
     case glslang::EOpMemoryBarrier:
-        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAllMemory);
+        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAllMemory |
+                                                      spv::MemorySemanticsAcquireReleaseMask);
         return 0;
     case glslang::EOpMemoryBarrierAtomicCounter:
-        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAtomicCounterMemoryMask);
+        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAtomicCounterMemoryMask |
+                                                      spv::MemorySemanticsAcquireReleaseMask);
         return 0;
     case glslang::EOpMemoryBarrierBuffer:
-        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsUniformMemoryMask);
+        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsUniformMemoryMask |
+                                                      spv::MemorySemanticsAcquireReleaseMask);
         return 0;
     case glslang::EOpMemoryBarrierImage:
-        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsImageMemoryMask);
+        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsImageMemoryMask |
+                                                      spv::MemorySemanticsAcquireReleaseMask);
         return 0;
     case glslang::EOpMemoryBarrierShared:
-        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsWorkgroupMemoryMask);
+        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsWorkgroupMemoryMask |
+                                                      spv::MemorySemanticsAcquireReleaseMask);
         return 0;
     case glslang::EOpGroupMemoryBarrier:
-        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsCrossWorkgroupMemoryMask);
+        builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsAllMemory |
+                                                         spv::MemorySemanticsAcquireReleaseMask);
         return 0;
     case glslang::EOpAllMemoryBarrierWithGroupSync:
-        // Control barrier with non-"None" semantic is also a memory barrier.
-        builder.createControlBarrier(spv::ScopeDevice, spv::ScopeDevice, spv::MemorySemanticsAllMemory);
+        builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeDevice,
+                                        spv::MemorySemanticsAllMemory |
+                                        spv::MemorySemanticsAcquireReleaseMask);
         return 0;
-    case glslang::EOpGroupMemoryBarrierWithGroupSync:
-        // Control barrier with non-"None" semantic is also a memory barrier.
-        builder.createControlBarrier(spv::ScopeDevice, spv::ScopeDevice, spv::MemorySemanticsCrossWorkgroupMemoryMask);
+    case glslang::EOpDeviceMemoryBarrier:
+        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsUniformMemoryMask |
+                                                      spv::MemorySemanticsImageMemoryMask |
+                                                      spv::MemorySemanticsAcquireReleaseMask);
+        return 0;
+    case glslang::EOpDeviceMemoryBarrierWithGroupSync:
+        builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeDevice, spv::MemorySemanticsUniformMemoryMask |
+                                                                            spv::MemorySemanticsImageMemoryMask |
+                                                                            spv::MemorySemanticsAcquireReleaseMask);
         return 0;
     case glslang::EOpWorkgroupMemoryBarrier:
-        builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsWorkgroupMemoryMask);
+        builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsWorkgroupMemoryMask |
+                                                         spv::MemorySemanticsAcquireReleaseMask);
         return 0;
     case glslang::EOpWorkgroupMemoryBarrierWithGroupSync:
-        // Control barrier with non-"None" semantic is also a memory barrier.
-        builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup, spv::MemorySemanticsWorkgroupMemoryMask);
+        builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup,
+                                        spv::MemorySemanticsWorkgroupMemoryMask |
+                                        spv::MemorySemanticsAcquireReleaseMask);
         return 0;
+    case glslang::EOpSubgroupBarrier:
+        builder.createControlBarrier(spv::ScopeSubgroup, spv::ScopeSubgroup, spv::MemorySemanticsAllMemory |
+                                                                             spv::MemorySemanticsAcquireReleaseMask);
+        return spv::NoResult;
+    case glslang::EOpSubgroupMemoryBarrier:
+        builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsAllMemory |
+                                                        spv::MemorySemanticsAcquireReleaseMask);
+        return spv::NoResult;
+    case glslang::EOpSubgroupMemoryBarrierBuffer:
+        builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsUniformMemoryMask |
+                                                        spv::MemorySemanticsAcquireReleaseMask);
+        return spv::NoResult;
+    case glslang::EOpSubgroupMemoryBarrierImage:
+        builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsImageMemoryMask |
+                                                        spv::MemorySemanticsAcquireReleaseMask);
+        return spv::NoResult;
+    case glslang::EOpSubgroupMemoryBarrierShared:
+        builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsWorkgroupMemoryMask |
+                                                        spv::MemorySemanticsAcquireReleaseMask);
+        return spv::NoResult;
+    case glslang::EOpSubgroupElect: {
+        std::vector<spv::Id> operands;
+        return createSubgroupOperation(op, typeId, operands, glslang::EbtVoid);
+    }
 #ifdef AMD_EXTENSIONS
     case glslang::EOpTime:
     {
@@ -5494,24 +6429,15 @@
     symbolValues[symbol->getId()] = id;
 
     if (symbol->getBasicType() != glslang::EbtBlock) {
-        addDecoration(id, TranslatePrecisionDecoration(symbol->getType()));
-        addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier()));
-        addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier()));
+        builder.addDecoration(id, TranslatePrecisionDecoration(symbol->getType()));
+        builder.addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier()));
+        builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier()));
         if (symbol->getType().getQualifier().hasSpecConstantId())
-            addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId);
+            builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId);
         if (symbol->getQualifier().hasIndex())
             builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
         if (symbol->getQualifier().hasComponent())
             builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent);
-        if (glslangIntermediate->getXfbMode()) {
-            builder.addCapability(spv::CapabilityTransformFeedback);
-            if (symbol->getQualifier().hasXfbStride())
-                builder.addDecoration(id, spv::DecorationXfbStride, symbol->getQualifier().layoutXfbStride);
-            if (symbol->getQualifier().hasXfbBuffer())
-                builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer);
-            if (symbol->getQualifier().hasXfbOffset())
-                builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset);
-        }
         // atomic counters use this:
         if (symbol->getQualifier().hasOffset())
             builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset);
@@ -5519,7 +6445,7 @@
 
     if (symbol->getQualifier().hasLocation())
         builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
-    addDecoration(id, TranslateInvariantDecoration(symbol->getType().getQualifier()));
+    builder.addDecoration(id, TranslateInvariantDecoration(symbol->getType().getQualifier()));
     if (symbol->getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
         builder.addCapability(spv::CapabilityGeometryStreams);
         builder.addDecoration(id, spv::DecorationStream, symbol->getQualifier().layoutStream);
@@ -5538,21 +6464,30 @@
         builder.addCapability(spv::CapabilityTransformFeedback);
         if (symbol->getQualifier().hasXfbStride())
             builder.addDecoration(id, spv::DecorationXfbStride, symbol->getQualifier().layoutXfbStride);
-        if (symbol->getQualifier().hasXfbBuffer())
+        if (symbol->getQualifier().hasXfbBuffer()) {
             builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer);
+            unsigned stride = glslangIntermediate->getXfbStride(symbol->getQualifier().layoutXfbBuffer);
+            if (stride != glslang::TQualifier::layoutXfbStrideEnd)
+                builder.addDecoration(id, spv::DecorationXfbStride, stride);
+        }
+        if (symbol->getQualifier().hasXfbOffset())
+            builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset);
     }
 
     if (symbol->getType().isImage()) {
         std::vector<spv::Decoration> memory;
         TranslateMemoryDecoration(symbol->getType().getQualifier(), memory);
         for (unsigned int i = 0; i < memory.size(); ++i)
-            addDecoration(id, memory[i]);
+            builder.addDecoration(id, memory[i]);
     }
 
     // built-in variable decorations
     spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false);
     if (builtIn != spv::BuiltInMax)
-        addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
+        builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
+
+    // nonuniform
+    builder.addDecoration(id, TranslateNonUniformDecoration(symbol->getType().getQualifier()));
 
 #ifdef NV_EXTENSIONS
     if (builtIn == spv::BuiltInSampleMask) {
@@ -5562,7 +6497,7 @@
               decoration = (spv::Decoration)spv::DecorationOverrideCoverageNV;
           else
               decoration = (spv::Decoration)spv::DecorationMax;
-        addDecoration(id, decoration);
+        builder.addDecoration(id, decoration);
         if (decoration != spv::DecorationMax) {
             builder.addExtension(spv::E_SPV_NV_sample_mask_override_coverage);
         }
@@ -5570,55 +6505,34 @@
     else if (builtIn == spv::BuiltInLayer) {
         // SPV_NV_viewport_array2 extension
         if (symbol->getQualifier().layoutViewportRelative) {
-            addDecoration(id, (spv::Decoration)spv::DecorationViewportRelativeNV);
+            builder.addDecoration(id, (spv::Decoration)spv::DecorationViewportRelativeNV);
             builder.addCapability(spv::CapabilityShaderViewportMaskNV);
             builder.addExtension(spv::E_SPV_NV_viewport_array2);
         }
         if (symbol->getQualifier().layoutSecondaryViewportRelativeOffset != -2048) {
-            addDecoration(id, (spv::Decoration)spv::DecorationSecondaryViewportRelativeNV, symbol->getQualifier().layoutSecondaryViewportRelativeOffset);
+            builder.addDecoration(id, (spv::Decoration)spv::DecorationSecondaryViewportRelativeNV,
+                                  symbol->getQualifier().layoutSecondaryViewportRelativeOffset);
             builder.addCapability(spv::CapabilityShaderStereoViewNV);
             builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
         }
     }
 
     if (symbol->getQualifier().layoutPassthrough) {
-        addDecoration(id, spv::DecorationPassthroughNV);
+        builder.addDecoration(id, spv::DecorationPassthroughNV);
         builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
         builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
     }
 #endif
 
+    if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) {
+        builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
+        builder.addDecoration(id, (spv::Decoration)spv::DecorationHlslSemanticGOOGLE,
+                              symbol->getType().getQualifier().semanticName);
+    }
+
     return id;
 }
 
-// If 'dec' is valid, add no-operand decoration to an object
-void TGlslangToSpvTraverser::addDecoration(spv::Id id, spv::Decoration dec)
-{
-    if (dec != spv::DecorationMax)
-        builder.addDecoration(id, dec);
-}
-
-// If 'dec' is valid, add a one-operand decoration to an object
-void TGlslangToSpvTraverser::addDecoration(spv::Id id, spv::Decoration dec, unsigned value)
-{
-    if (dec != spv::DecorationMax)
-        builder.addDecoration(id, dec, value);
-}
-
-// If 'dec' is valid, add a no-operand decoration to a struct member
-void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::Decoration dec)
-{
-    if (dec != spv::DecorationMax)
-        builder.addMemberDecoration(id, (unsigned)member, dec);
-}
-
-// If 'dec' is valid, add a one-operand decoration to a struct member
-void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::Decoration dec, unsigned value)
-{
-    if (dec != spv::DecorationMax)
-        builder.addMemberDecoration(id, (unsigned)member, dec, value);
-}
-
 // Make a full tree of instructions to build a SPIR-V specialization constant,
 // or regular constant if possible.
 //
@@ -5651,8 +6565,10 @@
         for (int dim = 0; dim < 3; ++dim) {
             bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
             dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
-            if (specConst)
-                addDecoration(dimConstId.back(), spv::DecorationSpecId, glslangIntermediate->getLocalSizeSpecId(dim));
+            if (specConst) {
+                builder.addDecoration(dimConstId.back(), spv::DecorationSpecId,
+                                      glslangIntermediate->getLocalSizeSpecId(dim));
+            }
         }
         return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true);
     }
@@ -5711,6 +6627,18 @@
         for (unsigned int i = 0; i < (unsigned int)glslangType.getVectorSize(); ++i) {
             bool zero = nextConst >= consts.size();
             switch (glslangType.getBasicType()) {
+            case glslang::EbtInt8:
+                spvConsts.push_back(builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const()));
+                break;
+            case glslang::EbtUint8:
+                spvConsts.push_back(builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const()));
+                break;
+            case glslang::EbtInt16:
+                spvConsts.push_back(builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const()));
+                break;
+            case glslang::EbtUint16:
+                spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const()));
+                break;
             case glslang::EbtInt:
                 spvConsts.push_back(builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst()));
                 break;
@@ -5723,25 +6651,15 @@
             case glslang::EbtUint64:
                 spvConsts.push_back(builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const()));
                 break;
-#ifdef AMD_EXTENSIONS
-            case glslang::EbtInt16:
-                spvConsts.push_back(builder.makeInt16Constant(zero ? 0 : (short)consts[nextConst].getIConst()));
-                break;
-            case glslang::EbtUint16:
-                spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : (unsigned short)consts[nextConst].getUConst()));
-                break;
-#endif
             case glslang::EbtFloat:
                 spvConsts.push_back(builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
                 break;
             case glslang::EbtDouble:
                 spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst()));
                 break;
-#ifdef AMD_EXTENSIONS
             case glslang::EbtFloat16:
                 spvConsts.push_back(builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
                 break;
-#endif
             case glslang::EbtBool:
                 spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst()));
                 break;
@@ -5756,6 +6674,18 @@
         bool zero = nextConst >= consts.size();
         spv::Id scalar = 0;
         switch (glslangType.getBasicType()) {
+        case glslang::EbtInt8:
+            scalar = builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const(), specConstant);
+            break;
+        case glslang::EbtUint8:
+            scalar = builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const(), specConstant);
+            break;
+        case glslang::EbtInt16:
+            scalar = builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const(), specConstant);
+            break;
+        case glslang::EbtUint16:
+            scalar = builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const(), specConstant);
+            break;
         case glslang::EbtInt:
             scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst(), specConstant);
             break;
@@ -5768,25 +6698,15 @@
         case glslang::EbtUint64:
             scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant);
             break;
-#ifdef AMD_EXTENSIONS
-        case glslang::EbtInt16:
-            scalar = builder.makeInt16Constant(zero ? 0 : (short)consts[nextConst].getIConst(), specConstant);
-            break;
-        case glslang::EbtUint16:
-            scalar = builder.makeUint16Constant(zero ? 0 : (unsigned short)consts[nextConst].getUConst(), specConstant);
-            break;
-#endif
         case glslang::EbtFloat:
             scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant);
             break;
         case glslang::EbtDouble:
             scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst(), specConstant);
             break;
-#ifdef AMD_EXTENSIONS
         case glslang::EbtFloat16:
             scalar = builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant);
             break;
-#endif
         case glslang::EbtBool:
             scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant);
             break;
@@ -5933,6 +6853,7 @@
     return builder.createOp(spv::OpPhi, boolTypeId, phiOperands);
 }
 
+#ifdef AMD_EXTENSIONS
 // Return type Id of the imported set of extended instructions corresponds to the name.
 // Import this set if it has not been imported yet.
 spv::Id TGlslangToSpvTraverser::getExtBuiltins(const char* name)
@@ -5946,6 +6867,7 @@
         return extBuiltins;
     }
 }
+#endif
 
 };  // end anonymous namespace
 
@@ -5959,6 +6881,20 @@
     version = buf;
 }
 
+// For low-order part of the generator's magic number. Bump up
+// when there is a change in the style (e.g., if SSA form changes,
+// or a different instruction sequence to do something gets used).
+int GetSpirvGeneratorVersion()
+{
+    // return 1; // start
+    // return 2; // EOpAtomicCounterDecrement gets a post decrement, to map between GLSL -> SPIR-V
+    // return 3; // change/correct barrier-instruction operands, to match memory model group decisions
+    // return 4; // some deeper access chains: for dynamic vector component, and local Boolean component
+    // return 5; // make OpArrayLength result type be an int with signedness of 0
+    return 6; // revert version 5 change, which makes a different (new) kind of incorrect code,
+              // versions 4 and 6 each generate OpArrayLength as it has long been done
+}
+
 // Write SPIR-V out to a binary file
 void OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName)
 {
@@ -5980,7 +6916,9 @@
     out.open(baseName, std::ios::binary | std::ios::out);
     if (out.fail())
         printf("ERROR: Failed to open file: %s\n", baseName);
-    out << "\t// " GLSLANG_REVISION " " GLSLANG_DATE << std::endl;
+    out << "\t// " << 
+        glslang::GetSpirvGeneratorVersion() << "." << GLSLANG_MINOR_VERSION << "." << GLSLANG_PATCH_LEVEL <<
+        std::endl;
     if (varName != nullptr) {
         out << "\t #pragma once" << std::endl;
         out << "const uint32_t " << varName << "[] = {" << std::endl;
@@ -6003,12 +6941,6 @@
     out.close();
 }
 
-#ifdef ENABLE_OPT
-void errHandler(const std::string& str) {
-    std::cerr << str << std::endl;
-}
-#endif
-
 //
 // Set up the glslang traversal
 //
@@ -6032,12 +6964,12 @@
 
     glslang::GetThreadPoolAllocator().push();
 
-    TGlslangToSpvTraverser it(&intermediate, logger, *options);
+    TGlslangToSpvTraverser it(intermediate.getSpv().spv, &intermediate, logger, *options);
     root->traverse(&it);
     it.finishSpv();
     it.dumpSpv(spirv);
 
-#ifdef ENABLE_OPT
+#if ENABLE_OPT
     // If from HLSL, run spirv-opt to "legalize" the SPIR-V for Vulkan
     // eg. forward and remove memory writes of opaque types.
     if ((intermediate.getSource() == EShSourceHlsl ||
@@ -6054,30 +6986,35 @@
                       << std::endl;
         });
 
+        optimizer.RegisterPass(CreateMergeReturnPass());
         optimizer.RegisterPass(CreateInlineExhaustivePass());
+        optimizer.RegisterPass(CreateEliminateDeadFunctionsPass());
+        optimizer.RegisterPass(CreateScalarReplacementPass());
         optimizer.RegisterPass(CreateLocalAccessChainConvertPass());
         optimizer.RegisterPass(CreateLocalSingleBlockLoadStoreElimPass());
         optimizer.RegisterPass(CreateLocalSingleStoreElimPass());
-        optimizer.RegisterPass(CreateInsertExtractElimPass());
         optimizer.RegisterPass(CreateAggressiveDCEPass());
+        optimizer.RegisterPass(CreateInsertExtractElimPass());
+        optimizer.RegisterPass(CreateDeadInsertElimPass());
+        optimizer.RegisterPass(CreateAggressiveDCEPass());
+        optimizer.RegisterPass(CreateCCPPass());
+        optimizer.RegisterPass(CreateSimplificationPass());
         optimizer.RegisterPass(CreateDeadBranchElimPass());
         optimizer.RegisterPass(CreateCFGCleanupPass());
         optimizer.RegisterPass(CreateBlockMergePass());
         optimizer.RegisterPass(CreateLocalMultiStoreElimPass());
-        optimizer.RegisterPass(CreateInsertExtractElimPass());
         optimizer.RegisterPass(CreateAggressiveDCEPass());
-        // TODO(greg-lunarg): Add this when AMD driver issues are resolved
-        // if (options->optimizeSize)
-        //     optimizer.RegisterPass(CreateCommonUniformElimPass());
+        optimizer.RegisterPass(CreateInsertExtractElimPass());
+        optimizer.RegisterPass(CreateDeadInsertElimPass());
+        if (options->optimizeSize) {
+            optimizer.RegisterPass(CreateRedundancyEliminationPass());
+            // TODO(greg-lunarg): Add this when AMD driver issues are resolved
+            // optimizer.RegisterPass(CreateCommonUniformElimPass());
+        }
+        optimizer.RegisterPass(CreateAggressiveDCEPass());
 
         if (!optimizer.Run(spirv.data(), spirv.size(), &spirv))
             return;
-
-        // Remove dead module-level objects: functions, types, vars
-        // TODO(greg-lunarg): Switch to spirv-opt versions when available
-        spv::spirvbin_t Remapper(0);
-        Remapper.registerErrorHandler(errHandler);
-        Remapper.remap(spirv, spv::spirvbin_t::DCE_ALL);
     }
 #endif
 
diff --git a/SPIRV/GlslangToSpv.h b/SPIRV/GlslangToSpv.h
index 0398501..f7f7cff 100644
--- a/SPIRV/GlslangToSpv.h
+++ b/SPIRV/GlslangToSpv.h
@@ -34,7 +34,7 @@
 
 #pragma once
 
-#if _MSC_VER >= 1900
+#if defined(_MSC_VER) && _MSC_VER >= 1900
     #pragma warning(disable : 4464) // relative include path contains '..'
 #endif
 
@@ -56,6 +56,7 @@
 };
 
 void GetSpirvVersion(std::string&);
+int GetSpirvGeneratorVersion();
 void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
                   SpvOptions* options = nullptr);
 void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
diff --git a/SPIRV/SPVRemapper.cpp b/SPIRV/SPVRemapper.cpp
index 4d96df6..4bac145 100755
--- a/SPIRV/SPVRemapper.cpp
+++ b/SPIRV/SPVRemapper.cpp
@@ -256,7 +256,7 @@
 
     spv::Id spirvbin_t::localId(spv::Id id, spv::Id newId)
     {
-        assert(id != spv::NoResult && newId != spv::NoResult);
+        //assert(id != spv::NoResult && newId != spv::NoResult);
 
         if (id > bound()) {
             error(std::string("ID out of range: ") + std::to_string(id));
@@ -1392,7 +1392,7 @@
 
         int strippedPos = 0;
         for (unsigned word = 0; word < unsigned(spv.size()); ++word) {
-            if (strip_it != stripRange.end() && word >= strip_it->second)
+            while (strip_it != stripRange.end() && word >= strip_it->second)
                 ++strip_it;
 
             if (strip_it == stripRange.end() || word < strip_it->first || word >= strip_it->second)
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index c795ca8..27ce71c 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -46,9 +46,7 @@
 
 #include "SpvBuilder.h"
 
-#ifdef AMD_EXTENSIONS
-    #include "hex_float.h"
-#endif
+#include "hex_float.h"
 
 #ifndef _WIN32
     #include <cstdio>
@@ -56,7 +54,8 @@
 
 namespace spv {
 
-Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
+Builder::Builder(unsigned int spvVersion, unsigned int magicNumber, SpvBuildLogger* buildLogger) :
+    spvVersion(spvVersion),
     source(SourceLanguageUnknown),
     sourceVersion(0),
     sourceFileStringId(NoResult),
@@ -193,6 +192,9 @@
 
     // deal with capabilities
     switch (width) {
+    case 8:
+        addCapability(CapabilityInt8);
+        break;
     case 16:
         addCapability(CapabilityInt16);
         break;
@@ -621,7 +623,7 @@
 
 // See if a scalar constant of this type has already been created, so it
 // can be reused rather than duplicated.  (Required by the specification).
-Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const
+Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value)
 {
     Instruction* constant;
     for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
@@ -636,7 +638,7 @@
 }
 
 // Version of findScalarConstant (see above) for scalars that take two operands (e.g. a 'double' or 'int64').
-Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const
+Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2)
 {
     Instruction* constant;
     for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
@@ -818,7 +820,6 @@
     return c->getResultId();
 }
 
-#ifdef AMD_EXTENSIONS
 Id Builder::makeFloat16Constant(float f16, bool specConstant)
 {
     Op opcode = specConstant ? OpSpecConstant : OpConstant;
@@ -846,9 +847,27 @@
 
     return c->getResultId();
 }
-#endif
 
-Id Builder::findCompositeConstant(Op typeClass, const std::vector<Id>& comps) const
+Id Builder::makeFpConstant(Id type, double d, bool specConstant)
+{
+        assert(isFloatType(type));
+
+        switch (getScalarTypeWidth(type)) {
+        case 16:
+                return makeFloat16Constant((float)d, specConstant);
+        case 32:
+                return makeFloatConstant((float)d, specConstant);
+        case 64:
+                return makeDoubleConstant(d, specConstant);
+        default:
+                break;
+        }
+
+        assert(false);
+        return NoResult;
+}
+
+Id Builder::findCompositeConstant(Op typeClass, const std::vector<Id>& comps)
 {
     Instruction* constant = 0;
     bool found = false;
@@ -876,6 +895,30 @@
     return found ? constant->getResultId() : NoResult;
 }
 
+Id Builder::findStructConstant(Id typeId, const std::vector<Id>& comps)
+{
+    Instruction* constant = 0;
+    bool found = false;
+    for (int i = 0; i < (int)groupedStructConstants[typeId].size(); ++i) {
+        constant = groupedStructConstants[typeId][i];
+
+        // same contents?
+        bool mismatch = false;
+        for (int op = 0; op < constant->getNumOperands(); ++op) {
+            if (constant->getIdOperand(op) != comps[op]) {
+                mismatch = true;
+                break;
+            }
+        }
+        if (! mismatch) {
+            found = true;
+            break;
+        }
+    }
+
+    return found ? constant->getResultId() : NoResult;
+}
+
 // Comments in header
 Id Builder::makeCompositeConstant(Id typeId, const std::vector<Id>& members, bool specConstant)
 {
@@ -886,25 +929,33 @@
     switch (typeClass) {
     case OpTypeVector:
     case OpTypeArray:
-    case OpTypeStruct:
     case OpTypeMatrix:
+        if (! specConstant) {
+            Id existing = findCompositeConstant(typeClass, members);
+            if (existing)
+                return existing;
+        }
+        break;
+    case OpTypeStruct:
+        if (! specConstant) {
+            Id existing = findStructConstant(typeId, members);
+            if (existing)
+                return existing;
+        }
         break;
     default:
         assert(0);
         return makeFloatConstant(0.0);
     }
 
-    if (! specConstant) {
-        Id existing = findCompositeConstant(typeClass, members);
-        if (existing)
-            return existing;
-    }
-
     Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
     for (int op = 0; op < (int)members.size(); ++op)
         c->addIdOperand(members[op]);
     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
-    groupedConstants[typeClass].push_back(c);
+    if (typeClass == OpTypeStruct)
+        groupedStructConstants[typeId].push_back(c);
+    else
+        groupedConstants[typeClass].push_back(c);
     module.mapInstruction(c);
 
     return c->getResultId();
@@ -961,6 +1012,7 @@
 {
     if (decoration == spv::DecorationMax)
         return;
+
     Instruction* dec = new Instruction(OpDecorate);
     dec->addIdOperand(id);
     dec->addImmediateOperand(decoration);
@@ -970,8 +1022,37 @@
     decorations.push_back(std::unique_ptr<Instruction>(dec));
 }
 
+void Builder::addDecoration(Id id, Decoration decoration, const char* s)
+{
+    if (decoration == spv::DecorationMax)
+        return;
+
+    Instruction* dec = new Instruction(OpDecorateStringGOOGLE);
+    dec->addIdOperand(id);
+    dec->addImmediateOperand(decoration);
+    dec->addStringOperand(s);
+
+    decorations.push_back(std::unique_ptr<Instruction>(dec));
+}
+
+void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
+{
+    if (decoration == spv::DecorationMax)
+        return;
+
+    Instruction* dec = new Instruction(OpDecorateId);
+    dec->addIdOperand(id);
+    dec->addImmediateOperand(decoration);
+    dec->addIdOperand(idDecoration);
+
+    decorations.push_back(std::unique_ptr<Instruction>(dec));
+}
+
 void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
 {
+    if (decoration == spv::DecorationMax)
+        return;
+
     Instruction* dec = new Instruction(OpMemberDecorate);
     dec->addIdOperand(id);
     dec->addImmediateOperand(member);
@@ -982,6 +1063,20 @@
     decorations.push_back(std::unique_ptr<Instruction>(dec));
 }
 
+void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const char *s)
+{
+    if (decoration == spv::DecorationMax)
+        return;
+
+    Instruction* dec = new Instruction(OpMemberDecorateStringGOOGLE);
+    dec->addIdOperand(id);
+    dec->addImmediateOperand(member);
+    dec->addImmediateOperand(decoration);
+    dec->addStringOperand(s);
+
+    decorations.push_back(std::unique_ptr<Instruction>(dec));
+}
+
 // Comments in header
 Function* Builder::makeEntryPoint(const char* entryPoint)
 {
@@ -1387,16 +1482,13 @@
         return createCompositeInsert(source, target, typeId, channels.front());
 
     Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle);
+
     assert(isVector(target));
     swizzle->addIdOperand(target);
-    if (accessChain.component != NoResult)
-        // For dynamic component selection, source does not involve in l-value swizzle
-        swizzle->addIdOperand(target);
-    else {
-        assert(getNumComponents(source) == (int)channels.size());
-        assert(isVector(source));
-        swizzle->addIdOperand(source);
-    }
+
+    assert(getNumComponents(source) == (int)channels.size());
+    assert(isVector(source));
+    swizzle->addIdOperand(source);
 
     // Set up an identity shuffle from the base value to the result value
     unsigned int components[4];
@@ -1405,12 +1497,8 @@
         components[i] = i;
 
     // Punch in the l-value swizzle
-    for (int i = 0; i < (int)channels.size(); ++i) {
-        if (accessChain.component != NoResult)
-            components[i] = channels[i]; // Only shuffle the base value
-        else
-            components[channels[i]] = numTargetComponents + i;
-    }
+    for (int i = 0; i < (int)channels.size(); ++i)
+        components[channels[i]] = numTargetComponents + i;
 
     // finish the instruction with these components selectors
     for (int i = 0; i < numTargetComponents; ++i)
@@ -1725,7 +1813,11 @@
         break;
     }
     case OpImageQueryLod:
+#ifdef AMD_EXTENSIONS
+        resultType = makeVectorType(getScalarTypeId(getTypeId(parameters.coords)), 2);
+#else
         resultType = makeVectorType(makeFloatType(32), 2);
+#endif
         break;
     case OpImageQueryLevels:
     case OpImageQuerySamples:
@@ -2202,7 +2294,7 @@
         accessChain.preSwizzleBaseType = preSwizzleBaseType;
 
     // if needed, propagate the swizzle for the current access chain
-    if (accessChain.swizzle.size()) {
+    if (accessChain.swizzle.size() > 0) {
         std::vector<unsigned> oldSwizzle = accessChain.swizzle;
         accessChain.swizzle.resize(0);
         for (unsigned int i = 0; i < swizzle.size(); ++i) {
@@ -2223,34 +2315,28 @@
 
     transferAccessChainSwizzle(true);
     Id base = collapseAccessChain();
+    Id source = rvalue;
+
+    // dynamic component should be gone
+    assert(accessChain.component == NoResult);
 
     // If swizzle still exists, it is out-of-order or not full, we must load the target vector,
     // extract and insert elements to perform writeMask and/or swizzle.
-    Id source = NoResult;
-    if (accessChain.swizzle.size()) {
+    if (accessChain.swizzle.size() > 0) {
         Id tempBaseId = createLoad(base);
-        source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, rvalue, accessChain.swizzle);
+        source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
     }
 
-    // dynamic component selection
-    if (accessChain.component != NoResult) {
-        Id tempBaseId = (source == NoResult) ? createLoad(base) : source;
-        source = createVectorInsertDynamic(tempBaseId, getTypeId(tempBaseId), rvalue, accessChain.component);
-    }
-
-    if (source == NoResult)
-        source = rvalue;
-
     createStore(source, base);
 }
 
 // Comments in header
-Id Builder::accessChainLoad(Decoration precision, Id resultType)
+Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType)
 {
     Id id;
 
     if (accessChain.isRValue) {
-        // transfer access chain, but keep it static, so we can stay in registers
+        // transfer access chain, but try to stay in registers
         transferAccessChainSwizzle(false);
         if (accessChain.indexChain.size() > 0) {
             Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType;
@@ -2291,6 +2377,7 @@
         // load through the access chain
         id = createLoad(collapseAccessChain());
         setPrecision(id, precision);
+        addDecoration(id, nonUniform);
     }
 
     // Done, unless there are swizzles to do
@@ -2298,19 +2385,20 @@
         return id;
 
     // Do remaining swizzling
-    // First, static swizzling
-    if (accessChain.swizzle.size()) {
-        // static swizzle
+
+    // Do the basic swizzle
+    if (accessChain.swizzle.size() > 0) {
         Id swizzledType = getScalarTypeId(getTypeId(id));
         if (accessChain.swizzle.size() > 1)
             swizzledType = makeVectorType(swizzledType, (int)accessChain.swizzle.size());
         id = createRvalueSwizzle(precision, swizzledType, id, accessChain.swizzle);
     }
 
-    // dynamic single-component selection
+    // Do the dynamic component
     if (accessChain.component != NoResult)
         id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision);
 
+    addDecoration(id, nonUniform);
     return id;
 }
 
@@ -2403,7 +2491,7 @@
 {
     // Header, before first instructions:
     out.push_back(MagicNumber);
-    out.push_back(Version);
+    out.push_back(spvVersion);
     out.push_back(builderNumber);
     out.push_back(uniqueId + 1);
     out.push_back(0);
@@ -2433,7 +2521,6 @@
 
     // Debug instructions
     dumpInstructions(out, strings);
-    dumpModuleProcesses(out);
     dumpSourceInstructions(out);
     for (int e = 0; e < (int)sourceExtensions.size(); ++e) {
         Instruction sourceExtInst(0, 0, OpSourceExtension);
@@ -2441,7 +2528,7 @@
         sourceExtInst.dump(out);
     }
     dumpInstructions(out, names);
-    dumpInstructions(out, lines);
+    dumpModuleProcesses(out);
 
     // Annotation instructions
     dumpInstructions(out, decorations);
@@ -2457,26 +2544,66 @@
 // Protected methods.
 //
 
-// Turn the described access chain in 'accessChain' into an instruction
+// Turn the described access chain in 'accessChain' into an instruction(s)
 // computing its address.  This *cannot* include complex swizzles, which must
-// be handled after this is called, but it does include swizzles that select
-// an individual element, as a single address of a scalar type can be
-// computed by an OpAccessChain instruction.
+// be handled after this is called.
+//
+// Can generate code.
 Id Builder::collapseAccessChain()
 {
     assert(accessChain.isRValue == false);
 
-    if (accessChain.indexChain.size() > 0) {
-        if (accessChain.instr == 0) {
-            StorageClass storageClass = (StorageClass)module.getStorageClass(getTypeId(accessChain.base));
-            accessChain.instr = createAccessChain(storageClass, accessChain.base, accessChain.indexChain);
-        }
-
+    // did we already emit an access chain for this?
+    if (accessChain.instr != NoResult)
         return accessChain.instr;
-    } else
+
+    // If we have a dynamic component, we can still transfer
+    // that into a final operand to the access chain.  We need to remap the
+    // dynamic component through the swizzle to get a new dynamic component to
+    // update.
+    //
+    // This was not done in transferAccessChainSwizzle() because it might
+    // generate code.
+    remapDynamicSwizzle();
+    if (accessChain.component != NoResult) {
+        // transfer the dynamic component to the access chain
+        accessChain.indexChain.push_back(accessChain.component);
+        accessChain.component = NoResult;
+    }
+
+    // note that non-trivial swizzling is left pending
+
+    // do we have an access chain?
+    if (accessChain.indexChain.size() == 0)
         return accessChain.base;
 
-    // note that non-trivial swizzling is left pending...
+    // emit the access chain
+    StorageClass storageClass = (StorageClass)module.getStorageClass(getTypeId(accessChain.base));
+    accessChain.instr = createAccessChain(storageClass, accessChain.base, accessChain.indexChain);
+
+    return accessChain.instr;
+}
+
+// For a dynamic component selection of a swizzle.
+//
+// Turn the swizzle and dynamic component into just a dynamic component.
+//
+// Generates code.
+void Builder::remapDynamicSwizzle()
+{
+    // do we have a swizzle to remap a dynamic component through?
+    if (accessChain.component != NoResult && accessChain.swizzle.size() > 1) {
+        // build a vector of the swizzle for the component to map into
+        std::vector<Id> components;
+        for (int c = 0; c < (int)accessChain.swizzle.size(); ++c)
+            components.push_back(makeUintConstant(accessChain.swizzle[c]));
+        Id mapType = makeVectorType(makeUintType(32), (int)accessChain.swizzle.size());
+        Id map = makeCompositeConstant(mapType, components);
+
+        // use it
+        accessChain.component = createVectorExtractDynamic(map, makeUintType(32), accessChain.component);
+        accessChain.swizzle.clear();
+    }
 }
 
 // clear out swizzle if it is redundant, that is reselecting the same components
@@ -2502,38 +2629,30 @@
 
 // To the extent any swizzling can become part of the chain
 // of accesses instead of a post operation, make it so.
-// If 'dynamic' is true, include transferring a non-static component index,
-// otherwise, only transfer static indexes.
+// If 'dynamic' is true, include transferring the dynamic component,
+// otherwise, leave it pending.
 //
-// Also, Boolean vectors are likely to be special.  While
-// for external storage, they should only be integer types,
-// function-local bool vectors could use sub-word indexing,
-// so keep that as a separate Insert/Extract on a loaded vector.
+// Does not generate code. just updates the access chain.
 void Builder::transferAccessChainSwizzle(bool dynamic)
 {
-    // too complex?
-    if (accessChain.swizzle.size() > 1)
-        return;
-
     // non existent?
     if (accessChain.swizzle.size() == 0 && accessChain.component == NoResult)
         return;
 
-    // single component...
-
-    // skip doing it for Boolean vectors
-    if (isBoolType(getContainedTypeId(accessChain.preSwizzleBaseType)))
+    // too complex?
+    // (this requires either a swizzle, or generating code for a dynamic component)
+    if (accessChain.swizzle.size() > 1)
         return;
 
+    // single component, either in the swizzle and/or dynamic component
     if (accessChain.swizzle.size() == 1) {
-        // handle static component
+        assert(accessChain.component == NoResult);
+        // handle static component selection
         accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front()));
         accessChain.swizzle.clear();
-        // note, the only valid remaining dynamic access would be to this one
-        // component, so don't bother even looking at accessChain.component
         accessChain.preSwizzleBaseType = NoType;
-        accessChain.component = NoResult;
     } else if (dynamic && accessChain.component != NoResult) {
+        assert(accessChain.swizzle.size() == 0);
         // handle dynamic component
         accessChain.indexChain.push_back(accessChain.component);
         accessChain.preSwizzleBaseType = NoType;
@@ -2572,12 +2691,15 @@
     buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
 }
 
-void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control)
+void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
+                              unsigned int dependencyLength)
 {
     Instruction* merge = new Instruction(OpLoopMerge);
     merge->addIdOperand(mergeBlock->getId());
     merge->addIdOperand(continueBlock->getId());
     merge->addImmediateOperand(control);
+    if ((control & LoopControlDependencyLengthMask) != 0)
+        merge->addImmediateOperand(dependencyLength);
     buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
 }
 
@@ -2644,8 +2766,6 @@
 void Builder::dumpModuleProcesses(std::vector<unsigned int>& out) const
 {
     for (int i = 0; i < (int)moduleProcesses.size(); ++i) {
-        // TODO: switch this out for the 1.1 headers
-        const spv::Op OpModuleProcessed = (spv::Op)330;
         Instruction moduleProcessed(OpModuleProcessed);
         moduleProcessed.addStringOperand(moduleProcesses[i]);
         moduleProcessed.dump(out);
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index 59b1da2..099b1d9 100755
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -1,6 +1,7 @@
 //
 // Copyright (C) 2014-2015 LunarG, Inc.
 // Copyright (C) 2015-2016 Google, Inc.
+// Copyright (C) 2017 ARM Limited.
 //
 // All rights reserved.
 //
@@ -55,16 +56,19 @@
 #include <set>
 #include <sstream>
 #include <stack>
+#include <unordered_map>
 
 namespace spv {
 
 class Builder {
 public:
-    Builder(unsigned int userNumber, SpvBuildLogger* logger);
+    Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
     virtual ~Builder();
 
     static const int maxMatrixSize = 4;
 
+    unsigned int getSpvVersion() const { return spvVersion; }
+
     void setSource(spv::SourceLanguage lang, int version)
     {
         source = lang;
@@ -149,7 +153,7 @@
     bool isAggregate(Id resultId)    const { return isAggregateType(getTypeId(resultId)); }
     bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
 
-    bool isBoolType(Id typeId)         const { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
+    bool isBoolType(Id typeId)               { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
     bool isIntType(Id typeId)          const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
     bool isUintType(Id typeId)         const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
     bool isFloatType(Id typeId)        const { return getTypeClass(typeId) == OpTypeFloat; }
@@ -211,19 +215,18 @@
 
     // For making new constants (will return old constant if the requested one was already made).
     Id makeBoolConstant(bool b, bool specConstant = false);
+    Id makeInt8Constant(int i, bool specConstant = false)        { return makeIntConstant(makeIntType(8),  (unsigned)i, specConstant); }
+    Id makeUint8Constant(unsigned u, bool specConstant = false)  { return makeIntConstant(makeUintType(8),           u, specConstant); }
+    Id makeInt16Constant(int i, bool specConstant = false)       { return makeIntConstant(makeIntType(16),  (unsigned)i, specConstant); }
+    Id makeUint16Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(16),           u, specConstant); }
     Id makeIntConstant(int i, bool specConstant = false)         { return makeIntConstant(makeIntType(32),  (unsigned)i, specConstant); }
     Id makeUintConstant(unsigned u, bool specConstant = false)   { return makeIntConstant(makeUintType(32),           u, specConstant); }
     Id makeInt64Constant(long long i, bool specConstant = false)            { return makeInt64Constant(makeIntType(64),  (unsigned long long)i, specConstant); }
     Id makeUint64Constant(unsigned long long u, bool specConstant = false)  { return makeInt64Constant(makeUintType(64),                     u, specConstant); }
-#ifdef AMD_EXTENSIONS
-    Id makeInt16Constant(short i, bool specConstant = false)        { return makeIntConstant(makeIntType(16),      (unsigned)((unsigned short)i), specConstant); }
-    Id makeUint16Constant(unsigned short u, bool specConstant = false)  { return makeIntConstant(makeUintType(16), (unsigned)u, specConstant); }
-#endif
     Id makeFloatConstant(float f, bool specConstant = false);
     Id makeDoubleConstant(double d, bool specConstant = false);
-#ifdef AMD_EXTENSIONS
     Id makeFloat16Constant(float f16, bool specConstant = false);
-#endif
+    Id makeFpConstant(Id type, double d, bool specConstant = false);
 
     // Turn the array of constants into a proper spv constant of the requested type.
     Id makeCompositeConstant(Id type, const std::vector<Id>& comps, bool specConst = false);
@@ -234,7 +237,10 @@
     void addName(Id, const char* name);
     void addMemberName(Id, int member, const char* name);
     void addDecoration(Id, Decoration, int num = -1);
+    void addDecoration(Id, Decoration, const char*);
+    void addDecorationId(Id id, Decoration, Id idDecoration);
     void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
+    void addMemberDecoration(Id, unsigned int member, Decoration, const char*);
 
     // At the end of what block do the next create*() instructions go?
     void setBuildPoint(Block* bp) { buildPoint = bp; }
@@ -330,7 +336,7 @@
     // Generally, the type of 'scalar' does not need to be the same type as the components in 'vector'.
     // The type of the created vector is a vector of components of the same type as the scalar.
     //
-    // Note: One of the arguments will change, with the result coming back that way rather than 
+    // Note: One of the arguments will change, with the result coming back that way rather than
     // through the return value.
     void promoteScalar(Decoration precision, Id& left, Id& right);
 
@@ -533,19 +539,22 @@
     // push new swizzle onto the end of any existing swizzle, merging into a single swizzle
     void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType);
 
-    // push a variable component selection onto the access chain; supporting only one, so unsided
+    // push a dynamic component selection onto the access chain, only applicable with a
+    // non-trivial swizzle or no swizzle
     void accessChainPushComponent(Id component, Id preSwizzleBaseType)
     {
-        accessChain.component = component;
-        if (accessChain.preSwizzleBaseType == NoType)
-            accessChain.preSwizzleBaseType = preSwizzleBaseType;
+        if (accessChain.swizzle.size() != 1) {
+            accessChain.component = component;
+            if (accessChain.preSwizzleBaseType == NoType)
+                accessChain.preSwizzleBaseType = preSwizzleBaseType;
+        }
     }
 
     // use accessChain and swizzle to store value
     void accessChainStore(Id rvalue);
 
     // use accessChain and swizzle to load an r-value
-    Id accessChainLoad(Decoration precision, Id ResultType);
+    Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType);
 
     // get the direct pointer for an l-value
     Id accessChainGetLValue();
@@ -561,7 +570,7 @@
 
     void createBranch(Block* block);
     void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
-    void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control);
+    void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, unsigned int dependencyLength);
 
     // Sets to generate opcode for specialization constants.
     void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
@@ -573,10 +582,12 @@
  protected:
     Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
     Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
-    Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const;
-    Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const;
-    Id findCompositeConstant(Op typeClass, const std::vector<Id>& comps) const;
+    Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value);
+    Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2);
+    Id findCompositeConstant(Op typeClass, const std::vector<Id>& comps);
+    Id findStructConstant(Id typeId, const std::vector<Id>& comps);
     Id collapseAccessChain();
+    void remapDynamicSwizzle();
     void transferAccessChainSwizzle(bool dynamic);
     void simplifyAccessChainSwizzle();
     void createAndSetNoPredecessorBlock(const char*);
@@ -585,6 +596,7 @@
     void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
     void dumpModuleProcesses(std::vector<unsigned int>&) const;
 
+    unsigned int spvVersion;     // the version of SPIR-V to emit in the header
     SourceLanguage source;
     int sourceVersion;
     spv::Id sourceFileStringId;
@@ -611,15 +623,15 @@
     std::vector<std::unique_ptr<Instruction> > entryPoints;
     std::vector<std::unique_ptr<Instruction> > executionModes;
     std::vector<std::unique_ptr<Instruction> > names;
-    std::vector<std::unique_ptr<Instruction> > lines;
     std::vector<std::unique_ptr<Instruction> > decorations;
     std::vector<std::unique_ptr<Instruction> > constantsTypesGlobals;
     std::vector<std::unique_ptr<Instruction> > externals;
     std::vector<std::unique_ptr<Function> > functions;
 
      // not output, internally used for quick & dirty canonical (unique) creation
-    std::vector<Instruction*> groupedConstants[OpConstant];  // all types appear before OpConstant
-    std::vector<Instruction*> groupedTypes[OpConstant];
+    std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants;       // map type opcodes to constant inst.
+    std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants; // map struct-id to constant instructions
+    std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;           // map type opcodes to type instructions
 
     // stack of switches
     std::stack<Block*> switchMerges;
diff --git a/SPIRV/disassemble.cpp b/SPIRV/disassemble.cpp
index c950a66..c07dfc7 100644
--- a/SPIRV/disassemble.cpp
+++ b/SPIRV/disassemble.cpp
@@ -54,6 +54,7 @@
 #ifdef AMD_EXTENSIONS
         #include "GLSL.ext.AMD.h"
 #endif
+
 #ifdef NV_EXTENSIONS
         #include "GLSL.ext.NV.h"
 #endif
@@ -80,12 +81,15 @@
 // used to identify the extended instruction library imported when printing
 enum ExtInstSet {
     GLSL450Inst,
+
 #ifdef AMD_EXTENSIONS
     GLSLextAMDInst,
 #endif
+
 #ifdef NV_EXTENSIONS
     GLSLextNVInst,
 #endif
+
     OpenCLExtInst,
 };
 
@@ -653,7 +657,6 @@
 }
 #endif
 
-
 #ifdef NV_EXTENSIONS
 static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
 {
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index f9d5254..a905968 100755
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -49,6 +49,7 @@
     extern "C" {
         // Include C-based headers that don't have a namespace
         #include "GLSL.ext.KHR.h"
+        #include "GLSL.ext.EXT.h"
 #ifdef AMD_EXTENSIONS
         #include "GLSL.ext.AMD.h"
 #endif
@@ -65,7 +66,7 @@
 // the specification (or their sanitized versions for auto-generating the
 // spirv headers.
 //
-// Also, the ceilings are declared next to these, to help keep them in sync.
+// Also, for masks the ceilings are declared next to these, to help keep them in sync.
 // Ceilings should be
 //  - one more than the maximum value an enumerant takes on, for non-mask enumerants
 //    (for non-sparse enums, this is the number of enumerants)
@@ -73,8 +74,6 @@
 //    (for non-sparse mask enums, this is the number of enumerants)
 //
 
-const int SourceLanguageCeiling = 6; // HLSL todo: need official enumerant
-
 const char* SourceString(int source)
 {
     switch (source) {
@@ -85,13 +84,10 @@
     case 4:  return "OpenCL_CPP";
     case 5:  return "HLSL";
 
-    case SourceLanguageCeiling:
     default: return "Bad";
     }
 }
 
-const int ExecutionModelCeiling = 7;
-
 const char* ExecutionModelString(int model)
 {
     switch (model) {
@@ -103,13 +99,10 @@
     case 5:  return "GLCompute";
     case 6:  return "Kernel";
 
-    case ExecutionModelCeiling:
     default: return "Bad";
     }
 }
 
-const int AddressingModelCeiling = 3;
-
 const char* AddressingString(int addr)
 {
     switch (addr) {
@@ -117,13 +110,10 @@
     case 1:  return "Physical32";
     case 2:  return "Physical64";
 
-    case AddressingModelCeiling:
     default: return "Bad";
     }
 }
 
-const int MemoryModelCeiling = 3;
-
 const char* MemoryString(int mem)
 {
     switch (mem) {
@@ -131,7 +121,6 @@
     case 1:  return "GLSL450";
     case 2:  return "OpenCL";
 
-    case MemoryModelCeiling:
     default: return "Bad";
     }
 }
@@ -181,8 +170,6 @@
     }
 }
 
-const int StorageClassCeiling = 13;
-
 const char* StorageClassString(int StorageClass)
 {
     switch (StorageClass) {
@@ -200,7 +187,6 @@
     case 11: return "Image";
     case 12: return "StorageBuffer";
 
-    case StorageClassCeiling:
     default: return "Bad";
     }
 }
@@ -260,19 +246,21 @@
     default:  return "Bad";
 
 #ifdef AMD_EXTENSIONS
-    case 4999: return "ExplicitInterpAMD";
+    case DecorationExplicitInterpAMD: return "ExplicitInterpAMD";
 #endif
 #ifdef NV_EXTENSIONS
-    case 5248: return "OverrideCoverageNV";
-    case 5250: return "PassthroughNV";
-    case 5252: return "ViewportRelativeNV";
-    case 5256: return "SecondaryViewportRelativeNV";
+    case DecorationOverrideCoverageNV:          return "OverrideCoverageNV";
+    case DecorationPassthroughNV:               return "PassthroughNV";
+    case DecorationViewportRelativeNV:          return "ViewportRelativeNV";
+    case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
 #endif
+
+    case DecorationNonUniformEXT:           return "DecorationNonUniformEXT";
+    case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
+    case DecorationHlslSemanticGOOGLE:      return "DecorationHlslSemanticGOOGLE";
     }
 }
 
-const int BuiltInCeiling = 44;
-
 const char* BuiltInString(int builtIn)
 {
     switch (builtIn) {
@@ -351,13 +339,12 @@
     case 5262: return "ViewportMaskPerViewNV";
 #endif
 
-    case BuiltInCeiling:
+    case 5264: return "FullyCoveredEXT";
+
     default: return "Bad";
     }
 }
 
-const int DimensionCeiling = 7;
-
 const char* DimensionString(int dim)
 {
     switch (dim) {
@@ -369,13 +356,10 @@
     case 5:  return "Buffer";
     case 6:  return "SubpassData";
 
-    case DimensionCeiling:
     default: return "Bad";
     }
 }
 
-const int SamplerAddressingModeCeiling = 5;
-
 const char* SamplerAddressingModeString(int mode)
 {
     switch (mode) {
@@ -385,26 +369,20 @@
     case 3:  return "Repeat";
     case 4:  return "RepeatMirrored";
 
-    case SamplerAddressingModeCeiling:
     default: return "Bad";
     }
 }
 
-const int SamplerFilterModeCeiling = 2;
-
 const char* SamplerFilterModeString(int mode)
 {
     switch (mode) {
     case 0: return "Nearest";
     case 1: return "Linear";
 
-    case SamplerFilterModeCeiling:
     default: return "Bad";
     }
 }
 
-const int ImageFormatCeiling = 40;
-
 const char* ImageFormatString(int format)
 {
     switch (format) {
@@ -461,14 +439,11 @@
     case 38: return "R16ui";
     case 39: return "R8ui";
 
-    case ImageFormatCeiling:
     default:
         return "Bad";
     }
 }
 
-const int ImageChannelOrderCeiling = 19;
-
 const char* ImageChannelOrderString(int format)
 {
     switch (format) {
@@ -492,14 +467,11 @@
     case 17: return "sRGBA";
     case 18: return "sBGRA";
 
-    case ImageChannelOrderCeiling:
     default: 
         return "Bad";
     }
 }
 
-const int ImageChannelDataTypeCeiling = 17;
-
 const char* ImageChannelDataTypeString(int type)
 {
     switch (type)
@@ -522,7 +494,6 @@
     case 15: return "UnormInt24";
     case 16: return "UnormInt101010_2";
 
-    case ImageChannelDataTypeCeiling:
     default:
         return "Bad";
     }
@@ -548,8 +519,6 @@
     }
 }
 
-const int FPFastMathCeiling = 5;
-
 const char* FPFastMathString(int mode)
 {
     switch (mode) {
@@ -559,13 +528,10 @@
     case 3: return "AllowRecip";
     case 4: return "Fast";
 
-    case FPFastMathCeiling:
     default:     return "Bad";
     }
 }
 
-const int FPRoundingModeCeiling = 4;
-
 const char* FPRoundingModeString(int mode)
 {
     switch (mode) {
@@ -574,26 +540,20 @@
     case 2:  return "RTP";
     case 3:  return "RTN";
 
-    case FPRoundingModeCeiling:
     default: return "Bad";
     }
 }
 
-const int LinkageTypeCeiling = 2;
-
 const char* LinkageTypeString(int type)
 {
     switch (type) {
     case 0:  return "Export";
     case 1:  return "Import";
 
-    case LinkageTypeCeiling:
     default: return "Bad";
     }
 }
 
-const int FuncParamAttrCeiling = 8;
-
 const char* FuncParamAttrString(int attr)
 {
     switch (attr) {
@@ -606,13 +566,10 @@
     case 6:  return "NoWrite";
     case 7:  return "NoReadWrite";
 
-    case FuncParamAttrCeiling:
     default: return "Bad";
     }
 }
 
-const int AccessQualifierCeiling = 3;
-
 const char* AccessQualifierString(int attr)
 {
     switch (attr) {
@@ -620,7 +577,6 @@
     case 1:  return "WriteOnly";
     case 2:  return "ReadWrite";
 
-    case AccessQualifierCeiling:
     default: return "Bad";
     }
 }
@@ -668,8 +624,6 @@
     }
 }
 
-const int MemorySemanticsCeiling = 12;
-
 const char* MemorySemanticsString(int mem)
 {
     // Note: No bits set (None) means "Relaxed"
@@ -687,13 +641,10 @@
     case 10: return "AtomicCounterMemory";
     case 11: return "ImageMemory";
 
-    case MemorySemanticsCeiling:
     default:     return "Bad";
     }
 }
 
-const int MemoryAccessCeiling = 3;
-
 const char* MemoryAccessString(int mem)
 {
     switch (mem) {
@@ -701,13 +652,10 @@
     case 1:  return "Aligned";
     case 2:  return "Nontemporal";
 
-    case MemoryAccessCeiling:
     default: return "Bad";
     }
 }
 
-const int ScopeCeiling = 5;
-
 const char* ScopeString(int mem)
 {
     switch (mem) {
@@ -717,29 +665,29 @@
     case 3:  return "Subgroup";
     case 4:  return "Invocation";
 
-    case ScopeCeiling:
     default: return "Bad";
     }
 }
 
-const int GroupOperationCeiling = 3;
-
 const char* GroupOperationString(int gop)
 {
 
     switch (gop)
     {
-    case 0:  return "Reduce";
-    case 1:  return "InclusiveScan";
-    case 2:  return "ExclusiveScan";
+    case GroupOperationReduce:  return "Reduce";
+    case GroupOperationInclusiveScan:  return "InclusiveScan";
+    case GroupOperationExclusiveScan:  return "ExclusiveScan";
+    case GroupOperationClusteredReduce:  return "ClusteredReduce";
+#ifdef NV_EXTENSIONS
+    case GroupOperationPartitionedReduceNV:  return "PartitionedReduceNV";
+    case GroupOperationPartitionedInclusiveScanNV:  return "PartitionedInclusiveScanNV";
+    case GroupOperationPartitionedExclusiveScanNV:  return "PartitionedExclusiveScanNV";
+#endif
 
-    case GroupOperationCeiling:
     default: return "Bad";
     }
 }
 
-const int KernelEnqueueFlagsCeiling = 3;
-
 const char* KernelEnqueueFlagsString(int flag)
 {
     switch (flag)
@@ -748,26 +696,20 @@
     case 1:  return "WaitKernel";
     case 2:  return "WaitWorkGroup";
 
-    case KernelEnqueueFlagsCeiling:
     default: return "Bad";
     }
 }
 
-const int KernelProfilingInfoCeiling = 1;
-
 const char* KernelProfilingInfoString(int info)
 {
     switch (info)
     {
     case 0:  return "CmdExecTime";
 
-    case KernelProfilingInfoCeiling:
     default: return "Bad";
     }
 }
 
-const int CapabilityCeiling = 58;
-
 const char* CapabilityString(int info)
 {
     switch (info)
@@ -830,39 +772,63 @@
     case 55: return "StorageImageReadWithoutFormat";
     case 56: return "StorageImageWriteWithoutFormat";
     case 57: return "MultiViewport";
+    case 61: return "GroupNonUniform";
+    case 62: return "GroupNonUniformVote";
+    case 63: return "GroupNonUniformArithmetic";
+    case 64: return "GroupNonUniformBallot";
+    case 65: return "GroupNonUniformShuffle";
+    case 66: return "GroupNonUniformShuffleRelative";
+    case 67: return "GroupNonUniformClustered";
+    case 68: return "GroupNonUniformQuad";
 
-    case 4423: return "SubgroupBallotKHR";
-    case 4427: return "DrawParameters";
-    case 4431: return "SubgroupVoteKHR";
+    case CapabilitySubgroupBallotKHR: return "SubgroupBallotKHR";
+    case CapabilityDrawParameters:    return "DrawParameters";
+    case CapabilitySubgroupVoteKHR:   return "SubgroupVoteKHR";
 
-    case 4433: return "StorageUniformBufferBlock16";
-    case 4434: return "StorageUniform16";
-    case 4435: return "StoragePushConstant16";
-    case 4436: return "StorageInputOutput16";
+    case CapabilityStorageUniformBufferBlock16: return "StorageUniformBufferBlock16";
+    case CapabilityStorageUniform16:            return "StorageUniform16";
+    case CapabilityStoragePushConstant16:       return "StoragePushConstant16";
+    case CapabilityStorageInputOutput16:        return "StorageInputOutput16";
 
-    case 4437: return "DeviceGroup";
-    case 4439: return "MultiView";
+    case CapabilityDeviceGroup: return "DeviceGroup";
+    case CapabilityMultiView:   return "MultiView";
 
-    case 5013: return "StencilExportEXT";
+    case CapabilityStencilExportEXT: return "StencilExportEXT";
 
 #ifdef AMD_EXTENSIONS
-    case 5009: return "ImageGatherBiasLodAMD";
-    case 5010: return "FragmentMaskAMD";
-    case 5015: return "ImageReadWriteLodAMD";
+    case CapabilityFloat16ImageAMD:       return "Float16ImageAMD";
+    case CapabilityImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD";
+    case CapabilityFragmentMaskAMD:       return "FragmentMaskAMD";
+    case CapabilityImageReadWriteLodAMD:  return "ImageReadWriteLodAMD";
 #endif
 
-    case 4445: return "AtomicStorageOps";
+    case CapabilityAtomicStorageOps:             return "AtomicStorageOps";
 
-    case 4447: return "SampleMaskPostDepthCoverage";
+    case CapabilitySampleMaskPostDepthCoverage:  return "SampleMaskPostDepthCoverage";
 #ifdef NV_EXTENSIONS
-    case 5251: return "GeometryShaderPassthroughNV";
-    case 5254: return "ShaderViewportIndexLayerNV";
-    case 5255: return "ShaderViewportMaskNV";
-    case 5259: return "ShaderStereoViewNV";
-    case 5260: return "PerViewAttributesNV";
+    case CapabilityGeometryShaderPassthroughNV:  return "GeometryShaderPassthroughNV";
+    case CapabilityShaderViewportIndexLayerNV:   return "ShaderViewportIndexLayerNV";
+    case CapabilityShaderViewportMaskNV:         return "ShaderViewportMaskNV";
+    case CapabilityShaderStereoViewNV:           return "ShaderStereoViewNV";
+    case CapabilityPerViewAttributesNV:          return "PerViewAttributesNV";
+    case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
 #endif
 
-    case CapabilityCeiling:
+    case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT";
+
+    case CapabilityShaderNonUniformEXT:                          return "CapabilityShaderNonUniformEXT";
+    case CapabilityRuntimeDescriptorArrayEXT:                    return "CapabilityRuntimeDescriptorArrayEXT";
+    case CapabilityInputAttachmentArrayDynamicIndexingEXT:       return "CapabilityInputAttachmentArrayDynamicIndexingEXT";
+    case CapabilityUniformTexelBufferArrayDynamicIndexingEXT:    return "CapabilityUniformTexelBufferArrayDynamicIndexingEXT";
+    case CapabilityStorageTexelBufferArrayDynamicIndexingEXT:    return "CapabilityStorageTexelBufferArrayDynamicIndexingEXT";
+    case CapabilityUniformBufferArrayNonUniformIndexingEXT:      return "CapabilityUniformBufferArrayNonUniformIndexingEXT";
+    case CapabilitySampledImageArrayNonUniformIndexingEXT:       return "CapabilitySampledImageArrayNonUniformIndexingEXT";
+    case CapabilityStorageBufferArrayNonUniformIndexingEXT:      return "CapabilityStorageBufferArrayNonUniformIndexingEXT";
+    case CapabilityStorageImageArrayNonUniformIndexingEXT:       return "CapabilityStorageImageArrayNonUniformIndexingEXT";
+    case CapabilityInputAttachmentArrayNonUniformIndexingEXT:    return "CapabilityInputAttachmentArrayNonUniformIndexingEXT";
+    case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT";
+    case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT";
+
     default: return "Bad";
     }
 }
@@ -1192,6 +1158,44 @@
     case 319: return "OpAtomicFlagClear";
     case 320: return "OpImageSparseRead";
 
+    case OpModuleProcessed: return "OpModuleProcessed";
+    case OpDecorateId:      return "OpDecorateId";
+
+    case 333: return "OpGroupNonUniformElect";
+    case 334: return "OpGroupNonUniformAll";
+    case 335: return "OpGroupNonUniformAny";
+    case 336: return "OpGroupNonUniformAllEqual";
+    case 337: return "OpGroupNonUniformBroadcast";
+    case 338: return "OpGroupNonUniformBroadcastFirst";
+    case 339: return "OpGroupNonUniformBallot";
+    case 340: return "OpGroupNonUniformInverseBallot";
+    case 341: return "OpGroupNonUniformBallotBitExtract";
+    case 342: return "OpGroupNonUniformBallotBitCount";
+    case 343: return "OpGroupNonUniformBallotFindLSB";
+    case 344: return "OpGroupNonUniformBallotFindMSB";
+    case 345: return "OpGroupNonUniformShuffle";
+    case 346: return "OpGroupNonUniformShuffleXor";
+    case 347: return "OpGroupNonUniformShuffleUp";
+    case 348: return "OpGroupNonUniformShuffleDown";
+    case 349: return "OpGroupNonUniformIAdd";
+    case 350: return "OpGroupNonUniformFAdd";
+    case 351: return "OpGroupNonUniformIMul";
+    case 352: return "OpGroupNonUniformFMul";
+    case 353: return "OpGroupNonUniformSMin";
+    case 354: return "OpGroupNonUniformUMin";
+    case 355: return "OpGroupNonUniformFMin";
+    case 356: return "OpGroupNonUniformSMax";
+    case 357: return "OpGroupNonUniformUMax";
+    case 358: return "OpGroupNonUniformFMax";
+    case 359: return "OpGroupNonUniformBitwiseAnd";
+    case 360: return "OpGroupNonUniformBitwiseOr";
+    case 361: return "OpGroupNonUniformBitwiseXor";
+    case 362: return "OpGroupNonUniformLogicalAnd";
+    case 363: return "OpGroupNonUniformLogicalOr";
+    case 364: return "OpGroupNonUniformLogicalXor";
+    case 365: return "OpGroupNonUniformQuadBroadcast";
+    case 366: return "OpGroupNonUniformQuadSwap";
+
     case 4421: return "OpSubgroupBallotKHR";
     case 4422: return "OpSubgroupFirstInvocationKHR";
     case 4428: return "OpSubgroupAllKHR";
@@ -1213,7 +1217,12 @@
     case 5012: return "OpFragmentFetchAMD";
 #endif
 
-    case OpcodeCeiling:
+    case OpDecorateStringGOOGLE:       return "OpDecorateStringGOOGLE";
+    case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
+
+#ifdef NV_EXTENSIONS
+    case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV";
+#endif
     default:
         return "Bad";
     }
@@ -1226,35 +1235,12 @@
 OperandParameters DecorationOperands[DecorationCeiling];
 
 EnumDefinition OperandClassParams[OperandCount];
-EnumParameters ExecutionModelParams[ExecutionModelCeiling];
-EnumParameters AddressingParams[AddressingModelCeiling];
-EnumParameters MemoryParams[MemoryModelCeiling];
 EnumParameters ExecutionModeParams[ExecutionModeCeiling];
-EnumParameters StorageParams[StorageClassCeiling];
-EnumParameters SamplerAddressingModeParams[SamplerAddressingModeCeiling];
-EnumParameters SamplerFilterModeParams[SamplerFilterModeCeiling];
-EnumParameters ImageFormatParams[ImageFormatCeiling];
-EnumParameters ImageChannelOrderParams[ImageChannelOrderCeiling];
-EnumParameters ImageChannelDataTypeParams[ImageChannelDataTypeCeiling];
 EnumParameters ImageOperandsParams[ImageOperandsCeiling];
-EnumParameters FPFastMathParams[FPFastMathCeiling];
-EnumParameters FPRoundingModeParams[FPRoundingModeCeiling];
-EnumParameters LinkageTypeParams[LinkageTypeCeiling];
 EnumParameters DecorationParams[DecorationCeiling];
-EnumParameters BuiltInParams[BuiltInCeiling];
-EnumParameters DimensionalityParams[DimensionCeiling];
-EnumParameters FuncParamAttrParams[FuncParamAttrCeiling];
-EnumParameters AccessQualifierParams[AccessQualifierCeiling];
-EnumParameters GroupOperationParams[GroupOperationCeiling];
 EnumParameters LoopControlParams[FunctionControlCeiling];
 EnumParameters SelectionControlParams[SelectControlCeiling];
 EnumParameters FunctionControlParams[FunctionControlCeiling];
-EnumParameters MemorySemanticsParams[MemorySemanticsCeiling];
-EnumParameters MemoryAccessParams[MemoryAccessCeiling];
-EnumParameters ScopeParams[ScopeCeiling];
-EnumParameters KernelEnqueueFlagsParams[KernelEnqueueFlagsCeiling];
-EnumParameters KernelProfilingInfoParams[KernelProfilingInfoCeiling];
-EnumParameters CapabilityParams[CapabilityCeiling];
 
 // Set up all the parameterizing descriptions of the opcodes, operands, etc.
 void Parameterize()
@@ -1304,7 +1290,10 @@
     InstructionDesc[OpImageWrite].setResultAndType(false, false);
     InstructionDesc[OpDecorationGroup].setResultAndType(true, false);
     InstructionDesc[OpDecorate].setResultAndType(false, false);
+    InstructionDesc[OpDecorateId].setResultAndType(false, false);
+    InstructionDesc[OpDecorateStringGOOGLE].setResultAndType(false, false);
     InstructionDesc[OpMemberDecorate].setResultAndType(false, false);
+    InstructionDesc[OpMemberDecorateStringGOOGLE].setResultAndType(false, false);
     InstructionDesc[OpGroupDecorate].setResultAndType(false, false);
     InstructionDesc[OpGroupMemberDecorate].setResultAndType(false, false);
     InstructionDesc[OpName].setResultAndType(false, false);
@@ -1343,6 +1332,7 @@
     InstructionDesc[OpReleaseEvent].setResultAndType(false, false);
     InstructionDesc[OpGroupWaitEvents].setResultAndType(false, false);
     InstructionDesc[OpAtomicFlagClear].setResultAndType(false, false);
+    InstructionDesc[OpModuleProcessed].setResultAndType(false, false);
 
     // Specific additional context-dependent operands
 
@@ -1380,354 +1370,39 @@
     DecorationOperands[DecorationInputAttachmentIndex].push(OperandLiteralNumber, "'Attachment Index'");
     DecorationOperands[DecorationAlignment].push(OperandLiteralNumber, "'Alignment'");
 
-    OperandClassParams[OperandSource].set(SourceLanguageCeiling, SourceString, 0);
-    OperandClassParams[OperandExecutionModel].set(ExecutionModelCeiling, ExecutionModelString, ExecutionModelParams);
-    OperandClassParams[OperandAddressing].set(AddressingModelCeiling, AddressingString, AddressingParams);
-    OperandClassParams[OperandMemory].set(MemoryModelCeiling, MemoryString, MemoryParams);
+    OperandClassParams[OperandSource].set(0, SourceString, 0);
+    OperandClassParams[OperandExecutionModel].set(0, ExecutionModelString, nullptr);
+    OperandClassParams[OperandAddressing].set(0, AddressingString, nullptr);
+    OperandClassParams[OperandMemory].set(0, MemoryString, nullptr);
     OperandClassParams[OperandExecutionMode].set(ExecutionModeCeiling, ExecutionModeString, ExecutionModeParams);
     OperandClassParams[OperandExecutionMode].setOperands(ExecutionModeOperands);
-    OperandClassParams[OperandStorage].set(StorageClassCeiling, StorageClassString, StorageParams);
-    OperandClassParams[OperandDimensionality].set(DimensionCeiling, DimensionString, DimensionalityParams);
-    OperandClassParams[OperandSamplerAddressingMode].set(SamplerAddressingModeCeiling, SamplerAddressingModeString, SamplerAddressingModeParams);
-    OperandClassParams[OperandSamplerFilterMode].set(SamplerFilterModeCeiling, SamplerFilterModeString, SamplerFilterModeParams);
-    OperandClassParams[OperandSamplerImageFormat].set(ImageFormatCeiling, ImageFormatString, ImageFormatParams);
-    OperandClassParams[OperandImageChannelOrder].set(ImageChannelOrderCeiling, ImageChannelOrderString, ImageChannelOrderParams);
-    OperandClassParams[OperandImageChannelDataType].set(ImageChannelDataTypeCeiling, ImageChannelDataTypeString, ImageChannelDataTypeParams);
+    OperandClassParams[OperandStorage].set(0, StorageClassString, nullptr);
+    OperandClassParams[OperandDimensionality].set(0, DimensionString, nullptr);
+    OperandClassParams[OperandSamplerAddressingMode].set(0, SamplerAddressingModeString, nullptr);
+    OperandClassParams[OperandSamplerFilterMode].set(0, SamplerFilterModeString, nullptr);
+    OperandClassParams[OperandSamplerImageFormat].set(0, ImageFormatString, nullptr);
+    OperandClassParams[OperandImageChannelOrder].set(0, ImageChannelOrderString, nullptr);
+    OperandClassParams[OperandImageChannelDataType].set(0, ImageChannelDataTypeString, nullptr);
     OperandClassParams[OperandImageOperands].set(ImageOperandsCeiling, ImageOperandsString, ImageOperandsParams, true);
-    OperandClassParams[OperandFPFastMath].set(FPFastMathCeiling, FPFastMathString, FPFastMathParams, true);
-    OperandClassParams[OperandFPRoundingMode].set(FPRoundingModeCeiling, FPRoundingModeString, FPRoundingModeParams);
-    OperandClassParams[OperandLinkageType].set(LinkageTypeCeiling, LinkageTypeString, LinkageTypeParams);
-    OperandClassParams[OperandFuncParamAttr].set(FuncParamAttrCeiling, FuncParamAttrString, FuncParamAttrParams);
-    OperandClassParams[OperandAccessQualifier].set(AccessQualifierCeiling, AccessQualifierString, AccessQualifierParams);
+    OperandClassParams[OperandFPFastMath].set(0, FPFastMathString, nullptr, true);
+    OperandClassParams[OperandFPRoundingMode].set(0, FPRoundingModeString, nullptr);
+    OperandClassParams[OperandLinkageType].set(0, LinkageTypeString, nullptr);
+    OperandClassParams[OperandFuncParamAttr].set(0, FuncParamAttrString, nullptr);
+    OperandClassParams[OperandAccessQualifier].set(0, AccessQualifierString, nullptr);
     OperandClassParams[OperandDecoration].set(DecorationCeiling, DecorationString, DecorationParams);
     OperandClassParams[OperandDecoration].setOperands(DecorationOperands);
-    OperandClassParams[OperandBuiltIn].set(BuiltInCeiling, BuiltInString, BuiltInParams);
+    OperandClassParams[OperandBuiltIn].set(0, BuiltInString, nullptr);
     OperandClassParams[OperandSelect].set(SelectControlCeiling, SelectControlString, SelectionControlParams, true);
     OperandClassParams[OperandLoop].set(LoopControlCeiling, LoopControlString, LoopControlParams, true);
     OperandClassParams[OperandFunction].set(FunctionControlCeiling, FunctionControlString, FunctionControlParams, true);
-    OperandClassParams[OperandMemorySemantics].set(MemorySemanticsCeiling, MemorySemanticsString, MemorySemanticsParams, true);
-    OperandClassParams[OperandMemoryAccess].set(MemoryAccessCeiling, MemoryAccessString, MemoryAccessParams, true);
-    OperandClassParams[OperandScope].set(ScopeCeiling, ScopeString, ScopeParams);
-    OperandClassParams[OperandGroupOperation].set(GroupOperationCeiling, GroupOperationString, GroupOperationParams);
-    OperandClassParams[OperandKernelEnqueueFlags].set(KernelEnqueueFlagsCeiling, KernelEnqueueFlagsString, KernelEnqueueFlagsParams);
-    OperandClassParams[OperandKernelProfilingInfo].set(KernelProfilingInfoCeiling, KernelProfilingInfoString, KernelProfilingInfoParams, true);
-    OperandClassParams[OperandCapability].set(CapabilityCeiling, CapabilityString, CapabilityParams);
-    OperandClassParams[OperandOpcode].set(OpcodeCeiling, OpcodeString, 0);
-
-    CapabilityParams[CapabilityShader].caps.push_back(CapabilityMatrix);
-    CapabilityParams[CapabilityGeometry].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityTessellation].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityVector16].caps.push_back(CapabilityKernel);
-    CapabilityParams[CapabilityFloat16Buffer].caps.push_back(CapabilityKernel);
-    CapabilityParams[CapabilityInt64Atomics].caps.push_back(CapabilityInt64);
-    CapabilityParams[CapabilityImageBasic].caps.push_back(CapabilityKernel);
-    CapabilityParams[CapabilityImageReadWrite].caps.push_back(CapabilityImageBasic);
-    CapabilityParams[CapabilityImageMipmap].caps.push_back(CapabilityImageBasic);
-    CapabilityParams[CapabilityPipes].caps.push_back(CapabilityKernel);
-    CapabilityParams[CapabilityDeviceEnqueue].caps.push_back(CapabilityKernel);
-    CapabilityParams[CapabilityLiteralSampler].caps.push_back(CapabilityKernel);
-    CapabilityParams[CapabilityAtomicStorage].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilitySampleRateShading].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityTessellationPointSize].caps.push_back(CapabilityTessellation);
-    CapabilityParams[CapabilityGeometryPointSize].caps.push_back(CapabilityGeometry);
-    CapabilityParams[CapabilityImageGatherExtended].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityStorageImageExtendedFormats].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityStorageImageMultisample].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityUniformBufferArrayDynamicIndexing].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilitySampledImageArrayDynamicIndexing].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityStorageBufferArrayDynamicIndexing].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityStorageImageArrayDynamicIndexing].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityClipDistance].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityCullDistance].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityGenericPointer].caps.push_back(CapabilityAddresses);
-    CapabilityParams[CapabilityInt8].caps.push_back(CapabilityKernel);
-    CapabilityParams[CapabilityInputAttachment].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityMinLod].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilitySparseResidency].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilitySampled1D].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilitySampledRect].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilitySampledBuffer].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilitySampledCubeArray].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityImageMSArray].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityImage1D].caps.push_back(CapabilitySampled1D);
-    CapabilityParams[CapabilityImageRect].caps.push_back(CapabilitySampledRect);
-    CapabilityParams[CapabilityImageBuffer].caps.push_back(CapabilitySampledBuffer);
-    CapabilityParams[CapabilityImageCubeArray].caps.push_back(CapabilitySampledCubeArray);
-    CapabilityParams[CapabilityImageQuery].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityDerivativeControl].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityInterpolationFunction].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityTransformFeedback].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityGeometryStreams].caps.push_back(CapabilityGeometry);
-    CapabilityParams[CapabilityStorageImageReadWithoutFormat].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityStorageImageWriteWithoutFormat].caps.push_back(CapabilityShader);
-    CapabilityParams[CapabilityMultiViewport].caps.push_back(CapabilityGeometry);
-
-    AddressingParams[AddressingModelPhysical32].caps.push_back(CapabilityAddresses);
-    AddressingParams[AddressingModelPhysical64].caps.push_back(CapabilityAddresses);
-
-    MemoryParams[MemoryModelSimple].caps.push_back(CapabilityShader);
-    MemoryParams[MemoryModelGLSL450].caps.push_back(CapabilityShader);
-    MemoryParams[MemoryModelOpenCL].caps.push_back(CapabilityKernel);
-
-    MemorySemanticsParams[MemorySemanticsUniformMemoryShift].caps.push_back(CapabilityShader);
-    MemorySemanticsParams[MemorySemanticsAtomicCounterMemoryShift].caps.push_back(CapabilityAtomicStorage);
-
-    ExecutionModelParams[ExecutionModelVertex].caps.push_back(CapabilityShader);
-    ExecutionModelParams[ExecutionModelTessellationControl].caps.push_back(CapabilityTessellation);
-    ExecutionModelParams[ExecutionModelTessellationEvaluation].caps.push_back(CapabilityTessellation);
-    ExecutionModelParams[ExecutionModelGeometry].caps.push_back(CapabilityGeometry);
-    ExecutionModelParams[ExecutionModelFragment].caps.push_back(CapabilityShader);
-    ExecutionModelParams[ExecutionModelGLCompute].caps.push_back(CapabilityShader);
-    ExecutionModelParams[ExecutionModelKernel].caps.push_back(CapabilityKernel);
-
-    // Storage capabilites
-    StorageParams[StorageClassInput].caps.push_back(CapabilityShader);
-    StorageParams[StorageClassUniform].caps.push_back(CapabilityShader);
-    StorageParams[StorageClassOutput].caps.push_back(CapabilityShader);
-    StorageParams[StorageClassPrivate].caps.push_back(CapabilityShader);
-    StorageParams[StorageClassGeneric].caps.push_back(CapabilityKernel);
-    StorageParams[StorageClassAtomicCounter].caps.push_back(CapabilityAtomicStorage);
-    StorageParams[StorageClassPushConstant].caps.push_back(CapabilityShader);
-
-    // Sampler Filter & Addressing mode capabilities
-    SamplerAddressingModeParams[SamplerAddressingModeNone].caps.push_back(CapabilityKernel);
-    SamplerAddressingModeParams[SamplerAddressingModeClampToEdge].caps.push_back(CapabilityKernel);
-    SamplerAddressingModeParams[SamplerAddressingModeClamp].caps.push_back(CapabilityKernel);
-    SamplerAddressingModeParams[SamplerAddressingModeRepeat].caps.push_back(CapabilityKernel);
-    SamplerAddressingModeParams[SamplerAddressingModeRepeatMirrored].caps.push_back(CapabilityKernel);
-
-    SamplerFilterModeParams[SamplerFilterModeNearest].caps.push_back(CapabilityKernel);
-    SamplerFilterModeParams[SamplerFilterModeLinear].caps.push_back(CapabilityKernel);
-
-    // image format capabilities
-
-    // ES/Desktop float
-    ImageFormatParams[ImageFormatRgba32f].caps.push_back(CapabilityShader);
-    ImageFormatParams[ImageFormatRgba16f].caps.push_back(CapabilityShader);
-    ImageFormatParams[ImageFormatR32f].caps.push_back(CapabilityShader);
-    ImageFormatParams[ImageFormatRgba8].caps.push_back(CapabilityShader);
-    ImageFormatParams[ImageFormatRgba8Snorm].caps.push_back(CapabilityShader);
-
-    // Desktop float
-    ImageFormatParams[ImageFormatRg32f].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRg16f].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatR11fG11fB10f].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatR16f].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRgba16].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRgb10A2].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRg16].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRg8].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatR16].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatR8].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRgba16Snorm].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRg16Snorm].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRg8Snorm].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatR16Snorm].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatR8Snorm].caps.push_back(CapabilityStorageImageExtendedFormats);
-
-    // ES/Desktop int
-    ImageFormatParams[ImageFormatRgba32i].caps.push_back(CapabilityShader);
-    ImageFormatParams[ImageFormatRgba16i].caps.push_back(CapabilityShader);
-    ImageFormatParams[ImageFormatRgba8i].caps.push_back(CapabilityShader);
-    ImageFormatParams[ImageFormatR32i].caps.push_back(CapabilityShader);
-
-    // Desktop int
-    ImageFormatParams[ImageFormatRg32i].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRg16i].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRg8i].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatR16i].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatR8i].caps.push_back(CapabilityStorageImageExtendedFormats);
-
-    // ES/Desktop uint
-    ImageFormatParams[ImageFormatRgba32ui].caps.push_back(CapabilityShader);
-    ImageFormatParams[ImageFormatRgba16ui].caps.push_back(CapabilityShader);
-    ImageFormatParams[ImageFormatRgba8ui].caps.push_back(CapabilityShader);
-    ImageFormatParams[ImageFormatR32ui].caps.push_back(CapabilityShader);
-
-    // Desktop uint
-    ImageFormatParams[ImageFormatRgb10a2ui].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRg32ui].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRg16ui].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatRg8ui].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatR16ui].caps.push_back(CapabilityStorageImageExtendedFormats);
-    ImageFormatParams[ImageFormatR8ui].caps.push_back(CapabilityStorageImageExtendedFormats);
-
-    // image channel order capabilities
-    for (int i = 0; i < ImageChannelOrderCeiling; ++i) {
-        ImageChannelOrderParams[i].caps.push_back(CapabilityKernel);
-    }
-
-    // image channel type capabilities
-    for (int i = 0; i < ImageChannelDataTypeCeiling; ++i) {
-        ImageChannelDataTypeParams[i].caps.push_back(CapabilityKernel);
-    }
-
-    // image lookup operands
-    ImageOperandsParams[ImageOperandsBiasShift].caps.push_back(CapabilityShader);
-    ImageOperandsParams[ImageOperandsOffsetShift].caps.push_back(CapabilityImageGatherExtended);
-    ImageOperandsParams[ImageOperandsMinLodShift].caps.push_back(CapabilityMinLod);
-
-    // fast math flags capabilities
-    for (int i = 0; i < FPFastMathCeiling; ++i) {
-        FPFastMathParams[i].caps.push_back(CapabilityKernel);
-    }
-
-    // fp rounding mode capabilities
-    for (int i = 0; i < FPRoundingModeCeiling; ++i) {
-        FPRoundingModeParams[i].caps.push_back(CapabilityKernel);
-    }
-
-    // linkage types
-    for (int i = 0; i < LinkageTypeCeiling; ++i) {
-        LinkageTypeParams[i].caps.push_back(CapabilityLinkage);
-    }
-
-    // function argument types
-    for (int i = 0; i < FuncParamAttrCeiling; ++i) {
-        FuncParamAttrParams[i].caps.push_back(CapabilityKernel);
-    }
-
-    // function argument types
-    for (int i = 0; i < AccessQualifierCeiling; ++i) {
-        AccessQualifierParams[i].caps.push_back(CapabilityKernel);
-    }
-
-    ExecutionModeParams[ExecutionModeInvocations].caps.push_back(CapabilityGeometry);
-    ExecutionModeParams[ExecutionModeSpacingEqual].caps.push_back(CapabilityTessellation);
-    ExecutionModeParams[ExecutionModeSpacingFractionalEven].caps.push_back(CapabilityTessellation);
-    ExecutionModeParams[ExecutionModeSpacingFractionalOdd].caps.push_back(CapabilityTessellation);
-    ExecutionModeParams[ExecutionModeVertexOrderCw].caps.push_back(CapabilityTessellation);
-    ExecutionModeParams[ExecutionModeVertexOrderCcw].caps.push_back(CapabilityTessellation);
-    ExecutionModeParams[ExecutionModePixelCenterInteger].caps.push_back(CapabilityShader);
-    ExecutionModeParams[ExecutionModeOriginUpperLeft].caps.push_back(CapabilityShader);
-    ExecutionModeParams[ExecutionModeOriginLowerLeft].caps.push_back(CapabilityShader);
-    ExecutionModeParams[ExecutionModeEarlyFragmentTests].caps.push_back(CapabilityShader);
-    ExecutionModeParams[ExecutionModePointMode].caps.push_back(CapabilityTessellation);
-    ExecutionModeParams[ExecutionModeXfb].caps.push_back(CapabilityTransformFeedback);
-    ExecutionModeParams[ExecutionModeDepthReplacing].caps.push_back(CapabilityShader);
-    ExecutionModeParams[ExecutionModeDepthGreater].caps.push_back(CapabilityShader);
-    ExecutionModeParams[ExecutionModeDepthLess].caps.push_back(CapabilityShader);
-    ExecutionModeParams[ExecutionModeDepthUnchanged].caps.push_back(CapabilityShader);
-    ExecutionModeParams[ExecutionModeLocalSizeHint].caps.push_back(CapabilityKernel);
-    ExecutionModeParams[ExecutionModeInputPoints].caps.push_back(CapabilityGeometry);
-    ExecutionModeParams[ExecutionModeInputLines].caps.push_back(CapabilityGeometry);
-    ExecutionModeParams[ExecutionModeInputLinesAdjacency].caps.push_back(CapabilityGeometry);
-    ExecutionModeParams[ExecutionModeTriangles].caps.push_back(CapabilityGeometry);
-    ExecutionModeParams[ExecutionModeTriangles].caps.push_back(CapabilityTessellation);
-    ExecutionModeParams[ExecutionModeInputTrianglesAdjacency].caps.push_back(CapabilityGeometry);
-    ExecutionModeParams[ExecutionModeQuads].caps.push_back(CapabilityTessellation);
-    ExecutionModeParams[ExecutionModeIsolines].caps.push_back(CapabilityTessellation);
-    ExecutionModeParams[ExecutionModeOutputVertices].caps.push_back(CapabilityGeometry);
-    ExecutionModeParams[ExecutionModeOutputVertices].caps.push_back(CapabilityTessellation);
-    ExecutionModeParams[ExecutionModeOutputPoints].caps.push_back(CapabilityGeometry);
-    ExecutionModeParams[ExecutionModeOutputLineStrip].caps.push_back(CapabilityGeometry);
-    ExecutionModeParams[ExecutionModeOutputTriangleStrip].caps.push_back(CapabilityGeometry);
-    ExecutionModeParams[ExecutionModeVecTypeHint].caps.push_back(CapabilityKernel);
-    ExecutionModeParams[ExecutionModeContractionOff].caps.push_back(CapabilityKernel);
-
-    DecorationParams[DecorationRelaxedPrecision].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationBlock].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationBufferBlock].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationRowMajor].caps.push_back(CapabilityMatrix);
-    DecorationParams[DecorationColMajor].caps.push_back(CapabilityMatrix);
-    DecorationParams[DecorationGLSLShared].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationGLSLPacked].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationNoPerspective].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationFlat].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationPatch].caps.push_back(CapabilityTessellation);
-    DecorationParams[DecorationCentroid].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationSample].caps.push_back(CapabilitySampleRateShading);
-    DecorationParams[DecorationInvariant].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationConstant].caps.push_back(CapabilityKernel);
-    DecorationParams[DecorationUniform].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationCPacked].caps.push_back(CapabilityKernel);
-    DecorationParams[DecorationSaturatedConversion].caps.push_back(CapabilityKernel);
-    DecorationParams[DecorationStream].caps.push_back(CapabilityGeometryStreams);
-    DecorationParams[DecorationLocation].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationComponent].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationOffset].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationIndex].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationBinding].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationDescriptorSet].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationXfbBuffer].caps.push_back(CapabilityTransformFeedback);
-    DecorationParams[DecorationXfbStride].caps.push_back(CapabilityTransformFeedback);
-    DecorationParams[DecorationArrayStride].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationMatrixStride].caps.push_back(CapabilityMatrix);
-    DecorationParams[DecorationFuncParamAttr].caps.push_back(CapabilityKernel);
-    DecorationParams[DecorationFPRoundingMode].caps.push_back(CapabilityKernel);
-    DecorationParams[DecorationFPFastMathMode].caps.push_back(CapabilityKernel);
-    DecorationParams[DecorationLinkageAttributes].caps.push_back(CapabilityLinkage);
-    DecorationParams[DecorationSpecId].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationNoContraction].caps.push_back(CapabilityShader);
-    DecorationParams[DecorationInputAttachmentIndex].caps.push_back(CapabilityInputAttachment);
-    DecorationParams[DecorationAlignment].caps.push_back(CapabilityKernel);
-
-    BuiltInParams[BuiltInPosition].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInPointSize].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInClipDistance].caps.push_back(CapabilityClipDistance);
-    BuiltInParams[BuiltInCullDistance].caps.push_back(CapabilityCullDistance);
-
-    BuiltInParams[BuiltInVertexId].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInVertexId].desc = "Vertex ID, which takes on values 0, 1, 2, . . . .";
-
-    BuiltInParams[BuiltInInstanceId].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInInstanceId].desc = "Instance ID, which takes on values 0, 1, 2, . . . .";
-
-    BuiltInParams[BuiltInVertexIndex].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInVertexIndex].desc = "Vertex index, which takes on values base, base+1, base+2, . . . .";
-
-    BuiltInParams[BuiltInInstanceIndex].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInInstanceIndex].desc = "Instance index, which takes on values base, base+1, base+2, . . . .";
-
-    BuiltInParams[BuiltInPrimitiveId].caps.push_back(CapabilityGeometry);
-    BuiltInParams[BuiltInPrimitiveId].caps.push_back(CapabilityTessellation);
-    BuiltInParams[BuiltInInvocationId].caps.push_back(CapabilityGeometry);
-    BuiltInParams[BuiltInInvocationId].caps.push_back(CapabilityTessellation);
-    BuiltInParams[BuiltInLayer].caps.push_back(CapabilityGeometry);
-    BuiltInParams[BuiltInViewportIndex].caps.push_back(CapabilityMultiViewport);
-    BuiltInParams[BuiltInTessLevelOuter].caps.push_back(CapabilityTessellation);
-    BuiltInParams[BuiltInTessLevelInner].caps.push_back(CapabilityTessellation);
-    BuiltInParams[BuiltInTessCoord].caps.push_back(CapabilityTessellation);
-    BuiltInParams[BuiltInPatchVertices].caps.push_back(CapabilityTessellation);
-    BuiltInParams[BuiltInFragCoord].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInPointCoord].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInFrontFacing].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInSampleId].caps.push_back(CapabilitySampleRateShading);
-    BuiltInParams[BuiltInSamplePosition].caps.push_back(CapabilitySampleRateShading);
-    BuiltInParams[BuiltInSampleMask].caps.push_back(CapabilitySampleRateShading);
-    BuiltInParams[BuiltInFragDepth].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInHelperInvocation].caps.push_back(CapabilityShader);
-    BuiltInParams[BuiltInWorkDim].caps.push_back(CapabilityKernel);
-    BuiltInParams[BuiltInGlobalSize].caps.push_back(CapabilityKernel);
-    BuiltInParams[BuiltInEnqueuedWorkgroupSize].caps.push_back(CapabilityKernel);
-    BuiltInParams[BuiltInGlobalOffset].caps.push_back(CapabilityKernel);
-    BuiltInParams[BuiltInGlobalLinearId].caps.push_back(CapabilityKernel);
-
-    BuiltInParams[BuiltInSubgroupSize].caps.push_back(CapabilityKernel);
-    BuiltInParams[BuiltInSubgroupMaxSize].caps.push_back(CapabilityKernel);
-    BuiltInParams[BuiltInNumSubgroups].caps.push_back(CapabilityKernel);
-    BuiltInParams[BuiltInNumEnqueuedSubgroups].caps.push_back(CapabilityKernel);
-    BuiltInParams[BuiltInSubgroupId].caps.push_back(CapabilityKernel);
-    BuiltInParams[BuiltInSubgroupLocalInvocationId].caps.push_back(CapabilityKernel);
-
-    DimensionalityParams[Dim1D].caps.push_back(CapabilitySampled1D);
-    DimensionalityParams[DimCube].caps.push_back(CapabilityShader);
-    DimensionalityParams[DimRect].caps.push_back(CapabilitySampledRect);
-    DimensionalityParams[DimBuffer].caps.push_back(CapabilitySampledBuffer);
-    DimensionalityParams[DimSubpassData].caps.push_back(CapabilityInputAttachment);
-
-    // Group Operations
-    for (int i = 0; i < GroupOperationCeiling; ++i) {
-        GroupOperationParams[i].caps.push_back(CapabilityKernel);
-    }
-
-    // Enqueue flags
-    for (int i = 0; i < KernelEnqueueFlagsCeiling; ++i) {
-        KernelEnqueueFlagsParams[i].caps.push_back(CapabilityKernel);
-    }
-
-    // Profiling info
-    KernelProfilingInfoParams[0].caps.push_back(CapabilityKernel);
+    OperandClassParams[OperandMemorySemantics].set(0, MemorySemanticsString, nullptr, true);
+    OperandClassParams[OperandMemoryAccess].set(0, MemoryAccessString, nullptr, true);
+    OperandClassParams[OperandScope].set(0, ScopeString, nullptr);
+    OperandClassParams[OperandGroupOperation].set(0, GroupOperationString, nullptr);
+    OperandClassParams[OperandKernelEnqueueFlags].set(0, KernelEnqueueFlagsString, nullptr);
+    OperandClassParams[OperandKernelProfilingInfo].set(0, KernelProfilingInfoString, nullptr, true);
+    OperandClassParams[OperandCapability].set(0, CapabilityString, nullptr);
+    OperandClassParams[OperandOpcode].set(OpCodeMask + 1, OpcodeString, 0);
 
     // set name of operator, an initial set of <id> style operands, and the description
 
@@ -1779,7 +1454,6 @@
     InstructionDesc[OpTypeVector].operands.push(OperandId, "'Component Type'");
     InstructionDesc[OpTypeVector].operands.push(OperandLiteralNumber, "'Component Count'");
 
-    InstructionDesc[OpTypeMatrix].capabilities.push_back(CapabilityMatrix);
     InstructionDesc[OpTypeMatrix].operands.push(OperandId, "'Column Type'");
     InstructionDesc[OpTypeMatrix].operands.push(OperandLiteralNumber, "'Column Count'");
 
@@ -1797,31 +1471,19 @@
     InstructionDesc[OpTypeArray].operands.push(OperandId, "'Element Type'");
     InstructionDesc[OpTypeArray].operands.push(OperandId, "'Length'");
 
-    InstructionDesc[OpTypeRuntimeArray].capabilities.push_back(CapabilityShader);
     InstructionDesc[OpTypeRuntimeArray].operands.push(OperandId, "'Element Type'");
 
     InstructionDesc[OpTypeStruct].operands.push(OperandVariableIds, "'Member 0 type', +\n'member 1 type', +\n...");
 
-    InstructionDesc[OpTypeOpaque].capabilities.push_back(CapabilityKernel);
     InstructionDesc[OpTypeOpaque].operands.push(OperandLiteralString, "The name of the opaque type.");
 
     InstructionDesc[OpTypePointer].operands.push(OperandStorage, "");
     InstructionDesc[OpTypePointer].operands.push(OperandId, "'Type'");
 
-    InstructionDesc[OpTypeForwardPointer].capabilities.push_back(CapabilityAddresses);
     InstructionDesc[OpTypeForwardPointer].operands.push(OperandId, "'Pointer Type'");
     InstructionDesc[OpTypeForwardPointer].operands.push(OperandStorage, "");
 
-    InstructionDesc[OpTypeEvent].capabilities.push_back(CapabilityKernel);
-
-    InstructionDesc[OpTypeDeviceEvent].capabilities.push_back(CapabilityDeviceEnqueue);
-
-    InstructionDesc[OpTypeReserveId].capabilities.push_back(CapabilityPipes);
-
-    InstructionDesc[OpTypeQueue].capabilities.push_back(CapabilityDeviceEnqueue);
-
     InstructionDesc[OpTypePipe].operands.push(OperandAccessQualifier, "'Qualifier'");
-    InstructionDesc[OpTypePipe].capabilities.push_back(CapabilityPipes);
 
     InstructionDesc[OpTypeFunction].operands.push(OperandId, "'Return Type'");
     InstructionDesc[OpTypeFunction].operands.push(OperandVariableIds, "'Parameter 0 Type', +\n'Parameter 1 Type', +\n...");
@@ -1830,7 +1492,6 @@
 
     InstructionDesc[OpConstantComposite].operands.push(OperandVariableIds, "'Constituents'");
 
-    InstructionDesc[OpConstantSampler].capabilities.push_back(CapabilityLiteralSampler);
     InstructionDesc[OpConstantSampler].operands.push(OperandSamplerAddressingMode, "");
     InstructionDesc[OpConstantSampler].operands.push(OperandLiteralNumber, "'Param'");
     InstructionDesc[OpConstantSampler].operands.push(OperandSamplerFilterMode, "");
@@ -1868,11 +1529,24 @@
     InstructionDesc[OpDecorate].operands.push(OperandDecoration, "");
     InstructionDesc[OpDecorate].operands.push(OperandVariableLiterals, "See <<Decoration,'Decoration'>>.");
 
+    InstructionDesc[OpDecorateId].operands.push(OperandId, "'Target'");
+    InstructionDesc[OpDecorateId].operands.push(OperandDecoration, "");
+    InstructionDesc[OpDecorateId].operands.push(OperandVariableIds, "See <<Decoration,'Decoration'>>.");
+
+    InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'");
+    InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandDecoration, "");
+    InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'");
+
     InstructionDesc[OpMemberDecorate].operands.push(OperandId, "'Structure Type'");
     InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'");
     InstructionDesc[OpMemberDecorate].operands.push(OperandDecoration, "");
     InstructionDesc[OpMemberDecorate].operands.push(OperandVariableLiterals, "See <<Decoration,'Decoration'>>.");
 
+    InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'");
+    InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'");
+    InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandDecoration, "");
+    InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'");
+
     InstructionDesc[OpGroupDecorate].operands.push(OperandId, "'Decoration Group'");
     InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'");
 
@@ -1910,8 +1584,6 @@
     InstructionDesc[OpCopyMemorySized].operands.push(OperandId, "'Size'");
     InstructionDesc[OpCopyMemorySized].operands.push(OperandMemoryAccess, "", true);
 
-    InstructionDesc[OpCopyMemorySized].capabilities.push_back(CapabilityAddresses);
-
     InstructionDesc[OpSampledImage].operands.push(OperandId, "'Image'");
     InstructionDesc[OpSampledImage].operands.push(OperandId, "'Sampler'");
 
@@ -1932,7 +1604,6 @@
     InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSampleImplicitLod].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandId, "'Coordinate'");
@@ -1944,40 +1615,34 @@
     InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandId, "'D~ref~'");
     InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSampleDrefImplicitLod].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'D~ref~'");
     InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSampleDrefExplicitLod].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSampleProjImplicitLod].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSampleProjExplicitLod].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'D~ref~'");
     InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSampleProjDrefImplicitLod].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'D~ref~'");
     InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSampleProjDrefExplicitLod].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpImageFetch].operands.push(OperandId, "'Image'");
     InstructionDesc[OpImageFetch].operands.push(OperandId, "'Coordinate'");
@@ -1989,122 +1654,96 @@
     InstructionDesc[OpImageGather].operands.push(OperandId, "'Component'");
     InstructionDesc[OpImageGather].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageGather].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageGather].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'D~ref~'");
     InstructionDesc[OpImageDrefGather].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageDrefGather].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageDrefGather].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseSampleImplicitLod].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseSampleExplicitLod].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'D~ref~'");
     InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseSampleDrefImplicitLod].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'D~ref~'");
     InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseSampleDrefExplicitLod].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseSampleProjImplicitLod].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseSampleProjExplicitLod].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'D~ref~'");
     InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'D~ref~'");
     InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseFetch].operands.push(OperandId, "'Image'");
     InstructionDesc[OpImageSparseFetch].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseFetch].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseFetch].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseFetch].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Component'");
     InstructionDesc[OpImageSparseGather].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseGather].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseGather].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'D~ref~'");
     InstructionDesc[OpImageSparseDrefGather].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseDrefGather].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseDrefGather].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseRead].operands.push(OperandId, "'Image'");
     InstructionDesc[OpImageSparseRead].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpImageSparseRead].operands.push(OperandImageOperands, "", true);
     InstructionDesc[OpImageSparseRead].operands.push(OperandVariableIds, "", true);
-    InstructionDesc[OpImageSparseRead].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageSparseTexelsResident].operands.push(OperandId, "'Resident Code'");
-    InstructionDesc[OpImageSparseTexelsResident].capabilities.push_back(CapabilitySparseResidency);
 
     InstructionDesc[OpImageQuerySizeLod].operands.push(OperandId, "'Image'");
     InstructionDesc[OpImageQuerySizeLod].operands.push(OperandId, "'Level of Detail'");
-    InstructionDesc[OpImageQuerySizeLod].capabilities.push_back(CapabilityKernel);
-    InstructionDesc[OpImageQuerySizeLod].capabilities.push_back(CapabilityImageQuery);
 
     InstructionDesc[OpImageQuerySize].operands.push(OperandId, "'Image'");
-    InstructionDesc[OpImageQuerySize].capabilities.push_back(CapabilityKernel);
-    InstructionDesc[OpImageQuerySize].capabilities.push_back(CapabilityImageQuery);
 
     InstructionDesc[OpImageQueryLod].operands.push(OperandId, "'Image'");
     InstructionDesc[OpImageQueryLod].operands.push(OperandId, "'Coordinate'");
-    InstructionDesc[OpImageQueryLod].capabilities.push_back(CapabilityImageQuery);
 
     InstructionDesc[OpImageQueryLevels].operands.push(OperandId, "'Image'");
-    InstructionDesc[OpImageQueryLevels].capabilities.push_back(CapabilityKernel);
-    InstructionDesc[OpImageQueryLevels].capabilities.push_back(CapabilityImageQuery);
 
     InstructionDesc[OpImageQuerySamples].operands.push(OperandId, "'Image'");
-    InstructionDesc[OpImageQuerySamples].capabilities.push_back(CapabilityKernel);
-    InstructionDesc[OpImageQuerySamples].capabilities.push_back(CapabilityImageQuery);
 
     InstructionDesc[OpImageQueryFormat].operands.push(OperandId, "'Image'");
-    InstructionDesc[OpImageQueryFormat].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpImageQueryOrder].operands.push(OperandId, "'Image'");
-    InstructionDesc[OpImageQueryOrder].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpAccessChain].operands.push(OperandId, "'Base'");
     InstructionDesc[OpAccessChain].operands.push(OperandVariableIds, "'Indexes'");
@@ -2115,12 +1754,10 @@
     InstructionDesc[OpPtrAccessChain].operands.push(OperandId, "'Base'");
     InstructionDesc[OpPtrAccessChain].operands.push(OperandId, "'Element'");
     InstructionDesc[OpPtrAccessChain].operands.push(OperandVariableIds, "'Indexes'");
-    InstructionDesc[OpPtrAccessChain].capabilities.push_back(CapabilityAddresses);
 
     InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandId, "'Base'");
     InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandId, "'Element'");
     InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandVariableIds, "'Indexes'");
-    InstructionDesc[OpInBoundsPtrAccessChain].capabilities.push_back(CapabilityAddresses);
 
     InstructionDesc[OpSNegate].operands.push(OperandId, "'Operand'");
 
@@ -2147,65 +1784,49 @@
     InstructionDesc[OpFConvert].operands.push(OperandId, "'Float Value'");
 
     InstructionDesc[OpSatConvertSToU].operands.push(OperandId, "'Signed Value'");
-    InstructionDesc[OpSatConvertSToU].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpSatConvertUToS].operands.push(OperandId, "'Unsigned Value'");
-    InstructionDesc[OpSatConvertUToS].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpConvertPtrToU].operands.push(OperandId, "'Pointer'");
-    InstructionDesc[OpConvertPtrToU].capabilities.push_back(CapabilityAddresses);
 
     InstructionDesc[OpConvertUToPtr].operands.push(OperandId, "'Integer Value'");
-    InstructionDesc[OpConvertUToPtr].capabilities.push_back(CapabilityAddresses);
 
     InstructionDesc[OpPtrCastToGeneric].operands.push(OperandId, "'Pointer'");
-    InstructionDesc[OpPtrCastToGeneric].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpGenericCastToPtr].operands.push(OperandId, "'Pointer'");
-    InstructionDesc[OpGenericCastToPtr].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpGenericCastToPtrExplicit].operands.push(OperandId, "'Pointer'");
     InstructionDesc[OpGenericCastToPtrExplicit].operands.push(OperandStorage, "'Storage'");
-    InstructionDesc[OpGenericCastToPtrExplicit].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpGenericPtrMemSemantics].operands.push(OperandId, "'Pointer'");
-    InstructionDesc[OpGenericPtrMemSemantics].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpBitcast].operands.push(OperandId, "'Operand'");
 
     InstructionDesc[OpQuantizeToF16].operands.push(OperandId, "'Value'");
 
-    InstructionDesc[OpTranspose].capabilities.push_back(CapabilityMatrix);
     InstructionDesc[OpTranspose].operands.push(OperandId, "'Matrix'");
 
     InstructionDesc[OpIsNan].operands.push(OperandId, "'x'");
 
     InstructionDesc[OpIsInf].operands.push(OperandId, "'x'");
 
-    InstructionDesc[OpIsFinite].capabilities.push_back(CapabilityKernel);
     InstructionDesc[OpIsFinite].operands.push(OperandId, "'x'");
 
-    InstructionDesc[OpIsNormal].capabilities.push_back(CapabilityKernel);
     InstructionDesc[OpIsNormal].operands.push(OperandId, "'x'");
 
-    InstructionDesc[OpSignBitSet].capabilities.push_back(CapabilityKernel);
     InstructionDesc[OpSignBitSet].operands.push(OperandId, "'x'");
 
-    InstructionDesc[OpLessOrGreater].capabilities.push_back(CapabilityKernel);
     InstructionDesc[OpLessOrGreater].operands.push(OperandId, "'x'");
     InstructionDesc[OpLessOrGreater].operands.push(OperandId, "'y'");
 
-    InstructionDesc[OpOrdered].capabilities.push_back(CapabilityKernel);
     InstructionDesc[OpOrdered].operands.push(OperandId, "'x'");
     InstructionDesc[OpOrdered].operands.push(OperandId, "'y'");
 
-    InstructionDesc[OpUnordered].capabilities.push_back(CapabilityKernel);
     InstructionDesc[OpUnordered].operands.push(OperandId, "'x'");
     InstructionDesc[OpUnordered].operands.push(OperandId, "'y'");
 
     InstructionDesc[OpArrayLength].operands.push(OperandId, "'Structure'");
     InstructionDesc[OpArrayLength].operands.push(OperandLiteralNumber, "'Array member'");
-    InstructionDesc[OpArrayLength].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpIAdd].operands.push(OperandId, "'Operand 1'");
     InstructionDesc[OpIAdd].operands.push(OperandId, "'Operand 2'");
@@ -2252,23 +1873,18 @@
     InstructionDesc[OpVectorTimesScalar].operands.push(OperandId, "'Vector'");
     InstructionDesc[OpVectorTimesScalar].operands.push(OperandId, "'Scalar'");
 
-    InstructionDesc[OpMatrixTimesScalar].capabilities.push_back(CapabilityMatrix);
     InstructionDesc[OpMatrixTimesScalar].operands.push(OperandId, "'Matrix'");
     InstructionDesc[OpMatrixTimesScalar].operands.push(OperandId, "'Scalar'");
 
-    InstructionDesc[OpVectorTimesMatrix].capabilities.push_back(CapabilityMatrix);
     InstructionDesc[OpVectorTimesMatrix].operands.push(OperandId, "'Vector'");
     InstructionDesc[OpVectorTimesMatrix].operands.push(OperandId, "'Matrix'");
 
-    InstructionDesc[OpMatrixTimesVector].capabilities.push_back(CapabilityMatrix);
     InstructionDesc[OpMatrixTimesVector].operands.push(OperandId, "'Matrix'");
     InstructionDesc[OpMatrixTimesVector].operands.push(OperandId, "'Vector'");
 
-    InstructionDesc[OpMatrixTimesMatrix].capabilities.push_back(CapabilityMatrix);
     InstructionDesc[OpMatrixTimesMatrix].operands.push(OperandId, "'LeftMatrix'");
     InstructionDesc[OpMatrixTimesMatrix].operands.push(OperandId, "'RightMatrix'");
 
-    InstructionDesc[OpOuterProduct].capabilities.push_back(CapabilityMatrix);
     InstructionDesc[OpOuterProduct].operands.push(OperandId, "'Vector 1'");
     InstructionDesc[OpOuterProduct].operands.push(OperandId, "'Vector 2'");
 
@@ -2319,23 +1935,19 @@
     InstructionDesc[OpBitwiseAnd].operands.push(OperandId, "'Operand 1'");
     InstructionDesc[OpBitwiseAnd].operands.push(OperandId, "'Operand 2'");
 
-    InstructionDesc[OpBitFieldInsert].capabilities.push_back(CapabilityShader);
     InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Base'");
     InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Insert'");
     InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Offset'");
     InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Count'");
-    
-    InstructionDesc[OpBitFieldSExtract].capabilities.push_back(CapabilityShader);
+
     InstructionDesc[OpBitFieldSExtract].operands.push(OperandId, "'Base'");
     InstructionDesc[OpBitFieldSExtract].operands.push(OperandId, "'Offset'");
     InstructionDesc[OpBitFieldSExtract].operands.push(OperandId, "'Count'");
     
-    InstructionDesc[OpBitFieldUExtract].capabilities.push_back(CapabilityShader);
     InstructionDesc[OpBitFieldUExtract].operands.push(OperandId, "'Base'");
     InstructionDesc[OpBitFieldUExtract].operands.push(OperandId, "'Offset'");
     InstructionDesc[OpBitFieldUExtract].operands.push(OperandId, "'Count'");
     
-    InstructionDesc[OpBitReverse].capabilities.push_back(CapabilityShader);
     InstructionDesc[OpBitReverse].operands.push(OperandId, "'Base'");
 
     InstructionDesc[OpBitCount].operands.push(OperandId, "'Base'");
@@ -2410,42 +2022,27 @@
     InstructionDesc[OpFUnordGreaterThanEqual].operands.push(OperandId, "'Operand 1'");
     InstructionDesc[OpFUnordGreaterThanEqual].operands.push(OperandId, "'Operand 2'");
 
-    InstructionDesc[OpDPdx].capabilities.push_back(CapabilityShader);
     InstructionDesc[OpDPdx].operands.push(OperandId, "'P'");
 
-    InstructionDesc[OpDPdy].capabilities.push_back(CapabilityShader);
     InstructionDesc[OpDPdy].operands.push(OperandId, "'P'");
 
-    InstructionDesc[OpFwidth].capabilities.push_back(CapabilityShader);
     InstructionDesc[OpFwidth].operands.push(OperandId, "'P'");
 
-    InstructionDesc[OpDPdxFine].capabilities.push_back(CapabilityDerivativeControl);
     InstructionDesc[OpDPdxFine].operands.push(OperandId, "'P'");
 
-    InstructionDesc[OpDPdyFine].capabilities.push_back(CapabilityDerivativeControl);
     InstructionDesc[OpDPdyFine].operands.push(OperandId, "'P'");
 
-    InstructionDesc[OpFwidthFine].capabilities.push_back(CapabilityDerivativeControl);
     InstructionDesc[OpFwidthFine].operands.push(OperandId, "'P'");
 
-    InstructionDesc[OpDPdxCoarse].capabilities.push_back(CapabilityDerivativeControl);
     InstructionDesc[OpDPdxCoarse].operands.push(OperandId, "'P'");
 
-    InstructionDesc[OpDPdyCoarse].capabilities.push_back(CapabilityDerivativeControl);
     InstructionDesc[OpDPdyCoarse].operands.push(OperandId, "'P'");
 
-    InstructionDesc[OpFwidthCoarse].capabilities.push_back(CapabilityDerivativeControl);
     InstructionDesc[OpFwidthCoarse].operands.push(OperandId, "'P'");
 
-    InstructionDesc[OpEmitVertex].capabilities.push_back(CapabilityGeometry);
-
-    InstructionDesc[OpEndPrimitive].capabilities.push_back(CapabilityGeometry);
-
     InstructionDesc[OpEmitStreamVertex].operands.push(OperandId, "'Stream'");
-    InstructionDesc[OpEmitStreamVertex].capabilities.push_back(CapabilityGeometryStreams);
 
     InstructionDesc[OpEndStreamPrimitive].operands.push(OperandId, "'Stream'");
-    InstructionDesc[OpEndStreamPrimitive].capabilities.push_back(CapabilityGeometryStreams);
 
     InstructionDesc[OpControlBarrier].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpControlBarrier].operands.push(OperandScope, "'Memory'");
@@ -2485,7 +2082,6 @@
     InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandMemorySemantics, "'Unequal'");
     InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId, "'Value'");
     InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId, "'Comparator'");
-    InstructionDesc[OpAtomicCompareExchangeWeak].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpAtomicIIncrement].operands.push(OperandId, "'Pointer'");
     InstructionDesc[OpAtomicIIncrement].operands.push(OperandScope, "'Scope'");
@@ -2543,16 +2139,15 @@
     InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandId, "'Pointer'");
     InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandScope, "'Scope'");
     InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandMemorySemantics, "'Semantics'");
-    InstructionDesc[OpAtomicFlagTestAndSet].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpAtomicFlagClear].operands.push(OperandId, "'Pointer'");
     InstructionDesc[OpAtomicFlagClear].operands.push(OperandScope, "'Scope'");
     InstructionDesc[OpAtomicFlagClear].operands.push(OperandMemorySemantics, "'Semantics'");
-    InstructionDesc[OpAtomicFlagClear].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Merge Block'");
     InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Continue Target'");
     InstructionDesc[OpLoopMerge].operands.push(OperandLoop, "");
+    InstructionDesc[OpLoopMerge].operands.push(OperandOptionalLiteral, "");
 
     InstructionDesc[OpSelectionMerge].operands.push(OperandId, "'Merge Block'");
     InstructionDesc[OpSelectionMerge].operands.push(OperandSelect, "");
@@ -2568,19 +2163,15 @@
     InstructionDesc[OpSwitch].operands.push(OperandId, "'Default'");
     InstructionDesc[OpSwitch].operands.push(OperandVariableLiteralId, "'Target'");
 
-    InstructionDesc[OpKill].capabilities.push_back(CapabilityShader);
 
     InstructionDesc[OpReturnValue].operands.push(OperandId, "'Value'");
 
     InstructionDesc[OpLifetimeStart].operands.push(OperandId, "'Pointer'");
     InstructionDesc[OpLifetimeStart].operands.push(OperandLiteralNumber, "'Size'");
-    InstructionDesc[OpLifetimeStart].capabilities.push_back(CapabilityKernel);
 
     InstructionDesc[OpLifetimeStop].operands.push(OperandId, "'Pointer'");
     InstructionDesc[OpLifetimeStop].operands.push(OperandLiteralNumber, "'Size'");
-    InstructionDesc[OpLifetimeStop].capabilities.push_back(CapabilityKernel);
 
-    InstructionDesc[OpGroupAsyncCopy].capabilities.push_back(CapabilityKernel);
     InstructionDesc[OpGroupAsyncCopy].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Destination'");
     InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Source'");
@@ -2588,77 +2179,62 @@
     InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Stride'");
     InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Event'");
 
-    InstructionDesc[OpGroupWaitEvents].capabilities.push_back(CapabilityKernel);
     InstructionDesc[OpGroupWaitEvents].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupWaitEvents].operands.push(OperandId, "'Num Events'");
     InstructionDesc[OpGroupWaitEvents].operands.push(OperandId, "'Events List'");
 
-    InstructionDesc[OpGroupAll].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupAll].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupAll].operands.push(OperandId, "'Predicate'");
 
-    InstructionDesc[OpGroupAny].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupAny].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupAny].operands.push(OperandId, "'Predicate'");
 
-    InstructionDesc[OpGroupBroadcast].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupBroadcast].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupBroadcast].operands.push(OperandId, "'Value'");
     InstructionDesc[OpGroupBroadcast].operands.push(OperandId, "'LocalId'");
 
-    InstructionDesc[OpGroupIAdd].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupIAdd].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupIAdd].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupIAdd].operands.push(OperandId, "'X'");
 
-    InstructionDesc[OpGroupFAdd].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupFAdd].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupFAdd].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupFAdd].operands.push(OperandId, "'X'");
 
-    InstructionDesc[OpGroupUMin].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupUMin].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupUMin].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupUMin].operands.push(OperandId, "'X'");
 
-    InstructionDesc[OpGroupSMin].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupSMin].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupSMin].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupSMin].operands.push(OperandId, "X");
 
-    InstructionDesc[OpGroupFMin].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupFMin].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupFMin].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupFMin].operands.push(OperandId, "X");
 
-    InstructionDesc[OpGroupUMax].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupUMax].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupUMax].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupUMax].operands.push(OperandId, "X");
 
-    InstructionDesc[OpGroupSMax].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupSMax].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupSMax].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupSMax].operands.push(OperandId, "X");
 
-    InstructionDesc[OpGroupFMax].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupFMax].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupFMax].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupFMax].operands.push(OperandId, "X");
 
-    InstructionDesc[OpReadPipe].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpReadPipe].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpReadPipe].operands.push(OperandId, "'Pointer'");
     InstructionDesc[OpReadPipe].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpReadPipe].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpWritePipe].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpWritePipe].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpWritePipe].operands.push(OperandId, "'Pointer'");
     InstructionDesc[OpWritePipe].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpWritePipe].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpReservedReadPipe].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Reserve Id'");
     InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Index'");
@@ -2666,7 +2242,6 @@
     InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpReservedWritePipe].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Reserve Id'");
     InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Index'");
@@ -2674,127 +2249,99 @@
     InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpReserveReadPipePackets].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Num Packets'");
     InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpReserveWritePipePackets].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Num Packets'");
     InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpCommitReadPipe].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Reserve Id'");
     InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpCommitWritePipe].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Reserve Id'");
     InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpIsValidReserveId].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpIsValidReserveId].operands.push(OperandId, "'Reserve Id'");
 
-    InstructionDesc[OpGetNumPipePackets].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpGetMaxPipePackets].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpGroupReserveReadPipePackets].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Num Packets'");
     InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpGroupReserveWritePipePackets].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Num Packets'");
     InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpGroupCommitReadPipe].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Reserve Id'");
     InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpGroupCommitWritePipe].capabilities.push_back(CapabilityPipes);
     InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Pipe'");
     InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Reserve Id'");
     InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Packet Size'");
     InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Packet Alignment'");
 
-    InstructionDesc[OpBuildNDRange].capabilities.push_back(CapabilityDeviceEnqueue);
     InstructionDesc[OpBuildNDRange].operands.push(OperandId, "'GlobalWorkSize'");
     InstructionDesc[OpBuildNDRange].operands.push(OperandId, "'LocalWorkSize'");
     InstructionDesc[OpBuildNDRange].operands.push(OperandId, "'GlobalWorkOffset'");
 
-    InstructionDesc[OpGetDefaultQueue].capabilities.push_back(CapabilityDeviceEnqueue);
-
-    InstructionDesc[OpCaptureEventProfilingInfo].capabilities.push_back(CapabilityDeviceEnqueue);
-
     InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId, "'Event'");
     InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId, "'Profiling Info'");
     InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId, "'Value'");
 
-    InstructionDesc[OpSetUserEventStatus].capabilities.push_back(CapabilityDeviceEnqueue);
-
     InstructionDesc[OpSetUserEventStatus].operands.push(OperandId, "'Event'");
     InstructionDesc[OpSetUserEventStatus].operands.push(OperandId, "'Status'");
 
-    InstructionDesc[OpIsValidEvent].capabilities.push_back(CapabilityDeviceEnqueue);
     InstructionDesc[OpIsValidEvent].operands.push(OperandId, "'Event'");
 
-    InstructionDesc[OpCreateUserEvent].capabilities.push_back(CapabilityDeviceEnqueue);
-
-    InstructionDesc[OpRetainEvent].capabilities.push_back(CapabilityDeviceEnqueue);
     InstructionDesc[OpRetainEvent].operands.push(OperandId, "'Event'");
 
-    InstructionDesc[OpReleaseEvent].capabilities.push_back(CapabilityDeviceEnqueue);
     InstructionDesc[OpReleaseEvent].operands.push(OperandId, "'Event'");
 
-    InstructionDesc[OpGetKernelWorkGroupSize].capabilities.push_back(CapabilityDeviceEnqueue);
     InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Invoke'");
     InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Param'");
     InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Param Size'");
     InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Param Align'");
 
-    InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].capabilities.push_back(CapabilityDeviceEnqueue);
     InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Invoke'");
     InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Param'");
     InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Param Size'");
     InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Param Align'");
 
-    InstructionDesc[OpGetKernelNDrangeSubGroupCount].capabilities.push_back(CapabilityDeviceEnqueue);
     InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'ND Range'");
     InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Invoke'");
     InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Param'");
     InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Param Size'");
     InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Param Align'");
 
-    InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].capabilities.push_back(CapabilityDeviceEnqueue);
     InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'ND Range'");
     InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Invoke'");
     InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Param'");
     InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Param Size'");
     InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Param Align'");
 
-    InstructionDesc[OpEnqueueKernel].capabilities.push_back(CapabilityDeviceEnqueue);
     InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Queue'");
     InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Flags'");
     InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'ND Range'");
@@ -2807,82 +2354,215 @@
     InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Param Align'");
     InstructionDesc[OpEnqueueKernel].operands.push(OperandVariableIds, "'Local Size'");
 
-    InstructionDesc[OpEnqueueMarker].capabilities.push_back(CapabilityDeviceEnqueue);
     InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Queue'");
     InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Num Events'");
     InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Wait Events'");
     InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Ret Event'");
 
+    InstructionDesc[OpGroupNonUniformElect].operands.push(OperandScope, "'Execution'");
+
+    InstructionDesc[OpGroupNonUniformAll].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformAll].operands.push(OperandId, "X");
+
+    InstructionDesc[OpGroupNonUniformAny].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformAny].operands.push(OperandId, "X");
+
+    InstructionDesc[OpGroupNonUniformAllEqual].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformAllEqual].operands.push(OperandId, "X");
+
+    InstructionDesc[OpGroupNonUniformBroadcast].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformBroadcast].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformBroadcast].operands.push(OperandId, "ID");
+
+    InstructionDesc[OpGroupNonUniformBroadcastFirst].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformBroadcastFirst].operands.push(OperandId, "X");
+
+    InstructionDesc[OpGroupNonUniformBallot].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformBallot].operands.push(OperandId, "X");
+
+    InstructionDesc[OpGroupNonUniformInverseBallot].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformInverseBallot].operands.push(OperandId, "X");
+
+    InstructionDesc[OpGroupNonUniformBallotBitExtract].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformBallotBitExtract].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformBallotBitExtract].operands.push(OperandId, "Bit");
+
+    InstructionDesc[OpGroupNonUniformBallotBitCount].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformBallotBitCount].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformBallotBitCount].operands.push(OperandId, "X");
+
+    InstructionDesc[OpGroupNonUniformBallotFindLSB].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformBallotFindLSB].operands.push(OperandId, "X");
+
+    InstructionDesc[OpGroupNonUniformBallotFindMSB].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformBallotFindMSB].operands.push(OperandId, "X");
+
+    InstructionDesc[OpGroupNonUniformShuffle].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformShuffle].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformShuffle].operands.push(OperandId, "'Id'");
+
+    InstructionDesc[OpGroupNonUniformShuffleXor].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformShuffleXor].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformShuffleXor].operands.push(OperandId, "Mask");
+
+    InstructionDesc[OpGroupNonUniformShuffleUp].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformShuffleUp].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformShuffleUp].operands.push(OperandId, "Offset");
+
+    InstructionDesc[OpGroupNonUniformShuffleDown].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformShuffleDown].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformShuffleDown].operands.push(OperandId, "Offset");
+
+    InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandGroupOperation, "'Operation'");
+    InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandId, "'ClusterSize'", true);
+
+    InstructionDesc[OpGroupNonUniformQuadBroadcast].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformQuadBroadcast].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformQuadBroadcast].operands.push(OperandId, "'Id'");
+
+    InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandScope, "'Execution'");
+    InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "X");
+    InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandLiteralNumber, "'Direction'");
+
     InstructionDesc[OpSubgroupBallotKHR].operands.push(OperandId, "'Predicate'");
 
     InstructionDesc[OpSubgroupFirstInvocationKHR].operands.push(OperandId, "'Value'");
 
-    InstructionDesc[OpSubgroupAnyKHR].capabilities.push_back(CapabilitySubgroupVoteKHR);
     InstructionDesc[OpSubgroupAnyKHR].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpSubgroupAnyKHR].operands.push(OperandId, "'Predicate'");
 
-    InstructionDesc[OpSubgroupAllKHR].capabilities.push_back(CapabilitySubgroupVoteKHR);
     InstructionDesc[OpSubgroupAllKHR].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpSubgroupAllKHR].operands.push(OperandId, "'Predicate'");
 
-    InstructionDesc[OpSubgroupAllEqualKHR].capabilities.push_back(CapabilitySubgroupVoteKHR);
     InstructionDesc[OpSubgroupAllEqualKHR].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpSubgroupAllEqualKHR].operands.push(OperandId, "'Predicate'");
 
-    InstructionDesc[OpSubgroupReadInvocationKHR].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Value'");
     InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Index'");
 
+    InstructionDesc[OpModuleProcessed].operands.push(OperandLiteralString, "'process'");
+
 #ifdef AMD_EXTENSIONS
-    InstructionDesc[OpGroupIAddNonUniformAMD].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandId, "'X'");
 
-    InstructionDesc[OpGroupFAddNonUniformAMD].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupFAddNonUniformAMD].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupFAddNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupFAddNonUniformAMD].operands.push(OperandId, "'X'");
 
-    InstructionDesc[OpGroupUMinNonUniformAMD].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupUMinNonUniformAMD].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupUMinNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupUMinNonUniformAMD].operands.push(OperandId, "'X'");
 
-    InstructionDesc[OpGroupSMinNonUniformAMD].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupSMinNonUniformAMD].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupSMinNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupSMinNonUniformAMD].operands.push(OperandId, "X");
 
-    InstructionDesc[OpGroupFMinNonUniformAMD].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupFMinNonUniformAMD].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupFMinNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupFMinNonUniformAMD].operands.push(OperandId, "X");
 
-    InstructionDesc[OpGroupUMaxNonUniformAMD].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupUMaxNonUniformAMD].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupUMaxNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupUMaxNonUniformAMD].operands.push(OperandId, "X");
 
-    InstructionDesc[OpGroupSMaxNonUniformAMD].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupSMaxNonUniformAMD].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupSMaxNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupSMaxNonUniformAMD].operands.push(OperandId, "X");
 
-    InstructionDesc[OpGroupFMaxNonUniformAMD].capabilities.push_back(CapabilityGroups);
     InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
     InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandId, "X");
 
-    InstructionDesc[OpFragmentMaskFetchAMD].capabilities.push_back(CapabilityFragmentMaskAMD);
     InstructionDesc[OpFragmentMaskFetchAMD].operands.push(OperandId, "'Image'");
     InstructionDesc[OpFragmentMaskFetchAMD].operands.push(OperandId, "'Coordinate'");
 
-    InstructionDesc[OpFragmentFetchAMD].capabilities.push_back(CapabilityFragmentMaskAMD);
     InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Image'");
     InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Coordinate'");
     InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Fragment Index'");
 #endif
+
+#ifdef NV_EXTENSIONS
+    InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
+#endif
 }
 
 }; // end spv namespace
diff --git a/SPIRV/doc.h b/SPIRV/doc.h
index 710ca1a..7d0475d 100644
--- a/SPIRV/doc.h
+++ b/SPIRV/doc.h
@@ -190,7 +190,6 @@
 class EnumParameters {
 public:
     EnumParameters() : desc(0) { }
-    EnumCaps caps;
     const char* desc;
 };
 
@@ -235,7 +234,6 @@
     bool hasType()   const { return typePresent != 0; }
 
     const char* opDesc;
-    EnumCaps capabilities;
     OpcodeClass opClass;
     OperandParameters operands;
 
@@ -244,8 +242,6 @@
     int resultPresent : 1;
 };
 
-const int OpcodeCeiling = 321;
-
 // The set of objects that hold all the instruction/operand
 // parameterization information.
 extern InstructionParameters InstructionDesc[];
diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp
old mode 100755
new mode 100644
index 8bddf7e..e21762d
--- a/SPIRV/spirv.hpp
+++ b/SPIRV/spirv.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 The Khronos Group Inc.
+// Copyright (c) 2014-2018 The Khronos Group Inc.
 // 
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and/or associated documentation files (the "Materials"),
@@ -46,12 +46,12 @@
 
 typedef unsigned int Id;
 
-#define SPV_VERSION 0x10000
-#define SPV_REVISION 12
+#define SPV_VERSION 0x10300
+#define SPV_REVISION 1
 
 static const unsigned int MagicNumber = 0x07230203;
-static const unsigned int Version = 0x00010000;
-static const unsigned int Revision = 12;
+static const unsigned int Version = 0x00010300;
+static const unsigned int Revision = 1;
 static const unsigned int OpCodeMask = 0xffff;
 static const unsigned int WordCountShift = 16;
 
@@ -122,7 +122,15 @@
     ExecutionModeOutputTriangleStrip = 29,
     ExecutionModeVecTypeHint = 30,
     ExecutionModeContractionOff = 31,
+    ExecutionModeInitializer = 33,
+    ExecutionModeFinalizer = 34,
+    ExecutionModeSubgroupSize = 35,
+    ExecutionModeSubgroupsPerWorkgroup = 36,
+    ExecutionModeSubgroupsPerWorkgroupId = 37,
+    ExecutionModeLocalSizeId = 38,
+    ExecutionModeLocalSizeHintId = 39,
     ExecutionModePostDepthCoverage = 4446,
+    ExecutionModeStencilRefReplacingEXT = 5027,
     ExecutionModeMax = 0x7fffffff,
 };
 
@@ -377,11 +385,17 @@
     DecorationNoContraction = 42,
     DecorationInputAttachmentIndex = 43,
     DecorationAlignment = 44,
+    DecorationMaxByteOffset = 45,
+    DecorationAlignmentId = 46,
+    DecorationMaxByteOffsetId = 47,
     DecorationExplicitInterpAMD = 4999,
     DecorationOverrideCoverageNV = 5248,
     DecorationPassthroughNV = 5250,
     DecorationViewportRelativeNV = 5252,
     DecorationSecondaryViewportRelativeNV = 5256,
+    DecorationNonUniformEXT = 5300,
+    DecorationHlslCounterBufferGOOGLE = 5634,
+    DecorationHlslSemanticGOOGLE = 5635,
     DecorationMax = 0x7fffffff,
 };
 
@@ -427,10 +441,15 @@
     BuiltInSubgroupLocalInvocationId = 41,
     BuiltInVertexIndex = 42,
     BuiltInInstanceIndex = 43,
+    BuiltInSubgroupEqMask = 4416,
     BuiltInSubgroupEqMaskKHR = 4416,
+    BuiltInSubgroupGeMask = 4417,
     BuiltInSubgroupGeMaskKHR = 4417,
+    BuiltInSubgroupGtMask = 4418,
     BuiltInSubgroupGtMaskKHR = 4418,
+    BuiltInSubgroupLeMask = 4419,
     BuiltInSubgroupLeMaskKHR = 4419,
+    BuiltInSubgroupLtMask = 4420,
     BuiltInSubgroupLtMaskKHR = 4420,
     BuiltInBaseVertex = 4424,
     BuiltInBaseInstance = 4425,
@@ -450,6 +469,7 @@
     BuiltInSecondaryViewportMaskNV = 5258,
     BuiltInPositionPerViewNV = 5261,
     BuiltInViewportMaskPerViewNV = 5262,
+    BuiltInFullyCoveredEXT = 5264,
     BuiltInMax = 0x7fffffff,
 };
 
@@ -468,6 +488,8 @@
 enum LoopControlShift {
     LoopControlUnrollShift = 0,
     LoopControlDontUnrollShift = 1,
+    LoopControlDependencyInfiniteShift = 2,
+    LoopControlDependencyLengthShift = 3,
     LoopControlMax = 0x7fffffff,
 };
 
@@ -475,6 +497,8 @@
     LoopControlMaskNone = 0,
     LoopControlUnrollMask = 0x00000001,
     LoopControlDontUnrollMask = 0x00000002,
+    LoopControlDependencyInfiniteMask = 0x00000004,
+    LoopControlDependencyLengthMask = 0x00000008,
 };
 
 enum FunctionControlShift {
@@ -548,6 +572,10 @@
     GroupOperationReduce = 0,
     GroupOperationInclusiveScan = 1,
     GroupOperationExclusiveScan = 2,
+    GroupOperationClusteredReduce = 3,
+    GroupOperationPartitionedReduceNV = 6,
+    GroupOperationPartitionedInclusiveScanNV = 7,
+    GroupOperationPartitionedExclusiveScanNV = 8,
     GroupOperationMax = 0x7fffffff,
 };
 
@@ -625,6 +653,17 @@
     CapabilityStorageImageReadWithoutFormat = 55,
     CapabilityStorageImageWriteWithoutFormat = 56,
     CapabilityMultiViewport = 57,
+    CapabilitySubgroupDispatch = 58,
+    CapabilityNamedBarrier = 59,
+    CapabilityPipeStorage = 60,
+    CapabilityGroupNonUniform = 61,
+    CapabilityGroupNonUniformVote = 62,
+    CapabilityGroupNonUniformArithmetic = 63,
+    CapabilityGroupNonUniformBallot = 64,
+    CapabilityGroupNonUniformShuffle = 65,
+    CapabilityGroupNonUniformShuffleRelative = 66,
+    CapabilityGroupNonUniformClustered = 67,
+    CapabilityGroupNonUniformQuad = 68,
     CapabilitySubgroupBallotKHR = 4423,
     CapabilityDrawParameters = 4427,
     CapabilitySubgroupVoteKHR = 4431,
@@ -640,8 +679,11 @@
     CapabilityVariablePointers = 4442,
     CapabilityAtomicStorageOps = 4445,
     CapabilitySampleMaskPostDepthCoverage = 4447,
+    CapabilityFloat16ImageAMD = 5008,
     CapabilityImageGatherBiasLodAMD = 5009,
+    CapabilityFragmentMaskAMD = 5010,
     CapabilityStencilExportEXT = 5013,
+    CapabilityImageReadWriteLodAMD = 5015,
     CapabilitySampleMaskOverrideCoverageNV = 5249,
     CapabilityGeometryShaderPassthroughNV = 5251,
     CapabilityShaderViewportIndexLayerEXT = 5254,
@@ -649,6 +691,23 @@
     CapabilityShaderViewportMaskNV = 5255,
     CapabilityShaderStereoViewNV = 5259,
     CapabilityPerViewAttributesNV = 5260,
+    CapabilityFragmentFullyCoveredEXT = 5265,
+    CapabilityGroupNonUniformPartitionedNV = 5297,
+    CapabilityShaderNonUniformEXT = 5301,
+    CapabilityRuntimeDescriptorArrayEXT = 5302,
+    CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303,
+    CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304,
+    CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305,
+    CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306,
+    CapabilitySampledImageArrayNonUniformIndexingEXT = 5307,
+    CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308,
+    CapabilityStorageImageArrayNonUniformIndexingEXT = 5309,
+    CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
+    CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
+    CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
+    CapabilitySubgroupShuffleINTEL = 5568,
+    CapabilitySubgroupBufferBlockIOINTEL = 5569,
+    CapabilitySubgroupImageBlockIOINTEL = 5570,
     CapabilityMax = 0x7fffffff,
 };
 
@@ -947,6 +1006,52 @@
     OpAtomicFlagTestAndSet = 318,
     OpAtomicFlagClear = 319,
     OpImageSparseRead = 320,
+    OpSizeOf = 321,
+    OpTypePipeStorage = 322,
+    OpConstantPipeStorage = 323,
+    OpCreatePipeFromPipeStorage = 324,
+    OpGetKernelLocalSizeForSubgroupCount = 325,
+    OpGetKernelMaxNumSubgroups = 326,
+    OpTypeNamedBarrier = 327,
+    OpNamedBarrierInitialize = 328,
+    OpMemoryNamedBarrier = 329,
+    OpModuleProcessed = 330,
+    OpExecutionModeId = 331,
+    OpDecorateId = 332,
+    OpGroupNonUniformElect = 333,
+    OpGroupNonUniformAll = 334,
+    OpGroupNonUniformAny = 335,
+    OpGroupNonUniformAllEqual = 336,
+    OpGroupNonUniformBroadcast = 337,
+    OpGroupNonUniformBroadcastFirst = 338,
+    OpGroupNonUniformBallot = 339,
+    OpGroupNonUniformInverseBallot = 340,
+    OpGroupNonUniformBallotBitExtract = 341,
+    OpGroupNonUniformBallotBitCount = 342,
+    OpGroupNonUniformBallotFindLSB = 343,
+    OpGroupNonUniformBallotFindMSB = 344,
+    OpGroupNonUniformShuffle = 345,
+    OpGroupNonUniformShuffleXor = 346,
+    OpGroupNonUniformShuffleUp = 347,
+    OpGroupNonUniformShuffleDown = 348,
+    OpGroupNonUniformIAdd = 349,
+    OpGroupNonUniformFAdd = 350,
+    OpGroupNonUniformIMul = 351,
+    OpGroupNonUniformFMul = 352,
+    OpGroupNonUniformSMin = 353,
+    OpGroupNonUniformUMin = 354,
+    OpGroupNonUniformFMin = 355,
+    OpGroupNonUniformSMax = 356,
+    OpGroupNonUniformUMax = 357,
+    OpGroupNonUniformFMax = 358,
+    OpGroupNonUniformBitwiseAnd = 359,
+    OpGroupNonUniformBitwiseOr = 360,
+    OpGroupNonUniformBitwiseXor = 361,
+    OpGroupNonUniformLogicalAnd = 362,
+    OpGroupNonUniformLogicalOr = 363,
+    OpGroupNonUniformLogicalXor = 364,
+    OpGroupNonUniformQuadBroadcast = 365,
+    OpGroupNonUniformQuadSwap = 366,
     OpSubgroupBallotKHR = 4421,
     OpSubgroupFirstInvocationKHR = 4422,
     OpSubgroupAllKHR = 4428,
@@ -961,6 +1066,19 @@
     OpGroupFMaxNonUniformAMD = 5005,
     OpGroupUMaxNonUniformAMD = 5006,
     OpGroupSMaxNonUniformAMD = 5007,
+    OpFragmentMaskFetchAMD = 5011,
+    OpFragmentFetchAMD = 5012,
+    OpGroupNonUniformPartitionNV = 5296,
+    OpSubgroupShuffleINTEL = 5571,
+    OpSubgroupShuffleDownINTEL = 5572,
+    OpSubgroupShuffleUpINTEL = 5573,
+    OpSubgroupShuffleXorINTEL = 5574,
+    OpSubgroupBlockReadINTEL = 5575,
+    OpSubgroupBlockWriteINTEL = 5576,
+    OpSubgroupImageBlockReadINTEL = 5577,
+    OpSubgroupImageBlockWriteINTEL = 5578,
+    OpDecorateStringGOOGLE = 5632,
+    OpMemberDecorateStringGOOGLE = 5633,
     OpMax = 0x7fffffff,
 };
 
diff --git a/SPIRV/spvIR.h b/SPIRV/spvIR.h
index 6880595..faa2701 100755
--- a/SPIRV/spvIR.h
+++ b/SPIRV/spvIR.h
@@ -74,11 +74,8 @@
 
 POTENTIALLY_UNUSED
 const MemorySemanticsMask MemorySemanticsAllMemory =
-                (MemorySemanticsMask)(MemorySemanticsSequentiallyConsistentMask |
-                                      MemorySemanticsUniformMemoryMask |
-                                      MemorySemanticsSubgroupMemoryMask |
+                (MemorySemanticsMask)(MemorySemanticsUniformMemoryMask |
                                       MemorySemanticsWorkgroupMemoryMask |
-                                      MemorySemanticsCrossWorkgroupMemoryMask |
                                       MemorySemanticsAtomicCounterMemoryMask |
                                       MemorySemanticsImageMemoryMask);
 
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 19302cb..044662f 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -98,7 +98,10 @@
     EOptionStdin                = (1 << 27),
     EOptionOptimizeDisable      = (1 << 28),
     EOptionOptimizeSize         = (1 << 29),
+    EOptionInvertY              = (1 << 30),
+    EOptionDumpBareVersion      = (1 << 31),
 };
+bool targetHlslFunctionality1 = false;
 
 //
 // Return codes from main/exit().
@@ -127,6 +130,9 @@
 bool CompileFailed = false;
 bool LinkFailed = false;
 
+// array of unique places to leave the shader names and infologs for the asynchronous compiles
+std::vector<std::unique_ptr<glslang::TWorkItem>> WorkItems;
+
 TBuiltInResource Resources;
 std::string ConfigFile;
 
@@ -151,12 +157,16 @@
 const char* sourceEntryPointName = nullptr;
 const char* shaderStageName = nullptr;
 const char* variableName = nullptr;
+bool HlslEnable16BitTypes = false;
 std::vector<std::string> IncludeDirectoryList;
-int ClientInputSemanticsVersion = 100;   // maps to, say, #define VULKAN 100
-int VulkanClientVersion = 100;           // would map to, say, Vulkan 1.0
-int OpenGLClientVersion = 450;           // doesn't influence anything yet, but maps to OpenGL 4.50
-unsigned int TargetVersion = 0x00001000; // maps to, say, SPIR-V 1.0
-std::vector<std::string> Processes;      // what should be recorded by OpModuleProcessed, or equivalent
+int ClientInputSemanticsVersion = 100;                  // maps to, say, #define VULKAN 100
+glslang::EShTargetClientVersion VulkanClientVersion =
+                          glslang::EShTargetVulkan_1_0; // would map to, say, Vulkan 1.0
+glslang::EShTargetClientVersion OpenGLClientVersion =
+                          glslang::EShTargetOpenGL_450; // doesn't influence anything yet, but maps to OpenGL 4.50
+glslang::EShTargetLanguageVersion TargetVersion =
+                          glslang::EShTargetSpv_1_0;    // maps to, say, SPIR-V 1.0
+std::vector<std::string> Processes;                     // what should be recorded by OpModuleProcessed, or equivalent
 
 // Per descriptor-set binding base data
 typedef std::map<unsigned int, unsigned int> TPerSetBaseBinding;
@@ -261,14 +271,14 @@
 //
 void Error(const char* message)
 {
-    printf("%s: Error %s (use -h for usage)\n", ExecutableName, message);
+    fprintf(stderr, "%s: Error %s (use -h for usage)\n", ExecutableName, message);
     exit(EFailUsage);
 }
 
 //
 // Process an optional binding base of one the forms:
 //   --argname [stage] base            // base for stage (if given) or all stages (if not)
-//   --argname [stage] [set base]...   // set/base pairs: set the base for given binding set.
+//   --argname [stage] [base set]...   // set/base pairs: set the base for given binding set.
 
 // Where stage is one of the forms accepted by FindLanguage, and base is an integer
 //
@@ -293,8 +303,8 @@
     if ((argc - arg) > 2 && isdigit(argv[arg+0][0]) && isdigit(argv[arg+1][0])) {
         // Parse a per-set binding base
         while ((argc - arg) > 2 && isdigit(argv[arg+0][0]) && isdigit(argv[arg+1][0])) {
-            const int setNum = atoi(argv[arg++]);
             const int baseNum = atoi(argv[arg++]);
+            const int setNum = atoi(argv[arg++]);
             perSetBase[setNum] = baseNum;
         }
     } else {
@@ -445,6 +455,11 @@
                                lowerword == "hlsl-iomapper" ||
                                lowerword == "hlsl-iomapping") {
                         Options |= EOptionHlslIoMapping;
+                    } else if (lowerword == "hlsl-enable-16bit-types") {
+                        HlslEnable16BitTypes = true;
+                    } else if (lowerword == "invert-y" ||  // synonyms
+                               lowerword == "iy") {
+                        Options |= EOptionInvertY;
                     } else if (lowerword == "keep-uncalled" || // synonyms
                                lowerword == "ku") {
                         Options |= EOptionKeepUncalled;
@@ -500,22 +515,28 @@
                         if (argc > 1) {
                             if (strcmp(argv[1], "vulkan1.0") == 0) {
                                 setVulkanSpv();
-                                VulkanClientVersion = 100;
+                                VulkanClientVersion = glslang::EShTargetVulkan_1_0;
+                            } else if (strcmp(argv[1], "vulkan1.1") == 0) {
+                                setVulkanSpv();
+                                TargetVersion = glslang::EShTargetSpv_1_3;
+                                VulkanClientVersion = glslang::EShTargetVulkan_1_1;
                             } else if (strcmp(argv[1], "opengl") == 0) {
                                 setOpenGlSpv();
-                                OpenGLClientVersion = 450;
+                                OpenGLClientVersion = glslang::EShTargetOpenGL_450;
                             } else
-                                Error("--target-env expected vulkan1.0 or opengl");
+                                Error("--target-env expected vulkan1.0, vulkan1.1, or opengl");
                         }
                         bumpArg();
                     } else if (lowerword == "variable-name" || // synonyms
-                        lowerword == "vn") {
+                               lowerword == "vn") {
                         Options |= EOptionOutputHexadecimal;
                         if (argc <= 1)
                             Error("no <C-variable-name> provided for --variable-name");
                         variableName = argv[1];
                         bumpArg();
                         break;
+                    } else if (lowerword == "version") {
+                        Options |= EOptionDumpVersions;
                     } else {
                         usage();
                     }
@@ -553,7 +574,7 @@
                 if (argv[0][2] == 'd')
                     Options |= EOptionOptimizeDisable;
                 else if (argv[0][2] == 's')
-#ifdef ENABLE_OPT
+#if ENABLE_OPT
                     Options |= EOptionOptimizeSize;
 #else
                     Error("-Os not available; optimizer not linked");
@@ -573,13 +594,17 @@
             case 'V':
                 setVulkanSpv();
                 if (argv[0][2] != 0)
-                    ClientInputSemanticsVersion = getAttachedNumber("-G<num> client input semantics");
+                    ClientInputSemanticsVersion = getAttachedNumber("-V<num> client input semantics");
                 break;
             case 'c':
                 Options |= EOptionDumpConfig;
                 break;
             case 'd':
-                Options |= EOptionDefaultDesktop;
+                if (strncmp(&argv[0][1], "dumpversion", strlen(&argv[0][1]) + 1) == 0 ||
+                    strncmp(&argv[0][1], "dumpfullversion", strlen(&argv[0][1]) + 1) == 0)
+                    Options |= EOptionDumpBareVersion;
+                else
+                    Options |= EOptionDefaultDesktop;
                 break;
             case 'e':
                 // HLSL todo: entry point handle needs much more sophistication.
@@ -589,6 +614,12 @@
                     Error("no <name> provided for -e");
                 bumpArg();
                 break;
+            case 'f':
+                if (strcmp(&argv[0][2], "hlsl_functionality1") == 0)
+                    targetHlslFunctionality1 = true;
+                else
+                    Error("-f: expected hlsl_functionality1");
+                break;
             case 'g':
                 Options |= EOptionDebug;
                 break;
@@ -687,6 +718,10 @@
         messages = (EShMessages)(messages | EShMsgHlslOffsets);
     if (Options & EOptionDebug)
         messages = (EShMessages)(messages | EShMsgDebugInfo);
+    if (HlslEnable16BitTypes)
+        messages = (EShMessages)(messages | EShMsgHlslEnable16BitTypes);
+    if ((Options & EOptionOptimizeDisable) || !ENABLE_OPT)
+        messages = (EShMessages)(messages | EShMsgHlslLegalization);
 }
 
 //
@@ -694,6 +729,9 @@
 //
 void CompileShaders(glslang::TWorklist& worklist)
 {
+    if (Options & EOptionDebug)
+        Error("cannot generate debug information unless linking to generate code");
+
     glslang::TWorkItem* workItem;
     if (Options & EOptionStdin) {
         worklist.remove(workItem);
@@ -821,7 +859,7 @@
             // TODO: use a range based for loop here, when available in all environments.
             for (auto i = baseBindingForSet[res][compUnit.stage].begin();
                  i != baseBindingForSet[res][compUnit.stage].end(); ++i)
-                shader->setShiftBindingForSet(res, i->first, i->second);
+                shader->setShiftBindingForSet(res, i->second, i->first);
         }
 
         shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
@@ -837,6 +875,9 @@
         if (Options & EOptionAutoMapLocations)
             shader->setAutoMapLocations(true);
 
+        if (Options & EOptionInvertY)
+            shader->setInvertY(true);
+
         // Set up the environment, some subsettings take precedence over earlier
         // ways of setting things.
         if (Options & EOptionSpv) {
@@ -845,14 +886,15 @@
                                                                 : glslang::EShSourceGlsl,
                                         compUnit.stage, glslang::EShClientVulkan, ClientInputSemanticsVersion);
                 shader->setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
-                shader->setEnvTarget(glslang::EshTargetSpv, TargetVersion);
             } else {
                 shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl
                                                                 : glslang::EShSourceGlsl,
                                         compUnit.stage, glslang::EShClientOpenGL, ClientInputSemanticsVersion);
                 shader->setEnvClient(glslang::EShClientOpenGL, OpenGLClientVersion);
-                shader->setEnvTarget(glslang::EshTargetSpv, TargetVersion);
             }
+            shader->setEnvTarget(glslang::EShTargetSpv, TargetVersion);
+            if (targetHlslFunctionality1)
+                shader->setEnvTargetHlslFunctionality1();
         }
 
         shaders.push_back(shader);
@@ -1022,14 +1064,10 @@
         FreeFileData(const_cast<char*>(it->text[0]));
 }
 
-int C_DECL main(int argc, char* argv[])
+int singleMain()
 {
-    // array of unique places to leave the shader names and infologs for the asynchronous compiles
-    std::vector<std::unique_ptr<glslang::TWorkItem>> workItems;
-    ProcessArguments(workItems, argc, argv);
-
     glslang::TWorklist workList;
-    std::for_each(workItems.begin(), workItems.end(), [&workList](std::unique_ptr<glslang::TWorkItem>& item) {
+    std::for_each(WorkItems.begin(), WorkItems.end(), [&workList](std::unique_ptr<glslang::TWorkItem>& item) {
         assert(item);
         workList.add(item.get());
     });
@@ -1040,8 +1078,14 @@
             return ESuccess;
     }
 
-    if (Options & EOptionDumpVersions) {
-        printf("Glslang Version: %s %s\n", GLSLANG_REVISION, GLSLANG_DATE);
+    if (Options & EOptionDumpBareVersion) {
+        printf("%d.%d.%d\n",
+            glslang::GetSpirvGeneratorVersion(), GLSLANG_MINOR_VERSION, GLSLANG_PATCH_LEVEL);
+        if (workList.empty())
+            return ESuccess;
+    } else if (Options & EOptionDumpVersions) {
+        printf("Glslang Version: %d.%d.%d\n",
+            glslang::GetSpirvGeneratorVersion(), GLSLANG_MINOR_VERSION, GLSLANG_PATCH_LEVEL);
         printf("ESSL Version: %s\n", glslang::GetEsslVersionString());
         printf("GLSL Version: %s\n", glslang::GetGlslVersionString());
         std::string spirvVersion;
@@ -1049,6 +1093,7 @@
         printf("SPIR-V Version %s\n", spirvVersion.c_str());
         printf("GLSL.std.450 Version %d, Revision %d\n", GLSLstd450Version, GLSLstd450Revision);
         printf("Khronos Tool ID %d\n", glslang::GetKhronosToolId());
+        printf("SPIR-V Generator Version %d\n", glslang::GetSpirvGeneratorVersion());
         printf("GL_KHR_vulkan_glsl version %d\n", 100);
         printf("ARB_GL_gl_spirv version %d\n", 100);
         if (workList.empty())
@@ -1060,8 +1105,8 @@
     }
 
     if (Options & EOptionStdin) {
-        workItems.push_back(std::unique_ptr<glslang::TWorkItem>{new glslang::TWorkItem("stdin")});
-        workList.add(workItems.back().get());
+        WorkItems.push_back(std::unique_ptr<glslang::TWorkItem>{new glslang::TWorkItem("stdin")});
+        workList.add(WorkItems.back().get());
     }
 
     ProcessConfigFile();
@@ -1074,22 +1119,25 @@
     if (Options & EOptionLinkProgram ||
         Options & EOptionOutputPreprocessed) {
         glslang::InitializeProcess();
+        glslang::InitializeProcess();  // also test reference counting of users
+        glslang::InitializeProcess();  // also test reference counting of users
+        glslang::FinalizeProcess();    // also test reference counting of users
+        glslang::FinalizeProcess();    // also test reference counting of users
         CompileAndLinkShaderFiles(workList);
         glslang::FinalizeProcess();
     } else {
         ShInitialize();
+        ShInitialize();  // also test reference counting of users
+        ShFinalize();    // also test reference counting of users
 
         bool printShaderNames = workList.size() > 1;
 
-        if (Options & EOptionMultiThreaded)
-        {
+        if (Options & EOptionMultiThreaded) {
             std::array<std::thread, 16> threads;
-            for (unsigned int t = 0; t < threads.size(); ++t)
-            {
+            for (unsigned int t = 0; t < threads.size(); ++t) {
                 threads[t] = std::thread(CompileShaders, std::ref(workList));
-                if (threads[t].get_id() == std::thread::id())
-                {
-                    printf("Failed to create thread\n");
+                if (threads[t].get_id() == std::thread::id()) {
+                    fprintf(stderr, "Failed to create thread\n");
                     return EFailThreadCreate;
                 }
             }
@@ -1099,11 +1147,11 @@
             CompileShaders(workList);
 
         // Print out all the resulting infologs
-        for (size_t w = 0; w < workItems.size(); ++w) {
-            if (workItems[w]) {
-                if (printShaderNames || workItems[w]->results.size() > 0)
-                    PutsIfNonEmpty(workItems[w]->name.c_str());
-                PutsIfNonEmpty(workItems[w]->results.c_str());
+        for (size_t w = 0; w < WorkItems.size(); ++w) {
+            if (WorkItems[w]) {
+                if (printShaderNames || WorkItems[w]->results.size() > 0)
+                    PutsIfNonEmpty(WorkItems[w]->name.c_str());
+                PutsIfNonEmpty(WorkItems[w]->results.c_str());
             }
         }
 
@@ -1118,6 +1166,25 @@
     return 0;
 }
 
+int C_DECL main(int argc, char* argv[])
+{
+    ProcessArguments(WorkItems, argc, argv);
+
+    int ret = 0;
+
+    // Loop over the entire init/finalize cycle to watch memory changes
+    const int iterations = 1;
+    if (iterations > 1)
+        glslang::OS_DumpMemoryCounters();
+    for (int i = 0; i < iterations; ++i) {
+        ret = singleMain();
+        if (iterations > 1)
+            glslang::OS_DumpMemoryCounters();
+    }
+
+    return ret;
+}
+
 //
 //   Deduce the language from the filename.  Files must end in one of the
 //   following extensions:
@@ -1264,6 +1331,9 @@
            "  -d          default to desktop (#version 110) when there is no shader #version\n"
            "              (default is ES version 100)\n"
            "  -e <name>   specify <name> as the entry-point name\n"
+           "  -f{hlsl_functionality1}\n"
+           "              'hlsl_functionality1' enables use of the\n"
+           "                  SPV_GOOGLE_hlsl_functionality1 extension\n"
            "  -g          generate debug information\n"
            "  -h          print this usage message\n"
            "  -i          intermediate tree (glslang AST) is printed out\n"
@@ -1272,7 +1342,7 @@
            "  -o <file>   save binary to <file>, requires a binary option (e.g., -V)\n"
            "  -q          dump reflection query database\n"
            "  -r          synonym for --relaxed-errors\n"
-           "  -s          silent mode\n"
+           "  -s          silence syntax and semantic error reporting\n"
            "  -t          multi-threaded mode\n"
            "  -v          print version strings\n"
            "  -w          synonym for --suppress-warnings\n"
@@ -1284,12 +1354,16 @@
            "                                       'location' (fragile, not cross stage)\n"
            "  --aml                                synonym for --auto-map-locations\n"
            "  --client {vulkan<ver>|opengl<ver>}   see -V and -G\n"
+           "  -dumpfullversion                     print bare major.minor.patchlevel\n"
+           "  -dumpversion                         same as -dumpfullversion\n"
            "  --flatten-uniform-arrays             flatten uniform texture/sampler arrays to\n"
            "                                       scalars\n"
            "  --fua                                synonym for --flatten-uniform-arrays\n"
            "  --hlsl-offsets                       Allow block offsets to follow HLSL rules\n"
            "                                       Works independently of source language\n"
            "  --hlsl-iomap                         Perform IO mapping in HLSL register space\n"
+           "  --hlsl-enable-16bit-types            Allow use of 16-bit types in SPIR-V for HLSL\n"
+           "  --invert-y | --iy                    invert position.Y output in vertex shader\n"
            "  --keep-uncalled                      don't eliminate uncalled functions\n"
            "  --ku                                 synonym for --keep-uncalled\n"
            "  --no-storage-format                  use Unknown image format\n"
@@ -1301,24 +1375,24 @@
            "              Set descriptor set for all resources\n"
            "  --rsb [stage] type set binding       synonym for --resource-set-binding\n"
            "  --shift-image-binding [stage] num    base binding number for images (uav)\n"
-           "  --shift-image-binding [stage] [set num]... per-descriptor-set shift values\n"
+           "  --shift-image-binding [stage] [num set]... per-descriptor-set shift values\n"
            "  --sib [stage] num                    synonym for --shift-image-binding\n"
            "  --shift-sampler-binding [stage] num  base binding number for samplers\n"
-           "  --shift-sampler-binding [stage] [set num]... per-descriptor-set shift values\n"
+           "  --shift-sampler-binding [stage] [num set]... per-descriptor-set shift values\n"
            "  --ssb [stage] num                    synonym for --shift-sampler-binding\n"
            "  --shift-ssbo-binding [stage] num     base binding number for SSBOs\n"
-           "  --shift-ssbo-binding [stage] [set num]... per-descriptor-set shift values\n"
+           "  --shift-ssbo-binding [stage] [num set]... per-descriptor-set shift values\n"
            "  --sbb [stage] num                    synonym for --shift-ssbo-binding\n"
            "  --shift-texture-binding [stage] num  base binding number for textures\n"
-           "  --shift-texture-binding [stage] [set num]... per-descriptor-set shift values\n"
+           "  --shift-texture-binding [stage] [num set]... per-descriptor-set shift values\n"
            "  --stb [stage] num                    synonym for --shift-texture-binding\n"
            "  --shift-uav-binding [stage] num      base binding number for UAVs\n"
-           "  --shift-uav-binding [stage] [set num]... per-descriptor-set shift values\n"
+           "  --shift-uav-binding [stage] [num set]... per-descriptor-set shift values\n"
            "  --suavb [stage] num                  synonym for --shift-uav-binding\n"
            "  --shift-UBO-binding [stage] num      base binding number for UBOs\n"
-           "  --shift-UBO-binding [stage] [set num]... per-descriptor-set shift values\n"
+           "  --shift-UBO-binding [stage] [num set]... per-descriptor-set shift values\n"
            "  --shift-cbuffer-binding [stage] num  synonym for --shift-UBO-binding\n"
-           "  --shift-cbuffer-binding [stage] [set num]... per-descriptor-set shift values\n"
+           "  --shift-cbuffer-binding [stage] [num set]... per-descriptor-set shift values\n"
            "  --sub [stage] num                    synonym for --shift-UBO-binding\n"
            "  --source-entrypoint <name>           the given shader source function is\n"
            "                                       renamed to be the <name> given in -e\n"
@@ -1328,14 +1402,16 @@
            "                                       using -S.\n"
            "  --suppress-warnings                  suppress GLSL warnings\n"
            "                                       (except as required by #extension : warn)\n"
-           "  --target-env {vulkan1.0|opengl}      set the execution environment code will\n"
-           "                                       execute in (as opposed to language\n"
+           "  --target-env {vulkan1.0 | vulkan1.1 | opengl} \n"
+           "                                       set execution environment that emitted code\n"
+           "                                       will execute in (as opposed to the language\n"
            "                                       semantics selected by --client) defaults:\n"
-           "                                        'vulkan1.0' under '--client vulkan<ver>'\n"
-           "                                        'opengl' under '--client opengl<ver>'\n"
+           "                                          'vulkan1.0' under '--client vulkan<ver>'\n"
+           "                                          'opengl' under '--client opengl<ver>'\n"
            "  --variable-name <name>               Creates a C header file that contains a\n"
            "                                       uint32_t array named <name>\n"
            "                                       initialized with the shader binary code.\n"
+           "  --version                            synonym for -v\n"
            "  --vn <name>                          synonym for --variable-name <name>\n"
            );
 
diff --git a/Test/310AofA.vert b/Test/310AofA.vert
index a196388..fba2977 100644
--- a/Test/310AofA.vert
+++ b/Test/310AofA.vert
@@ -113,3 +113,9 @@
 uniform ubaa {

     int a;

 } ubaaname[2][3];  // ERROR

+

+vec3 func(in mat3[2] x[3])

+{

+	mat3 a0 = x[2][1];

+    return a0[2];

+}

diff --git a/Test/310implicitSizeArrayError.vert b/Test/310implicitSizeArrayError.vert
index 72c403e..7aa0ee1 100644
--- a/Test/310implicitSizeArrayError.vert
+++ b/Test/310implicitSizeArrayError.vert
@@ -1,5 +1,5 @@
 #version 310 es

-layout (location=0) uniform Block {

+layout (binding=0) uniform Block {

   highp int a[];

 } uni;

 layout (location=0) out highp int o;

diff --git a/Test/310runtimeArray.vert b/Test/310runtimeArray.vert
new file mode 100644
index 0000000..3d7b018
--- /dev/null
+++ b/Test/310runtimeArray.vert
@@ -0,0 +1,18 @@
+#version 310 es
+
+precision highp float;
+layout(location=0) out float o;
+
+struct S  { float f; };
+buffer b1 { S s[]; };
+buffer b2 { S s[]; } b2name;
+buffer b3 { S s[]; } b3name[];
+buffer b4 { S s[]; } b4name[4];
+
+void main()
+{
+  o = s[5].f;
+  o += b2name.s[6].f;
+  o += b3name[3].s[7].f;
+  o += b4name[2].s[8].f;
+}
diff --git a/Test/440.vert b/Test/440.vert
index 2e61f79..4ab6f2e 100644
--- a/Test/440.vert
+++ b/Test/440.vert
@@ -174,6 +174,12 @@
     float f;

 } bbinst10;

 

+layout(xfb_buffer = 3) out;

+layout(xfb_offset = 32) out gl_PerVertex {

+    layout(xfb_buffer = 2) float gl_PointSize; // ERROR, change in xfb_buffer

+    vec4 gl_Position;

+};

+

 int drawParamsBad()

 {

     return gl_BaseVertexARB + gl_BaseInstanceARB + gl_DrawIDARB; // ERROR, extension not requested

diff --git a/Test/450.vert b/Test/450.vert
index 51e9b10..e99a133 100644
--- a/Test/450.vert
+++ b/Test/450.vert
@@ -46,3 +46,11 @@
     allInvocationsEqual(b1);  // ERROR, need 4.6

 }

 ; // ERROR: no extraneous semicolons

+

+layout(location = 0) uniform locBlock {        // ERROR, no location uniform block

+    int a;

+};

+

+layout(location = 0) buffer locBuffBlock {     // ERROR, no location on buffer block

+    int b;

+};

diff --git a/Test/460.frag b/Test/460.frag
index 43a7c3b..23f8eea 100644
--- a/Test/460.frag
+++ b/Test/460.frag
@@ -15,3 +15,18 @@
     b1 = allInvocations(b1);

     b1 = allInvocationsEqual(b1);

 }

+

+void attExtBad()

+{

+    // ERRORs, not enabled

+    [[dependency_length(1+3)]] for (int i = 0; i < 8; ++i) { }
+    [[flatten]]                if (true) { } else { }
+}
+

+#extension GL_EXT_control_flow_attributes : enable

+

+void attExt()

+{

+    [[dependency_length(-3)]] do {  } while(true); // ERROR, not positive

+    [[dependency_length(0)]] do {  } while(true);  // ERROR, not positive
+}
diff --git a/Test/array.frag b/Test/array.frag
index 4ccb00c..63d5f4c 100644
--- a/Test/array.frag
+++ b/Test/array.frag
@@ -104,3 +104,9 @@
 int[] i = int[]();    // ERROR, need constructor arguments
 float emptyA[];

 float b = vec4(emptyA);    // ERROR, array can't be a constructor argument

+uniform sampler2D s2d[];

+

+void foo4()

+{

+    s2d[a];           // ERROR, can't variably index unsized array

+}

diff --git a/Test/baseLegalResults/hlsl.aliasOpaque.frag.out b/Test/baseLegalResults/hlsl.aliasOpaque.frag.out
index 779d5e1..f877db6 100644
--- a/Test/baseLegalResults/hlsl.aliasOpaque.frag.out
+++ b/Test/baseLegalResults/hlsl.aliasOpaque.frag.out
@@ -1,50 +1,46 @@
 hlsl.aliasOpaque.frag
-WARNING: AST will form illegal SPIR-V; need to transform to legalize
 // Module Version 10000
-// Generated by (magic number): 80002
-// Id's are bound by 81
+// Generated by (magic number): 80006
+// Id's are bound by 87
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Fragment 4  "main" 57
+                              EntryPoint Fragment 4  "main" 62
                               ExecutionMode 4 OriginUpperLeft
                               Source HLSL 500
                               Name 4  "main"
-                              Name 37  "gss2"
-                              Name 39  "gss"
-                              Name 43  "gtex"
-                              Name 57  "@entryPointOutput"
-                              Decorate 37(gss2) DescriptorSet 0
-                              Decorate 39(gss) DescriptorSet 0
-                              Decorate 43(gtex) DescriptorSet 0
-                              Decorate 57(@entryPointOutput) Location 0
+                              Name 47  "gss"
+                              Name 51  "gtex"
+                              Name 62  "@entryPointOutput"
+                              Decorate 47(gss) DescriptorSet 0
+                              Decorate 51(gtex) DescriptorSet 0
+                              Decorate 62(@entryPointOutput) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeSampler
-               8:             TypeFloat 32
-              10:             TypeImage 8(float) 2D sampled format:Unknown
-              12:             TypeVector 8(float) 4
-              25:             TypeSampledImage 10
-              27:             TypeVector 8(float) 2
-              28:    8(float) Constant 1045220557
-              29:    8(float) Constant 1050253722
-              30:   27(fvec2) ConstantComposite 28 29
-              36:             TypePointer UniformConstant 6
-        37(gss2):     36(ptr) Variable UniformConstant
-         39(gss):     36(ptr) Variable UniformConstant
-              42:             TypePointer UniformConstant 10
-        43(gtex):     42(ptr) Variable UniformConstant
-              46:    8(float) Constant 1077936128
-              56:             TypePointer Output 12(fvec4)
-57(@entryPointOutput):     56(ptr) Variable Output
+               7:             TypeFloat 32
+               8:             TypeImage 7(float) 2D sampled format:Unknown
+              11:             TypeVector 7(float) 4
+              32:             TypeSampledImage 8
+              34:             TypeVector 7(float) 2
+              35:    7(float) Constant 1045220557
+              36:    7(float) Constant 1050253722
+              37:   34(fvec2) ConstantComposite 35 36
+              43:             TypePointer UniformConstant 6
+         47(gss):     43(ptr) Variable UniformConstant
+              50:             TypePointer UniformConstant 8
+        51(gtex):     50(ptr) Variable UniformConstant
+              54:    7(float) Constant 1077936128
+              61:             TypePointer Output 11(fvec4)
+62(@entryPointOutput):     61(ptr) Variable Output
          4(main):           2 Function None 3
                5:             Label
-              68:           6 Load 39(gss)
-              69:          10 Load 43(gtex)
-              78:          25 SampledImage 69 68
-              79:   12(fvec4) ImageSampleImplicitLod 78 30
-              80:   12(fvec4) VectorTimesScalar 79 46
-                              Store 57(@entryPointOutput) 80
+              70:           6 Load 47(gss)
+              72:           8 Load 51(gtex)
+              84:          32 SampledImage 72 70
+              85:   11(fvec4) ImageSampleImplicitLod 84 37
+              86:   11(fvec4) VectorTimesScalar 85 54
+                              Store 62(@entryPointOutput) 86
                               Return
                               FunctionEnd
diff --git a/Test/baseLegalResults/hlsl.flattenOpaque.frag.out b/Test/baseLegalResults/hlsl.flattenOpaque.frag.out
index 3c7d198..ab9237b 100644
--- a/Test/baseLegalResults/hlsl.flattenOpaque.frag.out
+++ b/Test/baseLegalResults/hlsl.flattenOpaque.frag.out
@@ -1,65 +1,65 @@
 hlsl.flattenOpaque.frag
 // Module Version 10000
-// Generated by (magic number): 80002
-// Id's are bound by 144
+// Generated by (magic number): 80006
+// Id's are bound by 185
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Fragment 4  "main" 97
+                              EntryPoint Fragment 4  "main" 120
                               ExecutionMode 4 OriginUpperLeft
                               Source HLSL 500
                               Name 4  "main"
                               Name 38  "tex"
-                              Name 70  "s.s2D"
-                              Name 79  "s2.s2D"
-                              Name 80  "s2.tex"
-                              Name 97  "@entryPointOutput"
+                              Name 82  "s.s2D"
+                              Name 97  "s2.s2D"
+                              Name 100  "s2.tex"
+                              Name 120  "@entryPointOutput"
                               Decorate 38(tex) DescriptorSet 0
-                              Decorate 70(s.s2D) DescriptorSet 0
-                              Decorate 79(s2.s2D) DescriptorSet 0
-                              Decorate 80(s2.tex) DescriptorSet 0
-                              Decorate 97(@entryPointOutput) Location 0
+                              Decorate 82(s.s2D) DescriptorSet 0
+                              Decorate 97(s2.s2D) DescriptorSet 0
+                              Decorate 100(s2.tex) DescriptorSet 0
+                              Decorate 120(@entryPointOutput) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeSampler
-               8:             TypeFloat 32
-               9:             TypeVector 8(float) 4
-              14:             TypeVector 8(float) 2
-              21:             TypeImage 8(float) 2D sampled format:Unknown
-              37:             TypePointer UniformConstant 21
+               9:             TypeFloat 32
+              10:             TypeVector 9(float) 4
+              15:             TypeVector 9(float) 2
+              22:             TypeImage 9(float) 2D sampled format:Unknown
+              37:             TypePointer UniformConstant 22
          38(tex):     37(ptr) Variable UniformConstant
-              41:             TypeSampledImage 21
-              43:    8(float) Constant 1045220557
-              44:    8(float) Constant 1050253722
-              45:   14(fvec2) ConstantComposite 43 44
-              69:             TypePointer UniformConstant 6
-       70(s.s2D):     69(ptr) Variable UniformConstant
-      79(s2.s2D):     69(ptr) Variable UniformConstant
-      80(s2.tex):     37(ptr) Variable UniformConstant
-              96:             TypePointer Output 9(fvec4)
-97(@entryPointOutput):     96(ptr) Variable Output
+              45:             TypeSampledImage 22
+              47:    9(float) Constant 1045220557
+              48:    9(float) Constant 1050253722
+              49:   15(fvec2) ConstantComposite 47 48
+              81:             TypePointer UniformConstant 6
+       82(s.s2D):     81(ptr) Variable UniformConstant
+      97(s2.s2D):     81(ptr) Variable UniformConstant
+     100(s2.tex):     37(ptr) Variable UniformConstant
+             119:             TypePointer Output 10(fvec4)
+120(@entryPointOutput):    119(ptr) Variable Output
          4(main):           2 Function None 3
                5:             Label
-             109:           6 Load 70(s.s2D)
-             123:          21 Load 38(tex)
-             125:          41 SampledImage 123 109
-             126:    9(fvec4) ImageSampleImplicitLod 125 45
-             111:           6 Load 70(s.s2D)
-             128:          21 Load 38(tex)
-             130:          41 SampledImage 128 111
-             132:    9(fvec4) ImageSampleImplicitLod 130 45
-             113:    9(fvec4) FAdd 126 132
-             114:           6 Load 79(s2.s2D)
-             115:          21 Load 80(s2.tex)
-             136:          41 SampledImage 115 114
-             137:    9(fvec4) ImageSampleImplicitLod 136 45
-             117:    9(fvec4) FAdd 113 137
-             118:           6 Load 79(s2.s2D)
-             119:          21 Load 80(s2.tex)
-             141:          41 SampledImage 119 118
-             143:    9(fvec4) ImageSampleImplicitLod 141 45
-             121:    9(fvec4) FAdd 117 143
-                              Store 97(@entryPointOutput) 121
+             134:           6 Load 82(s.s2D)
+             158:          22 Load 38(tex)
+             161:          45 SampledImage 158 134
+             162:   10(fvec4) ImageSampleImplicitLod 161 49
+             138:           6 Load 82(s.s2D)
+             164:          22 Load 38(tex)
+             167:          45 SampledImage 164 138
+             169:   10(fvec4) ImageSampleImplicitLod 167 49
+             142:   10(fvec4) FAdd 162 169
+             143:           6 Load 97(s2.s2D)
+             145:          22 Load 100(s2.tex)
+             175:          45 SampledImage 145 143
+             176:   10(fvec4) ImageSampleImplicitLod 175 49
+             149:   10(fvec4) FAdd 142 176
+             150:           6 Load 97(s2.s2D)
+             152:          22 Load 100(s2.tex)
+             182:          45 SampledImage 152 150
+             184:   10(fvec4) ImageSampleImplicitLod 182 49
+             156:   10(fvec4) FAdd 149 184
+                              Store 120(@entryPointOutput) 156
                               Return
                               FunctionEnd
diff --git a/Test/baseLegalResults/hlsl.flattenOpaqueInit.vert.out b/Test/baseLegalResults/hlsl.flattenOpaqueInit.vert.out
index 4aef874..3d0a0bd 100644
--- a/Test/baseLegalResults/hlsl.flattenOpaqueInit.vert.out
+++ b/Test/baseLegalResults/hlsl.flattenOpaqueInit.vert.out
@@ -1,49 +1,52 @@
 hlsl.flattenOpaqueInit.vert
-WARNING: AST will form illegal SPIR-V; need to transform to legalize
 // Module Version 10000
-// Generated by (magic number): 80002
-// Id's are bound by 125
+// Generated by (magic number): 80006
+// Id's are bound by 134
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Vertex 4  "main" 82
+                              EntryPoint Vertex 4  "main" 80
                               Source HLSL 500
                               Name 4  "main"
-                              Name 17  "FxaaTex"
-                              MemberName 17(FxaaTex) 0  "smpl"
-                              MemberName 17(FxaaTex) 1  "tex"
-                              Name 38  "g_tInputTexture_sampler"
-                              Name 42  "g_tInputTexture"
-                              Name 82  "@entryPointOutput"
-                              Decorate 38(g_tInputTexture_sampler) DescriptorSet 0
-                              Decorate 42(g_tInputTexture) DescriptorSet 0
-                              Decorate 82(@entryPointOutput) Location 0
+                              Name 43  "g_tInputTexture_sampler"
+                              Name 47  "g_tInputTexture"
+                              Name 80  "@entryPointOutput"
+                              Decorate 43(g_tInputTexture_sampler) DescriptorSet 0
+                              Decorate 47(g_tInputTexture) DescriptorSet 0
+                              Decorate 80(@entryPointOutput) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeSampler
-               8:             TypeFloat 32
-               9:             TypeImage 8(float) 2D sampled format:Unknown
-              11:             TypeVector 8(float) 4
-     17(FxaaTex):             TypeStruct 6 9
-              26:             TypeSampledImage 9
-              28:             TypeVector 8(float) 2
-              29:    8(float) Constant 1050253722
-              30:    8(float) Constant 1053609165
-              31:   28(fvec2) ConstantComposite 29 30
-              32:    8(float) Constant 0
-              37:             TypePointer UniformConstant 6
-38(g_tInputTexture_sampler):     37(ptr) Variable UniformConstant
-              41:             TypePointer UniformConstant 9
-42(g_tInputTexture):     41(ptr) Variable UniformConstant
-              81:             TypePointer Output 11(fvec4)
-82(@entryPointOutput):     81(ptr) Variable Output
+               7:             TypeFloat 32
+               8:             TypeImage 7(float) 2D sampled format:Unknown
+              11:             TypeVector 7(float) 4
+              31:             TypeSampledImage 8
+              33:             TypeVector 7(float) 2
+              34:    7(float) Constant 1050253722
+              35:    7(float) Constant 1053609165
+              36:   33(fvec2) ConstantComposite 34 35
+              37:    7(float) Constant 0
+              42:             TypePointer UniformConstant 6
+43(g_tInputTexture_sampler):     42(ptr) Variable UniformConstant
+              46:             TypePointer UniformConstant 8
+47(g_tInputTexture):     46(ptr) Variable UniformConstant
+              79:             TypePointer Output 11(fvec4)
+80(@entryPointOutput):     79(ptr) Variable Output
          4(main):           2 Function None 3
                5:             Label
-              96:           6 Load 38(g_tInputTexture_sampler)
-              97:           9 Load 42(g_tInputTexture)
-             123:          26 SampledImage 97 96
-             124:   11(fvec4) ImageSampleExplicitLod 123 31 Lod 32
-                              Store 82(@entryPointOutput) 124
+              90:           6 Load 43(g_tInputTexture_sampler)
+              91:           8 Load 47(g_tInputTexture)
+             111:          31 SampledImage 91 90
+             112:   11(fvec4) ImageSampleExplicitLod 111 36 Lod 37
+             115:           6 Load 43(g_tInputTexture_sampler)
+             117:           8 Load 47(g_tInputTexture)
+             125:          31 SampledImage 117 115
+             126:   11(fvec4) ImageSampleExplicitLod 125 36 Lod 37
+              99:   11(fvec4) FAdd 112 126
+             132:          31 SampledImage 91 90
+             133:   11(fvec4) ImageSampleExplicitLod 132 36 Lod 37
+             104:   11(fvec4) FAdd 99 133
+                              Store 80(@entryPointOutput) 104
                               Return
                               FunctionEnd
diff --git a/Test/baseLegalResults/hlsl.flattenOpaqueInitMix.vert.out b/Test/baseLegalResults/hlsl.flattenOpaqueInitMix.vert.out
index 0b05615..9793d57 100644
--- a/Test/baseLegalResults/hlsl.flattenOpaqueInitMix.vert.out
+++ b/Test/baseLegalResults/hlsl.flattenOpaqueInitMix.vert.out
@@ -1,49 +1,43 @@
 hlsl.flattenOpaqueInitMix.vert
-WARNING: AST will form illegal SPIR-V; need to transform to legalize
 // Module Version 10000
-// Generated by (magic number): 80002
-// Id's are bound by 100
+// Generated by (magic number): 80006
+// Id's are bound by 97
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Vertex 4  "main" 68
+                              EntryPoint Vertex 4  "main" 57
                               Source HLSL 500
                               Name 4  "main"
-                              Name 34  "FxaaTex"
-                              MemberName 34(FxaaTex) 0  "smpl"
-                              MemberName 34(FxaaTex) 1  "tex"
-                              MemberName 34(FxaaTex) 2  "f"
-                              Name 38  "g_tInputTexture_sampler"
-                              Name 41  "g_tInputTexture"
-                              Name 68  "@entryPointOutput"
-                              Decorate 38(g_tInputTexture_sampler) DescriptorSet 0
-                              Decorate 41(g_tInputTexture) DescriptorSet 0
-                              Decorate 68(@entryPointOutput) Location 0
+                              Name 44  "g_tInputTexture_sampler"
+                              Name 47  "g_tInputTexture"
+                              Name 57  "@entryPointOutput"
+                              Decorate 44(g_tInputTexture_sampler) DescriptorSet 0
+                              Decorate 47(g_tInputTexture) DescriptorSet 0
+                              Decorate 57(@entryPointOutput) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeSampler
-               8:             TypeFloat 32
-               9:             TypeImage 8(float) 2D sampled format:Unknown
-              12:             TypeVector 8(float) 4
-              24:             TypeSampledImage 9
-              28:             TypeVector 8(float) 2
-              30:    8(float) Constant 0
-     34(FxaaTex):             TypeStruct 6 9 8(float)
-              37:             TypePointer UniformConstant 6
-38(g_tInputTexture_sampler):     37(ptr) Variable UniformConstant
-              40:             TypePointer UniformConstant 9
-41(g_tInputTexture):     40(ptr) Variable UniformConstant
-              43:    8(float) Constant 1056964608
-              67:             TypePointer Output 12(fvec4)
-68(@entryPointOutput):     67(ptr) Variable Output
+               7:             TypeFloat 32
+               8:             TypeImage 7(float) 2D sampled format:Unknown
+              11:             TypeVector 7(float) 4
+              28:             TypeSampledImage 8
+              36:             TypeVector 7(float) 2
+              38:    7(float) Constant 0
+              43:             TypePointer UniformConstant 6
+44(g_tInputTexture_sampler):     43(ptr) Variable UniformConstant
+              46:             TypePointer UniformConstant 8
+47(g_tInputTexture):     46(ptr) Variable UniformConstant
+              49:    7(float) Constant 1056964608
+              56:             TypePointer Output 11(fvec4)
+57(@entryPointOutput):     56(ptr) Variable Output
+              96:   36(fvec2) ConstantComposite 49 49
          4(main):           2 Function None 3
                5:             Label
-              79:           6 Load 38(g_tInputTexture_sampler)
-              80:           9 Load 41(g_tInputTexture)
-              95:          24 SampledImage 80 79
-              98:   28(fvec2) CompositeConstruct 43 43
-              99:   12(fvec4) ImageSampleExplicitLod 95 98 Lod 30
-                              Store 68(@entryPointOutput) 99
+              63:           6 Load 44(g_tInputTexture_sampler)
+              64:           8 Load 47(g_tInputTexture)
+              73:          28 SampledImage 64 63
+              79:   11(fvec4) ImageSampleExplicitLod 73 96 Lod 38
+                              Store 57(@entryPointOutput) 79
                               Return
                               FunctionEnd
diff --git a/Test/baseLegalResults/hlsl.flattenSubset.frag.out b/Test/baseLegalResults/hlsl.flattenSubset.frag.out
index 20aedec..617c719 100755
--- a/Test/baseLegalResults/hlsl.flattenSubset.frag.out
+++ b/Test/baseLegalResults/hlsl.flattenSubset.frag.out
@@ -1,48 +1,47 @@
 hlsl.flattenSubset.frag
-WARNING: AST will form illegal SPIR-V; need to transform to legalize
 // Module Version 10000
-// Generated by (magic number): 80002
-// Id's are bound by 85
+// Generated by (magic number): 80006
+// Id's are bound by 66
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Fragment 4  "main" 54 57
+                              EntryPoint Fragment 4  "main" 47 50
                               ExecutionMode 4 OriginUpperLeft
                               Source HLSL 500
                               Name 4  "main"
-                              Name 17  "samp"
-                              Name 41  "tex"
-                              Name 54  "vpos"
-                              Name 57  "@entryPointOutput"
-                              Decorate 17(samp) DescriptorSet 0
-                              Decorate 41(tex) DescriptorSet 0
-                              Decorate 54(vpos) Location 0
-                              Decorate 57(@entryPointOutput) Location 0
+                              Name 21  "samp"
+                              Name 33  "tex"
+                              Name 47  "vpos"
+                              Name 50  "@entryPointOutput"
+                              Decorate 21(samp) DescriptorSet 0
+                              Decorate 33(tex) DescriptorSet 0
+                              Decorate 47(vpos) Location 0
+                              Decorate 50(@entryPointOutput) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
                7:             TypeVector 6(float) 4
               13:             TypeSampler
-              16:             TypePointer UniformConstant 13
-        17(samp):     16(ptr) Variable UniformConstant
-              39:             TypeImage 6(float) 2D sampled format:Unknown
-              40:             TypePointer UniformConstant 39
-         41(tex):     40(ptr) Variable UniformConstant
-              44:             TypeSampledImage 39
-              46:             TypeVector 6(float) 2
-              47:    6(float) Constant 1056964608
-              48:   46(fvec2) ConstantComposite 47 47
-              53:             TypePointer Input 7(fvec4)
-        54(vpos):     53(ptr) Variable Input
-              56:             TypePointer Output 7(fvec4)
-57(@entryPointOutput):     56(ptr) Variable Output
+              20:             TypePointer UniformConstant 13
+        21(samp):     20(ptr) Variable UniformConstant
+              31:             TypeImage 6(float) 2D sampled format:Unknown
+              32:             TypePointer UniformConstant 31
+         33(tex):     32(ptr) Variable UniformConstant
+              37:             TypeSampledImage 31
+              39:             TypeVector 6(float) 2
+              40:    6(float) Constant 1056964608
+              41:   39(fvec2) ConstantComposite 40 40
+              46:             TypePointer Input 7(fvec4)
+        47(vpos):     46(ptr) Variable Input
+              49:             TypePointer Output 7(fvec4)
+50(@entryPointOutput):     49(ptr) Variable Output
          4(main):           2 Function None 3
                5:             Label
-              74:          13 Load 17(samp)
-              81:          39 Load 41(tex)
-              83:          44 SampledImage 81 74
-              84:    7(fvec4) ImageSampleImplicitLod 83 48
-                              Store 57(@entryPointOutput) 84
+              57:          13 Load 21(samp)
+              61:          31 Load 33(tex)
+              64:          37 SampledImage 61 57
+              65:    7(fvec4) ImageSampleImplicitLod 64 41
+                              Store 50(@entryPointOutput) 65
                               Return
                               FunctionEnd
diff --git a/Test/baseLegalResults/hlsl.flattenSubset2.frag.out b/Test/baseLegalResults/hlsl.flattenSubset2.frag.out
new file mode 100755
index 0000000..ef661ba
--- /dev/null
+++ b/Test/baseLegalResults/hlsl.flattenSubset2.frag.out
@@ -0,0 +1,31 @@
+hlsl.flattenSubset2.frag
+// Module Version 10000
+// Generated by (magic number): 80006
+// Id's are bound by 53
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 49 52
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 49  "vpos"
+                              Name 52  "@entryPointOutput"
+                              Decorate 49(vpos) Location 0
+                              Decorate 52(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+              43:    6(float) Constant 0
+              44:    7(fvec4) ConstantComposite 43 43 43 43
+              48:             TypePointer Input 7(fvec4)
+        49(vpos):     48(ptr) Variable Input
+              51:             TypePointer Output 7(fvec4)
+52(@entryPointOutput):     51(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+                              Store 52(@entryPointOutput) 44
+                              Return
+                              FunctionEnd
diff --git a/Test/baseLegalResults/hlsl.partialFlattenLocal.vert.out b/Test/baseLegalResults/hlsl.partialFlattenLocal.vert.out
new file mode 100755
index 0000000..8bf9614
--- /dev/null
+++ b/Test/baseLegalResults/hlsl.partialFlattenLocal.vert.out
@@ -0,0 +1,81 @@
+hlsl.partialFlattenLocal.vert
+// Module Version 10000
+// Generated by (magic number): 80006
+// Id's are bound by 169
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 83 86
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 83  "pos"
+                              Name 86  "@entryPointOutput"
+                              Decorate 83(pos) Location 0
+                              Decorate 86(@entryPointOutput) BuiltIn Position
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+              14:             TypeVector 6(float) 3
+              15:             TypeInt 32 0
+              16:     15(int) Constant 3
+              17:             TypeArray 14(fvec3) 16
+              18:             TypeVector 6(float) 2
+              19:     15(int) Constant 2
+              20:             TypeArray 18(fvec2) 19
+              21:             TypeInt 32 1
+              25:     21(int) Constant 0
+              31:     21(int) Constant 1
+              32:    6(float) Constant 0
+              33:   14(fvec3) ConstantComposite 32 32 32
+              34:             TypePointer Function 14(fvec3)
+              37:    6(float) Constant 1065353216
+              38:   18(fvec2) ConstantComposite 32 37
+              39:             TypePointer Function 18(fvec2)
+              54:             TypeBool
+              82:             TypePointer Input 7(fvec4)
+         83(pos):     82(ptr) Variable Input
+              85:             TypePointer Output 7(fvec4)
+86(@entryPointOutput):     85(ptr) Variable Output
+             130:             TypePointer Function 17
+             132:             TypePointer Function 20
+         4(main):           2 Function None 3
+               5:             Label
+             133:    132(ptr) Variable Function
+             131:    130(ptr) Variable Function
+              84:    7(fvec4) Load 83(pos)
+             136:     34(ptr) AccessChain 131 25
+                              Store 136 33
+             137:     39(ptr) AccessChain 133 25
+                              Store 137 38
+                              Branch 100
+             100:             Label
+             168:     21(int) Phi 25 5 119 106
+             105:    54(bool) SLessThan 168 31
+                              LoopMerge 101 106 None
+                              BranchConditional 105 106 101
+             106:               Label
+             138:     39(ptr)   AccessChain 133 168
+             110:   18(fvec2)   Load 138
+             139:     34(ptr)   AccessChain 131 168
+             112:   14(fvec3)   Load 139
+             113:   18(fvec2)   VectorShuffle 112 112 0 1
+             114:   18(fvec2)   FAdd 113 110
+             140:     34(ptr)   AccessChain 131 168
+             116:   14(fvec3)   Load 140
+             117:   14(fvec3)   VectorShuffle 116 114 3 4 2
+                                Store 140 117
+             119:     21(int)   IAdd 168 31
+                                Branch 100
+             101:             Label
+             142:          17 Load 131
+             161:   14(fvec3) CompositeExtract 142 0
+             124:    6(float) CompositeExtract 161 0
+             125:    6(float) CompositeExtract 161 1
+             126:    6(float) CompositeExtract 161 2
+             127:    7(fvec4) CompositeConstruct 124 125 126 32
+             128:    7(fvec4) FAdd 84 127
+                              Store 86(@entryPointOutput) 128
+                              Return
+                              FunctionEnd
diff --git a/Test/baseLegalResults/hlsl.partialFlattenMixed.vert.out b/Test/baseLegalResults/hlsl.partialFlattenMixed.vert.out
new file mode 100755
index 0000000..7e36eb9
--- /dev/null
+++ b/Test/baseLegalResults/hlsl.partialFlattenMixed.vert.out
@@ -0,0 +1,29 @@
+hlsl.partialFlattenMixed.vert
+// Module Version 10000
+// Generated by (magic number): 80006
+// Id's are bound by 36
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 32 35
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 32  "pos"
+                              Name 35  "@entryPointOutput"
+                              Decorate 32(pos) Location 0
+                              Decorate 35(@entryPointOutput) BuiltIn Position
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+              31:             TypePointer Input 7(fvec4)
+         32(pos):     31(ptr) Variable Input
+              34:             TypePointer Output 7(fvec4)
+35(@entryPointOutput):     34(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              33:    7(fvec4) Load 32(pos)
+                              Store 35(@entryPointOutput) 33
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/100.frag.out b/Test/baseResults/100.frag.out
index 3464dcb..5e702e8 100644
--- a/Test/baseResults/100.frag.out
+++ b/Test/baseResults/100.frag.out
@@ -395,7 +395,7 @@
 0:?     'v' ( smooth in 3-element array of mediump 4-component vector of float)
 0:?     'f' ( invariant global mediump float)
 0:?     'anon@0' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump int x})
-0:?     'fa' ( global implicitly-sized array of mediump float)
+0:?     'fa' ( global unsized 1-element array of mediump float)
 0:?     'f13' ( invariant global mediump float)
 0:?     'fi' ( invariant temp mediump float)
 0:?     'av' ( invariant smooth in mediump 4-component vector of float)
diff --git a/Test/baseResults/120.frag.out b/Test/baseResults/120.frag.out
index b516724..e63c001 100644
--- a/Test/baseResults/120.frag.out
+++ b/Test/baseResults/120.frag.out
@@ -19,7 +19,7 @@
 ERROR: 0:83: 'xyxyx' : vector swizzle too long 
 ERROR: 0:84: 'z' : vector swizzle selection out of range 
 ERROR: 0:85: 'assign' :  l-value required 
-ERROR: 0:91: 'int' : overloaded functions must have the same return type 
+ERROR: 0:91: 'main' : overloaded functions must have the same return type 
 ERROR: 0:91: 'main' : function already has a body 
 ERROR: 0:91: 'int' :  entry point cannot return a value
 ERROR: 0:92: 'main' : function cannot take any parameter(s) 
@@ -52,8 +52,13 @@
 ERROR: 0:212: 'sampler2DRect' : Reserved word. 
 ERROR: 0:244: ':' :  wrong operand types: no operation ':' exists that takes a left-hand operand of type ' global void' and a right operand of type ' const int' (or there is no acceptable conversion)
 ERROR: 0:245: ':' :  wrong operand types: no operation ':' exists that takes a left-hand operand of type ' const int' and a right operand of type ' global void' (or there is no acceptable conversion)
+ERROR: 0:248: 'explicit types' : required extension not requested: Possible extensions include:
+GL_AMD_gpu_shader_half_float
+GL_KHX_shader_explicit_arithmetic_types
+GL_KHX_shader_explicit_arithmetic_types_float16
+ERROR: 0:248: 'half floating-point suffix' : not supported with this profile: none
 ERROR: 0:248: '' :  syntax error, unexpected IDENTIFIER, expecting COMMA or SEMICOLON
-ERROR: 54 compilation errors.  No code generated.
+ERROR: 56 compilation errors.  No code generated.
 
 
 Shader version: 120
diff --git a/Test/baseResults/120.vert.out b/Test/baseResults/120.vert.out
index c89be98..5a91ed6 100644
--- a/Test/baseResults/120.vert.out
+++ b/Test/baseResults/120.vert.out
@@ -19,6 +19,7 @@
 ERROR: 0:35: 'arrays of arrays' : not supported with this profile: none
 ERROR: 0:36: 'arrays of arrays' : not supported with this profile: none
 ERROR: 0:37: 'arrays of arrays' : not supported with this profile: none
+ERROR: 0:37: 'arrays of arrays' : not supported with this profile: none
 ERROR: 0:38: 'arrays of arrays' : not supported with this profile: none
 ERROR: 0:39: 'arrays of arrays' : not supported with this profile: none
 ERROR: 0:40: 'arrays of arrays' : not supported with this profile: none
@@ -34,7 +35,7 @@
 ERROR: 0:52: 'arrays of arrays' : not supported with this profile: none
 ERROR: 0:53: 'arrays of arrays' : not supported with this profile: none
 ERROR: 0:56: 'out' : overloaded functions must have the same parameter storage qualifiers for argument 1
-ERROR: 0:57: 'float' : overloaded functions must have the same return type 
+ERROR: 0:57: 'overloadA' : overloaded functions must have the same return type 
 ERROR: 0:87: 'overloadC' : no matching overloaded function found 
 ERROR: 0:90: 'overloadC' : no matching overloaded function found 
 ERROR: 0:95: 'overloadD' : ambiguous function signature match: multiple signatures match under implicit type conversion 
@@ -78,7 +79,7 @@
 ERROR: 0:195: 'gl_ModelViewMatrix' : identifiers starting with "gl_" are reserved 
 ERROR: 0:200: 'token pasting (##)' : not supported for this version or the enabled extensions 
 ERROR: 0:203: 'token pasting (##)' : not supported for this version or the enabled extensions 
-ERROR: 79 compilation errors.  No code generated.
+ERROR: 80 compilation errors.  No code generated.
 
 
 Shader version: 120
diff --git a/Test/baseResults/130.frag.out b/Test/baseResults/130.frag.out
index c1c479a..81d055b 100644
--- a/Test/baseResults/130.frag.out
+++ b/Test/baseResults/130.frag.out
@@ -49,7 +49,7 @@
 0:18        move second child to first child ( temp float)
 0:18          'clip' ( temp float)
 0:18          direct index ( smooth temp float ClipDistance)
-0:18            'gl_ClipDistance' ( smooth in implicitly-sized array of float ClipDistance)
+0:18            'gl_ClipDistance' ( smooth in unsized 4-element array of float ClipDistance)
 0:18            Constant:
 0:18              3 (const int)
 0:23  Function Definition: foo( ( global void)
@@ -381,7 +381,7 @@
 0:?     'fflat' ( flat in float)
 0:?     'fsmooth' ( smooth in float)
 0:?     'fnop' ( noperspective in float)
-0:?     'gl_ClipDistance' ( smooth in implicitly-sized array of float ClipDistance)
+0:?     'gl_ClipDistance' ( smooth in unsized 4-element array of float ClipDistance)
 0:?     'sampC' ( uniform samplerCube)
 0:?     'gl_Color' ( in 4-component vector of float Color)
 0:?     'samp2D' ( uniform sampler2D)
diff --git a/Test/baseResults/130.vert.out b/Test/baseResults/130.vert.out
index 7ec82ad..e38043c 100644
--- a/Test/baseResults/130.vert.out
+++ b/Test/baseResults/130.vert.out
@@ -113,7 +113,7 @@
 0:45          'gl_VertexID' ( gl_VertexId int VertexId)
 0:46      move second child to first child ( temp float)
 0:46        direct index ( smooth temp float ClipDistance)
-0:46          'gl_ClipDistance' ( smooth out implicitly-sized array of float ClipDistance)
+0:46          'gl_ClipDistance' ( smooth out unsized 2-element array of float ClipDistance)
 0:46          Constant:
 0:46            1 (const int)
 0:46        Constant:
@@ -132,7 +132,7 @@
 0:66        'gl_DepthRange' ( uniform structure{ global float near,  global float far,  global float diff})
 0:66        Constant:
 0:66          1 (const int)
-0:67      'gl_TexCoord' ( smooth out implicitly-sized array of 4-component vector of float TexCoord)
+0:67      'gl_TexCoord' ( smooth out unsized 1-element array of 4-component vector of float TexCoord)
 0:68      'gl_FogFragCoord' ( smooth out float FogFragCoord)
 0:69      'gl_FrontColor' ( smooth out 4-component vector of float FrontColor)
 0:?   Linker Objects
@@ -145,8 +145,8 @@
 0:?     'c3D' ( in 3-component vector of float)
 0:?     'c4D' ( smooth temp 4-component vector of float)
 0:?     'v4' ( uniform 4-component vector of float)
-0:?     'gl_ClipDistance' ( smooth out implicitly-sized array of float ClipDistance)
-0:?     'gl_TexCoord' ( smooth out implicitly-sized array of 4-component vector of float TexCoord)
+0:?     'gl_ClipDistance' ( smooth out unsized 2-element array of float ClipDistance)
+0:?     'gl_TexCoord' ( smooth out unsized 1-element array of 4-component vector of float TexCoord)
 0:?     'abcdef' ( global int)
 0:?     'qrstuv' ( global int)
 0:?     'gl_VertexID' ( gl_VertexId int VertexId)
diff --git a/Test/baseResults/140.vert.out b/Test/baseResults/140.vert.out
index 975c932..020afd0 100644
--- a/Test/baseResults/140.vert.out
+++ b/Test/baseResults/140.vert.out
@@ -52,7 +52,7 @@
 0:17        'gl_DepthRange' ( uniform structure{ global float near,  global float far,  global float diff})
 0:17        Constant:
 0:17          1 (const int)
-0:18      'gl_TexCoord' ( smooth out implicitly-sized array of 4-component vector of float TexCoord)
+0:18      'gl_TexCoord' ( smooth out unsized 1-element array of 4-component vector of float TexCoord)
 0:19      'gl_FogFragCoord' ( smooth out float FogFragCoord)
 0:20      'gl_FrontColor' ( smooth out 4-component vector of float FrontColor)
 0:48  Function Definition: foo( ( global void)
@@ -133,7 +133,7 @@
 0:?   Linker Objects
 0:?     'sbuf' ( uniform isamplerBuffer)
 0:?     'anon@0' (layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform int anonMem})
-0:?     'gl_TexCoord' ( smooth out implicitly-sized array of 4-component vector of float TexCoord)
+0:?     'gl_TexCoord' ( smooth out unsized 1-element array of 4-component vector of float TexCoord)
 0:?     'gl_Position' ( smooth out 4-component vector of float)
 0:?     'locBad' (layout( location=9) in 4-component vector of float)
 0:?     'loc' (layout( location=9) in 4-component vector of float)
diff --git a/Test/baseResults/150.geom.out b/Test/baseResults/150.geom.out
index e3a78c9..92b8e1a 100644
--- a/Test/baseResults/150.geom.out
+++ b/Test/baseResults/150.geom.out
@@ -67,16 +67,16 @@
 0:32            0 (const int)
 0:33      move second child to first child ( temp float)
 0:33        direct index (layout( stream=0) temp float ClipDistance)
-0:33          gl_ClipDistance: direct index for structure (layout( stream=0) out implicitly-sized array of float ClipDistance)
-0:33            'anon@1' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:33          gl_ClipDistance: direct index for structure (layout( stream=0) out unsized 4-element array of float ClipDistance)
+0:33            'anon@1' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out unsized 4-element array of float ClipDistance gl_ClipDistance})
 0:33            Constant:
 0:33              2 (const uint)
 0:33          Constant:
 0:33            3 (const int)
 0:33        direct index ( temp float ClipDistance)
-0:33          gl_ClipDistance: direct index for structure ( in implicitly-sized array of float ClipDistance)
-0:33            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:33              'gl_in' ( in 4-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:33          gl_ClipDistance: direct index for structure ( in unsized 3-element array of float ClipDistance)
+0:33            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:33              'gl_in' ( in 4-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:33              Constant:
 0:33                1 (const int)
 0:33            Constant:
@@ -85,24 +85,24 @@
 0:33            2 (const int)
 0:34      move second child to first child ( temp 4-component vector of float)
 0:34        gl_Position: direct index for structure (layout( stream=0) gl_Position 4-component vector of float Position)
-0:34          'anon@1' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:34          'anon@1' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out unsized 4-element array of float ClipDistance gl_ClipDistance})
 0:34          Constant:
 0:34            0 (const uint)
 0:34        gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:34          direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:34            'gl_in' ( in 4-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:34          direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:34            'gl_in' ( in 4-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:34            Constant:
 0:34              0 (const int)
 0:34          Constant:
 0:34            0 (const int)
 0:35      move second child to first child ( temp float)
 0:35        gl_PointSize: direct index for structure (layout( stream=0) gl_PointSize float PointSize)
-0:35          'anon@1' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:35          'anon@1' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out unsized 4-element array of float ClipDistance gl_ClipDistance})
 0:35          Constant:
 0:35            1 (const uint)
 0:35        gl_PointSize: direct index for structure ( in float PointSize)
-0:35          direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:35            'gl_in' ( in 4-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:35          direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:35            'gl_in' ( in 4-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:35            Constant:
 0:35              3 (const int)
 0:35          Constant:
@@ -151,8 +151,8 @@
 0:?     'fromV' ( in 4-element array of block{ in 3-component vector of float color})
 0:?     'toF' (layout( stream=0) out block{layout( stream=0) out 3-component vector of float color})
 0:?     'anon@0' (layout( stream=0) out block{layout( stream=0) out 3-component vector of float color})
-0:?     'anon@1' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:?     'gl_in' ( in 4-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'anon@1' (layout( stream=0) out block{layout( stream=0) gl_Position 4-component vector of float Position gl_Position, layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out unsized 4-element array of float ClipDistance gl_ClipDistance})
+0:?     'gl_in' ( in 4-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:?     'ov0' (layout( stream=0) out 4-component vector of float)
 0:?     'ov4' (layout( stream=4) out 4-component vector of float)
 0:?     'o1v0' (layout( stream=0) out 4-component vector of float)
diff --git a/Test/baseResults/150.tesc.out b/Test/baseResults/150.tesc.out
index 25e44ed..d237ee4 100644
--- a/Test/baseResults/150.tesc.out
+++ b/Test/baseResults/150.tesc.out
@@ -16,8 +16,8 @@
 0:20        move second child to first child ( temp 4-component vector of float)
 0:20          'p' ( temp 4-component vector of float)
 0:20          gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:20            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:20              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:20            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:20              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:20              Constant:
 0:20                1 (const int)
 0:20            Constant:
@@ -26,8 +26,8 @@
 0:21        move second child to first child ( temp float)
 0:21          'ps' ( temp float)
 0:21          gl_PointSize: direct index for structure ( in float PointSize)
-0:21            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:21              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:21            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:21              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:21              Constant:
 0:21                1 (const int)
 0:21            Constant:
@@ -36,9 +36,9 @@
 0:22        move second child to first child ( temp float)
 0:22          'cd' ( temp float)
 0:22          direct index ( temp float ClipDistance)
-0:22            gl_ClipDistance: direct index for structure ( in implicitly-sized array of float ClipDistance)
-0:22              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:22                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:22            gl_ClipDistance: direct index for structure ( in unsized 3-element array of float ClipDistance)
+0:22              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:22                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:22                Constant:
 0:22                  1 (const int)
 0:22              Constant:
@@ -59,25 +59,25 @@
 0:26          'gl_InvocationID' ( in int InvocationID)
 0:28      move second child to first child ( temp 4-component vector of float)
 0:28        gl_Position: direct index for structure ( out 4-component vector of float Position)
-0:28          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:28            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:28          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:28            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:28            'gl_InvocationID' ( in int InvocationID)
 0:28          Constant:
 0:28            0 (const int)
 0:28        'p' ( temp 4-component vector of float)
 0:29      move second child to first child ( temp float)
 0:29        gl_PointSize: direct index for structure ( out float PointSize)
-0:29          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:29            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:29          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:29            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:29            'gl_InvocationID' ( in int InvocationID)
 0:29          Constant:
 0:29            1 (const int)
 0:29        'ps' ( temp float)
 0:30      move second child to first child ( temp float)
 0:30        direct index ( temp float ClipDistance)
-0:30          gl_ClipDistance: direct index for structure ( out implicitly-sized array of float ClipDistance)
-0:30            indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:30              'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:30          gl_ClipDistance: direct index for structure ( out unsized 2-element array of float ClipDistance)
+0:30            indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:30              'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:30              'gl_InvocationID' ( in int InvocationID)
 0:30            Constant:
 0:30              2 (const int)
@@ -99,7 +99,7 @@
 0:33        Constant:
 0:33          1.300000
 0:?   Linker Objects
-0:?     'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:?     'outa' ( global 4-element array of int)
 0:?     'patchOut' ( patch out 4-component vector of float)
 
@@ -129,8 +129,8 @@
 0:22        move second child to first child ( temp 4-component vector of float)
 0:22          'p' ( temp 4-component vector of float)
 0:22          gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:22            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:22              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:22            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:22              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:22              Constant:
 0:22                1 (const int)
 0:22            Constant:
@@ -139,8 +139,8 @@
 0:23        move second child to first child ( temp float)
 0:23          'ps' ( temp float)
 0:23          gl_PointSize: direct index for structure ( in float PointSize)
-0:23            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:23              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:23            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:23              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:23              Constant:
 0:23                1 (const int)
 0:23            Constant:
@@ -149,9 +149,9 @@
 0:24        move second child to first child ( temp float)
 0:24          'cd' ( temp float)
 0:24          direct index ( temp float ClipDistance)
-0:24            gl_ClipDistance: direct index for structure ( in implicitly-sized array of float ClipDistance)
-0:24              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:24                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:24            gl_ClipDistance: direct index for structure ( in unsized 3-element array of float ClipDistance)
+0:24              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:24                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:24                Constant:
 0:24                  1 (const int)
 0:24              Constant:
@@ -186,20 +186,20 @@
 0:30              1 (const int)
 0:32      move second child to first child ( temp 4-component vector of float)
 0:32        gl_Position: direct index for structure ( gl_Position 4-component vector of float Position)
-0:32          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:32          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:32          Constant:
 0:32            0 (const uint)
 0:32        'p' ( temp 4-component vector of float)
 0:33      move second child to first child ( temp float)
 0:33        gl_PointSize: direct index for structure ( gl_PointSize float PointSize)
-0:33          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:33          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:33          Constant:
 0:33            1 (const uint)
 0:33        'ps' ( temp float)
 0:34      move second child to first child ( temp float)
 0:34        direct index ( temp float ClipDistance)
-0:34          gl_ClipDistance: direct index for structure ( out implicitly-sized array of float ClipDistance)
-0:34            'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:34          gl_ClipDistance: direct index for structure ( out unsized 3-element array of float ClipDistance)
+0:34            'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:34            Constant:
 0:34              2 (const uint)
 0:34          Constant:
@@ -207,7 +207,7 @@
 0:34        'cd' ( temp float)
 0:?   Linker Objects
 0:?     'patchIn' ( patch in 4-component vector of float)
-0:?     'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 
 400.tesc
 ERROR: 0:6: 'quads' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) 
@@ -255,8 +255,8 @@
 0:23        move second child to first child ( temp 4-component vector of float)
 0:23          'p' ( temp 4-component vector of float)
 0:23          gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:23            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:23              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:23            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:23              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:23              Constant:
 0:23                1 (const int)
 0:23            Constant:
@@ -265,8 +265,8 @@
 0:24        move second child to first child ( temp float)
 0:24          'ps' ( temp float)
 0:24          gl_PointSize: direct index for structure ( in float PointSize)
-0:24            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:24              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:24            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:24              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:24              Constant:
 0:24                1 (const int)
 0:24            Constant:
@@ -275,9 +275,9 @@
 0:25        move second child to first child ( temp float)
 0:25          'cd' ( temp float)
 0:25          direct index ( temp float ClipDistance)
-0:25            gl_ClipDistance: direct index for structure ( in implicitly-sized array of float ClipDistance)
-0:25              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:25                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:25            gl_ClipDistance: direct index for structure ( in unsized 3-element array of float ClipDistance)
+0:25              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:25                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:25                Constant:
 0:25                  1 (const int)
 0:25              Constant:
@@ -298,25 +298,25 @@
 0:29          'gl_InvocationID' ( in int InvocationID)
 0:31      move second child to first child ( temp 4-component vector of float)
 0:31        gl_Position: direct index for structure ( out 4-component vector of float Position)
-0:31          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:31            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:31          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:31            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:31            'gl_InvocationID' ( in int InvocationID)
 0:31          Constant:
 0:31            0 (const int)
 0:31        'p' ( temp 4-component vector of float)
 0:32      move second child to first child ( temp float)
 0:32        gl_PointSize: direct index for structure ( out float PointSize)
-0:32          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:32            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:32          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:32            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:32            'gl_InvocationID' ( in int InvocationID)
 0:32          Constant:
 0:32            1 (const int)
 0:32        'ps' ( temp float)
 0:33      move second child to first child ( temp float)
 0:33        direct index ( temp float ClipDistance)
-0:33          gl_ClipDistance: direct index for structure ( out implicitly-sized array of float ClipDistance)
-0:33            indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:33              'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:33          gl_ClipDistance: direct index for structure ( out unsized 2-element array of float ClipDistance)
+0:33            indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:33              'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:33              'gl_InvocationID' ( in int InvocationID)
 0:33            Constant:
 0:33              2 (const int)
@@ -386,8 +386,8 @@
 0:67    Function Parameters: 
 0:69    Sequence
 0:69      gl_PointSize: direct index for structure ( out float PointSize)
-0:69        direct index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:69          'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:69        direct index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:69          'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:69          Constant:
 0:69            4 (const int)
 0:69        Constant:
@@ -422,7 +422,7 @@
 0:123      'gl_DeviceIndex' ( in int DeviceIndex)
 0:124      'gl_ViewIndex' ( in int ViewIndex)
 0:?   Linker Objects
-0:?     'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:?     'outa' ( global 4-element array of int)
 0:?     'patchIn' ( patch in 4-component vector of float)
 0:?     'patchOut' ( patch out 4-component vector of float)
@@ -453,7 +453,7 @@
 ERROR: 0:48: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:49: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:50: '' : can only have one auxiliary qualifier (centroid, patch, and sample) 
-ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as implicitly-sized 
+ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as unsized 
 ERROR: 0:59: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use 
 ERROR: 0:64: 'quads' : cannot apply to 'out' 
 ERROR: 0:64: 'cw' : can only apply to 'in' 
@@ -499,8 +499,8 @@
 0:32        move second child to first child ( temp 4-component vector of float)
 0:32          'p' ( temp 4-component vector of float)
 0:32          gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:32            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:32              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:32            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:32              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:32              Constant:
 0:32                1 (const int)
 0:32            Constant:
@@ -509,8 +509,8 @@
 0:33        move second child to first child ( temp float)
 0:33          'ps' ( temp float)
 0:33          gl_PointSize: direct index for structure ( in float PointSize)
-0:33            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:33              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:33            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:33              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:33              Constant:
 0:33                1 (const int)
 0:33            Constant:
@@ -519,9 +519,9 @@
 0:34        move second child to first child ( temp float)
 0:34          'cd' ( temp float)
 0:34          direct index ( temp float ClipDistance)
-0:34            gl_ClipDistance: direct index for structure ( in implicitly-sized array of float ClipDistance)
-0:34              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:34                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:34            gl_ClipDistance: direct index for structure ( in unsized 3-element array of float ClipDistance)
+0:34              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:34                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:34                Constant:
 0:34                  1 (const int)
 0:34              Constant:
@@ -556,20 +556,20 @@
 0:40              1 (const int)
 0:42      move second child to first child ( temp 4-component vector of float)
 0:42        gl_Position: direct index for structure ( gl_Position 4-component vector of float Position)
-0:42          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:42          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:42          Constant:
 0:42            0 (const uint)
 0:42        'p' ( temp 4-component vector of float)
 0:43      move second child to first child ( temp float)
 0:43        gl_PointSize: direct index for structure ( gl_PointSize float PointSize)
-0:43          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:43          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:43          Constant:
 0:43            1 (const uint)
 0:43        'ps' ( temp float)
 0:44      move second child to first child ( temp float)
 0:44        direct index ( temp float ClipDistance)
-0:44          gl_ClipDistance: direct index for structure ( out implicitly-sized array of float ClipDistance)
-0:44            'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:44          gl_ClipDistance: direct index for structure ( out unsized 3-element array of float ClipDistance)
+0:44            'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:44            Constant:
 0:44              2 (const uint)
 0:44          Constant:
@@ -588,7 +588,7 @@
 0:?   Linker Objects
 0:?     'patchIn' ( patch in 4-component vector of float)
 0:?     'patchOut' ( patch out 4-component vector of float)
-0:?     'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:?     'badp1' ( smooth patch in 4-component vector of float)
 0:?     'badp2' ( flat patch in 4-component vector of float)
 0:?     'badp3' ( noperspective patch in 4-component vector of float)
@@ -620,7 +620,7 @@
 0:8  Function Definition: main( ( global void)
 0:8    Function Parameters: 
 0:?   Linker Objects
-0:?     'gl_out' ( out implicitly-sized array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'gl_out' ( out unsized 1-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 1-element array of float ClipDistance gl_ClipDistance})
 0:?     'outa' ( global 1-element array of int)
 0:?     'patchOut' ( patch out 4-component vector of float)
 
@@ -646,8 +646,8 @@
 0:17        move second child to first child ( temp 4-component vector of float)
 0:17          'p' ( temp 4-component vector of float)
 0:17          gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:17            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:17              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:17            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:17              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:17              Constant:
 0:17                1 (const int)
 0:17            Constant:
@@ -656,8 +656,8 @@
 0:18        move second child to first child ( temp float)
 0:18          'ps' ( temp float)
 0:18          gl_PointSize: direct index for structure ( in float PointSize)
-0:18            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:18              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:18            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:18              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:18              Constant:
 0:18                1 (const int)
 0:18            Constant:
@@ -666,9 +666,9 @@
 0:19        move second child to first child ( temp float)
 0:19          'cd' ( temp float)
 0:19          direct index ( temp float ClipDistance)
-0:19            gl_ClipDistance: direct index for structure ( in implicitly-sized array of float ClipDistance)
-0:19              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:19                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:19            gl_ClipDistance: direct index for structure ( in unsized 3-element array of float ClipDistance)
+0:19              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:19                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:19                Constant:
 0:19                  1 (const int)
 0:19              Constant:
@@ -883,7 +883,7 @@
 0:?     'b3' ( global 2-element array of 4-component vector of float)
 0:?     'b4' ( global 2-element array of 4-component vector of float)
 0:?     'c3' ( global 4X2 matrix of float)
-0:?     'd2' ( global implicitly-sized array of structure{ global float s,  global float t})
+0:?     'd2' ( global unsized 1-element array of structure{ global float s,  global float t})
 0:?     'b5' ( global 5-element array of float)
 0:?     'single1' ( global structure{ global int f})
 0:?     'single2' ( global structure{ global 2-component vector of uint v})
@@ -943,8 +943,6 @@
 ERROR: Linking tessellation control stage: Multiple function bodies in multiple compilation units for the same signature in the same stage:
     main(
 ERROR: Linking tessellation control stage: Types must match:
-    gl_out: " out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance}" versus " out implicitly-sized array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance}"
-ERROR: Linking tessellation control stage: Types must match:
     outa: " global 4-element array of int" versus " global 1-element array of int"
 ERROR: Linking tessellation control stage: can't handle multiple entry points per stage
 ERROR: Linking tessellation control stage: Multiple function bodies in multiple compilation units for the same signature in the same stage:
@@ -956,7 +954,7 @@
 ERROR: Linking tessellation control stage: Multiple function bodies in multiple compilation units for the same signature in the same stage:
     main(
 ERROR: Linking tessellation control stage: Types must match:
-    gl_out: " out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance}" versus " out 3-element array of block{ out 4-component vector of float Position gl_Position}"
+    gl_out: " out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance}" versus " out 3-element array of block{ out 4-component vector of float Position gl_Position}"
 
 Linked tessellation evaluation stage:
 
diff --git a/Test/baseResults/150.vert.out b/Test/baseResults/150.vert.out
index 61a558a..504160d 100644
--- a/Test/baseResults/150.vert.out
+++ b/Test/baseResults/150.vert.out
@@ -11,20 +11,20 @@
 0:15    Sequence
 0:15      move second child to first child ( temp 4-component vector of float)
 0:15        gl_Position: direct index for structure ( invariant gl_Position 4-component vector of float Position)
-0:15          'anon@0' ( out block{ invariant gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 4-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out implicitly-sized array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
+0:15          'anon@0' ( out block{ invariant gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 4-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out unsized 1-element array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
 0:15          Constant:
 0:15            0 (const uint)
 0:15        'iv4' ( in 4-component vector of float)
 0:16      move second child to first child ( temp float)
 0:16        gl_PointSize: direct index for structure ( gl_PointSize float PointSize)
-0:16          'anon@0' ( out block{ invariant gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 4-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out implicitly-sized array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
+0:16          'anon@0' ( out block{ invariant gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 4-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out unsized 1-element array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
 0:16          Constant:
 0:16            1 (const uint)
 0:16        'ps' ( uniform float)
 0:17      move second child to first child ( temp float)
 0:17        direct index ( temp float ClipDistance)
 0:17          gl_ClipDistance: direct index for structure ( out 4-element array of float ClipDistance)
-0:17            'anon@0' ( out block{ invariant gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 4-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out implicitly-sized array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
+0:17            'anon@0' ( out block{ invariant gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 4-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out unsized 1-element array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
 0:17            Constant:
 0:17              2 (const uint)
 0:17          Constant:
@@ -35,14 +35,14 @@
 0:17            0 (const int)
 0:18      move second child to first child ( temp 4-component vector of float)
 0:18        gl_ClipVertex: direct index for structure ( gl_ClipVertex 4-component vector of float ClipVertex)
-0:18          'anon@0' ( out block{ invariant gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 4-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out implicitly-sized array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
+0:18          'anon@0' ( out block{ invariant gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 4-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out unsized 1-element array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
 0:18          Constant:
 0:18            3 (const uint)
 0:18        'iv4' ( in 4-component vector of float)
 0:?   Linker Objects
 0:?     'iv4' ( in 4-component vector of float)
 0:?     'ps' ( uniform float)
-0:?     'anon@1' (layout( column_major shared) uniform block{layout( column_major shared) uniform implicitly-sized array of int a})
+0:?     'anon@1' (layout( column_major shared) uniform block{layout( column_major shared) uniform unsized 1-element array of int a})
 0:?     'gl_VertexID' ( gl_VertexId int VertexId)
 0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
 
diff --git a/Test/baseResults/300.frag.out b/Test/baseResults/300.frag.out
index 63abec1..ee1b8a5 100644
--- a/Test/baseResults/300.frag.out
+++ b/Test/baseResults/300.frag.out
@@ -1,7 +1,7 @@
 300.frag
 ERROR: 0:2: 'float' : type requires declaration of default precision qualifier 
 ERROR: 0:30: 'noperspective' : Reserved word. 
-ERROR: 0:30: 'noperspective' : not supported with this profile: es
+ERROR: 0:30: 'noperspective' : not supported for this version or the enabled extensions 
 ERROR: 0:31: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: bads
 ERROR: 0:32: 'uint' : cannot apply precision statement to this type; use 'float', 'int' or a sampler type 
 ERROR: 0:39: 'structure' : must be qualified as flat in
@@ -26,6 +26,7 @@
 ERROR: 0:102: 'arrays of arrays' : not supported for this version or the enabled extensions 
 ERROR: 0:102: 'arrays of arrays' : not supported for this version or the enabled extensions 
 ERROR: 0:103: 'arrays of arrays' : not supported for this version or the enabled extensions 
+ERROR: 0:103: 'arrays of arrays' : not supported for this version or the enabled extensions 
 ERROR: 0:100: 'arrays of arrays' : not supported for this version or the enabled extensions 
 ERROR: 0:100: 'array-of-array of block' : not supported with this profile: es
 ERROR: 0:111: 'variable indexing fragment shader output array' : not supported with this profile: es
@@ -44,7 +45,7 @@
 ERROR: 0:158: 'invariant' : can only apply to an output 
 ERROR: 0:160: 'imageBuffer' : Reserved word. 
 ERROR: 0:160: '' :  syntax error, unexpected IMAGEBUFFER, expecting COMMA or SEMICOLON
-ERROR: 45 compilation errors.  No code generated.
+ERROR: 46 compilation errors.  No code generated.
 
 
 Shader version: 300
@@ -392,7 +393,7 @@
 0:?     'sc' ( out lowp 3-component vector of float)
 0:?     'sf' ( out lowp float)
 0:?     'arrayedSampler' ( uniform 5-element array of lowp sampler2D)
-0:?     'multiInst' (layout( column_major shared) uniform 2-element array of 3-element array of block{layout( column_major shared) uniform 2-element array of mediump int a, layout( column_major shared) uniform 2-element array of 3-element array of mediump int b, layout( column_major shared) uniform 2-element array of 3-element array of mediump int c})
+0:?     'multiInst' (layout( column_major shared) uniform 2-element array of 3-element array of block{layout( column_major shared) uniform 3-element array of 2-element array of mediump int a, layout( column_major shared) uniform 2-element array of 3-element array of mediump int b, layout( column_major shared) uniform 2-element array of 3-element array of mediump int c})
 0:?     'colors' ( out 4-element array of lowp 4-component vector of float)
 0:?     'st1' ( uniform structure{ global mediump int i,  global lowp sampler2D s})
 0:?     'st2' ( uniform structure{ global mediump int i,  global lowp sampler2D s})
@@ -623,7 +624,7 @@
 0:?     'sc' ( out lowp 3-component vector of float)
 0:?     'sf' ( out lowp float)
 0:?     'arrayedSampler' ( uniform 5-element array of lowp sampler2D)
-0:?     'multiInst' (layout( column_major shared) uniform 2-element array of 3-element array of block{layout( column_major shared) uniform 2-element array of mediump int a, layout( column_major shared) uniform 2-element array of 3-element array of mediump int b, layout( column_major shared) uniform 2-element array of 3-element array of mediump int c})
+0:?     'multiInst' (layout( column_major shared) uniform 2-element array of 3-element array of block{layout( column_major shared) uniform 3-element array of 2-element array of mediump int a, layout( column_major shared) uniform 2-element array of 3-element array of mediump int b, layout( column_major shared) uniform 2-element array of 3-element array of mediump int c})
 0:?     'colors' ( out 4-element array of lowp 4-component vector of float)
 0:?     'st1' ( uniform structure{ global mediump int i,  global lowp sampler2D s})
 0:?     'st2' ( uniform structure{ global mediump int i,  global lowp sampler2D s})
diff --git a/Test/baseResults/300.vert.out b/Test/baseResults/300.vert.out
index 507ad73..95ebb92 100644
--- a/Test/baseResults/300.vert.out
+++ b/Test/baseResults/300.vert.out
@@ -320,9 +320,9 @@
 0:?     'rep2' ( centroid smooth sample out highp 4-component vector of float)
 0:?     'rep3' ( in highp 4-component vector of float)
 0:?     's' ( smooth out structure{ global highp 3-component vector of float c,  global highp float f})
-0:?     'badsize' ( global implicitly-sized array of highp float)
-0:?     'badsize2' ( global implicitly-sized array of highp float)
-0:?     'ubInst' (layout( column_major shared) uniform implicitly-sized array of block{layout( column_major shared) uniform implicitly-sized array of highp int a})
+0:?     'badsize' ( global unsized 1-element array of highp float)
+0:?     'badsize2' ( global unsized 1-element array of highp float)
+0:?     'ubInst' (layout( column_major shared) uniform unsized 1-element array of block{layout( column_major shared) uniform unsized 1-element array of highp int a})
 0:?     'okayA' ( global 2-element array of highp float)
 0:?     'newV' ( invariant smooth out highp 3-component vector of float)
 0:?     'invIn' ( invariant in highp 4-component vector of float)
diff --git a/Test/baseResults/310.comp.out b/Test/baseResults/310.comp.out
index f2d48ef..5a926f6 100644
--- a/Test/baseResults/310.comp.out
+++ b/Test/baseResults/310.comp.out
@@ -40,7 +40,6 @@
 ERROR: 0:128: 'atomic_uint' : samplers and atomic_uints cannot be output parameters 
 ERROR: 0:130: 'return' : type does not match, or is not convertible to, the function's return type 
 ERROR: 0:136: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: non_uniform_counter
-ERROR: 0:136: 'atomic_uint' : layout(binding=X) is required 
 ERROR: 0:141: 'atomic_uint' : atomic counters can only be highp 
 ERROR: 0:141: 'binding' : atomic_uint binding is too large; see gl_MaxAtomicCounterBindings 
 ERROR: 0:143: 'binding' : atomic_uint binding is too large; see gl_MaxAtomicCounterBindings 
@@ -84,7 +83,7 @@
 ERROR: 0:244: 'gl_DeviceIndex' : required extension not requested: GL_EXT_device_group
 ERROR: 0:245: 'gl_ViewIndex' : undeclared identifier 
 ERROR: 0:255: 'gl_ViewIndex' : undeclared identifier 
-ERROR: 83 compilation errors.  No code generated.
+ERROR: 82 compilation errors.  No code generated.
 
 
 Shader version: 310
@@ -103,13 +102,13 @@
 0:35      GroupMemoryBarrier ( global void)
 0:36      move second child to first child ( temp highp int)
 0:36        value: direct index for structure (layout( column_major shared) buffer highp int)
-0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
 0:36          Constant:
 0:36            0 (const uint)
 0:36        Convert float to int ( temp highp int)
 0:36          indirect index (layout( column_major shared) temp highp float)
-0:36            values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:36            values: direct index for structure (layout( column_major shared) buffer runtime-sized array of highp float)
+0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
 0:36              Constant:
 0:36                1 (const uint)
 0:36            'gl_LocalInvocationIndex' ( in highp uint LocalInvocationIndex)
@@ -118,8 +117,8 @@
 0:61    Sequence
 0:61      move second child to first child ( temp highp float)
 0:61        direct index (layout( column_major shared) temp highp float)
-0:61          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:61            'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:61          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:61            'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:61            Constant:
 0:61              1 (const int)
 0:61          Constant:
@@ -127,8 +126,8 @@
 0:61        Constant:
 0:61          4.700000
 0:62      array length ( temp int)
-0:62        values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:62          'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:62        values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:62          'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:62          Constant:
 0:62            1 (const int)
 0:63      Pre-Increment ( temp highp 4-component vector of float)
@@ -281,8 +280,8 @@
 0:194      move second child to first child ( temp highp float)
 0:194        'g' ( temp highp float)
 0:194        direct index (layout( column_major shared) temp highp float)
-0:194          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:194            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:194          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:194            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:194            Constant:
 0:194              1 (const int)
 0:194          Constant:
@@ -291,24 +290,24 @@
 0:195        move second child to first child ( temp highp float)
 0:195          'f' ( temp highp float)
 0:195          direct index (layout( column_major shared) temp highp float)
-0:195            values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:195              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:195            values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:195              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:195              Constant:
 0:195                1 (const int)
 0:195            Constant:
 0:195              2 (const int)
 0:196      Pre-Increment ( temp highp float)
 0:196        direct index (layout( column_major shared) temp highp float)
-0:196          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:196            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:196          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:196            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:196            Constant:
 0:196              1 (const int)
 0:196          Constant:
 0:196            2 (const int)
 0:197      Post-Decrement ( temp highp float)
 0:197        direct index (layout( column_major shared) temp highp float)
-0:197          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:197            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:197          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:197            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:197            Constant:
 0:197              1 (const int)
 0:197          Constant:
@@ -316,16 +315,16 @@
 0:198      add ( temp highp float)
 0:198        'f' ( temp highp float)
 0:198        direct index (layout( column_major shared) temp highp float)
-0:198          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:198            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:198          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:198            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:198            Constant:
 0:198              1 (const int)
 0:198          Constant:
 0:198            2 (const int)
 0:199      subtract ( temp highp float)
 0:199        direct index (layout( column_major shared) temp highp float)
-0:199          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:199            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:199          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:199            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:199            Constant:
 0:199              1 (const int)
 0:199          Constant:
@@ -338,8 +337,8 @@
 0:201        'f' ( temp highp float)
 0:201        false case
 0:201        direct index (layout( column_major shared) temp highp float)
-0:201          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:201            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:201          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:201            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:201            Constant:
 0:201              1 (const int)
 0:201          Constant:
@@ -349,8 +348,8 @@
 0:202        'b' ( temp bool)
 0:202        true case
 0:202        direct index (layout( column_major shared) temp highp float)
-0:202          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:202            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:202          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:202            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:202            Constant:
 0:202              1 (const int)
 0:202          Constant:
@@ -362,8 +361,8 @@
 0:203        Compare Equal ( temp bool)
 0:203          'f' ( temp highp float)
 0:203          direct index (layout( column_major shared) temp highp float)
-0:203            values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:203              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:203            values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:203              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:203              Constant:
 0:203                1 (const int)
 0:203            Constant:
@@ -376,8 +375,8 @@
 0:205        Compare Greater Than or Equal ( temp bool)
 0:205          'f' ( temp highp float)
 0:205          direct index (layout( column_major shared) temp highp float)
-0:205            values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:205              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:205            values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:205              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:205              Constant:
 0:205                1 (const int)
 0:205            Constant:
@@ -390,8 +389,8 @@
 0:207        direct index ( temp highp float)
 0:207          Construct vec3 ( temp highp 3-component vector of float)
 0:207            direct index (layout( column_major shared) temp highp float)
-0:207              values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:207                'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:207              values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:207                'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:207                Constant:
 0:207                  1 (const int)
 0:207              Constant:
@@ -400,13 +399,13 @@
 0:207            0 (const int)
 0:208      Bitwise not ( temp highp int)
 0:208        value: direct index for structure (layout( column_major shared) buffer highp int)
-0:208          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:208          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:208          Constant:
 0:208            0 (const int)
 0:209      move second child to first child ( temp highp float)
 0:209        direct index (layout( column_major shared) temp highp float)
-0:209          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:209            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:209          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:209            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:209            Constant:
 0:209              1 (const int)
 0:209          Constant:
@@ -419,21 +418,21 @@
 0:221      move second child to first child ( temp highp float)
 0:221        'g' ( temp highp float)
 0:221        direct index (layout( column_major shared) temp highp float)
-0:221          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:221            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:221          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:221            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:221            Constant:
 0:221              1 (const int)
 0:221          Constant:
 0:221            2 (const int)
 0:222      Bitwise not ( temp highp int)
 0:222        value: direct index for structure (layout( column_major shared) buffer highp int)
-0:222          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:222          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:222          Constant:
 0:222            0 (const int)
 0:223      move second child to first child ( temp highp float)
 0:223        direct index (layout( column_major shared) temp highp float)
-0:223          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:223            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:223          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:223            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:223            Constant:
 0:223              1 (const int)
 0:223          Constant:
@@ -442,7 +441,7 @@
 0:223          3.400000
 0:224      move second child to first child ( temp highp int)
 0:224        value: direct index for structure (layout( column_major shared) buffer highp int)
-0:224          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:224          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:224          Constant:
 0:224            0 (const int)
 0:224        Constant:
@@ -464,8 +463,8 @@
 0:?       4096 (const uint)
 0:?     'total' ( const highp int)
 0:?       66592 (const int)
-0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
-0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer implicitly-sized array of highp float values, layout( column_major shared) buffer highp int value})
+0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
+0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 1-element array of highp float values, layout( column_major shared) buffer highp int value})
 0:?     'v3' (layout( location=2) in highp 3-component vector of float)
 0:?     'f' ( in highp float)
 0:?     'fo' ( out highp float)
@@ -475,7 +474,7 @@
 0:?     'arrX' ( global 2-element array of highp int)
 0:?     'arrY' ( global 1-element array of highp int)
 0:?     'arrZ' ( global 4096-element array of highp int)
-0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:?     'v' ( buffer highp 4-component vector of float)
 0:?     'us2dbad' ( uniform mediump usampler2D)
 0:?     'us2d' ( uniform highp usampler2D)
@@ -514,8 +513,8 @@
 0:?     'badQ1' (layout( rgba32f) coherent volatile restrict uniform highp image2D)
 0:?     'badQ2' (layout( rgba8i) coherent volatile restrict uniform highp iimage2D)
 0:?     'badQ3' (layout( rgba16ui) coherent volatile restrict uniform highp uimage2D)
-0:?     'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
-0:?     'multio' (layout( column_major shared) buffer block{layout( column_major shared) readonly buffer highp int value, layout( column_major shared) writeonly buffer implicitly-sized array of highp float values})
+0:?     'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
+0:?     'multio' (layout( column_major shared) buffer block{layout( column_major shared) readonly buffer highp int value, layout( column_major shared) writeonly buffer unsized 1-element array of highp float values})
 0:?     'inbi' ( in block{ in highp int a})
 0:?     'outbi' ( out block{ out highp int a})
 0:?     't__' ( global highp float)
@@ -541,13 +540,13 @@
 0:35      GroupMemoryBarrier ( global void)
 0:36      move second child to first child ( temp highp int)
 0:36        value: direct index for structure (layout( column_major shared) buffer highp int)
-0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
 0:36          Constant:
 0:36            0 (const uint)
 0:36        Convert float to int ( temp highp int)
 0:36          indirect index (layout( column_major shared) temp highp float)
-0:36            values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp float)
-0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:36            values: direct index for structure (layout( column_major shared) buffer runtime-sized array of highp float)
+0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
 0:36              Constant:
 0:36                1 (const uint)
 0:36            'gl_LocalInvocationIndex' ( in highp uint LocalInvocationIndex)
@@ -558,8 +557,8 @@
 0:?       4096 (const uint)
 0:?     'total' ( const highp int)
 0:?       66592 (const int)
-0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
-0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer implicitly-sized array of highp float values, layout( column_major shared) buffer highp int value})
+0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
+0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer 1-element array of highp float values, layout( column_major shared) buffer highp int value})
 0:?     'v3' (layout( location=2) in highp 3-component vector of float)
 0:?     'f' ( in highp float)
 0:?     'fo' ( out highp float)
@@ -569,7 +568,7 @@
 0:?     'arrX' ( global 2-element array of highp int)
 0:?     'arrY' ( global 1-element array of highp int)
 0:?     'arrZ' ( global 4096-element array of highp int)
-0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
+0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:?     'v' ( buffer highp 4-component vector of float)
 0:?     'us2dbad' ( uniform mediump usampler2D)
 0:?     'us2d' ( uniform highp usampler2D)
@@ -608,8 +607,8 @@
 0:?     'badQ1' (layout( rgba32f) coherent volatile restrict uniform highp image2D)
 0:?     'badQ2' (layout( rgba8i) coherent volatile restrict uniform highp iimage2D)
 0:?     'badQ3' (layout( rgba16ui) coherent volatile restrict uniform highp uimage2D)
-0:?     'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer implicitly-sized array of highp float values})
-0:?     'multio' (layout( column_major shared) buffer block{layout( column_major shared) readonly buffer highp int value, layout( column_major shared) writeonly buffer implicitly-sized array of highp float values})
+0:?     'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
+0:?     'multio' (layout( column_major shared) buffer block{layout( column_major shared) readonly buffer highp int value, layout( column_major shared) writeonly buffer unsized 1-element array of highp float values})
 0:?     'inbi' ( in block{ in highp int a})
 0:?     'outbi' ( out block{ out highp int a})
 0:?     't__' ( global highp float)
diff --git a/Test/baseResults/310.frag.out b/Test/baseResults/310.frag.out
index 8107556..6763c0a 100644
--- a/Test/baseResults/310.frag.out
+++ b/Test/baseResults/310.frag.out
@@ -105,7 +105,7 @@
 ERROR: 0:347: 'flat/smooth/noperspective' : can't use interpolation qualifier on a fragment output 
 ERROR: 0:348: 'flat/smooth/noperspective' : can't use interpolation qualifier on a fragment output 
 ERROR: 0:349: 'noperspective' : Reserved word. 
-ERROR: 0:349: 'noperspective' : not supported with this profile: es
+ERROR: 0:349: 'noperspective' : not supported for this version or the enabled extensions 
 ERROR: 0:349: 'flat/smooth/noperspective' : can't use interpolation qualifier on a fragment output 
 ERROR: 0:355: 'interpolateAtCentroid' : required extension not requested: GL_OES_shader_multisample_interpolation
 ERROR: 0:356: 'interpolateAtSample' : required extension not requested: GL_OES_shader_multisample_interpolation
@@ -569,12 +569,12 @@
 0:259        move second child to first child ( temp highp int)
 0:259          'a3' ( temp highp int)
 0:259          direct index ( flat temp highp int SampleMaskIn)
-0:259            'gl_SampleMaskIn' ( flat in implicitly-sized array of highp int SampleMaskIn)
+0:259            'gl_SampleMaskIn' ( flat in unsized 1-element array of highp int SampleMaskIn)
 0:259            Constant:
 0:259              0 (const int)
 0:260      move second child to first child ( temp highp int)
 0:260        direct index ( temp highp int SampleMaskIn)
-0:260          'gl_SampleMask' ( out implicitly-sized array of highp int SampleMaskIn)
+0:260          'gl_SampleMask' ( out unsized 1-element array of highp int SampleMaskIn)
 0:260          Constant:
 0:260            0 (const int)
 0:260        'a3' ( temp highp int)
@@ -597,12 +597,12 @@
 0:272        move second child to first child ( temp highp int)
 0:272          'a3' ( temp highp int)
 0:272          direct index ( flat temp highp int SampleMaskIn)
-0:272            'gl_SampleMaskIn' ( flat in implicitly-sized array of highp int SampleMaskIn)
+0:272            'gl_SampleMaskIn' ( flat in unsized 1-element array of highp int SampleMaskIn)
 0:272            Constant:
 0:272              0 (const int)
 0:273      move second child to first child ( temp highp int)
 0:273        direct index ( temp highp int SampleMaskIn)
-0:273          'gl_SampleMask' ( out implicitly-sized array of highp int SampleMaskIn)
+0:273          'gl_SampleMask' ( out unsized 1-element array of highp int SampleMaskIn)
 0:273          Constant:
 0:273            0 (const int)
 0:273        'a3' ( temp highp int)
@@ -1001,8 +1001,8 @@
 0:?     'CA5' ( uniform highp samplerCubeArrayShadow)
 0:?     'CA6' ( uniform highp isamplerCubeArray)
 0:?     'CA7' ( uniform highp usamplerCubeArray)
-0:?     'gl_SampleMaskIn' ( flat in implicitly-sized array of highp int SampleMaskIn)
-0:?     'gl_SampleMask' ( out implicitly-sized array of highp int SampleMaskIn)
+0:?     'gl_SampleMaskIn' ( flat in unsized 1-element array of highp int SampleMaskIn)
+0:?     'gl_SampleMask' ( out unsized 1-element array of highp int SampleMaskIn)
 0:?     'im2Df' (layout( r32f) uniform highp image2D)
 0:?     'im2Du' (layout( r32ui) uniform highp uimage2D)
 0:?     'im2Di' (layout( r32i) uniform highp iimage2D)
diff --git a/Test/baseResults/310.tesc.out b/Test/baseResults/310.tesc.out
index 01d7ecf..433a7dc 100644
--- a/Test/baseResults/310.tesc.out
+++ b/Test/baseResults/310.tesc.out
@@ -70,8 +70,8 @@
 0:25        move second child to first child ( temp highp 4-component vector of float)
 0:25          'p' ( temp highp 4-component vector of float)
 0:25          gl_Position: direct index for structure ( in highp 4-component vector of float Position)
-0:25            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
-0:25              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
+0:25            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
+0:25              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
 0:25              Constant:
 0:25                1 (const int)
 0:25            Constant:
@@ -80,8 +80,8 @@
 0:26        move second child to first child ( temp highp float)
 0:26          'ps' ( temp highp float)
 0:26          gl_PointSize: direct index for structure ( in highp float PointSize)
-0:26            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
-0:26              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
+0:26            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
+0:26              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
 0:26              Constant:
 0:26                1 (const int)
 0:26            Constant:
@@ -209,8 +209,8 @@
 0:114        move second child to first child ( temp highp float)
 0:114          'ps' ( temp highp float)
 0:114          gl_PointSize: direct index for structure ( in highp float PointSize)
-0:114            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
-0:114              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
+0:114            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
+0:114              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
 0:114              Constant:
 0:114                1 (const int)
 0:114            Constant:
@@ -357,7 +357,7 @@
 0:?     'inb' ( in 32-element array of highp 2-component vector of float)
 0:?     'inc' ( in 32-element array of highp 2-component vector of float)
 0:?     'ind' ( in 32-element array of highp 2-component vector of float)
-0:?     'implA' ( patch out implicitly-sized array of highp float)
+0:?     'implA' ( patch out unsized 1-element array of highp float)
 0:?     'ivla' (layout( location=3) in 32-element array of highp 4-component vector of float)
 0:?     'ivlb' (layout( location=4) in 32-element array of highp 4-component vector of float)
 0:?     'ivlc' (layout( location=4) in 32-element array of highp 4-component vector of float)
@@ -372,7 +372,7 @@
 0:?     'misSized' ( out 5-element array of highp float)
 0:?     'okaySize' ( out 4-element array of highp float)
 0:?     'pv3' ( noContraction temp highp 3-component vector of float)
-0:?     'badpatchIName' ( patch out implicitly-sized array of block{ out highp float f})
+0:?     'badpatchIName' ( patch out unsized 1-element array of block{ out highp float f})
 0:?     'patchIName' ( patch out 4-element array of block{ out highp float f})
 
 
diff --git a/Test/baseResults/310.tese.out b/Test/baseResults/310.tese.out
index 52d19b4..7d91e93 100644
--- a/Test/baseResults/310.tese.out
+++ b/Test/baseResults/310.tese.out
@@ -21,11 +21,11 @@
 ERROR: 0:51: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:52: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:53: 'noperspective' : Reserved word. 
-ERROR: 0:53: 'noperspective' : not supported with this profile: es
+ERROR: 0:53: 'noperspective' : not supported for this version or the enabled extensions 
 ERROR: 0:53: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:54: 'sample' : Reserved word. 
 ERROR: 0:54: '' : can only have one auxiliary qualifier (centroid, patch, and sample) 
-ERROR: 0:58: 'gl_PerVertex' : block already declared with size, can't redeclare as implicitly-sized 
+ERROR: 0:58: 'gl_PerVertex' : block already declared with size, can't redeclare as unsized 
 ERROR: 0:63: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use 
 ERROR: 0:68: 'quads' : cannot apply to 'out' 
 ERROR: 0:68: 'cw' : can only apply to 'in' 
@@ -77,8 +77,8 @@
 0:36        move second child to first child ( temp highp 4-component vector of float)
 0:36          'p' ( temp highp 4-component vector of float)
 0:36          gl_Position: direct index for structure ( in highp 4-component vector of float Position)
-0:36            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
-0:36              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
+0:36            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
+0:36              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
 0:36              Constant:
 0:36                1 (const int)
 0:36            Constant:
@@ -87,8 +87,8 @@
 0:37        move second child to first child ( temp highp float)
 0:37          'ps' ( temp highp float)
 0:37          gl_PointSize: direct index for structure ( in highp float PointSize)
-0:37            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
-0:37              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
+0:37            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
+0:37              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
 0:37              Constant:
 0:37                1 (const int)
 0:37            Constant:
diff --git a/Test/baseResults/310AofA.vert.out b/Test/baseResults/310AofA.vert.out
index 882c58a..451cc0b 100644
--- a/Test/baseResults/310AofA.vert.out
+++ b/Test/baseResults/310AofA.vert.out
@@ -7,12 +7,12 @@
 ERROR: 0:49: 'constructor' : array constructor argument not correct type to construct array element 
 ERROR: 0:62: '[' :  array index out of range '4'
 ERROR: 0:78: 'assign' :  cannot convert from ' global 4-element array of 7-element array of highp float' to ' global 5-element array of 7-element array of highp float'
-ERROR: 0:79: 'assign' :  cannot convert from ' global 4-element array of 7-element array of highp float' to ' global implicitly-sized array of 7-element array of highp float'
+ERROR: 0:79: 'assign' :  cannot convert from ' global 4-element array of 7-element array of highp float' to ' global unsized 1-element array of 7-element array of highp float'
 ERROR: 0:81: 'foo' : no matching overloaded function found 
 ERROR: 0:86: '==' :  wrong operand types: no operation '==' exists that takes a left-hand operand of type ' global 4-element array of 7-element array of highp float' and a right operand of type ' global 5-element array of 7-element array of highp float' (or there is no acceptable conversion)
 ERROR: 0:90: '[' :  array index out of range '5'
 ERROR: 0:94: '[' :  index out of range '-1'
-ERROR: 0:96: 'assign' :  cannot convert from ' temp 3-element array of highp 4-component vector of float' to 'layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float'
+ERROR: 0:96: 'assign' :  cannot convert from ' temp 3-element array of highp 4-component vector of float' to 'layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float'
 ERROR: 0:103: '' : array size required 
 ERROR: 0:104: '' : array size required 
 ERROR: 0:105: '' : array size required 
@@ -245,7 +245,7 @@
 0:77        Function Call: foo(f1[5][7]; ( global 4-element array of 7-element array of highp float)
 0:77          'g5' ( global 5-element array of 7-element array of highp float)
 0:78      'g5' ( global 5-element array of 7-element array of highp float)
-0:79      'gu' ( global implicitly-sized array of 7-element array of highp float)
+0:79      'gu' ( global unsized 1-element array of 7-element array of highp float)
 0:81      Constant:
 0:81        0.000000
 0:82      Function Call: bar(f1[5][7]; ( global void)
@@ -275,9 +275,9 @@
 0:91      Function Call: foo(f1[5][7]; ( global 4-element array of 7-element array of highp float)
 0:91        'u' ( temp 5-element array of 7-element array of highp float)
 0:94      direct index (layout( column_major shared) temp highp 4-component vector of float)
-0:94        v: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float)
-0:94          direct index (layout( column_major shared) temp block{layout( column_major shared) buffer implicitly-sized array of highp float u, layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float v})
-0:94            'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer implicitly-sized array of highp float u, layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float v})
+0:94        v: direct index for structure (layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float)
+0:94          direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
+0:94            'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
 0:94            Constant:
 0:94              1 (const int)
 0:94          Constant:
@@ -286,9 +286,9 @@
 0:94          -1 (const int)
 0:95      move second child to first child ( temp highp 4-component vector of float)
 0:95        direct index (layout( column_major shared) temp highp 4-component vector of float)
-0:95          v: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float)
-0:95            direct index (layout( column_major shared) temp block{layout( column_major shared) buffer implicitly-sized array of highp float u, layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float v})
-0:95              'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer implicitly-sized array of highp float u, layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float v})
+0:95          v: direct index for structure (layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float)
+0:95            direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
+0:95              'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
 0:95              Constant:
 0:95                1 (const int)
 0:95            Constant:
@@ -300,9 +300,9 @@
 0:95          4.300000
 0:95          4.300000
 0:95          4.300000
-0:96      v: direct index for structure (layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float)
-0:96        direct index (layout( column_major shared) temp block{layout( column_major shared) buffer implicitly-sized array of highp float u, layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float v})
-0:96          'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer implicitly-sized array of highp float u, layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float v})
+0:96      v: direct index for structure (layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float)
+0:96        direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
+0:96          'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
 0:96          Constant:
 0:96            1 (const int)
 0:96        Constant:
@@ -310,20 +310,39 @@
 0:98      Constant:
 0:98        7 (const int)
 0:99      array length ( temp int)
-0:99        v: direct index for structure (layout( column_major shared) buffer implicitly-sized array of 7-element array of highp 4-component vector of float)
-0:99          direct index (layout( column_major shared) temp block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer implicitly-sized array of 7-element array of highp 4-component vector of float v})
-0:99            'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer implicitly-sized array of 7-element array of highp 4-component vector of float v})
+0:99        v: direct index for structure (layout( column_major shared) buffer unsized 2-element array of 7-element array of highp 4-component vector of float)
+0:99          direct index (layout( column_major shared) temp block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 2-element array of 7-element array of highp 4-component vector of float v})
+0:99            'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 2-element array of 7-element array of highp 4-component vector of float v})
 0:99            Constant:
 0:99              0 (const int)
 0:99          Constant:
 0:99            1 (const int)
+0:117  Function Definition: func(mf33[3][2]; ( global highp 3-component vector of float)
+0:117    Function Parameters: 
+0:117      'x' ( in 3-element array of 2-element array of highp 3X3 matrix of float)
+0:119    Sequence
+0:119      Sequence
+0:119        move second child to first child ( temp highp 3X3 matrix of float)
+0:119          'a0' ( temp highp 3X3 matrix of float)
+0:119          direct index ( temp highp 3X3 matrix of float)
+0:119            direct index ( temp 2-element array of highp 3X3 matrix of float)
+0:119              'x' ( in 3-element array of 2-element array of highp 3X3 matrix of float)
+0:119              Constant:
+0:119                2 (const int)
+0:119            Constant:
+0:119              1 (const int)
+0:120      Branch: Return with expression
+0:120        direct index ( temp highp 3-component vector of float)
+0:120          'a0' ( temp highp 3X3 matrix of float)
+0:120          Constant:
+0:120            2 (const int)
 0:?   Linker Objects
-0:?     'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer implicitly-sized array of highp float u, layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float v})
-0:?     'uname' (layout( column_major shared) uniform 3-element array of block{layout( column_major shared) uniform highp float u, layout( column_major shared) uniform implicitly-sized array of highp 4-component vector of float v})
-0:?     'name2' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer implicitly-sized array of implicitly-sized array of highp 4-component vector of float v})
-0:?     'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer implicitly-sized array of 7-element array of highp 4-component vector of float v})
+0:?     'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
+0:?     'uname' (layout( column_major shared) uniform 3-element array of block{layout( column_major shared) uniform highp float u, layout( column_major shared) uniform unsized 1-element array of highp 4-component vector of float v})
+0:?     'name2' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 1-element array of 1-element array of highp 4-component vector of float v})
+0:?     'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 2-element array of 7-element array of highp 4-component vector of float v})
 0:?     'many' ( global 1-element array of 2-element array of 3-element array of 4-element array of 5-element array of 6-element array of highp float)
-0:?     'gu' ( global implicitly-sized array of 7-element array of highp float)
+0:?     'gu' ( global unsized 1-element array of 7-element array of highp float)
 0:?     'g4' ( global 4-element array of 7-element array of highp float)
 0:?     'g5' ( global 5-element array of 7-element array of highp float)
 0:?     'inArray' ( in 2-element array of 3-element array of highp float)
@@ -359,10 +378,10 @@
 0:13          2 (const uint)
 0:13        'd' ( temp 3-element array of 2-element array of highp int)
 0:?   Linker Objects
-0:?     'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer implicitly-sized array of highp float u, layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float v})
+0:?     'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
 0:?     'uname' (layout( column_major shared) uniform 3-element array of block{layout( column_major shared) uniform highp float u, layout( column_major shared) uniform 1-element array of highp 4-component vector of float v})
-0:?     'name2' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer implicitly-sized array of implicitly-sized array of highp 4-component vector of float v})
-0:?     'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer implicitly-sized array of 7-element array of highp 4-component vector of float v})
+0:?     'name2' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 1-element array of 1-element array of highp 4-component vector of float v})
+0:?     'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 2-element array of 7-element array of highp 4-component vector of float v})
 0:?     'many' ( global 1-element array of 2-element array of 3-element array of 4-element array of 5-element array of 6-element array of highp float)
 0:?     'gu' ( global 1-element array of 7-element array of highp float)
 0:?     'g4' ( global 4-element array of 7-element array of highp float)
diff --git a/Test/baseResults/310implicitSizeArrayError.vert.out b/Test/baseResults/310implicitSizeArrayError.vert.out
index 1eed457..6975cde 100644
--- a/Test/baseResults/310implicitSizeArrayError.vert.out
+++ b/Test/baseResults/310implicitSizeArrayError.vert.out
@@ -11,14 +11,14 @@
 0:7      move second child to first child ( temp highp int)
 0:7        'o' (layout( location=0) smooth out highp int)
 0:7        direct index (layout( column_major shared) temp highp int)
-0:7          a: direct index for structure (layout( column_major shared) uniform implicitly-sized array of highp int)
-0:7            'uni' (layout( location=0 column_major shared) uniform block{layout( column_major shared) uniform implicitly-sized array of highp int a})
+0:7          a: direct index for structure (layout( column_major shared) uniform unsized 3-element array of highp int)
+0:7            'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform unsized 3-element array of highp int a})
 0:7            Constant:
 0:7              0 (const int)
 0:7          Constant:
 0:7            2 (const int)
 0:?   Linker Objects
-0:?     'uni' (layout( location=0 column_major shared) uniform block{layout( column_major shared) uniform implicitly-sized array of highp int a})
+0:?     'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform unsized 3-element array of highp int a})
 0:?     'o' (layout( location=0) smooth out highp int)
 0:?     'gl_VertexID' ( gl_VertexId highp int VertexId)
 0:?     'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
@@ -35,14 +35,14 @@
 0:7      move second child to first child ( temp highp int)
 0:7        'o' (layout( location=0) smooth out highp int)
 0:7        direct index (layout( column_major shared) temp highp int)
-0:7          a: direct index for structure (layout( column_major shared) uniform 1-element array of highp int)
-0:7            'uni' (layout( location=0 column_major shared) uniform block{layout( column_major shared) uniform 1-element array of highp int a})
+0:7          a: direct index for structure (layout( column_major shared) uniform 3-element array of highp int)
+0:7            'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform 3-element array of highp int a})
 0:7            Constant:
 0:7              0 (const int)
 0:7          Constant:
 0:7            2 (const int)
 0:?   Linker Objects
-0:?     'uni' (layout( location=0 column_major shared) uniform block{layout( column_major shared) uniform 1-element array of highp int a})
+0:?     'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform 3-element array of highp int a})
 0:?     'o' (layout( location=0) smooth out highp int)
 0:?     'gl_VertexID' ( gl_VertexId highp int VertexId)
 0:?     'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
diff --git a/Test/baseResults/310runtimeArray.vert.out b/Test/baseResults/310runtimeArray.vert.out
new file mode 100755
index 0000000..84c731e
--- /dev/null
+++ b/Test/baseResults/310runtimeArray.vert.out
@@ -0,0 +1,145 @@
+310runtimeArray.vert
+ERROR: 0:9: '' : array size required 
+ERROR: 1 compilation errors.  No code generated.
+
+
+Shader version: 310
+ERROR: node is still EOpNull!
+0:12  Function Definition: main( ( global void)
+0:12    Function Parameters: 
+0:14    Sequence
+0:14      move second child to first child ( temp highp float)
+0:14        'o' (layout( location=0) smooth out highp float)
+0:14        f: direct index for structure ( global highp float)
+0:14          direct index (layout( column_major shared) temp structure{ global highp float f})
+0:14            s: direct index for structure (layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f})
+0:14              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f} s})
+0:14              Constant:
+0:14                0 (const uint)
+0:14            Constant:
+0:14              5 (const int)
+0:14          Constant:
+0:14            0 (const int)
+0:15      add second child into first child ( temp highp float)
+0:15        'o' (layout( location=0) smooth out highp float)
+0:15        f: direct index for structure ( global highp float)
+0:15          direct index (layout( column_major shared) temp structure{ global highp float f})
+0:15            s: direct index for structure (layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f})
+0:15              'b2name' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f} s})
+0:15              Constant:
+0:15                0 (const int)
+0:15            Constant:
+0:15              6 (const int)
+0:15          Constant:
+0:15            0 (const int)
+0:16      add second child into first child ( temp highp float)
+0:16        'o' (layout( location=0) smooth out highp float)
+0:16        f: direct index for structure ( global highp float)
+0:16          direct index (layout( column_major shared) temp structure{ global highp float f})
+0:16            s: direct index for structure (layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f})
+0:16              direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
+0:16                'b3name' (layout( column_major shared) buffer unsized 4-element array of block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
+0:16                Constant:
+0:16                  3 (const int)
+0:16              Constant:
+0:16                0 (const int)
+0:16            Constant:
+0:16              7 (const int)
+0:16          Constant:
+0:16            0 (const int)
+0:17      add second child into first child ( temp highp float)
+0:17        'o' (layout( location=0) smooth out highp float)
+0:17        f: direct index for structure ( global highp float)
+0:17          direct index (layout( column_major shared) temp structure{ global highp float f})
+0:17            s: direct index for structure (layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f})
+0:17              direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
+0:17                'b4name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
+0:17                Constant:
+0:17                  2 (const int)
+0:17              Constant:
+0:17                0 (const int)
+0:17            Constant:
+0:17              8 (const int)
+0:17          Constant:
+0:17            0 (const int)
+0:?   Linker Objects
+0:?     'o' (layout( location=0) smooth out highp float)
+0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f} s})
+0:?     'b2name' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f} s})
+0:?     'b3name' (layout( column_major shared) buffer unsized 4-element array of block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
+0:?     'b4name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
+0:?     'gl_VertexID' ( gl_VertexId highp int VertexId)
+0:?     'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
+
+
+Linked vertex stage:
+
+
+Shader version: 310
+ERROR: node is still EOpNull!
+0:12  Function Definition: main( ( global void)
+0:12    Function Parameters: 
+0:14    Sequence
+0:14      move second child to first child ( temp highp float)
+0:14        'o' (layout( location=0) smooth out highp float)
+0:14        f: direct index for structure ( global highp float)
+0:14          direct index (layout( column_major shared) temp structure{ global highp float f})
+0:14            s: direct index for structure (layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f})
+0:14              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f} s})
+0:14              Constant:
+0:14                0 (const uint)
+0:14            Constant:
+0:14              5 (const int)
+0:14          Constant:
+0:14            0 (const int)
+0:15      add second child into first child ( temp highp float)
+0:15        'o' (layout( location=0) smooth out highp float)
+0:15        f: direct index for structure ( global highp float)
+0:15          direct index (layout( column_major shared) temp structure{ global highp float f})
+0:15            s: direct index for structure (layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f})
+0:15              'b2name' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f} s})
+0:15              Constant:
+0:15                0 (const int)
+0:15            Constant:
+0:15              6 (const int)
+0:15          Constant:
+0:15            0 (const int)
+0:16      add second child into first child ( temp highp float)
+0:16        'o' (layout( location=0) smooth out highp float)
+0:16        f: direct index for structure ( global highp float)
+0:16          direct index (layout( column_major shared) temp structure{ global highp float f})
+0:16            s: direct index for structure (layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f})
+0:16              direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
+0:16                'b3name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
+0:16                Constant:
+0:16                  3 (const int)
+0:16              Constant:
+0:16                0 (const int)
+0:16            Constant:
+0:16              7 (const int)
+0:16          Constant:
+0:16            0 (const int)
+0:17      add second child into first child ( temp highp float)
+0:17        'o' (layout( location=0) smooth out highp float)
+0:17        f: direct index for structure ( global highp float)
+0:17          direct index (layout( column_major shared) temp structure{ global highp float f})
+0:17            s: direct index for structure (layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f})
+0:17              direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
+0:17                'b4name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
+0:17                Constant:
+0:17                  2 (const int)
+0:17              Constant:
+0:17                0 (const int)
+0:17            Constant:
+0:17              8 (const int)
+0:17          Constant:
+0:17            0 (const int)
+0:?   Linker Objects
+0:?     'o' (layout( location=0) smooth out highp float)
+0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f} s})
+0:?     'b2name' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f} s})
+0:?     'b3name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
+0:?     'b4name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
+0:?     'gl_VertexID' ( gl_VertexId highp int VertexId)
+0:?     'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
+
diff --git a/Test/baseResults/320.frag.out b/Test/baseResults/320.frag.out
index 76dbeaf..002aa7f 100755
--- a/Test/baseResults/320.frag.out
+++ b/Test/baseResults/320.frag.out
@@ -23,7 +23,7 @@
 ERROR: 0:158: 'flat/smooth/noperspective' : can't use interpolation qualifier on a fragment output 
 ERROR: 0:159: 'flat/smooth/noperspective' : can't use interpolation qualifier on a fragment output 
 ERROR: 0:160: 'noperspective' : Reserved word. 
-ERROR: 0:160: 'noperspective' : not supported with this profile: es
+ERROR: 0:160: 'noperspective' : not supported for this version or the enabled extensions 
 ERROR: 0:160: 'flat/smooth/noperspective' : can't use interpolation qualifier on a fragment output 
 ERROR: 0:165: 'centroid/sample/patch' : can't use auxiliary qualifier on a fragment output 
 ERROR: 0:180: 'interpolateAtCentroid' : no matching overloaded function found 
@@ -211,12 +211,12 @@
 0:113        move second child to first child ( temp highp int)
 0:113          'a3' ( temp highp int)
 0:113          direct index ( flat temp highp int SampleMaskIn)
-0:113            'gl_SampleMaskIn' ( flat in implicitly-sized array of highp int SampleMaskIn)
+0:113            'gl_SampleMaskIn' ( flat in unsized 1-element array of highp int SampleMaskIn)
 0:113            Constant:
 0:113              0 (const int)
 0:114      move second child to first child ( temp highp int)
 0:114        direct index ( temp highp int SampleMaskIn)
-0:114          'gl_SampleMask' ( out implicitly-sized array of highp int SampleMaskIn)
+0:114          'gl_SampleMask' ( out unsized 1-element array of highp int SampleMaskIn)
 0:114          Constant:
 0:114            0 (const int)
 0:114        'a3' ( temp highp int)
@@ -473,8 +473,8 @@
 0:?     'CA5' ( uniform highp samplerCubeArrayShadow)
 0:?     'CA6' ( uniform highp isamplerCubeArray)
 0:?     'CA7' ( uniform highp usamplerCubeArray)
-0:?     'gl_SampleMaskIn' ( flat in implicitly-sized array of highp int SampleMaskIn)
-0:?     'gl_SampleMask' ( out implicitly-sized array of highp int SampleMaskIn)
+0:?     'gl_SampleMaskIn' ( flat in unsized 1-element array of highp int SampleMaskIn)
+0:?     'gl_SampleMask' ( out unsized 1-element array of highp int SampleMaskIn)
 0:?     'im2Df' (layout( r32f) uniform highp image2D)
 0:?     'im2Du' (layout( r32ui) uniform highp uimage2D)
 0:?     'im2Di' (layout( r32i) uniform highp iimage2D)
diff --git a/Test/baseResults/320.tesc.out b/Test/baseResults/320.tesc.out
index ff8012b..41ee29c 100755
--- a/Test/baseResults/320.tesc.out
+++ b/Test/baseResults/320.tesc.out
@@ -62,8 +62,8 @@
 0:23        move second child to first child ( temp highp 4-component vector of float)
 0:23          'p' ( temp highp 4-component vector of float)
 0:23          gl_Position: direct index for structure ( in highp 4-component vector of float Position)
-0:23            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
-0:23              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
+0:23            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
+0:23              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
 0:23              Constant:
 0:23                1 (const int)
 0:23            Constant:
@@ -72,8 +72,8 @@
 0:24        move second child to first child ( temp highp float)
 0:24          'ps' ( temp highp float)
 0:24          gl_PointSize: direct index for structure ( in highp float PointSize)
-0:24            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
-0:24              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
+0:24            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
+0:24              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
 0:24              Constant:
 0:24                1 (const int)
 0:24            Constant:
@@ -192,8 +192,8 @@
 0:104        move second child to first child ( temp highp float)
 0:104          'ps' ( temp highp float)
 0:104          gl_PointSize: direct index for structure ( in highp float PointSize)
-0:104            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
-0:104              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
+0:104            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
+0:104              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
 0:104              Constant:
 0:104                1 (const int)
 0:104            Constant:
@@ -336,7 +336,7 @@
 0:?     'inb' ( in 32-element array of highp 2-component vector of float)
 0:?     'inc' ( in 32-element array of highp 2-component vector of float)
 0:?     'ind' ( in 32-element array of highp 2-component vector of float)
-0:?     'implA' ( patch out implicitly-sized array of highp float)
+0:?     'implA' ( patch out unsized 1-element array of highp float)
 0:?     'ivla' (layout( location=3) in 32-element array of highp 4-component vector of float)
 0:?     'ivlb' (layout( location=4) in 32-element array of highp 4-component vector of float)
 0:?     'ivlc' (layout( location=4) in 32-element array of highp 4-component vector of float)
@@ -351,7 +351,7 @@
 0:?     'misSized' ( out 5-element array of highp float)
 0:?     'okaySize' ( out 4-element array of highp float)
 0:?     'pv3' ( noContraction temp highp 3-component vector of float)
-0:?     'badpatchIName' ( patch out implicitly-sized array of block{ out highp float f})
+0:?     'badpatchIName' ( patch out unsized 1-element array of block{ out highp float f})
 0:?     'patchIName' ( patch out 4-element array of block{ out highp float f})
 
 
diff --git a/Test/baseResults/320.tese.out b/Test/baseResults/320.tese.out
index ad8fe72..456bd88 100755
--- a/Test/baseResults/320.tese.out
+++ b/Test/baseResults/320.tese.out
@@ -21,10 +21,10 @@
 ERROR: 0:47: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:48: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:49: 'noperspective' : Reserved word. 
-ERROR: 0:49: 'noperspective' : not supported with this profile: es
+ERROR: 0:49: 'noperspective' : not supported for this version or the enabled extensions 
 ERROR: 0:49: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:50: '' : can only have one auxiliary qualifier (centroid, patch, and sample) 
-ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as implicitly-sized 
+ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as unsized 
 ERROR: 0:59: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use 
 ERROR: 0:64: 'quads' : cannot apply to 'out' 
 ERROR: 0:64: 'cw' : can only apply to 'in' 
@@ -67,8 +67,8 @@
 0:32        move second child to first child ( temp highp 4-component vector of float)
 0:32          'p' ( temp highp 4-component vector of float)
 0:32          gl_Position: direct index for structure ( in highp 4-component vector of float Position)
-0:32            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
-0:32              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
+0:32            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
+0:32              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
 0:32              Constant:
 0:32                1 (const int)
 0:32            Constant:
@@ -77,8 +77,8 @@
 0:33        move second child to first child ( temp highp float)
 0:33          'ps' ( temp highp float)
 0:33          gl_PointSize: direct index for structure ( in highp float PointSize)
-0:33            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
-0:33              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in implicitly-sized array of highp 4-component vector of float gl_PositionPerViewNV})
+0:33            direct index ( temp block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
+0:33              'gl_in' ( in 32-element array of block{ in highp 4-component vector of float Position gl_Position,  in highp float PointSize gl_PointSize,  in highp 4-component vector of float gl_SecondaryPositionNV,  in unsized 1-element array of highp 4-component vector of float gl_PositionPerViewNV})
 0:33              Constant:
 0:33                1 (const int)
 0:33            Constant:
diff --git a/Test/baseResults/330.frag.out b/Test/baseResults/330.frag.out
index 5919c76..7745631 100644
--- a/Test/baseResults/330.frag.out
+++ b/Test/baseResults/330.frag.out
@@ -16,6 +16,7 @@
 ERROR: 0:62: 'location on block member' : can only use in an in/out block 
 ERROR: 0:62: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions 
 ERROR: 0:60: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions 
+ERROR: 0:60: 'location' : cannot apply to uniform or buffer block 
 ERROR: 0:68: 'layout-id value' : cannot be negative 
 ERROR: 0:69: 'layout-id value' : cannot be negative 
 ERROR: 0:76: 'f2' : cannot use layout qualifiers on structure members 
@@ -23,6 +24,7 @@
 ERROR: 0:91: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions 
 ERROR: 0:91: 'location' : overlapping use of location 3
 ERROR: 0:89: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions 
+ERROR: 0:89: 'location' : cannot apply to uniform or buffer block 
 ERROR: 0:94: 'location' : either the block needs a location, or all members need a location, or no members have a location 
 ERROR: 0:108: 'A' : cannot use layout qualifiers on structure members 
 ERROR: 0:119: 'location' : overlapping use of location 44
@@ -38,7 +40,7 @@
 ERROR: 0:141: 'textureQueryLod' : no matching overloaded function found 
 ERROR: 0:141: 'assign' :  cannot convert from ' const float' to ' temp 2-component vector of float'
 ERROR: 0:152: 'index' : value must be 0 or 1 
-ERROR: 39 compilation errors.  No code generated.
+ERROR: 41 compilation errors.  No code generated.
 
 
 Shader version: 330
diff --git a/Test/baseResults/400.frag.out b/Test/baseResults/400.frag.out
index 443b102..90f73dc 100644
--- a/Test/baseResults/400.frag.out
+++ b/Test/baseResults/400.frag.out
@@ -516,7 +516,7 @@
 0:?     'vl' (layout( location=4) smooth in 4-component vector of float)
 0:?     'vl2' (layout( location=6) smooth in 4-component vector of float)
 0:?     'uv3' (layout( location=3) uniform 3-component vector of float)
-0:?     'anon@0' ( in block{ in float FogFragCoord gl_FogFragCoord,  in implicitly-sized array of 4-component vector of float TexCoord gl_TexCoord,  smooth in 4-component vector of float Color gl_Color,  in 4-component vector of float SecondaryColor gl_SecondaryColor})
+0:?     'anon@0' ( in block{ in float FogFragCoord gl_FogFragCoord,  in unsized 1-element array of 4-component vector of float TexCoord gl_TexCoord,  smooth in 4-component vector of float Color gl_Color,  in 4-component vector of float SecondaryColor gl_SecondaryColor})
 0:?     'gl_FragCoord' ( gl_FragCoord 4-component vector of float FragCoord)
 0:?     'u2drs' ( uniform sampler2DRectShadow)
 0:?     'patchIn' ( smooth patch in 4-component vector of float)
diff --git a/Test/baseResults/400.geom.out b/Test/baseResults/400.geom.out
index 1d009d9..52ebebc 100644
--- a/Test/baseResults/400.geom.out
+++ b/Test/baseResults/400.geom.out
@@ -1,7 +1,7 @@
 400.geom
 ERROR: 0:12: 'invocations' : can only apply to a standalone qualifier 
 ERROR: 0:20: 'patch' : not supported in this stage: geometry
-ERROR: 0:20: 'gl_PointSize' : cannot add layout to redeclared block member 
+ERROR: 0:20: 'gl_PointSize' : cannot add non-XFB layout to redeclared block member 
 ERROR: 0:20: 'gl_PointSize' : cannot add patch to redeclared block member 
 ERROR: 0:25: 'length' :  array must first be sized by a redeclaration or layout qualifier
 ERROR: 0:36: 'length' :  array must first be sized by a redeclaration or layout qualifier
diff --git a/Test/baseResults/400.tesc.out b/Test/baseResults/400.tesc.out
index 762f0b8..0475741 100644
--- a/Test/baseResults/400.tesc.out
+++ b/Test/baseResults/400.tesc.out
@@ -44,8 +44,8 @@
 0:23        move second child to first child ( temp 4-component vector of float)
 0:23          'p' ( temp 4-component vector of float)
 0:23          gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:23            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:23              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:23            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:23              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:23              Constant:
 0:23                1 (const int)
 0:23            Constant:
@@ -54,8 +54,8 @@
 0:24        move second child to first child ( temp float)
 0:24          'ps' ( temp float)
 0:24          gl_PointSize: direct index for structure ( in float PointSize)
-0:24            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:24              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:24            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:24              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:24              Constant:
 0:24                1 (const int)
 0:24            Constant:
@@ -64,9 +64,9 @@
 0:25        move second child to first child ( temp float)
 0:25          'cd' ( temp float)
 0:25          direct index ( temp float ClipDistance)
-0:25            gl_ClipDistance: direct index for structure ( in implicitly-sized array of float ClipDistance)
-0:25              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:25                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:25            gl_ClipDistance: direct index for structure ( in unsized 3-element array of float ClipDistance)
+0:25              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:25                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:25                Constant:
 0:25                  1 (const int)
 0:25              Constant:
@@ -87,25 +87,25 @@
 0:29          'gl_InvocationID' ( in int InvocationID)
 0:31      move second child to first child ( temp 4-component vector of float)
 0:31        gl_Position: direct index for structure ( out 4-component vector of float Position)
-0:31          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:31            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:31          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:31            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:31            'gl_InvocationID' ( in int InvocationID)
 0:31          Constant:
 0:31            0 (const int)
 0:31        'p' ( temp 4-component vector of float)
 0:32      move second child to first child ( temp float)
 0:32        gl_PointSize: direct index for structure ( out float PointSize)
-0:32          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:32            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:32          indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:32            'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:32            'gl_InvocationID' ( in int InvocationID)
 0:32          Constant:
 0:32            1 (const int)
 0:32        'ps' ( temp float)
 0:33      move second child to first child ( temp float)
 0:33        direct index ( temp float ClipDistance)
-0:33          gl_ClipDistance: direct index for structure ( out implicitly-sized array of float ClipDistance)
-0:33            indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:33              'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:33          gl_ClipDistance: direct index for structure ( out unsized 2-element array of float ClipDistance)
+0:33            indirect index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:33              'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:33              'gl_InvocationID' ( in int InvocationID)
 0:33            Constant:
 0:33              2 (const int)
@@ -175,8 +175,8 @@
 0:67    Function Parameters: 
 0:69    Sequence
 0:69      gl_PointSize: direct index for structure ( out float PointSize)
-0:69        direct index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:69          'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:69        direct index ( temp block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
+0:69          'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:69          Constant:
 0:69            4 (const int)
 0:69        Constant:
@@ -211,7 +211,7 @@
 0:123      'gl_DeviceIndex' ( in int DeviceIndex)
 0:124      'gl_ViewIndex' ( in int ViewIndex)
 0:?   Linker Objects
-0:?     'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'gl_out' ( out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance})
 0:?     'outa' ( global 4-element array of int)
 0:?     'patchIn' ( patch in 4-component vector of float)
 0:?     'patchOut' ( patch out 4-component vector of float)
diff --git a/Test/baseResults/400.tese.out b/Test/baseResults/400.tese.out
index e9ffcdf..28c4468 100644
--- a/Test/baseResults/400.tese.out
+++ b/Test/baseResults/400.tese.out
@@ -11,7 +11,7 @@
 ERROR: 0:48: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:49: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:50: '' : can only have one auxiliary qualifier (centroid, patch, and sample) 
-ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as implicitly-sized 
+ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as unsized 
 ERROR: 0:59: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use 
 ERROR: 0:64: 'quads' : cannot apply to 'out' 
 ERROR: 0:64: 'cw' : can only apply to 'in' 
@@ -57,8 +57,8 @@
 0:32        move second child to first child ( temp 4-component vector of float)
 0:32          'p' ( temp 4-component vector of float)
 0:32          gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:32            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:32              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:32            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:32              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:32              Constant:
 0:32                1 (const int)
 0:32            Constant:
@@ -67,8 +67,8 @@
 0:33        move second child to first child ( temp float)
 0:33          'ps' ( temp float)
 0:33          gl_PointSize: direct index for structure ( in float PointSize)
-0:33            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:33              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:33            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:33              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:33              Constant:
 0:33                1 (const int)
 0:33            Constant:
@@ -77,9 +77,9 @@
 0:34        move second child to first child ( temp float)
 0:34          'cd' ( temp float)
 0:34          direct index ( temp float ClipDistance)
-0:34            gl_ClipDistance: direct index for structure ( in implicitly-sized array of float ClipDistance)
-0:34              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:34                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:34            gl_ClipDistance: direct index for structure ( in unsized 3-element array of float ClipDistance)
+0:34              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:34                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:34                Constant:
 0:34                  1 (const int)
 0:34              Constant:
@@ -114,20 +114,20 @@
 0:40              1 (const int)
 0:42      move second child to first child ( temp 4-component vector of float)
 0:42        gl_Position: direct index for structure ( gl_Position 4-component vector of float Position)
-0:42          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:42          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:42          Constant:
 0:42            0 (const uint)
 0:42        'p' ( temp 4-component vector of float)
 0:43      move second child to first child ( temp float)
 0:43        gl_PointSize: direct index for structure ( gl_PointSize float PointSize)
-0:43          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:43          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:43          Constant:
 0:43            1 (const uint)
 0:43        'ps' ( temp float)
 0:44      move second child to first child ( temp float)
 0:44        direct index ( temp float ClipDistance)
-0:44          gl_ClipDistance: direct index for structure ( out implicitly-sized array of float ClipDistance)
-0:44            'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:44          gl_ClipDistance: direct index for structure ( out unsized 3-element array of float ClipDistance)
+0:44            'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:44            Constant:
 0:44              2 (const uint)
 0:44          Constant:
@@ -146,7 +146,7 @@
 0:?   Linker Objects
 0:?     'patchIn' ( patch in 4-component vector of float)
 0:?     'patchOut' ( patch out 4-component vector of float)
-0:?     'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:?     'badp1' ( smooth patch in 4-component vector of float)
 0:?     'badp2' ( flat patch in 4-component vector of float)
 0:?     'badp3' ( noperspective patch in 4-component vector of float)
diff --git a/Test/baseResults/410.geom.out b/Test/baseResults/410.geom.out
index 4d35d52..ab5ad47 100644
--- a/Test/baseResults/410.geom.out
+++ b/Test/baseResults/410.geom.out
@@ -31,7 +31,7 @@
 0:30          'p' ( temp float)
 0:30          gl_PointSize: direct index for structure ( in float PointSize)
 0:30            direct index ( temp block{ in float PointSize gl_PointSize})
-0:30              'gl_in' ( in implicitly-sized array of block{ in float PointSize gl_PointSize})
+0:30              'gl_in' ( in unsized 2-element array of block{ in float PointSize gl_PointSize})
 0:30              Constant:
 0:30                1 (const int)
 0:30            Constant:
@@ -53,7 +53,7 @@
 0:38        Constant:
 0:38          4.000000
 0:?   Linker Objects
-0:?     'gl_in' ( in implicitly-sized array of block{ in float PointSize gl_PointSize})
+0:?     'gl_in' ( in unsized 2-element array of block{ in float PointSize gl_PointSize})
 0:?     'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize, })
 
 
diff --git a/Test/baseResults/410.tesc.out b/Test/baseResults/410.tesc.out
index 68593d0..0a397fd 100644
--- a/Test/baseResults/410.tesc.out
+++ b/Test/baseResults/410.tesc.out
@@ -9,7 +9,7 @@
 0:8  Function Definition: main( ( global void)
 0:8    Function Parameters: 
 0:?   Linker Objects
-0:?     'gl_out' ( out implicitly-sized array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'gl_out' ( out unsized 1-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 1-element array of float ClipDistance gl_ClipDistance})
 0:?     'outa' ( global 1-element array of int)
 0:?     'patchOut' ( patch out 4-component vector of float)
 
diff --git a/Test/baseResults/420.frag.out b/Test/baseResults/420.frag.out
index 5f2b0f7..ffb8f6d 100644
--- a/Test/baseResults/420.frag.out
+++ b/Test/baseResults/420.frag.out
@@ -19,7 +19,7 @@
 0:?   Linker Objects
 0:?     'gl_FragDepth' ( gl_FragDepth float FragDepth)
 0:?     'depth' ( smooth in float)
-0:?     'a' (layout( binding=0 offset=0) uniform implicitly-sized array of atomic_uint)
+0:?     'a' (layout( binding=0 offset=0) uniform unsized 1-element array of atomic_uint)
 
 
 Linked fragment stage:
diff --git a/Test/baseResults/420.geom.out b/Test/baseResults/420.geom.out
index fe9e12f..6bf6eb3 100644
--- a/Test/baseResults/420.geom.out
+++ b/Test/baseResults/420.geom.out
@@ -20,15 +20,15 @@
 0:9      Constant:
 0:9        1 (const int)
 0:10      gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:10        direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:10          'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:10        direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
+0:10          'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
 0:10          Constant:
 0:10            1 (const int)
 0:10        Constant:
 0:10          0 (const int)
 0:11      gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:11        indirect index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:11          'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:11        indirect index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
+0:11          'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
 0:11          'i' ( global int)
 0:11        Constant:
 0:11          0 (const int)
@@ -38,8 +38,8 @@
 0:20      Constant:
 0:20        3 (const int)
 0:21      gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:21        indirect index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:21          'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:21        indirect index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
+0:21          'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
 0:21          'i' ( global int)
 0:21        Constant:
 0:21          0 (const int)
@@ -121,12 +121,12 @@
 0:54          'i' ( global int)
 0:?   Linker Objects
 0:?     'i' ( global int)
-0:?     'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
 0:?     'color3' ( in 3-element array of 4-component vector of float)
 0:?     's2D' ( uniform sampler2D)
 0:?     'coord' ( in 3-element array of 2-component vector of float)
 0:?     'v4' ( uniform 4-component vector of float)
-0:?     'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize, layout( stream=0) out unsized 1-element array of float ClipDistance gl_ClipDistance})
 
 
 Linked geometry stage:
diff --git a/Test/baseResults/420.tesc.out b/Test/baseResults/420.tesc.out
index 7876bd6..a1f881c 100644
--- a/Test/baseResults/420.tesc.out
+++ b/Test/baseResults/420.tesc.out
@@ -20,8 +20,8 @@
 0:17        move second child to first child ( temp 4-component vector of float)
 0:17          'p' ( temp 4-component vector of float)
 0:17          gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:17            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:17              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:17            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:17              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:17              Constant:
 0:17                1 (const int)
 0:17            Constant:
@@ -30,8 +30,8 @@
 0:18        move second child to first child ( temp float)
 0:18          'ps' ( temp float)
 0:18          gl_PointSize: direct index for structure ( in float PointSize)
-0:18            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:18              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:18            direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:18              'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:18              Constant:
 0:18                1 (const int)
 0:18            Constant:
@@ -40,9 +40,9 @@
 0:19        move second child to first child ( temp float)
 0:19          'cd' ( temp float)
 0:19          direct index ( temp float ClipDistance)
-0:19            gl_ClipDistance: direct index for structure ( in implicitly-sized array of float ClipDistance)
-0:19              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:19                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:19            gl_ClipDistance: direct index for structure ( in unsized 3-element array of float ClipDistance)
+0:19              direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
+0:19                'gl_in' ( in 32-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 3-element array of float ClipDistance gl_ClipDistance})
 0:19                Constant:
 0:19                  1 (const int)
 0:19              Constant:
diff --git a/Test/baseResults/420.tese.out b/Test/baseResults/420.tese.out
index f14e1c0..71fca85 100644
--- a/Test/baseResults/420.tese.out
+++ b/Test/baseResults/420.tese.out
@@ -139,7 +139,7 @@
 0:?     'b3' ( global 2-element array of 4-component vector of float)
 0:?     'b4' ( global 2-element array of 4-component vector of float)
 0:?     'c3' ( global 4X2 matrix of float)
-0:?     'd2' ( global implicitly-sized array of structure{ global float s,  global float t})
+0:?     'd2' ( global unsized 1-element array of structure{ global float s,  global float t})
 0:?     'b5' ( global 5-element array of float)
 0:?     'single1' ( global structure{ global int f})
 0:?     'single2' ( global structure{ global 2-component vector of uint v})
diff --git a/Test/baseResults/420.vert.out b/Test/baseResults/420.vert.out
index b912dc0..25bce16 100644
--- a/Test/baseResults/420.vert.out
+++ b/Test/baseResults/420.vert.out
@@ -51,7 +51,7 @@
 ERROR: 0:157: 'assign' :  cannot convert from ' const float' to ' temp int'
 ERROR: 0:158: 'textureQueryLevels' : no matching overloaded function found 
 ERROR: 0:158: 'assign' :  cannot convert from ' const float' to ' temp int'
-WARNING: 0:161: '[]' : assuming array size of one for compile-time checking of binding numbers for implicitly-sized array 
+WARNING: 0:161: '[]' : assuming binding count of one for compile-time checking of binding numbers for unsized array 
 ERROR: 51 compilation errors.  No code generated.
 
 
@@ -302,7 +302,7 @@
 0:?     'offcheckI' (layout( column_major shared) uniform block{layout( column_major shared offset=16) uniform int foo})
 0:?     'samp1D' ( uniform sampler1D)
 0:?     'samp1Ds' ( uniform sampler1DShadow)
-0:?     'badArray' (layout( binding=0) writeonly uniform implicitly-sized array of image1D)
+0:?     'badArray' (layout( binding=0) writeonly uniform unsized 1-element array of image1D)
 0:?     'gl_VertexID' ( gl_VertexId int VertexId)
 0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
 
diff --git a/Test/baseResults/420_size_gl_in.geom.out b/Test/baseResults/420_size_gl_in.geom.out
index d058013..9d95495 100644
--- a/Test/baseResults/420_size_gl_in.geom.out
+++ b/Test/baseResults/420_size_gl_in.geom.out
@@ -15,8 +15,8 @@
 0:13      Constant:
 0:13        3 (const int)
 0:14      gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:14        direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:14          'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:14        direct index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
+0:14          'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
 0:14          Constant:
 0:14            1 (const int)
 0:14        Constant:
@@ -24,8 +24,8 @@
 0:15      Constant:
 0:15        3 (const int)
 0:16      gl_Position: direct index for structure ( in 4-component vector of float Position)
-0:16        indirect index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
-0:16          'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:16        indirect index ( temp block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
+0:16          'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
 0:16          'i' ( global int)
 0:16        Constant:
 0:16          0 (const int)
@@ -33,7 +33,7 @@
 0:?     'i' ( global int)
 0:?     'colorun' ( in 3-element array of 4-component vector of float)
 0:?     'color3' ( in 3-element array of 4-component vector of float)
-0:?     'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in implicitly-sized array of float ClipDistance gl_ClipDistance})
+0:?     'gl_in' ( in 3-element array of block{ in 4-component vector of float Position gl_Position,  in float PointSize gl_PointSize,  in unsized 1-element array of float ClipDistance gl_ClipDistance})
 
 
 Linked geometry stage:
diff --git a/Test/baseResults/430.comp.out b/Test/baseResults/430.comp.out
index c4ad19e..599cd8e 100644
--- a/Test/baseResults/430.comp.out
+++ b/Test/baseResults/430.comp.out
@@ -33,13 +33,13 @@
 0:35      GroupMemoryBarrier ( global void)
 0:36      move second child to first child ( temp int)
 0:36        value: direct index for structure (layout( column_major shared) buffer int)
-0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer implicitly-sized array of float values})
+0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
 0:36          Constant:
 0:36            0 (const uint)
 0:36        Convert float to int ( temp int)
 0:36          indirect index (layout( column_major shared) temp float)
-0:36            values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of float)
-0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer implicitly-sized array of float values})
+0:36            values: direct index for structure (layout( column_major shared) buffer runtime-sized array of float)
+0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
 0:36              Constant:
 0:36                1 (const uint)
 0:36            'gl_LocalInvocationIndex' ( in uint LocalInvocationIndex)
@@ -56,8 +56,8 @@
 0:65    Sequence
 0:65      move second child to first child ( temp float)
 0:65        direct index (layout( column_major shared) temp float)
-0:65          values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of float)
-0:65            'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer implicitly-sized array of float values})
+0:65          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of float)
+0:65            'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 3-element array of float values})
 0:65            Constant:
 0:65              1 (const int)
 0:65          Constant:
@@ -65,8 +65,8 @@
 0:65        Constant:
 0:65          4.700000
 0:66      array length ( temp int)
-0:66        values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of float)
-0:66          'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer implicitly-sized array of float values})
+0:66        values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of float)
+0:66          'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 3-element array of float values})
 0:66          Constant:
 0:66            1 (const int)
 0:67      Barrier ( global void)
@@ -129,8 +129,8 @@
 0:?       4096 (const uint)
 0:?     'total' ( const int)
 0:?       66592 (const int)
-0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer implicitly-sized array of float values})
-0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer implicitly-sized array of float values, layout( column_major shared) buffer int value})
+0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
+0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 1-element array of float values, layout( column_major shared) buffer int value})
 0:?     'v3' (layout( location=2) in 3-component vector of float)
 0:?     'f' ( in float)
 0:?     'fo' ( out float)
@@ -140,7 +140,7 @@
 0:?     'arrX' ( global 2-element array of int)
 0:?     'arrY' ( global 1-element array of int)
 0:?     'arrZ' ( global 4096-element array of int)
-0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer implicitly-sized array of float values})
+0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 3-element array of float values})
 0:?     'roll' ( uniform double)
 0:?     'destTex' ( writeonly uniform image2D)
 0:?     'inbi' ( in block{ in int a})
@@ -165,13 +165,13 @@
 0:35      GroupMemoryBarrier ( global void)
 0:36      move second child to first child ( temp int)
 0:36        value: direct index for structure (layout( column_major shared) buffer int)
-0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer implicitly-sized array of float values})
+0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
 0:36          Constant:
 0:36            0 (const uint)
 0:36        Convert float to int ( temp int)
 0:36          indirect index (layout( column_major shared) temp float)
-0:36            values: direct index for structure (layout( column_major shared) buffer implicitly-sized array of float)
-0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer implicitly-sized array of float values})
+0:36            values: direct index for structure (layout( column_major shared) buffer runtime-sized array of float)
+0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
 0:36              Constant:
 0:36                1 (const uint)
 0:36            'gl_LocalInvocationIndex' ( in uint LocalInvocationIndex)
@@ -190,8 +190,8 @@
 0:?       4096 (const uint)
 0:?     'total' ( const int)
 0:?       66592 (const int)
-0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer implicitly-sized array of float values})
-0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer implicitly-sized array of float values, layout( column_major shared) buffer int value})
+0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
+0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer 1-element array of float values, layout( column_major shared) buffer int value})
 0:?     'v3' (layout( location=2) in 3-component vector of float)
 0:?     'f' ( in float)
 0:?     'fo' ( out float)
@@ -201,7 +201,7 @@
 0:?     'arrX' ( global 2-element array of int)
 0:?     'arrY' ( global 1-element array of int)
 0:?     'arrZ' ( global 4096-element array of int)
-0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer implicitly-sized array of float values})
+0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 3-element array of float values})
 0:?     'roll' ( uniform double)
 0:?     'destTex' ( writeonly uniform image2D)
 0:?     'inbi' ( in block{ in int a})
diff --git a/Test/baseResults/430AofA.frag.out b/Test/baseResults/430AofA.frag.out
index 788a8d1..ac23dac 100644
--- a/Test/baseResults/430AofA.frag.out
+++ b/Test/baseResults/430AofA.frag.out
@@ -7,7 +7,7 @@
 ERROR: 0:60: 'constructor' :  cannot convert parameter 2 from ' const 2-element array of 4-component vector of float' to ' temp 3-element array of 4-component vector of float'
 ERROR: 0:64: '=' :  cannot convert from ' const 3-element array of 2-element array of 4-component vector of float' to ' temp 4-element array of 2-element array of 4-component vector of float'
 ERROR: 0:70: 'assign' :  cannot convert from ' global 4-element array of 7-element array of float' to ' global 5-element array of 7-element array of float'
-ERROR: 0:71: 'assign' :  cannot convert from ' global 4-element array of 7-element array of float' to ' global implicitly-sized array of 7-element array of float'
+ERROR: 0:71: 'assign' :  cannot convert from ' global 4-element array of 7-element array of float' to ' global unsized 1-element array of 7-element array of float'
 ERROR: 0:73: 'foo' : no matching overloaded function found 
 ERROR: 0:78: '==' :  wrong operand types: no operation '==' exists that takes a left-hand operand of type ' global 4-element array of 7-element array of float' and a right operand of type ' global 5-element array of 7-element array of float' (or there is no acceptable conversion)
 ERROR: 0:84: '[' :  array index out of range '5'
@@ -335,7 +335,7 @@
 0:69        Function Call: foo(f1[5][7]; ( global 4-element array of 7-element array of float)
 0:69          'g5' ( global 5-element array of 7-element array of float)
 0:70      'g5' ( global 5-element array of 7-element array of float)
-0:71      'gu' ( global implicitly-sized array of 7-element array of float)
+0:71      'gu' ( global unsized 1-element array of 7-element array of float)
 0:73      Constant:
 0:73        0.000000
 0:74      Function Call: bar(f1[5][7]; ( global void)
@@ -404,8 +404,8 @@
 0:98        0.000000
 0:?   Linker Objects
 0:?     'many' ( global 1-element array of 2-element array of 3-element array of 4-element array of 5-element array of 6-element array of float)
-0:?     'gu' ( global implicitly-sized array of 7-element array of float)
-0:?     'gimp' ( global implicitly-sized array of implicitly-sized array of float)
+0:?     'gu' ( global unsized 1-element array of 7-element array of float)
+0:?     'gimp' ( global unsized 1-element array of 1-element array of float)
 0:?     'g4' ( global 4-element array of 7-element array of float)
 0:?     'g5' ( global 5-element array of 7-element array of float)
 
@@ -768,7 +768,7 @@
 0:?   Linker Objects
 0:?     'many' ( global 1-element array of 2-element array of 3-element array of 4-element array of 5-element array of 6-element array of float)
 0:?     'gu' ( global 1-element array of 7-element array of float)
-0:?     'gimp' ( global 1-element array of implicitly-sized array of float)
+0:?     'gimp' ( global 1-element array of 1-element array of float)
 0:?     'g4' ( global 4-element array of 7-element array of float)
 0:?     'g5' ( global 5-element array of 7-element array of float)
 
diff --git a/Test/baseResults/430scope.vert.out b/Test/baseResults/430scope.vert.out
index 0d91389..973c21a 100644
--- a/Test/baseResults/430scope.vert.out
+++ b/Test/baseResults/430scope.vert.out
@@ -63,7 +63,7 @@
 0:47          3.000000
 0:49      move second child to first child ( temp 4-component vector of float)
 0:49        gl_Position: direct index for structure ( invariant gl_Position 4-component vector of float Position)
-0:49          'anon@0' ( out block{ invariant gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out implicitly-sized array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
+0:49          'anon@0' ( out block{ invariant gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 1-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out unsized 1-element array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
 0:49          Constant:
 0:49            0 (const uint)
 0:49        Construct vec4 ( temp 4-component vector of float)
diff --git a/Test/baseResults/440.vert.out b/Test/baseResults/440.vert.out
index 8eafb0a..41796cb 100644
--- a/Test/baseResults/440.vert.out
+++ b/Test/baseResults/440.vert.out
@@ -46,51 +46,54 @@
 ERROR: 0:169: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
 ERROR: 0:169: 'xfb_stride' : 1/4 stride is too large: gl_MaxTransformFeedbackInterleavedComponents is 64
 ERROR: 0:171: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
-ERROR: 0:179: 'gl_BaseVertexARB' : required extension not requested: GL_ARB_shader_draw_parameters
-ERROR: 0:179: 'gl_BaseInstanceARB' : required extension not requested: GL_ARB_shader_draw_parameters
-ERROR: 0:179: 'gl_DrawIDARB' : required extension not requested: GL_ARB_shader_draw_parameters
-ERROR: 0:187: 'assign' :  l-value required "gl_BaseVertexARB" (can't modify shader input)
-ERROR: 0:188: 'assign' :  l-value required "gl_BaseInstanceARB" (can't modify shader input)
-ERROR: 0:189: 'assign' :  l-value required "gl_DrawIDARB" (can't modify shader input)
-ERROR: 0:190: 'glBaseInstanceARB' : undeclared identifier 
-ERROR: 54 compilation errors.  No code generated.
+ERROR: 0:178: 'xfb_offset' : overlapping offsets at offset 36 in buffer 3
+ERROR: 0:179: 'xfb_buffer' : member cannot contradict block (or what block inherited from global) 
+ERROR: 0:178: 'xfb_offset' : overlapping offsets at offset 32 in buffer 3
+ERROR: 0:185: 'gl_BaseVertexARB' : required extension not requested: GL_ARB_shader_draw_parameters
+ERROR: 0:185: 'gl_BaseInstanceARB' : required extension not requested: GL_ARB_shader_draw_parameters
+ERROR: 0:185: 'gl_DrawIDARB' : required extension not requested: GL_ARB_shader_draw_parameters
+ERROR: 0:193: 'assign' :  l-value required "gl_BaseVertexARB" (can't modify shader input)
+ERROR: 0:194: 'assign' :  l-value required "gl_BaseInstanceARB" (can't modify shader input)
+ERROR: 0:195: 'assign' :  l-value required "gl_DrawIDARB" (can't modify shader input)
+ERROR: 0:196: 'glBaseInstanceARB' : undeclared identifier 
+ERROR: 57 compilation errors.  No code generated.
 
 
 Shader version: 440
 Requested GL_ARB_shader_draw_parameters
 in xfb mode
 ERROR: node is still EOpNull!
-0:177  Function Definition: drawParamsBad( ( global int)
-0:177    Function Parameters: 
-0:179    Sequence
-0:179      Branch: Return with expression
-0:179        add ( temp int)
-0:179          add ( temp int)
-0:179            'gl_BaseVertexARB' ( in int BaseVertex)
-0:179            'gl_BaseInstanceARB' ( in int BaseInstance)
-0:179          'gl_DrawIDARB' ( in int DrawId)
-0:184  Function Definition: drawParams( ( global int)
-0:184    Function Parameters: 
-0:186    Sequence
-0:186      Branch: Return with expression
-0:186        add ( temp int)
-0:186          add ( temp int)
-0:186            'gl_BaseVertexARB' ( in int BaseVertex)
-0:186            'gl_BaseInstanceARB' ( in int BaseInstance)
-0:186          'gl_DrawIDARB' ( in int DrawId)
-0:187      move second child to first child ( temp int)
-0:187        'gl_BaseVertexARB' ( in int BaseVertex)
-0:187        Constant:
-0:187          3 (const int)
-0:188      move second child to first child ( temp int)
-0:188        'gl_BaseInstanceARB' ( in int BaseInstance)
-0:188        Constant:
-0:188          3 (const int)
-0:189      move second child to first child ( temp int)
-0:189        'gl_DrawIDARB' ( in int DrawId)
-0:189        Constant:
-0:189          3 (const int)
-0:190      'glBaseInstanceARB' ( temp float)
+0:183  Function Definition: drawParamsBad( ( global int)
+0:183    Function Parameters: 
+0:185    Sequence
+0:185      Branch: Return with expression
+0:185        add ( temp int)
+0:185          add ( temp int)
+0:185            'gl_BaseVertexARB' ( in int BaseVertex)
+0:185            'gl_BaseInstanceARB' ( in int BaseInstance)
+0:185          'gl_DrawIDARB' ( in int DrawId)
+0:190  Function Definition: drawParams( ( global int)
+0:190    Function Parameters: 
+0:192    Sequence
+0:192      Branch: Return with expression
+0:192        add ( temp int)
+0:192          add ( temp int)
+0:192            'gl_BaseVertexARB' ( in int BaseVertex)
+0:192            'gl_BaseInstanceARB' ( in int BaseInstance)
+0:192          'gl_DrawIDARB' ( in int DrawId)
+0:193      move second child to first child ( temp int)
+0:193        'gl_BaseVertexARB' ( in int BaseVertex)
+0:193        Constant:
+0:193          3 (const int)
+0:194      move second child to first child ( temp int)
+0:194        'gl_BaseInstanceARB' ( in int BaseInstance)
+0:194        Constant:
+0:194          3 (const int)
+0:195      move second child to first child ( temp int)
+0:195        'gl_DrawIDARB' ( in int DrawId)
+0:195        Constant:
+0:195          3 (const int)
+0:196      'glBaseInstanceARB' ( temp float)
 0:?   Linker Objects
 0:?     'a' (layout( location=2 component=2) in 2-component vector of float)
 0:?     'b' (layout( location=2 component=1) in float)
@@ -153,6 +156,7 @@
 0:?     'bbinst9' ( out block{layout( xfb_buffer=4 xfb_offset=1) out bool b, layout( xfb_buffer=4 xfb_offset=12) out structure{ global bool b,  global structure{ global int i,  global double d,  global float f} s,  global 2-component vector of float v2} t, layout( xfb_buffer=4 xfb_offset=52) out 3X3 matrix of float m3, layout( xfb_buffer=4 xfb_offset=90) out int i, layout( xfb_buffer=4 xfb_offset=98) out double d, layout( xfb_buffer=4 xfb_offset=108) out structure{ global int a} s})
 0:?     'bm' (layout( xfb_buffer=5 xfb_offset=0) smooth out float)
 0:?     'bbinst10' ( out block{layout( xfb_buffer=7 xfb_offset=0) out 4X4 matrix of double m1, layout( xfb_buffer=7 xfb_offset=128) out 4X4 matrix of double m2, layout( xfb_buffer=7 xfb_offset=256) out float f})
+0:?     'anon@0' ( out block{layout( xfb_buffer=3 xfb_offset=36) gl_Position 4-component vector of float Position gl_Position, layout( xfb_buffer=3 xfb_offset=32) gl_PointSize float PointSize gl_PointSize, })
 0:?     'gl_VertexID' ( gl_VertexId int VertexId)
 0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
 
@@ -235,6 +239,7 @@
 0:?     'bbinst9' ( out block{layout( xfb_buffer=4 xfb_offset=1) out bool b, layout( xfb_buffer=4 xfb_offset=12) out structure{ global bool b,  global structure{ global int i,  global double d,  global float f} s,  global 2-component vector of float v2} t, layout( xfb_buffer=4 xfb_offset=52) out 3X3 matrix of float m3, layout( xfb_buffer=4 xfb_offset=90) out int i, layout( xfb_buffer=4 xfb_offset=98) out double d, layout( xfb_buffer=4 xfb_offset=108) out structure{ global int a} s})
 0:?     'bm' (layout( xfb_buffer=5 xfb_offset=0) smooth out float)
 0:?     'bbinst10' ( out block{layout( xfb_buffer=7 xfb_offset=0) out 4X4 matrix of double m1, layout( xfb_buffer=7 xfb_offset=128) out 4X4 matrix of double m2, layout( xfb_buffer=7 xfb_offset=256) out float f})
+0:?     'anon@0' ( out block{layout( xfb_buffer=3 xfb_offset=36) gl_Position 4-component vector of float Position gl_Position, layout( xfb_buffer=3 xfb_offset=32) gl_PointSize float PointSize gl_PointSize, })
 0:?     'gl_VertexID' ( gl_VertexId int VertexId)
 0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
 
diff --git a/Test/baseResults/450.vert.out b/Test/baseResults/450.vert.out
index 64143de..0f5f231 100644
--- a/Test/baseResults/450.vert.out
+++ b/Test/baseResults/450.vert.out
@@ -19,7 +19,9 @@
 ERROR: 0:45: 'allInvocations' : no matching overloaded function found 
 ERROR: 0:46: 'allInvocationsEqual' : no matching overloaded function found 
 ERROR: 0:48: 'extraneous semicolon' : not supported for this version or the enabled extensions 
-ERROR: 20 compilation errors.  No code generated.
+ERROR: 0:50: 'location' : cannot apply to uniform or buffer block 
+ERROR: 0:54: 'location' : cannot apply to uniform or buffer block 
+ERROR: 22 compilation errors.  No code generated.
 
 
 Shader version: 450
@@ -77,6 +79,8 @@
 0:?     'outSS' ( smooth out structure{ global float f,  global structure{ global float f} s})
 0:?     'aui' (layout( binding=0 offset=0) uniform atomic_uint)
 0:?     'ui' ( global uint)
+0:?     'anon@1' (layout( location=0 column_major shared) uniform block{layout( column_major shared) uniform int a})
+0:?     'anon@2' (layout( location=0 column_major shared) buffer block{layout( column_major shared) buffer int b})
 0:?     'gl_VertexID' ( gl_VertexId int VertexId)
 0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
 
@@ -112,6 +116,8 @@
 0:?     'outSS' ( smooth out structure{ global float f,  global structure{ global float f} s})
 0:?     'aui' (layout( binding=0 offset=0) uniform atomic_uint)
 0:?     'ui' ( global uint)
+0:?     'anon@1' (layout( location=0 column_major shared) uniform block{layout( column_major shared) uniform int a})
+0:?     'anon@2' (layout( location=0 column_major shared) buffer block{layout( column_major shared) buffer int b})
 0:?     'gl_VertexID' ( gl_VertexId int VertexId)
 0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
 
diff --git a/Test/baseResults/460.frag.out b/Test/baseResults/460.frag.out
index 883d949..90c4837 100755
--- a/Test/baseResults/460.frag.out
+++ b/Test/baseResults/460.frag.out
@@ -1,6 +1,14 @@
 460.frag
+ERROR: 0:22: 'attribute' : required extension not requested: GL_EXT_control_flow_attributes
+ERROR: 0:23: 'attribute' : required extension not requested: GL_EXT_control_flow_attributes
+ERROR: 0:30: 'dependency_length' : must be positive 
+ERROR: 0:31: 'dependency_length' : must be positive 
+ERROR: 4 compilation errors.  No code generated.
+
+
 Shader version: 460
-0:? Sequence
+Requested GL_EXT_control_flow_attributes
+ERROR: node is still EOpNull!
 0:10  Function Definition: main( ( global void)
 0:10    Function Parameters: 
 0:12    Sequence
@@ -21,6 +29,43 @@
 0:16        'b1' ( temp bool)
 0:16        allInvocationsEqual ( global bool)
 0:16          'b1' ( temp bool)
+0:19  Function Definition: attExtBad( ( global void)
+0:19    Function Parameters: 
+0:22    Sequence
+0:22      Sequence
+0:22        Sequence
+0:22          move second child to first child ( temp int)
+0:22            'i' ( temp int)
+0:22            Constant:
+0:22              0 (const int)
+0:22        Loop with condition tested first: Dependency 4
+0:22          Loop Condition
+0:22          Compare Less Than ( temp bool)
+0:22            'i' ( temp int)
+0:22            Constant:
+0:22              8 (const int)
+0:22          No loop body
+0:22          Loop Terminal Expression
+0:22          Pre-Increment ( temp int)
+0:22            'i' ( temp int)
+0:23      Test condition and select ( temp void): Flatten
+0:23        Condition
+0:23        Constant:
+0:23          true (const bool)
+0:23        true case is null
+0:28  Function Definition: attExt( ( global void)
+0:28    Function Parameters: 
+0:30    Sequence
+0:30      Loop with condition not tested first: Dependency -3
+0:30        Loop Condition
+0:30        Constant:
+0:30          true (const bool)
+0:30        No loop body
+0:31      Loop with condition not tested first
+0:31        Loop Condition
+0:31        Constant:
+0:31          true (const bool)
+0:31        No loop body
 0:?   Linker Objects
 0:?     's' ( smooth in structure{ global float f,  global 4-component vector of float v})
 
@@ -29,7 +74,8 @@
 
 
 Shader version: 460
-0:? Sequence
+Requested GL_EXT_control_flow_attributes
+ERROR: node is still EOpNull!
 0:10  Function Definition: main( ( global void)
 0:10    Function Parameters: 
 0:12    Sequence
diff --git a/Test/baseResults/array.frag.out b/Test/baseResults/array.frag.out
index f41f0af..fadccf5 100644
--- a/Test/baseResults/array.frag.out
+++ b/Test/baseResults/array.frag.out
@@ -2,7 +2,7 @@
 ERROR: 0:21: '[' :  array index out of range '2'
 ERROR: 0:27: '[' :  array must be redeclared with a size before being indexed with a variable
 ERROR: 0:30: 'assign' :  cannot convert from ' global 4-element array of float' to ' global 5-element array of float'
-ERROR: 0:31: 'assign' :  cannot convert from ' global 4-element array of float' to ' global implicitly-sized array of float'
+ERROR: 0:31: 'assign' :  cannot convert from ' global 4-element array of float' to ' global runtime-sized array of float'
 ERROR: 0:33: 'foo' : no matching overloaded function found 
 ERROR: 0:42: '[' :  array index out of range '5'
 ERROR: 0:45: '[' :  array index out of range '1000'
@@ -23,9 +23,11 @@
 ERROR: 0:93: 'length' :  array must be declared with a size before using this method
 ERROR: 0:101: '[' :  array index out of range '5'
 ERROR: 0:104: 'constructor' : array constructor must have at least one argument 
-ERROR: 0:104: '=' :  cannot convert from ' const float' to ' global implicitly-sized array of int'
+ERROR: 0:104: '=' :  cannot convert from ' const float' to ' global unsized 1-element array of int'
 ERROR: 0:106: 'constructor' : array argument must be sized 
-ERROR: 26 compilation errors.  No code generated.
+ERROR: 0:111: 'variable index' : required extension not requested: GL_EXT_nonuniform_qualifier
+ERROR: 0:111: 'variable indexing sampler array' : not supported with this profile: none
+ERROR: 28 compilation errors.  No code generated.
 
 
 Shader version: 130
@@ -68,21 +70,21 @@
 0:21            4.000000
 0:24      move second child to first child ( temp float)
 0:24        direct index ( temp float)
-0:24          'gu' ( global implicitly-sized array of float)
+0:24          'gu' ( global runtime-sized array of float)
 0:24          Constant:
 0:24            2 (const int)
 0:24        Constant:
 0:24          4.000000
 0:26      move second child to first child ( temp float)
 0:26        direct index ( temp float)
-0:26          'gu' ( global implicitly-sized array of float)
+0:26          'gu' ( global runtime-sized array of float)
 0:26          Constant:
 0:26            3 (const int)
 0:26        Constant:
 0:26          3.000000
 0:27      move second child to first child ( temp float)
 0:27        indirect index ( temp float)
-0:27          'gu' ( global implicitly-sized array of float)
+0:27          'gu' ( global runtime-sized array of float)
 0:27          'a' ( uniform int)
 0:27        Constant:
 0:27          5.000000
@@ -91,7 +93,7 @@
 0:29        Function Call: foo(f1[5]; ( global 4-element array of float)
 0:29          'g5' ( global 5-element array of float)
 0:30      'g5' ( global 5-element array of float)
-0:31      'gu' ( global implicitly-sized array of float)
+0:31      'gu' ( global runtime-sized array of float)
 0:33      Constant:
 0:33        0.000000
 0:34      Function Call: bar(f1[5]; ( global void)
@@ -108,7 +110,7 @@
 0:36        true case
 0:37        move second child to first child ( temp float)
 0:37          direct index ( temp float)
-0:37            'gu' ( global implicitly-sized array of float)
+0:37            'gu' ( global runtime-sized array of float)
 0:37            Constant:
 0:37              0 (const int)
 0:37          Constant:
@@ -199,21 +201,21 @@
 0:?     Sequence
 0:71      move second child to first child ( temp int)
 0:71        direct index ( temp int)
-0:71          'uns' ( temp implicitly-sized array of int)
+0:71          'uns' ( temp unsized 4-element array of int)
 0:71          Constant:
 0:71            3 (const int)
 0:71        Constant:
 0:71          40 (const int)
 0:72      move second child to first child ( temp int)
 0:72        direct index ( temp int)
-0:72          'uns' ( temp implicitly-sized array of int)
+0:72          'uns' ( temp unsized 4-element array of int)
 0:72          Constant:
 0:72            1 (const int)
 0:72        Constant:
 0:72          30 (const int)
 0:73      move second child to first child ( temp 3-component vector of float)
 0:73        direct index ( temp 3-component vector of float)
-0:73          'guns' ( global implicitly-sized array of 3-component vector of float)
+0:73          'guns' ( global unsized 8-element array of 3-component vector of float)
 0:73          Constant:
 0:73            2 (const int)
 0:73        Constant:
@@ -222,11 +224,11 @@
 0:73          2.400000
 0:76      Constant:
 0:76        0.000000
-0:79  Function Definition: foo2( ( global implicitly-sized array of float)
+0:79  Function Definition: foo2( ( global unsized 1-element array of float)
 0:79    Function Parameters: 
 0:?     Sequence
 0:82      Branch: Return with expression
-0:82        'f' ( temp implicitly-sized array of float)
+0:82        'f' ( temp unsized 1-element array of float)
 0:84      Branch: Return with expression
 0:84        'g' ( temp 9-element array of float)
 0:89  Function Definition: foo3( ( global void)
@@ -264,17 +266,24 @@
 0:106      'b' ( global float)
 0:106      Constant:
 0:106        0.000000
+0:109  Function Definition: foo4( ( global void)
+0:109    Function Parameters: 
+0:111    Sequence
+0:111      indirect index ( temp sampler2D)
+0:111        's2d' ( uniform runtime-sized array of sampler2D)
+0:111        'a' ( uniform int)
 0:?   Linker Objects
-0:?     'gu' ( global implicitly-sized array of float)
+0:?     'gu' ( global runtime-sized array of float)
 0:?     'g4' ( global 4-element array of float)
 0:?     'g5' ( global 5-element array of float)
 0:?     'a' ( uniform int)
-0:?     'guns' ( global implicitly-sized array of 3-component vector of float)
+0:?     'guns' ( global unsized 8-element array of 3-component vector of float)
 0:?     'f' ( global float)
-0:?     'gUnusedUnsized' ( global implicitly-sized array of float)
-0:?     'i' ( global implicitly-sized array of int)
-0:?     'emptyA' ( global implicitly-sized array of float)
+0:?     'gUnusedUnsized' ( global unsized 1-element array of float)
+0:?     'i' ( global unsized 1-element array of int)
+0:?     'emptyA' ( global unsized 1-element array of float)
 0:?     'b' ( global float)
+0:?     's2d' ( uniform runtime-sized array of sampler2D)
 
 
 Linked fragment stage:
@@ -320,21 +329,21 @@
 0:21            4.000000
 0:24      move second child to first child ( temp float)
 0:24        direct index ( temp float)
-0:24          'gu' ( global 4-element array of float)
+0:24          'gu' ( global runtime-sized array of float)
 0:24          Constant:
 0:24            2 (const int)
 0:24        Constant:
 0:24          4.000000
 0:26      move second child to first child ( temp float)
 0:26        direct index ( temp float)
-0:26          'gu' ( global 4-element array of float)
+0:26          'gu' ( global runtime-sized array of float)
 0:26          Constant:
 0:26            3 (const int)
 0:26        Constant:
 0:26          3.000000
 0:27      move second child to first child ( temp float)
 0:27        indirect index ( temp float)
-0:27          'gu' ( global 4-element array of float)
+0:27          'gu' ( global runtime-sized array of float)
 0:27          'a' ( uniform int)
 0:27        Constant:
 0:27          5.000000
@@ -343,7 +352,7 @@
 0:29        Function Call: foo(f1[5]; ( global 4-element array of float)
 0:29          'g5' ( global 5-element array of float)
 0:30      'g5' ( global 5-element array of float)
-0:31      'gu' ( global 4-element array of float)
+0:31      'gu' ( global runtime-sized array of float)
 0:33      Constant:
 0:33        0.000000
 0:34      Function Call: bar(f1[5]; ( global void)
@@ -360,7 +369,7 @@
 0:36        true case
 0:37        move second child to first child ( temp float)
 0:37          direct index ( temp float)
-0:37            'gu' ( global 4-element array of float)
+0:37            'gu' ( global runtime-sized array of float)
 0:37            Constant:
 0:37              0 (const int)
 0:37          Constant:
@@ -452,7 +461,7 @@
 0:106      Constant:
 0:106        0.000000
 0:?   Linker Objects
-0:?     'gu' ( global 4-element array of float)
+0:?     'gu' ( global runtime-sized array of float)
 0:?     'g4' ( global 4-element array of float)
 0:?     'g5' ( global 5-element array of float)
 0:?     'a' ( uniform int)
@@ -462,4 +471,5 @@
 0:?     'i' ( global 1-element array of int)
 0:?     'emptyA' ( global 1-element array of float)
 0:?     'b' ( global float)
+0:?     's2d' ( uniform runtime-sized array of sampler2D)
 
diff --git a/Test/baseResults/array100.frag.out b/Test/baseResults/array100.frag.out
index b99d817..e6f9f8d 100644
--- a/Test/baseResults/array100.frag.out
+++ b/Test/baseResults/array100.frag.out
@@ -10,7 +10,7 @@
 ERROR: 0:25: 'array assignment' : not supported for this version or the enabled extensions 
 ERROR: 0:25: 'assign' :  cannot convert from ' global 4-element array of mediump float' to ' global 5-element array of mediump float'
 ERROR: 0:26: 'array assignment' : not supported for this version or the enabled extensions 
-ERROR: 0:26: 'assign' :  cannot convert from ' global 4-element array of mediump float' to ' global implicitly-sized array of mediump float'
+ERROR: 0:26: 'assign' :  cannot convert from ' global 4-element array of mediump float' to ' global unsized 1-element array of mediump float'
 ERROR: 0:28: 'foo' : no matching overloaded function found 
 ERROR: 0:31: 'arrayed constructor' : not supported for this version or the enabled extensions 
 ERROR: 0:31: 'array comparison' : not supported for this version or the enabled extensions 
@@ -67,7 +67,7 @@
 0:24        Function Call: foo(f1[5]; ( global 4-element array of mediump float)
 0:24          'g5' ( global 5-element array of mediump float)
 0:25      'g5' ( global 5-element array of mediump float)
-0:26      'gu' ( global implicitly-sized array of mediump float)
+0:26      'gu' ( global unsized 1-element array of mediump float)
 0:28      Constant:
 0:28        0.000000
 0:29      Function Call: bar(f1[5]; ( global void)
@@ -84,7 +84,7 @@
 0:31        true case
 0:32        move second child to first child ( temp mediump float)
 0:32          direct index ( temp mediump float)
-0:32            'gu' ( global implicitly-sized array of mediump float)
+0:32            'gu' ( global unsized 1-element array of mediump float)
 0:32            Constant:
 0:32              0 (const int)
 0:32          Constant:
@@ -152,7 +152,7 @@
 0:69          'initSb' ( temp structure{ global mediump 4-component vector of float v4,  global structure{ global mediump 3-component vector of float v3,  global 4-element array of mediump 2-component vector of float v2} sa})
 0:69          's1' ( temp structure{ global mediump 4-component vector of float v4,  global structure{ global mediump 3-component vector of float v3,  global 4-element array of mediump 2-component vector of float v2} sa})
 0:?   Linker Objects
-0:?     'gu' ( global implicitly-sized array of mediump float)
+0:?     'gu' ( global unsized 1-element array of mediump float)
 0:?     'g4' ( global 4-element array of mediump float)
 0:?     'g5' ( global 5-element array of mediump float)
 0:?     'a' ( uniform mediump int)
diff --git a/Test/baseResults/atomic_uint.frag.out b/Test/baseResults/atomic_uint.frag.out
index e2773f9..c705a06 100644
--- a/Test/baseResults/atomic_uint.frag.out
+++ b/Test/baseResults/atomic_uint.frag.out
@@ -2,7 +2,6 @@
 ERROR: 0:10: 'atomic_uint' : samplers and atomic_uints cannot be output parameters 
 ERROR: 0:12: 'return' : type does not match, or is not convertible to, the function's return type 
 ERROR: 0:18: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: non_uniform_counter
-ERROR: 0:18: 'atomic_uint' : layout(binding=X) is required 
 ERROR: 0:23: 'binding' : atomic_uint binding is too large; see gl_MaxAtomicCounterBindings 
 ERROR: 0:28: '+' :  wrong operand types: no operation '+' exists that takes a left-hand operand of type 'layout( binding=0 offset=0) uniform atomic_uint' and a right operand of type 'layout( binding=0 offset=0) uniform atomic_uint' (or there is no acceptable conversion)
 ERROR: 0:29: '-' :  wrong operand type no operation '-' exists that takes an operand of type layout( binding=0 offset=0) uniform atomic_uint (or there is no acceptable conversion)
@@ -10,14 +9,10 @@
 ERROR: 0:34: 'assign' :  l-value required "counter" (can't modify a uniform)
 ERROR: 0:34: 'assign' :  cannot convert from ' const int' to 'layout( binding=0 offset=0) uniform atomic_uint'
 ERROR: 0:37: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: acin
-ERROR: 0:37: 'atomic_uint' : layout(binding=X) is required 
 ERROR: 0:38: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: acg
-ERROR: 0:38: 'atomic_uint' : layout(binding=X) is required 
-ERROR: 0:40: 'atomic_uint' : layout(binding=X) is required 
-ERROR: 0:46: 'atomic_uint' : layout(binding=X) is required 
 ERROR: 0:47: 'offset' : atomic counters sharing the same offset: 12
 ERROR: 0:48: 'binding' : atomic_uint binding is too large; see gl_MaxAtomicCounterBindings 
-ERROR: 18 compilation errors.  No code generated.
+ERROR: 13 compilation errors.  No code generated.
 
 
 Shader version: 420
diff --git a/Test/baseResults/constFoldIntMin.frag.out b/Test/baseResults/constFoldIntMin.frag.out
new file mode 100644
index 0000000..2c45ca8
--- /dev/null
+++ b/Test/baseResults/constFoldIntMin.frag.out
@@ -0,0 +1,51 @@
+constFoldIntMin.frag
+Shader version: 460
+Requested GL_AMD_gpu_shader_int16
+Requested GL_ARB_gpu_shader_int64
+0:? Sequence
+0:5  Function Definition: a( ( global void)
+0:5    Function Parameters: 
+0:6    Sequence
+0:6      Sequence
+0:6        move second child to first child ( temp int16_t)
+0:6          'u' ( temp int16_t)
+0:6          Constant:
+0:6            -32768 (const int16_t)
+0:7      Sequence
+0:7        move second child to first child ( temp int)
+0:7          'v' ( temp int)
+0:7          Constant:
+0:7            -2147483648 (const int)
+0:8      Sequence
+0:8        move second child to first child ( temp int64_t)
+0:8          'w' ( temp int64_t)
+0:8          Constant:
+0:8            -9223372036854775808 (const int64_t)
+0:9      Sequence
+0:9        move second child to first child ( temp int16_t)
+0:9          'x' ( temp int16_t)
+0:9          Constant:
+0:9            0 (const int8_t)
+0:10      Sequence
+0:10        move second child to first child ( temp int)
+0:10          'y' ( temp int)
+0:10          Constant:
+0:10            0 (const int)
+0:11      Sequence
+0:11        move second child to first child ( temp int64_t)
+0:11          'z' ( temp int64_t)
+0:11          Constant:
+0:11            0 (const int64_t)
+0:?   Linker Objects
+
+
+Linked fragment stage:
+
+ERROR: Linking fragment stage: Missing entry point: Each stage requires one entry point
+
+Shader version: 460
+Requested GL_AMD_gpu_shader_int16
+Requested GL_ARB_gpu_shader_int64
+0:? Sequence
+0:?   Linker Objects
+
diff --git a/Test/baseResults/cppBad.vert.out b/Test/baseResults/cppBad.vert.out
index 205c29b..1a2286a 100755
--- a/Test/baseResults/cppBad.vert.out
+++ b/Test/baseResults/cppBad.vert.out
@@ -2,10 +2,9 @@
 ERROR: 0:2: 'preprocessor evaluation' : bad expression 
 ERROR: 0:2: '#if' : unexpected tokens following directive 
 ERROR: 0:5: 'string' : End of line in string 
-ERROR: 0:5: 'macro expansion' : expected '(' following n
 ERROR: 0:5: '""' : string literals not supported 
 ERROR: 0:5: '' :  syntax error, unexpected INT, expecting COMMA or SEMICOLON
-ERROR: 6 compilation errors.  No code generated.
+ERROR: 5 compilation errors.  No code generated.
 
 
 Shader version: 100
diff --git a/Test/baseResults/cppPassMacroName.frag.out b/Test/baseResults/cppPassMacroName.frag.out
new file mode 100755
index 0000000..d8459b3
--- /dev/null
+++ b/Test/baseResults/cppPassMacroName.frag.out
@@ -0,0 +1,67 @@
+cppPassMacroName.frag
+Shader version: 100
+0:? Sequence
+0:5  Function Definition: main( ( global void)
+0:5    Function Parameters: 
+0:7    Sequence
+0:7      Sequence
+0:7        move second child to first child ( temp mediump int)
+0:7          'f1' ( temp mediump int)
+0:7          Constant:
+0:7            4 (const int)
+0:8      Sequence
+0:8        move second child to first child ( temp mediump int)
+0:8          'f2' ( temp mediump int)
+0:8          'f1' ( temp mediump int)
+0:9      Sequence
+0:9        move second child to first child ( temp mediump int)
+0:9          'f3' ( temp mediump int)
+0:9          Constant:
+0:9            9 (const int)
+0:10      Sequence
+0:10        move second child to first child ( temp mediump int)
+0:10          'f4' ( temp mediump int)
+0:10          Constant:
+0:10            1 (const int)
+0:11      Sequence
+0:11        move second child to first child ( temp mediump int)
+0:11          'f5' ( temp mediump int)
+0:11          Constant:
+0:11            5 (const int)
+0:?   Linker Objects
+
+
+Linked fragment stage:
+
+
+Shader version: 100
+0:? Sequence
+0:5  Function Definition: main( ( global void)
+0:5    Function Parameters: 
+0:7    Sequence
+0:7      Sequence
+0:7        move second child to first child ( temp mediump int)
+0:7          'f1' ( temp mediump int)
+0:7          Constant:
+0:7            4 (const int)
+0:8      Sequence
+0:8        move second child to first child ( temp mediump int)
+0:8          'f2' ( temp mediump int)
+0:8          'f1' ( temp mediump int)
+0:9      Sequence
+0:9        move second child to first child ( temp mediump int)
+0:9          'f3' ( temp mediump int)
+0:9          Constant:
+0:9            9 (const int)
+0:10      Sequence
+0:10        move second child to first child ( temp mediump int)
+0:10          'f4' ( temp mediump int)
+0:10          Constant:
+0:10            1 (const int)
+0:11      Sequence
+0:11        move second child to first child ( temp mediump int)
+0:11          'f5' ( temp mediump int)
+0:11          Constant:
+0:11            5 (const int)
+0:?   Linker Objects
+
diff --git a/Test/baseResults/cppRelaxSkipTokensErrors.vert.out b/Test/baseResults/cppRelaxSkipTokensErrors.vert.out
new file mode 100755
index 0000000..e9b4b1b
--- /dev/null
+++ b/Test/baseResults/cppRelaxSkipTokensErrors.vert.out
@@ -0,0 +1,14 @@
+cppRelaxSkipTokensErrors.vert
+Shader version: 110
+0:? Sequence
+0:?   Linker Objects
+
+
+Linked vertex stage:
+
+ERROR: Linking vertex stage: Missing entry point: Each stage requires one entry point
+
+Shader version: 110
+0:? Sequence
+0:?   Linker Objects
+
diff --git a/Test/baseResults/cppSimple.vert.out b/Test/baseResults/cppSimple.vert.out
index 1b6e6b5..8da3ae6 100644
--- a/Test/baseResults/cppSimple.vert.out
+++ b/Test/baseResults/cppSimple.vert.out
@@ -75,10 +75,8 @@
 ERROR: 12:20055: '#error' : good evaluation 2  
 ERROR: 12:9000: 'preprocessor evaluation' : expected ')' 
 ERROR: 12:9002: '#if' : unexpected tokens following directive 
-ERROR: 12:9014: 'macro expansion' : expected '(' following FOOOM
 ERROR: 12:9014: 'FOOOM' : undeclared identifier 
 ERROR: 12:9014: '=' :  cannot convert from ' temp float' to ' global int'
-ERROR: 12:9015: 'macro expansion' : expected '(' following FOOOM
 ERROR: 12:9016: 'preprocessor evaluation' : can't evaluate expression 
 ERROR: 12:9016: 'preprocessor evaluation' : bad expression 
 ERROR: 12:9500: 'preprocessor evaluation' : bad expression 
@@ -93,7 +91,7 @@
 ERROR: 12:9602: 'defined' : cannot use in preprocessor expression when expanded from macros 
 ERROR: 12:9603: '#error' : DEF_DEFINED then  
 ERROR: 12:10002: '' : missing #endif 
-ERROR: 90 compilation errors.  No code generated.
+ERROR: 88 compilation errors.  No code generated.
 
 
 Shader version: 400
@@ -136,7 +134,7 @@
 0:65          0.050000
 0:69      move second child to first child ( temp 4-component vector of float)
 0:69        gl_Position: direct index for structure ( gl_Position 4-component vector of float Position)
-0:69          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out implicitly-sized array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
+0:69          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 1-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out unsized 1-element array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
 0:69          Constant:
 0:69            0 (const uint)
 0:69        Construct vec4 ( temp 4-component vector of float)
@@ -176,7 +174,7 @@
 12:20033    Sequence
 12:20033      move second child to first child ( temp 4-component vector of float)
 12:20033        gl_Position: direct index for structure ( gl_Position 4-component vector of float Position)
-12:20033          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out implicitly-sized array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
+12:20033          'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 1-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out unsized 1-element array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
 12:20033          Constant:
 12:20033            0 (const uint)
 12:20033        Constant:
@@ -190,7 +188,7 @@
 12:9011      'RECURSE' ( global int)
 0:?   Linker Objects
 0:?     'sum' ( global float)
-0:?     'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out implicitly-sized array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out implicitly-sized array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
+0:?     'anon@0' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 1-element array of float ClipDistance gl_ClipDistance,  gl_ClipVertex 4-component vector of float ClipVertex gl_ClipVertex,  out 4-component vector of float FrontColor gl_FrontColor,  out 4-component vector of float BackColor gl_BackColor,  out 4-component vector of float FrontSecondaryColor gl_FrontSecondaryColor,  out 4-component vector of float BackSecondaryColor gl_BackSecondaryColor,  out unsized 1-element array of 4-component vector of float TexCoord gl_TexCoord,  out float FogFragCoord gl_FogFragCoord})
 0:?     'linenumber' ( global int)
 0:?     'filenumber' ( global int)
 0:?     'version' ( global int)
diff --git a/Test/baseResults/findFunction.frag.out b/Test/baseResults/findFunction.frag.out
new file mode 100644
index 0000000..ec4f3e4
--- /dev/null
+++ b/Test/baseResults/findFunction.frag.out
@@ -0,0 +1,233 @@
+findFunction.frag
+ERROR: 0:39: 'func' : ambiguous best function under implicit type conversion 
+ERROR: 0:40: 'func' : no matching overloaded function found 
+ERROR: 0:40: '=' :  cannot convert from ' const float' to ' temp int64_t'
+ERROR: 0:41: 'func' : no matching overloaded function found 
+ERROR: 0:41: '=' :  cannot convert from ' const float' to ' temp int64_t'
+ERROR: 0:44: 'func' : no matching overloaded function found 
+ERROR: 0:44: '=' :  cannot convert from ' const float' to ' temp int64_t'
+ERROR: 0:45: 'func' : ambiguous best function under implicit type conversion 
+ERROR: 8 compilation errors.  No code generated.
+
+
+Shader version: 450
+Requested GL_KHX_shader_explicit_arithmetic_types
+ERROR: node is still EOpNull!
+0:5  Function Definition: func(i81;i161;i161; ( global int64_t)
+0:5    Function Parameters: 
+0:5      'a' ( in int8_t)
+0:5      'b' ( in int16_t)
+0:5      'c' ( in int16_t)
+0:7    Sequence
+0:7      Branch: Return with expression
+0:7        Convert int16_t to int64 ( temp int64_t)
+0:7          inclusive-or ( temp int16_t)
+0:7            Convert int8_t to int16_t ( temp int16_t)
+0:7              'a' ( in int8_t)
+0:7            add ( temp int16_t)
+0:7              'b' ( in int16_t)
+0:7              'c' ( in int16_t)
+0:10  Function Definition: func(i81;i161;i1; ( global int64_t)
+0:10    Function Parameters: 
+0:10      'a' ( in int8_t)
+0:10      'b' ( in int16_t)
+0:10      'c' ( in int)
+0:12    Sequence
+0:12      Branch: Return with expression
+0:12        Convert int to int64 ( temp int64_t)
+0:12          inclusive-or ( temp int)
+0:12            Convert int8_t to int ( temp int)
+0:12              'a' ( in int8_t)
+0:12            subtract ( temp int)
+0:12              Convert int16_t to int ( temp int)
+0:12                'b' ( in int16_t)
+0:12              'c' ( in int)
+0:15  Function Definition: func(i1;i1;i1; ( global int64_t)
+0:15    Function Parameters: 
+0:15      'a' ( in int)
+0:15      'b' ( in int)
+0:15      'c' ( in int)
+0:17    Sequence
+0:17      Branch: Return with expression
+0:17        Convert int to int64 ( temp int64_t)
+0:17          add ( temp int)
+0:17            divide ( temp int)
+0:17              'a' ( in int)
+0:17              'b' ( in int)
+0:17            'c' ( in int)
+0:20  Function Definition: func(f161;f161;f1; ( global int64_t)
+0:20    Function Parameters: 
+0:20      'a' ( in float16_t)
+0:20      'b' ( in float16_t)
+0:20      'c' ( in float)
+0:22    Sequence
+0:22      Branch: Return with expression
+0:22        Convert float to int64 ( temp int64_t)
+0:22          subtract ( temp float)
+0:22            Convert float16_t to float ( temp float)
+0:22              'a' ( in float16_t)
+0:22            component-wise multiply ( temp float)
+0:22              Convert float16_t to float ( temp float)
+0:22                'b' ( in float16_t)
+0:22              'c' ( in float)
+0:25  Function Definition: func(f161;i161;f1; ( global int64_t)
+0:25    Function Parameters: 
+0:25      'a' ( in float16_t)
+0:25      'b' ( in int16_t)
+0:25      'c' ( in float)
+0:27    Sequence
+0:27      Branch: Return with expression
+0:27        Convert float to int64 ( temp int64_t)
+0:27          subtract ( temp float)
+0:27            Convert float16_t to float ( temp float)
+0:27              'a' ( in float16_t)
+0:27            component-wise multiply ( temp float)
+0:27              Convert int16_t to float ( temp float)
+0:27                'b' ( in int16_t)
+0:27              'c' ( in float)
+0:30  Function Definition: main( ( global void)
+0:30    Function Parameters: 
+0:?     Sequence
+0:38      Sequence
+0:38        move second child to first child ( temp int64_t)
+0:38          'b1' ( temp int64_t)
+0:38          Function Call: func(i81;i161;i1; ( global int64_t)
+0:38            'x' ( temp int8_t)
+0:38            'y' ( temp int16_t)
+0:38            'z' ( temp int)
+0:39      Sequence
+0:39        move second child to first child ( temp int64_t)
+0:39          'b2' ( temp int64_t)
+0:39          Function Call: func(f161;i161;f1; ( global int64_t)
+0:39            Convert int16_t to float16_t ( temp float16_t)
+0:39              'y' ( temp int16_t)
+0:39            'y' ( temp int16_t)
+0:39            Convert int to float ( temp float)
+0:39              'z' ( temp int)
+0:42      Sequence
+0:42        move second child to first child ( temp int64_t)
+0:42          'b5' ( temp int64_t)
+0:42          Function Call: func(f161;i161;f1; ( global int64_t)
+0:42            Convert int16_t to float16_t ( temp float16_t)
+0:42              'y' ( temp int16_t)
+0:42            'y' ( temp int16_t)
+0:42            Convert float16_t to float ( temp float)
+0:42              'f16' ( temp float16_t)
+0:43      Sequence
+0:43        move second child to first child ( temp int64_t)
+0:43          'b7' ( temp int64_t)
+0:43          Function Call: func(f161;f161;f1; ( global int64_t)
+0:43            'f16' ( temp float16_t)
+0:43            'f16' ( temp float16_t)
+0:43            Convert int16_t to float ( temp float)
+0:43              'y' ( temp int16_t)
+0:45      Sequence
+0:45        move second child to first child ( temp int64_t)
+0:45          'b9' ( temp int64_t)
+0:45          Function Call: func(f161;f161;f1; ( global int64_t)
+0:45            'f16' ( temp float16_t)
+0:45            Convert int8_t to float16_t ( temp float16_t)
+0:45              'x' ( temp int8_t)
+0:45            Convert float16_t to float ( temp float)
+0:45              'f16' ( temp float16_t)
+0:?   Linker Objects
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+Requested GL_KHX_shader_explicit_arithmetic_types
+ERROR: node is still EOpNull!
+0:10  Function Definition: func(i81;i161;i1; ( global int64_t)
+0:10    Function Parameters: 
+0:10      'a' ( in int8_t)
+0:10      'b' ( in int16_t)
+0:10      'c' ( in int)
+0:12    Sequence
+0:12      Branch: Return with expression
+0:12        Convert int to int64 ( temp int64_t)
+0:12          inclusive-or ( temp int)
+0:12            Convert int8_t to int ( temp int)
+0:12              'a' ( in int8_t)
+0:12            subtract ( temp int)
+0:12              Convert int16_t to int ( temp int)
+0:12                'b' ( in int16_t)
+0:12              'c' ( in int)
+0:20  Function Definition: func(f161;f161;f1; ( global int64_t)
+0:20    Function Parameters: 
+0:20      'a' ( in float16_t)
+0:20      'b' ( in float16_t)
+0:20      'c' ( in float)
+0:22    Sequence
+0:22      Branch: Return with expression
+0:22        Convert float to int64 ( temp int64_t)
+0:22          subtract ( temp float)
+0:22            Convert float16_t to float ( temp float)
+0:22              'a' ( in float16_t)
+0:22            component-wise multiply ( temp float)
+0:22              Convert float16_t to float ( temp float)
+0:22                'b' ( in float16_t)
+0:22              'c' ( in float)
+0:25  Function Definition: func(f161;i161;f1; ( global int64_t)
+0:25    Function Parameters: 
+0:25      'a' ( in float16_t)
+0:25      'b' ( in int16_t)
+0:25      'c' ( in float)
+0:27    Sequence
+0:27      Branch: Return with expression
+0:27        Convert float to int64 ( temp int64_t)
+0:27          subtract ( temp float)
+0:27            Convert float16_t to float ( temp float)
+0:27              'a' ( in float16_t)
+0:27            component-wise multiply ( temp float)
+0:27              Convert int16_t to float ( temp float)
+0:27                'b' ( in int16_t)
+0:27              'c' ( in float)
+0:30  Function Definition: main( ( global void)
+0:30    Function Parameters: 
+0:?     Sequence
+0:38      Sequence
+0:38        move second child to first child ( temp int64_t)
+0:38          'b1' ( temp int64_t)
+0:38          Function Call: func(i81;i161;i1; ( global int64_t)
+0:38            'x' ( temp int8_t)
+0:38            'y' ( temp int16_t)
+0:38            'z' ( temp int)
+0:39      Sequence
+0:39        move second child to first child ( temp int64_t)
+0:39          'b2' ( temp int64_t)
+0:39          Function Call: func(f161;i161;f1; ( global int64_t)
+0:39            Convert int16_t to float16_t ( temp float16_t)
+0:39              'y' ( temp int16_t)
+0:39            'y' ( temp int16_t)
+0:39            Convert int to float ( temp float)
+0:39              'z' ( temp int)
+0:42      Sequence
+0:42        move second child to first child ( temp int64_t)
+0:42          'b5' ( temp int64_t)
+0:42          Function Call: func(f161;i161;f1; ( global int64_t)
+0:42            Convert int16_t to float16_t ( temp float16_t)
+0:42              'y' ( temp int16_t)
+0:42            'y' ( temp int16_t)
+0:42            Convert float16_t to float ( temp float)
+0:42              'f16' ( temp float16_t)
+0:43      Sequence
+0:43        move second child to first child ( temp int64_t)
+0:43          'b7' ( temp int64_t)
+0:43          Function Call: func(f161;f161;f1; ( global int64_t)
+0:43            'f16' ( temp float16_t)
+0:43            'f16' ( temp float16_t)
+0:43            Convert int16_t to float ( temp float)
+0:43              'y' ( temp int16_t)
+0:45      Sequence
+0:45        move second child to first child ( temp int64_t)
+0:45          'b9' ( temp int64_t)
+0:45          Function Call: func(f161;f161;f1; ( global int64_t)
+0:45            'f16' ( temp float16_t)
+0:45            Convert int8_t to float16_t ( temp float16_t)
+0:45              'x' ( temp int8_t)
+0:45            Convert float16_t to float ( temp float)
+0:45              'f16' ( temp float16_t)
+0:?   Linker Objects
+
diff --git a/Test/baseResults/glsl.entryPointRename.vert.bad.out b/Test/baseResults/glsl.entryPointRename.vert.bad.out
index 6f4c9ae..0162324 100644
--- a/Test/baseResults/glsl.entryPointRename.vert.bad.out
+++ b/Test/baseResults/glsl.entryPointRename.vert.bad.out
@@ -2,7 +2,7 @@
 ERROR: Source entry point must be "main"
 
 // Module Version 10000
-// Generated by (magic number): 80002
+// Generated by (magic number): 80006
 // Id's are bound by 20
 
                               Capability Shader
diff --git a/Test/baseResults/glsl.entryPointRename.vert.out b/Test/baseResults/glsl.entryPointRename.vert.out
index 7cc825b..3dc296c 100644
--- a/Test/baseResults/glsl.entryPointRename.vert.out
+++ b/Test/baseResults/glsl.entryPointRename.vert.out
@@ -1,6 +1,6 @@
 glsl.entryPointRename.vert
 // Module Version 10000
-// Generated by (magic number): 80002
+// Generated by (magic number): 80006
 // Id's are bound by 20
 
                               Capability Shader
diff --git a/Test/baseResults/glspv.frag.out b/Test/baseResults/glspv.frag.out
index 5622d01..db75213 100755
--- a/Test/baseResults/glspv.frag.out
+++ b/Test/baseResults/glspv.frag.out
@@ -1,9 +1,15 @@
 glspv.frag
 ERROR: 0:4: '#error' : GL_SPIRV is set ( correct , not an error )  
 ERROR: 0:6: '#error' : GL_SPIR is 100  
-ERROR: 0:19: 'input_attachment_index' : only allowed when using GLSL for Vulkan 
-ERROR: 0:19: '' :  syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON
-ERROR: 4 compilation errors.  No code generated.
+ERROR: 0:14: 'f' : non-opaque uniform variables need a layout(location=L) 
+ERROR: 0:21: 'noise1' : no matching overloaded function found 
+ERROR: 0:22: 'noise2' : no matching overloaded function found 
+ERROR: 0:23: 'noise3' : no matching overloaded function found 
+ERROR: 0:24: 'noise4' : no matching overloaded function found 
+ERROR: 0:27: 'atomic_uint' : layout(binding=X) is required 
+ERROR: 0:28: 'input_attachment_index' : only allowed when using GLSL for Vulkan 
+ERROR: 0:28: '' :  syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON
+ERROR: 10 compilation errors.  No code generated.
 
 
 SPIR-V is not generated for failed compile or link
diff --git a/Test/baseResults/glspv.version.frag.out b/Test/baseResults/glspv.version.frag.out
index 30eb445..7805cfc 100755
--- a/Test/baseResults/glspv.version.frag.out
+++ b/Test/baseResults/glspv.version.frag.out
@@ -2,7 +2,7 @@
 ERROR: #version: compilation for SPIR-V does not support the compatibility profile
 
 // Module Version 10000
-// Generated by (magic number): 80002
+// Generated by (magic number): 80006
 // Id's are bound by 6
 
                               Capability Shader
diff --git a/Test/baseResults/hlsl.PointSize.geom.out b/Test/baseResults/hlsl.PointSize.geom.out
new file mode 100755
index 0000000..c92bc31
--- /dev/null
+++ b/Test/baseResults/hlsl.PointSize.geom.out
@@ -0,0 +1,143 @@
+hlsl.PointSize.geom
+Shader version: 500
+invocations = -1
+max_vertices = 4
+input primitive = triangles
+output primitive = line_strip
+0:? Sequence
+0:8  Function Definition: @main(u1[3];struct-S-f11; ( temp void)
+0:8    Function Parameters: 
+0:8      'ps' ( in 3-element array of uint)
+0:8      'OutputStream' ( out structure{ temp float ps})
+0:?     Sequence
+0:10      Sequence
+0:10        Sequence
+0:10          move second child to first child ( temp float)
+0:?             'OutputStream.ps' ( out float PointSize)
+0:10            ps: direct index for structure ( temp float)
+0:10              's' ( temp structure{ temp float ps})
+0:10              Constant:
+0:10                0 (const int)
+0:10        EmitVertex ( temp void)
+0:8  Function Definition: main( ( temp void)
+0:8    Function Parameters: 
+0:?     Sequence
+0:8      move second child to first child ( temp 3-element array of uint)
+0:?         'ps' ( temp 3-element array of uint)
+0:?         'ps' ( in 3-element array of uint PointSize)
+0:8      Function Call: @main(u1[3];struct-S-f11; ( temp void)
+0:?         'ps' ( temp 3-element array of uint)
+0:?         'OutputStream' ( temp structure{ temp float ps})
+0:?   Linker Objects
+0:?     'ps' ( in 3-element array of uint PointSize)
+0:?     'OutputStream.ps' ( out float PointSize)
+
+
+Linked geometry stage:
+
+
+Shader version: 500
+invocations = 1
+max_vertices = 4
+input primitive = triangles
+output primitive = line_strip
+0:? Sequence
+0:8  Function Definition: @main(u1[3];struct-S-f11; ( temp void)
+0:8    Function Parameters: 
+0:8      'ps' ( in 3-element array of uint)
+0:8      'OutputStream' ( out structure{ temp float ps})
+0:?     Sequence
+0:10      Sequence
+0:10        Sequence
+0:10          move second child to first child ( temp float)
+0:?             'OutputStream.ps' ( out float PointSize)
+0:10            ps: direct index for structure ( temp float)
+0:10              's' ( temp structure{ temp float ps})
+0:10              Constant:
+0:10                0 (const int)
+0:10        EmitVertex ( temp void)
+0:8  Function Definition: main( ( temp void)
+0:8    Function Parameters: 
+0:?     Sequence
+0:8      move second child to first child ( temp 3-element array of uint)
+0:?         'ps' ( temp 3-element array of uint)
+0:?         'ps' ( in 3-element array of uint PointSize)
+0:8      Function Call: @main(u1[3];struct-S-f11; ( temp void)
+0:?         'ps' ( temp 3-element array of uint)
+0:?         'OutputStream' ( temp structure{ temp float ps})
+0:?   Linker Objects
+0:?     'ps' ( in 3-element array of uint PointSize)
+0:?     'OutputStream.ps' ( out float PointSize)
+
+// Module Version 10000
+// Generated by (magic number): 80006
+// Id's are bound by 36
+
+                              Capability Geometry
+                              Capability GeometryPointSize
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Geometry 4  "main" 19 28
+                              ExecutionMode 4 Triangles
+                              ExecutionMode 4 Invocations 1
+                              ExecutionMode 4 OutputLineStrip
+                              ExecutionMode 4 OutputVertices 4
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 11  "S"
+                              MemberName 11(S) 0  "ps"
+                              Name 16  "@main(u1[3];struct-S-f11;"
+                              Name 14  "ps"
+                              Name 15  "OutputStream"
+                              Name 19  "OutputStream.ps"
+                              Name 20  "s"
+                              Name 26  "ps"
+                              Name 28  "ps"
+                              Name 30  "OutputStream"
+                              Name 31  "param"
+                              Name 33  "param"
+                              Decorate 19(OutputStream.ps) BuiltIn PointSize
+                              Decorate 28(ps) BuiltIn PointSize
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 0
+               7:      6(int) Constant 3
+               8:             TypeArray 6(int) 7
+               9:             TypePointer Function 8
+              10:             TypeFloat 32
+           11(S):             TypeStruct 10(float)
+              12:             TypePointer Function 11(S)
+              13:             TypeFunction 2 9(ptr) 12(ptr)
+              18:             TypePointer Output 10(float)
+19(OutputStream.ps):     18(ptr) Variable Output
+              21:             TypeInt 32 1
+              22:     21(int) Constant 0
+              23:             TypePointer Function 10(float)
+              27:             TypePointer Input 8
+          28(ps):     27(ptr) Variable Input
+         4(main):           2 Function None 3
+               5:             Label
+          26(ps):      9(ptr) Variable Function
+30(OutputStream):     12(ptr) Variable Function
+       31(param):      9(ptr) Variable Function
+       33(param):     12(ptr) Variable Function
+              29:           8 Load 28(ps)
+                              Store 26(ps) 29
+              32:           8 Load 26(ps)
+                              Store 31(param) 32
+              34:           2 FunctionCall 16(@main(u1[3];struct-S-f11;) 31(param) 33(param)
+              35:       11(S) Load 33(param)
+                              Store 30(OutputStream) 35
+                              Return
+                              FunctionEnd
+16(@main(u1[3];struct-S-f11;):           2 Function None 13
+          14(ps):      9(ptr) FunctionParameter
+15(OutputStream):     12(ptr) FunctionParameter
+              17:             Label
+           20(s):     12(ptr) Variable Function
+              24:     23(ptr) AccessChain 20(s) 22
+              25:   10(float) Load 24
+                              Store 19(OutputStream.ps) 25
+                              EmitVertex
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.PointSize.vert.out b/Test/baseResults/hlsl.PointSize.vert.out
new file mode 100755
index 0000000..f2221ad
--- /dev/null
+++ b/Test/baseResults/hlsl.PointSize.vert.out
@@ -0,0 +1,69 @@
+hlsl.PointSize.vert
+Shader version: 500
+0:? Sequence
+0:2  Function Definition: @main( ( temp float)
+0:2    Function Parameters: 
+0:?     Sequence
+0:3      Branch: Return with expression
+0:3        Constant:
+0:3          2.300000
+0:2  Function Definition: main( ( temp void)
+0:2    Function Parameters: 
+0:?     Sequence
+0:2      move second child to first child ( temp float)
+0:?         '@entryPointOutput' ( out float PointSize)
+0:2        Function Call: @main( ( temp float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' ( out float PointSize)
+
+
+Linked vertex stage:
+
+
+Shader version: 500
+0:? Sequence
+0:2  Function Definition: @main( ( temp float)
+0:2    Function Parameters: 
+0:?     Sequence
+0:3      Branch: Return with expression
+0:3        Constant:
+0:3          2.300000
+0:2  Function Definition: main( ( temp void)
+0:2    Function Parameters: 
+0:?     Sequence
+0:2      move second child to first child ( temp float)
+0:?         '@entryPointOutput' ( out float PointSize)
+0:2        Function Call: @main( ( temp float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' ( out float PointSize)
+
+// Module Version 10000
+// Generated by (magic number): 80006
+// Id's are bound by 16
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 14
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 8  "@main("
+                              Name 14  "@entryPointOutput"
+                              Decorate 14(@entryPointOutput) BuiltIn PointSize
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeFunction 6(float)
+              10:    6(float) Constant 1075000115
+              13:             TypePointer Output 6(float)
+14(@entryPointOutput):     13(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              15:    6(float) FunctionCall 8(@main()
+                              Store 14(@entryPointOutput) 15
+                              Return
+                              FunctionEnd
+       8(@main():    6(float) Function None 7
+               9:             Label
+                              ReturnValue 10
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.aliasOpaque.frag.out b/Test/baseResults/hlsl.aliasOpaque.frag.out
ind