Merge remote-tracking branch 'origin/main' into HEAD

Change-Id: I6c263be000d8cf1ab51fb9c82e0b112298f2fc78
diff --git a/.appveyor.yml b/.appveyor.yml
deleted file mode 100644
index 50446ac..0000000
--- a/.appveyor.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-# Windows Build Configuration for AppVeyor
-# http://www.appveyor.com/docs/appveyor-yml
-
-# version format
-version: "{build}"
-
-platform:
-  - x64
-
-environment:
-  PYTHON_PATH: "C:/Python27"
-  PYTHON_PACKAGE_PATH: "C:/Python27/Scripts"
-
-configuration:
-  - Debug
-  - Release
-
-branches:
-  only:
-    - master
-
-# scripts that are called at very beginning, before repo cloning
-init:
-  - ps: (new-object net.webclient).DownloadFile('https://bootstrap.pypa.io/get-pip.py', 'C:/get-pip.py')
-  - "%PYTHON_PATH%/python.exe C:/get-pip.py"
-  - "%PYTHON_PACKAGE_PATH%/pip.exe install nose"
-
-# scripts that run after cloning repository
-install:
-  - git clone https://github.com/google/googletest.git          third_party/googletest
-  - git clone https://github.com/google/glslang.git             third_party/glslang
-  - git clone https://github.com/KhronosGroup/SPIRV-Tools.git   third_party/spirv-tools
-  - git clone https://github.com/KhronosGroup/SPIRV-Headers.git third_party/spirv-tools/external/spirv-headers
-
-build:
-  parallel: true  # enable MSBuild parallel builds
-  verbosity: minimal
-
-build_script:
-  - mkdir build && cd build
-  - cmake ..
-  - cmake --build . --config %CONFIGURATION%
-
-test_script:
-  - ctest -C %CONFIGURATION% --output-on-failure
-
-notifications:
-  - provider: Email
-    to:
-      - antiagainst@google.com
-      - awoloszyn@google.com
-      - deki@google.com
-      - dneto@google.com
-      - qining@google.com
-    subject: 'Shaderc Windows Build #{{buildVersion}}: {{status}}'
-    on_build_success: false
-    on_build_failure: true
-    on_build_status_changed: true
diff --git a/glslc/.clang-format b/.clang-format
similarity index 100%
rename from glslc/.clang-format
rename to .clang-format
diff --git a/.gitignore b/.gitignore
index 61cc44f..2565dcd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,19 @@
 build/
 build-*/
+out/
 *.pyc
 *.swp
 compile_commands.json
 .ycm_extra_conf.py
 cscope.*
-third_party/glslang/
-third_party/googletest/
-third_party/spirv-tools/
+third_party/effcee
+third_party/glslang
+third_party/googletest
+third_party/re2
+third_party/spirv-tools
+third_party/spirv-headers
+third_party/spirv-cross
+third_party/tint
+android_test/libs
+android_test/include
 .DS_Store
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 7a88559..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,118 +0,0 @@
-# Linux Build Configuration for Travis
-
-language: cpp
-
-os:
-  - linux
-  - osx
-
-# Use Ubuntu 14.04 LTS (Trusty) as the Linux testing environment.
-sudo: required
-dist: trusty
-
-env:
-  - SHADERC_BUILD_TYPE=Release
-  - SHADERC_BUILD_TYPE=Debug
-
-compiler:
-  - clang
-  - gcc
-
-matrix:
-  fast_finish: true # Show final status immediately if a test fails.
-  exclude:
-    # Skip GCC builds on Mac OS X.
-    - os: osx
-      compiler: gcc
-  include:
-    # Additional GCC builds for code coverage.
-    - os: linux
-      compiler: gcc
-      env: SHADERC_CODE_COVERAGE=ON
-    # Additional build using Android NDK
-    - env: BUILD_NDK=ON
-
-
-cache:
-  apt: true
-
-branches:
-  only:
-    - master
-
-addons:
-  apt:
-    packages:
-      - clang-3.6
-      - ninja-build
-      - lcov
-
-before_install:
-  # Install ninja on Mac OS X.
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update && brew install ninja; fi
-  - if [[ "$BUILD_NDK" == "ON" ]]; then
-      git clone --depth=1 https://github.com/urho3d/android-ndk.git $HOME/android-ndk;
-      export ANDROID_NDK=$HOME/android-ndk;
-      git clone --depth=1 https://github.com/taka-no-me/android-cmake.git $HOME/android-cmake;
-      export TOOLCHAIN_PATH=$HOME/android-cmake/android.toolchain.cmake;
-    fi
-
-install:
-  - pip install --user nose
-  - pip install --user cpp-coveralls
-
-  - export PATH=$HOME/.local/bin:$PATH # Make sure we can find the above Python packages
-    # Make sure that clang-3.6 is selected.
-  - if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "clang" ]]; then
-      export CC=clang-3.6 CXX=clang++-3.6;
-    fi
-
-before_script:
-  - git clone https://github.com/google/googletest.git          third_party/googletest
-  - git clone https://github.com/google/glslang.git             third_party/glslang
-  - git clone https://github.com/KhronosGroup/SPIRV-Tools.git   third_party/spirv-tools
-  - git clone https://github.com/KhronosGroup/SPIRV-Headers.git third_party/spirv-tools/external/spirv-headers
-
-script:
-  - mkdir build && cd build
-  - if [[ "$BUILD_NDK" == "ON" ]]; then
-      cmake -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_PATH}
-            -DANDROID_NATIVE_API_LEVEL=android-9
-            -DCMAKE_BUILD_TYPE=Release
-            -DANDROID_ABI="armeabi-v7a with NEON"
-            -DSHADERC_SKIP_TESTS=ON
-            -GNinja ..;
-    else
-      cmake -DCMAKE_BUILD_TYPE=${SHADERC_BUILD_TYPE:-Debug}
-            -DENABLE_CODE_COVERAGE=${SHADERC_CODE_COVERAGE:-OFF}
-            -GNinja ..;
-    fi
-  - ninja
-  - if [[ "$BUILD_NDK" != "ON" ]]; then ctest -j`nproc` --output_on_failure; fi
-
-after_success:
-  # Collect coverage and push to coveralls.info.
-  # Ignore third party source code and tests.
-  - if [[ "$CC" == "gcc" && "$SHADERC_CODE_COVERAGE" == "ON" ]]; then
-      coveralls
-        --root ../
-        --build-root ./
-        --exclude-pattern '.+/third_party/'
-        --exclude-pattern '.+/.+_test\.cc'
-        --exclude-pattern '.+/CMakeFiles/'
-        --gcov /usr/bin/gcov
-        --gcov-options '\--long-file-names --preserve-paths'
-        --verbose;
-    fi
-
-
-notifications:
-  email:
-    recipients:
-      - antiagainst@google.com
-      - awoloszyn@google.com
-      - deki@google.com
-      - dneto@google.com
-      - qining@google.com
-    on_success: change
-    on_failure: always
diff --git a/Android.mk b/Android.mk
index e23b77a..e1ad18a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,3 +1,17 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 ROOT_SHADERC_PATH := $(call my-dir)
 
 include $(ROOT_SHADERC_PATH)/third_party/Android.mk
@@ -14,7 +28,20 @@
 	libSPIRV-Tools.a \
 	libSPIRV-Tools-opt.a
 
+SHADERC_HEADERS=shaderc.hpp shaderc.h env.h status.h visibility.h
+SHADERC_HEADERS_IN_OUT_DIR=$(foreach H,$(SHADERC_HEADERS),$(NDK_APP_LIBS_OUT)/../include/shaderc/$(H))
+
+define gen_libshaderc_header
+$(NDK_APP_LIBS_OUT)/../include/shaderc/$(1) : \
+		$(ROOT_SHADERC_PATH)/libshaderc/include/shaderc/$(1)
+	$(call host-mkdir,$(NDK_APP_LIBS_OUT)/../include/shaderc)
+	$(call host-cp,$(ROOT_SHADERC_PATH)/libshaderc/include/shaderc/$(1) \
+		,$(NDK_APP_LIBS_OUT)/../include/shaderc/$(1))
+
+endef
+
 define gen_libshaderc
+
 $(1)/combine.ar: $(addprefix $(1)/, $(ALL_LIBS))
 	@echo "create libshaderc_combined.a" > $(1)/combine.ar
 	$(foreach lib,$(ALL_LIBS),
@@ -36,24 +63,14 @@
 
 ifndef HEADER_TARGET
 HEADER_TARGET=1
-$(NDK_APP_LIBS_OUT)/../include/shaderc/shaderc.hpp: \
-		$(ROOT_SHADERC_PATH)/libshaderc/include/shaderc/shaderc.hpp
-	$(call host-mkdir,$(NDK_APP_LIBS_OUT)/../include/shaderc)
-	$(call host-cp,$(ROOT_SHADERC_PATH)/libshaderc/include/shaderc/shaderc.hpp \
-		,$(NDK_APP_LIBS_OUT)/../include/shaderc/shaderc.hpp)
-
-$(NDK_APP_LIBS_OUT)/../include/shaderc/shaderc.h: \
-	$(ROOT_SHADERC_PATH)/libshaderc/include/shaderc/shaderc.h
-	$(call host-mkdir,$(NDK_APP_LIBS_OUT)/../include/shaderc)
-	$(call host-cp,$(ROOT_SHADERC_PATH)/libshaderc/include/shaderc/shaderc.h \
-		,$(NDK_APP_LIBS_OUT)/../include/shaderc/shaderc.h)
+$(eval $(foreach H,$(SHADERC_HEADERS),$(call gen_libshaderc_header,$(H))))
 endif
 
 libshaderc_combined: \
 	$(NDK_APP_LIBS_OUT)/$(APP_STL)/$(TARGET_ARCH_ABI)/libshaderc.a
 
 endef
-libshaderc_combined: $(NDK_APP_LIBS_OUT)/../include/shaderc/shaderc.hpp \
-	$(NDK_APP_LIBS_OUT)/../include/shaderc/shaderc.h
+
+libshaderc_combined: $(SHADERC_HEADERS_IN_OUT_DIR)
 
 $(eval $(call gen_libshaderc,$(TARGET_OUT),$(TOOLCHAIN_PREFIX)))
diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644
index 0000000..7b40d1d
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,101 @@
+# Copyright 2018 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/build.gni")
+import("//build_overrides/shaderc.gni")
+
+glslang_dir = shaderc_glslang_dir
+spirv_tools_dir = shaderc_spirv_tools_dir
+
+config("shaderc_util_public") {
+  include_dirs = [ "libshaderc_util/include" ]
+}
+
+source_set("shaderc_util_sources") {
+  sources = [
+    "libshaderc_util/include/libshaderc_util/counting_includer.h",
+    "libshaderc_util/include/libshaderc_util/exceptions.h",
+    "libshaderc_util/include/libshaderc_util/file_finder.h",
+    "libshaderc_util/include/libshaderc_util/format.h",
+    "libshaderc_util/include/libshaderc_util/io.h",
+    "libshaderc_util/include/libshaderc_util/message.h",
+    "libshaderc_util/include/libshaderc_util/mutex.h",
+    "libshaderc_util/include/libshaderc_util/resources.h",
+    "libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h",
+    "libshaderc_util/include/libshaderc_util/string_piece.h",
+    "libshaderc_util/include/libshaderc_util/universal_unistd.h",
+    "libshaderc_util/include/libshaderc_util/version_profile.h",
+    "libshaderc_util/src/compiler.cc",
+    "libshaderc_util/src/file_finder.cc",
+    "libshaderc_util/src/io.cc",
+    "libshaderc_util/src/message.cc",
+    "libshaderc_util/src/resources.cc",
+    "libshaderc_util/src/shader_stage.cc",
+    "libshaderc_util/src/spirv_tools_wrapper.cc",
+    "libshaderc_util/src/version_profile.cc",
+  ]
+
+  # Configure Glslang's interface to include HLSL-related entry points.
+  defines = [ "ENABLE_HLSL=1" ]
+
+  public_configs = [ ":shaderc_util_public" ]
+
+  deps = [
+    "${glslang_dir}:glslang_sources",
+    "${spirv_tools_dir}:spvtools",
+  ]
+
+  if (build_with_chromium) {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  }
+}
+
+config("shaderc_public") {
+  include_dirs = [ "libshaderc/include" ]
+  if (is_component_build) {
+    defines = [ "SHADERC_SHAREDLIB" ]
+  }
+}
+
+component("libshaderc") {
+  public_configs = [
+    ":shaderc_public",
+    ":shaderc_util_public",
+  ]
+
+  defines = [ "SHADERC_IMPLEMENTATION" ]
+
+  sources = [
+    "libshaderc/include/shaderc/env.h",
+    "libshaderc/include/shaderc/shaderc.h",
+    "libshaderc/include/shaderc/shaderc.hpp",
+    "libshaderc/include/shaderc/status.h",
+    "libshaderc/include/shaderc/visibility.h",
+    "libshaderc/src/shaderc.cc",
+    "libshaderc/src/shaderc_private.h",
+  ]
+
+  deps = [
+    ":shaderc_util_sources",
+    "${spirv_tools_dir}:spvtools",
+    "${spirv_tools_dir}:spvtools_val",
+    "${glslang_dir}:glslang_sources",
+  ]
+
+  if (build_with_chromium) {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  }
+}
diff --git a/CHANGES b/CHANGES
index 4cf6bd4..83e8382 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,11 +1,240 @@
 Revision history for Shaderc
 
-v2016.2-dev 2016-10-12
+v2020.5 2021-02-19
+ - Refresh dependencies (in DEPS):
+   - SPIRV-Tools v2020.7 + 1 patch
+   - Glslang 11.1.0
+ - Add option to skip building examples
+ - Fixes:
+   #1153: Improve file+line parsing from Glslang messages
+
+v2020.4 2020-12-09
+ - Removed svpc
+ - Fixed issues with embedders getting duplicate symbols
+ - Converted C-style casts to static_cast
+ - Rolled ahead to fix/pickup Vulkan Raytracing support
+
+v2020.3 2020-09-02
+ - General:
+   - Last release with spvc
+   - Cleaned up issues discovered by Infer
+ - spvc:
+   - Added support for Dawn using deprecated Options constructor
+   - Adding support for the additional fixed sample mask in MSL
+
+v2020.2 2020-07-23
+ - General:
+   - Remove VS2013 support
+   - Support both posix and non-posix MinGW toolchains
+   - Support optionally building Tint tooling for WGSL
+   - Add -h option to glslc, spvc; same as --help
+   - Add source file license checker
+   - BUILD.gn improvements
+
+ - glslc, libshaderc:
+   - Update to Glslang generator 9
+   - Add interface to support 16bit types in HLSL
+   - Add glslc hidden experimental option -mfmt=wgsl; requires Tint
+
+ - spvc:
+   - Add minimum buffer size for Dawn reflection
+
+v2020.1 2020-06-09
+ This is the last version that officially supports VS2013.
+
+ - General:
+   - Added warning signs about unsupported downloads (#1041)
+   - Added .NET bindings to README.md (#1060)
+   - Only add -fPIC if supported by the compiler. (#1061)
+
+ - glslc, libshaderc:
+   - Removed Singleton pattern around access to glslang (#1059)
+
+ - spvc:
+   - Added concept of comparison sampler to API (#1036)
+   - Added support for options.hlsl.nonwritable_uav_texture_as_srv (#1048)
+   - Support forcing storage buffers to be always declared as UAV. (#1076)
+
+v2020.0 2020-03-06
+ - General:
+   - Getting spirv.hpp from SPIRV-Headers instead of not glslang (#992)
+   - Added clarification about status of artifacts in downloads.md (#1012)
+
+ - glslc, libshaderc:
+   - Added support for new Glslang profile enum, EProfileCount (#973)
+   - Updated user documentation for -S in glslc (#978)
+   - Add documentation for Vulkan 1.2 and SPIR-V 1.5 (#980)
+   - Removed NV_EXTENSIONS conditionals (#1003)
+   - Added support for generating WebGPU SPIR-V to libshaderc (#1021)
+   - Rolled in all DEPS for provisional SPIR-V extensions for raytracing
+
+ - spvc:
+   - Normalized API behaviour (#967)
+   - Added source_set target for libshaderc_spvc (#976)
+   - Added in support for spvc logging to the terminal (#981)
+   - Internal refactoring to reduce boiler plate in API implementations (#984)
+   - Added newline to logging messages to make them readable (#985)
+   - Added reflection support for Dawn:
+     - storage textures (#1001)
+     - storage texture format (#1005)
+     - texture dimension for storage textures (#1008)
+     - is storage texture declared as multisampled texture (#1011)
+   - Converted compile options to require explicit environments (#1019)
+   - Added knob to control force_zero_initialized_variables in SPIRV-Cross (#1028)
+
+v2019.1 2020-01-22
+ - glslc, libshaderc:
+   - Add -fnan-clamp: Generate code for max and min builtins so that,
+     given a NaN operand, will return the other operand. Similarly, the
+     clamp builtin favours non-NaN operands, as if clamp was implemented
+     as the composition of max and min.
+   - Add -finvert-y
+   - Using SetBeforeHlslLegalization for more relaxed validation rules
+   - Added support for SPIR-V 1.5
+   - Add --emit-line-directive option
+   - Added support for Vulkan 1.2
+ - spvc:
+   - Add many options:
+	--flatten-multidimensional-arrays
+	--es
+	--no-es
+	--glsl-emit-push-constant-as-ubo
+	--msl-swizzle-texture-samples
+	--msl-platform=ios|macos
+	--msl-pad-fragment-output
+	--msl-capture-output
+	--msl-domain-lower-left
+	--msl-argument-buffers
+	--msl-discrete-descriptor-set=<number>
+	--hlsl-enable-compat
+   - Reintroduce shaderc_spvc_compile_options_set_shader_model
+   - Added option to inject robust buffer access code
+   - Added support for emitting ToVulkan shaders
+   - Added spirv-opt based IR generation as alternative to built in spirv_cross IR gen
+   - Added API for specifying source and target execution environments
+   - Added option & reflection API methods neede by Dawn
+   - Substantial internal refactoring and code cleanup
+   - Large number of breaking changes to the API
+      -  Replaced shaderc_spvc_compile_options_set_shader_model with
+         shaderc_spvc_compile_options_set_hlsl_shader_model
+      - Compiler initialization and shader generation moved into seperate calls
+      - Seperated return codes from shaderc ones
+      - Many small API changes
+   - Improvements to testing
+      - Refactoring and clean up of run_spirv_cross_tests.py
+      - Seperation of expectations into known failures, known invalids, and cases
+        that need investigation
+      - Tweaks and fixes to substantially increase passing cases
+      - Added support for running tests using spvc IR generation
+   - Infrastructure
+   - Update DEPS with cross-verified commits from associated repos.
+   - Add utils/roll-deps
+ - Infrastructure:
+   - Removed Appveyor artifacts link
+   - Improvements and clean up of DEPS rolling scripts
+   - Enabled warnings about implicit fallthrough
+   - Enabled improper semicolon warnings
+   - Restricted -fPIC to platforms that support it
+   - Converted remaining scripts to use Python 3
+   - Replaced nosetest with unittest
+   - Removed assumptions aabout location of spirv-tools, effcee, and RE2
+   - Migrated BUILD.gn spirv_cross dependency to local repo
+ - Fixes:
+   - Fix duplicate install paths when using VisualStudio
+   - Fixed BUILD.gn for Chromium, Dawn & Fuchsia
+   - Explicitly enabled HLSL support in glslang
+   - Added installing necessary headers in Android.mk
+   - Removed unsupported Unicode characters
+   - Fixed detection of spirv-headers directory
+   #666: Update Docker file to use Python3
+
+v2019.0 2019-06-04
+ - Add optional spvc, libshaderc_spvc as wrapper around SPIRV-Cross:
+   - Rejects bad modules by running the SPIR-V validator first
+   - Skips exception-heavy SPIRV-Cross SPIR-V parser
+ - Support NV extensions for shader stages
+ - Require SPIRV-Tools and SPIRV-Headers with SPIR-V 1.4 support
+ Build support:
+ - Use KhronosGroup/glslang instead of google/glslang
+ - Stop running tests on VS 2013 (googletest no longer supports VS2013)
+ - Require Python3 for building
+ - Support Chromium's GN build system
+ - Kokoro build fixes
+ - Cmake build fixes: Only build subdirs if those targets are not yet defined
+ - Use Android.mk from Glslang
+ - Dockerfile gets re2 and effcee sources
+ - Fixes for newer googletest
+ - Add address sanitizer presubmit bot
+ - Generate config files for pkg-config
+ Spvc:
+ - Add option to specify source environment.  Spvc will transform from source
+   to target environment if they are different.  This only works for WebGPU0
+   and Vulkan 1.1.
+ Fixes:
+  #499: In HLSL compilation, relax layout and logical pointer validation rules
+   prior to running the legalization recipe.
+
+v2018.0 2018-10-01
+ - Support -fhlsl_functionality1 (also -fhlsl-functionality1)
+ - Support NVIDIA Turing extensions. Requires updated Glslang and SPIRV-Tools.
+ - Use SPIR-V optimization and HLSL legalization recipes from SPIRV-Tools.
+   - Pass target environment into SPIRV-Tools code, e.g. from --target-env vulkan1.1
+ - Add SONAME=1 property to shared library
+ - Support GN build for Chromium
+ Fixes:
+  #469: Add virtual dtor to classes with virtual functions.
+  #457: Fix writing SPIR-V binaries to standard output on Windows.
+
+v2017.2 2018-02-27
+ - Add a shared library version of libshaderc
+ - Support GLSL 4.6 and ESSL 3.2
+ - Fail compilation if a resource does not have a binding.
+ - Add options for automatically setting bindings for (uniform) resources that
+   don't have bindings set in shader source.
+ - Add options for automatically setting locations for pipline inputs and outputs.
+ - Add option for using HLSL IO mappings as expressed in source.
+ - Add options for setting resource binding base numbers.
+ - Add option to use HLSL resource register numbers for bindings.
+ - HLSL compilation now defaults to HLSL packing rules.
+   (This change is inherited from Glslang commit 7cca140.)
+ - HLSL compilation runs SPIR-V "legalization" transforms to reduce
+   manipulation of opaque handles (e.g. images), to satisfy Vulkan rules.
+ - Adapt to Glslang generator version numbers:
+   - To 2: a fix for code generation for atomicCounterDecrement.
+   - To 3: change memory barrier semantics masks
+   - To 4: generate more access chains for swizzles
+ - CMake install rules uses GNUInstallDirs.  For example, install to lib64
+   when that is the norm for the target system.
+
+v2017.1 2017-03-10
+ - Add option to automatically assign bindings to uniform variables
+   that don't have an explicit 'binding' layout in the shader source.
+ - Enable NVIDIA extensions by default in GLSL compilation
+ - README mentions language bindings provided by 3rd parties.
+ - README describes the known-good branch on GitHub
+ - Fixed examples in shaderc.h; added C API use to examples/online-compile
+ - Fixes issues:
+   #289: Don't output an object file when compilation fails.
+   #296: Enable use of the CMake in Android Studio.
+
+v2016.2 2016-12-13
+ - Describe Shaderc's level of stability.
  - Support HLSL compilation, exposing functionality in Glslang.
    - Supported in C, C++ API
    - glslc accepts "-x hlsl", and assumes .hlsl files are HLSL.
    - glslc accepts "-fentry-point=<name>" to set entry point name,
      overriding default value "main".
+ - Support setting shader resource limits in C, C++ APIs, and in
+   glslc
+   - glslc adds -flimit=<setting>
+   - glslc adds --show-limits to display defaults and valid resource
+     limit syntax.
+   - glslc adds "-flimit-file <file>" support to read Glslang resource
+     configuration files, i.e. the output of "glslangValidator -c".
+ - Enable AMD extensions by default in GLSL compilation
+ - Fixes issues:
+   #281: Work around Android build issue with abspath on Windows
+   #283: Increase default maxDrawBuffers to 4, to match Vulkan/GLES3.0
 
 v2016.1 2016-10-12
  - C API for assembling now takes an options object
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a4c2fac..0c8d1ae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,9 +1,35 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 cmake_minimum_required(VERSION 2.8.12)
 project(shaderc)
 enable_testing()
 
+if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
+  message(STATUS "No build type selected, default to Debug")
+  set(CMAKE_BUILD_TYPE "Debug")
+endif()
+
 message(STATUS "Shaderc: build type is \"${CMAKE_BUILD_TYPE}\".")
 
+option(SHADERC_ENABLE_WGSL_OUTPUT "Enable WGSL output" OFF)
+
+option(SHADERC_SKIP_INSTALL "Skip installation" ${SHADERC_SKIP_INSTALL})
+if(NOT ${SHADERC_SKIP_INSTALL})
+  set(SHADERC_ENABLE_INSTALL ON)
+endif()
+
 option(SHADERC_SKIP_TESTS "Skip building tests" ${SHADERC_SKIP_TESTS})
 if(NOT ${SHADERC_SKIP_TESTS})
   set(SHADERC_ENABLE_TESTS ON)
@@ -14,17 +40,56 @@
   message(STATUS "Configuring Shaderc to avoid building tests.")
 endif()
 
+option(SHADERC_SKIP_EXAMPLES "Skip building examples" ${SHADERC_SKIP_EXAMPLES})
+if(NOT ${SHADERC_SKIP_EXAMPLES})
+  set(SHADERC_ENABLE_EXAMPLES ON)
+endif()
+if(${SHADERC_ENABLE_EXAMPLES})
+  message(STATUS "Configuring Shaderc to build examples.")
+else()
+  message(STATUS "Configuring Shaderc to avoid building examples.")
+endif()
+
+option(SHADERC_ENABLE_WERROR_COMPILE "Enable passing -Werror to compiler, if available" ON)
+
+set (CMAKE_CXX_STANDARD 11)
+
+include(GNUInstallDirs)
 include(cmake/setup_build.cmake)
 include(cmake/utils.cmake)
+include(CheckCXXCompilerFlag)
+
+set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS ${DISABLE_EXCEPTIONS} CACHE BOOL "Coupling SPIRV-Cross exception conversion to DISABLE_EXCEPTIONS" FORCE)
+if(DISABLE_EXCEPTIONS)
+  # Need to set additional values here, since some of the wrapped code occurs in
+  # .h/.hpp files, so maybe included outside of the library.
+ add_definitions(-DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
+endif()
+
+# These flags are not supported on Windows and some older version of GCC
+# that our bots use.
+# Warning about implicit fallthrough in switch blocks
+check_cxx_compiler_flag(-Wimplicit-fallthrough COMPILER_SUPPORTS_FALLTHROUGH_WARNING)
+if (COMPILER_SUPPORTS_FALLTHROUGH_WARNING)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wimplicit-fallthrough")
+endif()
+
+# Warning about extra semi-colons
+check_cxx_compiler_flag(-Wextra-semi COMPILER_SUPPORTS_EXTRA_SEMI_WARNING)
+if (COMPILER_SUPPORTS_EXTRA_SEMI_WARNING)
+    add_compile_options("-Wextra-semi")
+endif()
+
+find_host_package(PythonInterp 3 REQUIRED)
 
 add_custom_target(check-copyright ALL
-  ${PYTHON_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/utils/add_copyright.py
+  ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/utils/add_copyright.py
   --check
   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
   COMMENT "Check copyright")
 
 add_custom_target(add-copyright
-  ${PYTHON_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/utils/add_copyright.py
+  ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/utils/add_copyright.py
   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
   COMMENT "Add copyright")
 
@@ -44,6 +109,7 @@
   endif(NOT SHADERC_ENABLE_SHARED_CRT)
 endif(MSVC)
 
+
 # Configure subdirectories.
 # We depend on these for later projects, so they should come first.
 add_subdirectory(third_party)
@@ -51,10 +117,38 @@
 add_subdirectory(libshaderc_util)
 add_subdirectory(libshaderc)
 add_subdirectory(glslc)
-add_subdirectory(examples)
+if(${SHADERC_ENABLE_EXAMPLES})
+    add_subdirectory(examples)
+endif()
 
 add_custom_target(build-version
-  ${PYTHON_EXE}
+  ${PYTHON_EXECUTABLE}
   ${CMAKE_CURRENT_SOURCE_DIR}/utils/update_build_version.py
-  ${shaderc_SOURCE_DIR} ${spirv-tools_SOURCE_DIR} ${glslang_SOURCE_DIR}
+  ${shaderc_SOURCE_DIR} ${spirv-tools_SOURCE_DIR} ${glslang_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/build-version.inc
   COMMENT "Update build-version.inc in the Shaderc build directory (if necessary).")
+
+function(define_pkg_config_file NAME LIBS)
+  add_custom_target(${NAME}-pkg-config ALL
+    COMMAND ${CMAKE_COMMAND}
+      -DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
+      -DTEMPLATE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/${NAME}.pc.in
+      -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${NAME}.pc
+      -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
+      -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
+      -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
+      -DLIBS=${LIBS}
+      -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
+  DEPENDS "CHANGES" "cmake/${NAME}.pc.in" "cmake/write_pkg_config.cmake")
+
+  if (SHADERC_ENABLE_INSTALL)
+    install(
+      FILES
+        ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.pc
+      DESTINATION
+        ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+  endif()
+endfunction()
+
+define_pkg_config_file(shaderc -lshaderc_shared)
+define_pkg_config_file(shaderc_static "-lshaderc ${EXTRA_STATIC_PKGCONFIG_LIBS} -lshaderc_util")
+define_pkg_config_file(shaderc_combined -lshaderc_combined)
diff --git a/DEPS b/DEPS
new file mode 100644
index 0000000..46f4e6e
--- /dev/null
+++ b/DEPS
@@ -0,0 +1,33 @@
+use_relative_paths = True
+
+vars = {
+  'google_git':  'https://github.com/google',
+  'khronos_git': 'https://github.com/KhronosGroup',
+
+  'effcee_revision' : '2ec8f8738118cc483b67c04a759fee53496c5659',
+  'glslang_revision': 'e56beaee736863ce48455955158f1839e6e4c1a1',
+  'googletest_revision': '389cb68b87193358358ae87cc56d257fd0d80189',
+  're2_revision': '7107ebc4fbf7205151d8d2a57b2fc6e7853125d4',
+  'spirv_headers_revision': 'a3fdfe81465d57efc97cfd28ac6c8190fb31a6c8',
+  'spirv_tools_revision': 'ef3290bbea35935ba8fd623970511ed9f045bbd7',
+}
+
+deps = {
+  'third_party/effcee': Var('google_git') + '/effcee.git@' +
+      Var('effcee_revision'),
+
+  'third_party/googletest': Var('google_git') + '/googletest.git@' +
+      Var('googletest_revision'),
+
+  'third_party/glslang': Var('khronos_git') + '/glslang.git@' +
+      Var('glslang_revision'),
+
+  'third_party/re2': Var('google_git') + '/re2.git@' +
+      Var('re2_revision'),
+
+  'third_party/spirv-headers': Var('khronos_git') + '/SPIRV-Headers.git@' +
+      Var('spirv_headers_revision'),
+
+  'third_party/spirv-tools': Var('khronos_git') + '/SPIRV-Tools.git@' +
+      Var('spirv_tools_revision'),
+}
diff --git a/DEVELOPMENT.howto.md b/DEVELOPMENT.howto.md
index 0abb405..b2c9d80 100644
--- a/DEVELOPMENT.howto.md
+++ b/DEVELOPMENT.howto.md
@@ -24,7 +24,7 @@
 will require a comment.  Reviewers will also expect to see test coverage for
 every code change.  _How much_ coverage will be a judgment call on a
 case-by-case basis, balancing the required effort against the incremental
-benefit.  But coverage will be expected.  As a matter of development philosophy,
+benefit.  Coverage will be expected.  As a matter of development philosophy,
 we will strive to engineer the code to make writing tests easy.
 
 ## Coding style
@@ -50,41 +50,3 @@
 | Mac OS X | [![Mac Build Status](https://travis-ci.org/google/shaderc.svg)](https://travis-ci.org/google/shaderc "Mac Build Status") |
 | Windows (x86_64) | [![Windows Build status](https://ci.appveyor.com/api/projects/status/g6c372blna7vnk1l?svg=true)](https://ci.appveyor.com/project/dneto0/shaderc "Windows Build Status") |
 
-
-## glslang
-
-Some Shaderc changes require concomitant changes to glslang.  It is our policy
-to upstream such work to glslang by following the official glslang project's
-procedures.  At the same time, we would like to have those changes available to
-all Shaderc developers immediately upon passing our code review.  Currently this
-is best done by maintaining
-[our own GitHub fork](https://github.com/google/glslang) of glslang, landing
-Shaderc-supporting changes there<sup>\*</sup>, building Shaderc against it, and
-generating pull requests from there to the glslang's original GitHub repository.
-Although a separate repository, this should be treated as essentially a part of
-Shaderc: the Shaderc master should always<sup>\**</sup> build against our
-glslang fork's master.
-
-Changes made to glslang in the course of Shaderc development must build and test
-correctly on their own, independently of Shaderc code, so they don't break other
-users of glslang when sent upstream.  We will periodically upstream the content
-of our fork's `master` branch to the official glslang `master` branch, so all
-the contributions we accept will find their way to glslang.
-
-We aim to keep our fork up to date with the official glslang by pulling their
-changes frequently and merging them into our `master` branch.
-
-<hr><small>
-
-\*: Please note that GitHub uses the term "fork" as a routine part of
-[contributing to another project](https://help.github.com/articles/using-pull-requests/#types-of-collaborative-development-models),
-_not_ in the sense of scary open-source schism.  This is why you'll hear us
-speak of "our fork" and see "forked from KhronosGroup/glslang" atop the
-[google/glslang](https://github.com/google/glslang) GitHub page.  It does _not_
-mean that we're divorcing our glslang development from the original -- quite the
-opposite.  As stated above, we intend to upstream all our work to the original
-glslang repository.
-
-\*\*: with one small exception: if a Shaderc and glslang pull requests need each
-other and are simultaneously cherry-picked, then a `HEAD`s inconsistency will be
-tolerated for the short moment that one has landed while the other hasn't.
diff --git a/Dockerfile b/Dockerfile
index 7e7b1e0..8821239 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -21,17 +21,15 @@
     cmake \
     git \
     ninja \
-    python \
+    python3 \
     py-pip \
   && rm -rf /var/cache/apk/*
 
 WORKDIR /root
 RUN git clone https://github.com/google/shaderc
+
 WORKDIR shaderc
-RUN git clone https://github.com/google/googletest.git          third_party/googletest
-RUN git clone https://github.com/google/glslang.git             third_party/glslang
-RUN git clone https://github.com/KhronosGroup/SPIRV-Tools.git   third_party/spirv-tools
-RUN git clone https://github.com/KhronosGroup/SPIRV-Headers.git third_party/spirv-tools/external/spirv-headers
+RUN ./utils/git-sync-deps
 
 WORKDIR build
 RUN cmake -GNinja \
diff --git a/OWNERS b/OWNERS
index 8ab9c85..b5ae8b9 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,6 @@
+cfontas@google.com
+cstout@google.com
+jbauman@google.com
 jjosh@google.com
 liyl@google.com
-cfontas@google.com
+rosasco@google.com
diff --git a/README.md b/README.md
index ab68e49..2262272 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,18 @@
 # Shaderc
 
-[![Linux and Mac Build Status](https://travis-ci.org/google/shaderc.svg)](https://travis-ci.org/google/shaderc "Linux and Mac Build Status")
-[![Windows Build status](https://ci.appveyor.com/api/projects/status/g6c372blna7vnk1l?svg=true)](https://ci.appveyor.com/project/dneto0/shaderc "Windows Build Status")
-[![Coverage Status](https://coveralls.io/repos/google/shaderc/badge.svg?branch=master&service=github)](https://coveralls.io/github/google/shaderc?branch=master)
-
 A collection of tools, libraries and tests for shader compilation.
 At the moment it includes:
 
 - [`glslc`](glslc), a command line compiler for GLSL/HLSL to SPIR-V, and
-- [`libshaderc`](libshaderc), a library API for doing the same.
+- [`libshaderc`](libshaderc), a library API for accessing `glslc` functionality.
 
-Shaderc wraps around core functionality in [glslang][khr-glslang]
-and [SPIRV-Tools][spirv-tools].  Shaderc aims to
+**Note:** The fact that that `libshaderc` is not named `libshaderc_glslc` is a
+quirk of history, and a known inconsistency. Changing it would require a
+significant amount of renaming and breaking of downstream projects, so it is
+being left as is.
+
+`glslc` wraps around core functionality in [glslang][khr-glslang]
+and [SPIRV-Tools][spirv-tools]. `glslc` and its library aims to
 to provide:
 * a command line compiler with GCC- and Clang-like usage, for better
   integration with build systems
@@ -20,14 +21,28 @@
   operating systems
 * increased functionality such as file `#include` support
 
+## Downloads
+
+**Note: These binaries are just the artifacts of the builders and have not
+  undergone any QA, thus they should be considered unsupported.**
+
+<img alt="Linux" src="kokoro/img/linux.png" width="20px" height="20px" hspace="2px"/>[![Linux Build Status](https://storage.googleapis.com/shaderc/badges/build_status_linux_clang_release.svg)](https://storage.googleapis.com/shaderc/badges/build_link_linux_clang_release.html)
+<img alt="MacOS" src="kokoro/img/macos.png" width="20px" height="20px" hspace="2px"/>[![MacOS Build Status](https://storage.googleapis.com/shaderc/badges/build_status_macos_clang_release.svg)](https://storage.googleapis.com/shaderc/badges/build_link_macos_clang_release.html)
+<img alt="Windows" src="kokoro/img/windows.png" width="20px" height="20px" hspace="2px"/>[![Windows Build Status](https://storage.googleapis.com/shaderc/badges/build_status_windows_vs2017_release.svg)](https://storage.googleapis.com/shaderc/badges/build_link_windows_vs2017_release.html)
+
+[More downloads](downloads.md)
+
 ## Status
 
-Shaderc is approaching maturity, but is still subject to incompatible changes.
+Shaderc has maintained backward compatibility for quite some time, and we
+don't anticipate any breaking changes.
+Ongoing enhancements are described in the [CHANGES](CHANGES) file.
 
 Shaderc has been shipping in the
 [Android NDK](https://developer.android.com/ndk/index.html) since version r12b.
 (The NDK build uses sources from https://android.googlesource.com/platform/external/shaderc/.
 Those repos are downstream from GitHub.)
+We currently require r18b.
 
 For licensing terms, please see the [`LICENSE`](LICENSE) file.  If interested in
 contributing to this project, please see [`CONTRIBUTING.md`](CONTRIBUTING.md).
@@ -50,13 +65,6 @@
 - `utils/`: utility scripts for Shaderc
 
 Shaderc depends on glslang, the Khronos reference compiler for GLSL.
-Sometimes a change updates both Shaderc and glslang.  In that case the
-glslang change will appear in [google/glslang][google-glslang]
-before it appears upstream in [KhronosGroup/glslang][khr-glslang]
-We intend to upstream all changes to glslang. We maintain the separate
-copy only to stage those changes for review, and to provide something for
-Shaderc to build against in the meantime.  Please see
-[DEVELOPMENT.howto.md](DEVELOPMENT.howto.md) for more details.
 
 Shaderc depends on [SPIRV-Tools][spirv-tools] for assembling, disassembling,
 and transforming SPIR-V binaries.
@@ -69,18 +77,39 @@
 
 ## Getting and building Shaderc
 
+**If you only want prebuilt executables or libraries, see the
+[Downloads](#downloads) section.**
+
+The rest of this section describes how to build Shaderc from sources.
+
+Note: Shaderc assumes Glslang supports HLSL compilation.  The instructions
+below assume you're building Glslang from sources, and in a subtree
+of `shaderc/third_party`.  In that scenario, Glslang's HLSL support
+is automatically enabled.  Shaderc also can be built using a Glslang
+from outside the `shaderc/third_party` tree.  In that case you must
+ensure that that external Glslang is built with HLSL functionality.
+See Glslang's `ENABLE_HLSL` CMake setting.)
+
 1) Check out the source code:
 
 ```sh
 git clone https://github.com/google/shaderc $SOURCE_DIR
-cd $SOURCE_DIR/third_party
-git clone https://github.com/google/googletest.git
-git clone https://github.com/google/glslang.git
-git clone https://github.com/KhronosGroup/SPIRV-Tools.git spirv-tools
-git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-tools/external/spirv-headers
+cd $SOURCE_DIR
+./utils/git-sync-deps
 cd $SOURCE_DIR/
 ```
 
+**Note:** The [known-good](https://github.com/google/shaderc/tree/known-good)
+branch of the repository contains a
+[known_good.json](https://github.com/google/shaderc/blob/known-good/known_good.json)
+file describing a set of repo URLs and specific commits that have been
+tested together.  This information is updated periodically, and typically
+matches the latest update of these sources in the development branch
+of the Android NDK.
+The `known-good` branch also contains a
+[update_shaderc.py](https://github.com/google/shaderc/blob/known-good/update_shaderc_sources.py)
+script that will read the JSON file and checkout those specific commits for you.
+
 2) Ensure you have the requisite tools -- see the tools subsection below.
 
 3) Decide where to place the build output. In the following steps, we'll call it
@@ -135,7 +164,7 @@
 installed regardless of your OS:
 
 - [CMake](http://www.cmake.org/): for generating compilation targets.
-- [Python](http://www.python.org/): for utility scripts and running the test suite.
+- [Python 3](http://www.python.org/): for utility scripts and running the test suite.
 
 On Linux, the following tools should be installed:
 
@@ -152,18 +181,17 @@
 
 On Windows, the following tools should be installed and available on your path:
 
-- Visual Studio 2013 Update 4 or later. Previous versions of Visual Studio
-  will likely work but are untested.
+- Visual Studio 2015 or later. Previous versions of Visual Studio may work but
+  are untested and unsupported.
 - Git - including the associated tools, Bash, `diff`.
 
 Optionally, the following tools may be installed on any OS:
 
- - [`asciidoctor`](http://asciidoctor.org/): for generating documenation.
+ - [`asciidoctor`](http://asciidoctor.org/): for generating documentation.
    - [`pygments.rb`](https://rubygems.org/gems/pygments.rb) required by
      `asciidoctor` for syntax highlighting.
- - [`nosetests`](https://nose.readthedocs.io): for testing the Python code.
 
-### Building and running Shderc using Docker
+### Building and running Shaderc using Docker
 
 Please make sure you have the Docker engine
 [installed](https://docs.docker.com/engine/installation/) on your machine.
@@ -171,7 +199,7 @@
 To create a Docker image containing Shaderc command line tools, issue the
 following command in `${SOURCE_DIR}`: `docker build -t <IMAGE-NAME> .`.
 The created image will have all the command line tools installed at
-`/usr/local` interally, and a data volume mounted at `/code`.
+`/usr/local` internally, and a data volume mounted at `/code`.
 
 Assume `<IMAGE-NAME>` is `shaderc/shaderc` from now on.
 
@@ -211,6 +239,23 @@
 Then the coverage report can be found under the `$BUILD_DIR/coverage-report`
 directory.
 
+## Bindings
+
+Bindings are maintained by third parties, may contain content
+offered under a different license, and may reference or contain
+older versions of Shaderc and its dependencies.
+
+* **Python:** [pyshaderc][pyshaderc]
+* **Rust:** [shaderc-rs][shaderc-rs]
+* **Go:** [gshaderc][gshaderc]
+* **.NET:** [shaderc.net][shadercdotnet]
+
 [khr-glslang]: https://github.com/KhronosGroup/glslang
-[google-glslang]: https://github.com/google/glslang
 [spirv-tools]: https://github.com/KhronosGroup/SPIRV-Tools
+[spirv-cross]: https://github.com/KhronosGroup/SPIRV-Cross
+[pyshaderc]: https://github.com/realitix/pyshaderc
+[shaderc-rs]: https://github.com/google/shaderc-rs
+[appveyor]: https://ci.appveyor.com/project/dneto0/shaderc
+[dawn]: https://dawn.googlesource.com/dawn
+[gshaderc]: https://github.com/celer/gshaderc
+[shadercdotnet]: https://github.com/jpbruyere/shaderc.net
diff --git a/android_test/Android.mk b/android_test/Android.mk
index 4959331..31ad381 100644
--- a/android_test/Android.mk
+++ b/android_test/Android.mk
@@ -1,3 +1,17 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
diff --git a/android_test/jni/Android.mk b/android_test/jni/Android.mk
index 8a36259..1360751 100644
--- a/android_test/jni/Android.mk
+++ b/android_test/jni/Android.mk
@@ -1,2 +1,16 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 LOCAL_PATH := $(call my-dir)
 include $(LOCAL_PATH)/../Android.mk
diff --git a/android_test/jni/Application.mk b/android_test/jni/Application.mk
index 1f3808b..ef50946 100644
--- a/android_test/jni/Application.mk
+++ b/android_test/jni/Application.mk
@@ -1,4 +1,18 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 APP_ABI := all
 APP_BUILD_SCRIPT := Android.mk
-APP_STL := gnustl_static
-APP_PLATFORM := android-9
+APP_STL := c++_static
+APP_PLATFORM := android-16
diff --git a/android_test/test.cpp b/android_test/test.cpp
index 23df9b8..b4b9f93 100644
--- a/android_test/test.cpp
+++ b/android_test/test.cpp
@@ -16,7 +16,6 @@
 #include <android_native_app_glue.h>
 
 void android_main(struct android_app* state) {
-  app_dummy();
   shaderc::Compiler compiler;
   const char* test_program = "void main() {}";
   compiler.CompileGlslToSpv(test_program, strlen(test_program),
diff --git a/build_overrides/build.gni b/build_overrides/build.gni
new file mode 100644
index 0000000..abfb5d1
--- /dev/null
+++ b/build_overrides/build.gni
@@ -0,0 +1,18 @@
+# Copyright 2019 The Shaderc Authors. All rights reserved.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# These are variables that are overridable by projects that include shaderc.
+
+# Set to true when building shaderc as part of Chromium.
+build_with_chromium = false
diff --git a/build_overrides/shaderc.gni b/build_overrides/shaderc.gni
new file mode 100644
index 0000000..fea75fd
--- /dev/null
+++ b/build_overrides/shaderc.gni
@@ -0,0 +1,21 @@
+# Copyright 2018 The Shaderc Authors. All rights reserved.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# These are variables that are overridable by projects that include shaderc.
+
+# The path to shaderc dependencies.
+shaderc_glslang_dir = "//third_party/glslang"
+shaderc_spirv_tools_dir = "//third_party/spirv-tools"
+shaderc_spirv_headers_dir = "//third_party/spirv-headers"
+
diff --git a/cmake/linux-mingw-toolchain.cmake b/cmake/linux-mingw-toolchain.cmake
index 400b9a0..60e965e 100644
--- a/cmake/linux-mingw-toolchain.cmake
+++ b/cmake/linux-mingw-toolchain.cmake
@@ -1,3 +1,17 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 SET(CMAKE_SYSTEM_NAME Windows)
 
 set(MINGW_COMPILER_PREFIX "i686-w64-mingw32" CACHE STRING
@@ -8,8 +22,12 @@
 
 # Which compilers to use for C and C++
 find_program(CMAKE_RC_COMPILER NAMES ${MINGW_COMPILER_PREFIX}-windres)
-find_program(CMAKE_C_COMPILER NAMES ${MINGW_COMPILER_PREFIX}-gcc)
-find_program(CMAKE_CXX_COMPILER NAMES ${MINGW_COMPILER_PREFIX}-g++)
+find_program(CMAKE_C_COMPILER NAMES
+	     ${MINGW_COMPILER_PREFIX}-gcc-posix
+	     ${MINGW_COMPILER_PREFIX}-gcc)
+find_program(CMAKE_CXX_COMPILER NAMES
+	     ${MINGW_COMPILER_PREFIX}-g++-posix
+	     ${MINGW_COMPILER_PREFIX}-g++)
 
 SET(CMAKE_FIND_ROOT_PATH ${MINGW_SYSROOT})
 
diff --git a/cmake/setup_build.cmake b/cmake/setup_build.cmake
index b46d920..5dab384 100644
--- a/cmake/setup_build.cmake
+++ b/cmake/setup_build.cmake
@@ -1,8 +1,26 @@
-# Find nosetests; see shaderc_add_nosetests() from utils.cmake for opting in to
-# nosetests in a specific directory.
-find_program(NOSETESTS_EXE NAMES nosetests PATHS $ENV{PYTHON_PACKAGE_PATH})
-if (NOT NOSETESTS_EXE)
-  message(STATUS "nosetests was not found - python code will not be tested")
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if(NOT COMMAND find_host_package)
+  macro(find_host_package)
+    find_package(${ARGN})
+  endmacro()
+endif()
+if(NOT COMMAND find_host_program)
+  macro(find_host_program)
+    find_program(${ARGN})
+  endmacro()
 endif()
 
 # Find asciidoctor; see shaderc_add_asciidoc() from utils.cmake for
@@ -24,18 +42,16 @@
 if (ANDROID)
 # For android let's preemptively find the correct packages so that
 # child projects (glslang, googletest) do not fail to find them.
-find_host_package(PythonInterp)
+
+# Tests in glslc and SPIRV-Tools tests require Python 3, or a Python 2
+# with the "future" package.  Require Python 3 because we can't force
+# developers to manually install the "future" package.
+find_host_package(PythonInterp 3 REQUIRED)
 find_host_package(BISON)
+else()
+find_package(PythonInterp 3 REQUIRED)
 endif()
 
-foreach(PROGRAM echo python)
-  string(TOUPPER ${PROGRAM} PROG_UC)
-  if (ANDROID)
-    find_host_program(${PROG_UC}_EXE ${PROGRAM} REQUIRED)
-  else()
-    find_program(${PROG_UC}_EXE ${PROGRAM} REQUIRED)
-  endif()
-endforeach(PROGRAM)
 
 option(ENABLE_CODE_COVERAGE "Enable collecting code coverage." OFF)
 if (ENABLE_CODE_COVERAGE)
@@ -71,7 +87,7 @@
     # The symptom is that some .gcno files are wrong after code change and
     # recompiling. We don't know the exact reason yet. Figure it out.
     # Remove all .gcno files in the directory recursively.
-    COMMAND ${PYTHON_EXE}
+    COMMAND ${PYTHON_EXECUTABLE}
     ${shaderc_SOURCE_DIR}/utils/remove-file-by-suffix.py . ".gcno"
     # .gcno files are not tracked by CMake. So no recompiling is triggered
     # even if they are missing. Unfortunately, we just removed all of them
diff --git a/cmake/shaderc.pc.in b/cmake/shaderc.pc.in
new file mode 100644
index 0000000..6d217bf
--- /dev/null
+++ b/cmake/shaderc.pc.in
@@ -0,0 +1,12 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+
+Name: shaderc
+Description: Tools and libraries for Vulkan shader compilation
+Version: @CURRENT_VERSION@
+URL: https://github.com/google/shaderc
+
+Libs: -L${libdir} @LIBS@
+Cflags: -I${includedir}
diff --git a/cmake/shaderc_combined.pc.in b/cmake/shaderc_combined.pc.in
new file mode 100644
index 0000000..6d217bf
--- /dev/null
+++ b/cmake/shaderc_combined.pc.in
@@ -0,0 +1,12 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+
+Name: shaderc
+Description: Tools and libraries for Vulkan shader compilation
+Version: @CURRENT_VERSION@
+URL: https://github.com/google/shaderc
+
+Libs: -L${libdir} @LIBS@
+Cflags: -I${includedir}
diff --git a/cmake/shaderc_static.pc.in b/cmake/shaderc_static.pc.in
new file mode 100644
index 0000000..6d217bf
--- /dev/null
+++ b/cmake/shaderc_static.pc.in
@@ -0,0 +1,12 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+
+Name: shaderc
+Description: Tools and libraries for Vulkan shader compilation
+Version: @CURRENT_VERSION@
+URL: https://github.com/google/shaderc
+
+Libs: -L${libdir} @LIBS@
+Cflags: -I${includedir}
diff --git a/cmake/utils.cmake b/cmake/utils.cmake
index f807d9f..d64757d 100644
--- a/cmake/utils.cmake
+++ b/cmake/utils.cmake
@@ -1,3 +1,17 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 # utility functions
 
 function (shaderc_use_gmock TARGET)
@@ -9,7 +23,15 @@
 
 function(shaderc_default_c_compile_options TARGET)
   if (NOT "${MSVC}")
-    target_compile_options(${TARGET} PRIVATE -Wall -Werror)
+    if (SHADERC_ENABLE_WERROR_COMPILE)
+      target_compile_options(${TARGET} PRIVATE -Wall -Werror -fvisibility=hidden)
+    else()
+      target_compile_options(${TARGET} PRIVATE -Wall -fvisibility=hidden)
+    endif()
+    check_cxx_compiler_flag(-fPIC COMPILER_SUPPORTS_PIC)
+    if (NOT "${MINGW}" AND COMPILER_SUPPORTS_PIC)
+      target_compile_options(${TARGET} PRIVATE -fPIC)
+    endif()
     if (ENABLE_CODE_COVERAGE)
       # The --coverage option is a synonym for -fprofile-arcs -ftest-coverage
       # when compiling.
@@ -59,22 +81,13 @@
         ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.asciidoc
       DEPENDS ${FILE}.asciidoc ${ARGN}
       OUTPUT ${DEST})
-    add_custom_target(${TARGET} ALL DEPENDS ${DEST})
+    # Create the target, but the default build target does not depend on it.
+    # Some Asciidoctor installations are mysteriously broken, and it's hard
+    # to detect those cases.  Generating HTML is not critical by default.
+    add_custom_target(${TARGET} DEPENDS ${DEST})
   endif(ASCIIDOCTOR_EXE)
 endfunction()
 
-# Run nosetests on file ${PREFIX}_nosetest.py. Nosetests will look for classes
-# and functions whose names start with "nosetest". The test name will be
-# ${PREFIX}_nosetests.
-function(shaderc_add_nosetests PREFIX)
-  if("${SHADERC_ENABLE_TESTS}" AND NOSETESTS_EXE)
-    add_test(
-      NAME ${PREFIX}_nosetests
-      COMMAND ${NOSETESTS_EXE} -m "^[Nn]ose[Tt]est" -v
-        ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}_nosetest.py)
-  endif()
-endfunction()
-
 # Adds a set of tests.
 # This function accepts the following parameters:
 # TEST_PREFIX:  a prefix for each test target name
@@ -103,6 +116,11 @@
       if (MINGW)
         target_compile_options(${TEST_NAME} PRIVATE -DSHADERC_DISABLE_THREADED_TESTS)
       endif()
+      if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+        # Disable this warning, which is useless in test code.
+        # Fixes https://github.com/google/shaderc/issues/334
+        target_compile_options(${TEST_NAME} PRIVATE -Wno-noexcept-type)
+      endif()
       if (PARSED_ARGS_LINK_LIBS)
         target_link_libraries(${TEST_NAME} PRIVATE
         ${PARSED_ARGS_LINK_LIBS})
@@ -128,7 +146,18 @@
     get_target_property(libtype ${target} TYPE)
     # If this target is a static library, get anything it depends on.
     if ("${libtype}" STREQUAL "STATIC_LIBRARY")
-      list(INSERT ${out_list} 0 "${target}")
+      # Get the original library if this is an alias library. This is
+      # to avoid putting both the original library and the alias library
+      # in the list (given we are deduplicating according to target names).
+      # Otherwise, we may pack the same library twice, resulting in
+      # duplicated symbols.
+      get_target_property(aliased_target ${target} ALIASED_TARGET)
+      if (aliased_target)
+        list(INSERT ${out_list} 0 "${aliased_target}")
+      else()
+        list(INSERT ${out_list} 0 "${target}")
+      endif()
+
       get_target_property(libs ${target} LINK_LIBRARIES)
       if (libs)
         foreach(lib ${libs})
@@ -150,15 +179,7 @@
   shaderc_get_transitive_libs(${target} all_libs)
 
   set(libname
-      ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${new_target}${CMAKE_STATIC_LIBRARY_SUFFIX})
-
-  if (CMAKE_CONFIGURATION_TYPES)
-    list(LENGTH CMAKE_CONFIGURATION_TYPES num_configurations)
-    if (${num_configurations} GREATER 1)
-      set(libname
-          ${CMAKE_CFG_INTDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${new_target}${CMAKE_STATIC_LIBRARY_SUFFIX})
-    endif()
-  endif()
+      ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${new_target}${CMAKE_STATIC_LIBRARY_SUFFIX})
 
   if (MSVC)
     string(REPLACE ";" ">;$<TARGET_FILE:" temp_string "${all_libs}")
diff --git a/cmake/write_pkg_config.cmake b/cmake/write_pkg_config.cmake
new file mode 100644
index 0000000..d367ce3
--- /dev/null
+++ b/cmake/write_pkg_config.cmake
@@ -0,0 +1,31 @@
+# Copyright (c) 2017 Pierre Moreau
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# First, retrieve the current version from CHANGES
+file(STRINGS ${CHANGES_FILE} CHANGES_CONTENT)
+string(
+REGEX
+  MATCH "v[0-9]+(.[0-9]+)?(-dev)? [0-9]+-[0-9]+-[0-9]+"
+  FIRST_VERSION_LINE
+  ${CHANGES_CONTENT})
+string(
+REGEX
+  REPLACE "^v([^ ]+) .+$" "\\1"
+  CURRENT_VERSION
+  "${FIRST_VERSION_LINE}")
+# If this is a development version, replace "-dev" by ".0" as pkg-config nor
+# CMake support "-dev" in the version.
+# If it's not a "-dev" version then ensure it ends with ".1"
+string(REGEX REPLACE "-dev.1" ".0" CURRENT_VERSION "${CURRENT_VERSION}.1")
+configure_file(${TEMPLATE_FILE} ${OUT_FILE} @ONLY)
diff --git a/downloads.md b/downloads.md
new file mode 100644
index 0000000..1738668
--- /dev/null
+++ b/downloads.md
@@ -0,0 +1,17 @@
+# Downloads
+Download the latest builds.
+
+**Note: These binaries are just the artifacts of the builders and have not
+  undergone any QA, thus they should be considered unsupported.**
+
+## Release
+| Windows | Linux | MacOS |
+| --- | --- | --- |
+| [MSVC 2017](https://storage.googleapis.com/shaderc/badges/build_link_windows_vs2017_release.html) | [clang](https://storage.googleapis.com/shaderc/badges/build_link_linux_clang_release.html) | [clang](https://storage.googleapis.com/shaderc/badges/build_link_macos_clang_release.html) |
+| [MSVC 2015](https://storage.googleapis.com/shaderc/badges/build_link_windows_vs2015_release.html) | [gcc](https://storage.googleapis.com/shaderc/badges/build_link_linux_gcc_release.html) | |
+
+## Debug
+| Windows | Linux | MacOS |
+| --- | --- | --- |
+| [MSVC 2017](https://storage.googleapis.com/shaderc/badges/build_link_windows_vs2017_debug.html) | [clang](https://storage.googleapis.com/shaderc/badges/build_link_linux_clang_debug.html) | [clang](https://storage.googleapis.com/shaderc/badges/build_link_macos_clang_debug.html) |
+| | [gcc](https://storage.googleapis.com/shaderc/badges/build_link_linux_gcc_debug.html) | |
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 176c40b..ce1f4c0 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1 +1,15 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 add_subdirectory(online-compile)
diff --git a/examples/online-compile/CMakeLists.txt b/examples/online-compile/CMakeLists.txt
index e4541e0..6cceb6b 100644
--- a/examples/online-compile/CMakeLists.txt
+++ b/examples/online-compile/CMakeLists.txt
@@ -1,3 +1,18 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 add_executable(shaderc-online-compile main.cc)
 shaderc_default_compile_options(shaderc-online-compile)
+target_include_directories(shaderc-online-compile PUBLIC ${shaderc_SOURCE_DIR}/libshaderc_util/include)
 target_link_libraries(shaderc-online-compile PRIVATE shaderc)
diff --git a/examples/online-compile/main.cc b/examples/online-compile/main.cc
index 92d9835..9e1ca5b 100644
--- a/examples/online-compile/main.cc
+++ b/examples/online-compile/main.cc
@@ -23,6 +23,7 @@
 //  - Setting basic options: setting a preprocessor symbol.
 //  - Checking compilation status and extracting an error message.
 
+#include <cstring>
 #include <iostream>
 #include <string>
 #include <vector>
@@ -143,5 +144,28 @@
     compile_file("bad_src", shaderc_glsl_vertex_shader, kBadShaderSource);
   }
 
+  {  // Compile using the C API.
+    std::cout << "\n\nCompiling with the C API" << std::endl;
+
+    // The first example has a compilation problem.  The second does not.
+    const char source[2][80] = {"void main() {}", "#version 450\nvoid main() {}"};
+
+    shaderc_compiler_t compiler = shaderc_compiler_initialize();
+    for (int i = 0; i < 2; ++i) {
+      std::cout << "  Source is:\n---\n" << source[i] << "\n---\n";
+      shaderc_compilation_result_t result = shaderc_compile_into_spv(
+          compiler, source[i], std::strlen(source[i]), shaderc_glsl_vertex_shader,
+          "main.vert", "main", nullptr);
+      auto status = shaderc_result_get_compilation_status(result);
+      std::cout << "  Result code " << int(status) << std::endl;
+      if (status != shaderc_compilation_status_success) {
+        std::cout << "error: " << shaderc_result_get_error_message(result)
+                  << std::endl;
+      }
+      shaderc_result_release(result);
+    }
+    shaderc_compiler_release(compiler);
+  }
+
   return 0;
 }
diff --git a/glslc/CMakeLists.txt b/glslc/CMakeLists.txt
index ba4d4c5..31664d1 100644
--- a/glslc/CMakeLists.txt
+++ b/glslc/CMakeLists.txt
@@ -1,3 +1,17 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 find_package(Threads)
 
 add_library(glslc STATIC
@@ -7,6 +21,8 @@
   src/file.h
   src/file_includer.cc
   src/file_includer.h
+  src/resource_parse.h
+  src/resource_parse.cc
   src/shader_stage.cc
   src/shader_stage.h
   src/dependency_info.cc
@@ -15,9 +31,22 @@
 
 shaderc_default_compile_options(glslc)
 target_include_directories(glslc PUBLIC ${glslang_SOURCE_DIR})
-target_link_libraries(glslc PRIVATE glslang OSDependent OGLCompiler
-  HLSL glslang SPIRV ${CMAKE_THREAD_LIBS_INIT})
-target_link_libraries(glslc PRIVATE shaderc_util shaderc)
+
+if (SHADERC_ENABLE_WGSL_OUTPUT)
+  if (IS_DIRECTORY "${tint_SOURCE_DIR}/include")
+    target_include_directories(glslc PRIVATE "${tint_SOURCE_DIR}/include")
+    target_include_directories(glslc PRIVATE "${tint_SOURCE_DIR}")
+  endif()
+  # Turn on features in the tint/tint.h header
+  add_definitions(-DTINT_BUILD_SPV_READER=1 -DTINT_BUILD_WGSL_WRITER=1)
+  add_definitions(-DSHADERC_ENABLE_WGSL_OUTPUT=1)
+endif(SHADERC_ENABLE_WGSL_OUTPUT)
+
+target_link_libraries(glslc PRIVATE
+  glslang OSDependent OGLCompiler HLSL glslang SPIRV    # Glslang libraries
+  $<$<BOOL:${SHADERC_ENABLE_WGSL_OUTPUT}>:libtint>      # Tint libraries, optional
+  shaderc_util shaderc                                  # internal Shaderc libraries
+  ${CMAKE_THREAD_LIBS_INIT})
 
 add_executable(glslc_exe src/main.cc)
 shaderc_default_compile_options(glslc_exe)
@@ -31,11 +60,14 @@
   LINK_LIBS glslc shaderc_util shaderc
   TEST_NAMES
     file
+    resource_parse
     stage)
 
 shaderc_add_asciidoc(glslc_doc_README README)
 
-install(TARGETS glslc_exe
-  RUNTIME DESTINATION bin)
+if(SHADERC_ENABLE_INSTALL)
+  install(TARGETS glslc_exe
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+endif(SHADERC_ENABLE_INSTALL)
 
 add_subdirectory(test)
diff --git a/glslc/README.asciidoc b/glslc/README.asciidoc
index a8f22c9..dfd105b 100644
--- a/glslc/README.asciidoc
+++ b/glslc/README.asciidoc
@@ -1,5 +1,6 @@
 = glslc Manual
-
+:toc:
+:toclevels: 3
 :numbered:
 :source-highlighter: pygments
 
@@ -11,11 +12,24 @@
 == Synopsis
 
 ----
+glslc [--help]
+glslc [-h]
+
+glslc [--show-limits]
+
 glslc [-c|-S|-E]
       [-x ...] [-std=standard]
+      [ ... options for resource bindings ... ]
+      [-fhlsl-offsets]
+      [-fhlsl-functionality1]
+      [-fentry-point=<name>]
+      [-fauto-map-locations]
+      [-finvert-y]
+      [-flimit=...]
+      [-flimit-file <resource-limits-file>]
       [-fshader-stage=...]
-      [-fentry-point=...]
       [--target-env=...]
+      [--target-spv=...]
       [-g]
       [-O0|-Os]
       [-Idirectory...]
@@ -43,7 +57,7 @@
 on the other hand, enable you to specify shader stages from the command line
 and within the source file. Possible ``stage``s for them are also listed in
 the following table. Details about `-fshader-stage=` can be found in
-<<option-f-shader-stage,its own section>>.
+<<option-fshader-stage,its own section>>.
 
 [[shader-stage-selection]]
 .Shader Stage Selection
@@ -94,11 +108,11 @@
 ** If the input file has a <<shader-stage-selection,shader stage selection
    extension>>, the output file will be named as by appending the file extension
    for the compilation stage to the input file's name. E.g., `glslc -c foo.vert`
-   will generate `foo.vert.spv`, and `glslc -s bar.frag` will generate
+   will generate `foo.vert.spv`, and `glslc -S bar.frag` will generate
    `bar.frag.spvasm`.
 ** Otherwise, the output file will be named as by replacing the input file's
    file extension, if any, with the file extension for the compilation stage.
-   E.g., `glslc -c foo` will generate `foo.spv`, and `glslc -s bar.glsl` will
+   E.g., `glslc -c foo` will generate `foo.spv`, and `glslc -S bar.glsl` will
    generate `bar.spvasm`.
 * If no compilation stage is selected, the output file will be named `a.spv`.
 
@@ -106,9 +120,15 @@
 
 === Overall Options
 
-==== `--help`
+==== `--help`, `-h`
 
-`--help` tells the glslc compiler to display all available options and exit.
+Option `--help` or `-h` tells the glslc compiler to display all available options and exit.
+
+==== `--show-limits`
+
+`--show-limits` shows default resource limits for shader compilation.  The syntax
+is the same as accepted by `-flimit=` and for the contents of the file specified
+by `-flimit-file`.
 
 ==== `-o`
 
@@ -117,7 +137,34 @@
 
 === Language and Mode Selection Options
 
-[[option-f-shader-stage]]
+[[option-finvert-y]]
+==== `-finvert-y`
+
+Inverts position.Y output in a vertex shader.
+
+[[option-flimit]]
+==== `-flimit=`
+
+`-flimit=<resource-limits>` lets you specify resource limits.
+The argument should be a sequence of limit name, integer value pairs.  Tokens
+should be separated by whitespace.  If the same limit is specified several
+times, only the last setting takes effect.
+
+Use `--show-limits` to show the default values, and example syntax.
+
+This option affects all compiled shaders.
+
+[[option-flimit-file]]
+==== `-flimit-file`
+
+`-flimit-file <resource-limits-file>` lets you specify resource limits in a file.
+The syntax of the file contents is the same as the argument to `-flimit=` and
+the output of `--show-limits`.  This option accepts Glslang resource configuration
+files, e.g. as emitted by `glslangValidator -c`.
+
+This option affects all compiled shaders.
+
+[[option-fshader-stage]]
 ==== `-fshader-stage=`
 
 `-fshader-stage=<stage>` lets you specify the shader stage for one or more
@@ -151,12 +198,6 @@
 `-fshader-stage=`, since `-fshader-stage=` only affects the treatment of
 subsequent files.
 
-[[option-f-entry-point]]
-==== `-fentry-point=`
-
-`-fentry-point=<name>` lets you specify the entry point name.  This is only
-significant for HLSL compilation.  The default is "main".
-
 ==== `-std=`
 
 `-std=<value>` lets you specify a shader version and profile on the command
@@ -185,16 +226,39 @@
 ==== `--target-env=`
 
 `--target-env=<value>` lets you specify a target environment on the command line.
-This affects the generation of warnings and errors. ``<value>`` can be one of
+This affects the generation of warnings and errors. The ``<value>`` can be one of
 the following:
 
-* `vulkan`: create SPIR-V under Vulkan semantics.
-* `opengl`: create SPIR-V under OpenGL semantics.
+* `vulkan`: create SPIR-V under Vulkan 1.0 semantics.
+* `vulkan1.0`: create SPIR-V under Vulkan 1.0 semantics.
+* `vulkan1.1`: create SPIR-V under Vulkan 1.1 semantics.
+* `vulkan1.2`: create SPIR-V under Vulkan 1.2 semantics.
+* `opengl`: create SPIR-V under OpenGL 4.5 semantics.
+* `opengl4.5`: create SPIR-V under OpenGL 4.5 semantics.
 * `opengl_compat`: create SPIR-V under OpenGL semantics, including compatibility
   profile functions.
 
-By default, the ``<value>`` is set to `vulkan` and the compiler creates SPIR-V
-under Vulkan semantics.
+Generated code uses SPIR-V 1.0, except for code compiled for Vulkan 1.1, which uses
+SPIR-V 1.3, and code compiled for Vulkan 1.5, which uses SPIR-V 1.5.
+
+If this option is not specified, a default of `vulkan1.0` is used.
+
+==== `--target-spv=`
+
+`--target-spv=<value>` lets you specify the SPIR-V version to be used by the generated
+module.  The default is to use the highest version of SPIR-V required to be supported
+by the target environment.  The defaults for specific Vulkan target environments are
+as follows: SPIR-V 1.0 for Vulkan 1.0, SPIR-V 1.3 for Vulkan 1.1, and SPIR-V 1.5 for
+Vulkan 1.2.
+
+The ``<value>`` can be one of the following:
+
+* `spv1.0`
+* `spv1.1`
+* `spv1.2`
+* `spv1.3`
+* `spv1.4`
+* `spv1.5`
 
 ==== `-x`
 
@@ -202,6 +266,10 @@
 are `glsl` and `hlsl`.  If the file extension is `hlsl` then the default language
 is HLSL.  Otherwise the default is 'glsl'.
 
+Note: HLSL compilation will use HLSL packing (offset) rules for variables
+that are vertex shader outputs, and inputs and outputs of both geometry
+and pixel shaders.
+
 [[compilation-stage-selection-options]]
 === Compilation Stage Selection Options
 
@@ -272,6 +340,7 @@
 `-O` specifies which optimization level to use:
 
 * `-O0` means "no optimization". This level generates the most debuggable code.
+* `-O` means the default optimization level for better performance.
 * `-Os` enables optimizations to reduce code size.
 
 ==== `-mfmt=<format>`
@@ -307,6 +376,60 @@
                  {0x07230203, 0x00010000, 0x00080001, 0x00000006...}
 |===
 
+[[option-fhlsl-offsets]]
+==== `-fhlsl-offsets`
+
+Use HLSL packing rules instead of GLSL rules when determining offsets of
+members of blocks.  This option is always on when compiling for HLSL.
+
+[[option-fhlsl-functionality1]]
+==== `-fhlsl-functionality1`
+
+Enable extension `SPV_GOOGLE_hlsl_functionality1`, and instructs the compiler
+to:
+
+- Annotate HLSL semantic string decorations on interface objects
+- Explicitly record the association of a UAV resource with its companion counter buffer.
+
+This option can also be spelled with an underscore: `-fhlsl_functionality1`.
+
+[[option-fentry-point]]
+==== `-fentry-point=<name>`
+
+`-fentry-point=<name>` lets you specify the entry point name.  This is only
+significant for HLSL compilation.  The default is "main".
+
+[[option-fauto-map-locations]]
+==== `-fauto-map-locations`
+
+For GLSL compilation, option `-fauto-map-locations` directs the compiler to automatically
+assign location numbers to user-defined stage input and output variables if not explicitly
+specified by the shader source.
+
+For HLSL compilation, this option is on by default.
+
+Client APIs normally require adjacent stages to agree on their I/O interface.
+The compiler only sees one stage at a time, so it is strongly recommended that
+you avoid relying on this option to assign locations.
+
+Instead, an explicit binding number should be specified in the shader source, as follows:
+
+* In a GLSL shader, use a `location` layout qualifier:
+
+----
+layout(location = 1) in vec4 x;
+----
+
+* In an HLSL shader, use a `vk::location` attribute:
+
+----
+[[vk::location(1)]] float4 FooShader(
+  [[vk::location(0)]] float4 a,
+  [[vk::location(2)]] float4 b) : COLOR0 {
+  return a + b;
+}
+----
+
 === Warning and Error Options
 
 ==== `-w`
@@ -405,6 +528,113 @@
 |glslc -c -MD main.vert -o obj -MF dep_info -MT target|obj|dep_info|target: main.vert
 |===
 
+=== Resource Binding Options
+
+[[option-fauto-bind-uniforms]]
+==== `-fauto-bind-uniforms`
+
+Option `-fauto-bind-uniforms` directs the compiler to automatically assign
+binding numbers to uniform variables, when an explicit binding is not
+specified in the shader source.
+
+An explicit binding number can be specified in the shader source by using
+a `binding` layout qualifier.  For example:
+
+----
+layout(binding = 12) uniform texture2D;
+----
+
+[[option-fhlsl-iomap]]
+==== `-fhlsl-iomap`
+
+Option `-fhlsl-iomap` directs the compiler to use HLSL register
+assignments as binding values.
+
+[[option-fimage-binding-base]]
+==== `-fimage-binding-base`
+
+Option `-fimage-binding-base [stage] base` sets the lowest automatically
+assigned binding for images.  If a stage is specified, only affects the specified
+stage.
+
+For HLSL, sets one less than the base.
+
+[[option-fsampler-binding-base]]
+==== `-fsampler-binding-base`
+
+Option `-fsampler-binding-base [stage] base` sets the lowest automatically
+assigned binding for samplers.  If a stage is specified, only affects the specified
+stage.
+
+For HLSL, sets one less than the base.
+
+[[option-ftexture-binding-base]]
+==== `-ftexture-binding-base`
+
+Option `-ftexture-binding-base [stage] base` sets the lowest automatically
+assigned binding for textures.  If a stage is specified, only affects the specified
+stage.
+
+For HLSL, sets one less than the base.
+
+[[option-fubo-binding-base]]
+==== `-fubo-binding-base`
+
+Option `-fubo-binding-base [stage] base` sets the lowest automatically
+assigned binding for Uniform Buffer Objects (GLSL) or Cbuffers (HLSL).
+If a stage is specified, only affects the specified stage.
+
+For HLSL, sets one less than the base.
+
+[[option-fcbuffer-binding-base]]
+==== `-fcbuffer-binding-base`
+
+Option `-fcbuffer-binding-base [stage] base` is the same as
+`-fubo-binding-base [stage] base`.
+
+[[option-fssbo-binding-base]]
+==== `-fssbo-binding-base`
+
+Option `-fssbo-binding-base [stage] base` sets the lowest automatically
+assigned binding for Shader Storage Buffer Objects (GLSL).
+If a stage is specified, only affects the specified stage.
+
+This only affects GLSL compilation.
+
+[[option-fuav-binding-base]]
+==== `-fuav-binding-base`
+
+Option `-fuav-binding-base [stage] base` sets one less than the lowest
+automatically assigned binding for Unordered Access Views (UAV).
+If a stage is specified, only affects the specified stage.
+
+This only affects HLSL compilation.
+
+[[option-fregister-set-binding]]
+==== `-fresource-set-binding`
+
+Option `-fresource-set-binding [stage] <reg0> <set0> <binding0>` sets
+the descriptor set and binding for an HLSL resource, by register name.
+To specify settings for more registers, append their triples consisting
+of register name, descriptor set, and binding.
+
+Example:
+
+----
+# For a texture in register t1, use set 1 binding 0.
+# For a texture in register t2, use set 1 binding 3
+glslc -x hlsl foo.frag -fresource-set-binding t1 1 0 t2 1 3
+----
+
+If a stage is specified, only affects the specified stage.
+
+----
+# Same as the previous example, but the settings only apply
+# to fragment (pixel) shaders.
+glslc -x hlsl foo.frag -fresource-set-binding frag t1 1 0 t2 1 3
+----
+
+
 == Divergence from and extensions to GLSL specifications
 
 === Source-filename-based `#line` and `\\__FILE__`
diff --git a/glslc/src/dependency_info.cc b/glslc/src/dependency_info.cc
index 10169d9..2622629 100644
--- a/glslc/src/dependency_info.cc
+++ b/glslc/src/dependency_info.cc
@@ -49,7 +49,7 @@
   } else if (mode_ == dump_as_extra_file) {
     std::ofstream potential_file_stream_for_dep_info_dump;
     std::ostream* dep_file_stream = shaderc_util::GetOutputStream(
-        dep_file_name, &potential_file_stream_for_dep_info_dump);
+        dep_file_name, &potential_file_stream_for_dep_info_dump, &std::cerr);
     *dep_file_stream << dep_string_stream.str();
     if (dep_file_stream->fail()) {
       std::cerr << "glslc: error: error writing dependent_files info to output "
diff --git a/glslc/src/dependency_info.h b/glslc/src/dependency_info.h
index b0b4756..b7c7d8d 100644
--- a/glslc/src/dependency_info.h
+++ b/glslc/src/dependency_info.h
@@ -40,7 +40,7 @@
   // Sets the name of the file where dependency info will be written.
   void SetDependencyFileName(const std::string& dep_file_name) {
     user_specified_dep_file_name_ = dep_file_name;
-  };
+  }
 
   // Dump depdendency info to a) an extra dependency info file, b) an string
   // which holds the compilation output. The choice depends on the dump
@@ -70,7 +70,7 @@
   // Sets to always dump dependency info as an extra file, instead of the normal
   // compilation output. This means the output name specified by -o options
   // won't be used for the dependency info file.
-  void SetDumpToExtraDependencyInfoFiles() { mode_ = dump_as_extra_file; };
+  void SetDumpToExtraDependencyInfoFiles() { mode_ = dump_as_extra_file; }
 
   // Sets to dump dependency info as normal compilation output. The dependency
   // info will be either saved in a file with -o option specified file, or, if
diff --git a/glslc/src/file_compiler.cc b/glslc/src/file_compiler.cc
index 5469736..5d67be1 100644
--- a/glslc/src/file_compiler.cc
+++ b/glslc/src/file_compiler.cc
@@ -20,6 +20,10 @@
 #include <iostream>
 #include <sstream>
 
+#if SHADERC_ENABLE_WGSL_OUTPUT == 1
+#include "tint/tint.h"
+#endif  // SHADERC_ENABLE_WGSL_OUTPUT==1
+
 #include "file.h"
 #include "file_includer.h"
 #include "shader_stage.h"
@@ -69,15 +73,7 @@
     return false;
   }
 
-  std::string output_name = GetOutputFileName(input_file.name);
-
-  std::ofstream potential_file_stream;
-  std::ostream* output_stream =
-      shaderc_util::GetOutputStream(output_name, &potential_file_stream);
-  if (!output_stream) {
-    // An error message has already been emitted to the stderr stream.
-    return false;
-  }
+  std::string output_file_name = GetOutputFileName(input_file.name);
   string_piece error_file_name = input_file.name;
 
   if (error_file_name == "-") {
@@ -103,8 +99,8 @@
     if (output_type_ == OutputType::SpirvBinary) {
       const auto result =
           compiler_.AssembleToSpv(source_string.data(), source_string.size());
-      return EmitCompiledResult(result, input_file.name, error_file_name,
-                                used_source_files, output_stream);
+      return EmitCompiledResult(result, input_file.name, output_file_name,
+                                error_file_name, used_source_files);
     } else {
       return true;
     }
@@ -121,23 +117,23 @@
           source_string.data(), source_string.size(), input_file.stage,
           error_file_name.data(), input_file.entry_point_name.c_str(),
           options_);
-      return EmitCompiledResult(result, input_file.name, error_file_name,
-                                used_source_files, output_stream);
+      return EmitCompiledResult(result, input_file.name, output_file_name,
+                                error_file_name, used_source_files);
     }
     case OutputType::SpirvAssemblyText: {
       const auto result = compiler_.CompileGlslToSpvAssembly(
           source_string.data(), source_string.size(), input_file.stage,
           error_file_name.data(), input_file.entry_point_name.c_str(),
           options_);
-      return EmitCompiledResult(result, input_file.name, error_file_name,
-                                used_source_files, output_stream);
+      return EmitCompiledResult(result, input_file.name, output_file_name,
+                                error_file_name, used_source_files);
     }
     case OutputType::PreprocessedText: {
       const auto result = compiler_.PreprocessGlsl(
           source_string.data(), source_string.size(), input_file.stage,
           error_file_name.data(), options_);
-      return EmitCompiledResult(result, input_file.name, error_file_name,
-                                used_source_files, output_stream);
+      return EmitCompiledResult(result, input_file.name, output_file_name,
+                                error_file_name, used_source_files);
     }
   }
   return false;
@@ -146,9 +142,8 @@
 template <typename CompilationResultType>
 bool FileCompiler::EmitCompiledResult(
     const CompilationResultType& result, const std::string& input_file,
-    string_piece error_file_name,
-    const std::unordered_set<std::string>& used_source_files,
-    std::ostream* out) {
+    const std::string& output_file_name, string_piece error_file_name,
+    const std::unordered_set<std::string>& used_source_files) {
   total_errors_ += result.GetNumErrors();
   total_warnings_ += result.GetNumWarnings();
 
@@ -207,43 +202,80 @@
     }
   }
 
-  // Write compilation output to output file. If an output format for SPIR-V
-  // binary code is specified, it is handled here.
-  switch (binary_emission_format_) {
-    case SpirvBinaryEmissionFormat::Unspecified:
-    case SpirvBinaryEmissionFormat::Binary:
-      // The output format is unspecified or specified as binary output.
-      out->write(compilation_output.data(), compilation_output.size());
-      break;
-    case SpirvBinaryEmissionFormat::Numbers:
-      // The output format is specified to be a list of hex numbers, the
-      // compilation output must be in SPIR-V binary code form.
-      assert(output_type_ == OutputType::SpirvBinary);
-      if (EmitSpirvBinaryAsCommaSeparatedNumbers(result, out)) {
-        // Only emits the end-of-line character when the emitted compilation
-        // result is not empty.
-        *out << std::endl;
+  std::ostream* out = nullptr;
+  std::ofstream potential_file_stream;
+  if (compilation_success) {
+    out = shaderc_util::GetOutputStream(output_file_name,
+                                        &potential_file_stream, &std::cerr);
+    if (!out || out->fail()) {
+      // An error message has already been emitted to the stderr stream.
+      return false;
+    }
+
+    // Write compilation output to output file. If an output format for SPIR-V
+    // binary code is specified, it is handled here.
+    switch (binary_emission_format_) {
+      case SpirvBinaryEmissionFormat::Unspecified:
+      case SpirvBinaryEmissionFormat::Binary:
+        // The output format is unspecified or specified as binary output.
+        // On Windows, the output stream must be set to binary mode.  By
+        // default the standard output stream is set to text mode, which
+        // translates newlines (\n) to carriage-return newline pairs
+        // (\r\n).
+        if (out == &std::cout) shaderc_util::FlushAndSetBinaryModeOnStdout();
+        out->write(compilation_output.data(), compilation_output.size());
+        if (out == &std::cout) shaderc_util::FlushAndSetTextModeOnStdout();
+        break;
+      case SpirvBinaryEmissionFormat::Numbers:
+        // The output format is specified to be a list of hex numbers, the
+        // compilation output must be in SPIR-V binary code form.
+        assert(output_type_ == OutputType::SpirvBinary);
+        if (EmitSpirvBinaryAsCommaSeparatedNumbers(result, out)) {
+          // Only emits the end-of-line character when the emitted compilation
+          // result is not empty.
+          *out << std::endl;
+        }
+        break;
+      case SpirvBinaryEmissionFormat::CInitList:
+        // The output format is specified to be a C-style initializer list, the
+        // compilation output must be in SPIR-V binary code form.
+        assert(output_type_ == OutputType::SpirvBinary);
+        if (result.begin() != result.end()) {
+          // Only emits the '{' when the compilation result is not empty.
+          *out << "{";
+        }
+        if (EmitSpirvBinaryAsCommaSeparatedNumbers(result, out)) {
+          // Only emits the end-of-line character when the emitted compilation
+          // result is not empty.
+          *out << "}" << std::endl;
+        }
+        break;
+      case SpirvBinaryEmissionFormat::WGSL: {
+#if SHADERC_ENABLE_WGSL_OUTPUT == 1
+        tint::Context ctx;
+        tint::reader::spirv::Parser spv_reader(
+            &ctx, std::vector<uint32_t>(result.begin(), result.end()));
+        if (!spv_reader.Parse()) {
+          std::cout << "error: failed to convert SPIR-V binary to WGSL: "
+                    << spv_reader.error() << std::endl;
+          return false;
+        }
+        tint::writer::wgsl::Generator wgsl_writer(spv_reader.module());
+        if (!wgsl_writer.Generate()) {
+          std::cout << "error: failed to convert to WGSL: "
+                    << wgsl_writer.error() << std::endl;
+          return false;
+        }
+        *out << wgsl_writer.result();
+#endif  // SHADERC_ENABLE_WGSL_OUTPUT==1
+        break;
       }
-      break;
-    case SpirvBinaryEmissionFormat::CInitList:
-      // The output format is specified to be a C-style initializer list, the
-      // compilation output must be in SPIR-V binary code form.
-      assert(output_type_ == OutputType::SpirvBinary);
-      if (result.begin() != result.end()) {
-        // Only emits the '{' when the compilation result is not empty.
-        *out << "{";
-      }
-      if (EmitSpirvBinaryAsCommaSeparatedNumbers(result, out)) {
-        // Only emits the end-of-line character when the emitted compilation
-        // result is not empty.
-        *out << "}" << std::endl;
-      }
-      break;
+    }
   }
 
   // Write error message to std::cerr.
   std::cerr << result.GetErrorMessage();
-  if (out->fail()) {
+  if (out && out->fail()) {
     // Something wrong happened on output.
     if (out == &std::cout) {
       std::cerr << "glslc: error: error writing to standard output"
@@ -336,12 +368,15 @@
         case SpirvBinaryEmissionFormat::CInitList:
           std::cerr << "C-style initializer list";
           break;
+        case SpirvBinaryEmissionFormat::WGSL:
+          std::cerr << "WGSL source program";
+          break;
         case SpirvBinaryEmissionFormat::Unspecified:
           // The compiler should never be here at runtime. This case is added to
           // complete the switch cases.
           break;
       }
-      std::cerr << " when the output is not SPIR-V binary code" << std::endl;
+      std::cerr << " when only preprocessing the source" << std::endl;
       return false;
     }
     if (dependency_info_dumping_handler_ &&
@@ -349,9 +384,19 @@
       std::cerr << "glslc: error: cannot dump dependency info when specifying "
                    "any binary output format"
                 << std::endl;
+      return false;
     }
   }
 
+  if (binary_emission_format_ == SpirvBinaryEmissionFormat::WGSL) {
+#if SHADERC_ENABLE_WGSL_OUTPUT != 1
+    std::cerr << "glslc: error: can't output WGSL: glslc was built without "
+                 "WGSL output support"
+              << std::endl;
+    return false;
+#endif
+  }
+
   return true;
 }
 
diff --git a/glslc/src/file_compiler.h b/glslc/src/file_compiler.h
index 2f45e92..cd41f73 100644
--- a/glslc/src/file_compiler.h
+++ b/glslc/src/file_compiler.h
@@ -43,8 +43,10 @@
                   // code form.
     Binary,       // Emits SPIR-V binary code directly.
     Numbers,      // Emits SPIR-V binary code as a list of hex numbers.
-    CInitList,    // Emits SPIR-V bianry code as a C-style initializer list
+    CInitList,    // Emits SPIR-V binary code as a C-style initializer list
                   // of hex numbers.
+    WGSL,         // Emits SPIR-V module converted to WGSL source text.
+                  // Requires a build with Tint support.
   };
 
   FileCompiler()
@@ -116,7 +118,7 @@
 
   // Gets the reference of the compiler options which reflects the command-line
   // arguments.
-  shaderc::CompileOptions& options() { return options_; };
+  shaderc::CompileOptions& options() { return options_; }
 
   // Gets a pointer which points to the dependency info dumping hander. Creates
   // such a handler if such one does not exist.
@@ -126,7 +128,7 @@
           new DependencyInfoDumpingHandler());
     }
     return dependency_info_dumping_handler_.get();
-  };
+  }
 
  private:
   enum class OutputType {
@@ -136,16 +138,16 @@
   };
 
   // Emits the compilation output from the given result to the given output
-  // stream and returns true if the result represents a successful compilation
-  // step.  Otherwise returns false and possibly emits messages to the standard
-  // error stream.  Accumulates error and warning counts for use by the
-  // OutputMessages() method.
+  // file and returns true if the result represents a successful compilation
+  // step.  Otherwise returns false, possibly emits messages to the standard
+  // error stream, and does not produce an output file.  Accumulates error
+  // and warning counts for use by the OutputMessages() method.
   template <typename CompilationResultType>
   bool EmitCompiledResult(
       const CompilationResultType& result, const std::string& input_file_name,
+      const std::string& output_file_name,
       shaderc_util::string_piece error_file_name,
-      const std::unordered_set<std::string>& used_source_files,
-      std::ostream* out);
+      const std::unordered_set<std::string>& used_source_files);
 
   // Returns the final file name to be used for the output file.
   //
diff --git a/glslc/src/file_includer.cc b/glslc/src/file_includer.cc
index ea42e81..448bfba 100644
--- a/glslc/src/file_includer.cc
+++ b/glslc/src/file_includer.cc
@@ -25,6 +25,8 @@
   return new shaderc_include_result{"", 0, message, strlen(message)};
 }
 
+FileIncluder::~FileIncluder() = default;
+
 shaderc_include_result* FileIncluder::GetInclude(
     const char* requested_source, shaderc_include_type include_type,
     const char* requesting_source, size_t) {
diff --git a/glslc/src/file_includer.h b/glslc/src/file_includer.h
index ae42730..5032e11 100644
--- a/glslc/src/file_includer.h
+++ b/glslc/src/file_includer.h
@@ -38,6 +38,9 @@
  public:
   explicit FileIncluder(const shaderc_util::FileFinder* file_finder)
       : file_finder_(*file_finder) {}
+
+  ~FileIncluder() override;
+
   // Resolves a requested source file of a given type from a requesting
   // source into a shaderc_include_result whose contents will remain valid
   // until it's released.
@@ -51,7 +54,7 @@
   // Returns a reference to the member storing the set of included files.
   const std::unordered_set<std::string>& file_path_trace() const {
     return included_files_;
-  };
+  }
 
  private:
   // Used by GetInclude() to get the full filepath.
diff --git a/glslc/src/main.cc b/glslc/src/main.cc
index 571e65f..2b1c03e 100644
--- a/glslc/src/main.cc
+++ b/glslc/src/main.cc
@@ -16,18 +16,25 @@
 #include <cctype>
 #include <cstdint>
 #include <cstring>
+#include <iomanip>
 #include <iostream>
 #include <list>
+#include <sstream>
 #include <string>
+#include <tuple>
 #include <utility>
 
-#include "libshaderc_util/string_piece.h"
-#include "shaderc/shaderc.h"
-#include "spirv-tools/libspirv.h"
-
 #include "file.h"
 #include "file_compiler.h"
+#include "libshaderc_util/args.h"
+#include "libshaderc_util/compiler.h"
+#include "libshaderc_util/io.h"
+#include "libshaderc_util/string_piece.h"
+#include "resource_parse.h"
 #include "shader_stage.h"
+#include "shaderc/env.h"
+#include "shaderc/shaderc.h"
+#include "spirv-tools/libspirv.h"
 
 using shaderc_util::string_piece;
 
@@ -46,38 +53,123 @@
   -Dmacro[=defn]    Add an implicit macro definition.
   -E                Outputs only the results of the preprocessing step.
                     Output defaults to standard output.
-  -fshader-stage=<stage>
-                    Treat subsequent input files as having stage <stage>.
-                    Valid stages are vertex, fragment, tesscontrol, tesseval,
-                    geometry, and compute.
+  -fauto-bind-uniforms
+                    Automatically assign bindings to uniform variables that
+                    don't have an explicit 'binding' layout in the shader
+                    source.
+  -fauto-map-locations
+                    Automatically assign locations to uniform variables that
+                    don't have an explicit 'location' layout in the shader
+                    source.
   -fentry-point=<name>
                     Specify the entry point name for HLSL compilation, for
                     all subsequent source files.  Default is "main".
+  -fhlsl_functionality1, -fhlsl-functionality1
+                    Enable extension SPV_GOOGLE_hlsl_functionality1 for HLSL
+                    compilation.
+  -finvert-y        Invert position.Y output in vertex shader.
+  -fhlsl-iomap      Use HLSL IO mappings for bindings.
+  -fhlsl-offsets    Use HLSL offset rules for packing members of blocks.
+                    Affects only GLSL.  HLSL rules are always used for HLSL.
+  -flimit=<settings>
+                    Specify resource limits. Each limit is specified by a limit
+                    name followed by an integer value.  Tokens should be
+                    separated by whitespace.  If the same limit is specified
+                    several times, only the last setting takes effect.
+  -flimit-file <file>
+                    Set limits as specified in the given file.
+  -fnan-clamp       Generate code for max and min builtins so that, when given
+                    a NaN operand, the other operand is returned. Similarly,
+                    the clamp builtin will favour the non-NaN operands, as if
+                    clamp were implemented as a composition of max and min.
+  -fresource-set-binding [stage] <reg0> <set0> <binding0>
+                        [<reg1> <set1> <binding1>...]
+                    Explicitly sets the descriptor set and binding for
+                    HLSL resources, by register name.  Optionally restrict
+                    it to a single stage.
+  -fcbuffer-binding-base [stage] <value>
+                    Same as -fubo-binding-base.
+  -fimage-binding-base [stage] <value>
+                    Sets the lowest automatically assigned binding number for
+                    images.  Optionally only set it for a single shader stage.
+                    For HLSL, the resource register number is added to this
+                    base.
+  -fsampler-binding-base [stage] <value>
+                    Sets the lowest automatically assigned binding number for
+                    samplers  Optionally only set it for a single shader stage.
+                    For HLSL, the resource register number is added to this
+                    base.
+  -fssbo-binding-base [stage] <value>
+                    Sets the lowest automatically assigned binding number for
+                    shader storage buffer objects (SSBO).  Optionally only set
+                    it for a single shader stage.  Only affects GLSL.
+  -ftexture-binding-base [stage] <value>
+                    Sets the lowest automatically assigned binding number for
+                    textures.  Optionally only set it for a single shader stage.
+                    For HLSL, the resource register number is added to this
+                    base.
+  -fuav-binding-base [stage] <value>
+                    For automatically assigned bindings for unordered access
+                    views (UAV), the register number is added to this base to
+                    determine the binding number.  Optionally only set it for
+                    a single shader stage.  Only affects HLSL.
+  -fubo-binding-base [stage] <value>
+                    Sets the lowest automatically assigned binding number for
+                    uniform buffer objects (UBO).  Optionally only set it for
+                    a single shader stage.
+                    For HLSL, the resource register number is added to this
+                    base.
+  -fshader-stage=<stage>
+                    Treat subsequent input files as having stage <stage>.
+                    Valid stages are vertex, vert, fragment, frag, tesscontrol,
+                    tesc, tesseval, tese, geometry, geom, compute, and comp.
   -g                Generate source-level debug information.
                     Currently this option has no effect.
+  -h                Display available options.
   --help            Display available options.
-  --version         Display compiler version information.
   -I <value>        Add directory to include search path.
-  -o <file>         Write output to <file>.
-                    A file name of '-' represents standard output.
-  -std=<value>      Version and profile for GLSL input files. Possible values
-                    are concatenations of version and profile, e.g. 310es,
-                    450core, etc.  Ignored for HLSL files.
   -mfmt=<format>    Output SPIR-V binary code using the selected format. This
                     option may be specified only when the compilation output is
-                    in SPIR-V binary code form. Available options include bin, c
-                    and num. By default the binary output format is bin.
+                    in SPIR-V binary code form. Available options are:
+                      bin   - SPIR-V binary words.  This is the default.
+                      c     - Binary words as C initializer list of 32-bit ints
+                      num   - List of comma-separated 32-bit hex integers
   -M                Generate make dependencies. Implies -E and -w.
   -MM               An alias for -M.
   -MD               Generate make dependencies and compile.
   -MF <file>        Write dependency output to the given file.
   -MT <target>      Specify the target of the rule emitted by dependency
                     generation.
-  -S                Only run preprocess and compilation steps.
+  -O                Optimize the generated SPIR-V code for better performance.
+  -Os               Optimize the generated SPIR-V code for smaller size.
+  -O0               Disable optimization.
+  -o <file>         Write output to <file>.
+                    A file name of '-' represents standard output.
+  -std=<value>      Version and profile for GLSL input files. Possible values
+                    are concatenations of version and profile, e.g. 310es,
+                    450core, etc.  Ignored for HLSL files.
+  -S                Emit SPIR-V assembly instead of binary.
+  --show-limits     Display available limit names and their default values.
   --target-env=<environment>
-                    Set the target shader environment, and the semantics
-                    of warnings and errors. Valid values are 'opengl',
-                    'opengl_compat' and 'vulkan'. The default value is 'vulkan'.
+                    Set the target client environment, and the semantics
+                    of warnings and errors.  An optional suffix can specify
+                    the client version.  Values are:
+                        vulkan1.0       # The default
+                        vulkan1.1
+                        vulkan1.2
+                        vulkan          # Same as vulkan1.0
+                        opengl4.5
+                        opengl          # Same as opengl4.5
+  --target-spv=<spirv-version>
+                    Set the SPIR-V version to be used for the generated SPIR-V
+                    module.  The default is the highest version of SPIR-V
+                    required to be supported for the target environment.
+                    For example, default for vulkan1.0 is spv1.0, and
+                    the default for vulkan1.1 is spv1.3,
+                    the default for vulkan1.2 is spv1.5.
+                    Values are:
+                        spv1.0, spv1.1, spv1.2, spv1.3, spv1.4, spv1.5
+  --version         Display compiler version information.
   -w                Suppresses all warning messages.
   -Werror           Treat all warnings as errors.
   -x <language>     Treat subsequent input files as having type <language>.
@@ -87,32 +179,61 @@
 )";
 }
 
-// Gets the option argument for the option at *index in argv in a way consistent
-// with clang/gcc. On success, returns true and writes the parsed argument into
-// *option_argument. Returns false if any errors occur. After calling this
-// function, *index will the index of the last command line argument consumed.
-bool GetOptionArgument(int argc, char** argv, int* index,
-                       const std::string& option,
-                       string_piece* option_argument) {
-  const string_piece arg = argv[*index];
-  assert(arg.starts_with(option));
-  if (arg.size() != option.size()) {
-    *option_argument = arg.substr(option.size());
-    return true;
-  } else {
-    if (option.back() == '=') {
-      *option_argument = "";
-      return true;
-    }
-    if (++(*index) >= argc) return false;
-    *option_argument = argv[*index];
-    return true;
+// Sets resource limits according to the given string. The string
+// should be formated as required for ParseResourceSettings.
+// Returns true on success.  Otherwise returns false and sets err
+// to a descriptive error message.
+bool SetResourceLimits(const std::string& str, shaderc::CompileOptions* options,
+                       std::string* err) {
+  std::vector<glslc::ResourceSetting> settings;
+  if (!ParseResourceSettings(str, &settings, err)) {
+    return false;
   }
+  for (const auto& setting : settings) {
+    options->SetLimit(setting.limit, setting.value);
+  }
+  return true;
 }
 
 const char kBuildVersion[] =
 #include "build-version.inc"
     ;
+
+// Gets an optional stage name followed by required offset argument.  Returns
+// false and emits a message to *errs if any errors occur.  After calling this
+// function, *index will be the index of the last command line argument
+// consumed.  If no stage name is provided, then *stage contains
+// shaderc_glsl_infer_from_source.
+bool GetOptionalStageThenOffsetArgument(const shaderc_util::string_piece option,
+                                        std::ostream* errs, int argc,
+                                        char** argv, int* index,
+                                        shaderc_shader_kind* shader_kind,
+                                        uint32_t* offset) {
+  int& argi = *index;
+  if (argi + 1 >= argc) {
+    *errs << "glslc: error: Option " << option
+          << " requires at least one argument" << std::endl;
+    return false;
+  }
+  auto stage = glslc::MapStageNameToForcedKind(argv[argi + 1]);
+  if (stage != shaderc_glsl_infer_from_source) {
+    ++argi;
+    if (argi + 1 >= argc) {
+      *errs << "glslc: error: Option " << option << " with stage "
+            << argv[argi - 1] << " requires an offset argument" << std::endl;
+      return false;
+    }
+  }
+  if (!shaderc_util::ParseUint32(argv[argi + 1], offset)) {
+    *errs << "glslc: error: invalid offset value " << argv[argi + 1] << " for "
+          << option << std::endl;
+    return false;
+  }
+  ++argi;
+  *shader_kind = stage;
+  return true;
+}
+
 }  // anonymous namespace
 
 int main(int argc, char** argv) {
@@ -125,12 +246,43 @@
   glslc::FileCompiler compiler;
   bool success = true;
   bool has_stdin_input = false;
+  // Shader stage for a single option.
+  shaderc_shader_kind arg_stage = shaderc_glsl_infer_from_source;
+  // Binding base for a single option.
+  uint32_t arg_base = 0;
+
+  // What kind of uniform variable are we setting the binding base for?
+  shaderc_uniform_kind u_kind = shaderc_uniform_kind_buffer;
+
+  // Sets binding base for the given uniform kind.  If stage is
+  // shader_glsl_infer_from_source then set it for all shader stages.
+  auto set_binding_base = [&compiler](
+      shaderc_shader_kind stage, shaderc_uniform_kind kind, uint32_t base) {
+    if (stage == shaderc_glsl_infer_from_source)
+      compiler.options().SetBindingBase(kind, base);
+    else
+      compiler.options().SetBindingBaseForStage(stage, kind, base);
+  };
 
   for (int i = 1; i < argc; ++i) {
     const string_piece arg = argv[i];
-    if (arg == "--help") {
+    if (arg == "--help" || arg == "-h") {
       ::PrintHelp(&std::cout);
       return 0;
+    } else if (arg == "--show-limits") {
+      shaderc_util::Compiler default_compiler;
+// The static cast here depends on us keeping the shaderc_limit enum in
+// lockstep with the shaderc_util::Compiler::Limit enum.  The risk of mismatch
+// is low since both are generated from the same resources.inc file.
+#define RESOURCE(NAME, FIELD, ENUM)                            \
+  std::cout << #NAME << " "                                    \
+            << default_compiler.GetLimit(                      \
+                   static_cast<shaderc_util::Compiler::Limit>( \
+                       shaderc_limit_##ENUM))                  \
+            << std::endl;
+#include "libshaderc_util/resources.inc"
+#undef RESOURCE
+      return 0;
     } else if (arg == "--version") {
       std::cout << kBuildVersion << std::endl;
       std::cout << "Target: " << spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_0)
@@ -138,7 +290,7 @@
       return 0;
     } else if (arg.starts_with("-o")) {
       string_piece file_name;
-      if (!GetOptionArgument(argc, argv, &i, "-o", &file_name)) {
+      if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-o", &file_name)) {
         std::cerr
             << "glslc: error: argument to '-o' is missing (expected 1 value)"
             << std::endl;
@@ -153,9 +305,108 @@
                   << std::endl;
         return 1;
       }
+    } else if (arg == "-fauto-bind-uniforms") {
+      compiler.options().SetAutoBindUniforms(true);
+    } else if (arg == "-fauto-map-locations") {
+      compiler.options().SetAutoMapLocations(true);
+    } else if (arg == "-fhlsl-iomap") {
+      compiler.options().SetHlslIoMapping(true);
+    } else if (arg == "-fhlsl-offsets") {
+      compiler.options().SetHlslOffsets(true);
+    } else if (arg == "-fhlsl_functionality1" ||
+               arg == "-fhlsl-functionality1") {
+      compiler.options().SetHlslFunctionality1(true);
+    } else if (arg == "-finvert-y") {
+      compiler.options().SetInvertY(true);
+    } else if (arg == "-fnan-clamp") {
+      compiler.options().SetNanClamp(true);
+    } else if (((u_kind = shaderc_uniform_kind_image),
+                (arg == "-fimage-binding-base")) ||
+               ((u_kind = shaderc_uniform_kind_texture),
+                (arg == "-ftexture-binding-base")) ||
+               ((u_kind = shaderc_uniform_kind_sampler),
+                (arg == "-fsampler-binding-base")) ||
+               ((u_kind = shaderc_uniform_kind_buffer),
+                (arg == "-fubo-binding-base")) ||
+               ((u_kind = shaderc_uniform_kind_buffer),
+                (arg == "-fcbuffer-binding-base")) ||
+               ((u_kind = shaderc_uniform_kind_storage_buffer),
+                (arg == "-fssbo-binding-base")) ||
+               ((u_kind = shaderc_uniform_kind_unordered_access_view),
+                (arg == "-fuav-binding-base"))) {
+      if (!GetOptionalStageThenOffsetArgument(arg, &std::cerr, argc, argv, &i,
+                                              &arg_stage, &arg_base))
+        return 1;
+      set_binding_base(arg_stage, u_kind, arg_base);
+    } else if (arg == "-fresource-set-binding") {
+      auto need_three_args_err = []() {
+        std::cerr << "glsc: error: Option -fresource-set-binding"
+                  << " requires at least 3 arguments" << std::endl;
+        return 1;
+      };
+      if (i + 1 >= argc) return need_three_args_err();
+      auto stage = glslc::MapStageNameToForcedKind(argv[i + 1]);
+      if (stage != shaderc_glsl_infer_from_source) {
+        ++i;
+      }
+      bool seen_triple = false;
+      while (i + 3 < argc && argv[i + 1][0] != '-' && argv[i + 2][0] != '-' &&
+             argv[i + 3][0] != '-') {
+        seen_triple = true;
+        uint32_t set = 0;
+        if (!shaderc_util::ParseUint32(argv[i + 2], &set)) {
+          std::cerr << "glslc: error: Invalid set number: " << argv[i + 2]
+                    << std::endl;
+          return 1;
+        }
+        uint32_t binding = 0;
+        if (!shaderc_util::ParseUint32(argv[i + 3], &binding)) {
+          std::cerr << "glslc: error: Invalid binding number: " << argv[i + 3]
+                    << std::endl;
+          return 1;
+        }
+        if (stage == shaderc_glsl_infer_from_source) {
+          compiler.options().SetHlslRegisterSetAndBinding(
+              argv[i + 1], argv[i + 2], argv[i + 3]);
+        } else {
+          compiler.options().SetHlslRegisterSetAndBindingForStage(
+              stage, argv[i + 1], argv[i + 2], argv[i + 3]);
+        }
+        i += 3;
+      }
+      if (!seen_triple) return need_three_args_err();
     } else if (arg.starts_with("-fentry-point=")) {
       current_entry_point_name =
           arg.substr(std::strlen("-fentry-point=")).str();
+    } else if (arg.starts_with("-flimit=")) {
+      std::string err;
+      if (!SetResourceLimits(arg.substr(std::strlen("-flimit=")).str(),
+                             &compiler.options(), &err)) {
+        std::cerr << "glslc: error: -flimit error: " << err << std::endl;
+        return 1;
+      }
+    } else if (arg.starts_with("-flimit-file")) {
+      std::string err;
+      string_piece limits_file;
+      if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-flimit-file",
+                                           &limits_file)) {
+        std::cerr << "glslc: error: argument to '-flimit-file' is missing"
+                  << std::endl;
+        return 1;
+      }
+      std::vector<char> contents;
+      if (!shaderc_util::ReadFile(limits_file.str(), &contents)) {
+        std::cerr << "glslc: cannot read limits file: " << limits_file
+                  << std::endl;
+        return 1;
+      }
+      if (!SetResourceLimits(
+              string_piece(contents.data(), contents.data() + contents.size())
+                  .str(),
+              &compiler.options(), &err)) {
+        std::cerr << "glslc: error: -flimit-file error: " << err << std::endl;
+        return 1;
+      }
     } else if (arg.starts_with("-std=")) {
       const string_piece standard = arg.substr(std::strlen("-std="));
       int version;
@@ -171,10 +422,23 @@
       shaderc_target_env target_env = shaderc_target_env_default;
       const string_piece target_env_str =
           arg.substr(std::strlen("--target-env="));
+      uint32_t version = 0;  // Will default appropriately.
       if (target_env_str == "vulkan") {
         target_env = shaderc_target_env_vulkan;
+      } else if (target_env_str == "vulkan1.0") {
+        target_env = shaderc_target_env_vulkan;
+        version = shaderc_env_version_vulkan_1_0;
+      } else if (target_env_str == "vulkan1.1") {
+        target_env = shaderc_target_env_vulkan;
+        version = shaderc_env_version_vulkan_1_1;
+      } else if (target_env_str == "vulkan1.2") {
+        target_env = shaderc_target_env_vulkan;
+        version = shaderc_env_version_vulkan_1_2;
       } else if (target_env_str == "opengl") {
         target_env = shaderc_target_env_opengl;
+      } else if (target_env_str == "opengl4.5") {
+        target_env = shaderc_target_env_opengl;
+        version = shaderc_env_version_opengl_4_5;
       } else if (target_env_str == "opengl_compat") {
         target_env = shaderc_target_env_opengl_compat;
       } else {
@@ -183,7 +447,28 @@
                   << std::endl;
         return 1;
       }
-      compiler.options().SetTargetEnvironment(target_env, 0);
+      compiler.options().SetTargetEnvironment(target_env, version);
+    } else if (arg.starts_with("--target-spv=")) {
+      shaderc_spirv_version ver = shaderc_spirv_version_1_0;
+      const string_piece ver_str = arg.substr(std::strlen("--target-spv="));
+      if (ver_str == "spv1.0") {
+        ver = shaderc_spirv_version_1_0;
+      } else if (ver_str == "spv1.1") {
+        ver = shaderc_spirv_version_1_1;
+      } else if (ver_str == "spv1.2") {
+        ver = shaderc_spirv_version_1_2;
+      } else if (ver_str == "spv1.3") {
+        ver = shaderc_spirv_version_1_3;
+      } else if (ver_str == "spv1.4") {
+        ver = shaderc_spirv_version_1_4;
+      } else if (ver_str == "spv1.5") {
+        ver = shaderc_spirv_version_1_5;
+      } else {
+        std::cerr << "glslc: error: invalid value '" << ver_str
+                  << "' in '--target-spv=" << ver_str << "'" << std::endl;
+        return 1;
+      }
+      compiler.options().SetTargetSpirv(ver);
     } else if (arg.starts_with("-mfmt=")) {
       const string_piece binary_output_format =
           arg.substr(std::strlen("-mfmt="));
@@ -196,6 +481,9 @@
       } else if (binary_output_format == "c") {
         compiler.SetSpirvBinaryOutputFormat(
             glslc::FileCompiler::SpirvBinaryEmissionFormat::CInitList);
+      } else if (binary_output_format == "wgsl") {
+        compiler.SetSpirvBinaryOutputFormat(
+            glslc::FileCompiler::SpirvBinaryEmissionFormat::WGSL);
       } else {
         std::cerr << "glslc: error: invalid value '" << binary_output_format
                   << "' in '-mfmt=" << binary_output_format << "'" << std::endl;
@@ -203,7 +491,7 @@
       }
     } else if (arg.starts_with("-x")) {
       string_piece option_arg;
-      if (!GetOptionArgument(argc, argv, &i, "-x", &option_arg)) {
+      if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-x", &option_arg)) {
         std::cerr
             << "glslc: error: argument to '-x' is missing (expected 1 value)"
             << std::endl;
@@ -249,7 +537,8 @@
       }
     } else if (arg == "-MF") {
       string_piece dep_file_name;
-      if (!GetOptionArgument(argc, argv, &i, "-MF", &dep_file_name)) {
+      if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-MF",
+                                           &dep_file_name)) {
         std::cerr
             << "glslc: error: missing dependency info filename after '-MF'"
             << std::endl;
@@ -259,7 +548,8 @@
           std::string(dep_file_name.data(), dep_file_name.size()));
     } else if (arg == "-MT") {
       string_piece dep_file_name;
-      if (!GetOptionArgument(argc, argv, &i, "-MT", &dep_file_name)) {
+      if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-MT",
+                                           &dep_file_name)) {
         std::cerr << "glslc: error: missing dependency info target after '-MT'"
                   << std::endl;
         return 1;
@@ -305,7 +595,7 @@
       }
     } else if (arg.starts_with("-I")) {
       string_piece option_arg;
-      if (!GetOptionArgument(argc, argv, &i, "-I", &option_arg)) {
+      if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-I", &option_arg)) {
         std::cerr
             << "glslc: error: argument to '-I' is missing (expected 1 value)"
             << std::endl;
@@ -316,7 +606,10 @@
     } else if (arg == "-g") {
       compiler.options().SetGenerateDebugInfo();
     } else if (arg.starts_with("-O")) {
-      if (arg == "-Os") {
+      if (arg == "-O") {
+        compiler.options().SetOptimizationLevel(
+            shaderc_optimization_level_performance);
+      } else if (arg == "-Os") {
         compiler.options().SetOptimizationLevel(
             shaderc_optimization_level_size);
       } else if (arg == "-O0") {
diff --git a/glslc/src/resource_parse.cc b/glslc/src/resource_parse.cc
new file mode 100644
index 0000000..7109333
--- /dev/null
+++ b/glslc/src/resource_parse.cc
@@ -0,0 +1,97 @@
+// Copyright 2016 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "resource_parse.h"
+
+#include <algorithm>
+#include <cstring>
+#include <iterator>
+#include <sstream>
+#include <vector>
+
+namespace {
+
+// Converts a limit string to a limit enum.  Returns true on successful
+// conversion.
+bool StringToLimit(const std::string& str, shaderc_limit* limit) {
+  const char* cstr = str.c_str();
+#define RESOURCE(NAME, FIELD, ENUM)    \
+  if (0 == std::strcmp(#NAME, cstr)) { \
+    *limit = shaderc_limit_##ENUM;     \
+    return true;                       \
+  }
+#include "libshaderc_util/resources.inc"
+#undef RESOURCE
+  return false;
+}
+
+// Returns true if we should ignore the setting.
+bool IgnoreSetting(const std::string& str) {
+  const std::string ignore_list[] = {
+      "nonInductiveForLoops",
+      "whileLoops",
+      "doWhileLoops",
+      "generalUniformIndexing",
+      "generalAttributeMatrixVectorIndexing",
+      "generalVaryingIndexing",
+      "generalSamplerIndexing",
+      "generalVariableIndexing",
+      "generalConstantMatrixVectorIndexing",
+  };
+  return std::find(std::begin(ignore_list), std::end(ignore_list), str) !=
+         std::end(ignore_list);
+}
+
+}  //  anonymous namespace
+
+namespace glslc {
+
+bool ParseResourceSettings(const std::string& input,
+                           std::vector<ResourceSetting>* limits,
+                           std::string* err) {
+  auto failure = [err, limits](std::string msg) {
+    *err = msg;
+    limits->clear();
+    return false;
+  };
+  std::istringstream input_stream(input);
+  std::istream_iterator<std::string> pos((input_stream));
+  limits->clear();
+
+  while (pos != std::istream_iterator<std::string>()) {
+    const std::string limit_name = *pos++;
+    shaderc_limit limit = static_cast<shaderc_limit>(0);
+    bool ignore = IgnoreSetting(limit_name);
+    if (!ignore) {
+      if (!StringToLimit(limit_name, &limit))
+        return failure(std::string("invalid resource limit: " + limit_name));
+    }
+
+    if (pos == std::istream_iterator<std::string>())
+      return failure(std::string("missing value after limit: ") + limit_name);
+
+    const std::string value_str = *pos;
+    int value;
+    std::istringstream value_stream(value_str);
+    value_stream >> value;
+    if (value_stream.bad() || !value_stream.eof() || value_stream.fail())
+      return failure(std::string("invalid integer: ") + value_str);
+
+    if (!ignore) limits->push_back({limit, value});
+    ++pos;
+  }
+
+  return true;
+}
+}  // anonymous namespace
diff --git a/glslc/src/resource_parse.h b/glslc/src/resource_parse.h
new file mode 100644
index 0000000..9794ce4
--- /dev/null
+++ b/glslc/src/resource_parse.h
@@ -0,0 +1,60 @@
+// Copyright 2016 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef GLSLC_RESOURCE_PARSE_H
+#define GLSLC_RESOURCE_PARSE_H
+
+#include <string>
+#include <vector>
+
+#include "shaderc/shaderc.h"
+
+namespace glslc {
+
+// A resource limit setting.
+struct ResourceSetting {
+  shaderc_limit limit;
+  int value;
+};
+
+
+// Returns true when two resource setting structures are equal.
+inline bool operator==(const ResourceSetting& lhs, const ResourceSetting& rhs) {
+  return (lhs.limit == rhs.limit) && (lhs.value == rhs.value);
+}
+
+
+// Parses a resource limit setting string.  On success, returns true and populates
+// the limits parameter.  On failure returns failure and emits a message to err.
+// The setting string should be a seqeuence of pairs, where each pair
+// is a limit name followed by a decimal integer.  Tokens should be separated
+// by whitespace.  In particular, this function accepts Glslang's configuration
+// file syntax.  If a limit is mentioned multiple times, then the last setting
+// takes effect.  Ignore settings for:
+//   nonInductiveForLoops
+//   whileLoops
+//   doWhileLoops
+//   generalUniformIndexing
+//   generalAttributeMatrixVectorIndexing
+//   generalVaryingIndexing
+//   generalSamplerIndexing
+//   generalVariableIndexing
+//   generalConstantMatrixVectorIndexing
+bool ParseResourceSettings(const std::string& input,
+                           std::vector<ResourceSetting>* limits,
+                           std::string* err);
+}  // namespace glslc
+
+
+#endif  // GLSLC_FILE_H_
diff --git a/glslc/src/resource_parse_test.cc b/glslc/src/resource_parse_test.cc
new file mode 100644
index 0000000..4714106
--- /dev/null
+++ b/glslc/src/resource_parse_test.cc
@@ -0,0 +1,75 @@
+// Copyright 2017 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "resource_parse.h"
+
+#include <gmock/gmock.h>
+
+namespace {
+
+using glslc::ParseResourceSettings;
+using glslc::ResourceSetting;
+using testing::Eq;
+
+struct ResourceSettingsCase {
+  std::string input;
+  bool success;
+  std::vector<ResourceSetting> settings;
+  std::string message;
+};
+
+using ParseResourceSettingsTest = ::testing::TestWithParam<ResourceSettingsCase>;
+
+TEST_P(ParseResourceSettingsTest, Sample) {
+  std::vector<ResourceSetting> settings;
+  std::string err;
+  const bool succeeded = ParseResourceSettings(GetParam().input, &settings, &err);
+  EXPECT_THAT(succeeded, Eq(GetParam().success));
+  EXPECT_THAT(settings, Eq(GetParam().settings));
+  EXPECT_THAT(err, Eq(GetParam().message));
+}
+
+INSTANTIATE_TEST_SUITE_P(ParseResources, ParseResourceSettingsTest,
+  ::testing::ValuesIn(std::vector<ResourceSettingsCase>{
+    {"", true, {}, ""},
+    {"   \t \t \n ", true, {}, ""},
+    {" blorp blam", false, {}, "invalid resource limit: blorp"},
+    {"MaxLightsxyz", false, {}, "invalid resource limit: MaxLightsxyz"},
+    {"MaxLights", false, {}, "missing value after limit: MaxLights"},
+    {"MaxLights x", false, {}, "invalid integer: x"},
+    {"MaxLights 99x", false, {}, "invalid integer: 99x"},
+    {"MaxLights 12 blam", false, {}, "invalid resource limit: blam"},
+    {"MaxLights 12", true, {{shaderc_limit_max_lights, 12}}, ""},
+    // Test negative number
+    {"MinProgramTexelOffset -9", true, {{shaderc_limit_min_program_texel_offset, -9}}, ""},
+    // Test leading, intervening, and trailing whitespace
+    {" \tMaxLights \n 12 \t ", true, {{shaderc_limit_max_lights, 12}}, ""},
+    // Test more than one limit setting.
+    {"MinProgramTexelOffset -10 MaxLights 4", true, {{shaderc_limit_min_program_texel_offset, -10}, {shaderc_limit_max_lights, 4}}, ""},
+    // Check ignore cases.
+    {"nonInductiveForLoops", false, {}, "missing value after limit: nonInductiveForLoops"},
+    {"nonInductiveForLoops 1", true, {}, ""},
+    {"whileLoops 1", true, {}, ""},
+    {"doWhileLoops 1", true, {}, ""},
+    {"generalUniformIndexing 1", true, {}, ""},
+    {"generalAttributeMatrixVectorIndexing 1", true, {}, ""},
+    {"generalVaryingIndexing 1", true, {}, ""},
+    {"generalSamplerIndexing 1", true, {}, ""},
+    {"generalVariableIndexing 1", true, {}, ""},
+    {"generalConstantMatrixVectorIndexing 1", true, {}, ""},
+    // Check an ignore case with a regular case
+    {"whileLoops 1 MaxLights 99", true, {{shaderc_limit_max_lights, 99}}, ""},
+  }));
+
+}  // anonymous namespace
diff --git a/glslc/src/shader_stage.cc b/glslc/src/shader_stage.cc
index f6b227d..23f15b1 100644
--- a/glslc/src/shader_stage.cc
+++ b/glslc/src/shader_stage.cc
@@ -33,11 +33,26 @@
 shaderc_shader_kind MapStageNameToForcedKind(const string_piece& stage_name) {
   const StageMapping string_to_kind[] = {
       {"vertex", shaderc_glsl_vertex_shader},
+      {"vert", shaderc_glsl_vertex_shader},
       {"fragment", shaderc_glsl_fragment_shader},
+      {"frag", shaderc_glsl_fragment_shader},
       {"tesscontrol", shaderc_glsl_tess_control_shader},
+      {"tesc", shaderc_glsl_tess_control_shader},
       {"tesseval", shaderc_glsl_tess_evaluation_shader},
+      {"tese", shaderc_glsl_tess_evaluation_shader},
       {"geometry", shaderc_glsl_geometry_shader},
-      {"compute", shaderc_glsl_compute_shader}};
+      {"geom", shaderc_glsl_geometry_shader},
+      {"compute", shaderc_glsl_compute_shader},
+      {"comp", shaderc_glsl_compute_shader},
+      {"rgen", shaderc_glsl_raygen_shader },
+      {"rahit", shaderc_glsl_anyhit_shader },
+      {"rchit", shaderc_glsl_closesthit_shader },
+      {"rmiss", shaderc_glsl_miss_shader },
+      {"rint", shaderc_glsl_intersection_shader },
+      {"rcall", shaderc_glsl_callable_shader },
+      {"task", shaderc_glsl_task_shader },
+      {"mesh", shaderc_glsl_mesh_shader },
+  };
   for (const auto& entry : string_to_kind) {
     if (stage_name == entry.id) return entry.stage;
   }
@@ -62,6 +77,14 @@
       {"geom", shaderc_glsl_default_geometry_shader},
       {"comp", shaderc_glsl_default_compute_shader},
       {"spvasm", shaderc_spirv_assembly},
+      {"rgen", shaderc_glsl_default_raygen_shader },
+      {"rahit", shaderc_glsl_default_anyhit_shader },
+      {"rchit", shaderc_glsl_default_closesthit_shader },
+      {"rmiss", shaderc_glsl_default_miss_shader },
+      {"rint", shaderc_glsl_default_intersection_shader },
+      {"rcall", shaderc_glsl_default_callable_shader },
+      {"task", shaderc_glsl_default_task_shader },
+      {"mesh", shaderc_glsl_default_mesh_shader },
   };
 
   const string_piece extension = glslc::GetFileExtension(file_name);
diff --git a/glslc/src/shader_stage.h b/glslc/src/shader_stage.h
index 4900c6f..8e4ffde 100644
--- a/glslc/src/shader_stage.h
+++ b/glslc/src/shader_stage.h
@@ -22,10 +22,15 @@
 
 namespace glslc {
 
+// Maps a shader stage name to a forced shader stage enum value.  Returns
+// 'shaderc_glsl_infer_from_source' if the stage name is unrecognized.
+shaderc_shader_kind MapStageNameToForcedKind(
+    const shaderc_util::string_piece& f_shader_stage_str);
+
 // Parse the string piece from command line to get the force shader stage.
 // If the 'f_shader_stage_str' cannot be parsed to a valid force shader stage,
-// returns 'shaderc_glsl_infer_from_source' and an error should be emitted at
-// the caller site.
+// returns 'shaderc_glsl_infer_from_source'.  Requires the string to begin with
+// '='.
 shaderc_shader_kind GetForcedShaderKindFromCmdLine(
     const shaderc_util::string_piece& f_shader_stage_str);
 
diff --git a/glslc/src/stage_test.cc b/glslc/src/stage_test.cc
index 9b1c254..3177673 100644
--- a/glslc/src/stage_test.cc
+++ b/glslc/src/stage_test.cc
@@ -48,6 +48,30 @@
 
   EXPECT_EQ(shaderc_glsl_default_compute_shader,
             glslc::DeduceDefaultShaderKindFromFileName("a.comp"));
+
+  EXPECT_EQ(shaderc_glsl_default_raygen_shader,
+            glslc::DeduceDefaultShaderKindFromFileName("a.rgen"));
+
+  EXPECT_EQ(shaderc_glsl_default_anyhit_shader,
+            glslc::DeduceDefaultShaderKindFromFileName("a.rahit"));
+
+  EXPECT_EQ(shaderc_glsl_default_closesthit_shader,
+            glslc::DeduceDefaultShaderKindFromFileName("a.rchit"));
+
+  EXPECT_EQ(shaderc_glsl_default_miss_shader,
+            glslc::DeduceDefaultShaderKindFromFileName("a.rmiss"));
+
+  EXPECT_EQ(shaderc_glsl_default_intersection_shader,
+            glslc::DeduceDefaultShaderKindFromFileName("a.rint"));
+
+  EXPECT_EQ(shaderc_glsl_default_callable_shader,
+            glslc::DeduceDefaultShaderKindFromFileName("a.rcall"));
+
+  EXPECT_EQ(shaderc_glsl_default_task_shader,
+            glslc::DeduceDefaultShaderKindFromFileName("a.task"));
+
+  EXPECT_EQ(shaderc_glsl_default_mesh_shader,
+            glslc::DeduceDefaultShaderKindFromFileName("a.mesh"));
 }
 
 TEST(DeduceDefaultShaderKindFromFileName, InvalidStage) {
diff --git a/glslc/test/CMakeLists.txt b/glslc/test/CMakeLists.txt
index cca9314..ac001bd 100644
--- a/glslc/test/CMakeLists.txt
+++ b/glslc/test/CMakeLists.txt
@@ -1,9 +1,27 @@
-shaderc_add_nosetests(expect)
-shaderc_add_nosetests(glslc_test_framework)
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test(NAME shaderc_expect_unittests
+         COMMAND ${PYTHON_EXECUTABLE} -m unittest expect_unittest.py
+         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+add_test(NAME shaderc_glslc_test_framework_unittests
+         COMMAND ${PYTHON_EXECUTABLE} -m unittest glslc_test_framework_unittest.py
+         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 
 if(${SHADERC_ENABLE_TESTS})
   add_test(NAME glslc_tests
-    COMMAND ${PYTHON_EXE}
+    COMMAND ${PYTHON_EXECUTABLE}
     ${CMAKE_CURRENT_SOURCE_DIR}/glslc_test_framework.py
     $<TARGET_FILE:glslc_exe> $<TARGET_FILE:spirv-dis>
     --test-dir ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/glslc/test/assembly.py b/glslc/test/assembly.py
index 2a0e47f..30fdba4 100644
--- a/glslc/test/assembly.py
+++ b/glslc/test/assembly.py
@@ -21,7 +21,7 @@
     return """
     ; SPIR-V
     ; Version: 1.0
-    ; Generator: Khronos Glslang Reference Front End; 1
+    ; Generator: Google Shaderc over Glslang; 10
     ; Bound: 6
     ; Schema: 0"""
 
@@ -126,8 +126,10 @@
     expected_error = [
         shader, ": error: #version: Desktop shaders for Vulkan SPIR-V require "
         "version 140 or higher\n",
-        shader, ":2: error: '' :  syntax error\n",
-        '2 errors generated.\n']
+        shader, ":2: error: 'extraneous semicolon' :",
+        " not supported for this version or the enabled extensions\n",
+        shader, ":2: error: '' :  syntax error, unexpected IDENTIFIER\n",
+        '3 errors generated.\n']
 
 
 @inside_glslc_testsuite('SpirvAssembly')
diff --git a/glslc/test/error_no_object.py b/glslc/test/error_no_object.py
new file mode 100644
index 0000000..b55ebfd
--- /dev/null
+++ b/glslc/test/error_no_object.py
@@ -0,0 +1,59 @@
+# Copyright 2017 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import expect
+import os.path
+from glslc_test_framework import inside_glslc_testsuite
+from placeholder import FileShader
+
+
+@inside_glslc_testsuite('ErrorNoObject')
+class ErrorGeneratesNoObjectFile(expect.NoObjectFile,
+                                 expect.NoOutputOnStdout,
+                                 expect.ErrorMessageSubstr):
+    """Tests that on error, no object file is generated."""
+
+    shader = FileShader('#version 150\nBad', '.frag')
+    glslc_args = ['-c', shader]
+    expected_error_substr = ['syntax error']
+
+
+@inside_glslc_testsuite('ErrorNoObject')
+class FailureToMakeOutputFileIsErrorWithNoOutputFile(
+         expect.NoNamedOutputFiles,
+         expect.NoOutputOnStdout,
+         expect.ErrorMessageSubstr):
+    """Tests that if we fail to make an output file, no file is generated,
+    and we have certain error messages."""
+
+    shader = FileShader('#version 150\nvoid main() {}', '.frag')
+    bad_file = '/file/should/not/exist/today'
+    glslc_args = ['-c', shader, '-o', bad_file]
+    expected_output_filenames = [bad_file]
+    expected_error_substr = ['cannot open output file']
+
+
+@inside_glslc_testsuite('ErrorNoObject')
+class FailureToMakeOutputFileAsCurrentDirIsErrorWithNoOutputFile(
+         expect.NoNamedOutputFiles,
+         expect.NoOutputOnStdout,
+         expect.ErrorMessageSubstr):
+    """Tests that if we fail to make an output file because it is the current
+    directory, then no file is generated, and we have certain error messages."""
+
+    shader = FileShader('#version 150\nvoid main() {}', '.frag')
+    bad_file = '.'  # Current directory
+    glslc_args = ['-c', shader, '-o', bad_file]
+    expected_output_filenames = [bad_file]
+    expected_error_substr = ['cannot open output file']
diff --git a/glslc/test/expect.py b/glslc/test/expect.py
index cfd0524..7410f73 100644
--- a/glslc/test/expect.py
+++ b/glslc/test/expect.py
@@ -19,10 +19,33 @@
 methods in the mixin classes.
 """
 import difflib
+import functools
 import os
 import re
 import subprocess
+import sys
 from glslc_test_framework import GlslCTest
+from builtins import bytes
+
+GLSLANG_GENERATOR_VERSION=10
+SHADERC_GENERATOR_NUMBER=13
+SHADERC_GENERATOR_WORD=(SHADERC_GENERATOR_NUMBER << 16) + GLSLANG_GENERATOR_VERSION
+ASSEMBLER_GENERATOR_WORD=(7<<16)
+
+def convert_to_string(input):
+    if type(input) is not str:
+        if sys.version_info[0] == 2:
+            return input.decode('utf-8')
+        elif sys.version_info[0] == 3:
+            return str(input,
+                              encoding='utf-8',
+                              errors='ignore') if input is not None else input
+        else:
+            raise Exception(
+                'Unable to determine if running Python 2 or 3 from {}'.format(
+                    sys.version_info))
+    else:
+        return input
 
 
 def convert_to_unix_line_endings(source):
@@ -113,21 +136,30 @@
             return False, 'Extra files generated: {}'.format(generated_files)
 
 
-class CorrectObjectFilePreamble(GlslCTest):
-    """Provides methods for verifying preamble for a SPV object file."""
+class CorrectBinaryLengthAndPreamble(GlslCTest):
+    """Provides methods for verifying preamble for a SPIR-V binary."""
 
-    def verify_object_file_preamble(self, filename):
-        """Checks that the given SPIR-V binary file has correct preamble."""
+    def verify_binary_length_and_header(self, binary, spv_version = 0x10000):
+        """Checks that the given SPIR-V binary has valid length and header.
+
+        Returns:
+            False, error string if anything is invalid
+            True, '' otherwise
+        Args:
+            binary: a bytes object containing the SPIR-V binary
+            spv_version: target SPIR-V version number, with same encoding
+                 as the version word in a SPIR-V header.
+        """
 
         def read_word(binary, index, little_endian):
             """Reads the index-th word from the given binary file."""
             word = binary[index * 4:(index + 1) * 4]
             if little_endian:
                 word = reversed(word)
-            return reduce(lambda w, b: (w << 8) | ord(b), word, 0)
+            return functools.reduce(lambda w, b: (w << 8) | b, word, 0)
 
         def check_endianness(binary):
-            """Checks the endianness of the given SPIR-V binary file.
+            """Checks the endianness of the given SPIR-V binary.
 
             Returns:
               True if it's little endian, False if it's big endian.
@@ -141,6 +173,45 @@
                 return False
             return None
 
+        num_bytes = len(binary)
+        if num_bytes % 4 != 0:
+            return False, ('Incorrect SPV binary: size should be a multiple'
+                           ' of words')
+        if num_bytes < 20:
+            return False, 'Incorrect SPV binary: size less than 5 words'
+
+        preamble = binary[0:19]
+        little_endian = check_endianness(preamble)
+        # SPIR-V module magic number
+        if little_endian is None:
+            return False, 'Incorrect SPV binary: wrong magic number'
+
+        # SPIR-V version number
+        version = read_word(preamble, 1, little_endian)
+        # TODO(dneto): Recent Glslang uses version word 0 for opengl_compat
+        # profile
+
+        if version != spv_version and version != 0:
+            return False, 'Incorrect SPV binary: wrong version number'
+        # Shaderc-over-Glslang (0x000d....) or
+        # SPIRV-Tools (0x0007....) generator number
+        if read_word(preamble, 2, little_endian) != SHADERC_GENERATOR_WORD and \
+                read_word(preamble, 2, little_endian) != ASSEMBLER_GENERATOR_WORD:
+            return False, ('Incorrect SPV binary: wrong generator magic '
+                           'number')
+        # reserved for instruction schema
+        if read_word(preamble, 4, little_endian) != 0:
+            return False, 'Incorrect SPV binary: the 5th byte should be 0'
+
+        return True, ''
+
+
+class CorrectObjectFilePreamble(CorrectBinaryLengthAndPreamble):
+    """Provides methods for verifying preamble for a SPV object file."""
+
+    def verify_object_file_preamble(self, filename, spv_version = 0x10000):
+        """Checks that the given SPIR-V binary file has correct preamble."""
+
         success, message = verify_file_non_empty(filename)
         if not success:
             return False, message
@@ -148,31 +219,11 @@
         with open(filename, 'rb') as object_file:
             object_file.seek(0, os.SEEK_END)
             num_bytes = object_file.tell()
-            if num_bytes % 4 != 0:
-                return False, ('Incorrect SPV binary: size should be a multiple'
-                               ' of words')
-            if num_bytes < 20:
-                return False, 'Incorrect SPV binary: size less than 5 words'
 
             object_file.seek(0)
-            preamble = bytes(object_file.read(20))
 
-            little_endian = check_endianness(preamble)
-            # SPIR-V module magic number
-            if little_endian is None:
-                return False, 'Incorrect SPV binary: wrong magic number'
-
-            # SPIR-V version number
-            if read_word(preamble, 1, little_endian) != 0x00010000:
-                return False, 'Incorrect SPV binary: wrong version number'
-            # glslang (0x0008....) or SPIRV-Tools (0x0007....) generator number
-            if read_word(preamble, 2, little_endian) != 0x00080001 and \
-                    read_word(preamble, 2, little_endian) != 0x00070000:
-                return False, ('Incorrect SPV binary: wrong generator magic '
-                               'number')
-            # reserved for instruction schema
-            if read_word(preamble, 4, little_endian) != 0:
-                return False, 'Incorrect SPV binary: the 5th byte should be 0'
+            binary = bytes(object_file.read())
+            return self.verify_binary_length_and_header(binary, spv_version)
 
         return True, ''
 
@@ -192,15 +243,15 @@
 
         if (line1 != '; SPIR-V\n' or
             line2 != '; Version: 1.0\n' or
-            line3 != '; Generator: Khronos Glslang Reference Front End; 1\n'):
+            (not line3.startswith('; Generator: Google Shaderc over Glslang;'))):
             return False, 'Incorrect SPV assembly'
 
         return True, ''
 
 
 class ValidObjectFile(SuccessfulReturn, CorrectObjectFilePreamble):
-    """Mixin class for checking that every input file generates a valid object
-    file following the object file naming rule, and there is no output on
+    """Mixin class for checking that every input file generates a valid SPIR-V 1.0
+    object file following the object file naming rule, and there is no output on
     stdout/stderr."""
 
     def check_object_file_preamble(self, status):
@@ -213,6 +264,54 @@
         return True, ''
 
 
+class ValidObjectFile1_3(SuccessfulReturn, CorrectObjectFilePreamble):
+    """Mixin class for checking that every input file generates a valid SPIR-V 1.3
+    object file following the object file naming rule, and there is no output on
+    stdout/stderr."""
+
+    def check_object_file_preamble(self, status):
+        for input_filename in status.input_filenames:
+            object_filename = get_object_filename(input_filename)
+            success, message = self.verify_object_file_preamble(
+                os.path.join(status.directory, object_filename),
+                0x10300)
+            if not success:
+                return False, message
+        return True, ''
+
+
+class ValidObjectFile1_4(SuccessfulReturn, CorrectObjectFilePreamble):
+    """Mixin class for checking that every input file generates a valid SPIR-V 1.4
+    object file following the object file naming rule, and there is no output on
+    stdout/stderr."""
+
+    def check_object_file_preamble(self, status):
+        for input_filename in status.input_filenames:
+            object_filename = get_object_filename(input_filename)
+            success, message = self.verify_object_file_preamble(
+                os.path.join(status.directory, object_filename),
+                0x10400)
+            if not success:
+                return False, message
+        return True, ''
+
+
+class ValidObjectFile1_5(SuccessfulReturn, CorrectObjectFilePreamble):
+    """Mixin class for checking that every input file generates a valid SPIR-V 1.5
+    object file following the object file naming rule, and there is no output on
+    stdout/stderr."""
+
+    def check_object_file_preamble(self, status):
+        for input_filename in status.input_filenames:
+            object_filename = get_object_filename(input_filename)
+            success, message = self.verify_object_file_preamble(
+                os.path.join(status.directory, object_filename),
+                0x10500)
+            if not success:
+                return False, message
+        return True, ''
+
+
 class ValidObjectFileWithAssemblySubstr(SuccessfulReturn, CorrectObjectFilePreamble):
     """Mixin class for checking that every input file generates a valid object
     file following the object file naming rule, there is no output on
@@ -233,7 +332,7 @@
             disassembly = output[0]
             if not isinstance(an_input.assembly_substr, str):
                 return False, "Missing assembly_substr member"
-            if an_input.assembly_substr not in disassembly:
+            if bytes(an_input.assembly_substr, 'utf-8') not in disassembly:
                 return False, ('Incorrect disassembly output:\n{asm}\n'
                     'Expected substring not found:\n{exp}'.format(
                     asm=disassembly, exp=an_input.assembly_substr))
@@ -334,6 +433,32 @@
         return True, ''
 
 
+class ValidAssemblyFileWithoutSubstr(ValidAssemblyFile):
+    """Mixin class for checking that every input file generates a valid assembly
+    file following the assembly file naming rule, there is no output on
+    stdout/stderr, and no assembly files have the given substring specified
+    by unexpected_assembly_substr.
+
+    To mix in this class, subclasses need to provde unexpected_assembly_substr
+    as the substring we expect not to see.
+    """
+
+    def check_assembly_for_substr(self, status):
+        for input_filename in status.input_filenames:
+            assembly_filename = get_assembly_filename(input_filename)
+            success, message = self.verify_assembly_file_preamble(
+                os.path.join(status.directory, assembly_filename))
+            if not success:
+                return False, message
+            with open(assembly_filename, 'r') as f:
+                content = f.read()
+                if self.unexpected_assembly_substr in convert_to_unix_line_endings(content):
+                   return False, ('Incorrect assembly output:\n{asm}\n'
+                                  'Unexpected substring found:\n{unexp}'.format(
+                                  asm=content, exp=self.unexpected_assembly_substr))
+        return True, ''
+
+
 class ValidNamedAssemblyFile(SuccessfulReturn, CorrectAssemblyFilePreamble):
     """Mixin class for checking that a list of assembly files with the given
     names are correctly generated, and there is no output on stdout/stderr.
@@ -372,7 +497,7 @@
                            'signal ' + str(status.returncode))
         if not status.stderr:
             return False, 'Expected error message, but no output on stderr'
-        if self.expected_error != convert_to_unix_line_endings(status.stderr):
+        if self.expected_error != convert_to_unix_line_endings(convert_to_string(status.stderr)):
             return False, ('Incorrect stderr output:\n{act}\n'
                            'Expected:\n{exp}'.format(
                                act=status.stderr, exp=self.expected_error))
@@ -401,7 +526,7 @@
                            'signal ' + str(status.returncode))
         if not status.stderr:
             return False, 'Expected error message, but no output on stderr'
-        if self.expected_error_substr not in convert_to_unix_line_endings(status.stderr):
+        if self.expected_error_substr not in convert_to_unix_line_endings(convert_to_string(status.stderr)):
             return False, ('Incorrect stderr output:\n{act}\n'
                            'Expected substring not found in stderr:\n{exp}'.format(
                                act=status.stderr, exp=self.expected_error_substr))
@@ -421,7 +546,7 @@
                            ' glslc')
         if not status.stderr:
             return False, 'Expected warning message, but no output on stderr'
-        if self.expected_warning != convert_to_unix_line_endings(status.stderr):
+        if self.expected_warning != convert_to_unix_line_endings(convert_to_string(status.stderr)):
             return False, ('Incorrect stderr output:\n{act}\n'
                            'Expected:\n{exp}'.format(
                                act=status.stderr, exp=self.expected_warning))
@@ -480,16 +605,16 @@
                 return False, 'Expected something on stdout'
         elif type(self.expected_stdout) == str:
             if self.expected_stdout != convert_to_unix_line_endings(
-                status.stdout):
+                    convert_to_string(status.stdout)):
                 return False, ('Incorrect stdout output:\n{ac}\n'
                                'Expected:\n{ex}'.format(
                                    ac=status.stdout, ex=self.expected_stdout))
         else:
             if not self.expected_stdout.search(convert_to_unix_line_endings(
-                status.stdout)):
+                    convert_to_string(status.stdout))):
                 return False, ('Incorrect stdout output:\n{ac}\n'
                                'Expected to match regex:\n{ex}'.format(
-                                   ac=status.stdout,
+                                   ac=convert_to_string(status.stdout),
                                    ex=self.expected_stdout.pattern))
         return True, ''
 
@@ -513,7 +638,7 @@
                 return False, 'Expected something on stderr'
         else:
             if self.expected_stderr != convert_to_unix_line_endings(
-                status.stderr):
+                    convert_to_string(status.stderr)):
                 return False, ('Incorrect stderr output:\n{ac}\n'
                                'Expected:\n{ex}'.format(
                                    ac=status.stderr, ex=self.expected_stderr))
@@ -536,3 +661,31 @@
                     return False, ('Stdout line longer than 80 columns: %s'
                                    % line)
         return True, ''
+
+
+class NoObjectFile(GlslCTest):
+    """Mixin class for checking that no input file has a corresponding object
+    file."""
+
+    def check_no_object_file(self, status):
+        for input_filename in status.input_filenames:
+            object_filename = get_object_filename(input_filename)
+            full_object_file = os.path.join(status.directory, object_filename)
+            print("checking %s" % full_object_file)
+            if os.path.isfile(full_object_file):
+                return False, ('Expected no object file, but found: %s'
+                               % full_object_file)
+        return True, ''
+
+
+class NoNamedOutputFiles(GlslCTest):
+    """Mixin class for checking that no specified output files exist.
+
+    The expected_output_filenames member should be full pathnames."""
+
+    def check_no_named_output_files(self, status):
+        for object_filename in self.expected_output_filenames:
+            if os.path.isfile(object_filename):
+                return False, ('Expected no output file, but found: %s'
+                               % object_filename)
+        return True, ''
diff --git a/glslc/test/expect_nosetest.py b/glslc/test/expect_nosetest.py
deleted file mode 100644
index 567b0a0..0000000
--- a/glslc/test/expect_nosetest.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2015 The Shaderc Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Tests for the expect module."""
-
-import expect
-from glslc_test_framework import TestStatus
-from nose.tools import assert_equal, assert_true, assert_false
-import re
-
-def nosetest_get_object_name():
-    """Tests get_object_filename()."""
-    source_and_object_names = [
-        ('a.vert', 'a.vert.spv'), ('b.frag', 'b.frag.spv'),
-        ('c.tesc', 'c.tesc.spv'), ('d.tese', 'd.tese.spv'),
-        ('e.geom', 'e.geom.spv'), ('f.comp', 'f.comp.spv'),
-        ('file', 'file.spv'), ('file.', 'file.spv'),
-        ('file.uk', 'file.spv'), ('file.vert.', 'file.vert.spv'),
-        ('file.vert.bla', 'file.vert.spv')]
-    actual_object_names = [
-        expect.get_object_filename(f[0]) for f in source_and_object_names]
-    expected_object_names = [f[1] for f in source_and_object_names]
-
-    assert_equal(actual_object_names, expected_object_names)
-
-
-class TestStdoutMatchADotC(expect.StdoutMatch):
-    expected_stdout = re.compile("a.c")
-
-
-def nosetest_stdout_match_regex_has_match():
-    test = TestStdoutMatchADotC()
-    status = TestStatus(test_manager=None, returncode=0, stdout='0abc1',
-                        stderr=None, directory=None, inputs=None, input_filenames=None)
-    assert_true(test.check_stdout_match(status)[0])
-
-
-def nosetest_stdout_match_regex_no_match():
-    test = TestStdoutMatchADotC()
-    status = TestStatus(test_manager=None, returncode=0, stdout='ab',
-                        stderr=None, directory=None, inputs=None, input_filenames=None)
-    assert_false(test.check_stdout_match(status)[0])
-
-
-def nosetest_stdout_match_regex_empty_stdout():
-    test = TestStdoutMatchADotC()
-    status = TestStatus(test_manager=None, returncode=0, stdout='', stderr=None,
-                        directory=None, inputs=None, input_filenames=None)
-    assert_false(test.check_stdout_match(status)[0])
diff --git a/glslc/test/expect_unittest.py b/glslc/test/expect_unittest.py
new file mode 100644
index 0000000..1a49c0c
--- /dev/null
+++ b/glslc/test/expect_unittest.py
@@ -0,0 +1,83 @@
+# Copyright 2019 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Tests for the expect module."""
+
+
+import expect
+from glslc_test_framework import TestStatus
+import re
+import unittest
+
+
+class TestStdoutMatchADotC(expect.StdoutMatch):
+    expected_stdout = re.compile('a.c')
+
+
+class TestExpect(unittest.TestCase):
+    def test_get_object_name(self):
+        """Tests get_object_filename()."""
+        source_and_object_names = [('a.vert', 'a.vert.spv'),
+                                   ('b.frag', 'b.frag.spv'),
+                                   ('c.tesc', 'c.tesc.spv'),
+                                   ('d.tese', 'd.tese.spv'),
+                                   ('e.geom', 'e.geom.spv'),
+                                   ('f.comp', 'f.comp.spv'),
+                                   ('file', 'file.spv'), ('file.', 'file.spv'),
+                                   ('file.uk',
+                                    'file.spv'), ('file.vert.',
+                                                  'file.vert.spv'),
+                                   ('file.vert.bla',
+                                    'file.vert.spv')]
+        actual_object_names = [
+            expect.get_object_filename(f[0]) for f in source_and_object_names
+        ]
+        expected_object_names = [f[1] for f in source_and_object_names]
+
+        self.assertEqual(actual_object_names, expected_object_names)
+
+    def test_stdout_match_regex_has_match(self):
+        test = TestStdoutMatchADotC()
+        status = TestStatus(
+            test_manager=None,
+            returncode=0,
+            stdout=b'0abc1',
+            stderr=None,
+            directory=None,
+            inputs=None,
+            input_filenames=None)
+        self.assertTrue(test.check_stdout_match(status)[0])
+
+    def test_stdout_match_regex_no_match(self):
+        test = TestStdoutMatchADotC()
+        status = TestStatus(
+            test_manager=None,
+            returncode=0,
+            stdout=b'ab',
+            stderr=None,
+            directory=None,
+            inputs=None,
+            input_filenames=None)
+        self.assertFalse(test.check_stdout_match(status)[0])
+
+    def test_stdout_match_regex_empty_stdout(self):
+        test = TestStdoutMatchADotC()
+        status = TestStatus(
+            test_manager=None,
+            returncode=0,
+            stdout=b'',
+            stderr=None,
+            directory=None,
+            inputs=None,
+            input_filenames=None)
+        self.assertFalse(test.check_stdout_match(status)[0])
diff --git a/glslc/test/glslc_test_framework.py b/glslc/test/glslc_test_framework.py
index 6bf43a7..3d4bc17 100755
--- a/glslc/test/glslc_test_framework.py
+++ b/glslc/test/glslc_test_framework.py
@@ -45,8 +45,6 @@
 be deleted.
 """
 
-from __future__ import print_function
-
 import argparse
 import fnmatch
 import inspect
@@ -74,7 +72,7 @@
 
 
 def get_all_superclasses(cls):
-    """Returns all superclasses of a given class.
+    """Returns all superclasses of a given class. Omits root 'object' superclass.
 
     Returns:
       A list of superclasses of the given class. The order guarantees that
@@ -87,10 +85,10 @@
     classes = []
     for superclass in cls.__bases__:
         for c in get_all_superclasses(superclass):
-            if c not in classes:
+            if c is not object and c not in classes:
                 classes.append(c)
     for superclass in cls.__bases__:
-        if superclass not in classes:
+        if superclass is not object and superclass not in classes:
             classes.append(superclass)
     return classes
 
@@ -305,7 +303,7 @@
             run_results = [getattr(self.test, test_method)(test_status)
                            for test_method in get_all_test_methods(
                                self.test.__class__)]
-            success, message = zip(*run_results)
+            success, message = list(zip(*run_results))
             success = all(success)
             message = '\n'.join(message)
         except Exception as e:
@@ -335,8 +333,8 @@
         manager.leave_output = True
     for root, _, filenames in os.walk(root_dir):
         for filename in fnmatch.filter(filenames, '*.py'):
-            if filename.endswith('nosetest.py'):
-                # Skip nose tests, which are for testing functions of
+            if filename.endswith('unittest.py'):
+                # Skip unit tests, which are for testing functions of
                 # the test framework.
                 continue
             sys.path = default_path
diff --git a/glslc/test/glslc_test_framework_nosetest.py b/glslc/test/glslc_test_framework_nosetest.py
deleted file mode 100644
index b6bded5..0000000
--- a/glslc/test/glslc_test_framework_nosetest.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright 2015 The Shaderc Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from glslc_test_framework import get_all_test_methods, get_all_superclasses
-from nose.tools import assert_equal, with_setup
-
-
-# Classes to be used in testing get_all_{superclasses|test_methods}()
-class Root:
-    def check_root(self): pass
-
-class A(Root):
-    def check_a(self): pass
-class B(Root):
-    def check_b(self): pass
-class C(Root):
-    def check_c(self): pass
-class D(Root):
-    def check_d(self): pass
-class E(Root):
-    def check_e(self): pass
-
-class H(B, C, D):
-    def check_h(self): pass
-class I(E):
-    def check_i(self): pass
-
-class O(H, I):
-    def check_o(self): pass
-
-class U(A, O):
-    def check_u(self): pass
-
-class X(U, A):
-    def check_x(self): pass
-
-class R1:
-    def check_r1(self): pass
-class R2:
-    def check_r2(self): pass
-
-class Multi(R1, R2):
-    def check_multi(self): pass
-
-def nosetest_get_all_superclasses():
-    """Tests get_all_superclasses()."""
-
-    assert_equal(get_all_superclasses(A), [Root])
-    assert_equal(get_all_superclasses(B), [Root])
-    assert_equal(get_all_superclasses(C), [Root])
-    assert_equal(get_all_superclasses(D), [Root])
-    assert_equal(get_all_superclasses(E), [Root])
-
-    assert_equal(get_all_superclasses(H), [Root, B, C, D])
-    assert_equal(get_all_superclasses(I), [Root, E])
-
-    assert_equal(get_all_superclasses(O), [Root, B, C, D, E, H, I])
-
-    assert_equal(get_all_superclasses(U), [Root, B, C, D, E, H, I, A, O])
-    assert_equal(get_all_superclasses(X), [Root, B, C, D, E, H, I, A, O, U])
-
-    assert_equal(get_all_superclasses(Multi), [R1, R2])
-
-
-def nosetest_get_all_methods():
-    """Tests get_all_test_methods()."""
-    assert_equal(get_all_test_methods(A), ['check_root', 'check_a'])
-    assert_equal(get_all_test_methods(B), ['check_root', 'check_b'])
-    assert_equal(get_all_test_methods(C), ['check_root', 'check_c'])
-    assert_equal(get_all_test_methods(D), ['check_root', 'check_d'])
-    assert_equal(get_all_test_methods(E), ['check_root', 'check_e'])
-
-    assert_equal(
-        get_all_test_methods(H),
-        ['check_root', 'check_b', 'check_c', 'check_d', 'check_h'])
-    assert_equal(get_all_test_methods(I), ['check_root', 'check_e', 'check_i'])
-
-    assert_equal(
-        get_all_test_methods(O),
-        ['check_root', 'check_b', 'check_c', 'check_d',
-         'check_e', 'check_h', 'check_i', 'check_o'])
-
-    assert_equal(
-        get_all_test_methods(U),
-        ['check_root', 'check_b', 'check_c', 'check_d', 'check_e',
-         'check_h', 'check_i', 'check_a', 'check_o', 'check_u'])
-    assert_equal(
-        get_all_test_methods(X),
-        ['check_root', 'check_b', 'check_c', 'check_d', 'check_e',
-         'check_h', 'check_i', 'check_a', 'check_o', 'check_u', 'check_x'])
-
-    assert_equal(
-        get_all_test_methods(Multi), ['check_r1', 'check_r2', 'check_multi'])
diff --git a/glslc/test/glslc_test_framework_unittest.py b/glslc/test/glslc_test_framework_unittest.py
new file mode 100644
index 0000000..3f58432
--- /dev/null
+++ b/glslc/test/glslc_test_framework_unittest.py
@@ -0,0 +1,159 @@
+# Copyright 2019 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Tests for the glslc_test_framework module."""
+
+from glslc_test_framework import get_all_test_methods, get_all_superclasses
+import unittest
+
+
+# Classes to be used in testing get_all_{superclasses|test_methods}()
+
+
+class Root:
+
+    def check_root(self):
+        pass
+
+
+class A(Root):
+
+    def check_a(self):
+        pass
+
+
+class B(Root):
+
+    def check_b(self):
+        pass
+
+
+class C(Root):
+
+    def check_c(self):
+        pass
+
+
+class D(Root):
+
+    def check_d(self):
+        pass
+
+
+class E(Root):
+
+    def check_e(self):
+        pass
+
+
+class H(B, C, D):
+
+    def check_h(self):
+        pass
+
+
+class I(E):
+
+    def check_i(self):
+        pass
+
+
+class O(H, I):
+
+    def check_o(self):
+        pass
+
+
+class U(A, O):
+
+    def check_u(self):
+        pass
+
+
+class X(U, A):
+
+    def check_x(self):
+        pass
+
+
+class R1:
+
+    def check_r1(self):
+        pass
+
+
+class R2:
+
+    def check_r2(self):
+        pass
+
+
+class Multi(R1, R2):
+
+    def check_multi(self):
+        pass
+
+
+class TestSpirvTestFramework(unittest.TestCase):
+    def test_get_all_superclasses(self):
+        self.assertEqual(get_all_superclasses(A), [Root])
+        self.assertEqual(get_all_superclasses(B), [Root])
+        self.assertEqual(get_all_superclasses(C), [Root])
+        self.assertEqual(get_all_superclasses(D), [Root])
+        self.assertEqual(get_all_superclasses(E), [Root])
+
+        self.assertEqual(get_all_superclasses(H), [Root, B, C, D])
+        self.assertEqual(get_all_superclasses(I), [Root, E])
+
+        self.assertEqual(get_all_superclasses(O), [Root, B, C, D, E, H, I])
+
+        self.assertEqual(get_all_superclasses(
+            U), [Root, B, C, D, E, H, I, A, O])
+        self.assertEqual(get_all_superclasses(
+            X), [Root, B, C, D, E, H, I, A, O, U])
+
+        self.assertEqual(get_all_superclasses(Multi), [R1, R2])
+
+    def test_get_all_methods(self):
+        self.assertEqual(get_all_test_methods(A), ['check_root', 'check_a'])
+        self.assertEqual(get_all_test_methods(B), ['check_root', 'check_b'])
+        self.assertEqual(get_all_test_methods(C), ['check_root', 'check_c'])
+        self.assertEqual(get_all_test_methods(D), ['check_root', 'check_d'])
+        self.assertEqual(get_all_test_methods(E), ['check_root', 'check_e'])
+
+        self.assertEqual(
+            get_all_test_methods(H),
+            ['check_root', 'check_b', 'check_c', 'check_d', 'check_h'])
+        self.assertEqual(get_all_test_methods(
+            I), ['check_root', 'check_e', 'check_i'])
+
+        self.assertEqual(
+            get_all_test_methods(O), [
+                'check_root', 'check_b', 'check_c', 'check_d', 'check_e', 'check_h',
+                'check_i', 'check_o'
+            ])
+
+        self.assertEqual(
+            get_all_test_methods(U), [
+                'check_root', 'check_b', 'check_c', 'check_d', 'check_e', 'check_h',
+                'check_i', 'check_a', 'check_o', 'check_u'
+            ])
+
+        self.assertEqual(
+            get_all_test_methods(X), [
+                'check_root', 'check_b', 'check_c', 'check_d', 'check_e', 'check_h',
+                'check_i', 'check_a', 'check_o', 'check_u', 'check_x'
+            ])
+
+        self.assertEqual(
+            get_all_test_methods(Multi), ['check_r1', 'check_r2', 'check_multi'])
\ No newline at end of file
diff --git a/glslc/test/include.py b/glslc/test/include.py
index a965032..798ff22 100644
--- a/glslc/test/include.py
+++ b/glslc/test/include.py
@@ -49,7 +49,7 @@
 
     glslc_args = ['-E', 'a.vert']
     expected_error = [
-        "a.vert:3: error: '#include' : Cannot find or open include file.\n",
+        "a.vert:3: error: '#include' : Cannot find or open include file. for header name: b\n",
         '1 error generated.\n'
     ]
 
@@ -64,7 +64,7 @@
     glslc_args = ['a.vert']
 
 @inside_glslc_testsuite('Include')
-class VerifyIncludeWithoutNewline(expect.StdoutMatch):
+class VerifyIncludeWithoutNewline(expect.ErrorMessageSubstr):
     """Tests a #include without a newline."""
 
     environment = Directory('.', [
@@ -73,16 +73,8 @@
 
     glslc_args = ['-E', 'a.vert']
 
-    expected_stdout = \
-"""#version 140
-#extension GL_GOOGLE_include_directive : enable
-#line 0 "a.vert"
+    expected_error_substr = 'expected newline after header name: b'
 
-#line 0 "b"
-content b
-#line 2 "a.vert"
-
-"""
 
 @inside_glslc_testsuite('Include')
 class VerifyCompileIncludeWithoutNewline(expect.ValidObjectFile):
@@ -282,10 +274,11 @@
     environment = Directory('.', [
         File('a.vert', '#version 100000000\n#include "b.glsl"\n'),
         File('b.glsl', 'void main() {}\n')])
-    glslc_args = ['-c', 'a.vert']
+    glslc_args = ['-c', '-std=400', 'a.vert']
 
     expected_warning = [
-        'a.vert: warning: version 100000000 is unknown.\n',
+        'a.vert: warning: (version, profile) forced to be (400, none),'
+        ' while in source code it is (100000000, none)\n'
         '1 warning generated.\n'
     ]
 
@@ -506,7 +499,8 @@
     glslc_args = ['-E', 'a.vert']
 
     expected_error = [
-        "foo/b.glsl:1: error: '#include' : Cannot find or open include file.\n",
+        "foo/b.glsl:1: error: '#include' : "
+        'Cannot find or open include file. for header name: c.glsl\n',
         '1 error generated.\n'
     ]
 
diff --git a/glslc/test/line.py b/glslc/test/line.py
index a74cb11..0b4cd2c 100644
--- a/glslc/test/line.py
+++ b/glslc/test/line.py
@@ -243,7 +243,8 @@
     including_file = '''#version 310 es
 #include "error.glsl"
 int no_return() {}
-#include "main.glsl"'''
+#include "main.glsl"
+'''
 
     environment = Directory('.', [
         File('a.vert', including_file),
@@ -256,8 +257,8 @@
         "error.glsl:1: error: 'return' : type does not match, or is not "
         "convertible to, the function's return type\n",
         "a.vert:3: error: '' : function does not return a value: no_return\n",
-        "main.glsl:2: error: '=' :  cannot convert from 'const float' to "
-        "'temp highp int'\n",
+        "main.glsl:2: error: '=' :  cannot convert from ' const float' to "
+        "' temp highp int'\n",
         "4 errors generated.\n"]
 
 
@@ -272,7 +273,8 @@
 #include "inc.glsl"
 int plus2(int a) { return a + 2; }
 #line 55555
-#include "main.glsl"'''
+#include "main.glsl"
+'''
 
     environment = Directory('.', [
         File('a.vert', including_file),
diff --git a/glslc/test/messages_tests.py b/glslc/test/messages_tests.py
index 21c1bbc..401f3db 100644
--- a/glslc/test/messages_tests.py
+++ b/glslc/test/messages_tests.py
@@ -84,10 +84,11 @@
     void main() {
     }
     """, '.vert')
-    glslc_args = ['-c', shader]
+    glslc_args = ['-c', '-std=400', shader]
 
     expected_warning = [
-        shader, ': warning: version 550 is unknown.\n1 warning generated.\n']
+            shader, ': warning: (version, profile) forced to be (400, none),'
+            ' while in source code it is (550, none)\n1 warning generated.\n']
 
 @inside_glslc_testsuite('ErrorMessages')
 class SuppressedGlobalWarning(expect.SuccessfulReturn):
@@ -99,7 +100,7 @@
     void main() {
     }
     """, '.vert')
-    glslc_args = ['-c', shader, '-w']
+    glslc_args = ['-c', '-std=400', shader, '-w']
 
 
 @inside_glslc_testsuite('ErrorMessages')
@@ -112,18 +113,19 @@
     void main() {
     }
     """, '.vert')
-    glslc_args = ['-c', shader, '-Werror']
+    glslc_args = ['-c', '-std=400', shader, '-Werror']
 
     expected_error= [
-        shader, ': error: version 550 is unknown.\n1 error generated.\n']
+            shader, ': error: (version, profile) forced to be (400, none),'
+            ' while in source code it is (550, none)\n1 error generated.\n']
 
 @inside_glslc_testsuite('ErrorMessages')
 class WarningOnLine(expect.WarningMessage):
     """Tests that a warning message with a file/line number is emitted."""
 
     shader = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     void main() {
     }
     """, '.vert')
@@ -139,8 +141,8 @@
     presence of -w."""
 
     shader = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     void main() {
     }
     """, '.vert')
@@ -152,8 +154,8 @@
     number is emitted instead of a warning."""
 
     shader = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     void main() {
     }
     """, '.vert')
@@ -168,8 +170,8 @@
     """Tests that both warnings and errors are emitted together."""
 
     shader = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     int main() {
     }
     """, '.vert')
@@ -187,8 +189,8 @@
     """Tests that only warnings are suppressed in the presence of -w."""
 
     shader = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     int main() {
     }
     """, '.vert')
@@ -204,8 +206,8 @@
     """Tests that with -Werror an warnings and errors are emitted as errors."""
 
     shader = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     int main() {
     }
     """, '.vert')
@@ -243,8 +245,8 @@
     """
 
     shader = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     void main() {
     }
     """, '.vert')
@@ -255,21 +257,23 @@
     }
     """, '.vert')
 
-    glslc_args = ['-c', shader, '-Werror', shader2]
+    glslc_args = ['-c', '-std=400', shader, '-Werror', shader2]
 
     expected_error = [
         shader, ':2: error: attribute deprecated in version 130; ',
         'may be removed in future release\n',
-        shader2, ': error: version 550 is unknown.\n',
+        shader2, ': error: (version, profile) forced to be (400, none),'
+            ' while in source code it is (550, none)\n',
         '2 errors generated.\n']
 
+
 @inside_glslc_testsuite('ErrorMessages')
 class SuppressedWarningAsError(expect.SuccessfulReturn):
     """Tests that nothing is returned in the presence of -w -Werror."""
 
     shader = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     void main() {
     }
     """, '.vert')
@@ -280,8 +284,8 @@
     """Tests that multiple -w arguments are supported."""
 
     shader = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     void main() {
     }
     """, '.vert')
@@ -292,15 +296,15 @@
     """Tests that -w suppresses warnings from all files."""
 
     shader = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     void main() {
     }
     """, '.vert')
 
     shader2 = FileShader(
-        """#version 140
-    attribute float x;
+        """#version 400
+    layout(location = 0) attribute float x;
     void main() {
     }
     """, '.vert')
diff --git a/glslc/test/option_dash_M.py b/glslc/test/option_dash_M.py
index b7d77ba..9fadb01 100644
--- a/glslc/test/option_dash_M.py
+++ b/glslc/test/option_dash_M.py
@@ -14,6 +14,7 @@
 
 import expect
 import os.path
+import sys
 from environment import File, Directory
 from glslc_test_framework import inside_glslc_testsuite
 from placeholder import FileShader
@@ -100,7 +101,12 @@
         if not status.stdout:
             return False, 'Expect dependency rules on stdout'
 
-        rules = parse_text_rules(status.stdout.split('\n'))
+        if sys.version_info[0] == 2:
+            rules = parse_text_rules(status.stdout.decode('utf-8').split('\n'))
+        elif sys.version_info[0] == 3:
+            rules = parse_text_rules(str(status.stdout,
+                                         encoding='utf-8',
+                                         errors='ignore').split('\n'))
 
         process_test_specified_dependency_info_rules(
             self.dependency_rules_expected)
@@ -309,7 +315,7 @@
     environment = Directory('.', [
         Directory('include', [File('b.vert', 'void foo(){}\n')]),
     ])
-    shader_main = FileShader('#version 140\n#include "include/b.vert"',
+    shader_main = FileShader('#version 140\n#include "include/b.vert"\n',
                              '.vert')
     glslc_args = ['-M', shader_main]
     dependency_rules_expected = [{
@@ -381,7 +387,9 @@
          <no warning message should be generated>
     """
     environment = Directory('.', [File(
-        'shader.vert', '#version 140\nattribute float x;\nvoid main() {}')])
+            'shader.vert', """#version 400
+               layout(location=0) attribute float x;
+               void main() {}""")])
     glslc_args = ['-M', 'shader.vert']
     dependency_rules_expected = [{'target': 'shader.vert.spv',
                                   'dependency': {'shader.vert'}}]
@@ -412,7 +420,10 @@
          <no warning message should be generated>
     """
     environment = Directory('.', [File(
-        'shader.vert', '#version 140\nattribute float x;\nvoid main() {}')])
+        'shader.vert', """
+           #version 400
+           layout(location = 0) attribute float x;
+           void main() {}""")])
     glslc_args = ['-MM', 'shader.vert']
     dependency_rules_expected = [{'target': 'shader.vert.spv',
                                   'dependency': {'shader.vert'}}]
diff --git a/glslc/test/option_dash_cap_O.py b/glslc/test/option_dash_cap_O.py
index 8a7f234..9655a39 100644
--- a/glslc/test/option_dash_cap_O.py
+++ b/glslc/test/option_dash_cap_O.py
@@ -20,10 +20,38 @@
 MINIMAL_SHADER = '#version 310 es\nvoid main() {}'
 EMPTY_SHADER_IN_CWD = Directory('.', [File('shader.vert', MINIMAL_SHADER)])
 
+ASSEMBLY_WITH_DEBUG_SOURCE = [
+    '; SPIR-V\n',
+    '; Version: 1.0\n',
+    '; Generator: Google Shaderc over Glslang; 10\n',
+    '; Bound: 7\n',
+    '; Schema: 0\n',
+    '               OpCapability Shader\n',
+    '          %2 = OpExtInstImport "GLSL.std.450"\n',
+    '               OpMemoryModel Logical GLSL450\n',
+    '               OpEntryPoint Vertex %main "main"\n',
+    '          %1 = OpString "shader.vert"\n',
+    '               OpSource ESSL 310 %1 "// OpModuleProcessed entry-point main\n',
+    '// OpModuleProcessed client vulkan100\n',
+    '// OpModuleProcessed target-env vulkan1.0\n',
+    '// OpModuleProcessed entry-point main\n',
+    '#line 1\n',
+    '#version 310 es\n',
+    'void main() {}"\n',
+    '               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"\n',
+    '               OpSourceExtension "GL_GOOGLE_include_directive"\n',
+    '               OpName %main "main"\n',
+    '       %void = OpTypeVoid\n',
+    '          %4 = OpTypeFunction %void\n',
+    '       %main = OpFunction %void None %4\n',
+    '          %6 = OpLabel\n',
+    '               OpReturn\n',
+    '               OpFunctionEnd\n']
+
 ASSEMBLY_WITH_DEBUG = [
     '; SPIR-V\n',
     '; Version: 1.0\n',
-    '; Generator: Khronos Glslang Reference Front End; 1\n',
+    '; Generator: Google Shaderc over Glslang; 10\n',
     '; Bound: 6\n',
     '; Schema: 0\n',
     '               OpCapability Shader\n',
@@ -44,7 +72,7 @@
 ASSEMBLY_WITHOUT_DEBUG = [
     '; SPIR-V\n',
     '; Version: 1.0\n',
-    '; Generator: Khronos Glslang Reference Front End; 1\n',
+    '; Generator: Google Shaderc over Glslang; 10\n',
     '; Bound: 6\n',
     '; Schema: 0\n',
     '               OpCapability Shader\n',
@@ -68,6 +96,14 @@
     target_filename = 'shader.vert.spvasm'
     expected_file_contents = ASSEMBLY_WITH_DEBUG
 
+@inside_glslc_testsuite('OptionDashCapO')
+class TestDashCapOPerformance(expect.ValidFileContents):
+    """Tests -O works."""
+
+    environment = EMPTY_SHADER_IN_CWD
+    glslc_args = ['-S', '-O', 'shader.vert']
+    target_filename = 'shader.vert.spvasm'
+    expected_file_contents = ASSEMBLY_WITHOUT_DEBUG
 
 @inside_glslc_testsuite('OptionDashCapO')
 class TestDashCapOs(expect.ValidFileContents):
@@ -96,7 +132,7 @@
     environment = EMPTY_SHADER_IN_CWD
     glslc_args = ['-S', '-Os', '-g', 'shader.vert']
     target_filename = 'shader.vert.spvasm'
-    expected_file_contents = ASSEMBLY_WITH_DEBUG
+    expected_file_contents = ASSEMBLY_WITH_DEBUG_SOURCE
 
 
 @inside_glslc_testsuite('OptionDashCapO')
@@ -106,7 +142,7 @@
     environment = EMPTY_SHADER_IN_CWD
     glslc_args = ['-S', '-g', '-Os', 'shader.vert']
     target_filename = 'shader.vert.spvasm'
-    expected_file_contents = ASSEMBLY_WITH_DEBUG
+    expected_file_contents = ASSEMBLY_WITH_DEBUG_SOURCE
 
 
 @inside_glslc_testsuite('OptionDashCapO')
diff --git a/glslc/test/option_dash_fhlsl_offsets.py b/glslc/test/option_dash_fhlsl_offsets.py
new file mode 100644
index 0000000..4682d31
--- /dev/null
+++ b/glslc/test/option_dash_fhlsl_offsets.py
@@ -0,0 +1,44 @@
+# Copyright 2017 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import expect
+from glslc_test_framework import inside_glslc_testsuite
+from placeholder import FileShader
+
+
+# A GLSL shader with uniforms without explicit bindings.
+GLSL_SHADER = """#version 450
+  layout(set=0, binding=0)
+  buffer B { float x; vec3 y; } my_ssbo;
+  void main() {
+    my_ssbo.x = 1.0;
+  }"""
+
+
+@inside_glslc_testsuite('OptionFHlslOffsets')
+class StandardOffsetsByDefault(expect.ValidAssemblyFileWithSubstr):
+    """Tests that standard GLSL packign is used by default."""
+
+    shader = FileShader(GLSL_SHADER, '.vert')
+    glslc_args = ['-S', shader]
+    expected_assembly_substr = "OpMemberDecorate %B 1 Offset 16"
+
+
+@inside_glslc_testsuite('OptionFHlslOffsets')
+class HlslOffsetsWhenRequested(expect.ValidAssemblyFileWithSubstr):
+    """Tests that standard GLSL packign is used by default."""
+
+    shader = FileShader(GLSL_SHADER, '.vert')
+    glslc_args = ['-S', '-fhlsl-offsets', shader]
+    expected_assembly_substr = "OpMemberDecorate %B 1 Offset 4"
diff --git a/glslc/test/option_dash_fnan_clamp.py b/glslc/test/option_dash_fnan_clamp.py
new file mode 100644
index 0000000..36b9006
--- /dev/null
+++ b/glslc/test/option_dash_fnan_clamp.py
@@ -0,0 +1,69 @@
+# Copyright 2019 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import expect
+from glslc_test_framework import inside_glslc_testsuite
+from placeholder import FileShader
+
+# A GLSL shader using the clamp, max, and min builtin functions.
+GLSL_FRAG_SHADER_WITH_CLAMP = """#version 450
+layout(location=0) in vec4 i;
+layout(location=0) out vec4 o;
+void main() {
+  o = clamp(i, vec4(0.5), vec4(1.0))
+  +   max(i, vec4(0.5))
+  +   min(i, vec4(0.5));
+}
+"""
+
+
+@inside_glslc_testsuite('OptionFNanClamp')
+class TestClampMapsToFClampByDefault(expect.ValidAssemblyFileWithSubstr):
+    shader = FileShader(GLSL_FRAG_SHADER_WITH_CLAMP, '.frag')
+    glslc_args = ['-S', shader]
+    expected_assembly_substr = 'OpExtInst %v4float %1 FClamp'
+
+
+@inside_glslc_testsuite('OptionFNanClamp')
+class TestMaxMapsToFMaxByDefault(expect.ValidAssemblyFileWithSubstr):
+    shader = FileShader(GLSL_FRAG_SHADER_WITH_CLAMP, '.frag')
+    glslc_args = ['-S', shader]
+    expected_assembly_substr = 'OpExtInst %v4float %1 FMax'
+
+
+@inside_glslc_testsuite('OptionFNanClamp')
+class TestMinMapsToFMinByDefault(expect.ValidAssemblyFileWithSubstr):
+    shader = FileShader(GLSL_FRAG_SHADER_WITH_CLAMP, '.frag')
+    glslc_args = ['-S', shader]
+    expected_assembly_substr = 'OpExtInst %v4float %1 FMin'
+
+
+@inside_glslc_testsuite('OptionFNanClamp')
+class TestClampMapsToNClampWithFlag(expect.ValidAssemblyFileWithSubstr):
+    shader = FileShader(GLSL_FRAG_SHADER_WITH_CLAMP, '.frag')
+    glslc_args = ['-S', '-fnan-clamp', shader]
+    expected_assembly_substr = 'OpExtInst %v4float %1 NClamp'
+
+@inside_glslc_testsuite('OptionFNanClamp')
+class TestMaxMapsToNMaxWithFlag(expect.ValidAssemblyFileWithSubstr):
+    shader = FileShader(GLSL_FRAG_SHADER_WITH_CLAMP, '.frag')
+    glslc_args = ['-S', '-fnan-clamp', shader]
+    expected_assembly_substr = 'OpExtInst %v4float %1 NMax'
+
+
+@inside_glslc_testsuite('OptionFNanClamp')
+class TestMinMapsToNMinWithFlag(expect.ValidAssemblyFileWithSubstr):
+    shader = FileShader(GLSL_FRAG_SHADER_WITH_CLAMP, '.frag')
+    glslc_args = ['-S', '-fnan-clamp', shader]
+    expected_assembly_substr = 'OpExtInst %v4float %1 NMin'
diff --git a/glslc/test/option_dash_o.py b/glslc/test/option_dash_o.py
index 1a32c12..cd7f1d1 100644
--- a/glslc/test/option_dash_o.py
+++ b/glslc/test/option_dash_o.py
@@ -16,6 +16,7 @@
 import os.path
 from glslc_test_framework import inside_glslc_testsuite
 from placeholder import FileShader, TempFileName
+from builtins import bytes
 
 
 @inside_glslc_testsuite('OptionDashO')
@@ -63,3 +64,35 @@
     glslc_args = ['-o']
     expected_error = ['glslc: error: argument to \'-o\' is missing ' +
                       '(expected 1 value)\n']
+
+
+@inside_glslc_testsuite('OptionDashO')
+class OutputFileBinaryAvoidsCRLFTranslation(expect.ReturnCodeIsZero,
+                                            expect.NoOutputOnStderr,
+                                            expect.NoGeneratedFiles,
+                                            expect.CorrectBinaryLengthAndPreamble):
+    """Tests that the -o flag emits a binary file without CR/LF translation.
+    """
+
+    # A shader whose compiled output has three bytes that are newlines.
+    # If the output stream converts the newlines to CR/LF, then we end up
+    # with a file that is 4k + 3 bytes long.  That will be caught by the
+    # object file checks.
+    SHADER_WITH_THREE_NEWLINES_IN_BINARY = """#version 450
+       layout(location = 0) out uint ovar;
+       void main() { ovar = 9; }
+    """
+
+    shader = FileShader(SHADER_WITH_THREE_NEWLINES_IN_BINARY, '.vert')
+    glslc_args = [shader, '-o', '-']
+
+    def check_stdout_binary(self, status):
+        binary = bytes(status.stdout)
+        newlines = [x for x in binary if x == ord('\n')]
+        num_newlines = len(newlines)
+        if num_newlines % 4 == 0:
+            return False, "Bad test. Need nontrivial number of newlines"
+        if num_newlines != 3:
+            return False, ("Update this test. Expected 3 newlines in the "
+                           "binary, but found {}").format(num_newlines)
+        return self.verify_binary_length_and_header(bytes(status.stdout))
diff --git a/glslc/test/option_dash_x.py b/glslc/test/option_dash_x.py
index 3645340..4c0bbdf 100644
--- a/glslc/test/option_dash_x.py
+++ b/glslc/test/option_dash_x.py
@@ -19,8 +19,12 @@
 MINIMAL_SHADER = "#version 140\nvoid main(){}"
 # This one is valid GLSL but not valid HLSL.
 GLSL_VERTEX_SHADER = "#version 140\nvoid main(){ gl_Position = vec4(1.0);}"
+# This one is GLSL but without leading #version.  Should result in
+# a parser error when compiled as HLSL.
+GLSL_VERTEX_SHADER_WITHOUT_VERSION = "void main(){ gl_Position = vec4(1.0);}"
 # This one is valid HLSL but not valid GLSL.
-HLSL_VERTEX_SHADER = "float4 EntryPoint() : SV_POSITION { return float4(1.0); }"
+# Use entry point "main" so we don't have to specify -fentry-point
+HLSL_VERTEX_SHADER = "float4 main() : SV_POSITION { return float4(1.0); }"
 
 @inside_glslc_testsuite('OptionDashX')
 class TestDashXNoArg(expect.ErrorMessage):
@@ -56,6 +60,15 @@
 
     shader = FileShader(GLSL_VERTEX_SHADER, '.vert')
     glslc_args = ['-x', 'hlsl', '-c', shader]
+    expected_error_substr = ["error: '#version' : invalid preprocessor command\n"]
+
+
+@inside_glslc_testsuite('OptionDashX')
+class TestDashXHlslOnGlslShaderWithoutVertex(expect.ErrorMessageSubstr):
+    """Tests -x hlsl on a GLSL shader without leading #version."""
+
+    shader = FileShader(GLSL_VERTEX_SHADER_WITHOUT_VERSION, '.vert')
+    glslc_args = ['-x', 'hlsl', '-c', shader]
     expected_error_substr = ["error: 'vec4' : no matching overloaded function found\n"]
 
 
diff --git a/glslc/test/option_fauto_bind_uniforms.py b/glslc/test/option_fauto_bind_uniforms.py
new file mode 100644
index 0000000..3f90a12
--- /dev/null
+++ b/glslc/test/option_fauto_bind_uniforms.py
@@ -0,0 +1,431 @@
+# Copyright 2017 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import expect
+from glslc_test_framework import inside_glslc_testsuite
+from placeholder import FileShader
+
+# A GLSL shader with uniforms without explicit bindings.
+GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS = """#version 450
+  #extension GL_ARB_sparse_texture2 : enable
+  uniform texture2D my_tex;
+  uniform sampler my_sam;
+  layout(rgba32f) uniform image2D my_img;
+  layout(rgba32f) uniform imageBuffer my_imbuf;
+  uniform block { float x; float y; } my_ubo;
+  buffer B { float z; } my_ssbo;
+  void main() {
+    texture(sampler2D(my_tex,my_sam),vec2(1.0));
+    vec4 t;
+    sparseImageLoadARB(my_img,ivec2(0),t);
+    imageLoad(my_imbuf,42);
+    float x = my_ubo.x;
+    my_ssbo.z = 1.1;
+  }"""
+
+
+# An HLSL shader with uniforms without explicit bindings.
+# The counter buffer has an associated counter that needs a
+# binding.  Compile this shader with --auto-bind-uniforms to
+# give it a binding, since Glslang does not support attribute
+# [[vk::counter_binding(N))]].
+# See https://github.com/KhronosGroup/glslang/issues/1616
+HLSL_SHADER_WITHOUT_BINDINGS = """
+SamplerState s1 : register(s1);
+SamplerComparisonState s2 : register(s2);
+
+Texture1D t1 : register(t11);
+Texture2D <float4> t2 : register(t12);
+Texture3D <float2> t3 : register(t13);
+StructuredBuffer<float4> t4 : register(t14);
+ByteAddressBuffer t5 : register(t15);
+Buffer<float4> t6 : register(t16);
+
+RWTexture1D <float4>  u1 : register(u21);
+RWTexture1D <float4>  u2 : register(u22);
+RWTexture1D <float4>  u3 : register(u23);
+RWBuffer <float4> u4 : register(u24);
+RWByteAddressBuffer u5 : register(u25);
+RWStructuredBuffer<float> u6 : register(u26);
+AppendStructuredBuffer<float> u7 : register(u27);
+ConsumeStructuredBuffer<float> u8 : register(u28);
+
+float4 main() : SV_Target0 {
+   s1;
+   s2;
+
+   t1;
+   t2;
+   t3;
+   t4[2];
+   t5.Load(8);
+   t6;
+
+   u1;
+   u2;
+   u3;
+   u4[1];
+   u5.Load(15);
+   u6[2];
+   u7;
+   u8;
+   return float4(u8.Consume() + t2.SampleCmp(s2, 1.0, 2.0)) + t1.Sample(s1, 1.0)
+    + t6.Load(1);
+}
+"""
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class UniformBindingsNotCreatedByDefault(expect.ErrorMessageSubstr):
+    """Tests that compilation fails when uniforms have no binding."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader]
+    expected_error_substr = "sampler/texture/image requires layout(binding=X)"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FAutoBindingUniformsGeneratesBindings(expect.ValidAssemblyFileWithSubstr):
+    """Tests that the compiler generates bindings for uniforms upon request ."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms']
+    # Sufficient to just check one of the uniforms.
+    expected_assembly_substr = "OpDecorate %my_sam Binding 1"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FImageBindingBaseOptionRespectedOnImage(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fimage-binding-base value is respected on images."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base', '44']
+    expected_assembly_substr = "OpDecorate %my_img Binding 44"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FImageBindingBaseOptionRespectedOnImageBuffer(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fimage-binding-base value is respected on image buffers."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base', '44']
+    expected_assembly_substr = "OpDecorate %my_imbuf Binding 45"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FTextureBindingBaseOptionRespected(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -ftexture-binding-base value is respected."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-ftexture-binding-base', '44']
+    expected_assembly_substr = "OpDecorate %my_tex Binding 44"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FSamplerBindingBaseOptionRespected(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fsampler-binding-base value is respected."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fsampler-binding-base', '44']
+    expected_assembly_substr = "OpDecorate %my_sam Binding 44"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FUboBindingBaseOptionRespectedOnBuffer(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fubo-binding-base value is respected."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fubo-binding-base', '44']
+    expected_assembly_substr = "OpDecorate %my_ubo Binding 44"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FCbufferBindingBaseOptionRespectedOnBuffer(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fcbuffer-binding-base value is respected."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fcbuffer-binding-base', '44']
+    expected_assembly_substr = "OpDecorate %my_ubo Binding 44"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FImageBindingBaseNeedsValue(expect.ErrorMessageSubstr):
+    """Tests that -fimage-binding-base requires a value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fimage-binding-base']
+    expected_error_substr = "error: Option -fimage-binding-base requires at least one argument"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FTextureBindingBaseNeedsValue(expect.ErrorMessageSubstr):
+    """Tests that -ftexture-binding-base requires a value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-ftexture-binding-base']
+    expected_error_substr = "error: Option -ftexture-binding-base requires at least one argument"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FSamplerBindingBaseNeedsValue(expect.ErrorMessageSubstr):
+    """Tests that -fsampler-binding-base requires a value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fsampler-binding-base']
+    expected_error_substr = "error: Option -fsampler-binding-base requires at least one argument"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FUboBindingBaseNeedsValue(expect.ErrorMessageSubstr):
+    """Tests that -fubo-binding-base requires a value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fubo-binding-base']
+    expected_error_substr = "error: Option -fubo-binding-base requires at least one argument"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FImageBindingBaseNeedsNumberValueIfNotStage(expect.ErrorMessageSubstr):
+    """Tests that -fimage-binding-base requires a number value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fimage-binding-base', '9x']
+    expected_error_substr = "error: invalid offset value 9x for -fimage-binding-base"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FTextureBindingBaseNeedsNumberValue(expect.ErrorMessageSubstr):
+    """Tests that -ftexture-binding-base requires a number value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-ftexture-binding-base', '9x']
+    expected_error_substr = "error: invalid offset value 9x for -ftexture-binding-base"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FSamplerBindingBaseNeedsNumberValue(expect.ErrorMessageSubstr):
+    """Tests that -fsampler-binding-base requires a number value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fsampler-binding-base', '9x']
+    expected_error_substr = "error: invalid offset value 9x for -fsampler-binding-base"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FUboBindingBaseNeedsNumberValue(expect.ErrorMessageSubstr):
+    """Tests that -fubo-binding-base requires a number value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fubo-binding-base', '9x']
+    expected_error_substr = "error: invalid offset value 9x for -fubo-binding-base"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FImageBindingBaseNeedsUnsignedNumberValue(expect.ErrorMessageSubstr):
+    """Tests that -fimage-binding-base requires an unsigned number value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fimage-binding-base', '-6']
+    expected_error_substr = "error: invalid offset value -6 for -fimage-binding-base"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FTextureBindingBaseNeedsUnsignedNumberValue(expect.ErrorMessageSubstr):
+    """Tests that -ftexture-binding-base requires an unsigned number value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-ftexture-binding-base', '-6']
+    expected_error_substr = "error: invalid offset value -6 for -ftexture-binding-base"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FSamplerBindingBaseNeedsUnsignedNumberValue(expect.ErrorMessageSubstr):
+    """Tests that -fsampler-binding-base requires an unsigned value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fsampler-binding-base', '-6']
+    expected_error_substr = "error: invalid offset value -6 for -fsampler-binding-base"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FUboBindingBaseNeedsUnsignedNumberValue(expect.ErrorMessageSubstr):
+    """Tests that -fubo-binding-base requires an unsigned value."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fubo-binding-base', '-6']
+    expected_error_substr = "error: invalid offset value -6 for -fubo-binding-base"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FImageBindingBaseForVertOptionRespectedOnImageCompileAsVert(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fimage-binding-base with vert stage value is respected on images."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base', 'vert', '44']
+    expected_assembly_substr = "OpDecorate %my_img Binding 44"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FImageBindingBaseForVertOptionIgnoredOnImageCompileAsFrag(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fimage-binding-base with vert stage value is ignored when cmopiled as
+    fragment."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base', 'vert', '44']
+    expected_assembly_substr = "OpDecorate %my_img Binding 2"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FImageBindingBaseForFragOptionRespectedOnImageCompileAsFrag(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fimage-binding-base with frag stage value is respected on images."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base', 'frag', '44']
+    expected_assembly_substr = "OpDecorate %my_img Binding 44"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FSsboBindingBaseRespectedOnSsboCompileAsFrag(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fssbo-binding-base with frag stage value is respected on SSBOs."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fssbo-binding-base', '100']
+    expected_assembly_substr = "OpDecorate %my_ssbo Binding 100"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FSsboBindingBaseForFragOptionRespectedOnSsboCompileAsFrag(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fssbo-binding-base with frag stage value is respected on SSBOs."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fssbo-binding-base', 'frag', '100']
+    expected_assembly_substr = "OpDecorate %my_ssbo Binding 100"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class FSsboBindingBaseForFragOptionIgnoredOnSsboCompileAsVert(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fssbo-binding-base with frag stage value is ignored on SSBOs
+    when compiling as a vertex shader."""
+
+    shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fssbo-binding-base', 'frag', '100']
+    expected_assembly_substr = "OpDecorate %my_ssbo Binding 5"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class AutomaticHlslIoMapping(expect.ValidAssemblyFileWithSubstr):
+    """Tests that HLSL IO Mapping uses the register values in the source code."""
+
+    shader = FileShader(HLSL_SHADER_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl-iomap',
+                  '-fauto-bind-uniforms', shader]
+    expected_assembly_substr = "OpDecorate %u8 Binding 28"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class HlslFSamplerBindingBaseOptionRespected(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fsampler-binding-base sets binding base for samplers in HLSL
+    compilation."""
+
+    shader = FileShader(HLSL_SHADER_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl-iomap', shader,
+                  '-fauto-bind-uniforms', '-fsampler-binding-base', '100']
+    expected_assembly_substr = "OpDecorate %s2 Binding 102"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class HlslFSamplerBindingBaseForFragOptionRespected(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fsampler-binding-base for frag sets binding base for samplers
+    in HLSL compilation."""
+
+    shader = FileShader(HLSL_SHADER_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl-iomap', shader,
+                  '-fauto-bind-uniforms', '-fsampler-binding-base', 'frag', '100']
+    expected_assembly_substr = "OpDecorate %s2 Binding 102"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class HlslFSamplerBindingBaseForComputeOptionIgnoredWhenCompilingAsFrag(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fsampler-binding-base for compute is ignored when compiling
+    as a fragment shader."""
+
+    shader = FileShader(HLSL_SHADER_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl-iomap', shader,
+                  '-fauto-bind-uniforms', '-fsampler-binding-base', 'compute', '100']
+    expected_assembly_substr = "OpDecorate %s2 Binding 2"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class HlslFTextureBindingBaseOptionRespected(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -ftexture-binding-base sets binding base for textures in HLSL
+    compilation."""
+
+    shader = FileShader(HLSL_SHADER_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl-iomap', shader,
+                  '-fauto-bind-uniforms', '-ftexture-binding-base', '100']
+    expected_assembly_substr = "OpDecorate %t6 Binding 116"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class HlslFTextureBindingBaseForFragOptionRespected(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -ftexture-binding-base for frag sets binding base for textures
+    in HLSL compilation."""
+
+    shader = FileShader(HLSL_SHADER_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl-iomap', shader,
+                  '-fauto-bind-uniforms', '-ftexture-binding-base', 'frag', '100']
+    expected_assembly_substr = "OpDecorate %t6 Binding 116"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class HlslFTextureBindingBaseForComputeOptionIgnoredWhenCompilingAsFrag(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -ftexture-binding-base for compute is ignored when compiling
+    as a fragment shader."""
+
+    shader = FileShader(HLSL_SHADER_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl-iomap', shader,
+                  '-fauto-bind-uniforms', '-ftexture-binding-base', 'compute', '100']
+    expected_assembly_substr = "OpDecorate %t6 Binding 16"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class HlslFUavBindingBaseOptionRespected(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fuav-binding-base sets binding base for UAVs in HLSL
+    compilation."""
+
+    shader = FileShader(HLSL_SHADER_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl-iomap', shader,
+                  '-fauto-bind-uniforms', '-fuav-binding-base', '100']
+    expected_assembly_substr = "OpDecorate %u8 Binding 128"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class HlslFUavBindingBaseForFragOptionRespected(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fuav-binding-base for frag sets binding base for UAVs in HLSL
+    compilation."""
+
+    shader = FileShader(HLSL_SHADER_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl-iomap', shader,
+                  '-fauto-bind-uniforms', '-fuav-binding-base', 'frag', '100']
+    expected_assembly_substr = "OpDecorate %u8 Binding 128"
+
+
+@inside_glslc_testsuite('OptionFAutoBindUniforms')
+class HlslFUavBindingBaseForComputeOptionIgnoredWhenCompilingAsFrag(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fuav-binding-base for compute is ignored when compiling
+    as a fragment shader."""
+
+    shader = FileShader(HLSL_SHADER_WITHOUT_BINDINGS, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl-iomap', shader,
+                  '-fauto-bind-uniforms', '-fuav-binding-base', 'compute', '100']
+    expected_assembly_substr = "OpDecorate %u8 Binding 28"
diff --git a/glslc/test/option_fauto_map_locations.py b/glslc/test/option_fauto_map_locations.py
new file mode 100644
index 0000000..24ef496
--- /dev/null
+++ b/glslc/test/option_fauto_map_locations.py
@@ -0,0 +1,87 @@
+# Copyright 2018 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import expect
+from glslc_test_framework import inside_glslc_testsuite
+from placeholder import FileShader
+
+# A GLSL shader with inputs and outputs explicit locations.
+GLSL_SHADER_IO_WITHOUT_LOCATIONS = """#version 310 es
+  in vec4 m_in;
+  in vec4 m_in1;
+  out vec4 m_out;
+  out vec4 m_out1;
+  void main() {
+    m_out = m_in;
+    m_out1 = m_in1;
+  }"""
+
+
+# An HLSL fragment shader with inputs and outputs explicit locations.
+HLSL_SHADER_IO_WITHOUT_LOCATIONS = """
+  float4 Foo(float4 a, float4 b) : COLOR0 {
+    return a + b;
+  }"""
+
+
+@inside_glslc_testsuite('OptionFAutoMapLocations')
+class MissingLocationsResultsInError(expect.ErrorMessageSubstr):
+    """Tests that compilation fails when inputs or outputs have no location."""
+
+    shader = FileShader(GLSL_SHADER_IO_WITHOUT_LOCATIONS, '.vert')
+    glslc_args = ['-S', shader]
+    expected_error_substr = "SPIR-V requires location for user input/output"
+
+
+@inside_glslc_testsuite('OptionFAutoMapLocations')
+class FAutoMapLocationsGeneratesLocationsCheckInput(expect.ValidAssemblyFileWithSubstr):
+    """Tests that the compiler generates locations upon request:  Input 0"""
+
+    shader = FileShader(GLSL_SHADER_IO_WITHOUT_LOCATIONS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-map-locations']
+    expected_assembly_substr = "OpDecorate %m_in Location 0"
+
+
+@inside_glslc_testsuite('OptionFAutoMapLocations')
+class FAutoMapLocationsGeneratesLocationsCheckOutput0(expect.ValidAssemblyFileWithSubstr):
+    """Tests that the compiler generates locations upon request:  Output 0"""
+
+    shader = FileShader(GLSL_SHADER_IO_WITHOUT_LOCATIONS, '.vert')
+    glslc_args = ['-S', shader, '-fauto-map-locations']
+    expected_assembly_substr = "OpDecorate %m_out Location 0"
+
+
+# Currently Glslang only generates Location 0.
+# See https://github.com/KhronosGroup/glslang/issues/1261
+# TODO(dneto): Write tests that check Location 1 is generated for inputs and
+# outputs.
+
+
+# Glslang's HLSL compiler automatically assigns locations inptus and outputs.
+@inside_glslc_testsuite('OptionFAutoMapLocations')
+class HLSLCompilerGeneratesLocationsCheckInput0(expect.ValidAssemblyFileWithSubstr):
+    """Tests that the HLSL compiler generates locations automatically: Input 0."""
+
+    shader = FileShader(HLSL_SHADER_IO_WITHOUT_LOCATIONS, '.hlsl')
+    glslc_args = ['-S', '-fshader-stage=frag', '-fentry-point=Foo', shader]
+    expected_assembly_substr = "OpDecorate %a Location 0"
+
+
+@inside_glslc_testsuite('OptionFAutoMapLocations')
+class HLSLCompilerGeneratesLocationsCheckOutput(expect.ValidAssemblyFileWithSubstr):
+    """Tests that the HLSL compiler generates locations automatically: Output."""
+
+    shader = FileShader(HLSL_SHADER_IO_WITHOUT_LOCATIONS, '.hlsl')
+    glslc_args = ['-S', '-fshader-stage=frag', '-fentry-point=Foo', shader]
+    expected_assembly_substr = "OpDecorate %_entryPointOutput Location 0"
diff --git a/glslc/test/option_fentry_point.py b/glslc/test/option_fentry_point.py
index 5d8f96f..8625732 100644
--- a/glslc/test/option_fentry_point.py
+++ b/glslc/test/option_fentry_point.py
@@ -58,17 +58,21 @@
 
 
 @inside_glslc_testsuite('OptionFEntryPoint')
-class TestFEntryPointMainOnHlslShader(expect.ValidAssemblyFileWithSubstr):
-    """Tests -x hlsl on an HLSL shader with -fentry-point=main and -S."""
+class TestFEntryPointMainOnHlslShaderNotMatchingSource(expect.ValidObjectFileWithWarning):
+    """Tests -x hlsl on an HLSL shader with -fentry-point=main
+    not matching the source."""
 
     shader = FileShader(HLSL_VERTEX_SHADER, '.vert')
-    glslc_args = ['-x', 'hlsl', '-fentry-point=main', '-S', shader]
-    expected_assembly_substr = ASSEMBLY_MAIN
+    glslc_args = ['-x', 'hlsl', '-fentry-point=main', '-c', shader]
+    expected_warning = [shader,
+                        ': warning: Linking vertex stage: Entry point not found\n'
+                        '1 warning generated.\n']
 
 
 @inside_glslc_testsuite('OptionFEntryPoint')
 class TestFEntryPointSpecifiedOnHlslShaderInDisassembly(expect.ValidObjectFileWithAssemblySubstr):
-    """Tests -x hlsl on an HLSL shader with -fentry-point=EntryPoint."""
+    """Tests -x hlsl on an HLSL shader with -fentry-point=EntryPoint
+    matching source."""
 
     shader = FileShader(HLSL_VERTEX_SHADER, '.vert', assembly_substr=ASSEMBLY_ENTRY_POINT)
     glslc_args = ['-x', 'hlsl', '-fentry-point=EntryPoint', '-c', shader]
diff --git a/glslc/test/option_fhlsl_functionality1.py b/glslc/test/option_fhlsl_functionality1.py
new file mode 100644
index 0000000..51453ee
--- /dev/null
+++ b/glslc/test/option_fhlsl_functionality1.py
@@ -0,0 +1,71 @@
+# Copyright 2018 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import expect
+from glslc_test_framework import inside_glslc_testsuite
+from placeholder import FileShader
+
+# An HLSL shader with a counter buffer with a counter increment.
+# Glslang doesn't automatically assign a binding to the counter, and
+# it doesn't understand [[vk::counter_binding(n)]], so compile this
+# with --auto-bind-uniforms.
+# See https://github.com/KhronosGroup/glslang/issues/1616
+HLSL_VERTEX_SHADER_WITH_COUNTER_BUFFER = """
+RWStructuredBuffer<int> Ainc;
+float4 main() : SV_Target0 {
+  return float4(Ainc.IncrementCounter(), 0, 1, 2);
+}
+"""
+
+
+@inside_glslc_testsuite('OptionFHlslFunctionality1')
+class TestHlslFunctionality1MentionsExtension(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fhlsl_functionality1 enabled SPV_GOOGLE_hlsl_functionality1."""
+
+    shader = FileShader(HLSL_VERTEX_SHADER_WITH_COUNTER_BUFFER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl_functionality1',
+                  '-fauto-bind-uniforms', shader]
+    expected_assembly_substr = 'OpExtension "SPV_GOOGLE_hlsl_functionality1"'
+
+
+@inside_glslc_testsuite('OptionFHlslFunctionality1')
+class TestHlslFunctionality1DecoratesCounter(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fhlsl_functionality1 decorates the output target"""
+
+    shader = FileShader(HLSL_VERTEX_SHADER_WITH_COUNTER_BUFFER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl_functionality1',
+                  '-fauto-bind-uniforms', shader]
+    expected_assembly_substr = 'OpDecorateString'
+
+
+## Next tests use the option with the hypen instead of underscore.
+
+@inside_glslc_testsuite('OptionFHlslFunctionality1')
+class TestHlslHyphenFunctionality1MentionsExtension(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fhlsl-functionality1 enabled SPV_GOOGLE_hlsl_functionality1."""
+
+    shader = FileShader(HLSL_VERTEX_SHADER_WITH_COUNTER_BUFFER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl_functionality1',
+                  '-fauto-bind-uniforms', shader]
+    expected_assembly_substr = 'OpExtension "SPV_GOOGLE_hlsl_functionality1"'
+
+
+@inside_glslc_testsuite('OptionFHlslFunctionality1')
+class TestHlslHyphenFunctionality1DecoratesCounter(expect.ValidAssemblyFileWithSubstr):
+    """Tests that -fhlsl-functionality1 decorates the output target"""
+
+    shader = FileShader(HLSL_VERTEX_SHADER_WITH_COUNTER_BUFFER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', '-fhlsl_functionality1',
+                  '-fauto-bind-uniforms', shader]
+    expected_assembly_substr = 'OpDecorateString'
diff --git a/glslc/test/option_flimit.py b/glslc/test/option_flimit.py
new file mode 100644
index 0000000..30a0e02
--- /dev/null
+++ b/glslc/test/option_flimit.py
@@ -0,0 +1,136 @@
+# Copyright 2016 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import expect
+from environment import File, Directory
+from glslc_test_framework import inside_glslc_testsuite
+from placeholder import FileShader
+
+
+def shader_source_with_tex_offset(offset):
+    """Returns a vertex shader using a texture access with the given offset."""
+
+    return """#version 450
+              layout (binding=0) uniform sampler1D tex;
+              void main() { vec4 x = textureOffset(tex, 1.0, """ + str(offset) + "); }"
+
+
+def shader_with_tex_offset(offset):
+    """Returns a vertex FileShader using a texture access with the given offset."""
+
+    return FileShader(shader_source_with_tex_offset(offset), ".vert")
+
+
+@inside_glslc_testsuite('OptionFLimit')
+class TestFLimitNoEqual(expect.ErrorMessage):
+    """Tests -flimit without equal."""
+
+    glslc_args = ['-flimit']
+    expected_error = ["glslc: error: unknown argument: '-flimit'\n"]
+
+
+@inside_glslc_testsuite('OptionFLimit')
+class TestFLimitJustEqual(expect.ValidObjectFile):
+    """Tests -flimit= with no argument."""
+
+    shader = shader_with_tex_offset(0);
+    glslc_args = ['-c', shader, '-flimit=']
+
+
+@inside_glslc_testsuite('OptionFLimit')
+class TestFLimitJustEqualMaxOffset(expect.ValidObjectFile):
+    """Tests -flimit= with no argument.  The shader uses max offset."""
+
+    shader = shader_with_tex_offset(7);
+    glslc_args = ['-c', shader, '-flimit=']
+
+
+@inside_glslc_testsuite('OptionFLimit')
+class TestFLimitJustEqualMinOffset(expect.ValidObjectFile):
+    """Tests -flimit= with no argument.  The shader uses min offset."""
+
+    shader = shader_with_tex_offset(-8);
+    glslc_args = ['-c', shader, '-flimit=']
+
+
+@inside_glslc_testsuite('OptionFLimit')
+class TestFLimitJustEqualBelowMinOffset(expect.ErrorMessageSubstr):
+    """Tests -flimit= with no argument.  The shader uses below min default offset."""
+
+    shader = shader_with_tex_offset(-9);
+    glslc_args = ['-c', shader, '-flimit=']
+    expected_error_substr = ["'texel offset' : value is out of range"]
+
+
+@inside_glslc_testsuite('OptionFLimit')
+class TestFLimitLowerThanDefaultMinOffset(expect.ValidObjectFile):
+    """Tests -flimit= with lower than default argument.  The shader uses below min offset."""
+
+    shader = shader_with_tex_offset(-9);
+    glslc_args = ['-c', shader, '-flimit= MinProgramTexelOffset -9 ']
+
+
+@inside_glslc_testsuite('OptionFLimit')
+class TestFLimitIgnoredLangFeatureSettingSample(expect.ValidObjectFile):
+    """Tests -flimit= an ignored option."""
+
+    shader = FileShader("#version 150\nvoid main() { while(true); }", '.vert')
+    glslc_args = ['-c', shader, '-flimit=whileLoops 0']
+
+
+@inside_glslc_testsuite('OptionFLimit')
+class TestFLimitLowerThanDefaultMinOffset(expect.ValidObjectFile):
+    """Tests -flimit= with lower than default argument.  The shader uses that offset."""
+
+    shader = shader_with_tex_offset(-9);
+    glslc_args = ['-c', shader, '-flimit= MinProgramTexelOffset -9 ']
+
+
+@inside_glslc_testsuite('OptionFLimitFile')
+class TestFLimitFileNoArg(expect.ErrorMessage):
+    """Tests -flimit-file without an argument"""
+
+    shader = shader_with_tex_offset(-9);
+    glslc_args = ['-c', shader, '-flimit-file']
+    expected_error = "glslc: error: argument to '-flimit-file' is missing\n"
+
+
+@inside_glslc_testsuite('OptionFLimitFile')
+class TestFLimitFileMissingFile(expect.ErrorMessageSubstr):
+    """Tests -flimit-file without an argument"""
+
+    shader = shader_with_tex_offset(-9);
+    glslc_args = ['-c', shader, '-flimit-file', 'i do not exist']
+    expected_error_substr = "glslc: error: cannot open input file: 'i do not exist'";
+
+
+@inside_glslc_testsuite('OptionFLimitFile')
+class TestFLimitFileSetsLowerMinTexelOffset(expect.ValidObjectFile):
+    """Tests -flimit-file with lower than default argument.  The shader uses that offset."""
+
+    limits_file = File('limits.txt', 'MinProgramTexelOffset -9')
+    shader = File('shader.vert', shader_source_with_tex_offset(-9));
+    environment = Directory('.', [limits_file, shader])
+    glslc_args = ['-c', shader.name, '-flimit-file', limits_file.name]
+
+
+@inside_glslc_testsuite('OptionFLimitFile')
+class TestFLimitFileInvalidContents(expect.ErrorMessage):
+    """Tests -flimit-file bad file contents."""
+
+    limits_file = File('limits.txt', 'thisIsBad')
+    shader = File('shader.vert', shader_source_with_tex_offset(-9));
+    environment = Directory('.', [limits_file, shader])
+    glslc_args = ['-c', shader.name, '-flimit-file', limits_file.name]
+    expected_error = 'glslc: error: -flimit-file error: invalid resource limit: thisIsBad\n'
diff --git a/glslc/test/option_fresource_set_binding.py b/glslc/test/option_fresource_set_binding.py
new file mode 100644
index 0000000..254004e
--- /dev/null
+++ b/glslc/test/option_fresource_set_binding.py
@@ -0,0 +1,121 @@
+# Copyright 2017 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import expect
+from glslc_test_framework import inside_glslc_testsuite
+from placeholder import FileShader
+
+# An HLSL shader with uniforms without explicit bindings.
+HLSL_SHADER = """
+Buffer<float4> t4 : register(t4);
+Buffer<float4> t5 : register(t5);
+
+float4 main() : SV_Target0 {
+   return float4(t4.Load(0) + t5.Load(1));
+}
+"""
+
+
+NEED_THREE_ARGS_ERR = "error: Option -fresource-set-binding requires at least 3 arguments"
+
+@inside_glslc_testsuite('OptionFRegisterSetBinding')
+class FRegisterSetBindingForFragRespected(expect.ValidAssemblyFileWithSubstr):
+    """Tests -fresource-set-binding on specific shader two textures"""
+
+    shader = FileShader(HLSL_SHADER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', shader,
+                  '-fresource-set-binding', 'frag',
+                  't4', '9', '16',
+                  't5', '17', '18']
+    expected_assembly_substr = """OpDecorate %t4 DescriptorSet 9
+               OpDecorate %t4 Binding 16
+               OpDecorate %t5 DescriptorSet 17
+               OpDecorate %t5 Binding 18"""
+
+
+@inside_glslc_testsuite('OptionFRegisterSetBinding')
+class FRegisterSetBindingForFragRespectedJustOneTriple(expect.ValidAssemblyFileWithSubstr):
+    """Tests -fresource-set-binding on specific shader just one texture specified."""
+
+    shader = FileShader(HLSL_SHADER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', shader,
+                  '-fresource-set-binding', 'frag',
+                  't4', '9', '16']
+    expected_assembly_substr = """OpDecorate %t4 DescriptorSet 9
+               OpDecorate %t4 Binding 16
+               OpDecorate %t5 DescriptorSet 0
+               OpDecorate %t5 Binding 5"""
+
+
+@inside_glslc_testsuite('OptionFRegisterSetBinding')
+class FRegisterSetBindingForWrongStageIgnored(expect.ValidAssemblyFileWithSubstr):
+    """Tests -fresource-set-binding on wrong shader ignored"""
+
+    shader = FileShader(HLSL_SHADER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', shader,
+                  '-fresource-set-binding', 'vert',
+                  't4', '9', '16',
+                  't5', '17', '18']
+    expected_assembly_substr = """OpDecorate %t4 DescriptorSet 0
+               OpDecorate %t4 Binding 4
+               OpDecorate %t5 DescriptorSet 0
+               OpDecorate %t5 Binding 5"""
+
+
+@inside_glslc_testsuite('OptionFRegisterSetBinding')
+class FRegisterSetBindingForAllRespected(expect.ValidAssemblyFileWithSubstr):
+    """Tests -fresource-set-binding on all stages respected"""
+
+    shader = FileShader(HLSL_SHADER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', shader,
+                  '-fresource-set-binding',
+                  't4', '9', '16',
+                  't5', '17', '18']
+    expected_assembly_substr = """OpDecorate %t4 DescriptorSet 9
+               OpDecorate %t4 Binding 16
+               OpDecorate %t5 DescriptorSet 17
+               OpDecorate %t5 Binding 18"""
+
+
+@inside_glslc_testsuite('OptionFRegisterSetBinding')
+class FRegisterSetBindingTooFewArgs(expect.ErrorMessageSubstr):
+    """Tests -fresource-set-binding with too few arguments"""
+
+    shader = FileShader(HLSL_SHADER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', shader,
+                  '-fresource-set-binding', 'frag',
+                  't4', '9']
+    expected_error_substr = NEED_THREE_ARGS_ERR
+
+
+@inside_glslc_testsuite('OptionFRegisterSetBinding')
+class FRegisterSetBindingInvalidSetNumber(expect.ErrorMessageSubstr):
+    """Tests -fresource-set-binding with inavlid set number"""
+
+    shader = FileShader(HLSL_SHADER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', shader,
+                  '-fresource-set-binding', 'frag',
+                  't4', '-9', '16']
+    expected_error_substr = NEED_THREE_ARGS_ERR
+
+
+@inside_glslc_testsuite('OptionFRegisterSetBinding')
+class FRegisterSetBindingInvalidBindingNumber(expect.ErrorMessageSubstr):
+    """Tests -fresource-set-binding with inavlid binding number"""
+
+    shader = FileShader(HLSL_SHADER, '.frag')
+    glslc_args = ['-S', '-x', 'hlsl', shader,
+                  '-fresource-set-binding', 'frag',
+                  't4', '9', '-16']
+    expected_error_substr = NEED_THREE_ARGS_ERR
diff --git a/glslc/test/option_mfmt.py b/glslc/test/option_mfmt.py
index 2466319..bd58478 100644
--- a/glslc/test/option_mfmt.py
+++ b/glslc/test/option_mfmt.py
@@ -90,8 +90,7 @@
     shader = FileShader(MINIMAL_SHADER, '.vert')
     glslc_args = [shader, '-mfmt=c', '-S', '-o', 'output_file']
     expected_error = ("glslc: error: cannot emit output as a C-style "
-                      "initializer list when the output is not SPIR-V "
-                      "binary code\n")
+                      "initializer list when only preprocessing the source\n")
 
 
 @inside_glslc_testsuite('OptionMfmt')
@@ -103,7 +102,7 @@
     glslc_args = [shader, '-mfmt=num', '-S', '-o', 'output_file']
     expected_error = (
         "glslc: error: cannot emit output as a list of hex numbers "
-        "when the output is not SPIR-V binary code\n")
+        "when only preprocessing the source\n")
 
 
 @inside_glslc_testsuite('OptionMfmt')
@@ -114,7 +113,7 @@
     shader = FileShader(MINIMAL_SHADER, '.vert')
     glslc_args = [shader, '-mfmt=bin', '-S', '-o', 'output_file']
     expected_error = ("glslc: error: cannot emit output as a binary "
-                      "when the output is not SPIR-V binary code\n")
+                      "when only preprocessing the source\n")
 
 
 @inside_glslc_testsuite('OptionMfmt')
@@ -126,7 +125,7 @@
     glslc_args = [shader, '-mfmt=num', '-E', '-o', 'output_file']
     expected_error = (
         "glslc: error: cannot emit output as a list of hex numbers "
-        "when the output is not SPIR-V binary code\n")
+        "when only preprocessing the source\n")
 
 
 @inside_glslc_testsuite('OptionMfmt')
@@ -138,8 +137,7 @@
     shader = FileShader(MINIMAL_SHADER, '.vert')
     glslc_args = [shader, '-mfmt=c', '-M', '-o', 'output_file']
     expected_error = ("glslc: error: cannot emit output as a C-style "
-                      "initializer list when the output is not SPIR-V "
-                      "binary code\n")
+                      "initializer list when only preprocessing the source\n")
 
 
 @inside_glslc_testsuite('OptionMfmt')
diff --git a/glslc/test/option_shader_stage.py b/glslc/test/option_shader_stage.py
index 5114173..6b2ec0b 100644
--- a/glslc/test/option_shader_stage.py
+++ b/glslc/test/option_shader_stage.py
@@ -25,7 +25,8 @@
 
 
 def simple_hlsl_vertex_shader():
-    return """float4 EntryPoint() : SV_POSITION { return float4(1.0); } """
+    # Use "main" so we don't have to specify -fentry-point
+    return """float4 main() : SV_POSITION { return float4(1.0); } """
 
 
 def simple_fragment_shader():
diff --git a/glslc/test/option_std.py b/glslc/test/option_std.py
index 865a4d2..ff65a4b 100644
--- a/glslc/test/option_std.py
+++ b/glslc/test/option_std.py
@@ -29,7 +29,8 @@
 
 
 def hlsl_compute_shader_with_barriers():
-    return 'void Entry() { AllMemoryBarrierWithGroupSync(); }'
+    # Use "main" to avoid the need for -fentry-point
+    return 'void main() { AllMemoryBarrierWithGroupSync(); }'
 
 
 @inside_glslc_testsuite('OptionStd')
@@ -76,6 +77,30 @@
 
 
 @inside_glslc_testsuite('OptionStd')
+class TestGLSL460(expect.ValidObjectFile):
+    """Tests that GLSL version 4.6 is supported."""
+
+    shader = FileShader(core_frag_shader_without_version(), '.frag')
+    glslc_args = ['-c', '-std=460', shader]
+
+
+@inside_glslc_testsuite('OptionStd')
+class TestGLSL460Core(expect.ValidObjectFile):
+    """Tests that GLSL version 4.6 core profile is supported."""
+
+    shader = FileShader(core_frag_shader_without_version(), '.frag')
+    glslc_args = ['-c', '-std=460core', shader]
+
+
+@inside_glslc_testsuite('OptionStd')
+class TestESSL320(expect.ValidObjectFile):
+    """Tests that ESSL version 3.2 is supported."""
+
+    shader = FileShader(core_frag_shader_without_version(), '.frag')
+    glslc_args = ['-c', '-std=320es', shader]
+
+
+@inside_glslc_testsuite('OptionStd')
 class TestStdIgnoredInHlsl(expect.ValidObjectFile):
     """Tests HLSL compilation ignores -std."""
 
@@ -271,7 +296,7 @@
     glslc_args = ['-c', '-std=310', shader]
 
     expected_error = [
-        shader, ': error: #version: versions 300 and 310 require ',
+        shader, ': error: #version: versions 300, 310, and 320 require ',
         "specifying the 'es' profile\n1 error generated.\n"]
 
 
diff --git a/glslc/test/option_target_env.py b/glslc/test/option_target_env.py
index 7c0b67a..334a95f 100644
--- a/glslc/test/option_target_env.py
+++ b/glslc/test/option_target_env.py
@@ -35,6 +35,13 @@
 void main() { int t = gl_VertexIndex; }"""
 
 
+def vulkan_compute_subgroup_shader():
+    """Returns a compute shader that requires Vulkan 1.1"""
+    return """#version 450
+              #extension GL_KHR_shader_subgroup_basic : enable
+              void main() { subgroupBarrier(); }"""
+
+
 @inside_glslc_testsuite('OptionTargetEnv')
 class TestTargetEnvEqOpenglCompatWithOpenGlCompatShader(expect.ValidObjectFile):
     """Tests that compiling OpenGL Compatibility Fragment shader with
@@ -50,8 +57,9 @@
     shader = FileShader(opengl_compat_fragment_shader(), '.frag')
     glslc_args = ['--target-env=opengl', shader]
     expected_error_substr = [shader, ":4: error: 'assign' :  ",
-                             "cannot convert from 'const float' to ",
-                             "'fragColor"]
+                             "cannot convert from ' const float' to ",
+                             "'layout( location=0) out 4-component ",
+                             "vector of float"]
 
 
 @inside_glslc_testsuite('OptionTargetEnv')
@@ -79,13 +87,62 @@
 
 
 @inside_glslc_testsuite('OptionTargetEnv')
-class TestTargetEnvEqVulkanWithVulkanShader(expect.ValidObjectFile):
-    """Tests that compiling a Vulkan-specific shader succeeds with
+class TestTargetEnvEqVulkanWithVulkan1_0ShaderSucceeds(expect.ValidObjectFile):
+    """Tests that compiling a Vulkan-specific Vulkan 1.0 shader succeeds with
     --target-env=vulkan"""
     shader = FileShader(vulkan_vertex_shader(), '.vert')
     glslc_args = ['--target-env=vulkan', '-c', shader]
 
 
+@inside_glslc_testsuite('OptionTargetEnv')
+class TestTargetEnvEqVulkan1_0WithVulkan1_0ShaderSucceeds(expect.ValidObjectFile):
+    """Tests that compiling a Vulkan-specific Vulkan 1.0 shader succeeds with
+    --target-env=vulkan1.0"""
+    shader = FileShader(vulkan_vertex_shader(), '.vert')
+    glslc_args = ['--target-env=vulkan1.0', '-c', shader]
+
+
+@inside_glslc_testsuite('OptionTargetEnv')
+class TestTargetEnvEqVulkan1_0WithVulkan1_1ShaderFails(expect.ErrorMessageSubstr):
+    shader = FileShader(vulkan_compute_subgroup_shader(), '.comp')
+    glslc_args = ['--target-env=vulkan1.0', '-c', shader]
+    expected_error_substr = "error: 'subgroup op' : requires SPIR-V 1.3"
+
+
+@inside_glslc_testsuite('OptionTargetEnv')
+class TestTargetEnvEqVulkan1_1WithVulkan1_0ShaderSucceeds(expect.ValidObjectFile1_3):
+    shader = FileShader(vulkan_vertex_shader(), '.vert')
+    glslc_args = ['--target-env=vulkan1.1', '-c', shader]
+
+
+@inside_glslc_testsuite('OptionTargetEnv')
+class TestTargetEnvEqVulkan1_1WithVulkan1_1ShaderSucceeds(expect.ValidObjectFile1_3):
+    shader = FileShader(vulkan_compute_subgroup_shader(), '.comp')
+    glslc_args = ['--target-env=vulkan1.1', '-c', shader]
+
+@inside_glslc_testsuite('OptionTargetEnv')
+class TestTargetEnvEqVulkan1_2WithVulkan1_0ShaderSucceeds(expect.ValidObjectFile1_5):
+    shader = FileShader(vulkan_vertex_shader(), '.vert')
+    glslc_args = ['--target-env=vulkan1.2', '-c', shader]
+
+@inside_glslc_testsuite('OptionTargetEnv')
+class TestTargetEnvEqVulkan1_2WithVulkan1_1ShaderSucceeds(expect.ValidObjectFile1_5):
+    shader = FileShader(vulkan_compute_subgroup_shader(), '.comp')
+    glslc_args = ['--target-env=vulkan1.2', '-c', shader]
+
+@inside_glslc_testsuite('OptionTargetEnv')
+class TestTargetEnvEqOpenGL4_5WithOpenGLShaderSucceeds(expect.ValidObjectFile):
+    shader = FileShader(opengl_vertex_shader(), '.vert')
+    glslc_args = ['--target-env=opengl4.5', '-c', shader]
+
+
+@inside_glslc_testsuite('OptionTargetEnv')
+class TestTargetEnvEqOpenGL4_6WithOpenGLShaderFailsUnsupported(expect.ErrorMessageSubstr):
+    shader = FileShader(opengl_vertex_shader(), '.vert')
+    glslc_args = ['--target-env=opengl4.6', '-c', shader]
+    expected_error_substr = "invalid value 'opengl4.6' in '--target-env=opengl4.6'"
+
+
 # Note: Negative tests are covered in the libshaderc_util unit tests.
 # For example, that an OpenGL-specific shader should fail to compile
 # for Vulkan, or a Vulkan-specific shader should fail to compile for
diff --git a/glslc/test/option_target_spv.py b/glslc/test/option_target_spv.py
new file mode 100644
index 0000000..870025b
--- /dev/null
+++ b/glslc/test/option_target_spv.py
@@ -0,0 +1,118 @@
+# Copyright 2019 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import expect
+from glslc_test_framework import inside_glslc_testsuite
+from placeholder import FileShader
+
+
+def vulkan_vertex_shader():
+    return """#version 310 es
+void main() { int t = gl_VertexIndex; }"""
+
+
+def vulkan_compute_subgroup_shader():
+    """Returns a compute shader that requires Vulkan 1.1 and SPIR-V 1.3"""
+    return """#version 450
+              #extension GL_KHR_shader_subgroup_basic : enable
+              void main() { subgroupBarrier(); }"""
+
+
+@inside_glslc_testsuite('OptionTargetSpv')
+class TestDefaultTargetSpvWithVulkanShader(expect.ValidObjectFile):
+    """Tests that compiling a Vulkan-specific shader with a default
+    target environment succeeds"""
+    shader = FileShader(vulkan_vertex_shader(), '.vert')
+    glslc_args = ['-c', shader]
+
+
+@inside_glslc_testsuite('OptionTargetSpv')
+class TestDefaultTargetSpvWithShaderRequiringSpv1p3Fails(expect.ErrorMessageSubstr):
+    """Tests that compiling a shader requiring SPIR-V 1.3 with default SPIR-V
+    target should fail.
+    """
+    shader = FileShader(vulkan_compute_subgroup_shader(), '.comp')
+    glslc_args = ['-c', shader]
+    expected_error_substr = ["error: 'subgroup op' : requires SPIR-V 1.3\n"]
+
+
+@inside_glslc_testsuite('OptionTargetSpv')
+class TestTargetSpv1p2WithShaderRequiringSpv1p3Fails(expect.ErrorMessageSubstr):
+    """Tests that compiling a shader requiring SPIR-V 1.3 but targeting 1.2
+    should fail.
+    """
+    shader = FileShader(vulkan_compute_subgroup_shader(), '.comp')
+    glslc_args = ['--target-spv=spv1.2', '-c', shader]
+    expected_error_substr = ["error: 'subgroup op' : requires SPIR-V 1.3\n"]
+
+
+@inside_glslc_testsuite('OptionTargetSpv')
+class TestTargetSpv1p3(expect.ValidObjectFile1_3):
+    """Tests that compiling to spv1.3 succeeds and generates SPIR-V 1.3 binary."""
+    shader = FileShader(vulkan_compute_subgroup_shader(), '.comp')
+    glslc_args = ['--target-spv=spv1.3', '-c', shader]
+
+
+@inside_glslc_testsuite('OptionTargetSpv')
+class TestTargetSpv1p4(expect.ValidObjectFile1_4):
+    """Tests that compiling to spv1.4 succeeds and generates SPIR-V 1.4 binary."""
+    shader = FileShader(vulkan_vertex_shader(), '.vert')
+    glslc_args = ['--target-spv=spv1.4', '-c', shader]
+
+
+@inside_glslc_testsuite('OptionTargetSpv')
+class TestTargetSpv1p5(expect.ValidObjectFile1_5):
+    """Tests that compiling to spv1.5 succeeds and generates SPIR-V 1.5 binary."""
+    shader = FileShader(vulkan_vertex_shader(), '.vert')
+    glslc_args = ['--target-spv=spv1.5', '-c', shader]
+
+
+### Option parsing error cases
+
+@inside_glslc_testsuite('OptionTargetSpv')
+class TestTargetSpvNoArg(expect.ErrorMessage):
+    """Tests the error message of assigning empty string to --target-spv"""
+    shader = FileShader(vulkan_vertex_shader(), '.vert')
+    glslc_args = ['--target-spv=', shader]
+    expected_error = ["glslc: error: invalid value ",
+                      "'' in '--target-spv='\n"]
+
+
+@inside_glslc_testsuite('OptionTargetSpv')
+class TestTargetSpvNoEqNoArg(expect.ErrorMessage):
+    """Tests the error message of using --target-spv without equal sign and
+    arguments"""
+    shader = FileShader(vulkan_vertex_shader(), '.vert')
+    glslc_args = ['--target-spv', shader]
+    expected_error = ["glslc: error: unsupported option: ",
+                      "'--target-spv'\n"]
+
+
+@inside_glslc_testsuite('OptionTargetSpv')
+class TestTargetSpvNoEqWithArg(expect.ErrorMessage):
+    """Tests the error message of using --target-spv without equal sign but
+    arguments"""
+    shader = FileShader(vulkan_vertex_shader(), '.vert')
+    glslc_args = ['--target-spv', 'spv1.3', shader]
+    expected_error = ["glslc: error: unsupported option: ",
+                      "'--target-spv'\n"]
+
+
+@inside_glslc_testsuite('OptionTargetSpv')
+class TestTargetSpvEqWrongArg(expect.ErrorMessage):
+    """Tests the error message of using --target-spv with wrong argument"""
+    shader = FileShader(vulkan_vertex_shader(), '.vert')
+    glslc_args = ['--target-spv=wrong_arg', shader]
+    expected_error = ["glslc: error: invalid value ",
+                      "'wrong_arg' in '--target-spv=wrong_arg'\n"]
diff --git a/glslc/test/parameter_tests.py b/glslc/test/parameter_tests.py
index cbb6f11..18b43f4 100644
--- a/glslc/test/parameter_tests.py
+++ b/glslc/test/parameter_tests.py
@@ -57,38 +57,123 @@
   -Dmacro[=defn]    Add an implicit macro definition.
   -E                Outputs only the results of the preprocessing step.
                     Output defaults to standard output.
-  -fshader-stage=<stage>
-                    Treat subsequent input files as having stage <stage>.
-                    Valid stages are vertex, fragment, tesscontrol, tesseval,
-                    geometry, and compute.
+  -fauto-bind-uniforms
+                    Automatically assign bindings to uniform variables that
+                    don't have an explicit 'binding' layout in the shader
+                    source.
+  -fauto-map-locations
+                    Automatically assign locations to uniform variables that
+                    don't have an explicit 'location' layout in the shader
+                    source.
   -fentry-point=<name>
                     Specify the entry point name for HLSL compilation, for
                     all subsequent source files.  Default is "main".
+  -fhlsl_functionality1, -fhlsl-functionality1
+                    Enable extension SPV_GOOGLE_hlsl_functionality1 for HLSL
+                    compilation.
+  -finvert-y        Invert position.Y output in vertex shader.
+  -fhlsl-iomap      Use HLSL IO mappings for bindings.
+  -fhlsl-offsets    Use HLSL offset rules for packing members of blocks.
+                    Affects only GLSL.  HLSL rules are always used for HLSL.
+  -flimit=<settings>
+                    Specify resource limits. Each limit is specified by a limit
+                    name followed by an integer value.  Tokens should be
+                    separated by whitespace.  If the same limit is specified
+                    several times, only the last setting takes effect.
+  -flimit-file <file>
+                    Set limits as specified in the given file.
+  -fnan-clamp       Generate code for max and min builtins so that, when given
+                    a NaN operand, the other operand is returned. Similarly,
+                    the clamp builtin will favour the non-NaN operands, as if
+                    clamp were implemented as a composition of max and min.
+  -fresource-set-binding [stage] <reg0> <set0> <binding0>
+                        [<reg1> <set1> <binding1>...]
+                    Explicitly sets the descriptor set and binding for
+                    HLSL resources, by register name.  Optionally restrict
+                    it to a single stage.
+  -fcbuffer-binding-base [stage] <value>
+                    Same as -fubo-binding-base.
+  -fimage-binding-base [stage] <value>
+                    Sets the lowest automatically assigned binding number for
+                    images.  Optionally only set it for a single shader stage.
+                    For HLSL, the resource register number is added to this
+                    base.
+  -fsampler-binding-base [stage] <value>
+                    Sets the lowest automatically assigned binding number for
+                    samplers  Optionally only set it for a single shader stage.
+                    For HLSL, the resource register number is added to this
+                    base.
+  -fssbo-binding-base [stage] <value>
+                    Sets the lowest automatically assigned binding number for
+                    shader storage buffer objects (SSBO).  Optionally only set
+                    it for a single shader stage.  Only affects GLSL.
+  -ftexture-binding-base [stage] <value>
+                    Sets the lowest automatically assigned binding number for
+                    textures.  Optionally only set it for a single shader stage.
+                    For HLSL, the resource register number is added to this
+                    base.
+  -fuav-binding-base [stage] <value>
+                    For automatically assigned bindings for unordered access
+                    views (UAV), the register number is added to this base to
+                    determine the binding number.  Optionally only set it for
+                    a single shader stage.  Only affects HLSL.
+  -fubo-binding-base [stage] <value>
+                    Sets the lowest automatically assigned binding number for
+                    uniform buffer objects (UBO).  Optionally only set it for
+                    a single shader stage.
+                    For HLSL, the resource register number is added to this
+                    base.
+  -fshader-stage=<stage>
+                    Treat subsequent input files as having stage <stage>.
+                    Valid stages are vertex, vert, fragment, frag, tesscontrol,
+                    tesc, tesseval, tese, geometry, geom, compute, and comp.
   -g                Generate source-level debug information.
                     Currently this option has no effect.
+  -h                Display available options.
   --help            Display available options.
-  --version         Display compiler version information.
   -I <value>        Add directory to include search path.
-  -o <file>         Write output to <file>.
-                    A file name of '-' represents standard output.
-  -std=<value>      Version and profile for GLSL input files. Possible values
-                    are concatenations of version and profile, e.g. 310es,
-                    450core, etc.  Ignored for HLSL files.
   -mfmt=<format>    Output SPIR-V binary code using the selected format. This
                     option may be specified only when the compilation output is
-                    in SPIR-V binary code form. Available options include bin, c
-                    and num. By default the binary output format is bin.
+                    in SPIR-V binary code form. Available options are:
+                      bin   - SPIR-V binary words.  This is the default.
+                      c     - Binary words as C initializer list of 32-bit ints
+                      num   - List of comma-separated 32-bit hex integers
   -M                Generate make dependencies. Implies -E and -w.
   -MM               An alias for -M.
   -MD               Generate make dependencies and compile.
   -MF <file>        Write dependency output to the given file.
   -MT <target>      Specify the target of the rule emitted by dependency
                     generation.
-  -S                Only run preprocess and compilation steps.
+  -O                Optimize the generated SPIR-V code for better performance.
+  -Os               Optimize the generated SPIR-V code for smaller size.
+  -O0               Disable optimization.
+  -o <file>         Write output to <file>.
+                    A file name of '-' represents standard output.
+  -std=<value>      Version and profile for GLSL input files. Possible values
+                    are concatenations of version and profile, e.g. 310es,
+                    450core, etc.  Ignored for HLSL files.
+  -S                Emit SPIR-V assembly instead of binary.
+  --show-limits     Display available limit names and their default values.
   --target-env=<environment>
-                    Set the target shader environment, and the semantics
-                    of warnings and errors. Valid values are 'opengl',
-                    'opengl_compat' and 'vulkan'. The default value is 'vulkan'.
+                    Set the target client environment, and the semantics
+                    of warnings and errors.  An optional suffix can specify
+                    the client version.  Values are:
+                        vulkan1.0       # The default
+                        vulkan1.1
+                        vulkan1.2
+                        vulkan          # Same as vulkan1.0
+                        opengl4.5
+                        opengl          # Same as opengl4.5
+  --target-spv=<spirv-version>
+                    Set the SPIR-V version to be used for the generated SPIR-V
+                    module.  The default is the highest version of SPIR-V
+                    required to be supported for the target environment.
+                    For example, default for vulkan1.0 is spv1.0, and
+                    the default for vulkan1.1 is spv1.3,
+                    the default for vulkan1.2 is spv1.5.
+                    Values are:
+                        spv1.0, spv1.1, spv1.2, spv1.3, spv1.4, spv1.5
+  --version         Display compiler version information.
   -w                Suppresses all warning messages.
   -Werror           Treat all warnings as errors.
   -x <language>     Treat subsequent input files as having type <language>.
@@ -182,3 +267,96 @@
     expected_stderr = [
         "glslc: error: '-': -fshader-stage required when input is from "
         'standard input "-"\n']
+
+
+@inside_glslc_testsuite('Parameters')
+class LimitsHelp(expect.StdoutMatch, expect.StderrMatch):
+    """Tests --show-limits shows correct output."""
+
+    glslc_args = ['--show-limits']
+
+    expected_stderr = ''
+    expected_stdout = """MaxLights 8
+MaxClipPlanes 6
+MaxTextureUnits 2
+MaxTextureCoords 8
+MaxVertexAttribs 16
+MaxVertexUniformComponents 4096
+MaxVaryingFloats 60
+MaxVertexTextureImageUnits 16
+MaxCombinedTextureImageUnits 80
+MaxTextureImageUnits 16
+MaxFragmentUniformComponents 1024
+MaxDrawBuffers 8
+MaxVertexUniformVectors 256
+MaxVaryingVectors 15
+MaxFragmentUniformVectors 256
+MaxVertexOutputVectors 16
+MaxFragmentInputVectors 15
+MinProgramTexelOffset -8
+MaxProgramTexelOffset 7
+MaxClipDistances 8
+MaxComputeWorkGroupCountX 65535
+MaxComputeWorkGroupCountY 65535
+MaxComputeWorkGroupCountZ 65535
+MaxComputeWorkGroupSizeX 1024
+MaxComputeWorkGroupSizeY 1024
+MaxComputeWorkGroupSizeZ 64
+MaxComputeUniformComponents 512
+MaxComputeTextureImageUnits 16
+MaxComputeImageUniforms 8
+MaxComputeAtomicCounters 8
+MaxComputeAtomicCounterBuffers 1
+MaxVaryingComponents 60
+MaxVertexOutputComponents 64
+MaxGeometryInputComponents 64
+MaxGeometryOutputComponents 128
+MaxFragmentInputComponents 128
+MaxImageUnits 8
+MaxCombinedImageUnitsAndFragmentOutputs 8
+MaxCombinedShaderOutputResources 8
+MaxImageSamples 0
+MaxVertexImageUniforms 0
+MaxTessControlImageUniforms 0
+MaxTessEvaluationImageUniforms 0
+MaxGeometryImageUniforms 0
+MaxFragmentImageUniforms 8
+MaxCombinedImageUniforms 8
+MaxGeometryTextureImageUnits 16
+MaxGeometryOutputVertices 256
+MaxGeometryTotalOutputComponents 1024
+MaxGeometryUniformComponents 512
+MaxGeometryVaryingComponents 60
+MaxTessControlInputComponents 128
+MaxTessControlOutputComponents 128
+MaxTessControlTextureImageUnits 16
+MaxTessControlUniformComponents 1024
+MaxTessControlTotalOutputComponents 4096
+MaxTessEvaluationInputComponents 128
+MaxTessEvaluationOutputComponents 128
+MaxTessEvaluationTextureImageUnits 16
+MaxTessEvaluationUniformComponents 1024
+MaxTessPatchComponents 120
+MaxPatchVertices 32
+MaxTessGenLevel 64
+MaxViewports 16
+MaxVertexAtomicCounters 0
+MaxTessControlAtomicCounters 0
+MaxTessEvaluationAtomicCounters 0
+MaxGeometryAtomicCounters 0
+MaxFragmentAtomicCounters 8
+MaxCombinedAtomicCounters 8
+MaxAtomicCounterBindings 1
+MaxVertexAtomicCounterBuffers 0
+MaxTessControlAtomicCounterBuffers 0
+MaxTessEvaluationAtomicCounterBuffers 0
+MaxGeometryAtomicCounterBuffers 0
+MaxFragmentAtomicCounterBuffers 0
+MaxCombinedAtomicCounterBuffers 1
+MaxAtomicCounterBufferSize 32
+MaxTransformFeedbackBuffers 4
+MaxTransformFeedbackInterleavedComponents 64
+MaxCullDistances 8
+MaxCombinedClipAndCullDistances 8
+MaxSamples 4
+"""
diff --git a/glslc/test/placeholder.py b/glslc/test/placeholder.py
index 8a701bf..4bff75c 100644
--- a/glslc/test/placeholder.py
+++ b/glslc/test/placeholder.py
@@ -23,6 +23,7 @@
 import os
 import tempfile
 from string import Template
+from builtins import bytes
 
 
 class PlaceHolderException(Exception):
@@ -97,7 +98,7 @@
 
     def instantiate_for_glslc_args(self, testcase):
         """Writes the source code back to the TestCase instance."""
-        testcase.stdin_shader = self.source
+        testcase.stdin_shader = bytes(self.source, 'utf-8')
         self.filename = '-'
         return self.filename
 
diff --git a/kokoro/android-release/build.sh b/kokoro/android-release/build.sh
new file mode 100644
index 0000000..0443c8a
--- /dev/null
+++ b/kokoro/android-release/build.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Android Build Script.
+
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+BUILD_ROOT=$PWD
+SRC=$PWD/github/shaderc
+TARGET_ARCH=$1
+
+# Get NINJA.
+wget -q https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-linux.zip
+unzip -q ninja-linux.zip
+NINJA=$PWD/ninja
+
+# Get Android NDK.
+wget -q https://dl.google.com/android/repository/android-ndk-r18b-linux-x86_64.zip
+unzip -q android-ndk-r18b-linux-x86_64.zip
+NDK=$PWD/android-ndk-r18b
+
+cd $SRC
+./utils/git-sync-deps
+
+mkdir build
+cd $SRC/build
+
+# Invoke the build.
+BUILD_SHA=${KOKORO_GITHUB_COMMIT:-$KOKORO_GITHUB_PULL_REQUEST_COMMIT}
+echo $(date): Starting build...
+cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAKE_PROGRAM=$NINJA -DANDROID_ABI=$TARGET_ARCH -DSHADERC_SKIP_TESTS=ON -DSPIRV_SKIP_TESTS=ON -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake -DANDROID_NDK=$NDK ..
+
+echo $(date): Build glslang...
+$NINJA glslangValidator
+
+echo $(date): Build everything...
+$NINJA
+
+echo $(date): Check Shaderc for copyright notices...
+$NINJA check-copyright
+
+echo $(date): Build completed.
diff --git a/kokoro/android-release/build_arm.sh b/kokoro/android-release/build_arm.sh
new file mode 100644
index 0000000..6d43504
--- /dev/null
+++ b/kokoro/android-release/build_arm.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Android Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh "armeabi-v7a with NEON"
diff --git a/kokoro/android-release/build_x86.sh b/kokoro/android-release/build_x86.sh
new file mode 100644
index 0000000..c642ab1
--- /dev/null
+++ b/kokoro/android-release/build_x86.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Android Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh x86
+
diff --git a/kokoro/android-release/continuous_arm.cfg b/kokoro/android-release/continuous_arm.cfg
new file mode 100644
index 0000000..a4f931a
--- /dev/null
+++ b/kokoro/android-release/continuous_arm.cfg
@@ -0,0 +1,17 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+#
+build_file: "shaderc/kokoro/android-release/build_arm.sh"
diff --git a/kokoro/android-release/continuous_x86.cfg b/kokoro/android-release/continuous_x86.cfg
new file mode 100644
index 0000000..a8643d5
--- /dev/null
+++ b/kokoro/android-release/continuous_x86.cfg
@@ -0,0 +1,17 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+#
+build_file: "shaderc/kokoro/android-release/build_x86.sh"
diff --git a/kokoro/android-release/presubmit_arm.cfg b/kokoro/android-release/presubmit_arm.cfg
new file mode 100644
index 0000000..b88294d
--- /dev/null
+++ b/kokoro/android-release/presubmit_arm.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/android-release/build_arm.sh"
diff --git a/kokoro/android-release/presubmit_x86.cfg b/kokoro/android-release/presubmit_x86.cfg
new file mode 100644
index 0000000..590753e
--- /dev/null
+++ b/kokoro/android-release/presubmit_x86.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/android-release/build_x86.sh"
diff --git a/kokoro/img/linux.png b/kokoro/img/linux.png
new file mode 100644
index 0000000..ff066d9
--- /dev/null
+++ b/kokoro/img/linux.png
Binary files differ
diff --git a/kokoro/img/macos.png b/kokoro/img/macos.png
new file mode 100644
index 0000000..d1349c0
--- /dev/null
+++ b/kokoro/img/macos.png
Binary files differ
diff --git a/kokoro/img/windows.png b/kokoro/img/windows.png
new file mode 100644
index 0000000..a378469
--- /dev/null
+++ b/kokoro/img/windows.png
Binary files differ
diff --git a/kokoro/linux/build-docker.sh b/kokoro/linux/build-docker.sh
new file mode 100755
index 0000000..fb65f81
--- /dev/null
+++ b/kokoro/linux/build-docker.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Linux Build Script run inside docker container.
+
+set -e # Fail on any error.
+
+. /bin/using.sh # Declare the bash `using` function for configuring toolchains.
+
+set -x # Display commands being run.
+
+SKIP_TESTS="False"
+BUILD_TYPE="Debug"
+
+using cmake-3.17.2
+using ninja-1.10.0
+
+if [ ! -z "$COMPILER" ]; then
+    using "$COMPILER"
+fi
+
+# Possible configurations are:
+# ASAN, COVERAGE, RELEASE, DEBUG, DEBUG_EXCEPTION, RELEASE_MINGW
+
+if [ $CONFIG = "RELEASE" ] || [ $CONFIG = "RELEASE_MINGW" ]
+then
+  BUILD_TYPE="RelWithDebInfo"
+fi
+
+ADDITIONAL_CMAKE_FLAGS=""
+if [ $CONFIG = "ASAN" ]
+then
+  ADDITIONAL_CMAKE_FLAGS="-DCMAKE_CXX_FLAGS=-fsanitize=address -DCMAKE_C_FLAGS=-fsanitize=address"
+elif [ $CONFIG = "COVERAGE" ]
+then
+  ADDITIONAL_CMAKE_FLAGS="-DENABLE_CODE_COVERAGE=ON"
+  SKIP_TESTS="True"
+elif [ $CONFIG = "DEBUG_EXCEPTION" ]
+then
+  ADDITIONAL_CMAKE_FLAGS="-DDISABLE_EXCEPTIONS=ON -DDISABLE_RTTI=ON"
+elif [ $CONFIG = "RELEASE_MINGW" ]
+then
+  ADDITIONAL_CMAKE_FLAGS="-Dgtest_disable_pthreads=ON -DCMAKE_TOOLCHAIN_FILE=$ROOT_DIR/cmake/linux-mingw-toolchain.cmake"
+  SKIP_TESTS="True"
+fi
+
+cd $ROOT_DIR
+./utils/git-sync-deps
+
+mkdir build
+cd $ROOT_DIR/build
+
+# Invoke the build.
+BUILD_SHA=${KOKORO_GITHUB_COMMIT:-$KOKORO_GITHUB_PULL_REQUEST_COMMIT}
+echo $(date): Starting build...
+cmake -GNinja -DCMAKE_INSTALL_PREFIX=$KOKORO_ARTIFACTS_DIR/install -DSHADERC_ENABLE_SPVC=ON -DRE2_BUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=$BUILD_TYPE $ADDITIONAL_CMAKE_FLAGS ..
+
+echo $(date): Build glslang...
+ninja glslangValidator
+
+echo $(date): Build everything...
+ninja
+echo $(date): Build completed.
+
+echo $(date): Check Shaderc for copyright notices...
+ninja check-copyright
+
+if [ $CONFIG = "COVERAGE" ]
+then
+  echo $(date): Check coverage...
+  ninja report-coverage
+  echo $(date): Check coverage completed.
+fi
+
+echo $(date): Starting ctest...
+if [ $SKIP_TESTS = "False" ]
+then
+  ctest --output-on-failure -j4
+fi
+echo $(date): ctest completed.
+
+# Package the build.
+ninja install
+cd $KOKORO_ARTIFACTS_DIR
+tar czf install.tgz install
diff --git a/kokoro/linux/build.sh b/kokoro/linux/build.sh
new file mode 100755
index 0000000..765a387
--- /dev/null
+++ b/kokoro/linux/build.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# Copyright (C) 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+set -e # Fail on any error.
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )"
+ROOT_DIR="$( cd "${SCRIPT_DIR}/../.." >/dev/null 2>&1 && pwd )"
+
+CONFIG=$1
+COMPILER=$2
+
+docker run --rm -i \
+  --volume "${ROOT_DIR}:${ROOT_DIR}" \
+  --volume "${KOKORO_ARTIFACTS_DIR}:${KOKORO_ARTIFACTS_DIR}" \
+  --workdir "${ROOT_DIR}" \
+  --env ROOT_DIR="${ROOT_DIR}" \
+  --env SCRIPT_DIR="${SCRIPT_DIR}" \
+  --env CONFIG="${CONFIG}" \
+  --env COMPILER="${COMPILER}" \
+  --env KOKORO_ARTIFACTS_DIR="${KOKORO_ARTIFACTS_DIR}" \
+  --entrypoint "${SCRIPT_DIR}/build-docker.sh" \
+  "gcr.io/shaderc-build/radial-build:latest"
diff --git a/kokoro/linux/build_clang_asan.sh b/kokoro/linux/build_clang_asan.sh
new file mode 100755
index 0000000..9110bc5
--- /dev/null
+++ b/kokoro/linux/build_clang_asan.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh ASAN "clang-10.0.0"
diff --git a/kokoro/linux/build_clang_debug.sh b/kokoro/linux/build_clang_debug.sh
new file mode 100755
index 0000000..227237e
--- /dev/null
+++ b/kokoro/linux/build_clang_debug.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh DEBUG "clang-10.0.0"
diff --git a/kokoro/linux/build_clang_release.sh b/kokoro/linux/build_clang_release.sh
new file mode 100755
index 0000000..126f5d4
--- /dev/null
+++ b/kokoro/linux/build_clang_release.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh RELEASE "clang-10.0.0"
diff --git a/kokoro/linux/build_gcc_coverage.sh b/kokoro/linux/build_gcc_coverage.sh
new file mode 100755
index 0000000..7270334
--- /dev/null
+++ b/kokoro/linux/build_gcc_coverage.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh COVERAGE "gcc-7" # gcc-8+ has issues with lcov
diff --git a/kokoro/linux/build_gcc_debug.sh b/kokoro/linux/build_gcc_debug.sh
new file mode 100755
index 0000000..3a96cf7
--- /dev/null
+++ b/kokoro/linux/build_gcc_debug.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh DEBUG "gcc-9"
diff --git a/kokoro/linux/build_gcc_debug_exception.sh b/kokoro/linux/build_gcc_debug_exception.sh
new file mode 100755
index 0000000..9849336
--- /dev/null
+++ b/kokoro/linux/build_gcc_debug_exception.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh DEBUG_EXCEPTION "gcc-9"
diff --git a/kokoro/linux/build_gcc_release.sh b/kokoro/linux/build_gcc_release.sh
new file mode 100755
index 0000000..9123604
--- /dev/null
+++ b/kokoro/linux/build_gcc_release.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh RELEASE "gcc-9"
diff --git a/kokoro/linux/build_mingw_release.sh b/kokoro/linux/build_mingw_release.sh
new file mode 100755
index 0000000..0b54dc6
--- /dev/null
+++ b/kokoro/linux/build_mingw_release.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh RELEASE_MINGW
diff --git a/kokoro/linux/continuous_clang_asan.cfg b/kokoro/linux/continuous_clang_asan.cfg
new file mode 100644
index 0000000..1291151
--- /dev/null
+++ b/kokoro/linux/continuous_clang_asan.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/linux/build_clang_asan.sh"
diff --git a/kokoro/linux/continuous_clang_debug.cfg b/kokoro/linux/continuous_clang_debug.cfg
new file mode 100644
index 0000000..1021c44
--- /dev/null
+++ b/kokoro/linux/continuous_clang_debug.cfg
@@ -0,0 +1,22 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/linux/build_clang_debug.sh"
+
+action {
+  define_artifacts {
+    regex: "install.tgz"
+  }
+}
diff --git a/kokoro/linux/continuous_clang_release.cfg b/kokoro/linux/continuous_clang_release.cfg
new file mode 100644
index 0000000..cffba60
--- /dev/null
+++ b/kokoro/linux/continuous_clang_release.cfg
@@ -0,0 +1,22 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/linux/build_clang_release.sh"
+
+action {
+  define_artifacts {
+    regex: "install.tgz"
+  }
+}
diff --git a/kokoro/linux/continuous_gcc_coverage.cfg b/kokoro/linux/continuous_gcc_coverage.cfg
new file mode 100644
index 0000000..ab2878c
--- /dev/null
+++ b/kokoro/linux/continuous_gcc_coverage.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/linux/build_gcc_coverage.sh"
diff --git a/kokoro/linux/continuous_gcc_debug.cfg b/kokoro/linux/continuous_gcc_debug.cfg
new file mode 100644
index 0000000..526f08f
--- /dev/null
+++ b/kokoro/linux/continuous_gcc_debug.cfg
@@ -0,0 +1,22 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/linux/build_gcc_debug.sh"
+
+action {
+  define_artifacts {
+    regex: "install.tgz"
+  }
+}
diff --git a/kokoro/linux/continuous_gcc_debug_exception.cfg b/kokoro/linux/continuous_gcc_debug_exception.cfg
new file mode 100644
index 0000000..cecd155
--- /dev/null
+++ b/kokoro/linux/continuous_gcc_debug_exception.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/linux/build_gcc_debug_exception.sh"
diff --git a/kokoro/linux/continuous_gcc_release.cfg b/kokoro/linux/continuous_gcc_release.cfg
new file mode 100644
index 0000000..8e0cde8
--- /dev/null
+++ b/kokoro/linux/continuous_gcc_release.cfg
@@ -0,0 +1,22 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/linux/build_gcc_release.sh"
+
+action {
+  define_artifacts {
+    regex: "install.tgz"
+  }
+}
diff --git a/kokoro/linux/continuous_license_check.cfg b/kokoro/linux/continuous_license_check.cfg
new file mode 100644
index 0000000..066a4d3
--- /dev/null
+++ b/kokoro/linux/continuous_license_check.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/linux/license_check.sh"
diff --git a/kokoro/linux/continuous_mingw_release.cfg b/kokoro/linux/continuous_mingw_release.cfg
new file mode 100644
index 0000000..a0d4e76
--- /dev/null
+++ b/kokoro/linux/continuous_mingw_release.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/linux/build_mingw_release.sh"
diff --git a/kokoro/linux/license_check.sh b/kokoro/linux/license_check.sh
new file mode 100755
index 0000000..a36e4ff
--- /dev/null
+++ b/kokoro/linux/license_check.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Copyright (C) 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e # Fail on any error.
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )"
+ROOT_DIR="$( cd "${SCRIPT_DIR}/../.." >/dev/null 2>&1 && pwd )"
+
+docker run --rm -i \
+  --volume "${ROOT_DIR}:${ROOT_DIR}:ro" \
+  --workdir "${ROOT_DIR}" \
+  --env ROOT_DIR="${ROOT_DIR}" \
+  --env SCRIPT_DIR="${SCRIPT_DIR}" \
+  --entrypoint "${SCRIPT_DIR}/license_check_docker.sh" \
+  "gcr.io/shaderc-build/radial-build:latest"
diff --git a/kokoro/linux/license_check_docker.sh b/kokoro/linux/license_check_docker.sh
new file mode 100755
index 0000000..f88077e
--- /dev/null
+++ b/kokoro/linux/license_check_docker.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Copyright (C) 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e # Fail on any error.
+set -x # Display commands being run.
+
+license-checker --dir="$ROOT_DIR"
\ No newline at end of file
diff --git a/kokoro/linux/presubmit_clang_asan.cfg b/kokoro/linux/presubmit_clang_asan.cfg
new file mode 100644
index 0000000..fcaaa36
--- /dev/null
+++ b/kokoro/linux/presubmit_clang_asan.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/linux/build_clang_asan.sh"
diff --git a/kokoro/linux/presubmit_clang_debug.cfg b/kokoro/linux/presubmit_clang_debug.cfg
new file mode 100644
index 0000000..87abaf7
--- /dev/null
+++ b/kokoro/linux/presubmit_clang_debug.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/linux/build_clang_debug.sh"
diff --git a/kokoro/linux/presubmit_clang_release.cfg b/kokoro/linux/presubmit_clang_release.cfg
new file mode 100644
index 0000000..81ba77d
--- /dev/null
+++ b/kokoro/linux/presubmit_clang_release.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/linux/build_clang_release.sh"
diff --git a/kokoro/linux/presubmit_gcc_coverage.cfg b/kokoro/linux/presubmit_gcc_coverage.cfg
new file mode 100644
index 0000000..54733b0
--- /dev/null
+++ b/kokoro/linux/presubmit_gcc_coverage.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/linux/build_gcc_coverage.sh"
diff --git a/kokoro/linux/presubmit_gcc_debug.cfg b/kokoro/linux/presubmit_gcc_debug.cfg
new file mode 100644
index 0000000..f0eec27
--- /dev/null
+++ b/kokoro/linux/presubmit_gcc_debug.cfg
@@ -0,0 +1,17 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/linux/build_gcc_debug.sh"
+
diff --git a/kokoro/linux/presubmit_gcc_release.cfg b/kokoro/linux/presubmit_gcc_release.cfg
new file mode 100644
index 0000000..fda4333
--- /dev/null
+++ b/kokoro/linux/presubmit_gcc_release.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/linux/build_gcc_release.sh"
diff --git a/kokoro/linux/presubmit_license_check.cfg b/kokoro/linux/presubmit_license_check.cfg
new file mode 100644
index 0000000..38db8f5
--- /dev/null
+++ b/kokoro/linux/presubmit_license_check.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/linux/license_check.sh"
diff --git a/kokoro/macos/build.sh b/kokoro/macos/build.sh
new file mode 100644
index 0000000..ff2d38c
--- /dev/null
+++ b/kokoro/macos/build.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# MacOS Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+BUILD_ROOT=$PWD
+SRC=$PWD/github/shaderc
+BUILD_TYPE=$1
+
+# Get NINJA.
+wget -q https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-mac.zip
+unzip -q ninja-mac.zip
+chmod +x ninja
+export PATH="$PWD:$PATH"
+
+cd $SRC
+./utils/git-sync-deps
+
+mkdir build
+cd $SRC/build
+
+# Invoke the build.
+BUILD_SHA=${KOKORO_GITHUB_COMMIT:-$KOKORO_GITHUB_PULL_REQUEST_COMMIT}
+echo $(date): Starting build...
+cmake -GNinja -DCMAKE_INSTALL_PREFIX=$KOKORO_ARTIFACTS_DIR/install -DSHADERC_ENABLE_SPVC=ON -DRE2_BUILD_TESTING=OFF -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=$BUILD_TYPE ..
+
+echo $(date): Build glslang...
+ninja glslangValidator
+
+echo $(date): Build everything...
+ninja
+
+echo $(date): Check Shaderc for copyright notices...
+ninja check-copyright
+
+echo $(date): Build completed.
+
+echo $(date): Starting ctest...
+ctest --output-on-failure -j4
+echo $(date): ctest completed.
+
+# Package the build.
+ninja install
+cd $KOKORO_ARTIFACTS_DIR
+tar czf install.tgz install
diff --git a/kokoro/macos/build_clang_debug.sh b/kokoro/macos/build_clang_debug.sh
new file mode 100644
index 0000000..ed889ff
--- /dev/null
+++ b/kokoro/macos/build_clang_debug.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# MacOS Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh Debug
+
diff --git a/kokoro/macos/build_clang_release.sh b/kokoro/macos/build_clang_release.sh
new file mode 100644
index 0000000..9599bac
--- /dev/null
+++ b/kokoro/macos/build_clang_release.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# MacOS Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh RelWithDebInfo
+
diff --git a/kokoro/macos/continuous_clang_debug.cfg b/kokoro/macos/continuous_clang_debug.cfg
new file mode 100644
index 0000000..d8000a9
--- /dev/null
+++ b/kokoro/macos/continuous_clang_debug.cfg
@@ -0,0 +1,22 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/macos/build_clang_debug.sh"
+
+action {
+  define_artifacts {
+    regex: "install.tgz"
+  }
+}
diff --git a/kokoro/macos/continuous_clang_release.cfg b/kokoro/macos/continuous_clang_release.cfg
new file mode 100644
index 0000000..101d06e
--- /dev/null
+++ b/kokoro/macos/continuous_clang_release.cfg
@@ -0,0 +1,22 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/macos/build_clang_release.sh"
+
+action {
+  define_artifacts {
+    regex: "install.tgz"
+  }
+}
diff --git a/kokoro/macos/presubmit_clang_debug.cfg b/kokoro/macos/presubmit_clang_debug.cfg
new file mode 100644
index 0000000..d2748ae
--- /dev/null
+++ b/kokoro/macos/presubmit_clang_debug.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/macos/build_clang_debug.sh"
diff --git a/kokoro/macos/presubmit_clang_release.cfg b/kokoro/macos/presubmit_clang_release.cfg
new file mode 100644
index 0000000..3041155
--- /dev/null
+++ b/kokoro/macos/presubmit_clang_release.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/macos/build_clang_release.sh"
diff --git a/kokoro/ndk-build/build.sh b/kokoro/ndk-build/build.sh
new file mode 100644
index 0000000..edf361c
--- /dev/null
+++ b/kokoro/ndk-build/build.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+BUILD_ROOT=$PWD
+SRC=$PWD/github/shaderc
+
+# Get NINJA.
+wget -q https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-linux.zip
+unzip -q ninja-linux.zip
+export PATH="$PWD:$PATH"
+
+# Get Android NDK.
+wget -q https://dl.google.com/android/repository/android-ndk-r18b-linux-x86_64.zip
+unzip -q android-ndk-r18b-linux-x86_64.zip
+export ANDROID_NDK=$PWD/android-ndk-r18b
+
+# Get shaderc dependencies.
+cd $SRC
+./utils/git-sync-deps
+
+cd $SRC
+mkdir build
+cd $SRC/build
+
+# Invoke the build.
+BUILD_SHA=${KOKORO_GITHUB_COMMIT:-$KOKORO_GITHUB_PULL_REQUEST_COMMIT}
+echo $(date): Starting ndk-build ...
+$ANDROID_NDK/ndk-build \
+  -C $SRC/android_test \
+  NDK_APP_OUT=`pwd` \
+  V=1 \
+  SPVTOOLS_LOCAL_PATH=$SRC/third_party/spirv-tools \
+  SPVHEADERS_LOCAL_PATH=$SRC/third_party/spirv-headers \
+  -j 8
+
+echo $(date): ndk-build completed.
diff --git a/kokoro/ndk-build/build_khronos.sh b/kokoro/ndk-build/build_khronos.sh
new file mode 100644
index 0000000..b84052d
--- /dev/null
+++ b/kokoro/ndk-build/build_khronos.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Linux Build Script.
+
+# Fail on any error.
+set -e
+# Display commands being run.
+set -x
+
+SCRIPT_DIR=`dirname "$BASH_SOURCE"`
+source $SCRIPT_DIR/build.sh
diff --git a/kokoro/ndk-build/continuous_khronos.cfg b/kokoro/ndk-build/continuous_khronos.cfg
new file mode 100644
index 0000000..4821383
--- /dev/null
+++ b/kokoro/ndk-build/continuous_khronos.cfg
@@ -0,0 +1,17 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+#
+build_file: "shaderc/kokoro/ndk-build/build_khronos.sh"
diff --git a/kokoro/ndk-build/presubmit_khronos.cfg b/kokoro/ndk-build/presubmit_khronos.cfg
new file mode 100644
index 0000000..854a5d0
--- /dev/null
+++ b/kokoro/ndk-build/presubmit_khronos.cfg
@@ -0,0 +1,17 @@
+# Copyright (C) 2018 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+#
+build_file: "shaderc/kokoro/ndk-build/build_khronos.sh"
diff --git a/kokoro/windows/build.bat b/kokoro/windows/build.bat
new file mode 100644
index 0000000..077caef
--- /dev/null
+++ b/kokoro/windows/build.bat
@@ -0,0 +1,97 @@
+:: Copyright (C) 2017 Google Inc.
+::
+:: Licensed under the Apache License, Version 2.0 (the "License");
+:: you may not use this file except in compliance with the License.
+:: You may obtain a copy of the License at
+::
+::     http://www.apache.org/licenses/LICENSE-2.0
+::
+:: Unless required by applicable law or agreed to in writing, software
+:: distributed under the License is distributed on an "AS IS" BASIS,
+:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+:: See the License for the specific language governing permissions and
+:: limitations under the License.
+::
+:: Windows Build Script.
+
+@echo on
+
+set BUILD_ROOT=%cd%
+set SRC=%cd%\github\shaderc
+set BUILD_TYPE=%1
+set VS_VERSION=%2
+
+:: Force usage of python 3.6.
+set PATH=C:\python36;%PATH%
+
+cd %SRC%
+python utils\git-sync-deps
+
+cmake --version
+
+mkdir build
+cd %SRC%\build
+
+:: #########################################
+:: set up msvc build env
+:: #########################################
+if %VS_VERSION% == 2017 (
+  call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
+  echo "Using VS 2017..."
+) else if %VS_VERSION% == 2015 (
+  call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
+  echo "Using VS 2015..."
+)
+
+:: #########################################
+:: Start building.
+:: #########################################
+echo "Starting build... %DATE% %TIME%"
+if "%KOKORO_GITHUB_COMMIT%." == "." (
+  set BUILD_SHA=%KOKORO_GITHUB_PULL_REQUEST_COMMIT%
+) else (
+  set BUILD_SHA=%KOKORO_GITHUB_COMMIT%
+)
+
+set CMAKE_FLAGS=-DCMAKE_INSTALL_PREFIX=%KOKORO_ARTIFACTS_DIR%\install -DSHADERC_ENABLE_SPVC=ON -DRE2_BUILD_TESTING=OFF -GNinja -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_C_COMPILER=cl.exe -DCMAKE_CXX_COMPILER=cl.exe
+
+cmake %CMAKE_FLAGS% ..
+if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
+
+echo "Build glslang... %DATE% %TIME%"
+ninja glslangValidator
+if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
+
+echo "Build everything... %DATE% %TIME%"
+ninja
+if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
+
+echo "Check Shaderc for copyright notices... %DATE% %TIME%"
+ninja check-copyright
+if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
+echo "Build Completed %DATE% %TIME%"
+
+:: This lets us use !ERRORLEVEL! inside an IF ... () and get the actual error at that point.
+setlocal ENABLEDELAYEDEXPANSION
+
+:: ################################################
+:: Run the tests
+:: ################################################
+echo "Running tests... %DATE% %TIME%"
+ctest -C %BUILD_TYPE% --output-on-failure -j4
+if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL!
+echo "Tests passed %DATE% %TIME%"
+
+:: ################################################
+:: Install and package.
+:: ################################################
+ninja install
+cd %KOKORO_ARTIFACTS_DIR%
+zip -r install.zip install
+
+:: Clean up some directories.
+rm -rf %SRC%\build
+rm -rf %SRC%\install
+rm -rf %SRC%\third_party
+
+exit /b 0
diff --git a/kokoro/windows/build_debug_2017.bat b/kokoro/windows/build_debug_2017.bat
new file mode 100644
index 0000000..c1ecf87
--- /dev/null
+++ b/kokoro/windows/build_debug_2017.bat
@@ -0,0 +1,23 @@
+:: Copyright (C) 2017 Google Inc.
+::
+:: Licensed under the Apache License, Version 2.0 (the "License");
+:: you may not use this file except in compliance with the License.
+:: You may obtain a copy of the License at
+::
+::     http://www.apache.org/licenses/LICENSE-2.0
+::
+:: Unless required by applicable law or agreed to in writing, software
+:: distributed under the License is distributed on an "AS IS" BASIS,
+:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+:: See the License for the specific language governing permissions and
+:: limitations under the License.
+::
+:: Windows Build Script.
+
+@echo on
+
+:: Find out the directory of the common build script.
+set SCRIPT_DIR=%~dp0
+
+:: Call with correct parameter
+call %SCRIPT_DIR%\build.bat Debug 2017
diff --git a/kokoro/windows/build_release_2015.bat b/kokoro/windows/build_release_2015.bat
new file mode 100644
index 0000000..ea156fe
--- /dev/null
+++ b/kokoro/windows/build_release_2015.bat
@@ -0,0 +1,24 @@
+:: Copyright (C) 2017 Google Inc.
+::
+:: Licensed under the Apache License, Version 2.0 (the "License");
+:: you may not use this file except in compliance with the License.
+:: You may obtain a copy of the License at
+::
+::     http://www.apache.org/licenses/LICENSE-2.0
+::
+:: Unless required by applicable law or agreed to in writing, software
+:: distributed under the License is distributed on an "AS IS" BASIS,
+:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+:: See the License for the specific language governing permissions and
+:: limitations under the License.
+::
+:: Windows Build Script.
+
+@echo on
+
+:: Find out the directory of the common build script.
+set SCRIPT_DIR=%~dp0
+
+:: Call with correct parameter
+call %SCRIPT_DIR%\build.bat RelWithDebInfo 2015
+
diff --git a/kokoro/windows/build_release_2017.bat b/kokoro/windows/build_release_2017.bat
new file mode 100644
index 0000000..4102eaa
--- /dev/null
+++ b/kokoro/windows/build_release_2017.bat
@@ -0,0 +1,24 @@
+:: Copyright (C) 2017 Google Inc.
+::
+:: Licensed under the Apache License, Version 2.0 (the "License");
+:: you may not use this file except in compliance with the License.
+:: You may obtain a copy of the License at
+::
+::     http://www.apache.org/licenses/LICENSE-2.0
+::
+:: Unless required by applicable law or agreed to in writing, software
+:: distributed under the License is distributed on an "AS IS" BASIS,
+:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+:: See the License for the specific language governing permissions and
+:: limitations under the License.
+::
+:: Windows Build Script.
+
+@echo on
+
+:: Find out the directory of the common build script.
+set SCRIPT_DIR=%~dp0
+
+:: Call with correct parameter
+call %SCRIPT_DIR%\build.bat RelWithDebInfo 2017
+
diff --git a/kokoro/windows/continuous_debug_2017.cfg b/kokoro/windows/continuous_debug_2017.cfg
new file mode 100644
index 0000000..34c3b06
--- /dev/null
+++ b/kokoro/windows/continuous_debug_2017.cfg
@@ -0,0 +1,22 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/windows/build_debug_2017.bat"
+
+action {
+  define_artifacts {
+    regex: "install.zip"
+  }
+}
diff --git a/kokoro/windows/continuous_release_2015.cfg b/kokoro/windows/continuous_release_2015.cfg
new file mode 100644
index 0000000..9017c86
--- /dev/null
+++ b/kokoro/windows/continuous_release_2015.cfg
@@ -0,0 +1,22 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/windows/build_release_2015.bat"
+
+action {
+  define_artifacts {
+    regex: "install.zip"
+  }
+}
diff --git a/kokoro/windows/continuous_release_2017.cfg b/kokoro/windows/continuous_release_2017.cfg
new file mode 100644
index 0000000..b3249d4
--- /dev/null
+++ b/kokoro/windows/continuous_release_2017.cfg
@@ -0,0 +1,22 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Continuous build configuration.
+build_file: "shaderc/kokoro/windows/build_release_2017.bat"
+
+action {
+  define_artifacts {
+    regex: "install.zip"
+  }
+}
diff --git a/kokoro/windows/presubmit_debug_2017.cfg b/kokoro/windows/presubmit_debug_2017.cfg
new file mode 100644
index 0000000..57168d3
--- /dev/null
+++ b/kokoro/windows/presubmit_debug_2017.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/windows/build_debug_2017.bat"
diff --git a/kokoro/windows/presubmit_release_2015.cfg b/kokoro/windows/presubmit_release_2015.cfg
new file mode 100644
index 0000000..bd24415
--- /dev/null
+++ b/kokoro/windows/presubmit_release_2015.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/windows/build_release_2015.bat"
diff --git a/kokoro/windows/presubmit_release_2017.cfg b/kokoro/windows/presubmit_release_2017.cfg
new file mode 100644
index 0000000..16499fc
--- /dev/null
+++ b/kokoro/windows/presubmit_release_2017.cfg
@@ -0,0 +1,16 @@
+# Copyright (C) 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Presubmit build configuration.
+build_file: "shaderc/kokoro/windows/build_release_2017.bat"
diff --git a/libshaderc/.clang-format b/libshaderc/.clang-format
deleted file mode 100644
index e209e8c..0000000
--- a/libshaderc/.clang-format
+++ /dev/null
@@ -1,5 +0,0 @@
----
-# Use Google code formatting rules.
-Language: Cpp
-BasedOnStyle: Google
-...
diff --git a/libshaderc/Android.mk b/libshaderc/Android.mk
index 13d5057..294af69 100644
--- a/libshaderc/Android.mk
+++ b/libshaderc/Android.mk
@@ -1,3 +1,17 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
@@ -5,9 +19,11 @@
 LOCAL_MODULE:=shaderc
 LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)/include
 LOCAL_SRC_FILES:=src/shaderc.cc
-LOCAL_C_INCLUDES:=$(LOCAL_PATH)/include
+# The Shaderc third_party/Android.mk deduces SPVHEADERS_LOCAL_PATH,
+# or delegates that responsibility to SPIRV-Tools' Android.mk.
+LOCAL_C_INCLUDES:=$(LOCAL_PATH)/include $(SPVHEADERS_LOCAL_PATH)/include
 LOCAL_STATIC_LIBRARIES:=shaderc_util SPIRV-Tools-opt
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti
+LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -DENABLE_HLSL=1
 LOCAL_EXPORT_CPPFLAGS:=-std=c++11
 LOCAL_EXPORT_LDFLAGS:=-latomic
 include $(BUILD_STATIC_LIBRARY)
diff --git a/libshaderc/CMakeLists.txt b/libshaderc/CMakeLists.txt
index 888c858..3ada419 100644
--- a/libshaderc/CMakeLists.txt
+++ b/libshaderc/CMakeLists.txt
@@ -1,40 +1,123 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 project(libshaderc)
 
 # Even though shaderc.hpp is a headers-only library, adding
 # a dependency here will force clients of the library to rebuild
 # when it changes.
-add_library(shaderc STATIC
+set(SHADERC_SOURCES
   include/shaderc/shaderc.h
   include/shaderc/shaderc.hpp
   src/shaderc.cc
   src/shaderc_private.h
 )
 
+add_library(shaderc STATIC ${SHADERC_SOURCES})
 shaderc_default_compile_options(shaderc)
-target_include_directories(shaderc PUBLIC include PRIVATE ${glslang_SOURCE_DIR})
-find_package(Threads)
-target_link_libraries(shaderc PRIVATE
-  glslang OSDependent OGLCompiler glslang ${CMAKE_THREAD_LIBS_INIT})
-target_link_libraries(shaderc PRIVATE shaderc_util)
-target_link_libraries(shaderc PRIVATE SPIRV)  # from glslang
-target_link_libraries(shaderc PRIVATE SPIRV-Tools)
+target_include_directories(shaderc
+    PUBLIC include
+    PRIVATE ${glslang_SOURCE_DIR}
+            ${SPIRV-Headers_SOURCE_DIR}/include)
 
+add_library(shaderc_shared SHARED ${SHADERC_SOURCES})
+shaderc_default_compile_options(shaderc_shared)
+target_include_directories(shaderc_shared
+    PUBLIC include
+    PRIVATE ${glslang_SOURCE_DIR}
+            ${SPIRV-Headers_SOURCE_DIR}/include)
+target_compile_definitions(shaderc_shared
+    PRIVATE SHADERC_IMPLEMENTATION
+    PUBLIC SHADERC_SHAREDLIB
+)
+set_target_properties(shaderc_shared PROPERTIES SOVERSION 1)
+
+if(SHADERC_ENABLE_INSTALL)
+  install(
+    FILES
+      include/shaderc/env.h
+      include/shaderc/status.h
+      include/shaderc/visibility.h
+      include/shaderc/shaderc.h
+      include/shaderc/shaderc.hpp
+    DESTINATION
+      ${CMAKE_INSTALL_INCLUDEDIR}/shaderc)
+
+  install(TARGETS shaderc shaderc_shared
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+endif(SHADERC_ENABLE_INSTALL)
+
+find_package(Threads)
+set(SHADERC_LIBS
+  glslang OSDependent OGLCompiler glslang ${CMAKE_THREAD_LIBS_INIT}
+  shaderc_util
+  SPIRV # from glslang
+  SPIRV-Tools
+)
+
+target_link_libraries(shaderc PRIVATE ${SHADERC_LIBS})
+target_link_libraries(shaderc_shared PRIVATE ${SHADERC_LIBS})
 
 shaderc_add_tests(
   TEST_PREFIX shaderc
   LINK_LIBS shaderc
-  INCLUDE_DIRS include ${glslang_SOURCE_DIR} ${spirv-tools_SOURCE_DIR}/include
+  INCLUDE_DIRS include ${shaderc_SOURCE_DIR}/libshaderc_util/include ${glslang_SOURCE_DIR}
+               ${spirv-tools_SOURCE_DIR}/include
+               ${SPIRV-Headers_SOURCE_DIR}/include
   TEST_NAMES
     shaderc
-    shaderc_cpp)
+    shaderc_cpp
+    shaderc_private)
 
+shaderc_add_tests(
+  TEST_PREFIX shaderc_shared
+  LINK_LIBS shaderc_shared SPIRV-Tools
+  INCLUDE_DIRS include ${shaderc_SOURCE_DIR}/libshaderc_util/include ${glslang_SOURCE_DIR}
+               ${spirv-tools_SOURCE_DIR}/include
+               ${SPIRV-Headers_SOURCE_DIR}/include
+  TEST_NAMES
+    shaderc
+    shaderc_cpp
+    shaderc_private)
 
 shaderc_combine_static_lib(shaderc_combined shaderc)
 
+if(SHADERC_ENABLE_INSTALL)
+  # Since shaderc_combined is defined as an imported library, we cannot use the
+  # install() directive to install it. Install it like a normal file.
+  get_target_property(generated_location shaderc_combined LOCATION)
+  string(REGEX MATCH "Visual Studio .*" vs_generator "${CMAKE_GENERATOR}")
+  if (NOT "${vs_generator}" STREQUAL "")
+    # With Visual Studio generators, the LOCATION property is not properly
+    # expanded according to the current build configuration. We need to work
+    # around this problem by manually substitution.
+    string(REPLACE "$(Configuration)" "\${CMAKE_INSTALL_CONFIG_NAME}"
+      install_location "${generated_location}")
+    install(FILES ${install_location} DESTINATION ${CMAKE_INSTALL_LIBDIR})
+  else()
+    install(FILES ${generated_location} DESTINATION ${CMAKE_INSTALL_LIBDIR})
+  endif()
+endif(SHADERC_ENABLE_INSTALL)
+
 shaderc_add_tests(
   TEST_PREFIX shaderc_combined
   LINK_LIBS shaderc_combined ${CMAKE_THREAD_LIBS_INIT}
-  INCLUDE_DIRS include ${glslang_SOURCE_DIR} ${spirv-tools_SOURCE_DIR}/include
+  INCLUDE_DIRS include ${shaderc_SOURCE_DIR}/libshaderc_util/include ${glslang_SOURCE_DIR}
+               ${spirv-tools_SOURCE_DIR}/include
+               ${SPIRV-Headers_SOURCE_DIR}/include
   TEST_NAMES
     shaderc
     shaderc_cpp)
@@ -42,6 +125,7 @@
 if(${SHADERC_ENABLE_TESTS})
   add_executable(shaderc_c_smoke_test ./src/shaderc_c_smoke_test.c)
   shaderc_default_c_compile_options(shaderc_c_smoke_test)
+  target_include_directories(shaderc_c_smoke_test PUBLIC ${shaderc_SOURCE_DIR}/libshaderc_util/include)
   target_link_libraries(shaderc_c_smoke_test PRIVATE shaderc)
   add_test(NAME shaderc_c_smoke_test COMMAND shaderc_c_smoke_test)
 endif()
diff --git a/libshaderc/include/shaderc/env.h b/libshaderc/include/shaderc/env.h
new file mode 100644
index 0000000..5285b9e
--- /dev/null
+++ b/libshaderc/include/shaderc/env.h
@@ -0,0 +1,70 @@
+// Copyright 2018 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SHADERC_ENV_H_
+#define SHADERC_ENV_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+  shaderc_target_env_vulkan,  // SPIR-V under Vulkan semantics
+  shaderc_target_env_opengl,  // SPIR-V under OpenGL semantics
+  // NOTE: SPIR-V code generation is not supported for shaders under OpenGL
+  // compatibility profile.
+  shaderc_target_env_opengl_compat,  // SPIR-V under OpenGL semantics,
+                                     // including compatibility profile
+                                     // functions
+  shaderc_target_env_webgpu,         // Deprecated, SPIR-V under WebGPU
+                                     // semantics
+  shaderc_target_env_default = shaderc_target_env_vulkan
+} shaderc_target_env;
+
+typedef enum {
+  // For Vulkan, use Vulkan's mapping of version numbers to integers.
+  // See vulkan.h
+  shaderc_env_version_vulkan_1_0 = ((1u << 22)),
+  shaderc_env_version_vulkan_1_1 = ((1u << 22) | (1 << 12)),
+  shaderc_env_version_vulkan_1_2 = ((1u << 22) | (2 << 12)),
+  // For OpenGL, use the number from #version in shaders.
+  // TODO(dneto): Currently no difference between OpenGL 4.5 and 4.6.
+  // See glslang/Standalone/Standalone.cpp
+  // TODO(dneto): Glslang doesn't accept a OpenGL client version of 460.
+  shaderc_env_version_opengl_4_5 = 450,
+  shaderc_env_version_webgpu,  // Deprecated, WebGPU env never defined versions
+} shaderc_env_version;
+
+// The known versions of SPIR-V.
+typedef enum {
+  // Use the values used for word 1 of a SPIR-V binary:
+  // - bits 24 to 31: zero
+  // - bits 16 to 23: major version number
+  // - bits 8 to 15: minor version number
+  // - bits 0 to 7: zero
+  shaderc_spirv_version_1_0 = 0x010000u,
+  shaderc_spirv_version_1_1 = 0x010100u,
+  shaderc_spirv_version_1_2 = 0x010200u,
+  shaderc_spirv_version_1_3 = 0x010300u,
+  shaderc_spirv_version_1_4 = 0x010400u,
+  shaderc_spirv_version_1_5 = 0x010500u
+} shaderc_spirv_version;
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // SHADERC_ENV_H_
diff --git a/libshaderc/include/shaderc/shaderc.h b/libshaderc/include/shaderc/shaderc.h
index 26d5421..54a9f65 100644
--- a/libshaderc/include/shaderc/shaderc.h
+++ b/libshaderc/include/shaderc/shaderc.h
@@ -23,6 +23,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "shaderc/env.h"
+#include "shaderc/status.h"
+#include "shaderc/visibility.h"
+
 // Source language kind.
 typedef enum {
   shaderc_source_language_glsl,
@@ -32,12 +36,20 @@
 typedef enum {
   // Forced shader kinds. These shader kinds force the compiler to compile the
   // source code as the specified kind of shader.
-  shaderc_glsl_vertex_shader,
-  shaderc_glsl_fragment_shader,
-  shaderc_glsl_compute_shader,
-  shaderc_glsl_geometry_shader,
-  shaderc_glsl_tess_control_shader,
-  shaderc_glsl_tess_evaluation_shader,
+  shaderc_vertex_shader,
+  shaderc_fragment_shader,
+  shaderc_compute_shader,
+  shaderc_geometry_shader,
+  shaderc_tess_control_shader,
+  shaderc_tess_evaluation_shader,
+
+  shaderc_glsl_vertex_shader = shaderc_vertex_shader,
+  shaderc_glsl_fragment_shader = shaderc_fragment_shader,
+  shaderc_glsl_compute_shader = shaderc_compute_shader,
+  shaderc_glsl_geometry_shader = shaderc_geometry_shader,
+  shaderc_glsl_tess_control_shader = shaderc_tess_control_shader,
+  shaderc_glsl_tess_evaluation_shader = shaderc_tess_evaluation_shader,
+
   // Deduce the shader kind from #pragma annotation in the source code. Compiler
   // will emit error if #pragma annotation is not found.
   shaderc_glsl_infer_from_source,
@@ -51,18 +63,33 @@
   shaderc_glsl_default_tess_control_shader,
   shaderc_glsl_default_tess_evaluation_shader,
   shaderc_spirv_assembly,
+  shaderc_raygen_shader,
+  shaderc_anyhit_shader,
+  shaderc_closesthit_shader,
+  shaderc_miss_shader,
+  shaderc_intersection_shader,
+  shaderc_callable_shader,
+  shaderc_glsl_raygen_shader = shaderc_raygen_shader,
+  shaderc_glsl_anyhit_shader = shaderc_anyhit_shader,
+  shaderc_glsl_closesthit_shader = shaderc_closesthit_shader,
+  shaderc_glsl_miss_shader = shaderc_miss_shader,
+  shaderc_glsl_intersection_shader = shaderc_intersection_shader,
+  shaderc_glsl_callable_shader = shaderc_callable_shader,
+  shaderc_glsl_default_raygen_shader,
+  shaderc_glsl_default_anyhit_shader,
+  shaderc_glsl_default_closesthit_shader,
+  shaderc_glsl_default_miss_shader,
+  shaderc_glsl_default_intersection_shader,
+  shaderc_glsl_default_callable_shader,
+  shaderc_task_shader,
+  shaderc_mesh_shader,
+  shaderc_glsl_task_shader = shaderc_task_shader,
+  shaderc_glsl_mesh_shader = shaderc_mesh_shader,
+  shaderc_glsl_default_task_shader,
+  shaderc_glsl_default_mesh_shader,
 } shaderc_shader_kind;
 
 typedef enum {
-  shaderc_target_env_vulkan,         // create SPIR-V under Vulkan semantics
-  shaderc_target_env_opengl,         // create SPIR-V under OpenGL semantics
-  shaderc_target_env_opengl_compat,  // create SPIR-V under OpenGL semantics,
-                                     // including compatibility profile
-                                     // functions
-  shaderc_target_env_default = shaderc_target_env_vulkan
-} shaderc_target_env;
-
-typedef enum {
   shaderc_profile_none,  // Used if and only if GLSL version did not specify
                          // profiles.
   shaderc_profile_core,
@@ -70,20 +97,11 @@
   shaderc_profile_es,
 } shaderc_profile;
 
-// Indicate the status of a compilation.
-typedef enum {
-  shaderc_compilation_status_success = 0,
-  shaderc_compilation_status_invalid_stage,  // error stage deduction
-  shaderc_compilation_status_compilation_error,
-  shaderc_compilation_status_internal_error,  // unexpected failure
-  shaderc_compilation_status_null_result_object,
-  shaderc_compilation_status_invalid_assembly,
-} shaderc_compilation_status;
-
 // Optimization level.
 typedef enum {
   shaderc_optimization_level_zero,  // no optimization
   shaderc_optimization_level_size,  // optimize towards reducing code size
+  shaderc_optimization_level_performance,  // optimize towards performance
 } shaderc_optimization_level;
 
 // Resource limits.
@@ -173,13 +191,33 @@
   shaderc_limit_max_samples,
 } shaderc_limit;
 
+// Uniform resource kinds.
+// In Vulkan, uniform resources are bound to the pipeline via descriptors
+// with numbered bindings and sets.
+typedef enum {
+  // Image and image buffer.
+  shaderc_uniform_kind_image,
+  // Pure sampler.
+  shaderc_uniform_kind_sampler,
+  // Sampled texture in GLSL, and Shader Resource View in HLSL.
+  shaderc_uniform_kind_texture,
+  // Uniform Buffer Object (UBO) in GLSL.  Cbuffer in HLSL.
+  shaderc_uniform_kind_buffer,
+  // Shader Storage Buffer Object (SSBO) in GLSL.
+  shaderc_uniform_kind_storage_buffer,
+  // Unordered Access View, in HLSL.  (Writable storage image or storage
+  // buffer.)
+  shaderc_uniform_kind_unordered_access_view,
+} shaderc_uniform_kind;
+
 // Usage examples:
 //
 // Aggressively release compiler resources, but spend time in initialization
 // for each new use.
 //      shaderc_compiler_t compiler = shaderc_compiler_initialize();
 //      shaderc_compilation_result_t result = shaderc_compile_into_spv(
-//          compiler, "int main() {}", 13, shaderc_glsl_vertex_shader, "main");
+//          compiler, "#version 450\nvoid main() {}", 27,
+//          shaderc_glsl_vertex_shader, "main.vert", "main", nullptr);
 //      // Do stuff with compilation results.
 //      shaderc_result_release(result);
 //      shaderc_compiler_release(compiler);
@@ -189,7 +227,8 @@
 //      shaderc_compiler_t compiler = shaderc_compiler_initialize();
 //      // On the same, other or multiple simultaneous threads.
 //      shaderc_compilation_result_t result = shaderc_compile_into_spv(
-//          compiler, "int main() {}", 13, shaderc_glsl_vertex_shader, "main");
+//          compiler, "#version 450\nvoid main() {}", 27,
+//          shaderc_glsl_vertex_shader, "main.vert", "main", nullptr);
 //      // Do stuff with compilation results.
 //      shaderc_result_release(result);
 //      // Once no more compilations are to happen.
@@ -207,12 +246,12 @@
 // no synchronization; concurrent invocation of these functions on the SAME
 // object requires synchronization IF AND ONLY IF some of them take a non-const
 // argument.
-shaderc_compiler_t shaderc_compiler_initialize(void);
+SHADERC_EXPORT shaderc_compiler_t shaderc_compiler_initialize(void);
 
 // Releases the resources held by the shaderc_compiler_t.
 // After this call it is invalid to make any future calls to functions
 // involving this shaderc_compiler_t.
-void shaderc_compiler_release(shaderc_compiler_t);
+SHADERC_EXPORT void shaderc_compiler_release(shaderc_compiler_t);
 
 // An opaque handle to an object that manages options to a single compilation
 // result.
@@ -223,18 +262,20 @@
 // A return of NULL indicates that there was an error initializing the options.
 // Any function operating on shaderc_compile_options_t must offer the
 // basic thread-safety guarantee.
-shaderc_compile_options_t shaderc_compile_options_initialize(void);
+SHADERC_EXPORT shaderc_compile_options_t
+    shaderc_compile_options_initialize(void);
 
 // Returns a copy of the given shaderc_compile_options_t.
 // If NULL is passed as the parameter the call is the same as
 // shaderc_compile_options_init.
-shaderc_compile_options_t shaderc_compile_options_clone(
+SHADERC_EXPORT shaderc_compile_options_t shaderc_compile_options_clone(
     const shaderc_compile_options_t options);
 
 // Releases the compilation options. It is invalid to use the given
 // shaderc_compile_options_t object in any future calls. It is safe to pass
 // NULL to this function, and doing such will have no effect.
-void shaderc_compile_options_release(shaderc_compile_options_t options);
+SHADERC_EXPORT void shaderc_compile_options_release(
+    shaderc_compile_options_t options);
 
 // Adds a predefined macro to the compilation options. This has the same
 // effect as passing -Dname=value to the command-line compiler.  If value
@@ -247,21 +288,21 @@
 // modified or deleted after this function has returned. In case of adding
 // a valueless macro, the value argument should be a null pointer or the
 // value_length should be 0u.
-void shaderc_compile_options_add_macro_definition(
+SHADERC_EXPORT void shaderc_compile_options_add_macro_definition(
     shaderc_compile_options_t options, const char* name, size_t name_length,
     const char* value, size_t value_length);
 
 // Sets the source language.  The default is GLSL.
-void shaderc_compile_options_set_source_language(
+SHADERC_EXPORT void shaderc_compile_options_set_source_language(
     shaderc_compile_options_t options, shaderc_source_language lang);
 
 // Sets the compiler mode to generate debug information in the output.
-void shaderc_compile_options_set_generate_debug_info(
+SHADERC_EXPORT void shaderc_compile_options_set_generate_debug_info(
     shaderc_compile_options_t options);
 
 // Sets the compiler optimization level to the given level. Only the last one
 // takes effect if multiple calls of this function exist.
-void shaderc_compile_options_set_optimization_level(
+SHADERC_EXPORT void shaderc_compile_options_set_optimization_level(
     shaderc_compile_options_t options, shaderc_optimization_level level);
 
 // Forces the GLSL language version and profile to a given pair. The version
@@ -269,7 +310,7 @@
 // Version and profile specified here overrides the #version annotation in the
 // source. Use profile: 'shaderc_profile_none' for GLSL versions that do not
 // define profiles, e.g. versions below 150.
-void shaderc_compile_options_set_forced_version_profile(
+SHADERC_EXPORT void shaderc_compile_options_set_forced_version_profile(
     shaderc_compile_options_t options, int version, shaderc_profile profile);
 
 // Source text inclusion via #include is supported with a pair of callbacks
@@ -278,6 +319,8 @@
 // the contents of the result, and those contents must remain valid until the
 // second callback is invoked to release the result.  Both callbacks take a
 // user_data argument to specify the client context.
+// To return an error, set the source_name to an empty string and put your
+// error message in content.
 
 // An include result.
 typedef struct shaderc_include_result {
@@ -285,9 +328,11 @@
   // in the sense that it should be a unique name in the context of the
   // includer.  For example, if the includer maps source names to files in
   // a filesystem, then this name should be the absolute path of the file.
+  // For a failed inclusion, this string is empty.
   const char* source_name;
   size_t source_name_length;
-  // The text contents of the source file.
+  // The text contents of the source file in the normal case.
+  // For a failed inclusion, this contains the error message.
   const char* content;
   size_t content_length;
   // User data to be passed along with this request.
@@ -317,7 +362,7 @@
     void* user_data, shaderc_include_result* include_result);
 
 // Sets includer callback functions.
-void shaderc_compile_options_set_include_callbacks(
+SHADERC_EXPORT void shaderc_compile_options_set_include_callbacks(
     shaderc_compile_options_t options, shaderc_include_resolve_fn resolver,
     shaderc_include_result_release_fn result_releaser, void* user_data);
 
@@ -325,27 +370,103 @@
 // mode. When both suppress-warnings and warnings-as-errors modes are
 // turned on, warning messages will be inhibited, and will not be emitted
 // as error messages.
-void shaderc_compile_options_set_suppress_warnings(
+SHADERC_EXPORT void shaderc_compile_options_set_suppress_warnings(
     shaderc_compile_options_t options);
 
 // Sets the target shader environment, affecting which warnings or errors will
 // be issued.  The version will be for distinguishing between different versions
-// of the target environment.  "0" is the only supported version at this point
-void shaderc_compile_options_set_target_env(shaderc_compile_options_t options,
-                                            shaderc_target_env target,
-                                            uint32_t version);
+// of the target environment.  The version value should be either 0 or
+// a value listed in shaderc_env_version.  The 0 value maps to Vulkan 1.0 if
+// |target| is Vulkan, and it maps to OpenGL 4.5 if |target| is OpenGL.
+SHADERC_EXPORT void shaderc_compile_options_set_target_env(
+    shaderc_compile_options_t options,
+    shaderc_target_env target,
+    uint32_t version);
+
+// Sets the target SPIR-V version. The generated module will use this version
+// of SPIR-V.  Each target environment determines what versions of SPIR-V
+// it can consume.  Defaults to the highest version of SPIR-V 1.0 which is
+// required to be supported by the target environment.  E.g. Default to SPIR-V
+// 1.0 for Vulkan 1.0 and SPIR-V 1.3 for Vulkan 1.1.
+SHADERC_EXPORT void shaderc_compile_options_set_target_spirv(
+    shaderc_compile_options_t options, shaderc_spirv_version version);
 
 // Sets the compiler mode to treat all warnings as errors. Note the
 // suppress-warnings mode overrides this option, i.e. if both
 // warning-as-errors and suppress-warnings modes are set, warnings will not
 // be emitted as error messages.
-void shaderc_compile_options_set_warnings_as_errors(
+SHADERC_EXPORT void shaderc_compile_options_set_warnings_as_errors(
     shaderc_compile_options_t options);
 
 // Sets a resource limit.
-void shaderc_compile_options_set_limit(
+SHADERC_EXPORT void shaderc_compile_options_set_limit(
     shaderc_compile_options_t options, shaderc_limit limit, int value);
 
+// Sets whether the compiler should automatically assign bindings to uniforms
+// that aren't already explicitly bound in the shader source.
+SHADERC_EXPORT void shaderc_compile_options_set_auto_bind_uniforms(
+    shaderc_compile_options_t options, bool auto_bind);
+
+// Sets whether the compiler should use HLSL IO mapping rules for bindings.
+// Defaults to false.
+SHADERC_EXPORT void shaderc_compile_options_set_hlsl_io_mapping(
+    shaderc_compile_options_t options, bool hlsl_iomap);
+
+// Sets whether the compiler should determine block member offsets using HLSL
+// packing rules instead of standard GLSL rules.  Defaults to false.  Only
+// affects GLSL compilation.  HLSL rules are always used when compiling HLSL.
+SHADERC_EXPORT void shaderc_compile_options_set_hlsl_offsets(
+    shaderc_compile_options_t options, bool hlsl_offsets);
+
+// Sets the base binding number used for for a uniform resource type when
+// automatically assigning bindings.  For GLSL compilation, sets the lowest
+// automatically assigned number.  For HLSL compilation, the regsiter number
+// assigned to the resource is added to this specified base.
+SHADERC_EXPORT void shaderc_compile_options_set_binding_base(
+    shaderc_compile_options_t options,
+    shaderc_uniform_kind kind,
+    uint32_t base);
+
+// Like shaderc_compile_options_set_binding_base, but only takes effect when
+// compiling a given shader stage.  The stage is assumed to be one of vertex,
+// fragment, tessellation evaluation, tesselation control, geometry, or compute.
+SHADERC_EXPORT void shaderc_compile_options_set_binding_base_for_stage(
+    shaderc_compile_options_t options, shaderc_shader_kind shader_kind,
+    shaderc_uniform_kind kind, uint32_t base);
+
+// Sets whether the compiler should automatically assign locations to
+// uniform variables that don't have explicit locations in the shader source.
+SHADERC_EXPORT void shaderc_compile_options_set_auto_map_locations(
+    shaderc_compile_options_t options, bool auto_map);
+
+// Sets a descriptor set and binding for an HLSL register in the given stage.
+// This method keeps a copy of the string data.
+SHADERC_EXPORT void shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage(
+    shaderc_compile_options_t options, shaderc_shader_kind shader_kind,
+    const char* reg, const char* set, const char* binding);
+
+// Like shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage,
+// but affects all shader stages.
+SHADERC_EXPORT void shaderc_compile_options_set_hlsl_register_set_and_binding(
+    shaderc_compile_options_t options, const char* reg, const char* set,
+    const char* binding);
+
+// Sets whether the compiler should enable extension
+// SPV_GOOGLE_hlsl_functionality1.
+SHADERC_EXPORT void shaderc_compile_options_set_hlsl_functionality1(
+    shaderc_compile_options_t options, bool enable);
+
+// Sets whether the compiler should invert position.Y output in vertex shader.
+SHADERC_EXPORT void shaderc_compile_options_set_invert_y(
+    shaderc_compile_options_t options, bool enable);
+
+// Sets whether the compiler generates code for max and min builtins which,
+// if given a NaN operand, will return the other operand. Similarly, the clamp
+// builtin will favour the non-NaN operands, as if clamp were implemented
+// as a composition of max and min.
+SHADERC_EXPORT void shaderc_compile_options_set_nan_clamp(
+    shaderc_compile_options_t options, bool enable);
+
 // An opaque handle to the results of a call to any shaderc_compile_into_*()
 // function.
 typedef struct shaderc_compilation_result* shaderc_compilation_result_t;
@@ -369,7 +490,7 @@
 // present.  May be safely called from multiple threads without explicit
 // synchronization. If there was failure in allocating the compiler object,
 // null will be returned.
-shaderc_compilation_result_t shaderc_compile_into_spv(
+SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv(
     const shaderc_compiler_t compiler, const char* source_text,
     size_t source_text_size, shaderc_shader_kind shader_kind,
     const char* input_file_name, const char* entry_point_name,
@@ -378,7 +499,7 @@
 // Like shaderc_compile_into_spv, but the result contains SPIR-V assembly text
 // instead of a SPIR-V binary module.  The SPIR-V assembly syntax is as defined
 // by the SPIRV-Tools open source project.
-shaderc_compilation_result_t shaderc_compile_into_spv_assembly(
+SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv_assembly(
     const shaderc_compiler_t compiler, const char* source_text,
     size_t source_text_size, shaderc_shader_kind shader_kind,
     const char* input_file_name, const char* entry_point_name,
@@ -386,7 +507,7 @@
 
 // Like shaderc_compile_into_spv, but the result contains preprocessed source
 // code instead of a SPIR-V binary module
-shaderc_compilation_result_t shaderc_compile_into_preprocessed_text(
+SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_preprocessed_text(
     const shaderc_compiler_t compiler, const char* source_text,
     size_t source_text_size, shaderc_shader_kind shader_kind,
     const char* input_file_name, const char* entry_point_name,
@@ -401,7 +522,7 @@
 // May be safely called from multiple threads without explicit synchronization.
 // If there was failure in allocating the compiler object, null will be
 // returned.
-shaderc_compilation_result_t shaderc_assemble_into_spv(
+SHADERC_EXPORT shaderc_compilation_result_t shaderc_assemble_into_spv(
     const shaderc_compiler_t compiler, const char* source_assembly,
     size_t source_assembly_size,
     const shaderc_compile_options_t additional_options);
@@ -411,23 +532,23 @@
 
 // Releases the resources held by the result object. It is invalid to use the
 // result object for any further operations.
-void shaderc_result_release(shaderc_compilation_result_t result);
+SHADERC_EXPORT void shaderc_result_release(shaderc_compilation_result_t result);
 
 // Returns the number of bytes of the compilation output data in a result
 // object.
-size_t shaderc_result_get_length(const shaderc_compilation_result_t result);
+SHADERC_EXPORT size_t shaderc_result_get_length(const shaderc_compilation_result_t result);
 
 // Returns the number of warnings generated during the compilation.
-size_t shaderc_result_get_num_warnings(
+SHADERC_EXPORT size_t shaderc_result_get_num_warnings(
     const shaderc_compilation_result_t result);
 
 // Returns the number of errors generated during the compilation.
-size_t shaderc_result_get_num_errors(const shaderc_compilation_result_t result);
+SHADERC_EXPORT size_t shaderc_result_get_num_errors(const shaderc_compilation_result_t result);
 
 // Returns the compilation status, indicating whether the compilation succeeded,
 // or failed due to some reasons, like invalid shader stage or compilation
 // errors.
-shaderc_compilation_status shaderc_result_get_compilation_status(
+SHADERC_EXPORT shaderc_compilation_status shaderc_result_get_compilation_status(
     const shaderc_compilation_result_t);
 
 // Returns a pointer to the start of the compilation output data bytes, either
@@ -435,21 +556,21 @@
 // binary, this is guaranteed to be castable to a uint32_t*. If the result
 // contains assembly text or preprocessed source text, the pointer will point to
 // the resulting array of characters.
-const char* shaderc_result_get_bytes(const shaderc_compilation_result_t result);
+SHADERC_EXPORT const char* shaderc_result_get_bytes(const shaderc_compilation_result_t result);
 
 // Returns a null-terminated string that contains any error messages generated
 // during the compilation.
-const char* shaderc_result_get_error_message(
+SHADERC_EXPORT const char* shaderc_result_get_error_message(
     const shaderc_compilation_result_t result);
 
 // Provides the version & revision of the SPIR-V which will be produced
-void shaderc_get_spv_version(unsigned int* version, unsigned int* revision);
+SHADERC_EXPORT void shaderc_get_spv_version(unsigned int* version, unsigned int* revision);
 
 // Parses the version and profile from a given null-terminated string
 // containing both version and profile, like: '450core'. Returns false if
 // the string can not be parsed. Returns true when the parsing succeeds. The
 // parsed version and profile are returned through arguments.
-bool shaderc_parse_version_profile(const char* str, int* version,
+SHADERC_EXPORT bool shaderc_parse_version_profile(const char* str, int* version,
                                    shaderc_profile* profile);
 
 #ifdef __cplusplus
diff --git a/libshaderc/include/shaderc/shaderc.hpp b/libshaderc/include/shaderc/shaderc.hpp
index 3023ebb..1588dfe 100644
--- a/libshaderc/include/shaderc/shaderc.hpp
+++ b/libshaderc/include/shaderc/shaderc.hpp
@@ -47,11 +47,20 @@
   // CompilationResult, the shaderc_compilation_result will be released.
   explicit CompilationResult(shaderc_compilation_result_t compilation_result)
       : compilation_result_(compilation_result) {}
+  CompilationResult() : compilation_result_(nullptr) {}
   ~CompilationResult() { shaderc_result_release(compilation_result_); }
 
-  CompilationResult(CompilationResult&& other) {
+  CompilationResult(CompilationResult&& other) : compilation_result_(nullptr) {
+    *this = std::move(other);
+  }
+
+  CompilationResult& operator=(CompilationResult&& other) {
+    if (compilation_result_) {
+      shaderc_result_release(compilation_result_);
+    }
     compilation_result_ = other.compilation_result_;
     other.compilation_result_ = nullptr;
+    return *this;
   }
 
   // Returns any error message found during compilation.
@@ -180,6 +189,8 @@
 
     // Handles shaderc_include_result_release_fn callbacks.
     virtual void ReleaseInclude(shaderc_include_result* data) = 0;
+
+    virtual ~IncluderInterface() = default;
   };
 
   // Sets the includer instance for libshaderc to call during compilation, as
@@ -191,14 +202,14 @@
         options_,
         [](void* user_data, const char* requested_source, int type,
            const char* requesting_source, size_t include_depth) {
-          auto* includer = static_cast<IncluderInterface*>(user_data);
-          return includer->GetInclude(requested_source,
-                                      (shaderc_include_type)type,
-                                      requesting_source, include_depth);
+          auto* sub_includer = static_cast<IncluderInterface*>(user_data);
+          return sub_includer->GetInclude(
+              requested_source, static_cast<shaderc_include_type>(type),
+              requesting_source, include_depth);
         },
         [](void* user_data, shaderc_include_result* include_result) {
-          auto* includer = static_cast<IncluderInterface*>(user_data);
-          return includer->ReleaseInclude(include_result);
+          auto* sub_includer = static_cast<IncluderInterface*>(user_data);
+          return sub_includer->ReleaseInclude(include_result);
         },
         includer_.get());
   }
@@ -227,14 +238,23 @@
   }
 
   // Sets the target shader environment, affecting which warnings or errors will
-  // be issued.
-  // The version will be for distinguishing between different versions of the
-  // target environment.
-  // "0" is the only supported version at this point
+  // be issued.  The version will be for distinguishing between different
+  // versions of the target environment.  The version value should be either 0
+  // or a value listed in shaderc_env_version.  The 0 value maps to Vulkan 1.0
+  // if |target| is Vulkan, and it maps to OpenGL 4.5 if |target| is OpenGL.
   void SetTargetEnvironment(shaderc_target_env target, uint32_t version) {
     shaderc_compile_options_set_target_env(options_, target, version);
   }
 
+  // Sets the target SPIR-V version.  The generated module will use this version
+  // of SPIR-V.  Each target environment determines what versions of SPIR-V
+  // it can consume.  Defaults to the highest version of SPIR-V 1.0 which is
+  // required to be supported by the target environment.  E.g. Default to SPIR-V
+  // 1.0 for Vulkan 1.0 and SPIR-V 1.3 for Vulkan 1.1.
+  void SetTargetSpirv(shaderc_spirv_version version) {
+    shaderc_compile_options_set_target_spirv(options_, version);
+  }
+
   // Sets the compiler mode to make all warnings into errors. Note the
   // suppress-warnings mode overrides this option, i.e. if both
   // warning-as-errors and suppress-warnings modes are set on, warnings will not
@@ -248,6 +268,86 @@
     shaderc_compile_options_set_limit(options_, limit, value);
   }
 
+  // Sets whether the compiler should automatically assign bindings to uniforms
+  // that aren't already explicitly bound in the shader source.
+  void SetAutoBindUniforms(bool auto_bind) {
+    shaderc_compile_options_set_auto_bind_uniforms(options_, auto_bind);
+  }
+
+  // Sets whether the compiler should use HLSL IO mapping rules for bindings.
+  // Defaults to false.
+  void SetHlslIoMapping(bool hlsl_iomap) {
+    shaderc_compile_options_set_hlsl_io_mapping(options_, hlsl_iomap);
+  }
+
+  // Sets whether the compiler should determine block member offsets using HLSL
+  // packing rules instead of standard GLSL rules.  Defaults to false.  Only
+  // affects GLSL compilation.  HLSL rules are always used when compiling HLSL.
+  void SetHlslOffsets(bool hlsl_offsets) {
+    shaderc_compile_options_set_hlsl_offsets(options_, hlsl_offsets);
+  }
+
+  // Sets the base binding number used for for a uniform resource type when
+  // automatically assigning bindings.  For GLSL compilation, sets the lowest
+  // automatically assigned number.  For HLSL compilation, the regsiter number
+  // assigned to the resource is added to this specified base.
+  void SetBindingBase(shaderc_uniform_kind kind, uint32_t base) {
+    shaderc_compile_options_set_binding_base(options_, kind, base);
+  }
+
+  // Like SetBindingBase, but only takes effect when compiling a given shader
+  // stage.  The stage is assumed to be one of vertex, fragment, tessellation
+  // evaluation, tesselation control, geometry, or compute.
+  void SetBindingBaseForStage(shaderc_shader_kind shader_kind,
+                              shaderc_uniform_kind kind, uint32_t base) {
+    shaderc_compile_options_set_binding_base_for_stage(options_, shader_kind,
+                                                       kind, base);
+  }
+
+  // Sets whether the compiler automatically assigns locations to
+  // uniform variables that don't have explicit locations.
+  void SetAutoMapLocations(bool auto_map) {
+    shaderc_compile_options_set_auto_map_locations(options_, auto_map);
+  }
+
+  // Sets a descriptor set and binding for an HLSL register in the given stage.
+  // Copies the parameter strings.
+  void SetHlslRegisterSetAndBindingForStage(shaderc_shader_kind shader_kind,
+                                            const std::string& reg,
+                                            const std::string& set,
+                                            const std::string& binding) {
+    shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage(
+        options_, shader_kind, reg.c_str(), set.c_str(), binding.c_str());
+  }
+
+  // Sets a descriptor set and binding for an HLSL register in any stage.
+  // Copies the parameter strings.
+  void SetHlslRegisterSetAndBinding(const std::string& reg,
+                                    const std::string& set,
+                                    const std::string& binding) {
+    shaderc_compile_options_set_hlsl_register_set_and_binding(
+        options_, reg.c_str(), set.c_str(), binding.c_str());
+  }
+
+  // Sets whether the compiler should enable extension
+  // SPV_GOOGLE_hlsl_functionality1.
+  void SetHlslFunctionality1(bool enable) {
+    shaderc_compile_options_set_hlsl_functionality1(options_, enable);
+  }
+
+  // Sets whether the compiler should invert position.Y output in vertex shader.
+  void SetInvertY(bool enable) {
+    shaderc_compile_options_set_invert_y(options_, enable);
+  }
+
+  // Sets whether the compiler should generates code for max an min which,
+  // if given a NaN operand, will return the other operand. Similarly, the
+  // clamp builtin will favour the non-NaN operands, as if clamp were
+  // implemented as a composition of max and min.
+  void SetNanClamp(bool enable) {
+    shaderc_compile_options_set_nan_clamp(options_, enable);
+  }
+
  private:
   CompileOptions& operator=(const CompileOptions& other) = delete;
   shaderc_compile_options_t options_;
diff --git a/libshaderc/include/shaderc/status.h b/libshaderc/include/shaderc/status.h
new file mode 100644
index 0000000..57ac70d
--- /dev/null
+++ b/libshaderc/include/shaderc/status.h
@@ -0,0 +1,39 @@
+// Copyright 2018 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SHADERC_STATUS_H_
+#define SHADERC_STATUS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Indicate the status of a compilation.
+typedef enum {
+  shaderc_compilation_status_success = 0,
+  shaderc_compilation_status_invalid_stage = 1,  // error stage deduction
+  shaderc_compilation_status_compilation_error = 2,
+  shaderc_compilation_status_internal_error = 3,  // unexpected failure
+  shaderc_compilation_status_null_result_object = 4,
+  shaderc_compilation_status_invalid_assembly = 5,
+  shaderc_compilation_status_validation_error = 6,
+  shaderc_compilation_status_transformation_error = 7,
+  shaderc_compilation_status_configuration_error = 8,
+} shaderc_compilation_status;
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // SHADERC_STATUS_H_
diff --git a/libshaderc/include/shaderc/visibility.h b/libshaderc/include/shaderc/visibility.h
new file mode 100644
index 0000000..88ec151
--- /dev/null
+++ b/libshaderc/include/shaderc/visibility.h
@@ -0,0 +1,37 @@
+// Copyright 2018 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SHADERC_VISIBILITY_H_
+#define SHADERC_VISIBILITY_H_
+
+// SHADERC_EXPORT tags symbol that will be exposed by the shared libraries.
+#if defined(SHADERC_SHAREDLIB)
+#if defined(_WIN32)
+#if defined(SHADERC_IMPLEMENTATION)
+#define SHADERC_EXPORT __declspec(dllexport)
+#else
+#define SHADERC_EXPORT __declspec(dllimport)
+#endif
+#else
+#if defined(SHADERC_IMPLEMENTATION)
+#define SHADERC_EXPORT __attribute__((visibility("default")))
+#else
+#define SHADERC_EXPORT
+#endif
+#endif
+#else
+#define SHADERC_EXPORT
+#endif
+
+#endif  // SHADERC_VISIBILITY_H_
diff --git a/libshaderc/src/common_shaders_for_test.h b/libshaderc/src/common_shaders_for_test.h
index a0120a2..e177797 100644
--- a/libshaderc/src/common_shaders_for_test.h
+++ b/libshaderc/src/common_shaders_for_test.h
@@ -47,8 +47,8 @@
 // because some versions of glslang will error out for a too-low version
 // when generating SPIR-V.
 const char kDeprecatedAttributeShader[] =
-    "#version 140\n"
-    "attribute float x;\n"
+    "#version 400\n"
+    "layout(location = 0) attribute float x;\n"
     "void main() {}\n";
 
 // By default the compiler will emit a warning as version 550 is an unknown
@@ -80,9 +80,9 @@
 
 // Compiler should generate two warnings.
 const char kTwoWarningsShader[] =
-    "#version 140\n"
-    "attribute float x;\n"
-    "attribute float y;\n"
+    "#version 400\n"
+    "layout(location = 0) attribute float x;\n"
+    "layout(location = 1) attribute float y;\n"
     "void main(){}\n";
 
 // A shader that compiles under OpenGL compatibility profile rules,
@@ -176,6 +176,50 @@
     "    uvec3 temp = gl_WorkGroupID;\n"
     "}";
 
+// NV mesh shader without #pragma.
+const char kNVMeshShader[] =
+    "#version 450\n"
+    "#extension GL_NV_mesh_shader : enable\n"
+    "layout(local_size_x=8) in;\n"
+    "layout(max_vertices=5) out;\n"
+    "layout(max_primitives=10) out;\n"
+    "layout(triangles) out;\n"
+    "void main() {\n"
+    "  gl_MeshVerticesNV[gl_LocalInvocationID.x].gl_Position = vec4(0.0);\n"
+    "}\n";
+
+// NV mesh shader with #pragma annotation.
+const char kNVMeshShaderWithPragma[] =
+    "#version 450\n"
+    "#extension GL_NV_mesh_shader : enable\n"
+    "#pragma shader_stage(mesh)\n"
+    "layout(local_size_x=8) in;\n"
+    "layout(max_vertices=5) out;\n"
+    "layout(max_primitives=10) out;\n"
+    "layout(triangles) out;\n"
+    "void main() {\n"
+    "  gl_MeshVerticesNV[gl_LocalInvocationID.x].gl_Position = vec4(0.0);\n"
+    "}\n";
+
+// NV task shader without #pragma annotation.
+const char kNVTaskShader[] =
+    "#version 450\n"
+    "#extension GL_NV_mesh_shader : enable\n"
+    "layout(local_size_x=8) in;\n"
+    "void main() {\n"
+    "  gl_TaskCountNV = 2;\n"
+    "}\n";
+
+// NV task shader with #pragma annotation.
+const char kNVTaskShaderWithPragma[] =
+    "#version 450\n"
+    "#extension GL_NV_mesh_shader : enable\n"
+    "#pragma shader_stage(task)\n"
+    "layout(local_size_x=8) in;\n"
+    "void main() {\n"
+    "  gl_TaskCountNV = 2;\n"
+    "}\n";
+
 // Vertex only shader with invalid #pragma annotation.
 const char kVertexOnlyShaderWithInvalidPragma[] =
     "#version 310 es\n"
@@ -189,7 +233,7 @@
 const char* kMinimalShaderDisassemblySubstrings[] = {
     "; SPIR-V\n"
     "; Version: 1.0\n"
-    "; Generator: Khronos Glslang Reference Front End; 1\n"
+    "; Generator: Google Shaderc over Glslang; 10\n"
     "; Bound:",
 
     "               OpCapability Shader\n",
@@ -198,10 +242,22 @@
     "               OpReturn\n",
     "               OpFunctionEnd\n"};
 
+const char* kMinimalShaderDebugInfoDisassemblySubstrings[] = {
+    "; SPIR-V\n"
+    "; Version: 1.0\n"
+    "; Generator: Google Shaderc over Glslang; 10\n"
+    "; Bound:",
+
+    "               OpCapability Shader\n",
+    "          %2 = OpExtInstImport \"GLSL.std.450\"\n",
+    "               OpMemoryModel Logical GLSL450\n",
+    "               OpReturn\n",
+    "               OpFunctionEnd\n"};
+
 const char kMinimalShaderAssembly[] = R"(
     ; SPIR-V
     ; Version: 1.0
-    ; Generator: Khronos Glslang Reference Front End; 1
+    ; Generator: Google Shaderc over Glslang; 10
     ; Bound: 6
     ; Schema: 0
 
@@ -218,6 +274,138 @@
          OpReturn
          OpFunctionEnd)";
 
+const char kShaderWithUniformsWithoutBindings[] =
+    R"(#version 450
+       #extension GL_ARB_sparse_texture2 : enable
+       uniform texture2D my_tex;
+       uniform sampler my_sam;
+       layout(rgba32f) uniform image2D my_img;
+       layout(rgba32f) uniform imageBuffer my_imbuf;
+       uniform block { float x; float y; } my_ubo;
+       void main() {
+         texture(sampler2D(my_tex,my_sam),vec2(1.0));
+         vec4 t;
+         sparseImageLoadARB(my_img,ivec2(0),t);
+         imageLoad(my_imbuf,42);
+         float x = my_ubo.x;
+       })";
+
+// A GLSL vertex shader with a weirdly packed block.
+const char kGlslShaderWeirdPacking[] =
+    R"(#version 450
+       layout(set=0, binding=0)
+       buffer B { float x; vec3 foo; } my_ssbo;
+       void main() { my_ssbo.x = 1.0; })";
+
+// A HLSL fragment shader with a weirdly packed block.
+const char kHlslFragShaderWithRegisters[] =
+    R"(Buffer<float> t4 : register(t4);
+       Buffer<float> t5 : register(t5);
+       float4 main() : SV_Target0 {
+         return float4(t4.Load(0) + t5.Load(1));
+       })";
+
+// A GLSL compute shader using a regular barrier.
+const char kGlslShaderComputeBarrier[] =
+    R"(#version 450
+       void main() { barrier(); })";
+
+// A GLSL compute shader using the Subgroups feature.
+const char kGlslShaderComputeSubgroupBarrier[] =
+    R"(#version 450
+       #extension GL_KHR_shader_subgroup_basic : enable
+       void main() { subgroupBarrier(); })";
+
+// A GLSL task shader using a regular barrier.
+const char kGlslShaderTaskBarrier[] =
+    R"(#version 450
+       #extension GL_NV_mesh_shader : enable
+       layout(local_size_x = 32) in;
+       void main() { barrier(); })";
+
+// A GLSL task shader using the Subgroups feature.
+const char kGlslShaderTaskSubgroupBarrier[] =
+    R"(#version 450
+       #extension GL_NV_mesh_shader : enable
+       #extension GL_KHR_shader_subgroup_basic : enable
+       layout(local_size_x = 32) in;
+       void main() { subgroupBarrier(); })";
+
+// A GLSL mesh shader using a regular barrier.
+const char kGlslShaderMeshBarrier[] =
+    R"(#version 450
+       #extension GL_NV_mesh_shader : enable
+       layout(local_size_x = 32) in;
+       layout(max_vertices=81) out;
+       layout(max_primitives=32) out;
+       layout(triangles) out;
+       void main() { barrier(); })";
+
+// A GLSL mesh shader using the Subgroups feature.
+const char kGlslShaderMeshSubgroupBarrier[] =
+    R"(#version 450
+       #extension GL_NV_mesh_shader : enable
+       #extension GL_KHR_shader_subgroup_basic : enable
+       layout(local_size_x = 32) in;
+       layout(max_vertices=81) out;
+       layout(max_primitives=32) out;
+       layout(triangles) out;
+       void main() { subgroupBarrier(); })";
+
+const char kGlslMultipleFnShader[] =
+    R"(#version 450
+       layout(location=0) flat in  int inVal;
+       layout(location=0)      out int outVal;
+       int foo(int a) { return a; }
+       void main() { outVal = foo(inVal); })";
+
+const char kHlslShaderWithCounterBuffer[] =
+    R"(RWStructuredBuffer<uint> Ainc;
+       float4 main() : SV_Target0 {
+         return float4(Ainc.IncrementCounter(), 0, 0, 0);
+       })";
+
+const char kHlslWaveActiveSumeComputeShader[] =
+  R"(struct S { uint val; uint result; };
+
+     [[vk::binding(0,0)]]
+     RWStructuredBuffer<S> MyBuffer;
+
+     [numthreads(32, 1, 1)]
+     void main(uint3 id : SV_DispatchThreadID) {
+       MyBuffer[id.x].result = WaveActiveSum(MyBuffer[id.x].val);
+     })";
+
+const char kHlslMemLayoutResourceSelect[] =
+    R"(cbuffer Foo { float a; float3 b; }
+
+       [[vk::binding(0,0)]]
+       Texture2D Tex;
+       [[vk::binding(1,0)]]
+       SamplerState Sampler1;
+       [[vk::binding(2,0)]]
+       SamplerState Sampler2;
+
+       static const int val = 42;
+
+       float4 main() : SV_Target {
+         SamplerState samp;
+
+         if (val > 5)
+           samp = Sampler1;
+         else
+           samp = Sampler2;
+
+         return Tex.Sample(samp, float2(0.5, 0.5)) + float4(a, b);
+       })";
+
+const char kGlslShaderWithClamp[] =
+    R"(#version 450
+    layout(location=0) in vec4 i;
+    layout(location=0) out vec4 o;
+    void main() { o = clamp(i, vec4(0.5), vec4(1.0)); }
+    )";
+
 #ifdef __cplusplus
 }
 #endif  // __cplusplus
diff --git a/libshaderc/src/shaderc.cc b/libshaderc/src/shaderc.cc
index c7b6ef2..da0f3b2 100644
--- a/libshaderc/src/shaderc.cc
+++ b/libshaderc/src/shaderc.cc
@@ -12,21 +12,20 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "shaderc_private.h"
-
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
+#include <memory>
 #include <sstream>
 #include <vector>
 
-#include "SPIRV/spirv.hpp"
-
 #include "libshaderc_util/compiler.h"
 #include "libshaderc_util/counting_includer.h"
 #include "libshaderc_util/resources.h"
 #include "libshaderc_util/spirv_tools_wrapper.h"
 #include "libshaderc_util/version_profile.h"
+#include "shaderc_private.h"
+#include "spirv/unified1/spirv.hpp"
 
 #if (defined(_MSC_VER) && !defined(_CPPUNWIND)) || !defined(__EXCEPTIONS)
 #define TRY_IF_EXCEPTIONS_ENABLED
@@ -56,6 +55,24 @@
       return EShLangTessControl;
     case shaderc_glsl_tess_evaluation_shader:
       return EShLangTessEvaluation;
+
+    case shaderc_glsl_raygen_shader:
+      return EShLangRayGenNV;
+    case shaderc_glsl_anyhit_shader:
+      return EShLangAnyHitNV;
+    case shaderc_glsl_closesthit_shader:
+      return EShLangClosestHitNV;
+    case shaderc_glsl_miss_shader:
+      return EShLangMissNV;
+    case shaderc_glsl_intersection_shader:
+      return EShLangIntersectNV;
+    case shaderc_glsl_callable_shader:
+      return EShLangCallableNV;
+    case shaderc_glsl_task_shader:
+      return EShLangTaskNV;
+    case shaderc_glsl_mesh_shader:
+      return EShLangMeshNV;
+
     case shaderc_glsl_infer_from_source:
     case shaderc_glsl_default_vertex_shader:
     case shaderc_glsl_default_fragment_shader:
@@ -63,6 +80,14 @@
     case shaderc_glsl_default_geometry_shader:
     case shaderc_glsl_default_tess_control_shader:
     case shaderc_glsl_default_tess_evaluation_shader:
+    case shaderc_glsl_default_raygen_shader:
+    case shaderc_glsl_default_anyhit_shader:
+    case shaderc_glsl_default_closesthit_shader:
+    case shaderc_glsl_default_miss_shader:
+    case shaderc_glsl_default_intersection_shader:
+    case shaderc_glsl_default_callable_shader:
+    case shaderc_glsl_default_task_shader:
+    case shaderc_glsl_default_mesh_shader:
     case shaderc_spirv_assembly:
       return EShLangCount;
   }
@@ -83,7 +108,7 @@
  public:
   explicit StageDeducer(
       shaderc_shader_kind kind = shaderc_glsl_infer_from_source)
-      : kind_(kind), error_(false){};
+      : kind_(kind), error_(false){}
   // The method that underlying glslang will call to determine the shader stage
   // to be used in current compilation. It is called only when there is neither
   // forced shader kind (or say stage, in the view of glslang), nor #pragma
@@ -103,7 +128,7 @@
       error_ = false;
     }
     return stage;
-  };
+  }
 
   // Returns true if there is error during shader stage deduction.
   bool error() const { return error_; }
@@ -120,6 +145,14 @@
       case shaderc_glsl_tess_control_shader:
       case shaderc_glsl_tess_evaluation_shader:
       case shaderc_glsl_infer_from_source:
+      case shaderc_glsl_raygen_shader:
+      case shaderc_glsl_anyhit_shader:
+      case shaderc_glsl_closesthit_shader:
+      case shaderc_glsl_miss_shader:
+      case shaderc_glsl_intersection_shader:
+      case shaderc_glsl_callable_shader:
+      case shaderc_glsl_task_shader:
+      case shaderc_glsl_mesh_shader:
         return EShLangCount;
       case shaderc_glsl_default_vertex_shader:
         return EShLangVertex;
@@ -133,6 +166,22 @@
         return EShLangTessControl;
       case shaderc_glsl_default_tess_evaluation_shader:
         return EShLangTessEvaluation;
+      case shaderc_glsl_default_raygen_shader:
+        return EShLangRayGenNV;
+      case shaderc_glsl_default_anyhit_shader:
+        return EShLangAnyHitNV;
+      case shaderc_glsl_default_closesthit_shader:
+        return EShLangClosestHitNV;
+      case shaderc_glsl_default_miss_shader:
+        return EShLangMissNV;
+      case shaderc_glsl_default_intersection_shader:
+        return EShLangIntersectNV;
+      case shaderc_glsl_default_callable_shader:
+        return EShLangCallableNV;
+      case shaderc_glsl_default_task_shader:
+        return EShLangTaskNV;
+      case shaderc_glsl_default_mesh_shader:
+        return EShLangMeshNV;
       case shaderc_spirv_assembly:
         return EShLangCount;
     }
@@ -152,9 +201,9 @@
                        void* user_data)
       : resolver_(resolver),
         result_releaser_(result_releaser),
-        user_data_(user_data){};
+        user_data_(user_data){}
   InternalFileIncluder()
-      : resolver_(nullptr), result_releaser_(nullptr), user_data_(nullptr){};
+      : resolver_(nullptr), result_releaser_(nullptr), user_data_(nullptr){}
 
  private:
   // Check the validity of the callbacks.
@@ -162,18 +211,18 @@
     return resolver_ != nullptr && result_releaser_ != nullptr;
   }
 
-  // Maps a shaderc_include_type to the correpsonding Glslang include type.
-  shaderc_include_type GetIncludeType(
-      glslang::TShader::Includer::IncludeType type) {
+  // Maps CountingIncluder IncludeType value to a shaderc_include_type
+  // value.
+  shaderc_include_type GetIncludeType(IncludeType type) {
     switch (type) {
-      case glslang::TShader::Includer::EIncludeRelative:
+      case IncludeType::Local:
         return shaderc_include_type_relative;
-      case glslang::TShader::Includer::EIncludeStandard:
+      case IncludeType::System:
         return shaderc_include_type_standard;
       default:
         break;
     }
-    assert(0 && "Unhandled shaderc_include_type");
+    assert(0 && "Unhandled IncludeType");
     return shaderc_include_type_relative;
   }
 
@@ -185,11 +234,10 @@
   // resolved name member is an empty string, and the contents members
   // contains error details.
   virtual glslang::TShader::Includer::IncludeResult* include_delegate(
-      const char* requested_source,
-      glslang::TShader::Includer::IncludeType type,
-      const char* requesting_source, size_t include_depth) override {
+      const char* requested_source, const char* requesting_source,
+      IncludeType type, size_t include_depth) override {
     if (!AreValidCallbacks()) {
-      const char kUnexpectedIncludeError[] =
+      static const char kUnexpectedIncludeError[] =
           "#error unexpected include directive";
       return new glslang::TShader::Includer::IncludeResult{
           "", kUnexpectedIncludeError, strlen(kUnexpectedIncludeError),
@@ -213,7 +261,7 @@
       glslang::TShader::Includer::IncludeResult* result) override {
     if (result && result_releaser_) {
       result_releaser_(user_data_,
-                       static_cast<shaderc_include_result*>(result->user_data));
+                       static_cast<shaderc_include_result*>(result->userData));
     }
     delete result;
   }
@@ -230,6 +278,9 @@
       return shaderc_util::Compiler::TargetEnv::OpenGL;
     case shaderc_target_env_opengl_compat:
       return shaderc_util::Compiler::TargetEnv::OpenGLCompat;
+    case shaderc_target_env_webgpu:
+      assert(false);
+      break;
     case shaderc_target_env_vulkan:
     default:
       break;
@@ -238,11 +289,36 @@
   return shaderc_util::Compiler::TargetEnv::Vulkan;
 }
 
+shaderc_util::Compiler::TargetEnvVersion GetCompilerTargetEnvVersion(
+    uint32_t version_number) {
+  using namespace shaderc_util;
+
+  if (static_cast<uint32_t>(Compiler::TargetEnvVersion::Vulkan_1_0) ==
+      version_number) {
+    return Compiler::TargetEnvVersion::Vulkan_1_0;
+  }
+  if (static_cast<uint32_t>(Compiler::TargetEnvVersion::Vulkan_1_1) ==
+      version_number) {
+    return Compiler::TargetEnvVersion::Vulkan_1_1;
+  }
+  if (static_cast<uint32_t>(Compiler::TargetEnvVersion::Vulkan_1_2) ==
+      version_number) {
+    return Compiler::TargetEnvVersion::Vulkan_1_2;
+  }
+  if (static_cast<uint32_t>(Compiler::TargetEnvVersion::OpenGL_4_5) ==
+      version_number) {
+    return Compiler::TargetEnvVersion::OpenGL_4_5;
+  }
+
+  return Compiler::TargetEnvVersion::Default;
+}
+
 // Returns the Compiler::Limit enum for the given shaderc_limit enum.
 shaderc_util::Compiler::Limit CompilerLimit(shaderc_limit limit) {
   switch (limit) {
-#define RESOURCE(NAME,FIELD,CNAME) \
-     case shaderc_limit_##CNAME: return shaderc_util::Compiler::Limit::NAME;
+#define RESOURCE(NAME, FIELD, CNAME) \
+  case shaderc_limit_##CNAME:        \
+    return shaderc_util::Compiler::Limit::NAME;
 #include "libshaderc_util/resources.inc"
 #undef RESOURCE
     default:
@@ -252,10 +328,53 @@
   return static_cast<shaderc_util::Compiler::Limit>(0);
 }
 
+// Returns the Compiler::UniformKind for the given shaderc_uniform_kind.
+shaderc_util::Compiler::UniformKind GetUniformKind(shaderc_uniform_kind kind) {
+  switch (kind) {
+    case shaderc_uniform_kind_texture:
+      return shaderc_util::Compiler::UniformKind::Texture;
+    case shaderc_uniform_kind_sampler:
+      return shaderc_util::Compiler::UniformKind::Sampler;
+    case shaderc_uniform_kind_image:
+      return shaderc_util::Compiler::UniformKind::Image;
+    case shaderc_uniform_kind_buffer:
+      return shaderc_util::Compiler::UniformKind::Buffer;
+    case shaderc_uniform_kind_storage_buffer:
+      return shaderc_util::Compiler::UniformKind::StorageBuffer;
+    case shaderc_uniform_kind_unordered_access_view:
+      return shaderc_util::Compiler::UniformKind::UnorderedAccessView;
+  }
+  assert(0 && "Should not have reached here");
+  return static_cast<shaderc_util::Compiler::UniformKind>(0);
+}
+
+// Returns the Compiler::Stage for generic stage values in shaderc_shader_kind.
+shaderc_util::Compiler::Stage GetStage(shaderc_shader_kind kind) {
+  switch (kind) {
+    case shaderc_vertex_shader:
+      return shaderc_util::Compiler::Stage::Vertex;
+    case shaderc_fragment_shader:
+      return shaderc_util::Compiler::Stage::Fragment;
+    case shaderc_compute_shader:
+      return shaderc_util::Compiler::Stage::Compute;
+    case shaderc_tess_control_shader:
+      return shaderc_util::Compiler::Stage::TessControl;
+    case shaderc_tess_evaluation_shader:
+      return shaderc_util::Compiler::Stage::TessEval;
+    case shaderc_geometry_shader:
+      return shaderc_util::Compiler::Stage::Geometry;
+    default:
+      break;
+  }
+  assert(0 && "Should not have reached here");
+  return static_cast<shaderc_util::Compiler::Stage>(0);
+}
+
 }  // anonymous namespace
 
 struct shaderc_compile_options {
   shaderc_target_env target_env = shaderc_target_env_default;
+  uint32_t target_env_version = 0;
   shaderc_util::Compiler compiler;
   shaderc_include_resolve_fn include_resolver = nullptr;
   shaderc_include_result_release_fn include_result_releaser = nullptr;
@@ -285,8 +404,7 @@
 }
 
 void shaderc_compile_options_set_source_language(
-    shaderc_compile_options_t options,
-    shaderc_source_language set_lang) {
+    shaderc_compile_options_t options, shaderc_source_language set_lang) {
   auto lang = shaderc_util::Compiler::SourceLanguage::GLSL;
   if (set_lang == shaderc_source_language_hlsl)
     lang = shaderc_util::Compiler::SourceLanguage::HLSL;
@@ -305,6 +423,9 @@
     case shaderc_optimization_level_size:
       opt_level = shaderc_util::Compiler::OptimizationLevel::Size;
       break;
+    case shaderc_optimization_level_performance:
+      opt_level = shaderc_util::Compiler::OptimizationLevel::Performance;
+      break;
     default:
       break;
   }
@@ -349,10 +470,16 @@
 void shaderc_compile_options_set_target_env(shaderc_compile_options_t options,
                                             shaderc_target_env target,
                                             uint32_t version) {
-  // "version" reserved for future use, intended to distinguish between
-  // different versions of a target environment
   options->target_env = target;
-  options->compiler.SetTargetEnv(GetCompilerTargetEnv(target));
+  options->compiler.SetTargetEnv(GetCompilerTargetEnv(target),
+                                 GetCompilerTargetEnvVersion(version));
+}
+
+void shaderc_compile_options_set_target_spirv(shaderc_compile_options_t options,
+                                              shaderc_spirv_version ver) {
+  // We made the values match, so we can get away with a static cast.
+  options->compiler.SetTargetSpirv(
+      static_cast<shaderc_util::Compiler::SpirvVersion>(ver));
 }
 
 void shaderc_compile_options_set_warnings_as_errors(
@@ -360,20 +487,83 @@
   options->compiler.SetWarningsAsErrors();
 }
 
-void shaderc_compile_options_set_limit(
-    shaderc_compile_options_t options, shaderc_limit limit, int value) {
+void shaderc_compile_options_set_limit(shaderc_compile_options_t options,
+                                       shaderc_limit limit, int value) {
   options->compiler.SetLimit(CompilerLimit(limit), value);
 }
 
+void shaderc_compile_options_set_auto_bind_uniforms(
+    shaderc_compile_options_t options, bool auto_bind) {
+  options->compiler.SetAutoBindUniforms(auto_bind);
+}
+
+void shaderc_compile_options_set_hlsl_io_mapping(
+    shaderc_compile_options_t options, bool hlsl_iomap) {
+  options->compiler.SetHlslIoMapping(hlsl_iomap);
+}
+
+void shaderc_compile_options_set_hlsl_offsets(shaderc_compile_options_t options,
+                                              bool hlsl_offsets) {
+  options->compiler.SetHlslOffsets(hlsl_offsets);
+}
+
+void shaderc_compile_options_set_binding_base(shaderc_compile_options_t options,
+                                              shaderc_uniform_kind kind,
+                                              uint32_t base) {
+  options->compiler.SetAutoBindingBase(GetUniformKind(kind), base);
+}
+
+void shaderc_compile_options_set_binding_base_for_stage(
+    shaderc_compile_options_t options, shaderc_shader_kind shader_kind,
+    shaderc_uniform_kind kind, uint32_t base) {
+  options->compiler.SetAutoBindingBaseForStage(GetStage(shader_kind),
+                                               GetUniformKind(kind), base);
+}
+
+void shaderc_compile_options_set_auto_map_locations(
+    shaderc_compile_options_t options, bool auto_map) {
+  options->compiler.SetAutoMapLocations(auto_map);
+}
+
+void shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage(
+    shaderc_compile_options_t options, shaderc_shader_kind shader_kind,
+    const char* reg, const char* set, const char* binding) {
+  options->compiler.SetHlslRegisterSetAndBindingForStage(GetStage(shader_kind),
+                                                         reg, set, binding);
+}
+
+void shaderc_compile_options_set_hlsl_register_set_and_binding(
+    shaderc_compile_options_t options, const char* reg, const char* set,
+    const char* binding) {
+  options->compiler.SetHlslRegisterSetAndBinding(reg, set, binding);
+}
+
+void shaderc_compile_options_set_hlsl_functionality1(
+    shaderc_compile_options_t options, bool enable) {
+  options->compiler.EnableHlslFunctionality1(enable);
+}
+
+void shaderc_compile_options_set_invert_y(
+    shaderc_compile_options_t options, bool enable) {
+  options->compiler.EnableInvertY(enable);
+}
+
+void shaderc_compile_options_set_nan_clamp(shaderc_compile_options_t options,
+                                           bool enable) {
+  options->compiler.SetNanClamp(enable);
+}
+
 shaderc_compiler_t shaderc_compiler_initialize() {
-  static shaderc_util::GlslangInitializer* initializer =
-      new shaderc_util::GlslangInitializer;
   shaderc_compiler_t compiler = new (std::nothrow) shaderc_compiler;
-  compiler->initializer = initializer;
+  if (compiler) {
+    compiler->initializer.reset(new shaderc_util::GlslangInitializer);
+  }
   return compiler;
 }
 
-void shaderc_compiler_release(shaderc_compiler_t compiler) { delete compiler; }
+void shaderc_compiler_release(shaderc_compiler_t compiler) {
+  delete compiler;
+}
 
 namespace {
 shaderc_compilation_result_t CompileToSpecifiedOutputType(
@@ -418,7 +608,7 @@
               // We need to make this a reference wrapper, so that std::function
               // won't make a copy for this callable object.
               std::ref(stage_deducer), includer, output_type, &errors,
-              &total_warnings, &total_errors, compiler->initializer);
+              &total_warnings, &total_errors);
     } else {
       // Compile with default options.
       InternalFileIncluder includer;
@@ -427,7 +617,7 @@
           shaderc_util::Compiler().Compile(
               source_string, forced_stage, input_file_name_str, entry_point_name,
               std::ref(stage_deducer), includer, output_type, &errors,
-              &total_warnings, &total_errors, compiler->initializer);
+              &total_warnings, &total_errors);
     }
 
     result->messages = errors.str();
@@ -501,8 +691,11 @@
     std::string errors;
     const auto target_env = additional_options ? additional_options->target_env
                                                : shaderc_target_env_default;
+    const uint32_t target_env_version =
+        additional_options ? additional_options->target_env_version : 0;
     const bool assembling_succeeded = shaderc_util::SpirvToolsAssemble(
         GetCompilerTargetEnv(target_env),
+        GetCompilerTargetEnvVersion(target_env_version),
         {source_assembly, source_assembly + source_assembly_size},
         &assembling_output_data, &errors);
     result->num_errors = !assembling_succeeded;
@@ -582,6 +775,7 @@
       *profile = shaderc_profile_none;
       return true;
     case EBadProfile:
+    case EProfileCount:
       return false;
   }
 
diff --git a/libshaderc/src/shaderc_cpp_test.cc b/libshaderc/src/shaderc_cpp_test.cc
index bf5aa33..af9ae30 100644
--- a/libshaderc/src/shaderc_cpp_test.cc
+++ b/libshaderc/src/shaderc_cpp_test.cc
@@ -14,25 +14,26 @@
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
+
 #include <memory>
 #include <thread>
 #include <unordered_map>
 
-#include "SPIRV/spirv.hpp"
-#include "spirv-tools/libspirv.hpp"
-
 #include "common_shaders_for_test.h"
 #include "shaderc/shaderc.hpp"
+#include "spirv-tools/libspirv.hpp"
+#include "spirv/unified1/spirv.hpp"
 
 namespace {
 
 using shaderc::AssemblyCompilationResult;
+using shaderc::CompileOptions;
 using shaderc::PreprocessedSourceCompilationResult;
 using shaderc::SpvCompilationResult;
-using shaderc::CompileOptions;
 using testing::Each;
 using testing::Eq;
 using testing::HasSubstr;
+using testing::Not;
 
 // Helper function to check if the compilation result indicates a successful
 // compilation.
@@ -362,7 +363,7 @@
   const AssemblyCompilationResult result = compiler_.CompileGlslToSpvAssembly(
       kMinimalShader, shaderc_glsl_vertex_shader, "shader", options_);
   EXPECT_TRUE(CompilationResultIsSuccess(result));
-  // This should work with both the glslang native disassembly format and the
+  // This should work with both the glslang disassembly format and the
   // SPIR-V Tools assembly format.
   EXPECT_THAT(CompilerOutputAsString(result), HasSubstr("Capability Shader"));
   EXPECT_THAT(CompilerOutputAsString(result), HasSubstr("MemoryModel"));
@@ -429,9 +430,12 @@
   // Forces the version and profile to 4242core, which is an unknown version.
   options_.SetForcedVersionProfile(4242 /*unknown version*/,
                                    shaderc_profile_core);
-  EXPECT_THAT(
-      CompilationWarnings(kMinimalShader, shaderc_glsl_vertex_shader, options_),
-      HasSubstr("warning: version 4242 is unknown.\n"));
+  auto const errs =
+      CompilationErrors(kMinimalShader, shaderc_glsl_vertex_shader, options_);
+  EXPECT_THAT(errs,
+              HasSubstr("warning: (version, profile) forced to be (4242, core),"
+                        " while in source code it is (140, none)\n"));
+  EXPECT_THAT(errs, HasSubstr("error: version not supported\n"));
 }
 
 TEST_F(CppInterface, ForcedVersionProfileVersionsBefore150) {
@@ -454,21 +458,29 @@
 
 TEST_F(CppInterface, GenerateDebugInfoBinary) {
   options_.SetGenerateDebugInfo();
-  // The output binary should contain the name of the vector: debug_info_sample
-  // as char array.
-  EXPECT_THAT(CompilationOutput(kMinimalDebugInfoShader,
-                                shaderc_glsl_vertex_shader, options_),
-              HasSubstr("debug_info_sample"));
+  const std::string binary_output =
+      CompilationOutput(kMinimalDebugInfoShader,
+                        shaderc_glsl_vertex_shader, options_);
+  // The binary output should contain the name of the vector (debug_info_sample)
+  // null-terminated, as well as the whole original source.
+  std::string vector_name("debug_info_sample");
+  vector_name.resize(vector_name.size() + 1);
+  EXPECT_THAT(binary_output, HasSubstr(vector_name));
+  EXPECT_THAT(binary_output, HasSubstr(kMinimalDebugInfoShader));
 }
 
 TEST_F(CppInterface, GenerateDebugInfoBinaryClonedOptions) {
   options_.SetGenerateDebugInfo();
   CompileOptions cloned_options(options_);
-  // The output binary should contain the name of the vector: debug_info_sample
-  // as char array.
-  EXPECT_THAT(CompilationOutput(kMinimalDebugInfoShader,
-                                shaderc_glsl_vertex_shader, cloned_options),
-              HasSubstr("debug_info_sample"));
+  const std::string binary_output =
+      CompilationOutput(kMinimalDebugInfoShader,
+                        shaderc_glsl_vertex_shader, cloned_options);
+  // The binary output should contain the name of the vector (debug_info_sample)
+  // null-terminated, as well as the whole original source.
+  std::string vector_name("debug_info_sample");
+  vector_name.resize(vector_name.size() + 1);
+  EXPECT_THAT(binary_output, HasSubstr(vector_name));
+  EXPECT_THAT(binary_output, HasSubstr(kMinimalDebugInfoShader));
 }
 
 TEST_F(CppInterface, GenerateDebugInfoDisassembly) {
@@ -502,6 +514,14 @@
   EXPECT_THAT(disassembly_text, HasSubstr("OpSource"));
 }
 
+TEST_F(CppInterface, CompileAndOptimizeWithLevelPerformance) {
+  options_.SetOptimizationLevel(shaderc_optimization_level_performance);
+  const std::string disassembly_text = AssemblyOutput(
+      kGlslMultipleFnShader, shaderc_glsl_fragment_shader, options_);
+  // Check that we do not have function calls anymore.
+  EXPECT_THAT(disassembly_text, Not(HasSubstr("OpFunctionCall")));
+}
+
 TEST_F(CppInterface, CompileAndOptimizeWithLevelSize) {
   options_.SetOptimizationLevel(shaderc_optimization_level_size);
   const std::string disassembly_text =
@@ -514,6 +534,31 @@
   EXPECT_THAT(disassembly_text, Not(HasSubstr("OpSource")));
 }
 
+TEST_F(CppInterface, CompileAndOptimizeForVulkan10Failure) {
+  options_.SetSourceLanguage(shaderc_source_language_hlsl);
+  options_.SetTargetEnvironment(shaderc_target_env_vulkan,
+                                shaderc_env_version_vulkan_1_0);
+  options_.SetOptimizationLevel(shaderc_optimization_level_performance);
+
+  EXPECT_THAT(CompilationErrors(kHlslWaveActiveSumeComputeShader,
+                                shaderc_compute_shader, options_),
+              // TODO(antiagainst): the error message can be improved to be more
+              // explicit regarding Vulkan 1.1
+              HasSubstr("compilation succeeded but failed to optimize: "
+                        "Invalid capability operand"));
+}
+
+TEST_F(CppInterface, CompileAndOptimizeForVulkan11Success) {
+  options_.SetSourceLanguage(shaderc_source_language_hlsl);
+  options_.SetTargetEnvironment(shaderc_target_env_vulkan,
+                                shaderc_env_version_vulkan_1_1);
+  options_.SetOptimizationLevel(shaderc_optimization_level_performance);
+
+  const std::string disassembly_text = AssemblyOutput(
+      kHlslWaveActiveSumeComputeShader, shaderc_compute_shader, options_);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpGroupNonUniformIAdd"));
+}
+
 TEST_F(CppInterface, FollowingOptLevelOverridesPreviousOne) {
   options_.SetOptimizationLevel(shaderc_optimization_level_size);
   // Optimization level settings overridden by
@@ -534,7 +579,7 @@
   options_.SetGenerateDebugInfo();
   const std::string disassembly_text =
       AssemblyOutput(kMinimalShader, shaderc_glsl_vertex_shader, options_);
-  for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
+  for (const auto& substring : kMinimalShaderDebugInfoDisassemblySubstrings) {
     EXPECT_THAT(disassembly_text, HasSubstr(substring));
   }
   // Check that we still have debug instructions.
@@ -548,7 +593,7 @@
   options_.SetOptimizationLevel(shaderc_optimization_level_size);
   const std::string disassembly_text =
       AssemblyOutput(kMinimalShader, shaderc_glsl_vertex_shader, options_);
-  for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
+  for (const auto& substring : kMinimalShaderDebugInfoDisassemblySubstrings) {
     EXPECT_THAT(disassembly_text, HasSubstr(substring));
   }
   // Check that we still have debug instructions.
@@ -661,7 +706,7 @@
       CompilesToValidSpv(compiler, test_case.shader_, test_case.shader_kind_));
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CompileStringTest, ValidShaderKind,
     testing::ValuesIn(std::vector<ShaderKindTestCase>{
         // Valid default shader kinds.
@@ -698,7 +743,7 @@
       CompilesToValidSpv(compiler, test_case.shader_, test_case.shader_kind_));
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CompileStringTest, InvalidShaderKind,
     testing::ValuesIn(std::vector<ShaderKindTestCase>{
         // Invalid default shader kind.
@@ -799,7 +844,7 @@
               HasSubstr(test_case.expected_substring()));
 }
 
-INSTANTIATE_TEST_CASE_P(CppInterface, IncluderTests,
+INSTANTIATE_TEST_SUITE_P(CppInterface, IncluderTests,
                         testing::ValuesIn(std::vector<IncluderTestCase>{
                             IncluderTestCase(
                                 // Fake file system.
@@ -890,17 +935,21 @@
 TEST_F(CppInterface, GlobalWarnings) {
   // By default the compiler will emit a warning as version 550 is an unknown
   // version.
+  options_.SetForcedVersionProfile(400, shaderc_profile_core);
   EXPECT_THAT(CompilationWarnings(kMinimalUnknownVersionShader,
                                   shaderc_glsl_vertex_shader, options_),
-              HasSubstr("warning: version 550 is unknown.\n"));
+              HasSubstr("(version, profile) forced to be (400, core),"
+                        " while in source code it is (550, none)\n"));
 }
 
 TEST_F(CppInterface, SuppressGlobalWarnings) {
   // Sets the compiler to suppress warnings, so that the unknown version warning
   // won't be emitted.
   options_.SetSuppressWarnings();
-  EXPECT_EQ("", CompilationWarnings(kMinimalUnknownVersionShader,
-                                    shaderc_glsl_vertex_shader, options_));
+  options_.SetForcedVersionProfile(400, shaderc_profile_core);
+  EXPECT_THAT(CompilationWarnings(kMinimalUnknownVersionShader,
+                                  shaderc_glsl_vertex_shader, options_),
+              Eq(""));
 }
 
 TEST_F(CppInterface, SuppressGlobalWarningsClonedOptions) {
@@ -908,29 +957,34 @@
   // won't be emitted, and the mode should be carried into any clone of the
   // original option object.
   options_.SetSuppressWarnings();
+  options_.SetForcedVersionProfile(400, shaderc_profile_core);
   CompileOptions cloned_options(options_);
-  EXPECT_EQ("",
-            CompilationWarnings(kMinimalUnknownVersionShader,
-                                shaderc_glsl_vertex_shader, cloned_options));
+  EXPECT_THAT(CompilationWarnings(kMinimalUnknownVersionShader,
+                                  shaderc_glsl_vertex_shader, cloned_options),
+              Eq(""));
 }
 
 TEST_F(CppInterface, GlobalWarningsAsErrors) {
   // Sets the compiler to make warnings into errors. So that the unknown
   // version warning will be emitted as an error and compilation should fail.
   options_.SetWarningsAsErrors();
+  options_.SetForcedVersionProfile(400, shaderc_profile_core);
   EXPECT_THAT(CompilationErrors(kMinimalUnknownVersionShader,
                                 shaderc_glsl_vertex_shader, options_),
-              HasSubstr("error: version 550 is unknown.\n"));
+              HasSubstr("(version, profile) forced to be (400, core),"
+                        " while in source code it is (550, none)\n"));
 }
 
 TEST_F(CppInterface, GlobalWarningsAsErrorsClonedOptions) {
   // Sets the compiler to make warnings into errors. This mode should be carried
   // into any clone of the original option object.
   options_.SetWarningsAsErrors();
+  options_.SetForcedVersionProfile(400, shaderc_profile_core);
   CompileOptions cloned_options(options_);
   EXPECT_THAT(CompilationErrors(kMinimalUnknownVersionShader,
                                 shaderc_glsl_vertex_shader, cloned_options),
-              HasSubstr("error: version 550 is unknown.\n"));
+              HasSubstr("(version, profile) forced to be (400, core),"
+                        " while in source code it is (550, none)\n"));
 }
 
 TEST_F(CppInterface, SuppressWarningsModeFirstOverridesWarningsAsErrorsMode) {
@@ -944,8 +998,10 @@
                                     shaderc_glsl_vertex_shader, options_));
 
   // Global warnings should be inhibited.
-  EXPECT_EQ("", CompilationWarnings(kMinimalUnknownVersionShader,
-                                    shaderc_glsl_vertex_shader, options_));
+  // However, the unknown version will cause an error.
+  EXPECT_THAT(CompilationErrors(kMinimalUnknownVersionShader,
+                                shaderc_glsl_vertex_shader, options_),
+              Eq("shader: error: version not supported\n"));
 }
 
 TEST_F(CppInterface, SuppressWarningsModeSecondOverridesWarningsAsErrorsMode) {
@@ -959,23 +1015,82 @@
                                     shaderc_glsl_vertex_shader, options_));
 
   // Global warnings should be inhibited.
-  EXPECT_EQ("", CompilationWarnings(kMinimalUnknownVersionShader,
-                                    shaderc_glsl_vertex_shader, options_));
+  // However, the unknown version will cause an error.
+  EXPECT_THAT(CompilationErrors(kMinimalUnknownVersionShader,
+                                shaderc_glsl_vertex_shader, options_),
+              Eq("shader: error: version not supported\n"));
 }
 
-TEST_F(CppInterface, TargetEnvCompileOptions) {
-  // Test shader compilation which requires opengl compatibility environment
+TEST_F(CppInterface, TargetEnvCompileOptionsOpenGLCompatibilityShadersFail) {
+  // Glslang does not support SPIR-V code generation for OpenGL compatibility
+  // profile.
   options_.SetTargetEnvironment(shaderc_target_env_opengl_compat, 0);
   const std::string kGlslShader =
-      R"(#version 100
+      R"(#version 150 compatibility
        uniform highp sampler2D tex;
        void main() {
          gl_FragColor = texture2D(tex, vec2(0.0,0.0));
        }
   )";
 
-  EXPECT_TRUE(
-      CompilationSuccess(kGlslShader, shaderc_glsl_fragment_shader, options_));
+  EXPECT_THAT(
+      CompilationErrors(kGlslShader, shaderc_glsl_fragment_shader, options_),
+      HasSubstr(
+          "compilation for SPIR-V does not support the compatibility profile"));
+}
+
+std::string BarrierComputeShader() {
+  return R"(#version 450
+    void main() { barrier(); })";
+}
+
+std::string SubgroupBarrierComputeShader() {
+  return R"(#version 450
+    #extension GL_KHR_shader_subgroup_basic : enable
+    void main() { subgroupBarrier(); })";
+}
+
+TEST_F(CppInterface, TargetEnvCompileOptionsVulkanEnvVulkan1_0ShaderSucceeds) {
+  options_.SetTargetEnvironment(shaderc_target_env_vulkan, 0);
+  EXPECT_TRUE(CompilationSuccess(BarrierComputeShader(),
+                                 shaderc_glsl_compute_shader, options_));
+}
+
+TEST_F(CppInterface, TargetEnvCompileOptionsVulkanEnvVulkan1_0ShaderFails) {
+  options_.SetTargetEnvironment(shaderc_target_env_vulkan, 0);
+  EXPECT_FALSE(CompilationSuccess(SubgroupBarrierComputeShader(),
+                                  shaderc_glsl_compute_shader, options_));
+}
+
+TEST_F(CppInterface,
+       TargetEnvCompileOptionsVulkan1_0EnvVulkan1_0ShaderSucceeds) {
+  options_.SetTargetEnvironment(shaderc_target_env_vulkan,
+                                shaderc_env_version_vulkan_1_0);
+  EXPECT_TRUE(CompilationSuccess(BarrierComputeShader(),
+                                 shaderc_glsl_compute_shader, options_));
+}
+
+TEST_F(CppInterface, TargetEnvCompileOptionsVulkan1_0EnvVulkan1_1ShaderFails) {
+  options_.SetTargetEnvironment(shaderc_target_env_vulkan,
+                                shaderc_env_version_vulkan_1_0);
+  EXPECT_FALSE(CompilationSuccess(SubgroupBarrierComputeShader(),
+                                  shaderc_glsl_compute_shader, options_));
+}
+
+TEST_F(CppInterface,
+       TargetEnvCompileOptionsVulkan1_1EnvVulkan1_0ShaderSucceeds) {
+  options_.SetTargetEnvironment(shaderc_target_env_vulkan,
+                                shaderc_env_version_vulkan_1_1);
+  EXPECT_TRUE(CompilationSuccess(BarrierComputeShader(),
+                                 shaderc_glsl_compute_shader, options_));
+}
+
+TEST_F(CppInterface,
+       TargetEnvCompileOptionsVulkan1_1EnvVulkan1_1ShaderSucceeds) {
+  options_.SetTargetEnvironment(shaderc_target_env_vulkan,
+                                shaderc_env_version_vulkan_1_1);
+  EXPECT_TRUE(CompilationSuccess(SubgroupBarrierComputeShader(),
+                                 shaderc_glsl_compute_shader, options_));
 }
 
 TEST_F(CppInterface, BeginAndEndOnSpvCompilationResult) {
@@ -1104,10 +1219,10 @@
 // offset.
 std::string ShaderWithTexOffset(int offset) {
   std::ostringstream oss;
-  oss <<
-    "#version 150\n"
-    "uniform sampler1D tex;\n"
-    "void main() { vec4 x = textureOffset(tex, 1.0, " << offset << "); }\n";
+  oss << "#version 450\n"
+         "layout (binding=0) uniform sampler1D tex;\n"
+         "void main() { vec4 x = textureOffset(tex, 1.0, "
+      << offset << "); }\n";
   return oss.str();
 }
 
@@ -1115,37 +1230,235 @@
 // two particular limits.
 TEST_F(CppInterface, LimitsTexelOffsetDefault) {
   EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(-9).c_str(),
-                                  shaderc_glsl_fragment_shader,
-                                  options_));
+                                  shaderc_glsl_fragment_shader, options_));
   EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(-8).c_str(),
-                                 shaderc_glsl_fragment_shader,
-                                 options_));
+                                 shaderc_glsl_fragment_shader, options_));
   EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(7).c_str(),
-                                 shaderc_glsl_fragment_shader,
-                                 options_));
+                                 shaderc_glsl_fragment_shader, options_));
   EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(8).c_str(),
-                                  shaderc_glsl_fragment_shader,
-                                  options_));
+                                  shaderc_glsl_fragment_shader, options_));
 }
 
 TEST_F(CppInterface, LimitsTexelOffsetLowerMinimum) {
   options_.SetLimit(shaderc_limit_min_program_texel_offset, -99);
   EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(-100).c_str(),
-                                  shaderc_glsl_fragment_shader,
-                                  options_));
+                                  shaderc_glsl_fragment_shader, options_));
   EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(-99).c_str(),
-                                 shaderc_glsl_fragment_shader,
-                                 options_));
+                                 shaderc_glsl_fragment_shader, options_));
 }
 
 TEST_F(CppInterface, LimitsTexelOffsetHigherMaximum) {
   options_.SetLimit(shaderc_limit_max_program_texel_offset, 10);
   EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(10).c_str(),
-                                 shaderc_glsl_fragment_shader,
-                                 options_));
+                                 shaderc_glsl_fragment_shader, options_));
   EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(11).c_str(),
-                                  shaderc_glsl_fragment_shader,
-                                  options_));
+                                  shaderc_glsl_fragment_shader, options_));
+}
+
+TEST_F(CppInterface, UniformsWithoutBindingsFailCompilation) {
+  CompileOptions options;
+  const std::string errors = CompilationErrors(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
+  EXPECT_THAT(errors,
+              HasSubstr("sampler/texture/image requires layout(binding=X)"));
+}
+
+TEST_F(CppInterface,
+       UniformsWithoutBindingsOptionSetAutoBindingsAssignsBindings) {
+  CompileOptions options;
+  options.SetAutoBindUniforms(true);
+  const std::string disassembly_text = AssemblyOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 4"));
+}
+
+TEST_F(CppInterface, SetBindingBaseForTextureAdjustsTextureBindingsOnly) {
+  CompileOptions options;
+  options.SetAutoBindUniforms(true);
+  options.SetBindingBase(shaderc_uniform_kind_texture, 44);
+  const std::string disassembly_text = AssemblyOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 44"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 3"));
+}
+
+TEST_F(CppInterface, SetBindingBaseForSamplerAdjustsSamplerBindingsOnly) {
+  CompileOptions options;
+  options.SetAutoBindUniforms(true);
+  options.SetBindingBase(shaderc_uniform_kind_sampler, 44);
+  const std::string disassembly_text = AssemblyOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 44"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 3"));
+}
+
+TEST_F(CppInterface, SetBindingBaseForImageAdjustsImageBindingsOnly) {
+  CompileOptions options;
+  options.SetAutoBindUniforms(true);
+  options.SetBindingBase(shaderc_uniform_kind_image, 44);
+  const std::string disassembly_text = AssemblyOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 44"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 45"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 2"));
+}
+
+TEST_F(CppInterface, SetBindingBaseForBufferAdjustsBufferBindingsOnly) {
+  CompileOptions options;
+  options.SetAutoBindUniforms(true);
+  options.SetBindingBase(shaderc_uniform_kind_buffer, 44);
+  const std::string disassembly_text = AssemblyOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 44"));
+}
+
+TEST_F(CppInterface, SetBindingBaseSurvivesCloning) {
+  CompileOptions options;
+  options.SetAutoBindUniforms(true);
+  options.SetBindingBase(shaderc_uniform_kind_texture, 40);
+  options.SetBindingBase(shaderc_uniform_kind_sampler, 50);
+  options.SetBindingBase(shaderc_uniform_kind_image, 60);
+  options.SetBindingBase(shaderc_uniform_kind_buffer, 70);
+  CompileOptions cloned_options(options);
+  const std::string disassembly_text =
+      AssemblyOutput(kShaderWithUniformsWithoutBindings,
+                     shaderc_glsl_vertex_shader, cloned_options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 40"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 50"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 60"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 61"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 70"));
+}
+
+TEST_F(CppInterface, GlslDefaultPackingUsed) {
+  CompileOptions options;
+  const std::string disassembly_text = AssemblyOutput(
+      kGlslShaderWeirdPacking, shaderc_glsl_vertex_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 16"));
+}
+
+TEST_F(CppInterface, HlslOffsetsOptionDisableRespected) {
+  CompileOptions options;
+  options.SetHlslOffsets(false);
+  const std::string disassembly_text = AssemblyOutput(
+      kGlslShaderWeirdPacking, shaderc_glsl_vertex_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 16"));
+}
+
+TEST_F(CppInterface, HlslOffsetsOptionEnableRespected) {
+  CompileOptions options;
+  options.SetHlslOffsets(true);
+  const std::string disassembly_text = AssemblyOutput(
+      kGlslShaderWeirdPacking, shaderc_glsl_vertex_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 4"));
+}
+
+TEST_F(CppInterface, HlslRegSetBindingForFragmentRespected) {
+  CompileOptions options;
+  options.SetSourceLanguage(shaderc_source_language_hlsl);
+  options.SetHlslRegisterSetAndBindingForStage(shaderc_fragment_shader, "t4",
+                                               "9", "16");
+  const std::string disassembly_text = AssemblyOutput(
+      kHlslFragShaderWithRegisters, shaderc_glsl_fragment_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 DescriptorSet 9"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 Binding 16"));
+}
+
+TEST_F(CppInterface, HlslRegSetBindingForDifferentStageIgnored) {
+  CompileOptions options;
+  options.SetSourceLanguage(shaderc_source_language_hlsl);
+  options.SetHlslRegisterSetAndBindingForStage(shaderc_vertex_shader, "t4", "9",
+                                               "16");
+  const std::string disassembly_text = AssemblyOutput(
+      kHlslFragShaderWithRegisters, shaderc_glsl_fragment_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 DescriptorSet 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 Binding 4"));
+}
+
+TEST_F(CppInterface, HlslRegSetBindingForAllStagesRespected) {
+  CompileOptions options;
+  options.SetSourceLanguage(shaderc_source_language_hlsl);
+  options.SetHlslRegisterSetAndBinding("t4", "9", "16");
+  const std::string disassembly_text = AssemblyOutput(
+      kHlslFragShaderWithRegisters, shaderc_glsl_fragment_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 DescriptorSet 9"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 Binding 16"));
+}
+
+TEST_F(CppInterface, HlslFunctionality1OffByDefault) {
+  CompileOptions options;
+  options.SetSourceLanguage(shaderc_source_language_hlsl);
+  // The counter needs a binding, and there is no way to set it in the shader
+  // source.
+  options.SetAutoBindUniforms(true);
+  const std::string disassembly_text = AssemblyOutput(
+      kHlslShaderWithCounterBuffer, shaderc_glsl_fragment_shader, options);
+  EXPECT_THAT(disassembly_text, Not(HasSubstr("OpDecorateString")));
+}
+
+TEST_F(CppInterface, HlslFunctionality1Respected) {
+  CompileOptions options;
+  options.SetSourceLanguage(shaderc_source_language_hlsl);
+  // The counter needs a binding, and there is no way to set it in the shader
+  // source.  https://github.com/KhronosGroup/glslang/issues/1616
+  options.SetAutoBindUniforms(true);
+  options.SetHlslFunctionality1(true);
+  const std::string disassembly_text = AssemblyOutput(
+      kHlslShaderWithCounterBuffer, shaderc_glsl_fragment_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorateString"));
+}
+
+TEST_F(CppInterface, HlslFunctionality1SurvivesCloning) {
+  CompileOptions options;
+  options.SetSourceLanguage(shaderc_source_language_hlsl);
+  options.SetHlslFunctionality1(true);
+  // The counter needs a binding, and there is no way to set it in the shader
+  // source. https://github.com/KhronosGroup/glslang/issues/1616
+  options.SetAutoBindUniforms(true);
+  CompileOptions cloned_options(options);
+  const std::string disassembly_text = AssemblyOutput(
+      kHlslShaderWithCounterBuffer, shaderc_glsl_fragment_shader, cloned_options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorateString"));
+}
+
+TEST_F(CppInterface, NanClampDefaultsOff) {
+  CompileOptions options;
+  const std::string disassembly_text = AssemblyOutput(
+      kGlslShaderWithClamp, shaderc_glsl_fragment_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 FClamp"));
+}
+
+TEST_F(CppInterface, NanClampMapsClampToNClamp) {
+  CompileOptions options;
+  options.SetNanClamp(true);
+  const std::string disassembly_text = AssemblyOutput(
+      kGlslShaderWithClamp, shaderc_glsl_fragment_shader, options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 NClamp"));
+}
+
+TEST_F(CppInterface, NanClampSurvivesCloning) {
+  CompileOptions options;
+  options.SetNanClamp(true);
+  CompileOptions cloned_options(options);
+  const std::string disassembly_text = AssemblyOutput(
+      kGlslShaderWithClamp, shaderc_glsl_fragment_shader, cloned_options);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 NClamp"));
 }
 
 }  // anonymous namespace
diff --git a/libshaderc/src/shaderc_private.h b/libshaderc/src/shaderc_private.h
index de8fd07..ff35020 100644
--- a/libshaderc/src/shaderc_private.h
+++ b/libshaderc/src/shaderc_private.h
@@ -15,12 +15,14 @@
 #ifndef LIBSHADERC_SRC_SHADERC_PRIVATE_H_
 #define LIBSHADERC_SRC_SHADERC_PRIVATE_H_
 
+#include <cassert>
 #include <cstdint>
 #include <string>
 #include <vector>
 
 #include "shaderc/shaderc.h"
 
+#include "libshaderc_util/compiler.h"
 #include "spirv-tools/libspirv.h"
 
 // Described in shaderc.h.
@@ -88,7 +90,50 @@
 }
 
 struct shaderc_compiler {
-  shaderc_util::GlslangInitializer* initializer;
+  std::unique_ptr<shaderc_util::GlslangInitializer> initializer;
 };
 
+// Converts a shader stage from shaderc_shader_kind into a shaderc_util::Compiler::Stage.
+// This is only valid for a specifically named shader stage, e.g. vertex through fragment,
+// or compute.
+inline shaderc_util::Compiler::Stage shaderc_convert_specific_stage(
+    shaderc_shader_kind kind) {
+  switch (kind) {
+    case shaderc_vertex_shader:
+      return shaderc_util::Compiler::Stage::Vertex;
+    case shaderc_fragment_shader:
+      return shaderc_util::Compiler::Stage::Fragment;
+    case shaderc_tess_control_shader:
+      return shaderc_util::Compiler::Stage::TessControl;
+    case shaderc_tess_evaluation_shader:
+      return shaderc_util::Compiler::Stage::TessEval;
+    case shaderc_geometry_shader:
+      return shaderc_util::Compiler::Stage::Geometry;
+    case shaderc_compute_shader:
+      return shaderc_util::Compiler::Stage::Compute;
+    case shaderc_raygen_shader:
+      return shaderc_util::Compiler::Stage::RayGenNV;
+    case shaderc_intersection_shader:
+      return shaderc_util::Compiler::Stage::IntersectNV;
+    case shaderc_anyhit_shader:
+      return shaderc_util::Compiler::Stage::AnyHitNV;
+    case shaderc_closesthit_shader:
+      return shaderc_util::Compiler::Stage::ClosestHitNV;
+    case shaderc_miss_shader:
+      return shaderc_util::Compiler::Stage::MissNV;
+    case shaderc_callable_shader:
+      return shaderc_util::Compiler::Stage::CallableNV;
+    case shaderc_task_shader:
+      return shaderc_util::Compiler::Stage::TaskNV;
+    case shaderc_mesh_shader:
+      return shaderc_util::Compiler::Stage::MeshNV;
+    default:
+      // We don't care about the other kinds.
+      break;
+  }
+  // This should not occur.
+  assert(false && "Should have specified a specific stage");
+  return shaderc_util::Compiler::Stage::TessEval;
+}
+
 #endif  // LIBSHADERC_SRC_SHADERC_PRIVATE_H_
diff --git a/libshaderc/src/shaderc_private_test.cc b/libshaderc/src/shaderc_private_test.cc
new file mode 100644
index 0000000..72a7577
--- /dev/null
+++ b/libshaderc/src/shaderc_private_test.cc
@@ -0,0 +1,50 @@
+// Copyright 2017 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <gmock/gmock.h>
+#include "shaderc_private.h"
+
+namespace {
+
+TEST(ConvertSpecificStage, Exhaustive) {
+  EXPECT_EQ(shaderc_util::Compiler::Stage::Vertex,
+            shaderc_convert_specific_stage(shaderc_vertex_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::Fragment,
+            shaderc_convert_specific_stage(shaderc_fragment_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::TessControl,
+            shaderc_convert_specific_stage(shaderc_tess_control_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::TessEval,
+            shaderc_convert_specific_stage(shaderc_tess_evaluation_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::Geometry,
+            shaderc_convert_specific_stage(shaderc_geometry_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::Compute,
+            shaderc_convert_specific_stage(shaderc_compute_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::RayGenNV,
+            shaderc_convert_specific_stage(shaderc_raygen_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::AnyHitNV,
+            shaderc_convert_specific_stage(shaderc_anyhit_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::ClosestHitNV,
+            shaderc_convert_specific_stage(shaderc_closesthit_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::IntersectNV,
+            shaderc_convert_specific_stage(shaderc_intersection_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::MissNV,
+            shaderc_convert_specific_stage(shaderc_miss_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::CallableNV,
+            shaderc_convert_specific_stage(shaderc_callable_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::TaskNV,
+            shaderc_convert_specific_stage(shaderc_task_shader));
+  EXPECT_EQ(shaderc_util::Compiler::Stage::MeshNV,
+            shaderc_convert_specific_stage(shaderc_mesh_shader));
+}
+}  // anonymous namespace
diff --git a/libshaderc/src/shaderc_test.cc b/libshaderc/src/shaderc_test.cc
index 927a53d..3162468 100644
--- a/libshaderc/src/shaderc_test.cc
+++ b/libshaderc/src/shaderc_test.cc
@@ -12,21 +12,23 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "shaderc/shaderc.h"
+
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
+
 #include <memory>
 #include <thread>
 #include <unordered_map>
 
-#include "SPIRV/spirv.hpp"
-
 #include "common_shaders_for_test.h"
-#include "shaderc/shaderc.h"
+#include "spirv/unified1/spirv.hpp"
 
 namespace {
 
 using testing::Each;
 using testing::HasSubstr;
+using testing::Not;
 
 TEST(Init, MultipleCalls) {
   shaderc_compiler_t compiler1, compiler2, compiler3;
@@ -227,7 +229,7 @@
     EXPECT_TRUE(CompilationResultIsSuccess(comp.result())) << kind << '\n'
                                                            << shader;
     return shaderc_result_get_error_message(comp.result());
-  };
+  }
 
   // Compiles a shader, expects compilation failure, and returns the messages.
   const std::string CompilationErrors(
@@ -241,7 +243,7 @@
                                                             << shader;
     EXPECT_EQ(0u, shaderc_result_get_length(comp.result()));
     return shaderc_result_get_error_message(comp.result());
-  };
+  }
 
   // Compiles a shader and returns the messages.
   const std::string CompilationMessages(
@@ -251,7 +253,7 @@
     const Compilation comp(compiler_.get_compiler_handle(), shader, kind,
                            "shader", "main", options, output_type);
     return shaderc_result_get_error_message(comp.result());
-  };
+  }
 
   // Compiles a shader, expects compilation success, and returns the output
   // bytes.
@@ -261,15 +263,18 @@
       OutputType output_type = OutputType::SpirvBinary) {
     const Compilation comp(compiler_.get_compiler_handle(), shader, kind,
                            "shader", "main", options, output_type);
-    EXPECT_TRUE(CompilationResultIsSuccess(comp.result())) << kind << '\n'
-                                                           << shader;
+    EXPECT_TRUE(CompilationResultIsSuccess(comp.result()))
+        << "shader kind: " << kind << "\nerror message: "
+        << shaderc_result_get_error_message(comp.result())
+        << "\nshader source code: \n"
+        << shader;
     // Use string(const char* s, size_t n) constructor instead of
     // string(const char* s) to make sure the string has complete binary data.
     // string(const char* s) assumes a null-terminated C-string, which will cut
     // the binary data when it sees a '\0' byte.
     return std::string(shaderc_result_get_bytes(comp.result()),
                        shaderc_result_get_length(comp.result()));
-  };
+  }
 
   Compiler compiler_;
   compile_options_ptr options_;
@@ -493,7 +498,7 @@
 
 TEST_F(CompileStringWithOptionsTest, DisassemblyOption) {
   ASSERT_NE(nullptr, compiler_.get_compiler_handle());
-  // This should work with both the glslang native assembly format and the
+  // This should work with both the glslang assembly format and the
   // SPIR-V tools assembly format.
   const std::string disassembly_text =
       CompilationOutput(kMinimalShader, shaderc_glsl_vertex_shader,
@@ -568,9 +573,15 @@
       options_.get(), 4242 /*unknown version*/, shaderc_profile_core);
   ASSERT_NE(nullptr, compiler_.get_compiler_handle());
   // Warning message should complain about the unknown version.
-  EXPECT_THAT(CompilationWarnings(kMinimalShader, shaderc_glsl_vertex_shader,
-                                  options_.get()),
-              HasSubstr("warning: version 4242 is unknown.\n"));
+  //
+  // Also, Glslang errors out on unkown versions, due to commit:
+  // https://github.com/KhronosGroup/glslang/commit/9353f1afab8d1c2b1811c6acd807675128eaabc5
+  const auto errs = CompilationErrors(
+      kMinimalShader, shaderc_glsl_vertex_shader, options_.get());
+  EXPECT_THAT(
+      errs, HasSubstr("warning: (version, profile) forced to be (4242, core), "
+                      "while in source code it is (140, none)\n"));
+  EXPECT_THAT(errs, HasSubstr("error: version not supported\n"));
 }
 
 TEST_F(CompileStringWithOptionsTest, ForcedVersionProfileVersionsBefore150) {
@@ -598,10 +609,15 @@
 TEST_F(CompileStringWithOptionsTest, GenerateDebugInfoBinary) {
   shaderc_compile_options_set_generate_debug_info(options_.get());
   ASSERT_NE(nullptr, compiler_.get_compiler_handle());
-  // The binary output should contain the name of the vector: debug_info_sample.
-  EXPECT_THAT(CompilationOutput(kMinimalDebugInfoShader,
-                                shaderc_glsl_vertex_shader, options_.get()),
-              HasSubstr("debug_info_sample"));
+  const std::string binary_output =
+      CompilationOutput(kMinimalDebugInfoShader,
+                        shaderc_glsl_vertex_shader, options_.get());
+  // The binary output should contain the name of the vector (debug_info_sample)
+  // null-terminated, as well as the whole original source.
+  std::string vector_name("debug_info_sample");
+  vector_name.resize(vector_name.size() + 1);
+  EXPECT_THAT(binary_output, HasSubstr(vector_name));
+  EXPECT_THAT(binary_output, HasSubstr(kMinimalDebugInfoShader));
 }
 
 TEST_F(CompileStringWithOptionsTest, GenerateDebugInfoBinaryClonedOptions) {
@@ -609,11 +625,15 @@
   compile_options_ptr cloned_options(
       shaderc_compile_options_clone(options_.get()));
   ASSERT_NE(nullptr, compiler_.get_compiler_handle());
-  // The binary output should contain the name of the vector: debug_info_sample.
-  EXPECT_THAT(
-      CompilationOutput(kMinimalDebugInfoShader, shaderc_glsl_vertex_shader,
-                        cloned_options.get()),
-      HasSubstr("debug_info_sample"));
+  const std::string binary_output =
+      CompilationOutput(kMinimalDebugInfoShader,
+                        shaderc_glsl_vertex_shader, cloned_options.get());
+  // The binary output should contain the name of the vector (debug_info_sample)
+  // null-terminated, as well as the whole original source.
+  std::string vector_name("debug_info_sample");
+  vector_name.resize(vector_name.size() + 1);
+  EXPECT_THAT(binary_output, HasSubstr(vector_name));
+  EXPECT_THAT(binary_output, HasSubstr(kMinimalDebugInfoShader));
 }
 
 TEST_F(CompileStringWithOptionsTest, GenerateDebugInfoDisassembly) {
@@ -642,6 +662,16 @@
   EXPECT_THAT(disassembly_text, HasSubstr("OpSource"));
 }
 
+TEST_F(CompileStringWithOptionsTest, CompileAndOptimizeWithLevelPerformance) {
+  shaderc_compile_options_set_optimization_level(
+      options_.get(), shaderc_optimization_level_performance);
+  const std::string disassembly_text =
+      CompilationOutput(kGlslMultipleFnShader, shaderc_glsl_fragment_shader,
+                        options_.get(), OutputType::SpirvAssemblyText);
+  // Check that we do not have function calls anymore.
+  EXPECT_THAT(disassembly_text, Not(HasSubstr("OpFunctionCall")));
+}
+
 TEST_F(CompileStringWithOptionsTest, CompileAndOptimizeWithLevelSize) {
   shaderc_compile_options_set_optimization_level(
       options_.get(), shaderc_optimization_level_size);
@@ -656,6 +686,34 @@
   EXPECT_THAT(disassembly_text, Not(HasSubstr("OpSource")));
 }
 
+TEST_F(CompileStringWithOptionsTest, CompileAndOptimizeForVulkan10Failure) {
+  shaderc_compile_options_set_source_language(options_.get(),
+                                              shaderc_source_language_hlsl);
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_0);
+  shaderc_compile_options_set_optimization_level(
+      options_.get(), shaderc_optimization_level_performance);
+
+  EXPECT_FALSE(CompilesToValidSpv(compiler_, kHlslWaveActiveSumeComputeShader,
+                                  shaderc_compute_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest, CompileAndOptimizeForVulkan11Success) {
+  shaderc_compile_options_set_source_language(options_.get(),
+                                              shaderc_source_language_hlsl);
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_1);
+  shaderc_compile_options_set_optimization_level(
+      options_.get(), shaderc_optimization_level_performance);
+
+  const std::string disassembly_text = CompilationOutput(
+      kHlslWaveActiveSumeComputeShader, shaderc_compute_shader, options_.get(),
+      OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpGroupNonUniformIAdd"));
+}
+
 TEST_F(CompileStringWithOptionsTest, FollowingOptLevelOverridesPreviousOne) {
   shaderc_compile_options_set_optimization_level(
       options_.get(), shaderc_optimization_level_size);
@@ -682,7 +740,7 @@
   const std::string disassembly_text =
       CompilationOutput(kMinimalShader, shaderc_glsl_vertex_shader,
                         options_.get(), OutputType::SpirvAssemblyText);
-  for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
+  for (const auto& substring : kMinimalShaderDebugInfoDisassemblySubstrings) {
     EXPECT_THAT(disassembly_text, HasSubstr(substring));
   }
   // Check that we still have debug instructions.
@@ -699,7 +757,7 @@
   const std::string disassembly_text =
       CompilationOutput(kMinimalShader, shaderc_glsl_vertex_shader,
                         options_.get(), OutputType::SpirvAssemblyText);
-  for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
+  for (const auto& substring : kMinimalShaderDebugInfoDisassemblySubstrings) {
     EXPECT_THAT(disassembly_text, HasSubstr(substring));
   }
   // Check that we still have debug instructions.
@@ -755,7 +813,7 @@
       CompilesToValidSpv(compiler, test_case.shader_, test_case.shader_kind_));
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CompileStringTest, ValidShaderKind,
     testing::ValuesIn(std::vector<ShaderKindTestCase>{
         // Valid default shader kinds.
@@ -766,6 +824,8 @@
         {kTessControlOnlyShader, shaderc_glsl_default_tess_control_shader},
         {kTessEvaluationOnlyShader,
          shaderc_glsl_default_tess_evaluation_shader},
+        {kNVMeshShader, shaderc_glsl_default_mesh_shader},
+        {kNVTaskShader, shaderc_glsl_default_task_shader},
 
         // #pragma annotation overrides default shader kinds.
         {kVertexOnlyShaderWithPragma, shaderc_glsl_default_compute_shader},
@@ -777,6 +837,13 @@
         {kGeometryOnlyShaderWithPragma,
          shaderc_glsl_default_tess_evaluation_shader},
         {kComputeOnlyShaderWithPragma, shaderc_glsl_default_geometry_shader},
+        {kNVMeshShaderWithPragma, shaderc_glsl_default_geometry_shader},
+        {kNVTaskShaderWithPragma, shaderc_glsl_default_geometry_shader},
+
+        // Infer from source
+        {kVertexOnlyShaderWithPragma, shaderc_glsl_infer_from_source},
+        {kNVMeshShaderWithPragma, shaderc_glsl_infer_from_source},
+        {kNVTaskShaderWithPragma, shaderc_glsl_infer_from_source},
 
         // Specified non-default shader kind overrides #pragma annotation.
         {kVertexOnlyShaderWithInvalidPragma, shaderc_glsl_vertex_shader},
@@ -792,7 +859,7 @@
       CompilesToValidSpv(compiler, test_case.shader_, test_case.shader_kind_));
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CompileStringTest, InvalidShaderKind,
     testing::ValuesIn(std::vector<ShaderKindTestCase>{
         // Invalid default shader kind.
@@ -916,7 +983,7 @@
               HasSubstr(test_case.expected_substring()));
 }
 
-INSTANTIATE_TEST_CASE_P(CompileStringTest, IncluderTests,
+INSTANTIATE_TEST_SUITE_P(CompileStringTest, IncluderTests,
                         testing::ValuesIn(std::vector<IncluderTestCase>{
                             IncluderTestCase(
                                 // Fake file system.
@@ -983,22 +1050,30 @@
 
 TEST_F(CompileStringWithOptionsTest, GlobalWarnings) {
   ASSERT_NE(nullptr, compiler_.get_compiler_handle());
+  shaderc_compile_options_set_forced_version_profile(options_.get(), 400,
+                                                     shaderc_profile_core);
   EXPECT_THAT(CompilationWarnings(kMinimalUnknownVersionShader,
                                   shaderc_glsl_vertex_shader, options_.get()),
-              HasSubstr("version 550 is unknown.\n"));
+              HasSubstr("(version, profile) forced to be (400, core),"
+                        " while in source code it is (550, none)\n"));
 }
 
 TEST_F(CompileStringWithOptionsTest, GlobalWarningsAsErrors) {
   shaderc_compile_options_set_warnings_as_errors(options_.get());
   ASSERT_NE(nullptr, compiler_.get_compiler_handle());
+  shaderc_compile_options_set_forced_version_profile(options_.get(), 400,
+                                                     shaderc_profile_core);
   EXPECT_THAT(CompilationErrors(kMinimalUnknownVersionShader,
                                 shaderc_glsl_vertex_shader, options_.get()),
-              HasSubstr("error: version 550 is unknown.\n"));
+              HasSubstr("(version, profile) forced to be (400, core),"
+                        " while in source code it is (550, none)\n"));
 }
 
 TEST_F(CompileStringWithOptionsTest, SuppressGlobalWarnings) {
   ASSERT_NE(nullptr, compiler_.get_compiler_handle());
   shaderc_compile_options_set_suppress_warnings(options_.get());
+  shaderc_compile_options_set_forced_version_profile(options_.get(), 400,
+                                                     shaderc_profile_core);
   EXPECT_EQ("",
             CompilationWarnings(kMinimalUnknownVersionShader,
                                 shaderc_glsl_vertex_shader, options_.get()));
@@ -1061,11 +1136,11 @@
                                  shaderc_glsl_vertex_shader, options_.get()));
 }
 
-TEST_F(CompileStringWithOptionsTest,
-       TargetEnvRespectedWhenCompilingOpenGLCompatibilityShaderToBinary) {
-  // Confirm that kOpenGLCompatibilityFragmentShader compiles with
-  // shaderc_target_env_opengl_compat.  When targeting OpenGL core profile
-  // or Vulkan, it should fail to compile.
+TEST_F(
+    CompileStringWithOptionsTest,
+    TargetEnvRespectedWhenCompilingOpenGLCompatibilityShaderToBinaryAndAlwaysFails) {
+  // Glslang does not support generating SPIR-V for compatibility profile
+  // shaders.
 
   EXPECT_FALSE(CompilesToValidSpv(compiler_, kOpenGLCompatibilityFragmentShader,
                                   shaderc_glsl_fragment_shader,
@@ -1073,8 +1148,9 @@
 
   shaderc_compile_options_set_target_env(options_.get(),
                                          shaderc_target_env_opengl_compat, 0);
-  EXPECT_TRUE(CompilesToValidSpv(compiler_, kOpenGLCompatibilityFragmentShader,
-                                 shaderc_glsl_fragment_shader, options_.get()));
+  EXPECT_FALSE(CompilesToValidSpv(compiler_, kOpenGLCompatibilityFragmentShader,
+                                  shaderc_glsl_fragment_shader,
+                                  options_.get()));
 
   shaderc_compile_options_set_target_env(options_.get(),
                                          shaderc_target_env_opengl, 0);
@@ -1103,8 +1179,116 @@
                                          shaderc_target_env_opengl, 0);
   EXPECT_TRUE(CompilesToValidSpv(compiler_, kOpenGLVertexShader,
                                  shaderc_glsl_vertex_shader, options_.get()));
+}
 
-  // TODO(dneto): Check what happens when targeting Vulkan.
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_0ShaderToVulkan1_0Succeeds) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_0);
+  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderComputeBarrier,
+                                 shaderc_glsl_compute_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_0ShaderToVulkan1_1Succeeds) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_1);
+  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderComputeBarrier,
+                                 shaderc_glsl_compute_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_1ShaderToVulkan1_0Fails) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_0);
+  EXPECT_FALSE(CompilesToValidSpv(compiler_, kGlslShaderComputeSubgroupBarrier,
+                                  shaderc_glsl_compute_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_1ShaderToVulkan1_1Succeeds) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_1);
+  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderComputeSubgroupBarrier,
+                                 shaderc_glsl_compute_shader, options_.get()));
+}
+
+// task shader
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_0TaskShaderToVulkan1_0Succeeds) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_0);
+  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderTaskBarrier,
+                                 shaderc_glsl_task_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_0TaskShaderToVulkan1_1Succeeds) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_1);
+  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderTaskBarrier,
+                                 shaderc_glsl_task_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_1TaskShaderToVulkan1_0Fails) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_0);
+  EXPECT_FALSE(CompilesToValidSpv(compiler_, kGlslShaderTaskSubgroupBarrier,
+                                  shaderc_glsl_task_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_1TaskShaderToVulkan1_1Succeeds) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_1);
+  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderTaskSubgroupBarrier,
+                                 shaderc_glsl_task_shader, options_.get()));
+}
+
+// mesh shader
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_0MeshShaderToVulkan1_0Succeeds) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_0);
+  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderMeshBarrier,
+                                 shaderc_glsl_mesh_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_0MeshShaderToVulkan1_1Succeeds) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_1);
+  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderMeshBarrier,
+                                 shaderc_glsl_mesh_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_1MeshShaderToVulkan1_0Fails) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_0);
+  EXPECT_FALSE(CompilesToValidSpv(compiler_, kGlslShaderMeshSubgroupBarrier,
+                                  shaderc_glsl_mesh_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       TargetEnvRespectedWhenCompilingVulkan1_1MeshShaderToVulkan1_1Succeeds) {
+  shaderc_compile_options_set_target_env(options_.get(),
+                                         shaderc_target_env_vulkan,
+                                         shaderc_env_version_vulkan_1_1);
+  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderMeshSubgroupBarrier,
+                                 shaderc_glsl_mesh_shader, options_.get()));
 }
 
 TEST_F(CompileStringWithOptionsTest,
@@ -1272,7 +1456,7 @@
   }
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     HelperMethods, ParseVersionProfileTest,
     testing::ValuesIn(std::vector<ParseVersionProfileTestCase>{
         // Valid version profiles
@@ -1377,10 +1561,10 @@
 // offset.
 std::string ShaderWithTexOffset(int offset) {
   std::ostringstream oss;
-  oss <<
-    "#version 150\n"
-    "uniform sampler1D tex;\n"
-    "void main() { vec4 x = textureOffset(tex, 1.0, " << offset << "); }\n";
+  oss << "#version 450\n"
+         "layout (binding=0) uniform sampler1D tex;\n"
+         "void main() { vec4 x = textureOffset(tex, 1.0, "
+      << offset << "); }\n";
   return oss.str();
 }
 
@@ -1391,38 +1575,296 @@
                                   shaderc_glsl_fragment_shader,
                                   options_.get()));
   EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(-8).c_str(),
-                                 shaderc_glsl_fragment_shader,
-                                 options_.get()));
+                                 shaderc_glsl_fragment_shader, options_.get()));
   EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(7).c_str(),
-                                 shaderc_glsl_fragment_shader,
-                                 options_.get()));
+                                 shaderc_glsl_fragment_shader, options_.get()));
   EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(8).c_str(),
                                   shaderc_glsl_fragment_shader,
                                   options_.get()));
 }
 
 TEST_F(CompileStringTest, LimitsTexelOffsetLowerMinimum) {
-  shaderc_compile_options_set_limit(options_.get(),
-                                    shaderc_limit_min_program_texel_offset,
-                                    -99);
+  shaderc_compile_options_set_limit(
+      options_.get(), shaderc_limit_min_program_texel_offset, -99);
   EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(-100).c_str(),
                                   shaderc_glsl_fragment_shader,
                                   options_.get()));
   EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(-99).c_str(),
-                                 shaderc_glsl_fragment_shader,
-                                 options_.get()));
+                                 shaderc_glsl_fragment_shader, options_.get()));
 }
 
 TEST_F(CompileStringTest, LimitsTexelOffsetHigherMaximum) {
   shaderc_compile_options_set_limit(options_.get(),
-                                    shaderc_limit_max_program_texel_offset,
-                                    10);
+                                    shaderc_limit_max_program_texel_offset, 10);
   EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(10).c_str(),
-                                 shaderc_glsl_fragment_shader,
-                                 options_.get()));
+                                 shaderc_glsl_fragment_shader, options_.get()));
   EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(11).c_str(),
                                   shaderc_glsl_fragment_shader,
                                   options_.get()));
 }
 
+TEST_F(CompileStringWithOptionsTest, UniformsWithoutBindingsFailCompilation) {
+  const std::string errors =
+      CompilationErrors(kShaderWithUniformsWithoutBindings,
+                        shaderc_glsl_vertex_shader, options_.get());
+  EXPECT_THAT(errors,
+              HasSubstr("sampler/texture/image requires layout(binding=X)"));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       UniformsWithoutBindingsOptionSetAutoBindingsAssignsBindings) {
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  const std::string disassembly_text = CompilationOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
+      options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 4"));
+}
+
+TEST_F(CompileStringWithOptionsTest, AutoBindUniformsOptionsSurvivesCloning) {
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  compile_options_ptr cloned_options(
+      shaderc_compile_options_clone(options_.get()));
+  const std::string disassembly_text = CompilationOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
+      cloned_options.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 4"));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       SetBindingBaseForTextureAdjustsTextureBindingsOnly) {
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  shaderc_compile_options_set_binding_base(options_.get(),
+                                           shaderc_uniform_kind_texture, 44);
+  const std::string disassembly_text = CompilationOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
+      options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 44"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 3"));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       SetBindingBaseForSamplerAdjustsSamplerBindingsOnly) {
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  shaderc_compile_options_set_binding_base(options_.get(),
+                                           shaderc_uniform_kind_sampler, 44);
+  const std::string disassembly_text = CompilationOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
+      options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 44"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 3"));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       SetBindingBaseForImageAdjustsImageBindingsOnly) {
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  shaderc_compile_options_set_binding_base(options_.get(),
+                                           shaderc_uniform_kind_image, 44);
+  const std::string disassembly_text = CompilationOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
+      options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 44"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 45"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 2"));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       SetBindingBaseForBufferAdjustsBufferBindingsOnly) {
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  shaderc_compile_options_set_binding_base(options_.get(),
+                                           shaderc_uniform_kind_buffer, 44);
+  const std::string disassembly_text = CompilationOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
+      options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 44"));
+}
+
+TEST_F(CompileStringWithOptionsTest, SetBindingBaseSurvivesCloning) {
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  shaderc_compile_options_set_binding_base(options_.get(),
+                                           shaderc_uniform_kind_texture, 40);
+  shaderc_compile_options_set_binding_base(options_.get(),
+                                           shaderc_uniform_kind_sampler, 50);
+  shaderc_compile_options_set_binding_base(options_.get(),
+                                           shaderc_uniform_kind_image, 60);
+  shaderc_compile_options_set_binding_base(options_.get(),
+                                           shaderc_uniform_kind_buffer, 70);
+  compile_options_ptr cloned_options(
+      shaderc_compile_options_clone(options_.get()));
+  const std::string disassembly_text = CompilationOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
+      cloned_options.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 40"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 50"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 60"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 61"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 70"));
+}
+
+TEST(Compiler, IncludeWithoutOptionsReturnsValidError) {
+  auto compiler = shaderc_compiler_initialize();
+  const char source[] = "#version 450\n#include \"no where\"";
+  auto result = shaderc_compile_into_spv(compiler, source, strlen(source),
+                                         shaderc_glsl_vertex_shader, "file",
+                                         "main", nullptr);
+  EXPECT_EQ(shaderc_compilation_status_compilation_error,
+            shaderc_result_get_compilation_status(result));
+  EXPECT_THAT(shaderc_result_get_error_message(result),
+              HasSubstr("error: '#include' : #error unexpected include "
+                        "directive for header name: no where"));
+
+  shaderc_result_release(result);
+  shaderc_compiler_release(compiler);
+}
+
+TEST_F(
+    CompileStringWithOptionsTest,
+    SetBindingBaseForTextureForVertexAdjustsTextureBindingsOnlyCompilingAsVertex) {
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  shaderc_compile_options_set_binding_base_for_stage(
+      options_.get(), shaderc_vertex_shader, shaderc_uniform_kind_texture, 100);
+  const std::string disassembly_text = CompilationOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_vertex_shader, options_.get(),
+      OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 100"))
+      << disassembly_text;
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 3"));
+}
+
+TEST_F(CompileStringWithOptionsTest,
+       SetBindingBaseForTextureForVertexIgnoredWhenCompilingAsFragment) {
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  // This is ignored since we're compiling as a different stage.
+  shaderc_compile_options_set_binding_base_for_stage(
+      options_.get(), shaderc_vertex_shader, shaderc_uniform_kind_texture, 100);
+  const std::string disassembly_text = CompilationOutput(
+      kShaderWithUniformsWithoutBindings, shaderc_fragment_shader,
+      options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 4"));
+}
+
+TEST_F(CompileStringWithOptionsTest, GlslDefaultPackingUsed) {
+  const std::string disassembly_text =
+      CompilationOutput(kGlslShaderWeirdPacking, shaderc_vertex_shader,
+                        options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 16"));
+}
+
+TEST_F(CompileStringWithOptionsTest, HlslOffsetsOptionDisableRespected) {
+  shaderc_compile_options_set_hlsl_offsets(options_.get(), false);
+  const std::string disassembly_text =
+      CompilationOutput(kGlslShaderWeirdPacking, shaderc_vertex_shader,
+                        options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 16"));
+}
+
+TEST_F(CompileStringWithOptionsTest, HlslOffsetsOptionEnableRespected) {
+  shaderc_compile_options_set_hlsl_offsets(options_.get(), true);
+  const std::string disassembly_text =
+      CompilationOutput(kGlslShaderWeirdPacking, shaderc_vertex_shader,
+                        options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 4"));
+}
+
+TEST_F(CompileStringWithOptionsTest, HlslFunctionality1OffByDefault) {
+  shaderc_compile_options_set_source_language(options_.get(),
+                                              shaderc_source_language_hlsl);
+  // The counter should automatically get a binding.
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  const std::string disassembly_text =
+      CompilationOutput(kHlslShaderWithCounterBuffer, shaderc_fragment_shader,
+                        options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, Not(HasSubstr("OpDecorateString")))
+      << disassembly_text;
+}
+
+TEST_F(CompileStringWithOptionsTest, HlslFunctionality1Respected) {
+  shaderc_compile_options_set_source_language(options_.get(),
+                                              shaderc_source_language_hlsl);
+  shaderc_compile_options_set_hlsl_functionality1(options_.get(), true);
+  // The counter should automatically get a binding.
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  const std::string disassembly_text =
+      CompilationOutput(kHlslShaderWithCounterBuffer, shaderc_fragment_shader,
+                        options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorateString"));
+}
+
+TEST_F(CompileStringWithOptionsTest, HlslFunctionality1SurvivesCloning) {
+  shaderc_compile_options_set_source_language(options_.get(),
+                                              shaderc_source_language_hlsl);
+  shaderc_compile_options_set_hlsl_functionality1(options_.get(), true);
+  // The counter should automatically get a binding.
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  compile_options_ptr cloned_options(
+      shaderc_compile_options_clone(options_.get()));
+  const std::string disassembly_text =
+      CompilationOutput(kHlslShaderWithCounterBuffer, shaderc_fragment_shader,
+                        cloned_options.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorateString"));
+}
+
+TEST_F(CompileStringWithOptionsTest, HlslFlexibleMemoryLayoutAllowed) {
+  shaderc_compile_options_set_source_language(options_.get(),
+                                              shaderc_source_language_hlsl);
+  shaderc_compile_options_set_optimization_level(
+      options_.get(), shaderc_optimization_level_performance);
+  // There is no way to set the counter's binding, so set it automatically.
+  // See https://github.com/KhronosGroup/glslang/issues/1616
+  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
+  EXPECT_TRUE(CompilesToValidSpv(compiler_, kHlslMemLayoutResourceSelect,
+                                 shaderc_fragment_shader, options_.get()));
+}
+
+TEST_F(CompileStringWithOptionsTest, ClampMapsToFClampByDefault) {
+  const std::string disassembly_text =
+      CompilationOutput(kGlslShaderWithClamp, shaderc_fragment_shader,
+                        options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 FClamp"));
+}
+
+TEST_F(CompileStringWithOptionsTest, ClampMapsToNClampWithNanClamp) {
+  shaderc_compile_options_set_nan_clamp(options_.get(), true);
+  const std::string disassembly_text =
+      CompilationOutput(kGlslShaderWithClamp, shaderc_fragment_shader,
+                        options_.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 NClamp"));
+}
+
+TEST_F(CompileStringWithOptionsTest, NanClampSurvivesCloning) {
+  shaderc_compile_options_set_nan_clamp(options_.get(), true);
+  compile_options_ptr cloned_options(
+      shaderc_compile_options_clone(options_.get()));
+  const std::string disassembly_text =
+      CompilationOutput(kGlslShaderWithClamp, shaderc_fragment_shader,
+                        cloned_options.get(), OutputType::SpirvAssemblyText);
+  EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 NClamp"));
+}
+
 }  // anonymous namespace
diff --git a/libshaderc_util/.clang-format b/libshaderc_util/.clang-format
deleted file mode 100644
index e209e8c..0000000
--- a/libshaderc_util/.clang-format
+++ /dev/null
@@ -1,5 +0,0 @@
----
-# Use Google code formatting rules.
-Language: Cpp
-BasedOnStyle: Google
-...
diff --git a/libshaderc_util/Android.mk b/libshaderc_util/Android.mk
index 13c9f0a..a694787 100644
--- a/libshaderc_util/Android.mk
+++ b/libshaderc_util/Android.mk
@@ -1,10 +1,25 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE:=shaderc_util
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti
+LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -DENABLE_HLSL=1
 LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)/include
-LOCAL_SRC_FILES:=src/compiler.cc \
+LOCAL_SRC_FILES:=src/args.cc \
+                src/compiler.cc \
 		src/file_finder.cc \
 		src/io.cc \
 		src/message.cc \
@@ -12,6 +27,6 @@
 		src/shader_stage.cc \
 		src/spirv_tools_wrapper.cc \
 		src/version_profile.cc
-LOCAL_STATIC_LIBRARIES:=glslang SPIRV-Tools-opt
+LOCAL_STATIC_LIBRARIES:=SPIRV SPIRV-Tools-opt
 LOCAL_C_INCLUDES:=$(LOCAL_PATH)/include
 include $(BUILD_STATIC_LIBRARY)
diff --git a/libshaderc_util/CMakeLists.txt b/libshaderc_util/CMakeLists.txt
index cc6c927..48f9991 100644
--- a/libshaderc_util/CMakeLists.txt
+++ b/libshaderc_util/CMakeLists.txt
@@ -1,3 +1,17 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 project(libshaderc_util)
 
 add_library(shaderc_util STATIC
@@ -12,6 +26,7 @@
   include/libshaderc_util/string_piece.h
   include/libshaderc_util/universal_unistd.h
   include/libshaderc_util/version_profile.h
+  src/args.cc
   src/compiler.cc
   src/file_finder.cc
   src/io.cc
@@ -25,6 +40,10 @@
 shaderc_default_compile_options(shaderc_util)
 target_include_directories(shaderc_util
   PUBLIC include PRIVATE ${glslang_SOURCE_DIR})
+# We use parts of Glslang's HLSL compilation interface, which
+# now requires this preprocessor definition.
+add_definitions(-DENABLE_HLSL)
+
 find_package(Threads)
 target_link_libraries(shaderc_util PRIVATE
   glslang OSDependent OGLCompiler HLSL glslang SPIRV
@@ -40,11 +59,14 @@
     file_finder
     io
     message
-    mutex)
+    mutex
+    version_profile)
 
 if(${SHADERC_ENABLE_TESTS})
   target_include_directories(shaderc_util_counting_includer_test
     PRIVATE ${glslang_SOURCE_DIR})
+  target_include_directories(shaderc_util_version_profile_test
+    PRIVATE ${glslang_SOURCE_DIR})
 endif()
 
 shaderc_add_tests(
diff --git a/libshaderc_util/include/libshaderc_util/args.h b/libshaderc_util/include/libshaderc_util/args.h
new file mode 100644
index 0000000..1d08604
--- /dev/null
+++ b/libshaderc_util/include/libshaderc_util/args.h
@@ -0,0 +1,41 @@
+// Copyright 2019 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef LIBSHADERC_UTIL_INC_ARGS_H
+#define LIBSHADERC_UTIL_INC_ARGS_H
+
+#include <cstdint>
+#include <string>
+
+#include "libshaderc_util/string_piece.h"
+
+namespace shaderc_util {
+
+// Gets the option argument for the option at *index in argv in a way consistent
+// with clang/gcc. On success, returns true and writes the parsed argument into
+// *option_argument. Returns false if any errors occur. After calling this
+// function, *index will be the index of the last command line argument
+// consumed.
+bool GetOptionArgument(int argc, char** argv, int* index,
+                       const std::string& option,
+                       string_piece* option_argument);
+
+// Parses the given string as a number of the specified type.  Returns true
+// if parsing succeeded, and stores the parsed value via |value|.
+// (I've worked out the general case for this in
+// SPIRV-Tools source/util/parse_number.h. -- dneto)
+bool ParseUint32(const std::string& str, uint32_t* value);
+
+}  // namespace shaderc_util
+#endif  // LIBSHADERC_UTIL_INC_ARGS_H
diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h
index 50ab01c..3277a9b 100644
--- a/libshaderc_util/include/libshaderc_util/compiler.h
+++ b/libshaderc_util/include/libshaderc_util/compiler.h
@@ -15,7 +15,10 @@
 #ifndef LIBSHADERC_UTIL_INC_COMPILER_H
 #define LIBSHADERC_UTIL_INC_COMPILER_H
 
+#include <array>
+#include <cassert>
 #include <functional>
+#include <mutex>
 #include <ostream>
 #include <string>
 #include <unordered_map>
@@ -29,6 +32,9 @@
 #include "resources.h"
 #include "string_piece.h"
 
+// Fix a typo in glslang/Public/ShaderLang.h
+#define EShTargetClientVersion EshTargetClientVersion
+
 namespace shaderc_util {
 
 // To break recursive including. This header is already included in
@@ -36,54 +42,20 @@
 enum class PassId;
 
 // Initializes glslang on creation, and destroys it on completion.
-// This object is expected to be a singleton, so that internal
-// glslang state can be correctly handled.
-// TODO(awoloszyn): Once glslang no longer has static global mutable state
-//                  remove this class.
+// Used to tie gslang process operations to object lifetimes.
+// Additionally initialization/finalization of glslang is not thread safe, so
+// synchronizes these operations.
 class GlslangInitializer {
  public:
-  GlslangInitializer() { glslang::InitializeProcess(); }
-
-  ~GlslangInitializer() { glslang::FinalizeProcess(); }
-
-  // Calls release on GlslangInitializer used to intialize this object
-  // when it is destroyed.
-  class InitializationToken {
-   public:
-    ~InitializationToken() {
-      if (initializer_) {
-        initializer_->Release();
-      }
-    }
-
-    InitializationToken(InitializationToken&& other)
-        : initializer_(other.initializer_) {
-      other.initializer_ = nullptr;
-    }
-
-    InitializationToken(const InitializationToken&) = delete;
-
-   private:
-    InitializationToken(GlslangInitializer* initializer)
-        : initializer_(initializer) {}
-
-    friend class GlslangInitializer;
-    GlslangInitializer* initializer_;
-  };
-
-  // Obtains exclusive access to the glslang state. The state remains
-  // exclusive until the Initialization Token has been destroyed.
-  InitializationToken Acquire() {
-    state_lock_.lock();
-    return InitializationToken(this);
-  }
+  GlslangInitializer();
+  ~GlslangInitializer();
 
  private:
-  void Release() { state_lock_.unlock(); }
+  static unsigned int initialize_count_;
 
-  friend class InitializationToken;
-
-  mutex state_lock_;
+  // Using a bare pointer here to avoid any global class construction at the
+  // beginning of the execution.
+  static std::mutex* glslang_mutex_;
 };
 
 // Maps macro names to their definitions.  Stores string_pieces, so the
@@ -101,9 +73,30 @@
 
   // Target environment.
   enum class TargetEnv {
-    Vulkan,
-    OpenGL,
-    OpenGLCompat,
+    Vulkan,        // Default to Vulkan 1.0
+    OpenGL,        // Default to OpenGL 4.5
+    OpenGLCompat,  // Deprecated.
+  };
+
+  // Target environment versions.  These numbers match those used by Glslang.
+  enum class TargetEnvVersion : uint32_t {
+    Default = 0,  // Default for the corresponding target environment
+    // For Vulkan, use numbering scheme from vulkan.h
+    Vulkan_1_0 = ((1 << 22)),              // Vulkan 1.0
+    Vulkan_1_1 = ((1 << 22) | (1 << 12)),  // Vulkan 1.1
+    Vulkan_1_2 = ((1 << 22) | (2 << 12)),  // Vulkan 1.2
+    // For OpenGL, use the numbering from #version in shaders.
+    OpenGL_4_5 = 450,
+  };
+
+  // SPIR-V version.
+  enum class SpirvVersion : uint32_t {
+    v1_0 = 0x010000u,
+    v1_1 = 0x010100u,
+    v1_2 = 0x010200u,
+    v1_3 = 0x010300u,
+    v1_4 = 0x010400u,
+    v1_5 = 0x010500u,
   };
 
   enum class OutputType {
@@ -114,17 +107,81 @@
 
   // Supported optimization levels.
   enum class OptimizationLevel {
-    Zero,  // No optimization.
-    Size,  // Optimization towards reducing code size.
+    Zero,         // No optimization.
+    Size,         // Optimization towards reducing code size.
+    Performance,  // Optimization towards better performance.
   };
 
-  // Resource limits.  These map to the "max*" fields in glslang::TBuiltInResource.
+  // Resource limits.  These map to the "max*" fields in
+  // glslang::TBuiltInResource.
   enum class Limit {
-#define RESOURCE(NAME,FIELD,CNAME) NAME,
+#define RESOURCE(NAME, FIELD, CNAME) NAME,
 #include "resources.inc"
 #undef RESOURCE
   };
 
+  // Types of uniform variables.
+  enum class UniformKind {
+    // Image, and image buffer.
+    Image = 0,
+    // Pure sampler.
+    Sampler = 1,
+    // Sampled texture in GLSL.
+    // Shader Resource View, for HLSL.  (Read-only image or storage buffer.)
+    Texture = 2,
+    // Uniform Buffer Object, or UBO, in GLSL.
+    // Also a Cbuffer in HLSL.
+    Buffer = 3,
+    // Shader Storage Buffer Object, or SSBO
+    StorageBuffer = 4,
+    // Uniform Access View, in HLSL.  (Writable storage image or storage
+    // buffer.)
+    UnorderedAccessView = 5,
+  };
+  enum { kNumUniformKinds = int(UniformKind::UnorderedAccessView) + 1 };
+
+  // Shader pipeline stage.
+  // TODO(dneto): Replaces interface uses of EShLanguage with this enum.
+  enum class Stage {
+    Vertex,
+    TessEval,
+    TessControl,
+    Geometry,
+    Fragment,
+    Compute,
+    RayGenNV,
+    IntersectNV,
+    AnyHitNV,
+    ClosestHitNV,
+    MissNV,
+    CallableNV,
+    TaskNV,
+    MeshNV,
+    StageEnd,
+  };
+  enum { kNumStages = int(Stage::StageEnd) };
+
+  // Returns a std::array of all the Stage values.
+  const std::array<Stage, kNumStages>& stages() const {
+    static std::array<Stage, kNumStages> values{{
+        Stage::Vertex,
+        Stage::TessEval,
+        Stage::TessControl,
+        Stage::Geometry,
+        Stage::Fragment,
+        Stage::Compute,
+        Stage::RayGenNV,
+        Stage::IntersectNV,
+        Stage::AnyHitNV,
+        Stage::ClosestHitNV,
+        Stage::MissNV,
+        Stage::CallableNV,
+        Stage::TaskNV,
+        Stage::MeshNV,
+    }};
+    return values;
+  }
+
   // Creates an default compiler instance targeting at Vulkan environment. Uses
   // version 110 and no profile specification as the default for GLSL.
   Compiler()
@@ -138,8 +195,21 @@
         generate_debug_info_(false),
         enabled_opt_passes_(),
         target_env_(TargetEnv::Vulkan),
+        target_env_version_(TargetEnvVersion::Default),
+        target_spirv_version_(SpirvVersion::v1_0),
+        target_spirv_version_is_forced_(false),
         source_language_(SourceLanguage::GLSL),
-        limits_(kDefaultTBuiltInResource) {}
+        limits_(kDefaultTBuiltInResource),
+        auto_bind_uniforms_(false),
+        auto_binding_base_(),
+        auto_map_locations_(false),
+        hlsl_iomap_(false),
+        hlsl_offsets_(false),
+        hlsl_legalization_enabled_(true),
+        hlsl_functionality1_enabled_(false),
+        invert_y_enabled_(false),
+        nan_clamp_(false),
+        hlsl_explicit_bindings_() {}
 
   // Requests that the compiler place debug information into the object code,
   // such as identifier names and line numbers.
@@ -149,6 +219,21 @@
   // effect if multiple calls of this method exist.
   void SetOptimizationLevel(OptimizationLevel level);
 
+  // Enables or disables HLSL legalization passes.
+  void EnableHlslLegalization(bool hlsl_legalization_enabled);
+
+  // Enables or disables extension SPV_GOOGLE_hlsl_functionality1
+  void EnableHlslFunctionality1(bool enable);
+
+  // Enables or disables invert position.Y output in vertex shader.
+  void EnableInvertY(bool enable);
+
+  // Sets whether the compiler generates code for max and min builtins which,
+  // if given a NaN operand, will return the other operand.  Also, the clamp
+  // builtin will favour the non-NaN operands, as if clamp were implemented
+  // as a composition of max and min.
+  void SetNanClamp(bool enable);
+
   // When a warning is encountered it treat it as an error.
   void SetWarningsAsErrors();
 
@@ -162,8 +247,18 @@
   void AddMacroDefinition(const char* macro, size_t macro_length,
                           const char* definition, size_t definition_length);
 
-  // Sets the target environment.
-  void SetTargetEnv(TargetEnv env);
+  // Sets the target environment, including version.  The version value should
+  // be 0 or one of the values from TargetEnvVersion.  The default value maps
+  // to Vulkan 1.0 if the target environment is Vulkan, and it maps to OpenGL
+  // 4.5 if the target environment is OpenGL.
+  void SetTargetEnv(TargetEnv env,
+                    TargetEnvVersion version = TargetEnvVersion::Default);
+
+  // Sets the target version of SPIR-V.  The module will use this version
+  // of SPIR-V.  Defaults to the highest version of SPIR-V required to be
+  // supported by the target environment.  E.g. default to SPIR-V 1.0 for
+  // Vulkan 1.0, and SPIR-V 1.3 for Vulkan 1.1.
+  void SetTargetSpirv(SpirvVersion version);
 
   // Sets the souce language.
   void SetSourceLanguage(SourceLanguage lang);
@@ -178,6 +273,61 @@
   // Returns the current limit.
   int GetLimit(Limit limit) const;
 
+  // Set whether the compiler automatically assigns bindings to
+  // uniform variables that don't have explicit bindings.
+  void SetAutoBindUniforms(bool auto_bind) { auto_bind_uniforms_ = auto_bind; }
+
+  // Sets the lowest binding number used when automatically assigning bindings
+  // for uniform resources of the given type, for all shader stages.  The default
+  // base is zero.
+  void SetAutoBindingBase(UniformKind kind, uint32_t base) {
+    for (auto stage : stages()) {
+      SetAutoBindingBaseForStage(stage, kind, base);
+    }
+  }
+
+  // Sets the lowest binding number used when automatically assigning bindings
+  // for uniform resources of the given type for a specific shader stage.  The
+  // default base is zero.
+  void SetAutoBindingBaseForStage(Stage stage, UniformKind kind,
+                                  uint32_t base) {
+    auto_binding_base_[static_cast<int>(stage)][static_cast<int>(kind)] = base;
+  }
+
+  // Sets whether the compiler automatically assigns locations to
+  // uniform variables that don't have explicit locations.
+  void SetAutoMapLocations(bool auto_map) { auto_map_locations_ = auto_map; }
+
+  // Use HLSL IO mapping rules for bindings.  Default is false.
+  void SetHlslIoMapping(bool hlsl_iomap) { hlsl_iomap_ = hlsl_iomap; }
+
+  // Use HLSL rules for offsets in "transparent" memory.  These allow for
+  // tighter packing of some combinations of types than standard GLSL packings.
+  void SetHlslOffsets(bool hlsl_offsets) { hlsl_offsets_ = hlsl_offsets; }
+
+  // Sets an explicit set and binding for the given HLSL register.
+  void SetHlslRegisterSetAndBinding(const std::string& reg,
+                                    const std::string& set,
+                                    const std::string& binding) {
+    for (auto stage : stages()) {
+      SetHlslRegisterSetAndBindingForStage(stage, reg, set, binding);
+    }
+  }
+
+  // Sets an explicit set and binding for the given HLSL register in the given
+  // shader stage.  For example,
+  //    SetHlslRegisterSetAndBinding(Stage::Fragment, "t1", "4", "5")
+  // means register "t1" in a fragment shader should map to binding 5 in set 4.
+  // (Glslang wants this data as strings, not ints or enums.)  The string data is
+  // copied.
+  void SetHlslRegisterSetAndBindingForStage(Stage stage, const std::string& reg,
+                                            const std::string& set,
+                                            const std::string& binding) {
+    hlsl_explicit_bindings_[static_cast<int>(stage)].push_back(reg);
+    hlsl_explicit_bindings_[static_cast<int>(stage)].push_back(set);
+    hlsl_explicit_bindings_[static_cast<int>(stage)].push_back(binding);
+  }
+
   // Compiles the shader source in the input_source_string parameter.
   //
   // If the forced_shader stage parameter is not EShLangCount then
@@ -218,8 +368,7 @@
                                       const string_piece& error_tag)>&
           stage_callback,
       CountingIncluder& includer, OutputType output_type,
-      std::ostream* error_stream, size_t* total_warnings, size_t* total_errors,
-      GlslangInitializer* initializer) const;
+      std::ostream* error_stream, size_t* total_warnings, size_t* total_errors) const;
 
   static EShMessages GetDefaultRules() {
     return static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules |
@@ -322,11 +471,63 @@
   // implementation of glslang.
   TargetEnv target_env_;
 
+  // The version number of the target environment.  The numbering scheme is
+  // particular to each target environment.  If this is 0, then use a default
+  // for that particular target environment. See libshaders/shaderc/shaderc.h
+  // for those defaults.
+  TargetEnvVersion target_env_version_;
+
+  // The SPIR-V version to be used for the generated module.  Defaults to 1.0.
+  SpirvVersion target_spirv_version_;
+  // True if the user explicitly set the target SPIR-V version.
+  bool target_spirv_version_is_forced_;
+
   // The source language.  Defaults to GLSL.
   SourceLanguage source_language_;
 
   // The resource limits to be used.
   TBuiltInResource limits_;
+
+  // True if the compiler should automatically bind uniforms that don't
+  // have explicit bindings.
+  bool auto_bind_uniforms_;
+
+  // The base binding number per uniform type, per stage, used when automatically
+  // binding uniforms that don't hzve explicit bindings in the shader source.
+  // The default is zero.
+  uint32_t auto_binding_base_[kNumStages][kNumUniformKinds];
+
+  // True if the compiler should automatically map uniforms that don't
+  // have explicit locations.
+  bool auto_map_locations_;
+
+  // True if the compiler should use HLSL IO mapping rules when compiling HLSL.
+  bool hlsl_iomap_;
+
+  // True if the compiler should determine block member offsets using HLSL
+  // packing rules instead of standard GLSL rules.
+  bool hlsl_offsets_;
+
+  // True if the compiler should perform legalization optimization passes if
+  // source language is HLSL.
+  bool hlsl_legalization_enabled_;
+
+  // True if the compiler should support extension SPV_GOOGLE_hlsl_functionality1.
+  bool hlsl_functionality1_enabled_;
+
+  // True if the compiler should invert position.Y output in vertex shader.
+  bool invert_y_enabled_;
+
+  // True if the compiler generates code for max and min builtins which,
+  // if given a NaN operand, will return the other operand.  Also, the clamp
+  // builtin will favour the non-NaN operands, as if clamp were implemented
+  // as a composition of max and min.
+  bool nan_clamp_;
+
+  // A sequence of triples, each triple representing a specific HLSL register
+  // name, and the set and binding numbers it should be mapped to, but in
+  // the form of strings.  This is how Glslang wants to consume the data.
+  std::vector<std::string> hlsl_explicit_bindings_[kNumStages];
 };
 
 // Converts a string to a vector of uint32_t by copying the content of a given
@@ -334,5 +535,74 @@
 // are required to complete the last element.
 std::vector<uint32_t> ConvertStringToVector(const std::string& str);
 
+// Converts a valid Glslang shader stage value to a Compiler::Stage value.
+inline Compiler::Stage ConvertToStage(EShLanguage stage) {
+  switch (stage) {
+    case EShLangVertex:
+      return Compiler::Stage::Vertex;
+    case EShLangTessControl:
+      return Compiler::Stage::TessEval;
+    case EShLangTessEvaluation:
+      return Compiler::Stage::TessControl;
+    case EShLangGeometry:
+      return Compiler::Stage::Geometry;
+    case EShLangFragment:
+      return Compiler::Stage::Fragment;
+    case EShLangCompute:
+      return Compiler::Stage::Compute;
+    case EShLangRayGenNV:
+      return Compiler::Stage::RayGenNV;
+    case EShLangIntersectNV:
+      return Compiler::Stage::IntersectNV;
+    case EShLangAnyHitNV:
+      return Compiler::Stage::AnyHitNV;
+    case EShLangClosestHitNV:
+      return Compiler::Stage::ClosestHitNV;
+    case EShLangMissNV:
+      return Compiler::Stage::MissNV;
+    case EShLangCallableNV:
+      return Compiler::Stage::CallableNV;
+    case EShLangTaskNV:
+      return Compiler::Stage::TaskNV;
+    case EShLangMeshNV:
+      return Compiler::Stage::MeshNV;
+    default:
+      break;
+  }
+  assert(false && "Invalid case");
+  return Compiler::Stage::Compute;
+}
+
+// A GlslangClientInfo captures target client version and desired SPIR-V
+// version.
+struct GlslangClientInfo {
+  GlslangClientInfo() {}
+  GlslangClientInfo(const std::string& e, glslang::EShClient c,
+                    glslang::EShTargetClientVersion cv,
+                    glslang::EShTargetLanguage l,
+                    glslang::EShTargetLanguageVersion lv)
+      : error(e),
+        client(c),
+        client_version(cv),
+        target_language(l),
+        target_language_version(lv) {}
+
+  std::string error;  // Empty if ok, otherwise contains the error message.
+  glslang::EShClient client = glslang::EShClientNone;
+  glslang::EShTargetClientVersion client_version;
+  glslang::EShTargetLanguage target_language = glslang::EShTargetSpv;
+  glslang::EShTargetLanguageVersion target_language_version =
+      glslang::EShTargetSpv_1_0;
+};
+
+// Returns the mappings to Glslang client, client version, and SPIR-V version.
+// Also indicates whether the input values were valid.
+GlslangClientInfo GetGlslangClientInfo(
+    const std::string& error_tag,  // Indicates source location, for errors.
+    shaderc_util::Compiler::TargetEnv env,
+    shaderc_util::Compiler::TargetEnvVersion env_version,
+    shaderc_util::Compiler::SpirvVersion spv_version,
+    bool spv_version_is_forced);
+
 }  // namespace shaderc_util
 #endif  // LIBSHADERC_UTIL_INC_COMPILER_H
diff --git a/libshaderc_util/include/libshaderc_util/counting_includer.h b/libshaderc_util/include/libshaderc_util/counting_includer.h
index d341ad1..3e6b0a6 100644
--- a/libshaderc_util/include/libshaderc_util/counting_includer.h
+++ b/libshaderc_util/include/libshaderc_util/counting_includer.h
@@ -19,9 +19,13 @@
 
 #include "glslang/Public/ShaderLang.h"
 
+#include "libshaderc_util/mutex.h"
+
 namespace shaderc_util {
 
 // An Includer that counts how many #include directives it saw.
+// Inclusions are internally serialized, but releasing a previous result
+// can occur concurrently.
 class CountingIncluder : public glslang::TShader::Includer {
  public:
   // Done as .store(0) instead of in the initializer list for the following
@@ -33,18 +37,37 @@
     num_include_directives_.store(0);
   }
 
+  enum class IncludeType {
+    System,  // Only do < > include search
+    Local,   // Only do " " include search
+  };
+
   // Resolves an include request for a source by name, type, and name of the
   // requesting source.  For the semantics of the result, see the base class.
   // Also increments num_include_directives and returns the results of
   // include_delegate(filename).  Subclasses should override include_delegate()
-  // instead of this method.
-  glslang::TShader::Includer::IncludeResult* include(
-      const char* requested_source, glslang::TShader::Includer::IncludeType type,
-      const char* requesting_source,
+  // instead of this method.  Inclusions are serialized.
+  glslang::TShader::Includer::IncludeResult* includeSystem(
+      const char* requested_source, const char* requesting_source,
       size_t include_depth) final {
     ++num_include_directives_;
-    return include_delegate(requested_source, type, requesting_source,
-                            include_depth);
+    include_mutex_.lock();
+    auto result = include_delegate(requested_source, requesting_source,
+                                   IncludeType::System, include_depth);
+    include_mutex_.unlock();
+    return result;
+  }
+
+  // Like includeSystem, but for "local" include search.
+  glslang::TShader::Includer::IncludeResult* includeLocal(
+      const char* requested_source, const char* requesting_source,
+      size_t include_depth) final {
+    ++num_include_directives_;
+    include_mutex_.lock();
+    auto result = include_delegate(requested_source, requesting_source,
+                                   IncludeType::Local, include_depth);
+    include_mutex_.unlock();
+    return result;
   }
 
   // Releases the given IncludeResult.
@@ -55,11 +78,12 @@
   int num_include_directives() const { return num_include_directives_.load(); }
 
  private:
+
   // Invoked by this class to provide results to
   // glslang::TShader::Includer::include.
   virtual glslang::TShader::Includer::IncludeResult* include_delegate(
-      const char* requested_source, glslang::TShader::Includer::IncludeType type,
-      const char* requesting_source, size_t include_depth) = 0;
+      const char* requested_source, const char* requesting_source,
+      IncludeType type, size_t include_depth) = 0;
 
   // Release the given IncludeResult.
   virtual void release_delegate(
@@ -67,6 +91,10 @@
 
   // The number of #include directive encountered.
   std::atomic_int num_include_directives_;
+
+  // A mutex to protect against concurrent inclusions.  We can't trust
+  // our delegates to be safe for concurrent inclusions.
+  shaderc_util::mutex include_mutex_;
 };
 }
 
diff --git a/libshaderc_util/include/libshaderc_util/exceptions.h b/libshaderc_util/include/libshaderc_util/exceptions.h
new file mode 100644
index 0000000..93a03aa
--- /dev/null
+++ b/libshaderc_util/include/libshaderc_util/exceptions.h
@@ -0,0 +1,26 @@
+// Copyright 2018 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef LIBSHADERC_UTIL_EXCEPTIONS_H_
+#define LIBSHADERC_UTIL_EXCEPTIONS_H_
+
+#if (defined(_MSC_VER) && !defined(_CPPUNWIND)) || !defined(__EXCEPTIONS)
+#define TRY_IF_EXCEPTIONS_ENABLED
+#define CATCH_IF_EXCEPTIONS_ENABLED(X) if (0)
+#else
+#define TRY_IF_EXCEPTIONS_ENABLED try
+#define CATCH_IF_EXCEPTIONS_ENABLED(X) catch (X)
+#endif
+
+#endif  // LIBSHADERC_UTIL_EXCEPTIONS_H_
diff --git a/libshaderc_util/include/libshaderc_util/file_finder.h b/libshaderc_util/include/libshaderc_util/file_finder.h
index 2c1c9d1..a5f91cf 100644
--- a/libshaderc_util/include/libshaderc_util/file_finder.h
+++ b/libshaderc_util/include/libshaderc_util/file_finder.h
@@ -27,7 +27,7 @@
   // non-empty.  The search is attempted on filename prefixed by each element of
   // search_path() in turn.  The first hit is returned, or an empty string if
   // there are no hits.  Search attempts treat their argument the way
-  // std::fopen() treats its filename argument, blind to whether the path is
+  // std::fopen() treats its filename argument, ignoring whether the path is
   // absolute or relative.
   //
   // If a search_path() element is non-empty and not ending in a slash, then a
diff --git a/libshaderc_util/include/libshaderc_util/io.h b/libshaderc_util/include/libshaderc_util/io.h
index b57e0dd..b9116c1 100644
--- a/libshaderc_util/include/libshaderc_util/io.h
+++ b/libshaderc_util/include/libshaderc_util/io.h
@@ -47,16 +47,23 @@
 
 // Returns and initializes the file_stream parameter if the output_filename
 // refers to a file, or returns &std::cout if the output_filename is "-".
-// Returns nullptr and emits an error message to std::cout if the file could
+// Returns nullptr and emits an error message to err if the file could
 // not be opened for writing.  If the output refers to a file, and the open
 // failed for writing, file_stream is left with its fail_bit set.
 std::ostream* GetOutputStream(const string_piece& output_filename,
-                              std::ofstream* file_stream);
+                              std::ofstream* file_stream, std::ostream* err);
 
 // Writes output_data to a file, overwriting if it exists.  If output_file_name
 // is "-", writes to std::cout.
 bool WriteFile(std::ostream* output_stream, const string_piece& output_data);
 
+// Flush the standard output stream and set it to binary mode.  Subsequent
+// output will not translate newlines to carriage-return newline pairs.
+void FlushAndSetBinaryModeOnStdout();
+// Flush the standard output stream and set it to text mode.  Subsequent
+// output will translate newlines to carriage-return newline pairs.
+void FlushAndSetTextModeOnStdout();
+
 }  // namespace shaderc_util
 
 #endif  // LIBSHADERC_UTIL_IO_H_
diff --git a/libshaderc_util/include/libshaderc_util/message.h b/libshaderc_util/include/libshaderc_util/message.h
index f07a62c..8a77790 100644
--- a/libshaderc_util/include/libshaderc_util/message.h
+++ b/libshaderc_util/include/libshaderc_util/message.h
@@ -53,6 +53,9 @@
 //   source_name="", line_number="", rest="Message"
 // "ERROR: 2 errors found."
 //   source_name="2", line_number="", rest="errors found".
+//
+// Note that filenames can contain colons:
+//   "ERROR: foo:bar.comp.hlsl:2: 'a' : unknown variable"
 MessageType ParseGlslangOutput(const shaderc_util::string_piece& message,
                                bool warnings_as_errors, bool suppress_warnings,
                                shaderc_util::string_piece* source_name,
diff --git a/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h b/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h
index b02e15d..09d8462 100644
--- a/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h
+++ b/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h
@@ -27,21 +27,30 @@
 // Assembles the given assembly. On success, returns true, writes the assembled
 // binary to *binary, and clears *errors. Otherwise, writes the error message
 // into *errors.
-bool SpirvToolsAssemble(Compiler::TargetEnv env, const string_piece assembly,
-                        spv_binary* binary, std::string* errors);
+bool SpirvToolsAssemble(Compiler::TargetEnv env,
+                        Compiler::TargetEnvVersion version,
+                        const string_piece assembly, spv_binary* binary,
+                        std::string* errors);
 
 // Disassembles the given binary. Returns true and writes the disassembled text
 // to *text_or_error if successful. Otherwise, writes the error message to
 // *text_or_error.
 bool SpirvToolsDisassemble(Compiler::TargetEnv env,
+                           Compiler::TargetEnvVersion version,
                            const std::vector<uint32_t>& binary,
                            std::string* text_or_error);
 
 // The ids of a list of supported optimization passes.
 enum class PassId {
+  // SPIRV-Tools standard recipes
+  kLegalizationPasses,
+  kPerformancePasses,
+  kSizePasses,
+
+  // SPIRV-Tools specific passes
   kNullPass,
   kStripDebugInfo,
-  kUnifyConstant,
+  kCompactIds,
 };
 
 // Optimizes the given binary. Passes are registered in the exact order as shown
@@ -49,6 +58,7 @@
 // optimized binary back to *binary if successful. Otherwise, writes errors to
 // *errors and the content of binary may be in an invalid state.
 bool SpirvToolsOptimize(Compiler::TargetEnv env,
+                        Compiler::TargetEnvVersion version,
                         const std::vector<PassId>& enabled_passes,
                         std::vector<uint32_t>* binary, std::string* errors);
 
diff --git a/libshaderc_util/include/libshaderc_util/universal_unistd.h b/libshaderc_util/include/libshaderc_util/universal_unistd.h
index bd14c5a..9f6e74f 100644
--- a/libshaderc_util/include/libshaderc_util/universal_unistd.h
+++ b/libshaderc_util/include/libshaderc_util/universal_unistd.h
@@ -29,4 +29,4 @@
 #define W_OK 2
 #endif //_MSC_VER
 
-#endif // LIBSHADERC_UTIL_UNIVERSAL_UNISTD_H_
\ No newline at end of file
+#endif // LIBSHADERC_UTIL_UNIVERSAL_UNISTD_H_
diff --git a/libshaderc_util/include/libshaderc_util/version_profile.h b/libshaderc_util/include/libshaderc_util/version_profile.h
index 78196b2..f536b30 100644
--- a/libshaderc_util/include/libshaderc_util/version_profile.h
+++ b/libshaderc_util/include/libshaderc_util/version_profile.h
@@ -23,15 +23,36 @@
 
 // Returns true if the given version is an accepted GLSL (ES) version.
 inline bool IsKnownVersion(int version) {
-  return version == 100 || version == 110 || version == 120 || version == 130 ||
-         version == 140 || version == 150 || version == 300 || version == 330 ||
-         version == 310 || version == 400 || version == 410 || version == 420 ||
-         version == 430 || version == 440 || version == 450;
+  switch (version) {
+    case 100:
+    case 110:
+    case 120:
+    case 130:
+    case 140:
+    case 150:
+    case 300:
+    case 310:
+    case 320:
+    case 330:
+    case 400:
+    case 410:
+    case 420:
+    case 430:
+    case 440:
+    case 450:
+    case 460:
+      return true;
+    default:
+      break;
+  }
+  return false;
 }
 
 // Given a string version_profile containing both version and profile, decodes
 // it and puts the decoded version in version, decoded profile in profile.
 // Returns true if decoding is successful and version and profile are accepted.
+// This does not validate the version number against the profile.  For example,
+// "460es" doesn't make sense (yet), but is still accepted.
 bool ParseVersionProfile(const std::string& version_profile, int* version,
                          EProfile* profile);
 
diff --git a/libshaderc_util/src/args.cc b/libshaderc_util/src/args.cc
new file mode 100644
index 0000000..f1b36e7
--- /dev/null
+++ b/libshaderc_util/src/args.cc
@@ -0,0 +1,62 @@
+// Copyright 2019 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "libshaderc_util/args.h"
+
+#include <iomanip>
+#include <sstream>
+
+namespace shaderc_util {
+
+bool GetOptionArgument(int argc, char** argv, int* index,
+                       const std::string& option,
+                       string_piece* option_argument) {
+  const string_piece arg = argv[*index];
+  assert(arg.starts_with(option));
+  if (arg.size() != option.size()) {
+    *option_argument = arg.substr(option.size());
+    return true;
+  }
+
+  if (option.back() == '=') {
+    *option_argument = "";
+    return true;
+  }
+
+  if (++(*index) >= argc) return false;
+  *option_argument = argv[*index];
+  return true;
+}
+
+bool ParseUint32(const std::string& str, uint32_t* value) {
+  std::istringstream iss(str);
+
+  iss >> std::setbase(0);
+  iss >> *value;
+
+  // We should have read something.
+  bool ok = !str.empty() && !iss.bad();
+  // It should have been all the text.
+  ok = ok && iss.eof();
+  // It should have been in range.
+  ok = ok && !iss.fail();
+
+  // Work around a bugs in various C++ standard libraries.
+  // Count any negative number as an error, including "-0".
+  ok = ok && (str[0] != '-');
+
+  return ok;
+}
+
+}  // namespace shaderc_util
diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc
index 574ccfd..bf06589 100644
--- a/libshaderc_util/src/compiler.cc
+++ b/libshaderc_util/src/compiler.cc
@@ -15,8 +15,12 @@
 #include "libshaderc_util/compiler.h"
 
 #include <cstdint>
+#include <iomanip>
+#include <sstream>
+#include <thread>
 #include <tuple>
 
+#include "SPIRV/GlslangToSpv.h"
 #include "libshaderc_util/format.h"
 #include "libshaderc_util/io.h"
 #include "libshaderc_util/message.h"
@@ -26,8 +30,6 @@
 #include "libshaderc_util/string_piece.h"
 #include "libshaderc_util/version_profile.h"
 
-#include "SPIRV/GlslangToSpv.h"
-
 namespace {
 using shaderc_util::string_piece;
 
@@ -65,10 +67,12 @@
   return std::make_pair(line, directive);
 }
 
-// Returns the Glslang message rules for the given target environment
-// and source language.  We assume only valid combinations are used.
+// Returns the Glslang message rules for the given target environment,
+// source language, and whether we want HLSL offset rules.  We assume
+// only valid combinations are used.
 EShMessages GetMessageRules(shaderc_util::Compiler::TargetEnv env,
-                            shaderc_util::Compiler::SourceLanguage lang) {
+                            shaderc_util::Compiler::SourceLanguage lang,
+                            bool hlsl_offsets, bool debug_info) {
   using shaderc_util::Compiler;
   EShMessages result = EShMsgCascadingErrors;
   if (lang == Compiler::SourceLanguage::HLSL) {
@@ -85,6 +89,12 @@
           static_cast<EShMessages>(result | EShMsgSpvRules | EShMsgVulkanRules);
       break;
   }
+  if (hlsl_offsets) {
+    result = static_cast<EShMessages>(result | EShMsgHlslOffsets);
+  }
+  if (debug_info) {
+    result = static_cast<EShMessages>(result | EShMsgDebugInfo);
+  }
   return result;
 }
 
@@ -92,6 +102,46 @@
 
 namespace shaderc_util {
 
+unsigned int GlslangInitializer::initialize_count_ = 0;
+std::mutex* GlslangInitializer::glslang_mutex_ = nullptr;
+
+GlslangInitializer::GlslangInitializer() {
+  static std::mutex first_call_mutex;
+
+  // If this is the first call, glslang_mutex_ needs to be created, but in
+  // thread safe manner.
+  {
+    const std::lock_guard<std::mutex> first_call_lock(first_call_mutex);
+    if (glslang_mutex_ == nullptr) {
+      glslang_mutex_ = new std::mutex();
+    }
+  }
+
+  const std::lock_guard<std::mutex> glslang_lock(*glslang_mutex_);
+
+  if (initialize_count_ == 0) {
+    glslang::InitializeProcess();
+  }
+
+  initialize_count_++;
+}
+
+GlslangInitializer::~GlslangInitializer() {
+  const std::lock_guard<std::mutex> glslang_lock(*glslang_mutex_);
+
+  initialize_count_--;
+
+  if (initialize_count_ == 0) {
+    glslang::FinalizeProcess();
+    // There is no delete for glslang_mutex_ here, because we cannot guarantee
+    // there isn't a caller waiting for glslang_mutex_ in GlslangInitializer().
+    //
+    // This means that this class does leak one std::mutex worth of memory after
+    // the final instance is destroyed, but this allows us to defer allocating
+    // and constructing until we are sure we need to.
+  }
+}
+
 void Compiler::SetLimit(Compiler::Limit limit, int value) {
   switch (limit) {
 #define RESOURCE(NAME, FIELD, CNAME) \
@@ -121,8 +171,7 @@
                                     const string_piece& error_tag)>&
         stage_callback,
     CountingIncluder& includer, OutputType output_type,
-    std::ostream* error_stream, size_t* total_warnings, size_t* total_errors,
-    GlslangInitializer* initializer) const {
+    std::ostream* error_stream, size_t* total_warnings, size_t* total_errors) const {
   // Compilation results to be returned:
   // Initialize the result tuple as a failed compilation. In error cases, we
   // should return result_tuple directly without setting its members.
@@ -134,7 +183,17 @@
   std::vector<uint32_t>& compilation_output_data = std::get<1>(result_tuple);
   size_t& compilation_output_data_size_in_bytes = std::get<2>(result_tuple);
 
-  auto token = initializer->Acquire();
+  // Check target environment.
+  const auto target_client_info = GetGlslangClientInfo(
+      error_tag, target_env_, target_env_version_,
+      target_spirv_version_, target_spirv_version_is_forced_);
+  if (!target_client_info.error.empty()) {
+    *error_stream << target_client_info.error;
+    *total_warnings = 0;
+    *total_errors = 1;
+    return result_tuple;
+  }
+
   EShLanguage used_shader_stage = forced_shader_stage;
   const std::string macro_definitions =
       shaderc_util::format(predefined_macros_, "#define ", " ", "\n");
@@ -204,12 +263,37 @@
                                        &string_names, 1);
   shader.setPreamble(preamble.c_str());
   shader.setEntryPoint(entry_point_name);
+  shader.setAutoMapBindings(auto_bind_uniforms_);
+  shader.setAutoMapLocations(auto_map_locations_);
+  const auto& bases = auto_binding_base_[static_cast<int>(used_shader_stage)];
+  shader.setShiftImageBinding(bases[static_cast<int>(UniformKind::Image)]);
+  shader.setShiftSamplerBinding(bases[static_cast<int>(UniformKind::Sampler)]);
+  shader.setShiftTextureBinding(bases[static_cast<int>(UniformKind::Texture)]);
+  shader.setShiftUboBinding(bases[static_cast<int>(UniformKind::Buffer)]);
+  shader.setShiftSsboBinding(
+      bases[static_cast<int>(UniformKind::StorageBuffer)]);
+  shader.setShiftUavBinding(
+      bases[static_cast<int>(UniformKind::UnorderedAccessView)]);
+  shader.setHlslIoMapping(hlsl_iomap_);
+  shader.setResourceSetBinding(
+      hlsl_explicit_bindings_[static_cast<int>(used_shader_stage)]);
+  shader.setEnvClient(target_client_info.client,
+                      target_client_info.client_version);
+  shader.setEnvTarget(target_client_info.target_language,
+                      target_client_info.target_language_version);
+  if (hlsl_functionality1_enabled_) {
+    shader.setEnvTargetHlslFunctionality1();
+  }
+  shader.setInvertY(invert_y_enabled_);
+  shader.setNanMinMaxClamp(nan_clamp_);
 
-  // TODO(dneto): Generate source-level debug info if requested.
-  bool success =
-      shader.parse(&limits_, default_version_, default_profile_,
-                   force_version_profile_, kNotForwardCompatible,
-                   GetMessageRules(target_env_, source_language_), includer);
+  const EShMessages rules =
+      GetMessageRules(target_env_, source_language_, hlsl_offsets_,
+                      generate_debug_info_);
+
+  bool success = shader.parse(&limits_, default_version_, default_profile_,
+                              force_version_profile_, kNotForwardCompatible,
+                              rules, includer);
 
   success &= PrintFilteredErrors(error_tag, error_stream, warnings_as_errors_,
                                  suppress_warnings_, shader.getInfoLog(),
@@ -218,7 +302,7 @@
 
   glslang::TProgram program;
   program.addShader(&shader);
-  success = program.link(EShMsgDefault);
+  success = program.link(EShMsgDefault) && program.mapIO();
   success &= PrintFilteredErrors(error_tag, error_stream, warnings_as_errors_,
                                  suppress_warnings_, program.getInfoLog(),
                                  total_warnings, total_errors);
@@ -227,13 +311,37 @@
   // 'spirv' is an alias for the compilation_output_data. This alias is added
   // to serve as an input for the call to DissassemblyBinary.
   std::vector<uint32_t>& spirv = compilation_output_data;
+  glslang::SpvOptions options;
+  options.generateDebugInfo = generate_debug_info_;
+  options.disableOptimizer = true;
+  options.optimizeSize = false;
   // Note the call to GlslangToSpv also populates compilation_output_data.
-  glslang::GlslangToSpv(*program.getIntermediate(used_shader_stage), spirv);
+  glslang::GlslangToSpv(*program.getIntermediate(used_shader_stage), spirv,
+                        &options);
 
-  if (!enabled_opt_passes_.empty()) {
+  // Set the tool field (the top 16-bits) in the generator word to
+  // 'Shaderc over Glslang'.
+  const uint32_t shaderc_generator_word = 13;  // From SPIR-V XML Registry
+  const uint32_t generator_word_index = 2;     // SPIR-V 2.3: Physical layout
+  assert(spirv.size() > generator_word_index);
+  spirv[generator_word_index] =
+      (spirv[generator_word_index] & 0xffff) | (shaderc_generator_word << 16);
+
+  std::vector<PassId> opt_passes;
+
+  if (hlsl_legalization_enabled_ && source_language_ == SourceLanguage::HLSL) {
+    // If from HLSL, run this passes to "legalize" the SPIR-V for Vulkan
+    // eg. forward and remove memory writes of opaque types.
+    opt_passes.push_back(PassId::kLegalizationPasses);
+  }
+
+  opt_passes.insert(opt_passes.end(), enabled_opt_passes_.begin(),
+                    enabled_opt_passes_.end());
+
+  if (!opt_passes.empty()) {
     std::string opt_errors;
-    if (!SpirvToolsOptimize(target_env_, enabled_opt_passes_, &spirv,
-                            &opt_errors)) {
+    if (!SpirvToolsOptimize(target_env_, target_env_version_,
+                            opt_passes, &spirv, &opt_errors)) {
       *error_stream << "shaderc: internal error: compilation succeeded but "
                        "failed to optimize: "
                     << opt_errors << "\n";
@@ -243,7 +351,8 @@
 
   if (output_type == OutputType::SpirvAssemblyText) {
     std::string text_or_error;
-    if (!SpirvToolsDisassemble(target_env_, spirv, &text_or_error)) {
+    if (!SpirvToolsDisassemble(target_env_, target_env_version_, spirv,
+                               &text_or_error)) {
       *error_stream << "shaderc: internal error: compilation succeeded but "
                        "failed to disassemble: "
                     << text_or_error << "\n";
@@ -268,7 +377,16 @@
       definition ? std::string(definition, definition_length) : "";
 }
 
-void Compiler::SetTargetEnv(Compiler::TargetEnv env) { target_env_ = env; }
+void Compiler::SetTargetEnv(Compiler::TargetEnv env,
+                            Compiler::TargetEnvVersion version) {
+  target_env_ = env;
+  target_env_version_ = version;
+}
+
+void Compiler::SetTargetSpirv(Compiler::SpirvVersion version) {
+  target_spirv_version_ = version;
+  target_spirv_version_is_forced_ = true;
+}
 
 void Compiler::SetSourceLanguage(Compiler::SourceLanguage lang) {
   source_language_ = lang;
@@ -300,13 +418,31 @@
       if (!generate_debug_info_) {
         enabled_opt_passes_.push_back(PassId::kStripDebugInfo);
       }
-      enabled_opt_passes_.push_back(PassId::kUnifyConstant);
+      enabled_opt_passes_.push_back(PassId::kSizePasses);
+      break;
+    case OptimizationLevel::Performance:
+      if (!generate_debug_info_) {
+        enabled_opt_passes_.push_back(PassId::kStripDebugInfo);
+      }
+      enabled_opt_passes_.push_back(PassId::kPerformancePasses);
       break;
     default:
       break;
   }
 }
 
+void Compiler::EnableHlslLegalization(bool hlsl_legalization_enabled) {
+  hlsl_legalization_enabled_ = hlsl_legalization_enabled;
+}
+
+void Compiler::EnableHlslFunctionality1(bool enable) {
+  hlsl_functionality1_enabled_ = enable;
+}
+
+void Compiler::EnableInvertY(bool enable) { invert_y_enabled_ = enable; }
+
+void Compiler::SetNanClamp(bool enable) { nan_clamp_ = enable; }
+
 void Compiler::SetSuppressWarnings() { suppress_warnings_ = true; }
 
 std::tuple<bool, std::string, std::string> Compiler::PreprocessShader(
@@ -320,12 +456,27 @@
   shader.setStringsWithLengthsAndNames(&shader_strings, &shader_lengths,
                                        &string_names, 1);
   shader.setPreamble(shader_preamble.data());
+  auto target_client_info = GetGlslangClientInfo(
+      error_tag, target_env_, target_env_version_,
+      target_spirv_version_, target_spirv_version_is_forced_);
+  if (!target_client_info.error.empty()) {
+    return std::make_tuple(false, "", target_client_info.error);
+  }
+  shader.setEnvClient(target_client_info.client,
+                      target_client_info.client_version);
+  if (hlsl_functionality1_enabled_) {
+    shader.setEnvTargetHlslFunctionality1();
+  }
+  shader.setInvertY(invert_y_enabled_);
+  shader.setNanMinMaxClamp(nan_clamp_);
 
   // The preprocessor might be sensitive to the target environment.
   // So combine the existing rules with the just-give-me-preprocessor-output
   // flag.
   const auto rules = static_cast<EShMessages>(
-      EShMsgOnlyPreprocessor | GetMessageRules(target_env_, source_language_));
+      EShMsgOnlyPreprocessor |
+      GetMessageRules(target_env_, source_language_, hlsl_offsets_,
+                      false));
 
   std::string preprocessed_shader;
   const bool success = shader.preprocess(
@@ -543,4 +694,79 @@
   return result_vec;
 }
 
-}  // namesapce shaderc_util
+GlslangClientInfo GetGlslangClientInfo(
+    const std::string& error_tag, shaderc_util::Compiler::TargetEnv env,
+    shaderc_util::Compiler::TargetEnvVersion env_version,
+    shaderc_util::Compiler::SpirvVersion spv_version,
+    bool spv_version_is_forced) {
+  GlslangClientInfo result;
+  std::ostringstream errs;
+
+  using shaderc_util::Compiler;
+  switch (env) {
+    case Compiler::TargetEnv::Vulkan:
+      result.client = glslang::EShClientVulkan;
+      if (env_version == Compiler::TargetEnvVersion::Default ||
+          env_version == Compiler::TargetEnvVersion::Vulkan_1_0) {
+        result.client_version = glslang::EShTargetVulkan_1_0;
+      } else if (env_version == Compiler::TargetEnvVersion::Vulkan_1_1) {
+        result.client_version = glslang::EShTargetVulkan_1_1;
+        result.target_language_version = glslang::EShTargetSpv_1_3;
+      } else if (env_version == Compiler::TargetEnvVersion::Vulkan_1_2) {
+        result.client_version = glslang::EShTargetVulkan_1_2;
+        result.target_language_version = glslang::EShTargetSpv_1_5;
+      } else {
+        errs << "error:" << error_tag << ": Invalid target client version "
+             << static_cast<uint32_t>(env_version) << " for Vulkan environment "
+             << int(env);
+      }
+      break;
+    case Compiler::TargetEnv::OpenGLCompat:  // TODO(dneto): remove this
+    case Compiler::TargetEnv::OpenGL:
+      result.client = glslang::EShClientOpenGL;
+      if (env_version == Compiler::TargetEnvVersion::Default ||
+          env_version == Compiler::TargetEnvVersion::OpenGL_4_5) {
+        result.client_version = glslang::EShTargetOpenGL_450;
+      } else {
+        errs << "error:" << error_tag << ": Invalid target client version "
+             << static_cast<uint32_t>(env_version) << " for OpenGL environment "
+             << int(env);
+      }
+      break;
+    default:
+      errs << "error:" << error_tag << ": Invalid target client environment "
+           << int(env);
+      break;
+  }
+
+  if (spv_version_is_forced && errs.str().empty()) {
+    switch (spv_version) {
+      case Compiler::SpirvVersion::v1_0:
+        result.target_language_version = glslang::EShTargetSpv_1_0;
+        break;
+      case Compiler::SpirvVersion::v1_1:
+        result.target_language_version = glslang::EShTargetSpv_1_1;
+        break;
+      case Compiler::SpirvVersion::v1_2:
+        result.target_language_version = glslang::EShTargetSpv_1_2;
+        break;
+      case Compiler::SpirvVersion::v1_3:
+        result.target_language_version = glslang::EShTargetSpv_1_3;
+        break;
+      case Compiler::SpirvVersion::v1_4:
+        result.target_language_version = glslang::EShTargetSpv_1_4;
+        break;
+      case Compiler::SpirvVersion::v1_5:
+        result.target_language_version = glslang::EShTargetSpv_1_5;
+        break;
+      default:
+        errs << "error:" << error_tag << ": Unknown SPIR-V version " << std::hex
+             << uint32_t(spv_version);
+        break;
+    }
+  }
+  result.error = errs.str();
+  return result;
+}
+
+}  // namespace shaderc_util
diff --git a/libshaderc_util/src/compiler_test.cc b/libshaderc_util/src/compiler_test.cc
index 9938848..8d2c18d 100644
--- a/libshaderc_util/src/compiler_test.cc
+++ b/libshaderc_util/src/compiler_test.cc
@@ -20,20 +20,24 @@
 
 #include "death_test.h"
 #include "libshaderc_util/counting_includer.h"
+#include "libshaderc_util/spirv_tools_wrapper.h"
 
 namespace {
 
 using shaderc_util::Compiler;
-using ::testing::HasSubstr;
+using shaderc_util::GlslangClientInfo;
 using ::testing::Eq;
+using ::testing::HasSubstr;
+using ::testing::Not;
 
 // A trivial vertex shader
 const char kVertexShader[] =
     "#version 140\n"
     "void main() {}";
 
-// A shader that compiles under OpenGL compatibility profile rules,
-// but not OpenGL core profile rules.
+// A shader that parses under OpenGL compatibility profile rules.
+// It does not compile because Glslang does not support SPIR-V
+// code generation for OpenGL compatibility profile.
 const char kOpenGLCompatibilityFragShader[] =
     R"(#version 140
        uniform highp sampler2D tex;
@@ -41,16 +45,6 @@
          gl_FragColor = texture2D(tex, vec2(0.0,0.0));
        })";
 
-// A shader that compiles under OpenGL compatibility profile rules,
-// but not OpenGL core profile rules, even when deducing the stage.
-const char kOpenGLCompatibilityFragShaderDeducibleStage[] =
-    R"(#version 140
-       #pragma shader_stage(fragment)
-       uniform highp sampler2D tex;
-       void main() {
-         gl_FragColor = texture2D(tex, vec2(0.0,0.0));
-       })";
-
 // A shader that compiles under OpenGL core profile rules.
 const char kOpenGLVertexShader[] =
     R"(#version 330
@@ -84,14 +78,105 @@
     R"(float4 EntryPoint(uint index : SV_VERTEXID) : SV_POSITION
        { return float4(1.0, 2.0, 3.0, 4.0); })";
 
+// A GLSL fragment shader without bindings for its uniforms.
+// This also can be compiled as a vertex or compute shader.
+const char kGlslFragShaderNoExplicitBinding[] =
+    R"(#version 450
+       #extension GL_ARB_sparse_texture2: enable
+       uniform texture2D my_tex;
+       uniform sampler my_sam;
+       layout(rgba32f) uniform image2D my_img;
+       layout(rgba32f) uniform imageBuffer my_imbuf;
+       uniform block { float x; float y; } my_ubo;
+       void main() {
+         texture(sampler2D(my_tex,my_sam),vec2(1.0));
+         vec4 t = vec4(1.0);
+         sparseImageLoadARB(my_img,ivec2(0),t);
+         imageLoad(my_imbuf,2);
+         float x = my_ubo.x;
+       })";
+
+// A GLSL vertex shader with the location defined for its non-opaque uniform
+// variable.
+const char kGlslVertShaderExplicitLocation[] =
+    R"(#version 450
+       layout(location = 10) uniform mat4 my_mat;
+       layout(location = 0) in vec4 my_vec;
+       void main(void) {
+         gl_Position = my_mat * my_vec;
+       })";
+
+// A GLSL vertex shader without the location defined for its non-opaque uniform
+// variable.
+const char kGlslVertShaderNoExplicitLocation[] =
+    R"(#version 450
+       uniform mat4 my_mat;
+       layout(location = 0) in vec4 my_vec;
+       void main(void) {
+         gl_Position = my_mat * my_vec;
+       })";
+
+// A GLSL vertex shader with a weirdly packed block.
+const char kGlslShaderWeirdPacking[] =
+    R"(#version 450
+       layout(set = 0, binding = 0)
+       buffer B { float x; vec3 foo; } my_ssbo;
+       void main() { my_ssbo.x = 1.0; })";
+
+const char kHlslShaderForLegalizationTest[] = R"(
+struct CombinedTextureSampler {
+ Texture2D tex;
+ SamplerState sampl;
+};
+
+float4 sampleTexture(CombinedTextureSampler c, float2 loc) {
+ return c.tex.Sample(c.sampl, loc);
+};
+
+[[vk::binding(0,0)]]
+Texture2D gTex;
+[[vk::binding(0,1)]]
+SamplerState gSampler;
+
+float4 main(float2 loc: A) : SV_Target {
+ CombinedTextureSampler cts;
+ cts.tex = gTex;
+ cts.sampl = gSampler;
+
+ return sampleTexture(cts, loc);
+})";
+
+const char kHlslShaderWithCounterBuffer[] = R"(
+[[vk::binding(0,0)]]
+RWStructuredBuffer<float4> Ainc;
+float4 main() : SV_Target0 {
+  return float4(Ainc.IncrementCounter(), 0, 0, 0);
+}
+)";
+
+const char kGlslShaderWithClamp[] = R"(#version 450
+layout(location=0) in vec4 i;
+layout(location=0) out vec4 o;
+void main() { o = clamp(i, vec4(0.5), vec4(1.0)); }
+)";
+
+// Returns the disassembly of the given SPIR-V binary, as a string.
+// Assumes the disassembly will be successful when targeting Vulkan.
+std::string Disassemble(const std::vector<uint32_t> binary) {
+  std::string result;
+  shaderc_util::SpirvToolsDisassemble(Compiler::TargetEnv::Vulkan,
+                                      Compiler::TargetEnvVersion::Vulkan_1_2,
+                                      binary, &result);
+  return result;
+}
+
 // A CountingIncluder that never returns valid content for a requested
 // file inclusion.
 class DummyCountingIncluder : public shaderc_util::CountingIncluder {
  private:
   // Returns a pair of empty strings.
   virtual glslang::TShader::Includer::IncludeResult* include_delegate(
-      const char*, glslang::TShader::Includer::IncludeType, const char*,
-      size_t) override {
+      const char*, const char*, IncludeType, size_t) override {
     return nullptr;
   }
   virtual void release_delegate(
@@ -107,16 +192,16 @@
   // shader stage.
   bool SimpleCompilationSucceedsForOutputType(
       std::string source, EShLanguage stage, Compiler::OutputType output_type) {
+    shaderc_util::GlslangInitializer initializer;
     std::stringstream errors;
     size_t total_warnings = 0;
     size_t total_errors = 0;
-    shaderc_util::GlslangInitializer initializer;
     bool result = false;
     DummyCountingIncluder dummy_includer;
     std::tie(result, std::ignore, std::ignore) = compiler_.Compile(
         source, stage, "shader", "main", dummy_stage_callback_, dummy_includer,
         Compiler::OutputType::SpirvBinary, &errors, &total_warnings,
-        &total_errors, &initializer);
+        &total_errors);
     errors_ = errors.str();
     return result;
   }
@@ -128,6 +213,25 @@
         source, stage, Compiler::OutputType::SpirvBinary);
   }
 
+  // Returns the SPIR-V binary for a successful compilation of a shader.
+  std::vector<uint32_t> SimpleCompilationBinary(std::string source,
+                                                EShLanguage stage) {
+    shaderc_util::GlslangInitializer initializer;
+    std::stringstream errors;
+    size_t total_warnings = 0;
+    size_t total_errors = 0;
+    bool result = false;
+    DummyCountingIncluder dummy_includer;
+    std::vector<uint32_t> words;
+    std::tie(result, words, std::ignore) = compiler_.Compile(
+        source, stage, "shader", "main", dummy_stage_callback_, dummy_includer,
+        Compiler::OutputType::SpirvBinary, &errors, &total_warnings,
+        &total_errors);
+    errors_ = errors.str();
+    EXPECT_TRUE(result) << errors_;
+    return words;
+  }
+
  protected:
   Compiler compiler_;
   // The error string from the most recent compilation.
@@ -161,46 +265,6 @@
   EXPECT_TRUE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
 }
 
-TEST_F(CompilerTest, RespectTargetEnvOnOpenGLCompatibilityShader) {
-  const EShLanguage stage = EShLangFragment;
-
-  compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGLCompat);
-  EXPECT_TRUE(SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader, stage));
-  compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL);
-  EXPECT_FALSE(
-      SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader, stage));
-  compiler_.SetTargetEnv(Compiler::TargetEnv::Vulkan);
-  EXPECT_FALSE(
-      SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader, stage));
-  // Default compiler.
-  compiler_ = Compiler();
-  EXPECT_FALSE(
-      SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader, stage));
-}
-
-TEST_F(CompilerTest,
-       RespectTargetEnvOnOpenGLCompatibilityShaderWhenDeducingStage) {
-  const EShLanguage stage = EShLangCount;
-
-  compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGLCompat);
-  EXPECT_TRUE(SimpleCompilationSucceeds(
-      kOpenGLCompatibilityFragShaderDeducibleStage, stage))
-      << errors_;
-  compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL);
-  EXPECT_FALSE(SimpleCompilationSucceeds(
-      kOpenGLCompatibilityFragShaderDeducibleStage, stage))
-      << errors_;
-  compiler_.SetTargetEnv(Compiler::TargetEnv::Vulkan);
-  EXPECT_FALSE(SimpleCompilationSucceeds(
-      kOpenGLCompatibilityFragShaderDeducibleStage, stage))
-      << errors_;
-  // Default compiler.
-  compiler_ = Compiler();
-  EXPECT_FALSE(SimpleCompilationSucceeds(
-      kOpenGLCompatibilityFragShaderDeducibleStage, stage))
-      << errors_;
-}
-
 TEST_F(CompilerTest, RespectTargetEnvOnOpenGLShader) {
   const EShLanguage stage = EShLangVertex;
 
@@ -238,15 +302,16 @@
   EXPECT_FALSE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
 }
 
-TEST_F(CompilerTest, OpenGLCompatibilitySpecificShaderFailsUnderDefaultRules) {
-  EXPECT_FALSE(SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader,
-                                         EShLangFragment));
-}
-
 TEST_F(CompilerTest, OpenGLSpecificShaderFailsUnderDefaultRules) {
   EXPECT_FALSE(SimpleCompilationSucceeds(kOpenGLVertexShader, EShLangVertex));
 }
 
+TEST_F(CompilerTest, OpenGLCompatibilitySpecificShaderFailsUnderOpenGLRules) {
+  compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL);
+  EXPECT_FALSE(SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader,
+                                         EShLangFragment));
+}
+
 TEST_F(CompilerTest, OpenGLCompatibilitySpecificShaderFailsUnderVulkanRules) {
   compiler_.SetTargetEnv(Compiler::TargetEnv::Vulkan);
   EXPECT_FALSE(SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader,
@@ -258,6 +323,70 @@
   EXPECT_FALSE(SimpleCompilationSucceeds(kOpenGLVertexShader, EShLangVertex));
 }
 
+TEST_F(CompilerTest, BadTargetEnvFails) {
+  compiler_.SetTargetEnv(static_cast<Compiler::TargetEnv>(32767));
+  EXPECT_FALSE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
+  EXPECT_THAT(errors_, HasSubstr("Invalid target client environment 32767"));
+}
+
+TEST_F(CompilerTest, BadTargetEnvVulkanVersionFails) {
+  compiler_.SetTargetEnv(Compiler::TargetEnv::Vulkan,
+                         static_cast<Compiler::TargetEnvVersion>(123));
+  EXPECT_FALSE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
+  EXPECT_THAT(errors_,
+              HasSubstr("Invalid target client version 123 for Vulkan environment 0"));
+}
+
+TEST_F(CompilerTest, BadTargetEnvOpenGLVersionFails) {
+  compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL,
+                         static_cast<Compiler::TargetEnvVersion>(123));
+  EXPECT_FALSE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
+  EXPECT_THAT(errors_,
+              HasSubstr("Invalid target client version 123 for OpenGL environment 1"));
+}
+
+TEST_F(CompilerTest, SpirvTargetVersion1_0Succeeds) {
+  compiler_.SetTargetSpirv(Compiler::SpirvVersion::v1_0);
+  EXPECT_TRUE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
+  EXPECT_THAT(errors_, Eq(""));
+}
+
+TEST_F(CompilerTest, SpirvTargetVersion1_1Succeeds) {
+  compiler_.SetTargetSpirv(Compiler::SpirvVersion::v1_1);
+  EXPECT_TRUE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
+  EXPECT_THAT(errors_, Eq(""));
+}
+
+TEST_F(CompilerTest, SpirvTargetVersion1_2Succeeds) {
+  compiler_.SetTargetSpirv(Compiler::SpirvVersion::v1_2);
+  EXPECT_TRUE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
+  EXPECT_THAT(errors_, Eq(""));
+}
+
+TEST_F(CompilerTest, SpirvTargetVersion1_3Succeeds) {
+  compiler_.SetTargetSpirv(Compiler::SpirvVersion::v1_3);
+  EXPECT_TRUE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
+  EXPECT_THAT(errors_, Eq(""));
+}
+
+TEST_F(CompilerTest, SpirvTargetVersion1_4Succeeds) {
+  compiler_.SetTargetSpirv(Compiler::SpirvVersion::v1_4);
+  EXPECT_TRUE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
+  EXPECT_THAT(errors_, Eq(""));
+}
+
+TEST_F(CompilerTest, SpirvTargetVersion1_5Succeeds) {
+  compiler_.SetTargetSpirv(Compiler::SpirvVersion::v1_5);
+  EXPECT_TRUE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
+  EXPECT_THAT(errors_, Eq(""));
+}
+
+TEST_F(CompilerTest, SpirvTargetBadVersionFails) {
+  compiler_.SetTargetSpirv(static_cast<Compiler::SpirvVersion>(0x090900));
+  EXPECT_FALSE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
+  EXPECT_THAT(errors_, HasSubstr(": Unknown SPIR-V version 90900"));
+}
+
 TEST_F(CompilerTest, AddMacroDefinition) {
   const std::string kMinimalExpandedShader = "#version 140\nvoid E(){}";
   compiler_.AddMacroDefinition("E", 1u, "main", 4u);
@@ -304,7 +433,7 @@
       << "test_case.input_str: " << test_case.input_str << std::endl;
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     ConvertStringToVectorTest, ConvertStringToVectorTestFixture,
     testing::ValuesIn(std::vector<ConvertStringToVectorTestCase>{
         {"", {0x00000000}},
@@ -353,7 +482,7 @@
       compiler_.Compile(kHlslVertexShader, EShLangVertex, "shader",
                         "EntryPoint", dummy_stage_callback_, dummy_includer,
                         Compiler::OutputType::SpirvAssemblyText, &errors,
-                        &total_warnings, &total_errors, &initializer);
+                        &total_warnings, &total_errors);
   EXPECT_TRUE(result);
   std::string assembly(reinterpret_cast<char*>(words.data()));
   EXPECT_THAT(assembly,
@@ -380,7 +509,7 @@
 
 #define CASE(LIMIT, DEFAULT, NEW) \
   { Compiler::Limit::LIMIT, DEFAULT, NEW }
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CompilerTest, LimitTest,
     // See resources.cc for the defaults.
     testing::ValuesIn(std::vector<SetLimitCase>{
@@ -391,15 +520,15 @@
         CASE(MaxTessControlAtomicCounters, 0, 72),
         CASE(MaxSamples, 4, 8),
         // clang-format on
-    }), );
+    }));
 #undef CASE
 
 // Returns a fragment shader accessing a texture with the given
 // offset.
 std::string ShaderWithTexOffset(int offset) {
   std::ostringstream oss;
-  oss << "#version 150\n"
-         "uniform sampler1D tex;\n"
+  oss << "#version 450\n"
+         "layout (binding=0) uniform sampler1D tex;\n"
          "void main() { vec4 x = textureOffset(tex, 1.0, "
       << offset << "); }\n";
   return oss.str();
@@ -430,4 +559,378 @@
   EXPECT_FALSE(SimpleCompilationSucceeds(ShaderWithTexOffset(101), stage));
 }
 
+TEST_F(CompilerTest, GeneratorWordIsShadercOverGlslang) {
+  const auto words = SimpleCompilationBinary(kVertexShader, EShLangVertex);
+  const uint32_t shaderc_over_glslang = 13;  // From SPIR-V XML Registry
+  const uint32_t generator_word_index = 2;   // From SPIR-V binary layout
+  EXPECT_EQ(shaderc_over_glslang, words[generator_word_index] >> 16u);
+}
+
+TEST_F(CompilerTest, NoBindingsAndNoAutoMapBindingsFailsCompile) {
+  compiler_.SetAutoBindUniforms(false);
+  EXPECT_FALSE(SimpleCompilationSucceeds(kGlslFragShaderNoExplicitBinding,
+                                         EShLangFragment));
+  EXPECT_THAT(errors_,
+              HasSubstr("sampler/texture/image requires layout(binding=X)"));
+}
+
+TEST_F(CompilerTest, AutoMapBindingsSetsBindings) {
+  compiler_.SetAutoBindUniforms(true);
+  const auto words = SimpleCompilationBinary(kGlslFragShaderNoExplicitBinding,
+                                             EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_tex Binding 0"))
+      << disassembly;
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_img Binding 2"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_imbuf Binding 3"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_ubo Binding 4"));
+}
+
+TEST_F(CompilerTest, SetBindingBaseForTextureAdjustsTextureBindingsOnly) {
+  compiler_.SetAutoBindUniforms(true);
+  compiler_.SetAutoBindingBase(Compiler::UniformKind::Texture, 42);
+  const auto words = SimpleCompilationBinary(kGlslFragShaderNoExplicitBinding,
+                                             EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_tex Binding 42"))
+      << disassembly;
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_sam Binding 0"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_img Binding 1"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_imbuf Binding 2"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_ubo Binding 3"));
+}
+
+TEST_F(CompilerTest, SetBindingBaseForSamplersAdjustsSamplerBindingsOnly) {
+  compiler_.SetAutoBindUniforms(true);
+  compiler_.SetAutoBindingBase(Compiler::UniformKind::Sampler, 42);
+  const auto words = SimpleCompilationBinary(kGlslFragShaderNoExplicitBinding,
+                                             EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_tex Binding 0"))
+      << disassembly;
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_sam Binding 42"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_img Binding 1"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_imbuf Binding 2"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_ubo Binding 3"));
+}
+
+TEST_F(CompilerTest, SetBindingBaseForImagesAdjustsImageBindingsOnly) {
+  compiler_.SetAutoBindUniforms(true);
+  compiler_.SetAutoBindingBase(Compiler::UniformKind::Image, 42);
+  const auto words = SimpleCompilationBinary(kGlslFragShaderNoExplicitBinding,
+                                             EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_tex Binding 0"))
+      << disassembly;
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_img Binding 42"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_imbuf Binding 43"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_ubo Binding 2"));
+}
+
+TEST_F(CompilerTest, SetBindingBaseForBufferAdjustsBufferBindingsOnly) {
+  compiler_.SetAutoBindUniforms(true);
+  compiler_.SetAutoBindingBase(Compiler::UniformKind::Buffer, 42);
+  const auto words = SimpleCompilationBinary(kGlslFragShaderNoExplicitBinding,
+                                             EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_tex Binding 0"))
+      << disassembly;
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_img Binding 2"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_imbuf Binding 3"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_ubo Binding 42"));
+}
+
+TEST_F(CompilerTest,
+       AutoMapBindingsSetsBindingsSetFragTextureBindingBaseCompiledAsFrag) {
+  compiler_.SetAutoBindUniforms(true);
+  compiler_.SetAutoBindingBaseForStage(Compiler::Stage::Fragment,
+                                       Compiler::UniformKind::Texture, 100);
+  const auto words = SimpleCompilationBinary(kGlslFragShaderNoExplicitBinding,
+                                             EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_tex Binding 100"))
+      << disassembly;
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_sam Binding 0"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_img Binding 1"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_imbuf Binding 2"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_ubo Binding 3"));
+}
+
+TEST_F(CompilerTest,
+       AutoMapBindingsSetsBindingsSetFragImageBindingBaseCompiledAsVert) {
+  compiler_.SetAutoBindUniforms(true);
+  // This is ignored because we're compiling the shader as a vertex shader, not
+  // as a fragment shader.
+  compiler_.SetAutoBindingBaseForStage(Compiler::Stage::Fragment,
+                                       Compiler::UniformKind::Image, 100);
+  const auto words =
+      SimpleCompilationBinary(kGlslFragShaderNoExplicitBinding, EShLangVertex);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_tex Binding 0"))
+      << disassembly;
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_sam Binding 1"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_img Binding 2"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_imbuf Binding 3"));
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_ubo Binding 4"));
+}
+
+TEST_F(CompilerTest, NoAutoMapLocationsFailsCompilationOnOpenGLShader) {
+  compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL);
+  compiler_.SetAutoMapLocations(false);
+
+  const auto words =
+      SimpleCompilationBinary(kGlslVertShaderExplicitLocation, EShLangVertex);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpDecorate %my_mat Location 10"))
+      << disassembly;
+
+  EXPECT_FALSE(SimpleCompilationSucceeds(kGlslVertShaderNoExplicitLocation,
+                                         EShLangVertex));
+}
+
+TEST_F(CompilerTest, AutoMapLocationsSetsLocationsOnOpenGLShader) {
+  compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL);
+  compiler_.SetAutoMapLocations(true);
+
+  const auto words_no_auto =
+      SimpleCompilationBinary(kGlslVertShaderExplicitLocation, EShLangVertex);
+  const auto disassembly_no_auto = Disassemble(words_no_auto);
+  EXPECT_THAT(disassembly_no_auto, HasSubstr("OpDecorate %my_mat Location 10"))
+      << disassembly_no_auto;
+
+  const auto words_auto =
+      SimpleCompilationBinary(kGlslVertShaderNoExplicitLocation, EShLangVertex);
+  const auto disassembly_auto = Disassemble(words_auto);
+  EXPECT_THAT(disassembly_auto, HasSubstr("OpDecorate %my_mat Location 0"))
+      << disassembly_auto;
+}
+
+TEST_F(CompilerTest, EmitMessageTextOnlyOnce) {
+  // Emit a warning by compiling a shader without a default entry point name.
+  // The warning should only be emitted once even though we do parsing, linking,
+  // and IO mapping.
+  Compiler c;
+  std::stringstream errors;
+  size_t total_warnings = 0;
+  size_t total_errors = 0;
+  shaderc_util::GlslangInitializer initializer;
+  bool result = false;
+  DummyCountingIncluder dummy_includer;
+  std::tie(result, std::ignore, std::ignore) = c.Compile(
+      "#version 150\nvoid MyEntryPoint(){}", EShLangVertex, "shader", "",
+      dummy_stage_callback_, dummy_includer, Compiler::OutputType::SpirvBinary,
+      &errors, &total_warnings, &total_errors);
+  const std::string errs = errors.str();
+  EXPECT_THAT(errs, Eq("shader: error: Linking vertex stage: Missing entry "
+                       "point: Each stage requires one entry point\n"))
+      << errs;
+}
+
+TEST_F(CompilerTest, GlslDefaultPackingUsed) {
+  const auto words =
+      SimpleCompilationBinary(kGlslShaderWeirdPacking, EShLangVertex);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpMemberDecorate %B 1 Offset 16"))
+      << disassembly;
+}
+
+TEST_F(CompilerTest, HlslOffsetsOptionDisableRespected) {
+  compiler_.SetHlslOffsets(false);
+  const auto words =
+      SimpleCompilationBinary(kGlslShaderWeirdPacking, EShLangVertex);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpMemberDecorate %B 1 Offset 16"))
+      << disassembly;
+}
+
+TEST_F(CompilerTest, HlslOffsetsOptionEnableRespected) {
+  compiler_.SetHlslOffsets(true);
+  const auto words =
+      SimpleCompilationBinary(kGlslShaderWeirdPacking, EShLangVertex);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpMemberDecorate %B 1 Offset 4"))
+      << disassembly;
+}
+
+TEST_F(CompilerTest, HlslLegalizationEnabledNoSizeOpt) {
+  compiler_.SetSourceLanguage(Compiler::SourceLanguage::HLSL);
+  const auto words =
+      SimpleCompilationBinary(kHlslShaderForLegalizationTest, EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, Not(HasSubstr("OpFunctionCall"))) << disassembly;
+  EXPECT_THAT(disassembly, HasSubstr("OpName")) << disassembly;
+}
+
+TEST_F(CompilerTest, HlslLegalizationEnabledWithSizeOpt) {
+  compiler_.SetSourceLanguage(Compiler::SourceLanguage::HLSL);
+  compiler_.SetOptimizationLevel(Compiler::OptimizationLevel::Size);
+  const auto words =
+      SimpleCompilationBinary(kHlslShaderForLegalizationTest, EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, Not(HasSubstr("OpFunctionCall"))) << disassembly;
+  EXPECT_THAT(disassembly, Not(HasSubstr("OpName"))) << disassembly;
+}
+
+TEST_F(CompilerTest, HlslLegalizationDisabled) {
+  compiler_.SetSourceLanguage(Compiler::SourceLanguage::HLSL);
+  compiler_.EnableHlslLegalization(false);
+  const auto words =
+      SimpleCompilationBinary(kHlslShaderForLegalizationTest, EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpFunctionCall")) << disassembly;
+}
+
+TEST_F(CompilerTest, HlslFunctionality1Enabled) {
+  compiler_.SetSourceLanguage(Compiler::SourceLanguage::HLSL);
+  compiler_.EnableHlslFunctionality1(true);
+  compiler_.SetAutoBindUniforms(true);  // Counter variable needs a binding.
+  const auto words =
+      SimpleCompilationBinary(kHlslShaderWithCounterBuffer, EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly,
+              HasSubstr("OpExtension \"SPV_GOOGLE_hlsl_functionality1\""))
+      << disassembly;
+  EXPECT_THAT(disassembly,
+              HasSubstr("OpDecorateString %_entryPointOutput "
+                        "UserSemantic \"SV_TARGET0\""))
+      << disassembly;
+}
+
+TEST_F(CompilerTest, ClampMapsToFClampByDefault) {
+  const auto words =
+      SimpleCompilationBinary(kGlslShaderWithClamp, EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpExtInst %v4float %1 FClamp"))
+      << disassembly;
+}
+
+TEST_F(CompilerTest, ClampMapsToFClampWithNanClamp) {
+  compiler_.SetNanClamp(true);
+  const auto words =
+      SimpleCompilationBinary(kGlslShaderWithClamp, EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpExtInst %v4float %1 NClamp"))
+      << disassembly;
+}
+
+// A test coase for Glslang
+// expected vector after the conversion.
+struct GetGlslangClientInfoCase {
+  std::string prefix;
+  Compiler::TargetEnv env;
+  Compiler::TargetEnvVersion env_version;
+  Compiler::SpirvVersion spv_version;
+  bool spv_forced;
+  // Expected results.  The error field is matched as a substring.
+  GlslangClientInfo expected;
+};
+
+// Test the shaderc_util::GetGlslangClientInfo function.
+using GetGlslangClientInfoTest =
+    testing::TestWithParam<GetGlslangClientInfoCase>;
+
+TEST_P(GetGlslangClientInfoTest, Sample) {
+  const auto& c = GetParam();
+  const auto& expected = c.expected;
+  auto result = shaderc_util::GetGlslangClientInfo(
+      c.prefix, c.env, c.env_version, c.spv_version, c.spv_forced);
+
+  EXPECT_THAT(result.error.empty(), Eq(expected.error.empty()));
+  if (result.error.empty()) {
+    EXPECT_THAT(result.client, Eq(expected.client));
+    EXPECT_THAT(result.client_version, Eq(expected.client_version));
+    EXPECT_THAT(result.target_language, Eq(expected.target_language));
+    EXPECT_THAT(result.target_language_version,
+                Eq(expected.target_language_version));
+  } else {
+    EXPECT_THAT(result.error, HasSubstr(expected.error));
+  }
+}
+
+#define CASE_VK(VKVER, SPVVER)                                                 \
+  "", Compiler::TargetEnv::Vulkan, Compiler::TargetEnvVersion::Vulkan_##VKVER, \
+      Compiler::SpirvVersion::v##SPVVER
+
+#define BADCASE_VK(STR, VKVER, SPVVER)                \
+  STR, Compiler::TargetEnv::Vulkan,                   \
+      static_cast<Compiler::TargetEnvVersion>(VKVER), \
+      static_cast<Compiler::SpirvVersion>(SPVVER)
+
+#define CASE_GL(GLVER, SPVVER)                                                 \
+  "", Compiler::TargetEnv::OpenGL, Compiler::TargetEnvVersion::OpenGL_##GLVER, \
+      Compiler::SpirvVersion::v##SPVVER
+
+#define BADCASE_GL(STR, GLVER, SPVVER)                \
+  STR, Compiler::TargetEnv::OpenGL,                   \
+      static_cast<Compiler::TargetEnvVersion>(GLVER), \
+      static_cast<Compiler::SpirvVersion>(SPVVER)
+
+#define GCASE_VK(STR, VKVER, SPVVER)                             \
+  shaderc_util::GlslangClientInfo {                              \
+    std::string(STR), glslang::EShClientVulkan,                  \
+        glslang::EShTargetVulkan_##VKVER, glslang::EShTargetSpv, \
+        glslang::EShTargetSpv_##SPVVER                           \
+  }
+
+#define GCASE_GL(STR, GLVER, SPVVER)                             \
+  shaderc_util::GlslangClientInfo {                              \
+    std::string(STR), glslang::EShClientOpenGL,                  \
+        glslang::EShTargetOpenGL_##GLVER, glslang::EShTargetSpv, \
+        glslang::EShTargetSpv_##SPVVER                           \
+  }
+
+INSTANTIATE_TEST_SUITE_P(
+    UnforcedSpirvSuccess, GetGlslangClientInfoTest,
+    testing::ValuesIn(std::vector<GetGlslangClientInfoCase>{
+        // Unforced SPIR-V version. Success cases.
+        {CASE_VK(1_0, 1_4), false, GCASE_VK("", 1_0, 1_0)},
+        {CASE_VK(1_1, 1_4), false, GCASE_VK("", 1_1, 1_3)},
+        {CASE_GL(4_5, 1_4), false, GCASE_GL("", 450, 1_0)},
+    }));
+
+INSTANTIATE_TEST_SUITE_P(
+    ForcedSpirvSuccess, GetGlslangClientInfoTest,
+    testing::ValuesIn(std::vector<GetGlslangClientInfoCase>{
+        // Forced SPIR-V version. Success cases.
+        {CASE_VK(1_0, 1_0), true, GCASE_VK("", 1_0, 1_0)},
+        {CASE_VK(1_0, 1_1), true, GCASE_VK("", 1_0, 1_1)},
+        {CASE_VK(1_0, 1_2), true, GCASE_VK("", 1_0, 1_2)},
+        {CASE_VK(1_0, 1_3), true, GCASE_VK("", 1_0, 1_3)},
+        {CASE_VK(1_1, 1_0), true, GCASE_VK("", 1_1, 1_0)},
+        {CASE_VK(1_1, 1_1), true, GCASE_VK("", 1_1, 1_1)},
+        {CASE_VK(1_1, 1_2), true, GCASE_VK("", 1_1, 1_2)},
+        {CASE_VK(1_1, 1_3), true, GCASE_VK("", 1_1, 1_3)},
+        {CASE_GL(4_5, 1_0), true, GCASE_GL("", 450, 1_0)},
+        {CASE_GL(4_5, 1_1), true, GCASE_GL("", 450, 1_1)},
+        {CASE_GL(4_5, 1_2), true, GCASE_GL("", 450, 1_2)},
+    }));
+
+INSTANTIATE_TEST_SUITE_P(
+    Failure, GetGlslangClientInfoTest,
+    testing::ValuesIn(std::vector<GetGlslangClientInfoCase>{
+        // Failure cases.
+        {BADCASE_VK("foo", 999, Compiler::SpirvVersion::v1_0), false,
+         GCASE_VK("error:foo: Invalid target client version 999 for Vulkan "
+                  "environment 0",
+                  1_0, 1_0)},
+        {BADCASE_GL("foo", 999, Compiler::SpirvVersion::v1_0), false,
+         GCASE_GL("error:foo: Invalid target client version 999 for OpenGL "
+                  "environment 1",
+                  450, 1_0)},
+        // For bad SPIR-V versions, have to force=true to make it pay attention.
+        {BADCASE_VK("foo", Compiler::TargetEnvVersion::Vulkan_1_0, 999), true,
+         GCASE_VK("error:foo: Unknown SPIR-V version 3e7", 1_0, 1_0)},
+        {BADCASE_GL("foo", Compiler::TargetEnvVersion::OpenGL_4_5, 999), true,
+         GCASE_GL("error:foo: Unknown SPIR-V version 3e7", 450, 1_0)},
+    }));
+
+#undef CASE_VK
+#undef CASE_GL
+#undef BADCASE_VK
+#undef BADCASE_GL
+#undef GCASE_VK
+#undef GCASE_GL
 }  // anonymous namespace
diff --git a/libshaderc_util/src/counting_includer_test.cc b/libshaderc_util/src/counting_includer_test.cc
index 0400ae3..fbac441 100644
--- a/libshaderc_util/src/counting_includer_test.cc
+++ b/libshaderc_util/src/counting_includer_test.cc
@@ -14,66 +14,75 @@
 
 #include "libshaderc_util/counting_includer.h"
 
-#include <gmock/gmock.h>
 #include <thread>
+#include <vector>
+
+#include <gmock/gmock.h>
 
 namespace {
 
-const auto kRelative = glslang::TShader::Includer::EIncludeRelative;
-const auto kStandard = glslang::TShader::Includer::EIncludeStandard;
-
 // A trivial implementation of CountingIncluder's virtual methods, so tests can
 // instantiate.
 class ConcreteCountingIncluder : public shaderc_util::CountingIncluder {
  public:
-  virtual glslang::TShader::Includer::IncludeResult* include_delegate(
-      const char* requested, glslang::TShader::Includer::IncludeType,
-      const char* requestor,
+  using IncludeResult = glslang::TShader::Includer::IncludeResult;
+  ~ConcreteCountingIncluder() {
+    // Avoid leaks.
+    for (auto result : results_) {
+      release_delegate(result);
+    }
+  }
+  virtual IncludeResult* include_delegate(
+      const char* requested, const char* requestor, IncludeType,
       size_t) override {
     const char kError[] = "Unexpected #include";
-    return new glslang::TShader::Includer::IncludeResult{
-        "", kError, strlen(kError), nullptr};
+    results_.push_back(new IncludeResult{"", kError, strlen(kError), nullptr});
+    return results_.back();
   }
-  virtual void release_delegate(
-      glslang::TShader::Includer::IncludeResult* include_result) override {
+  virtual void release_delegate(IncludeResult* include_result) override {
     delete include_result;
   }
+
+ private:
+  // All the results we've returned so far.
+  std::vector<IncludeResult*> results_;
 };
 
 TEST(CountingIncluderTest, InitialCount) {
   EXPECT_EQ(0, ConcreteCountingIncluder().num_include_directives());
 }
 
-TEST(CountingIncluderTest, OneInclude) {
+TEST(CountingIncluderTest, OneIncludeLocal) {
   ConcreteCountingIncluder includer;
-  includer.include("random file name", kRelative, "from me", 0);
+  includer.includeLocal("random file name", "from me", 0);
   EXPECT_EQ(1, includer.num_include_directives());
 }
 
 TEST(CountingIncluderTest, TwoIncludesAnyIncludeType) {
   ConcreteCountingIncluder includer;
-  includer.include("name1", kRelative, "from me", 0);
-  includer.include("name2", kStandard, "me", 0);
+  includer.includeSystem("name1", "from me", 0);
+  includer.includeLocal("name2", "me", 0);
   EXPECT_EQ(2, includer.num_include_directives());
 }
 
 TEST(CountingIncluderTest, ManyIncludes) {
   ConcreteCountingIncluder includer;
   for (int i = 0; i < 100; ++i) {
-    includer.include("filename", kRelative, "from me", i);
+    includer.includeLocal("filename", "from me", i);
+    includer.includeSystem("filename", "from me", i);
   }
-  EXPECT_EQ(100, includer.num_include_directives());
+  EXPECT_EQ(200, includer.num_include_directives());
 }
 
 #ifndef SHADERC_DISABLE_THREADED_TESTS
 TEST(CountingIncluderTest, ThreadedIncludes) {
   ConcreteCountingIncluder includer;
   std::thread t1(
-      [&includer]() { includer.include("name1", kRelative, "me", 0); });
+      [&includer]() { includer.includeLocal("name1", "me", 0); });
   std::thread t2(
-      [&includer]() { includer.include("name2", kRelative, "me", 1); });
+      [&includer]() { includer.includeSystem("name2", "me", 1); });
   std::thread t3(
-      [&includer]() { includer.include("name3", kRelative, "me", 2); });
+      [&includer]() { includer.includeLocal("name3", "me", 2); });
   t1.join();
   t2.join();
   t3.join();
diff --git a/libshaderc_util/src/io.cc b/libshaderc_util/src/io.cc
index 4692b14..42ae89d 100644
--- a/libshaderc_util/src/io.cc
+++ b/libshaderc_util/src/io.cc
@@ -16,7 +16,15 @@
 
 #include "libshaderc_util/universal_unistd.h"
 
+#if _WIN32
+// Need _fileno from stdio.h
+// Need _O_BINARY and _O_TEXT from fcntl.h
+#include <fcntl.h>
+#include <stdio.h>
+#endif
+
 #include <errno.h>
+#include <cstdio>
 #include <cstring>
 #include <fstream>
 #include <iostream>
@@ -90,13 +98,13 @@
 }
 
 std::ostream* GetOutputStream(const string_piece& output_filename,
-                              std::ofstream* file_stream) {
+                              std::ofstream* file_stream, std::ostream* err) {
   std::ostream* stream = &std::cout;
   if (output_filename != "-") {
     file_stream->open(output_filename.str(), std::ios_base::binary);
     stream = file_stream;
     if (file_stream->fail()) {
-      std::cerr << "glslc: error: cannot open output file: '" << output_filename
+      *err << "glslc: error: cannot open output file: '" << output_filename
                 << "'";
       if (access(output_filename.str().c_str(), W_OK) != 0) {
         OutputFileErrorMessage(errno);
@@ -120,4 +128,18 @@
   return true;
 }
 
+void FlushAndSetBinaryModeOnStdout() {
+  std::fflush(stdout);
+#if _WIN32
+  _setmode(_fileno(stdout), _O_BINARY);
+#endif
+}
+
+void FlushAndSetTextModeOnStdout() {
+  std::fflush(stdout);
+#if _WIN32
+  _setmode(_fileno(stdout), _O_TEXT);
+#endif
+}
+
 }  // namespace shaderc_util
diff --git a/libshaderc_util/src/io_test.cc b/libshaderc_util/src/io_test.cc
index bb0d916..0f605dc 100644
--- a/libshaderc_util/src/io_test.cc
+++ b/libshaderc_util/src/io_test.cc
@@ -25,6 +25,8 @@
 using shaderc_util::WriteFile;
 using shaderc_util::GetOutputStream;
 using shaderc_util::GetBaseFileName;
+using testing::Eq;
+using testing::HasSubstr;
 
 std::string ToString(const std::vector<char>& v) {
   return std::string(v.data(), v.size());
@@ -105,18 +107,23 @@
 
 TEST(WriteFiletest, BadStream) {
   std::ofstream fstream;
+  std::ostringstream err;
   std::ostream* output_stream = GetOutputStream(
-      "/this/should/not/be/writable/asdfasdfasdfasdf", &fstream);
+      "/this/should/not/be/writable/asdfasdfasdfasdf", &fstream, &err);
   EXPECT_EQ(nullptr, output_stream);
   EXPECT_TRUE(fstream.fail());
+  EXPECT_EQ(nullptr, output_stream);
+  EXPECT_THAT(err.str(), HasSubstr("cannot open output file"));
 }
 
 TEST(WriteFileTest, Roundtrip) {
   const std::string content = "random content 12345";
   const std::string filename = "WriteFileTestOutput.tmp";
   std::ofstream fstream;
-  std::ostream* output_stream = GetOutputStream(filename, &fstream);
+  std::ostringstream err;
+  std::ostream* output_stream = GetOutputStream(filename, &fstream, &err);
   ASSERT_EQ(output_stream, &fstream);
+  EXPECT_THAT(err.str(), Eq(""));
   ASSERT_TRUE(WriteFile(output_stream, content));
   std::vector<char> read_data;
   ASSERT_TRUE(ReadFile(filename, &read_data));
@@ -125,7 +132,9 @@
 
 TEST(OutputStreamTest, Stdout) {
   std::ofstream fstream;
-  std::ostream* output_stream = GetOutputStream("-", &fstream);
+  std::ostringstream err;
+  std::ostream* output_stream = GetOutputStream("-", &fstream, &err);
   EXPECT_EQ(&std::cout, output_stream);
+  EXPECT_THAT(err.str(), Eq(""));
 }
 }  // anonymous namespace
diff --git a/libshaderc_util/src/message.cc b/libshaderc_util/src/message.cc
index 11fd10a..3604b1e 100644
--- a/libshaderc_util/src/message.cc
+++ b/libshaderc_util/src/message.cc
@@ -45,41 +45,72 @@
 }
 
 // Deduces a location specification from the given message. A location
-// specification is of the form "<source-name>:<line-number>:". If the deduction
-// is successful, returns true and updates source_name and line_number to the
-// deduced source name and line numer respectively. The prefix standing for the
-// location specification in message is skipped. Otherwise, returns false and
-// keeps all parameters untouched.
+// specification is of the form "<source-name>:<line-number>:" and a trailing
+// space.  If the deduction is successful, returns true and updates source_name
+// and line_number to the deduced source name and line numer respectively. The
+// prefix standing for the location specification in message is skipped.
+// Otherwise, returns false and keeps all parameters untouched.
 bool DeduceLocationSpec(string_piece* message, string_piece* source_name,
                         string_piece* line_number) {
-  // TODO(antiagainst): we use ':' as a delimiter here. It may be a valid
-  // character in the filename. Also be aware of other special characters,
-  // for example, ' '.
-  string_piece rest(*message);
-  size_t colon_after_source = rest.find_first_of(':');
-  if (colon_after_source == string_piece::npos) return false;
-
-  string_piece source = rest.substr(0, colon_after_source);
-  rest = rest.substr(colon_after_source + 1);
-  size_t colon_after_line = rest.find_first_of(':');
-  if (source.size() == 1 && ::isalpha(source.front()) && rest.size() > 0 &&
-      rest.front() == '\\') {
-    // Handle Windows path.
-    colon_after_source += colon_after_line + 1;
-    source = message->substr(0, colon_after_source);
-    rest = rest.substr(colon_after_line + 1);
-    colon_after_line = rest.find_first_of(':');
+  if (!message || message->empty()) {
+    return false;
   }
 
-  if (colon_after_line == string_piece::npos) return false;
-  const string_piece line = rest.substr(0, colon_after_line);
+  // When we find a pattern like this:
+  //     colon
+  //     digits
+  //     colon
+  //     space
+  // Then deduce that the source_name is the text before the first colon,
+  // the line number is the digits, and the message is the text after the
+  // second colon.
 
-  if (!std::all_of(line.begin(), line.end(), ::isdigit)) return false;
+  const size_t size = message->size();
+  if (size <= 4) {
+    // A valid message must have a colon, a digit, a colon, and a space.
+    return false;
+  }
+  // The last possible position of the first colon.
+  const size_t first_colon_cutoff = size - 4;
+  // The last possible position of the second colon.
+  const size_t next_colon_cutoff = size - 2;
 
-  *source_name = source;
-  *line_number = line;
-  *message = rest.substr(colon_after_line + 1).strip_whitespace();
-  return true;
+  for (size_t first_colon_pos = message->find_first_of(':'), next_colon_pos = 0;
+
+       // There is a first colon, and it's not too close to the end
+       (first_colon_pos != string_piece::npos) &&
+       (first_colon_pos <= first_colon_cutoff);
+
+       // Try the next pair of colons.
+       first_colon_pos = next_colon_pos) {
+    // We're guaranteed to have at least 3 more characters.
+    // Guarantee progress toward the end of the string.
+    next_colon_pos = message->find_first_of(':', first_colon_pos + 1);
+    if ((next_colon_pos == string_piece::npos) ||
+        (next_colon_pos > next_colon_cutoff)) {
+      // No valid solution.
+      return false;
+    }
+    if (first_colon_pos + 1 == next_colon_pos) {
+      // There is no room for digits.
+      continue;
+    }
+    if ((message->data()[next_colon_pos + 1] != ' ')) {
+      // There is no space character after the second colon.
+      continue;
+    }
+    if (message->find_first_not_of("0123456789", first_colon_pos + 1) ==
+        next_colon_pos) {
+      // We found the first solution.
+      *source_name = message->substr(0, first_colon_pos);
+      *line_number = message->substr(first_colon_pos + 1,
+                                     next_colon_pos - 1 - first_colon_pos);
+      *message = message->substr(next_colon_pos + 2);
+      return true;
+    }
+  }
+
+  return false;
 }
 
 // Returns true if the given message is a summary message.
@@ -114,6 +145,8 @@
   // <location-specification> is of the form:
   //   <filename-or-string-number>:<line-number>:
   // It doesn't exist if the warning/error message is a global one.
+  //
+  // See Glslang's TInfoSink class implementation for details.
 
   bool is_error = false;
 
diff --git a/libshaderc_util/src/message_test.cc b/libshaderc_util/src/message_test.cc
index 5d65023..26dc26b 100644
--- a/libshaderc_util/src/message_test.cc
+++ b/libshaderc_util/src/message_test.cc
@@ -135,6 +135,8 @@
   string_piece line_number;
   string_piece rest;
 
+  // Glslang reading from strings can give string segment numbers as
+  // the filename part.
   EXPECT_EQ(
       MessageType::Error,
       ParseGlslangOutput("ERROR: 0:2: '#' : invalid directive: foo", false,
@@ -154,7 +156,7 @@
             rest.str());
 }
 
-TEST(ParseGlslangOutputTest, FileName) {
+TEST(ParseGlslangOutputTest, FileName_BaseAndExtension) {
   string_piece source_name;
   string_piece line_number;
   string_piece rest;
@@ -165,6 +167,12 @@
   EXPECT_EQ("shader.vert", source_name.str());
   EXPECT_EQ("5", line_number.str());
   EXPECT_EQ("something wrong", rest.str());
+}
+
+TEST(ParseGlslangOutputTest, FileName_BaseOnly) {
+  string_piece source_name;
+  string_piece line_number;
+  string_piece rest;
 
   EXPECT_EQ(MessageType::Warning,
             ParseGlslangOutput("WARNING: file:42: something wrong", false,
@@ -172,6 +180,12 @@
   EXPECT_EQ("file", source_name.str());
   EXPECT_EQ("42", line_number.str());
   EXPECT_EQ("something wrong", rest.str());
+}
+
+TEST(ParseGlslangOutputTest, FileName_HexNumber) {
+  string_piece source_name;
+  string_piece line_number;
+  string_piece rest;
 
   EXPECT_EQ(MessageType::Warning,
             ParseGlslangOutput("WARNING: 0xdeedbeef:0: wa:ha:ha", false, false,
@@ -181,6 +195,60 @@
   EXPECT_EQ("wa:ha:ha", rest.str());
 }
 
+TEST(ParseGlslangOutputTest, FileName_ContainsColons) {
+  string_piece source_name;
+  string_piece line_number;
+  string_piece rest;
+
+  EXPECT_EQ(MessageType::Warning,
+            ParseGlslangOutput("WARNING:  foo:bar:0: wa:ha:ha", false, false,
+                               &source_name, &line_number, &rest));
+  EXPECT_EQ("foo:bar", source_name.str());
+  EXPECT_EQ("0", line_number.str());
+  EXPECT_EQ("wa:ha:ha", rest.str());
+}
+
+TEST(ParseGlslangOutputTest, NoFile) {
+  string_piece source_name;
+  string_piece line_number;
+  string_piece rest;
+
+  EXPECT_EQ(MessageType::Warning,
+            ParseGlslangOutput("WARNING:  :12: abc", false, false, &source_name,
+                               &line_number, &rest));
+  EXPECT_EQ("", source_name.str());
+  EXPECT_EQ("12", line_number.str());
+  EXPECT_EQ("abc", rest.str());
+}
+
+TEST(ParseGlslangOutputTest, NoLineNumber_InferredAsGlobalNoLocation) {
+  string_piece source_name;
+  string_piece line_number;
+  string_piece rest;
+
+  // No solution since there is no room for digits.
+  EXPECT_EQ(MessageType::GlobalWarning,
+            ParseGlslangOutput("WARNING:  foo:: abc", false, false,
+                               &source_name, &line_number, &rest));
+  EXPECT_EQ("", source_name.str());
+  EXPECT_EQ("", line_number.str());
+  EXPECT_EQ("foo:: abc", rest.str());
+}
+
+TEST(ParseGlslangOutputTest, NoSpaceAfterColon_InferredAsGlobalNoLocation) {
+  string_piece source_name;
+  string_piece line_number;
+  string_piece rest;
+
+  // No solution since there is no space after the line-number-and-colon.
+  EXPECT_EQ(MessageType::GlobalWarning,
+            ParseGlslangOutput("WARNING:  foo:12:abc", false, false,
+                               &source_name, &line_number, &rest));
+  EXPECT_EQ("", source_name.str());
+  EXPECT_EQ("", line_number.str());
+  EXPECT_EQ("foo:12:abc", rest.str());
+}
+
 TEST(ParseGlslangOutputTest, WindowsPath) {
   string_piece source_name;
   string_piece line_number;
diff --git a/libshaderc_util/src/resources.cc b/libshaderc_util/src/resources.cc
index e7dc069..d64e47f 100644
--- a/libshaderc_util/src/resources.cc
+++ b/libshaderc_util/src/resources.cc
@@ -32,7 +32,12 @@
     /*.maxCombinedTextureImageUnits = */ 80,
     /*.maxTextureImageUnits = */ 16,
     /*.maxFragmentUniformComponents = */ 1024,
-    /*.maxDrawBuffers = */ 2,
+
+    // glslang has 32 maxDrawBuffers.
+    // Pixel phone Vulkan driver in Android N has 8
+    // maxFragmentOutputAttachments.
+    /*.maxDrawBuffers = */ 8, 
+
     /*.maxVertexUniformVectors = */ 256,
     /*.maxVaryingVectors = */ 15,  // From OpenGLES 3.1 table 6.44.
     /*.maxFragmentUniformVectors = */ 256,
@@ -111,6 +116,16 @@
     /*.maxCullDistances = */ 8,                 // ARB_cull_distance.
     /*.maxCombinedClipAndCullDistances = */ 8,  // ARB_cull_distance.
     /*.maxSamples = */ 4,
+    /* .maxMeshOutputVerticesNV = */ 256,
+    /* .maxMeshOutputPrimitivesNV = */ 512,
+    /* .maxMeshWorkGroupSizeX_NV = */ 32,
+    /* .maxMeshWorkGroupSizeY_NV = */ 1,
+    /* .maxMeshWorkGroupSizeZ_NV = */ 1,
+    /* .maxTaskWorkGroupSizeX_NV = */ 32,
+    /* .maxTaskWorkGroupSizeY_NV = */ 1,
+    /* .maxTaskWorkGroupSizeZ_NV = */ 1,
+    /* .maxMeshViewCountNV = */ 4,
+    /* .maxDualSourceDrawBuffersEXT = */ 1,
     // This is the glslang TLimits structure.
     // It defines whether or not the following features are enabled.
     // We want them to all be enabled.
diff --git a/libshaderc_util/src/shader_stage.cc b/libshaderc_util/src/shader_stage.cc
index 9b693c3..3122a3d 100644
--- a/libshaderc_util/src/shader_stage.cc
+++ b/libshaderc_util/src/shader_stage.cc
@@ -33,7 +33,16 @@
       {"tesscontrol", EShLangTessControl},
       {"tesseval", EShLangTessEvaluation},
       {"geometry", EShLangGeometry},
-      {"compute", EShLangCompute}};
+      {"compute", EShLangCompute},
+      {"raygen", EShLangRayGenNV},
+      {"intersect", EShLangIntersectNV},
+      {"anyhit", EShLangAnyHitNV},
+      {"closest", EShLangClosestHitNV},
+      {"miss", EShLangMissNV},
+      {"callable", EShLangCallableNV},
+      {"task", EShLangTaskNV},
+      {"mesh", EShLangMeshNV},
+  };
 
   for (const auto& entry : string_to_stage) {
     if (stage_name == entry.id) return entry.language;
diff --git a/libshaderc_util/src/spirv_tools_wrapper.cc b/libshaderc_util/src/spirv_tools_wrapper.cc
index 273d1ba..4ed2bac 100644
--- a/libshaderc_util/src/spirv_tools_wrapper.cc
+++ b/libshaderc_util/src/spirv_tools_wrapper.cc
@@ -24,40 +24,61 @@
 namespace {
 
 // Gets the corresponding target environment used in SPIRV-Tools.
-spv_target_env GetSpirvToolsTargetEnv(Compiler::TargetEnv env) {
+spv_target_env GetSpirvToolsTargetEnv(Compiler::TargetEnv env,
+                                      Compiler::TargetEnvVersion version) {
   switch (env) {
     case Compiler::TargetEnv::Vulkan:
-      return SPV_ENV_VULKAN_1_0;
+      switch (version) {
+        case Compiler::TargetEnvVersion::Default:
+          return SPV_ENV_VULKAN_1_0;
+        case Compiler::TargetEnvVersion::Vulkan_1_0:
+          return SPV_ENV_VULKAN_1_0;
+        case Compiler::TargetEnvVersion::Vulkan_1_1:
+          return SPV_ENV_VULKAN_1_1;
+        case Compiler::TargetEnvVersion::Vulkan_1_2:
+          return SPV_ENV_VULKAN_1_2;
+        default:
+          break;
+      }
+      break;
     case Compiler::TargetEnv::OpenGL:
       return SPV_ENV_OPENGL_4_5;
-    case Compiler::TargetEnv::OpenGLCompat:
-      return SPV_ENV_OPENGL_4_5;  // TODO(antiagainst): is this correct?
+    case Compiler::TargetEnv::OpenGLCompat:  // Deprecated
+      return SPV_ENV_OPENGL_4_5;
   }
+  assert(false && "unexpected target environment or version");
   return SPV_ENV_VULKAN_1_0;
 }
 
 }  // anonymous namespace
 
 bool SpirvToolsDisassemble(Compiler::TargetEnv env,
+                           Compiler::TargetEnvVersion version,
                            const std::vector<uint32_t>& binary,
                            std::string* text_or_error) {
-  spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0);
+  spvtools::SpirvTools tools(GetSpirvToolsTargetEnv(env, version));
   std::ostringstream oss;
-  tools.SetMessageConsumer([&oss](
-      spv_message_level_t, const char*, const spv_position_t& position,
-      const char* message) { oss << position.index << ": " << message; });
-  const bool success = tools.Disassemble(
-      binary, text_or_error, SPV_BINARY_TO_TEXT_OPTION_INDENT |
-                                 SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
+  tools.SetMessageConsumer([&oss](spv_message_level_t, const char*,
+                                  const spv_position_t& position,
+                                  const char* message) {
+    oss << position.index << ": " << message;
+  });
+  const bool success =
+      tools.Disassemble(binary, text_or_error,
+                        SPV_BINARY_TO_TEXT_OPTION_INDENT |
+                            SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
   if (!success) {
     *text_or_error = oss.str();
   }
   return success;
 }
 
-bool SpirvToolsAssemble(Compiler::TargetEnv env, const string_piece assembly,
-                        spv_binary* binary, std::string* errors) {
-  auto spvtools_context = spvContextCreate(GetSpirvToolsTargetEnv(env));
+bool SpirvToolsAssemble(Compiler::TargetEnv env,
+                        Compiler::TargetEnvVersion version,
+                        const string_piece assembly, spv_binary* binary,
+                        std::string* errors) {
+  auto spvtools_context =
+      spvContextCreate(GetSpirvToolsTargetEnv(env, version));
   spv_diagnostic spvtools_diagnostic = nullptr;
 
   *binary = nullptr;
@@ -81,6 +102,7 @@
 }
 
 bool SpirvToolsOptimize(Compiler::TargetEnv env,
+                        Compiler::TargetEnvVersion version,
                         const std::vector<PassId>& enabled_passes,
                         std::vector<uint32_t>* binary, std::string* errors) {
   errors->clear();
@@ -91,7 +113,20 @@
     return true;
   }
 
-  spvtools::Optimizer optimizer(GetSpirvToolsTargetEnv(env));
+  spvtools::ValidatorOptions val_opts;
+  // This allows flexible memory layout for HLSL.
+  val_opts.SetSkipBlockLayout(true);
+  // This allows HLSL legalization regarding resources.
+  val_opts.SetRelaxLogicalPointer(true);
+  // This uses relaxed rules for pre-legalized HLSL.
+  val_opts.SetBeforeHlslLegalization(true);
+
+  spvtools::OptimizerOptions opt_opts;
+  opt_opts.set_validator_options(val_opts);
+  opt_opts.set_run_validator(true);
+
+  spvtools::Optimizer optimizer(GetSpirvToolsTargetEnv(env, version));
+
   std::ostringstream oss;
   optimizer.SetMessageConsumer(
       [&oss](spv_message_level_t, const char*, const spv_position_t&,
@@ -99,19 +134,28 @@
 
   for (const auto& pass : enabled_passes) {
     switch (pass) {
+      case PassId::kLegalizationPasses:
+        optimizer.RegisterLegalizationPasses();
+        break;
+      case PassId::kPerformancePasses:
+        optimizer.RegisterPerformancePasses();
+        break;
+      case PassId::kSizePasses:
+        optimizer.RegisterSizePasses();
+        break;
       case PassId::kNullPass:
         // We actually don't need to do anything for null pass.
         break;
       case PassId::kStripDebugInfo:
         optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
         break;
-      case PassId::kUnifyConstant:
-        optimizer.RegisterPass(spvtools::CreateUnifyConstantPass());
+      case PassId::kCompactIds:
+        optimizer.RegisterPass(spvtools::CreateCompactIdsPass());
         break;
     }
   }
 
-  if (!optimizer.Run(binary->data(), binary->size(), binary)) {
+  if (!optimizer.Run(binary->data(), binary->size(), binary, opt_opts)) {
     *errors = oss.str();
     return false;
   }
diff --git a/libshaderc_util/src/version_profile_test.cc b/libshaderc_util/src/version_profile_test.cc
new file mode 100644
index 0000000..9adb294
--- /dev/null
+++ b/libshaderc_util/src/version_profile_test.cc
@@ -0,0 +1,133 @@
+// Copyright 2017 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "libshaderc_util/version_profile.h"
+
+#include "gmock/gmock.h"
+
+namespace {
+
+using shaderc_util::IsKnownVersion;
+using shaderc_util::ParseVersionProfile;
+using ::testing::Eq;
+using ::testing::ValuesIn;
+
+
+TEST(IsKnownVersionTest, Samples) {
+  EXPECT_TRUE(IsKnownVersion(100));
+  EXPECT_TRUE(IsKnownVersion(110));
+  EXPECT_TRUE(IsKnownVersion(120));
+  EXPECT_TRUE(IsKnownVersion(130));
+  EXPECT_TRUE(IsKnownVersion(140));
+  EXPECT_TRUE(IsKnownVersion(150));
+  EXPECT_TRUE(IsKnownVersion(300));
+  EXPECT_TRUE(IsKnownVersion(330));
+  EXPECT_TRUE(IsKnownVersion(310));
+  EXPECT_TRUE(IsKnownVersion(400));
+  EXPECT_TRUE(IsKnownVersion(410));
+  EXPECT_TRUE(IsKnownVersion(420));
+  EXPECT_TRUE(IsKnownVersion(430));
+  EXPECT_TRUE(IsKnownVersion(440));
+  EXPECT_TRUE(IsKnownVersion(450));
+  EXPECT_TRUE(IsKnownVersion(460));
+  EXPECT_FALSE(IsKnownVersion(101));
+  EXPECT_FALSE(IsKnownVersion(470));
+}
+
+
+struct ParseVersionProfileCase {
+  std::string input;
+  bool success;
+  // The following are only used when success is true.
+  int expected_version;
+  EProfile expected_profile;
+};
+
+using ParseVersionProfileTest = ::testing::TestWithParam<ParseVersionProfileCase>;
+
+TEST_P(ParseVersionProfileTest, Sample) {
+  int version = 0;
+  EProfile profile = EBadProfile;
+  const bool result = ParseVersionProfile(GetParam().input, &version, &profile);
+  EXPECT_THAT(result, GetParam().success);
+  if (result) {
+    EXPECT_THAT(version, GetParam().expected_version);
+    EXPECT_THAT(profile, GetParam().expected_profile);
+  }
+}
+
+
+// For OpenGL ES GLSL (ESSL) versions, see
+// https://www.khronos.org/registry/OpenGL/index_e.php
+
+INSTANTIATE_TEST_SUITE_P(OpenGLESCases, ParseVersionProfileTest,
+                        ValuesIn(std::vector<ParseVersionProfileCase>{
+                            {"100es", true, 100, EEsProfile},
+                            {"300es", true, 300, EEsProfile},
+                            {"310es", true, 310, EEsProfile},
+                            {"320es", true, 320, EEsProfile},
+                            {"99es", false, 0, EBadProfile},
+                            {"500es", false, 0, EBadProfile},
+                        }));
+
+// For OpenGL GLSL versions, see
+// https://www.khronos.org/registry/OpenGL/index_gl.php
+
+INSTANTIATE_TEST_SUITE_P(OpenGLBlankCases, ParseVersionProfileTest,
+                        ValuesIn(std::vector<ParseVersionProfileCase>{
+                            {"110", true, 110, ENoProfile},
+                            {"120", true, 120, ENoProfile},
+                            {"130", true, 130, ENoProfile},
+                            {"140", true, 140, ENoProfile},
+                            {"150", true, 150, ENoProfile},
+                            {"330", true, 330, ENoProfile},
+                            {"400", true, 400, ENoProfile},
+                            {"410", true, 410, ENoProfile},
+                            {"420", true, 420, ENoProfile},
+                            {"430", true, 430, ENoProfile},
+                            {"440", true, 440, ENoProfile},
+                            {"450", true, 450, ENoProfile},
+                            {"460", true, 460, ENoProfile},
+                            {"99", false, 0, EBadProfile},
+                            {"500", false, 0, EBadProfile},
+                        }));
+
+INSTANTIATE_TEST_SUITE_P(OpenGLCoreCases, ParseVersionProfileTest,
+                        ValuesIn(std::vector<ParseVersionProfileCase>{
+                            {"320core", true, 320, ECoreProfile},
+                            {"330core", true, 330, ECoreProfile},
+                            {"400core", true, 400, ECoreProfile},
+                            {"410core", true, 410, ECoreProfile},
+                            {"420core", true, 420, ECoreProfile},
+                            {"430core", true, 430, ECoreProfile},
+                            {"440core", true, 440, ECoreProfile},
+                            {"450core", true, 450, ECoreProfile},
+                            {"460core", true, 460, ECoreProfile},
+                        }));
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenGLCompatibilityCases, ParseVersionProfileTest,
+    ValuesIn(std::vector<ParseVersionProfileCase>{
+        {"320compatibility", true, 320, ECompatibilityProfile},
+        {"330compatibility", true, 330, ECompatibilityProfile},
+        {"400compatibility", true, 400, ECompatibilityProfile},
+        {"410compatibility", true, 410, ECompatibilityProfile},
+        {"420compatibility", true, 420, ECompatibilityProfile},
+        {"430compatibility", true, 430, ECompatibilityProfile},
+        {"440compatibility", true, 440, ECompatibilityProfile},
+        {"450compatibility", true, 450, ECompatibilityProfile},
+        {"460compatibility", true, 460, ECompatibilityProfile},
+    }));
+
+}  // anonymous namespace
diff --git a/libshaderc_util/testdata/copy-to-build.cmake b/libshaderc_util/testdata/copy-to-build.cmake
index bf50a72..7b41b61 100644
--- a/libshaderc_util/testdata/copy-to-build.cmake
+++ b/libshaderc_util/testdata/copy-to-build.cmake
@@ -1,2 +1,16 @@
+# Copyright 2020 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 file(GLOB all_files ${CMAKE_CURRENT_LIST_DIR}/*)
 file(COPY ${all_files} DESTINATION .)
\ No newline at end of file
diff --git a/license-checker.cfg b/license-checker.cfg
new file mode 100644
index 0000000..0e00206
--- /dev/null
+++ b/license-checker.cfg
@@ -0,0 +1,36 @@
+[
+    {
+        "licenses": [ "Apache-2.0-Header" ],
+        "paths": [
+            {
+                "exclude": [
+                    "**.md",
+                    "**.png",
+                    "**/README.asciidoc",
+
+                    ".*",
+                    "AUTHORS",
+                    "CHANGES",
+                    "CONTRIBUTORS",
+                    "DEPS",
+                    "LICENSE",
+
+                    "cmake/*.pc.in",
+                    "libshaderc_util/testdata/dir/subdir/include_file.2",
+                    "libshaderc_util/testdata/include_file.1",
+
+                    "utils/git-sync-deps",
+
+                    "third_party/**"
+                ]
+            }
+        ]
+    },
+    {
+        "licenses": [ "BSD-3-Clause" ],
+        "paths": [
+            { "exclude": [ "**" ] },
+            { "include": [ "utils/git-sync-deps" ] }
+        ]
+    }
+]
\ No newline at end of file
diff --git a/third_party/Android.mk b/third_party/Android.mk
index 40395ad..16ea3a1 100644
--- a/third_party/Android.mk
+++ b/third_party/Android.mk
@@ -1,231 +1,35 @@
 THIRD_PARTY_PATH := $(call my-dir)
 
-GLSLANG_LOCAL_PATH := $(THIRD_PARTY_PATH)/glslang
-LOCAL_PATH := $(GLSLANG_LOCAL_PATH)
+# Set the location of glslang
+ifeq ($(GLSLANG_LOCAL_PATH),)
+	GLSLANG_LOCAL_PATH:=$(THIRD_PARTY_PATH)/glslang
+endif
+include $(GLSLANG_LOCAL_PATH)/Android.mk
 
-GLSLANG_OS_FLAGS := -DGLSLANG_OSINCLUDE_UNIX
-# AMD extensions are turned on by default in upstream Glslang.
-GLSLANG_DEFINES:= -DAMD_EXTENSIONS $(GLSLANG_OS_FLAGS)
+# Set the location of SPIRV-Tools.
+# Allow the user to override it, but default it to under our third_party directory.
+ifeq ($(SPVTOOLS_LOCAL_PATH),)
+  SPVTOOLS_LOCAL_PATH:=$(THIRD_PARTY_PATH)/spirv-tools
+endif
+ifeq ($(SPVHEADERS_LOCAL_PATH),)
+   # Use the third party dir if it exists.
+   ifneq ($(wildcard $(THIRD_PARTY_PATH)/spirv-headers/include/spirv/spir-v.xml),)
+     SPVHEADERS_LOCAL_PATH:=$(THIRD_PARTY_PATH)/spirv-headers
+   else
+     # Let SPIRV-Tools find its own headers and hope for the best.
+   endif
+endif
 
-include $(CLEAR_VARS)
-LOCAL_MODULE:=SPIRV
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
-LOCAL_EXPORT_C_INCLUDES:=$(GLSLANG_LOCAL_PATH)
-LOCAL_SRC_FILES:= \
-	SPIRV/GlslangToSpv.cpp \
-	SPIRV/InReadableOrder.cpp \
-	SPIRV/Logger.cpp \
-	SPIRV/SPVRemapper.cpp \
-	SPIRV/SpvBuilder.cpp \
-	SPIRV/disassemble.cpp \
-	SPIRV/doc.cpp
+# Now include the SPIRV-Tools dependency
+include $(SPVTOOLS_LOCAL_PATH)/Android.mk
 
-LOCAL_C_INCLUDES:=$(GLSLANG_LOCAL_PATH) $(GLSLANG_LOCAL_PATH)/glslang/SPIRV
-LOCAL_EXPORT_C_INCLUDES:=$(GLSLANG_LOCAL_PATH)/glslang/SPIRV
-include $(BUILD_STATIC_LIBRARY)
+ifeq ($(SHADERC_ENABLE_SPVC),1)
+  # Set the location of SPIRV-Cross.
+  # Allow the user to override it, but default it to under our third_party directory.
+  ifeq ($(SPVCROSS_LOCAL_PATH),)
+    SPVCROSS_LOCAL_PATH:=$(THIRD_PARTY_PATH)/spirv-cross
+  endif
 
-include $(CLEAR_VARS)
-LOCAL_MODULE:=OSDependent
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
-LOCAL_EXPORT_C_INCLUDES:=$(GLSLANG_LOCAL_PATH)
-LOCAL_SRC_FILES:=glslang/OSDependent/Unix/ossource.cpp
-LOCAL_C_INCLUDES:=$(GLSLANG_LOCAL_PATH) $(GLSLANG_LOCAL_PATH)/glslang/OSDependent/Unix/
-LOCAL_EXPORT_C_INCLUDES:=$(GLSLANG_LOCAL_PATH)/glslang/OSDependent/Unix/
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE:=OGLCompiler
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
-LOCAL_EXPORT_C_INCLUDES:=$(GLSLANG_LOCAL_PATH)
-LOCAL_SRC_FILES:=OGLCompilersDLL/InitializeDll.cpp
-LOCAL_C_INCLUDES:=$(GLSLANG_LOCAL_PATH)/OGLCompiler
-LOCAL_STATIC_LIBRARIES:=OSDependent
-include $(BUILD_STATIC_LIBRARY)
-
-
-# Build Glslang's HLSL parser library.
-include $(CLEAR_VARS)
-LOCAL_MODULE:=HLSL
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti
-LOCAL_SRC_FILES:= \
-		hlsl/hlslAttributes.cpp \
-		hlsl/hlslGrammar.cpp \
-		hlsl/hlslOpMap.cpp \
-		hlsl/hlslParseables.cpp \
-		hlsl/hlslParseHelper.cpp \
-		hlsl/hlslScanContext.cpp \
-		hlsl/hlslTokenStream.cpp
-LOCAL_C_INCLUDES:=$(GLSLANG_LOCAL_PATH) \
-	$(GLSLANG_LOCAL_PATH)/hlsl
-include $(BUILD_STATIC_LIBRARY)
-
-
-include $(CLEAR_VARS)
-
-GLSLANG_OUT_PATH=$(if $(call host-path-is-absolute,$(TARGET_OUT)),$(TARGET_OUT),$(abspath $(TARGET_OUT)))
-
-LOCAL_MODULE:=glslang
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
-LOCAL_EXPORT_C_INCLUDES:=$(GLSLANG_LOCAL_PATH)
-
-LOCAL_SRC_FILES:= \
-		glslang/GenericCodeGen/CodeGen.cpp \
-		glslang/GenericCodeGen/Link.cpp \
-		glslang/MachineIndependent/Constant.cpp \
-		glslang/MachineIndependent/glslang_tab.cpp \
-		glslang/MachineIndependent/InfoSink.cpp \
-		glslang/MachineIndependent/Initialize.cpp \
-		glslang/MachineIndependent/Intermediate.cpp \
-		glslang/MachineIndependent/intermOut.cpp \
-		glslang/MachineIndependent/IntermTraverse.cpp \
-		glslang/MachineIndependent/iomapper.cpp \
-		glslang/MachineIndependent/limits.cpp \
-		glslang/MachineIndependent/linkValidate.cpp \
-		glslang/MachineIndependent/parseConst.cpp \
-		glslang/MachineIndependent/ParseContextBase.cpp \
-		glslang/MachineIndependent/ParseHelper.cpp \
-		glslang/MachineIndependent/PoolAlloc.cpp \
-		glslang/MachineIndependent/propagateNoContraction.cpp \
-		glslang/MachineIndependent/reflection.cpp \
-		glslang/MachineIndependent/RemoveTree.cpp \
-		glslang/MachineIndependent/Scan.cpp \
-		glslang/MachineIndependent/ShaderLang.cpp \
-		glslang/MachineIndependent/SymbolTable.cpp \
-		glslang/MachineIndependent/Versions.cpp \
-		glslang/MachineIndependent/preprocessor/PpAtom.cpp \
-		glslang/MachineIndependent/preprocessor/PpContext.cpp \
-		glslang/MachineIndependent/preprocessor/Pp.cpp \
-		glslang/MachineIndependent/preprocessor/PpMemory.cpp \
-		glslang/MachineIndependent/preprocessor/PpScanner.cpp \
-		glslang/MachineIndependent/preprocessor/PpSymbols.cpp \
-		glslang/MachineIndependent/preprocessor/PpTokens.cpp
-
-LOCAL_C_INCLUDES:=$(GLSLANG_LOCAL_PATH) \
-	$(GLSLANG_LOCAL_PATH)/glslang/MachineIndependent \
-	$(GLSLANG_OUT_PATH)
-LOCAL_STATIC_LIBRARIES:=OSDependent OGLCompiler SPIRV HLSL
-include $(BUILD_STATIC_LIBRARY)
-
-
-SPVTOOLS_LOCAL_PATH := $(THIRD_PARTY_PATH)/spirv-tools
-LOCAL_PATH := $(SPVTOOLS_LOCAL_PATH)
-SPVTOOLS_OUT_PATH=$(if $(call host-path-is-absolute,$(TARGET_OUT)),$(TARGET_OUT),$(abspath $(TARGET_OUT)))
-SPVHEADERS_LOCAL_PATH := $(THIRD_PARTY_PATH)/spirv-tools/external/spirv-headers
-
-# Locations of grammar files.
-SPV_CORE10_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.0/spirv.core.grammar.json
-SPV_CORE11_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.1/spirv.core.grammar.json
-SPV_GLSL_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.0/extinst.glsl.std.450.grammar.json
-# OpenCL grammar has not yet been published to SPIRV-Headers
-SPV_OPENCL_GRAMMAR=$(SPVTOOLS_LOCAL_PATH)/source/extinst-1.0.opencl.std.grammar.json
-
-define gen_spvtools_grammar_tables
-$(call generate-file-dir,$(1)/core.insts-1.0.inc)
-$(1)/core.insts-1.0.inc $(1)/operand.kinds-1.0.inc $(1)/glsl.std.450.insts-1.0.inc $(1)/opencl.std.insts-1.0.inc: \
-        $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_CORE10_GRAMMAR) \
-        $(SPV_GLSL_GRAMMAR) \
-        $(SPV_OPENCL_GRAMMAR)
-		@$(HOST_PYTHON) $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_CORE10_GRAMMAR) \
-		                --extinst-glsl-grammar=$(SPV_GLSL_GRAMMAR) \
-		                --extinst-opencl-grammar=$(SPV_OPENCL_GRAMMAR) \
-		                --core-insts-output=$(1)/core.insts-1.0.inc \
-		                --glsl-insts-output=$(1)/glsl.std.450.insts-1.0.inc \
-		                --opencl-insts-output=$(1)/opencl.std.insts-1.0.inc \
-		                --operand-kinds-output=$(1)/operand.kinds-1.0.inc
-		@echo "[$(TARGET_ARCH_ABI)] Grammar v1.0   : instructions & operands <= grammar JSON files"
-$(1)/core.insts-1.1.inc $(1)/operand.kinds-1.1.inc: \
-        $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_CORE11_GRAMMAR)
-		@$(HOST_PYTHON) $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_CORE11_GRAMMAR) \
-		                --core-insts-output=$(1)/core.insts-1.1.inc \
-		                --operand-kinds-output=$(1)/operand.kinds-1.1.inc
-		@echo "[$(TARGET_ARCH_ABI)] Grammar v1.1   : instructions & operands <= grammar JSON files"
-$(SPVTOOLS_LOCAL_PATH)/source/opcode.cpp: $(1)/core.insts-1.0.inc $(1)/core.insts-1.1.inc
-$(SPVTOOLS_LOCAL_PATH)/source/operand.cpp: $(1)/operand.kinds-1.0.inc $(1)/operand.kinds-1.1.inc
-$(SPVTOOLS_LOCAL_PATH)/source/ext_inst.cpp: $(1)/glsl.std.450.insts-1.0.inc $(1)/opencl.std.insts-1.0.inc
-endef
-$(eval $(call gen_spvtools_grammar_tables,$(SPVTOOLS_OUT_PATH)))
-
-define gen_spvtools_build_version_inc
-$(call generate-file-dir,$(1)/dummy_filename)
-$(1)/build-version.inc: \
-        $(SPVTOOLS_LOCAL_PATH)/utils/update_build_version.py \
-        $(SPVTOOLS_LOCAL_PATH)/CHANGES
-		@$(HOST_PYTHON) $(SPVTOOLS_LOCAL_PATH)/utils/update_build_version.py \
-		                $(SPVTOOLS_LOCAL_PATH) $(1)/build-version.inc
-		@echo "[$(TARGET_ARCH_ABI)] Generate       : build-version.inc <= CHANGES"
-$(SPVTOOLS_LOCAL_PATH)/source/software_version.cpp: $(1)/build-version.inc
-endef
-$(eval $(call gen_spvtools_build_version_inc,$(SPVTOOLS_OUT_PATH)))
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := SPIRV-Tools
-LOCAL_C_INCLUDES := \
-		$(SPVTOOLS_LOCAL_PATH)/include \
-		$(SPVTOOLS_LOCAL_PATH)/source \
-		$(SPVTOOLS_LOCAL_PATH)/external/spirv-headers/include \
-		$(SPVTOOLS_OUT_PATH)
-LOCAL_EXPORT_C_INCLUDES := \
-		$(SPVTOOLS_LOCAL_PATH)/include
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti
-LOCAL_SRC_FILES:= \
-		source/assembly_grammar.cpp \
-		source/binary.cpp \
-		source/diagnostic.cpp \
-		source/disassemble.cpp \
-		source/ext_inst.cpp \
-		source/libspirv.cpp \
-		source/name_mapper.cpp \
-		source/opcode.cpp \
-		source/operand.cpp \
-		source/parsed_operand.cpp \
-		source/print.cpp \
-		source/software_version.cpp \
-		source/spirv_endian.cpp \
-		source/spirv_target_env.cpp \
-		source/table.cpp \
-		source/text.cpp \
-		source/text_handler.cpp \
-		source/util/parse_number.cpp \
-		source/val/basic_block.cpp \
-		source/val/construct.cpp \
-		source/val/function.cpp \
-		source/val/instruction.cpp \
-		source/val/validation_state.cpp \
-		source/validate.cpp \
-		source/validate_cfg.cpp \
-		source/validate_datarules.cpp \
-		source/validate_id.cpp \
-		source/validate_instruction.cpp \
-		source/validate_layout.cpp
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := SPIRV-Tools-opt
-LOCAL_C_INCLUDES := \
-		$(SPVTOOLS_LOCAL_PATH)/include \
-		$(SPVTOOLS_LOCAL_PATH)/source \
-		$(SPVTOOLS_LOCAL_PATH)/external/spirv-headers/include
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti
-LOCAL_STATIC_LIBRARIES:=SPIRV-Tools
-LOCAL_SRC_FILES:= \
-		source/opt/build_module.cpp \
-		source/opt/def_use_manager.cpp \
-		source/opt/eliminate_dead_constant_pass.cpp \
-		source/opt/fold_spec_constant_op_and_composite_pass.cpp \
-		source/opt/freeze_spec_constant_value_pass.cpp \
-		source/opt/function.cpp \
-		source/opt/instruction.cpp \
-		source/opt/ir_loader.cpp \
-		source/opt/module.cpp \
-		source/opt/optimizer.cpp \
-		source/opt/pass_manager.cpp \
-		source/opt/set_spec_constant_default_value_pass.cpp \
-		source/opt/strip_debug_info_pass.cpp \
-		source/opt/type_manager.cpp \
-		source/opt/types.cpp \
-		source/opt/unify_const_pass.cpp
-include $(BUILD_STATIC_LIBRARY)
+  # Now include the SPIRV-Cross dependency
+  include $(SPVCROSS_LOCAL_PATH)/jni/Android.mk
+endif
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index 0b50b96..7bd9617 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -7,8 +7,20 @@
   "Location of googletest source")
 set(SHADERC_SPIRV_TOOLS_DIR "${SHADERC_THIRD_PARTY_ROOT_DIR}/spirv-tools" CACHE STRING
   "Location of spirv-tools source")
+set(SHADERC_SPIRV_HEADERS_DIR "${SHADERC_THIRD_PARTY_ROOT_DIR}/spirv-headers" CACHE STRING
+  "Location of spirv-headers source")
 set(SHADERC_GLSLANG_DIR "${SHADERC_THIRD_PARTY_ROOT_DIR}/glslang" CACHE STRING
   "Location of glslang source")
+set(SHADERC_EFFCEE_DIR "${SHADERC_THIRD_PARTY_ROOT_DIR}/effcee" CACHE STRING
+  "Location of effcee source")
+set(SHADERC_RE2_DIR "${SHADERC_THIRD_PARTY_ROOT_DIR}/re2" CACHE STRING
+  "Location of re2 source")
+set(SHADERC_TINT_DIR "${SHADERC_THIRD_PARTY_ROOT_DIR}/tint" CACHE STRING
+  "Location of tint source")
+
+set( SKIP_GLSLANG_INSTALL ${SHADERC_SKIP_INSTALL} )
+set( SKIP_SPIRV_TOOLS_INSTALL ${SHADERC_SKIP_INSTALL} )
+set( SKIP_GOOGLETEST_INSTALL ${SHADERC_SKIP_INSTALL} )
 
 # Configure third party projects.
 if(${SHADERC_ENABLE_TESTS})
@@ -21,65 +33,68 @@
 endif()
 
 set(OLD_PLATFORM_TOOLSET ${CMAKE_GENERATOR_TOOLSET})
+check_cxx_compiler_flag(-fPIC COMPILER_SUPPORTS_PIC)
 
-if (IS_DIRECTORY ${SHADERC_GLSLANG_DIR})
-  add_subdirectory(${SHADERC_GLSLANG_DIR} glslang)
-endif()
-if (NOT TARGET glslang)
-  message(FATAL_ERROR "glslang was not found - required for compilation")
-endif()
-if(WIN32)
-    # This is unfortunate but glslang forces our
-    # platform toolset to be v110, which we may not even have
-    # installed, undo anything glslang has done to it.
-    set(CMAKE_GENERATOR_TOOLSET "${OLD_PLATFORM_TOOLSET}" CACHE STRING
-      "Platform Toolset" FORCE)
+
+if (IS_DIRECTORY ${SHADERC_SPIRV_HEADERS_DIR})
+  set(SPIRV_HEADERS_SKIP_EXAMPLES ON)
+  add_subdirectory(${SHADERC_SPIRV_HEADERS_DIR} spirv-headers)
 endif()
 
-if (IS_DIRECTORY ${SHADERC_SPIRV_TOOLS_DIR})
-  if ("${SHADERC_SKIP_TESTS}")
-    # Also skip building tests in SPIRV-Tools.
-    set(SPIRV_SKIP_TESTS ON CACHE BOOL "Skip building SPIRV-Tools tests")
-  endif()
-  add_subdirectory(${SHADERC_SPIRV_TOOLS_DIR} spirv-tools)
-endif()
 if (NOT TARGET SPIRV-Tools)
-  message(FATAL_ERROR "SPIRV-Tools was not found - required for compilation")
-endif()
-
-if(${SHADERC_ENABLE_TESTS})
-  # Configure out-of-source-directory tests for glslang.
-  # The glslang project uses a bash script called "runtests" to run tests.
-  # The runtests script assumes the glslangValidator executable exists in
-  # a location inside the source tree, but we build it elsewhere.
-  # We need to copy the test files, fix the path references, and then run tests.
-  set(GLSLANG_TEST_SRC_DIR ${SHADERC_GLSLANG_DIR}/Test)
-  set(GLSLANG_TEST_BIN_DIR
-        ${CMAKE_CURRENT_BINARY_DIR}/test-glslang/${CMAKE_CFG_INTDIR})
-
-  # If we are building in a multi-configuration setting we have
-  # to put the glslang tests into their respective subdirectories.
-  if (CMAKE_CONFIGURATION_TYPES)
-    set(GLSLANG_CONFIGURATION_DIR ${CMAKE_CFG_INTDIR})
+  # Check SPIRV-Tools before glslang so that it is linked into glslang.
+  # we control optimizations via glslang API calls directly.
+  if (IS_DIRECTORY ${SHADERC_SPIRV_TOOLS_DIR})
+    if ("${SHADERC_SKIP_TESTS}")
+      # Also skip building tests in SPIRV-Tools.
+      set(SPIRV_SKIP_TESTS ON CACHE BOOL "Skip building SPIRV-Tools tests")
+    elseif(NOT "${SPIRV_SKIP_TESTS}")
+      # SPIRV-Tools requires effcee and re2 to build tests.
+      # re2 tests take a long time and do not add much value, since re2 is a
+      # dependency of a dependency, so not running them.
+      set(RE2_BUILD_TESTING OFF CACHE STRING "Run RE2 Tests")
+      add_subdirectory(${SHADERC_RE2_DIR} re2)
+      add_subdirectory(${SHADERC_EFFCEE_DIR} effcee)
+    endif()
+    add_subdirectory(${SHADERC_SPIRV_TOOLS_DIR} spirv-tools)
   endif()
-
-  add_custom_target(copy-tests-if-necessary ALL
-    COMMAND ${PYTHON_EXE}
-      ${shaderc_SOURCE_DIR}/utils/copy-tests-if-necessary.py
-      ${GLSLANG_TEST_SRC_DIR} ${GLSLANG_TEST_BIN_DIR} ${GLSLANG_CONFIGURATION_DIR}
-    COMMENT "Copying and patching glslang tests if needed")
-
-  if (CMAKE_CONFIGURATION_TYPES)
-    # If we are running a multi-configuration project,
-    # the tests will be in test-glslang/${Configuration}
-    add_test(NAME glslang-testsuite
-      COMMAND bash runtests
-      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test-glslang/$<CONFIGURATION>
-    )
-  else()
-    add_test(NAME glslang-testsuite
-      COMMAND bash runtests
-      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test-glslang/
-    )
+  if (NOT TARGET SPIRV-Tools)
+    message(FATAL_ERROR "SPIRV-Tools was not found - required for compilation")
   endif()
 endif()
+
+if (NOT TARGET glslang)
+  if (IS_DIRECTORY ${SHADERC_GLSLANG_DIR})
+    add_subdirectory(${SHADERC_GLSLANG_DIR} glslang)
+  endif()
+  if (NOT TARGET glslang)
+    message(FATAL_ERROR "glslang was not found - required for compilation")
+  endif()
+  if(WIN32)
+      # This is unfortunate but glslang forces our
+      # platform toolset to be v110, which we may not even have
+      # installed, undo anything glslang has done to it.
+      set(CMAKE_GENERATOR_TOOLSET "${OLD_PLATFORM_TOOLSET}" CACHE STRING
+        "Platform Toolset" FORCE)
+  endif()
+endif()
+
+if (SHADERC_ENABLE_WGSL_OUTPUT)
+  # Use Google Tint for WGSL output.
+  if (NOT TARGET libtint)
+    if (IS_DIRECTORY ${SHADERC_TINT_DIR})
+      if (NOT IS_DIRECTORY ${SHADERC_TINT_DIR}/out/docs)
+        # The Tint Doxygen configuration assumes it can write to the out/docs
+        # source directory.
+        message(STATUS "Tint source directory out/docs does not exist. Disabling doc generation")
+        set(TINT_BUILD_DOCS OFF)
+      endif()
+      set(TINT_BUILD_SPV_READER ON CACHE BOOL "Built Tint SPIR-V reader" FORCE)
+      set(TINT_BUILD_WGSL_WRITER ON CACHE BOOL "Build Tint WGSL writer" FORCE)
+      add_subdirectory(${SHADERC_TINT_DIR} tint)
+    endif()
+  endif()
+  if (NOT TARGET libtint)
+    message(FATAL_ERROR "Tint was not found - required for WGSL output")
+  endif()
+endif (SHADERC_ENABLE_WGSL_OUTPUT)
diff --git a/utils/add_copyright.py b/utils/add_copyright.py
index 2d3f734..37505bc 100755
--- a/utils/add_copyright.py
+++ b/utils/add_copyright.py
@@ -12,8 +12,8 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-"""Adds copyright notices to all the files that need them under the
-current directory.
+"""Adds copyright notices to all the files that need them under the current
+directory.
 
 usage: add_copyright.py [--check]
 
@@ -21,8 +21,6 @@
 with status 1 if any such files are found, 0 if none.
 """
 
-from __future__ import print_function
-
 import fileinput
 import fnmatch
 import os
@@ -63,7 +61,8 @@
 def filtered_descendants(glob):
     """Returns glob-matching filenames under the current directory, but skips
     some irrelevant paths."""
-    return find('.', glob, ['third_party', 'ext', 'build*', 'out*'])
+    return find('.', glob, ['third_party', 'external', 'build*', 'out*',
+                            'CompilerIdCXX', '.venv'])
 
 
 def skip(line):
@@ -75,8 +74,8 @@
 def comment(text, prefix):
     """Returns commented-out text.
 
-    Each line of text will be prefixed by prefix and a space character.  Any
-    trailing whitespace will be trimmed.
+    Each line of text will be prefixed by prefix and a space character.
+    Any trailing whitespace will be trimmed.
     """
     accum = []
     for line in text.split('\n'):
@@ -85,11 +84,12 @@
 
 
 def insert_copyright(glob, comment_prefix):
-    """Finds all glob-matching files under the current directory and inserts the
-    copyright message into them unless they already have it or are empty.
+    """Finds all glob-matching files under the current directory and inserts
+    the copyright message into them unless they already have it or are empty.
 
-    The copyright message goes into the first non-whitespace, non-shebang line
-    in a file.  It is prefixed on each line by comment_prefix and a space.
+    The copyright message goes into the first non-whitespace, non-
+    shebang line in a file.  It is prefixed on each line by
+    comment_prefix and a space.
     """
     copyright = comment(COPYRIGHT, comment_prefix) + '\n'
     licensed = comment(LICENSED, comment_prefix) + '\n\n'
diff --git a/utils/build.py b/utils/build.py
deleted file mode 100755
index 733e958..0000000
--- a/utils/build.py
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright 2016 The Shaderc Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Builds the Shaderc project, on Linux, Mac, or Windows.
-"""
-
-from __future__ import print_function
-import argparse
-import os
-import platform
-import subprocess
-import sys
-
-
-OS = platform.system()
-
-
-def run(cmd, cwd, env, justprint):
-    """Prints a command to run, and optionally runs it.
-
-    Raises a RuntimeError if the command does not launch or otherwise fails.
-
-    Args:
-      justprint: If true, then only print the command. Otherwise run the
-                   command after printing it.
-      cmd:       List of words in the command.
-      cwd:       Working directory for the command.
-      env:       Environment to pass to subprocess.
-    """
-    print(cmd)
-    if justprint:
-        return
-
-    p = subprocess.Popen(cmd, cwd=cwd, env=env)
-    (_, _) = p.communicate()
-    if p.returncode != 0:
-        raise RuntimeError('Failed to run %s in %s' % (cmd, cwd))
-
-
-def build(args):
-    """ Builds Shaderc under specified conditions.
-
-    Args:
-        args: An object with attributes:
-            srcdir: where Shaderc source can be found
-            builddir: build working directory
-            installdir: install directory
-    """
-
-    if not os.path.isdir(args.srcdir):
-        raise RuntimeError('Soure directory %s does not exist' % (args.srcdir))
-
-    # Make paths absolute, and ensure directories exist.
-    for d in [args.builddir, args.installdir]:
-        if not os.path.isdir(d):
-            os.makedirs(d)
-    args.srcdir = os.path.abspath(args.srcdir)
-    args.builddir = os.path.abspath(args.builddir)
-    args.installdir = os.path.abspath(args.installdir)
-
-    print('Building Shaderc:')
-    print('   Source     : ', args.srcdir)
-    print('   Build dir  : ', args.builddir)
-    print('   Install dir: ', args.installdir)
-    cmake_command = ['cmake', args.srcdir, '-GNinja',
-                     '-DCMAKE_BUILD_TYPE=%s' % args.buildtype,
-                     '-DCMAKE_INSTALL_PREFIX=%s' % args.installdir]
-
-    env = None
-    if OS == 'Windows':
-        p = subprocess.Popen(
-            '"%VS140COMNTOOLS%..\\..\\VC\\vcvarsall.bat" & set',
-            stdout=subprocess.PIPE, cwd=args.builddir, shell=True)
-        env = dict([tuple(line.split('=', 1))
-                    for line in p.communicate()[0].splitlines()])
-    run(cmake_command, args.builddir, env, args.dry_run)
-    run(['ninja', 'install'], args.builddir, env, args.dry_run)
-    run(['ctest', '--output-on-failure'], args.builddir, env, args.dry_run)
-
-
-def cygpath(f):
-    p = subprocess.Popen(['cygpath', '-w', f], stdout=subprocess.PIPE)
-    return p.communicate()[0].rstrip()
-
-def main():
-    """Builds Shaderc after parsing argument specifying locations of
-    files, level of parallelism, and whether it's a dry run that should
-    skip actual compilation and installation."""
-
-    parser = argparse.ArgumentParser(description='Build Shaderc simply')
-    parser.add_argument('-n', '--dry_run', dest='dry_run', default=False,
-                        action='store_true',
-                        help='Dry run: Make dirs and only print commands '
-                        'to be run')
-    parser.add_argument('--srcdir', dest='srcdir', default='src/shaderc',
-                        help='Shaderc source directory. Default "src/shaderc".')
-    parser.add_argument('--builddir', dest='builddir', default='out',
-                        help='Build directory. Default is "out".')
-    parser.add_argument('--installdir', dest='installdir', required=True,
-                        help='Installation directory. Required.')
-    parser.add_argument('--type', dest='buildtype', default='RelWithDebInfo',
-                        help='Build type. Default is RelWithDebInfo')
-
-    arch = None
-    if (OS == 'Windows' or OS.startswith('CYGWIN')):
-        arch = 'windows-x86'
-    if OS == 'Linux':
-        arch = 'linux-x86'
-    if OS == 'Darwin':
-        arch = 'darwin-x86'
-    if arch is None:
-        raise RuntimeError('Unknown OS: %s' % OS)
-
-    path_default = os.pathsep.join([
-        os.path.join(os.getcwd(), 'prebuilts', 'cmake', arch, 'bin'),
-        os.path.join(os.getcwd(), 'prebuilts', 'ninja', arch),
-        os.path.join(os.getcwd(), 'prebuilts', 'python', arch, 'x64')])
-
-    parser.add_argument('--path', dest='path',
-                        default=path_default,
-                        help='Extra directories to prepend to the system path, '
-                        'separated by your system\'s path delimiter (typically '
-                        '":" or ";"). After prepending, path must contain '
-                        'cmake, ninja, and python. On Cygwin, the native '
-                        'Windows Python must come first. Default is %s.'
-                        % path_default)
-
-    args = parser.parse_args()
-
-    if args.path:
-        os.environ['PATH'] = os.pathsep.join([args.path, os.getenv('PATH')])
-
-    if OS.startswith('CYGWIN'):
-        # Escape to Windows.
-        winargv = []
-        args_dict = vars(args)
-        for k in args_dict:
-            if k=='path' or k.endswith('dir'):
-                winargv.extend(['--%s' % k, cygpath(args_dict[k])])
-            elif k=='buildtype':
-                winargv.extend(['--type', args.buildtype])
-            elif k=='dry_run':
-                if args.dry_run:
-                    winargv.append('-n')
-            else:
-                winargv.extend(['--%s' % k, args_dict[k]])
-        os.execlp('python', 'python', sys.argv[0], *winargv)
-
-    build(args)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/utils/copy-tests-if-necessary.py b/utils/copy-tests-if-necessary.py
deleted file mode 100755
index f47e816..0000000
--- a/utils/copy-tests-if-necessary.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Shaderc Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Copies tests from the source directory to the binary directory if something
-in the source directory has changed. It also updates the path in runtests
-to point to the correct binary directory.
-
-Arguments: glslang_test_source_dir glslang_test_bin_dir [intermediate-dir]
-
-intermediate-dir is optional, it specifies that there the additional directory
-between the root, and the tests/binary.
-"""
-
-import errno
-import os
-import shutil
-import sys
-
-
-def get_modified_times(path):
-    """Returns a string containing a newline-separated set of
-    filename:last_modified_time pairs for all files rooted at path.
-    """
-    output = []
-    for root, _, filenames in os.walk(path):
-        for filename in filenames:
-            fullpath = os.path.join(root, filename)
-            output.append(
-                filename + ":" +
-                str(os.path.getmtime(fullpath)) + "\n")
-    return "".join(sorted(output))
-
-
-def read_file(path):
-    """Reads a file and returns the data as a string."""
-    output = ""
-    try:
-        # If we could not open then we simply return "" as the output
-        with open(path, "r") as content:
-            output = content.read()
-    except:
-        pass
-    return output
-
-
-def write_file(path, output):
-    """Writes an output string to the file located at path."""
-    with open(path, "w") as content:
-        content.write(output)
-
-
-def substitute_file(path, substitution):
-    """Substitutes all instances of substitution[0] with substitution[1] for the
-    file located at path."""
-    with open(path, "r") as content:
-        f_input = content.read()
-    if f_input:
-        f_input = f_input.replace(substitution[0], substitution[1])
-    with open(path, "w") as content:
-        content.write(f_input)
-
-
-def substitute_files(path, substitution):
-    """Runs substitute_file() on all files rooted at path."""
-    for root, _, filenames in os.walk(path):
-        for filename in filenames:
-            substitute_file(os.path.join(root, filename), substitution)
-
-
-def setup_directory(source, dest):
-    """Removes the destination directory if it exists and copies the source
-    directory over the destination if it exists.
-    """
-    try:
-        shutil.rmtree(dest)
-    except OSError as e:
-        # shutil will throw if it could not find the directory.
-        if e.errno == errno.ENOENT:
-            pass
-        else:
-            raise
-    shutil.copytree(source, dest)
-
-
-def main():
-    glsl_src_dir = os.path.normpath(sys.argv[1])
-    glsl_bin_dir = os.path.normpath(sys.argv[2])
-    intermediate_directory = None
-    if (len(sys.argv) > 3):
-        intermediate_directory = sys.argv[3]
-    glsl_list_file = os.path.join(glsl_bin_dir, "glsl_test_list")
-
-    src_glsl_stamp = get_modified_times(glsl_src_dir)
-    old_glsl_stamp = read_file(glsl_list_file)
-
-    target_location = "../glslang/StandAlone/"
-    if intermediate_directory:
-        target_location = "../" + target_location + intermediate_directory + "/"
-    target_location = "EXE=" + target_location
-    if src_glsl_stamp != old_glsl_stamp:
-        setup_directory(glsl_src_dir, glsl_bin_dir)
-        substitute_file(os.path.join(glsl_bin_dir, "runtests"),
-                        ("EXE=../build/install/bin/", target_location))
-        write_file(glsl_list_file, src_glsl_stamp)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/utils/git-sync-deps b/utils/git-sync-deps
new file mode 100755
index 0000000..eecfbe9
--- /dev/null
+++ b/utils/git-sync-deps
@@ -0,0 +1,282 @@
+#!/usr/bin/env python3
+# Copyright 2014 Google Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#    * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#    * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Parse a DEPS file and git checkout all of the dependencies.
+
+Args:
+  An optional list of deps_os values.
+
+Environment Variables:
+  GIT_EXECUTABLE: path to "git" binary; if unset, will look for one of
+  ['git', 'git.exe', 'git.bat'] in your default path.
+
+  GIT_SYNC_DEPS_PATH: file to get the dependency list from; if unset,
+  will use the file ../DEPS relative to this script's directory.
+
+  GIT_SYNC_DEPS_QUIET: if set to non-empty string, suppress messages.
+
+Git Config:
+  To disable syncing of a single repository:
+      cd path/to/repository
+      git config sync-deps.disable true
+
+  To re-enable sync:
+      cd path/to/repository
+      git config --unset sync-deps.disable
+"""
+
+
+import os
+import re
+import subprocess
+import sys
+import threading
+from builtins import bytes
+
+
+def git_executable():
+  """Find the git executable.
+
+  Returns:
+      A string suitable for passing to subprocess functions, or None.
+  """
+  envgit = os.environ.get('GIT_EXECUTABLE')
+  searchlist = ['git', 'git.exe', 'git.bat']
+  if envgit:
+    searchlist.insert(0, envgit)
+  with open(os.devnull, 'w') as devnull:
+    for git in searchlist:
+      try:
+        subprocess.call([git, '--version'], stdout=devnull)
+      except (OSError,):
+        continue
+      return git
+  return None
+
+
+DEFAULT_DEPS_PATH = os.path.normpath(
+  os.path.join(os.path.dirname(__file__), os.pardir, 'DEPS'))
+
+
+def usage(deps_file_path = None):
+  sys.stderr.write(
+    'Usage: run to grab dependencies, with optional platform support:\n')
+  sys.stderr.write('  %s %s' % (sys.executable, __file__))
+  if deps_file_path:
+    parsed_deps = parse_file_to_dict(deps_file_path)
+    if 'deps_os' in parsed_deps:
+      for deps_os in parsed_deps['deps_os']:
+        sys.stderr.write(' [%s]' % deps_os)
+  sys.stderr.write('\n\n')
+  sys.stderr.write(__doc__)
+
+
+def git_repository_sync_is_disabled(git, directory):
+  try:
+    disable = subprocess.check_output(
+      [git, 'config', 'sync-deps.disable'], cwd=directory)
+    return disable.lower().strip() in ['true', '1', 'yes', 'on']
+  except subprocess.CalledProcessError:
+    return False
+
+
+def is_git_toplevel(git, directory):
+  """Return true iff the directory is the top level of a Git repository.
+
+  Args:
+    git (string) the git executable
+
+    directory (string) the path into which the repository
+              is expected to be checked out.
+  """
+  try:
+    toplevel = subprocess.check_output(
+      [git, 'rev-parse', '--show-toplevel'], cwd=directory).strip()
+    return os.path.realpath(bytes(directory, 'utf8')) == os.path.realpath(toplevel)
+  except subprocess.CalledProcessError:
+    return False
+
+
+def status(directory, checkoutable):
+  def truncate(s, length):
+    return s if len(s) <= length else s[:(length - 3)] + '...'
+  dlen = 36
+  directory = truncate(directory, dlen)
+  checkoutable = truncate(checkoutable, 40)
+  sys.stdout.write('%-*s @ %s\n' % (dlen, directory, checkoutable))
+
+
+def git_checkout_to_directory(git, repo, checkoutable, directory, verbose):
+  """Checkout (and clone if needed) a Git repository.
+
+  Args:
+    git (string) the git executable
+
+    repo (string) the location of the repository, suitable
+         for passing to `git clone`.
+
+    checkoutable (string) a tag, branch, or commit, suitable for
+                 passing to `git checkout`
+
+    directory (string) the path into which the repository
+              should be checked out.
+
+    verbose (boolean)
+
+  Raises an exception if any calls to git fail.
+  """
+  if not os.path.isdir(directory):
+    subprocess.check_call(
+      [git, 'clone', '--quiet', repo, directory])
+
+  if not is_git_toplevel(git, directory):
+    # if the directory exists, but isn't a git repo, you will modify
+    # the parent repostory, which isn't what you want.
+    sys.stdout.write('%s\n  IS NOT TOP-LEVEL GIT DIRECTORY.\n' % directory)
+    return
+
+  # Check to see if this repo is disabled.  Quick return.
+  if git_repository_sync_is_disabled(git, directory):
+    sys.stdout.write('%s\n  SYNC IS DISABLED.\n' % directory)
+    return
+
+  with open(os.devnull, 'w') as devnull:
+    # If this fails, we will fetch before trying again.  Don't spam user
+    # with error infomation.
+    if 0 == subprocess.call([git, 'checkout', '--quiet', checkoutable],
+                            cwd=directory, stderr=devnull):
+      # if this succeeds, skip slow `git fetch`.
+      if verbose:
+        status(directory, checkoutable)  # Success.
+      return
+
+  # If the repo has changed, always force use of the correct repo.
+  # If origin already points to repo, this is a quick no-op.
+  subprocess.check_call(
+      [git, 'remote', 'set-url', 'origin', repo], cwd=directory)
+
+  subprocess.check_call([git, 'fetch', '--quiet'], cwd=directory)
+
+  subprocess.check_call([git, 'checkout', '--quiet', checkoutable], cwd=directory)
+
+  if verbose:
+    status(directory, checkoutable)  # Success.
+
+
+def parse_file_to_dict(path):
+  dictionary = {}
+  contents = open(path).read()
+  # Need to convert Var() to vars[], so that the DEPS is actually Python. Var()
+  # comes from Autoroller using gclient which has a slightly different DEPS
+  # format.
+  contents = re.sub(r"Var\((.*?)\)", r"vars[\1]", contents)
+  exec(contents, dictionary)
+  return dictionary
+
+
+def git_sync_deps(deps_file_path, command_line_os_requests, verbose):
+  """Grab dependencies, with optional platform support.
+
+  Args:
+    deps_file_path (string) Path to the DEPS file.
+
+    command_line_os_requests (list of strings) Can be empty list.
+        List of strings that should each be a key in the deps_os
+        dictionary in the DEPS file.
+
+  Raises git Exceptions.
+  """
+  git = git_executable()
+  assert git
+
+  deps_file_directory = os.path.dirname(deps_file_path)
+  deps_file = parse_file_to_dict(deps_file_path)
+  dependencies = deps_file['deps'].copy()
+  os_specific_dependencies = deps_file.get('deps_os', dict())
+  if 'all' in command_line_os_requests:
+    for value in list(os_specific_dependencies.values()):
+      dependencies.update(value)
+  else:
+    for os_name in command_line_os_requests:
+      # Add OS-specific dependencies
+      if os_name in os_specific_dependencies:
+        dependencies.update(os_specific_dependencies[os_name])
+  for directory in dependencies:
+    for other_dir in dependencies:
+      if directory.startswith(other_dir + '/'):
+        raise Exception('%r is parent of %r' % (other_dir, directory))
+  list_of_arg_lists = []
+  for directory in sorted(dependencies):
+    if '@' in dependencies[directory]:
+      repo, checkoutable = dependencies[directory].split('@', 1)
+    else:
+      raise Exception("please specify commit or tag")
+
+    relative_directory = os.path.join(deps_file_directory, directory)
+
+    list_of_arg_lists.append(
+      (git, repo, checkoutable, relative_directory, verbose))
+
+  multithread(git_checkout_to_directory, list_of_arg_lists)
+
+  for directory in deps_file.get('recursedeps', []):
+    recursive_path = os.path.join(deps_file_directory, directory, 'DEPS')
+    git_sync_deps(recursive_path, command_line_os_requests, verbose)
+
+
+def multithread(function, list_of_arg_lists):
+  # for args in list_of_arg_lists:
+  #   function(*args)
+  # return
+  threads = []
+  for args in list_of_arg_lists:
+    thread = threading.Thread(None, function, None, args)
+    thread.start()
+    threads.append(thread)
+  for thread in threads:
+    thread.join()
+
+
+def main(argv):
+  deps_file_path = os.environ.get('GIT_SYNC_DEPS_PATH', DEFAULT_DEPS_PATH)
+  verbose = not bool(os.environ.get('GIT_SYNC_DEPS_QUIET', False))
+
+  if '--help' in argv or '-h' in argv:
+    usage(deps_file_path)
+    return 1
+
+  git_sync_deps(deps_file_path, argv, verbose)
+  # subprocess.check_call(
+  #     [sys.executable,
+  #      os.path.join(os.path.dirname(deps_file_path), 'bin', 'fetch-gn')])
+  return 0
+
+
+if __name__ == '__main__':
+  exit(main(sys.argv[1:]))
diff --git a/utils/roll-deps b/utils/roll-deps
new file mode 100755
index 0000000..4962fd6
--- /dev/null
+++ b/utils/roll-deps
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+
+# Copyright 2019 The Shaderc Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Attempts to roll all entries in DEPS to tip-of-tree and create a commit.
+#
+# Depends on roll-dep from depot_path being in PATH.
+
+effcee_dir="third_party/effcee/"
+effcee_trunk="origin/main"
+glslang_dir="third_party/glslang/"
+glslang_trunk="origin/master"
+googletest_dir="third_party/googletest/"
+googletest_trunk="origin/master"
+re2_dir="third_party/re2/"
+re2_trunk="origin/master"
+spirv_headers_dir="third_party/spirv-headers/"
+spirv_headers_trunk="origin/master"
+spirv_tools_dir="third_party/spirv-tools/"
+spirv_tools_trunk="origin/master"
+
+# This script assumes it's parent directory is the repo root.
+repo_path=$(dirname "$0")/..
+
+cd "$repo_path"
+
+if [[ $(git diff --stat) != '' ]]; then
+    echo "Working tree is dirty, commit changes before attempting to roll DEPS"
+    exit 1
+fi
+
+old_head=$(git rev-parse HEAD)
+
+roll-dep --ignore-dirty-tree --roll-to="${effcee_trunk}" "${effcee_dir}"
+roll-dep --ignore-dirty-tree --roll-to="${glslang_trunk}" "${glslang_dir}"
+roll-dep --ignore-dirty-tree --roll-to="${googletest_trunk}" "${googletest_dir}"
+roll-dep --ignore-dirty-tree --roll-to="${re2_trunk}" "${re2_dir}"
+roll-dep --ignore-dirty-tree --roll-to="${spirv_headers_trunk}" "${spirv_headers_dir}"
+roll-dep --ignore-dirty-tree --roll-to="${spirv_tools_trunk}" "${spirv_tools_dir}"
+
+git rebase --interactive "${old_head}"
diff --git a/utils/update_build_version.py b/utils/update_build_version.py
index b1a4b0b..5785390 100755
--- a/utils/update_build_version.py
+++ b/utils/update_build_version.py
@@ -23,16 +23,29 @@
 # directory's "git describe" output enclosed in double quotes and appropriately
 # escaped.
 
-from __future__ import print_function
-
 import datetime
+import errno
 import os.path
 import re
 import subprocess
 import sys
+import time
 
-OUTFILE = 'build-version.inc'
+def mkdir_p(directory):
+    """Make the directory, and all its ancestors as required.  Any of the
+    directories are allowed to already exist."""
 
+    if directory == "":
+        # We're being asked to make the current directory.
+        return
+
+    try:
+        os.makedirs(directory)
+    except OSError as e:
+        if e.errno == errno.EEXIST and os.path.isdir(directory):
+            pass
+        else:
+            raise
 
 def command_output(cmd, directory):
     """Runs a command in a directory and returns its standard output stream.
@@ -52,15 +65,19 @@
 
 
 def deduce_software_version(directory):
-    """Returns a software version number parsed from the CHANGES file
-    in the given directory.
+    """Returns a software version number parsed from the CHANGES file in the
+    given directory.
 
     The CHANGES file describes most recent versions first.
     """
 
-    pattern = re.compile(r'(v\d+\.\d+(-dev)?) \d\d\d\d-\d\d-\d\d$')
+    # Match the first well-formed version-and-date line.
+    # Allow trailing whitespace in the checked-out source code has
+    # unexpected carriage returns on a linefeed-only system such as
+    # Linux.
+    pattern = re.compile(r'^(v\d+\.\d+(-dev)?) \d\d\d\d-\d\d-\d\d\s*$')
     changes_file = os.path.join(directory, 'CHANGES')
-    with open(changes_file) as f:
+    with open(changes_file, errors='replace') as f:
         for line in f.readlines():
             match = pattern.match(line)
             if match:
@@ -69,11 +86,13 @@
 
 
 def describe(directory):
-    """Returns a string describing the current Git HEAD version as descriptively
-    as possible.
+    """Returns a string describing the current Git HEAD version as
+    descriptively as possible.
 
-    Runs 'git describe', or alternately 'git rev-parse HEAD', in directory.  If
-    successful, returns the output; otherwise returns 'unknown hash, <date>'."""
+    Runs 'git describe', or alternately 'git rev-parse HEAD', in
+    directory.  If successful, returns the output; otherwise returns
+    'unknown hash, <date>'.
+    """
     try:
         # decode() is needed here for Python3 compatibility. In Python2,
         # str and bytes are the same type, but not in Python3.
@@ -86,12 +105,21 @@
             return command_output(
                 ['git', 'rev-parse', 'HEAD'], directory).rstrip().decode()
         except:
-            return 'unknown hash, ' + datetime.date.today().isoformat()
+            # This is the fallback case where git gives us no information,
+            # e.g. because the source tree might not be in a git tree.
+            # In this case, usually use a timestamp.  However, to ensure
+            # reproducible builds, allow the builder to override the wall
+            # clock time with enviornment variable SOURCE_DATE_EPOCH
+            # containing a (presumably) fixed timestamp.
+            timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
+            formatted = datetime.date.fromtimestamp(timestamp).isoformat()
+            return 'unknown hash, {}'.format(formatted)
 
 
 def get_version_string(project, directory):
-    """Returns a detailed version string for a given project with its directory,
-    which consists of software version string and git description string."""
+    """Returns a detailed version string for a given project with its
+    directory, which consists of software version string and git description
+    string."""
     detailed_version_string_lst = [project]
     if project != 'glslang':
         detailed_version_string_lst.append(deduce_software_version(directory))
@@ -100,9 +128,9 @@
 
 
 def main():
-    if len(sys.argv) != 4:
-        print('usage: {} <shaderc-dir> <spirv-tools-dir> <glslang-dir>'.format(
-            sys.argv[0]))
+    if len(sys.argv) != 5:
+        print(('usage: {} <shaderc-dir> <spirv-tools-dir> <glslang-dir> <output-file>'.format(
+            sys.argv[0])))
         sys.exit(1)
 
     projects = ['shaderc', 'spirv-tools', 'glslang']
@@ -111,11 +139,14 @@
         for (p, d) in zip(projects, sys.argv[1:])
     ])
 
-    if os.path.isfile(OUTFILE):
-        with open(OUTFILE, 'r') as f:
+    output_file = sys.argv[4]
+    mkdir_p(os.path.dirname(output_file))
+
+    if os.path.isfile(output_file):
+        with open(output_file, 'r') as f:
             if new_content == f.read():
                 return
-    with open(OUTFILE, 'w') as f:
+    with open(output_file, 'w') as f:
         f.write(new_content)