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

Change-Id: Ieb3a49115d3b741eb664e491cddb452e3e411dcd
diff --git a/.appveyor.yml b/.appveyor.yml
index ebf7bc5..2b903bb 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -4,6 +4,11 @@
 # version format
 version: "{build}"
 
+image:
+  - Visual Studio 2013
+  - Visual Studio 2015
+  - Visual Studio 2017
+
 platform:
   - x64
 
diff --git a/CHANGES b/CHANGES
index 616571d..a5bf028 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,7 @@
 Revision history for Shaderc
 
 v2017.2-dev 2017-03-10
+ - Support GLSL 4.6 and ESSL 3.2
  - Add options for automatically set bindings for (uniform) resources that
    don't have bindings set in shader source.
  - Add option for using HLSL IO mappings as expressed in source.
diff --git a/cmake/utils.cmake b/cmake/utils.cmake
index d095486..95b4993 100644
--- a/cmake/utils.cmake
+++ b/cmake/utils.cmake
@@ -59,7 +59,10 @@
         ${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()
 
diff --git a/glslc/test/assembly.py b/glslc/test/assembly.py
index a537044..aad9e6d 100644
--- a/glslc/test/assembly.py
+++ b/glslc/test/assembly.py
@@ -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, unexpected SEMICOLON\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/option_std.py b/glslc/test/option_std.py
index 52609af..ff65a4b 100644
--- a/glslc/test/option_std.py
+++ b/glslc/test/option_std.py
@@ -77,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."""
 
diff --git a/libshaderc_util/CMakeLists.txt b/libshaderc_util/CMakeLists.txt
index e636452..873540a 100644
--- a/libshaderc_util/CMakeLists.txt
+++ b/libshaderc_util/CMakeLists.txt
@@ -47,11 +47,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/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/version_profile_test.cc b/libshaderc_util/src/version_profile_test.cc
new file mode 100644
index 0000000..1cbedfd
--- /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_CASE_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_CASE_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_CASE_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_CASE_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/third_party/Android.mk b/third_party/Android.mk
index 6b9e451..582955f 100644
--- a/third_party/Android.mk
+++ b/third_party/Android.mk
@@ -118,6 +118,7 @@
 		source/ext_inst.cpp \
 		source/enum_string_mapping.cpp \
 		source/extensions.cpp \
+		source/id_descriptor.cpp \
 		source/libspirv.cpp \
 		source/name_mapper.cpp \
 		source/opcode.cpp \
@@ -155,6 +156,7 @@
 		source/opt/block_merge_pass.cpp \
 		source/opt/build_module.cpp \
 		source/opt/compact_ids_pass.cpp \
+		source/opt/common_uniform_elim_pass.cpp \
 		source/opt/dead_branch_elim_pass.cpp \
 		source/opt/def_use_manager.cpp \
 		source/opt/eliminate_dead_constant_pass.cpp \
@@ -163,6 +165,8 @@
 		source/opt/freeze_spec_constant_value_pass.cpp \
 		source/opt/function.cpp \
 		source/opt/inline_pass.cpp \
+		source/opt/inline_exhaustive_pass.cpp \
+		source/opt/inline_opaque_pass.cpp \
 		source/opt/insert_extract_elim.cpp \
 		source/opt/instruction.cpp \
 		source/opt/ir_loader.cpp \
@@ -170,8 +174,10 @@
 		source/opt/local_single_block_elim_pass.cpp \
 		source/opt/local_single_store_elim_pass.cpp \
 		source/opt/local_ssa_elim_pass.cpp \
+		source/opt/mem_pass.cpp \
 		source/opt/module.cpp \
 		source/opt/optimizer.cpp \
+		source/opt/pass.cpp \
 		source/opt/pass_manager.cpp \
 		source/opt/set_spec_constant_default_value_pass.cpp \
 		source/opt/strip_debug_info_pass.cpp \