Web: Remove unused stage functionality, SPIR-V logger, and hex_utils

Saves another 20K.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 12c6e49..a91f180 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -248,6 +248,10 @@
 // Translate glslang profile to SPIR-V source language.
 spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile)
 {
+#ifdef GLSLANG_WEB
+    return spv::SourceLanguageESSL;
+#endif
+
     switch (source) {
     case glslang::EShSourceGlsl:
         switch (profile) {
@@ -601,6 +605,7 @@
 {
     switch (builtIn) {
     case glslang::EbvPointSize:
+#ifndef GLSLANG_WEB
         // Defer adding the capability until the built-in is actually used.
         if (! memberDeclaration) {
             switch (glslangIntermediate->getStage()) {
@@ -615,6 +620,7 @@
                 break;
             }
         }
+#endif
         return spv::BuiltInPointSize;
 
     case glslang::EbvPosition:             return spv::BuiltInPosition;
@@ -1664,6 +1670,7 @@
             builder.setAccessChainLValue(id);
     }
 
+#ifndef GLSLANG_WEB
     // Process linkage-only nodes for any special additional interface work.
     if (linkageOnly) {
         if (glslangIntermediate->getHlslFunctionality1()) {
@@ -1695,6 +1702,7 @@
             }
         }
     }
+#endif
 }
 
 bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
@@ -2151,12 +2159,14 @@
 
         return false;
 
+#ifndef GLSLANG_WEB
     case glslang::EOpEmitStreamVertex:
         builder.createNoResultOp(spv::OpEmitStreamVertex, operand);
         return false;
     case glslang::EOpEndStreamPrimitive:
         builder.createNoResultOp(spv::OpEndStreamPrimitive, operand);
         return false;
+#endif
 
     default:
         logger->missingFunctionality("unknown glslang unary");
@@ -4123,8 +4133,12 @@
         std::vector<std::vector<spv::Decoration>> paramDecorations; // list of decorations per parameter
         glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence();
 
+#ifdef ENABLE_HLSL
         bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() ==
                                                           glslangIntermediate->implicitThisName;
+#else
+        bool implicitThis = false;
+#endif
 
         paramDecorations.resize(parameters.size());
         for (int p = 0; p < (int)parameters.size(); ++p) {
@@ -7396,11 +7410,11 @@
 // Intrinsics with no arguments (or no return value, and no precision).
 spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId)
 {
+#ifndef GLSLANG_WEB
     // GLSL memory barriers use queuefamily scope in new model, device scope in old model
     spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
 
     switch (op) {
-#ifndef GLSLANG_WEB
     case glslang::EOpEmitVertex:
         builder.createNoResultOp(spv::OpEmitVertex);
         return 0;
@@ -7538,11 +7552,14 @@
         builder.addCapability(spv::CapabilityShaderClockKHR);
         return builder.createOp(spv::OpReadClockKHR, typeId, args);
     }
-#endif
     default:
-        logger->missingFunctionality("unknown operation with no arguments");
-        return 0;
+        break;
     }
+#endif
+
+    logger->missingFunctionality("unknown operation with no arguments");
+
+    return 0;
 }
 
 spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol)
@@ -7745,6 +7762,7 @@
 
     // We now know we have a specialization constant to build
 
+#ifndef GLSLANG_WEB
     // gl_WorkGroupSize is a special case until the front-end handles hierarchical specialization constants,
     // even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ...
     if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) {
@@ -7759,6 +7777,7 @@
         }
         return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true);
     }
+#endif
 
     // An AST node labelled as specialization constant should be a symbol node.
     // Its initializer should either be a sub tree with constant nodes, or a constant union array.
@@ -8114,6 +8133,7 @@
 // Write SPIR-V out to a text file with 32-bit hexadecimal words
 void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName)
 {
+#ifndef GLSLANG_WEB
     std::ofstream out;
     out.open(baseName, std::ios::binary | std::ios::out);
     if (out.fail())
@@ -8141,6 +8161,7 @@
         out << "};";
     }
     out.close();
+#endif
 }
 
 //
diff --git a/SPIRV/Logger.cpp b/SPIRV/Logger.cpp
index 48bd4e3..7ea0c63 100644
--- a/SPIRV/Logger.cpp
+++ b/SPIRV/Logger.cpp
@@ -32,6 +32,8 @@
 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 // POSSIBILITY OF SUCH DAMAGE.
 
+#ifndef GLSLANG_WEB
+
 #include "Logger.h"
 
 #include <algorithm>
@@ -66,3 +68,5 @@
 }
 
 } // end spv namespace
+
+#endif
\ No newline at end of file
diff --git a/SPIRV/Logger.h b/SPIRV/Logger.h
index 2e4ddaf..411367c 100644
--- a/SPIRV/Logger.h
+++ b/SPIRV/Logger.h
@@ -46,6 +46,14 @@
 public:
     SpvBuildLogger() {}
 
+#ifdef GLSLANG_WEB
+    void tbdFunctionality(const std::string& f) { }
+    void missingFunctionality(const std::string& f) { }
+    void warning(const std::string& w) { }
+    void error(const std::string& e) { errors.push_back(e); }
+    std::string getAllMessages() { return ""; }
+#else
+
     // Registers a TBD functionality.
     void tbdFunctionality(const std::string& f);
     // Registers a missing functionality.
@@ -59,6 +67,7 @@
     // Returns all messages accumulated in the order of:
     // TBD functionalities, missing functionalities, warnings, errors.
     std::string getAllMessages() const;
+#endif
 
 private:
     SpvBuildLogger(const SpvBuildLogger&);
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index d64f8cd..b0d56d4 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -46,7 +46,9 @@
 
 #include "SpvBuilder.h"
 
+#ifndef GLSLANG_WEB
 #include "hex_float.h"
+#endif
 
 #ifndef _WIN32
     #include <cstdio>
@@ -950,6 +952,10 @@
 
 Id Builder::makeDoubleConstant(double d, bool specConstant)
 {
+#ifdef GLSLANG_WEB
+    assert(0);
+    return NoResult;
+#else
     Op opcode = specConstant ? OpSpecConstant : OpConstant;
     Id typeId = makeFloatType(64);
     union { double db; unsigned long long ull; } u;
@@ -974,10 +980,15 @@
     module.mapInstruction(c);
 
     return c->getResultId();
+#endif
 }
 
 Id Builder::makeFloat16Constant(float f16, bool specConstant)
 {
+#ifdef GLSLANG_WEB
+    assert(0);
+    return NoResult;
+#else
     Op opcode = specConstant ? OpSpecConstant : OpConstant;
     Id typeId = makeFloatType(16);
 
@@ -1002,6 +1013,7 @@
     module.mapInstruction(c);
 
     return c->getResultId();
+#endif
 }
 
 Id Builder::makeFpConstant(Id type, double d, bool specConstant)
diff --git a/SPIRV/SpvTools.h b/SPIRV/SpvTools.h
index cf8fc85..7422d01 100644
--- a/SPIRV/SpvTools.h
+++ b/SPIRV/SpvTools.h
@@ -41,8 +41,10 @@
 #ifndef GLSLANG_SPV_TOOLS_H
 #define GLSLANG_SPV_TOOLS_H
 
+#ifdef ENABLE_OPT
 #include <vector>
 #include <ostream>
+#endif
 
 #include "../glslang/MachineIndependent/localintermediate.h"
 #include "Logger.h"
@@ -59,7 +61,7 @@
     bool validate;
 };
 
-#if ENABLE_OPT
+#ifdef ENABLE_OPT
 
 // Use the SPIRV-Tools disassembler to print SPIR-V.
 void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 17561a2..44d3ccc 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -977,6 +977,7 @@
             shader->setPreamble(UserPreamble.get());
         shader->addProcesses(Processes);
 
+#ifndef GLSLANG_WEB
         // Set IO mapper binding shift values
         for (int r = 0; r < glslang::EResCount; ++r) {
             const glslang::TResourceType res = glslang::TResourceType(r);
@@ -990,32 +991,33 @@
                  i != baseBindingForSet[res][compUnit.stage].end(); ++i)
                 shader->setShiftBindingForSet(res, i->second, i->first);
         }
-
-        shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
         shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0);
-        shader->setNanMinMaxClamp(NaNClamp);
         shader->setResourceSetBinding(baseResourceSetBinding[compUnit.stage]);
 
-#ifdef ENABLE_HLSL
-        if (Options & EOptionHlslIoMapping)
-            shader->setHlslIoMapping(true);
-#endif
-
         if (Options & EOptionAutoMapBindings)
             shader->setAutoMapBindings(true);
 
         if (Options & EOptionAutoMapLocations)
             shader->setAutoMapLocations(true);
 
-        if (Options & EOptionInvertY)
-            shader->setInvertY(true);
-
         for (auto& uniOverride : uniformLocationOverrides) {
             shader->addUniformLocationOverride(uniOverride.first.c_str(),
                                                uniOverride.second);
         }
 
         shader->setUniformLocationBase(uniformBase);
+#endif
+
+        shader->setNanMinMaxClamp(NaNClamp);
+
+#ifdef ENABLE_HLSL
+        shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
+        if (Options & EOptionHlslIoMapping)
+            shader->setHlslIoMapping(true);
+#endif
+
+        if (Options & EOptionInvertY)
+            shader->setInvertY(true);
 
         // Set up the environment, some subsettings take precedence over earlier
         // ways of setting things.
diff --git a/Test/baseResults/size b/Test/baseResults/size
index 4115f7f..6de1c4d 100644
--- a/Test/baseResults/size
+++ b/Test/baseResults/size
@@ -1 +1 @@
-812032 ../build/install/bin/glslangValidator.exe
+601088 ../build/install/bin/glslangValidator.exe
diff --git a/Test/baseResults/spv.hlslDebugInfo.frag.out b/Test/baseResults/spv.hlslDebugInfo.frag.out
index 9912d4e..35a6a4d 100644
--- a/Test/baseResults/spv.hlslDebugInfo.frag.out
+++ b/Test/baseResults/spv.hlslDebugInfo.frag.out
@@ -15,12 +15,12 @@
 // OpModuleProcessed shift-UBO-binding 6
 // OpModuleProcessed shift-ssbo-binding 3
 // OpModuleProcessed shift-uav-binding 5
-// OpModuleProcessed flatten-uniform-arrays
 // OpModuleProcessed no-storage-format
 // OpModuleProcessed resource-set-binding t0 0 0
-// OpModuleProcessed hlsl-iomap
 // OpModuleProcessed auto-map-bindings
 // OpModuleProcessed auto-map-locations
+// OpModuleProcessed flatten-uniform-arrays
+// OpModuleProcessed hlsl-iomap
 // OpModuleProcessed client vulkan100
 // OpModuleProcessed target-env vulkan1.0
 // OpModuleProcessed source-entrypoint origMain
diff --git a/Test/baseResults/web.builtins.vert.out b/Test/baseResults/web.builtins.vert.out
index 379035f..9ea6672 100644
--- a/Test/baseResults/web.builtins.vert.out
+++ b/Test/baseResults/web.builtins.vert.out
@@ -1,74 +1,62 @@
 ; SPIR-V
 ; Version: 1.0
 ; Generator: Khronos Glslang Reference Front End; 7
-; Bound: 42
+; Bound: 33
 ; Schema: 0
                OpCapability Shader
           %1 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
-               OpEntryPoint Vertex %main "main" %_ %ps %gl_VertexIndex %gl_InstanceIndex
+               OpEntryPoint Vertex %main "main" %gl_Position %ps %gl_VertexIndex %gl_PointSize %gl_InstanceIndex
                OpSource ESSL 310
                OpName %main "main"
-               OpName %gl_PerVertex "gl_PerVertex"
-               OpMemberName %gl_PerVertex 0 "gl_Position"
-               OpMemberName %gl_PerVertex 1 "gl_PointSize"
-               OpName %_ ""
+               OpName %gl_Position "gl_Position"
                OpName %ps "ps"
                OpName %gl_VertexIndex "gl_VertexIndex"
+               OpName %gl_PointSize "gl_PointSize"
                OpName %gl_InstanceIndex "gl_InstanceIndex"
-               OpMemberDecorate %gl_PerVertex 0 Invariant
-               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
-               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
-               OpDecorate %gl_PerVertex Block
+               OpDecorate %gl_Position Invariant
+               OpDecorate %gl_Position BuiltIn Position
                OpDecorate %ps RelaxedPrecision
                OpDecorate %ps Location 0
-               OpDecorate %15 RelaxedPrecision
+               OpDecorate %12 RelaxedPrecision
                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
-               OpDecorate %30 RelaxedPrecision
+               OpDecorate %gl_PointSize BuiltIn PointSize
+               OpDecorate %25 RelaxedPrecision
                OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
        %void = OpTypeVoid
           %3 = OpTypeFunction %void
       %float = OpTypeFloat 32
     %v4float = OpTypeVector %float 4
-%gl_PerVertex = OpTypeStruct %v4float %float
-%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
-          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%gl_Position = OpVariable %_ptr_Output_v4float Output
 %_ptr_Input_float = OpTypePointer Input %float
          %ps = OpVariable %_ptr_Input_float Input
-%_ptr_Output_v4float = OpTypePointer Output %v4float
+        %int = OpTypeInt 32 1
       %int_4 = OpConstant %int 4
 %_ptr_Input_int = OpTypePointer Input %int
 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
-      %int_1 = OpConstant %int 1
 %_ptr_Output_float = OpTypePointer Output %float
+%gl_PointSize = OpVariable %_ptr_Output_float Output
       %int_5 = OpConstant %int 5
 %gl_InstanceIndex = OpVariable %_ptr_Input_int Input
        %main = OpFunction %void None %3
           %5 = OpLabel
-         %15 = OpLoad %float %ps
-         %16 = OpCompositeConstruct %v4float %15 %15 %15 %15
-         %18 = OpAccessChain %_ptr_Output_v4float %_ %int_0
-               OpStore %18 %16
-         %22 = OpLoad %int %gl_VertexIndex
-         %23 = OpISub %int %int_4 %22
-         %24 = OpConvertSToF %float %23
-         %25 = OpAccessChain %_ptr_Output_v4float %_ %int_0
-         %26 = OpLoad %v4float %25
-         %27 = OpVectorTimesScalar %v4float %26 %24
-         %28 = OpAccessChain %_ptr_Output_v4float %_ %int_0
-               OpStore %28 %27
-         %30 = OpLoad %float %ps
-         %32 = OpAccessChain %_ptr_Output_float %_ %int_1
-               OpStore %32 %30
-         %35 = OpLoad %int %gl_InstanceIndex
-         %36 = OpISub %int %int_5 %35
-         %37 = OpConvertSToF %float %36
-         %38 = OpAccessChain %_ptr_Output_float %_ %int_1
-         %39 = OpLoad %float %38
-         %40 = OpFMul %float %39 %37
-         %41 = OpAccessChain %_ptr_Output_float %_ %int_1
-               OpStore %41 %40
+         %12 = OpLoad %float %ps
+         %13 = OpCompositeConstruct %v4float %12 %12 %12 %12
+               OpStore %gl_Position %13
+         %18 = OpLoad %int %gl_VertexIndex
+         %19 = OpISub %int %int_4 %18
+         %20 = OpConvertSToF %float %19
+         %21 = OpLoad %v4float %gl_Position
+         %22 = OpVectorTimesScalar %v4float %21 %20
+               OpStore %gl_Position %22
+         %25 = OpLoad %float %ps
+               OpStore %gl_PointSize %25
+         %28 = OpLoad %int %gl_InstanceIndex
+         %29 = OpISub %int %int_5 %28
+         %30 = OpConvertSToF %float %29
+         %31 = OpLoad %float %gl_PointSize
+         %32 = OpFMul %float %31 %30
+               OpStore %gl_PointSize %32
                OpReturn
                OpFunctionEnd
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index 87d3258..9fa47fa 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -778,9 +778,13 @@
         layoutLocation = layoutLocationEnd;
         layoutComponent = layoutComponentEnd;
         layoutIndex = layoutIndexEnd;
+#ifndef GLSLANG_WEB
         clearStreamLayout();
         clearXfbLayout();
+#endif
     }
+
+#ifndef GLSLANG_WEB
     void clearStreamLayout()
     {
         layoutStream = layoutStreamEnd;
@@ -791,6 +795,7 @@
         layoutXfbStride = layoutXfbStrideEnd;
         layoutXfbOffset = layoutXfbOffsetEnd;
     }
+#endif
 
     bool hasNonXfbLayout() const
     {
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 4b3d267..6e0090c 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -403,6 +403,10 @@
     forEachFunction(commonBuiltins, BaseFunctions);
     forEachFunction(stageBuiltins[EShLangFragment], DerivativeFunctions);
 
+#ifdef GLSLANG_WEB
+    return;
+#endif
+
     if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450))
         forEachFunction(stageBuiltins[EShLangCompute], DerivativeFunctions);
 }
@@ -1298,13 +1302,14 @@
         commonBuiltins.append(
             "mediump vec2 unpackHalf2x16(highp uint);"
             "\n");
-    } else if (profile != EEsProfile && version >= 420) {
+    }
+#ifndef GLSLANG_WEB
+    else if (profile != EEsProfile && version >= 420) {
         commonBuiltins.append(
             "        vec2 unpackHalf2x16(highp uint);"
             "\n");
     }
 
-#ifndef GLSLANG_WEB
     if ((profile == EEsProfile && version >= 310) ||
         (profile != EEsProfile && version >= 400)) {
         commonBuiltins.append(
@@ -5405,22 +5410,25 @@
                 "mediump float gl_PointSize;" // needs qualifier fixed later
                 );
         } else {
-#endif
             if (spvVersion.vulkan == 0)
                 stageBuiltins[EShLangVertex].append(
                     "in highp int gl_VertexID;"      // needs qualifier fixed later
                     "in highp int gl_InstanceID;"    // needs qualifier fixed later
                     );
             if (spvVersion.vulkan > 0)
+#endif
                 stageBuiltins[EShLangVertex].append(
                     "in highp int gl_VertexIndex;"
                     "in highp int gl_InstanceIndex;"
                     );
+#ifndef GLSLANG_WEB
             if (version < 310)
+#endif
                 stageBuiltins[EShLangVertex].append(
                     "highp vec4  gl_Position;"    // needs qualifier fixed later
                     "highp float gl_PointSize;"   // needs qualifier fixed later
                     );
+#ifndef GLSLANG_WEB
             else
                 stageBuiltins[EShLangVertex].append(
                     "out gl_PerVertex {"
@@ -5428,7 +5436,6 @@
                         "highp float gl_PointSize;"   // needs qualifier fixed later
                     "};"
                     );
-#ifndef GLSLANG_WEB
         }
     }
 
@@ -6155,16 +6162,18 @@
     // In this function proper, enumerate the types, then calls the next set of functions
     // to enumerate all the uses for that type.
     //
-    bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140);
-    bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130);
 
     // enumerate all the types
 #ifdef GLSLANG_WEB
     const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint };
     const int image = 0;
+    bool skipBuffer = true;
+    bool skipCubeArrayed = true;
 #else
     const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, EbtFloat16 };
     for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler
+    bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140);
+    bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130);
 #endif
     {
         for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not
@@ -7652,7 +7661,17 @@
 
     switch(language) {
     case EShLangVertex:
+        if (spvVersion.vulkan > 0) {
+            BuiltInVariable("gl_VertexIndex",   EbvVertexIndex,   symbolTable);
+            BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable);
+        }
+
 #ifndef GLSLANG_WEB
+        if (spvVersion.vulkan == 0) {
+            SpecialQualifier("gl_VertexID",   EvqVertexId,   EbvVertexId,   symbolTable);
+            SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
+        }
+
         if (profile != EEsProfile) {
             if (version >= 440) {
                 symbolTable.setVariableExtensions("gl_BaseVertexARB",   1, &E_GL_ARB_shader_draw_parameters);
@@ -7777,20 +7796,7 @@
             symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic);
             symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic);
         }
-#endif
 
-        if (spvVersion.vulkan == 0) {
-            SpecialQualifier("gl_VertexID",   EvqVertexId,   EbvVertexId,   symbolTable);
-            SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
-        }
-
-        if (spvVersion.vulkan > 0) {
-            BuiltInVariable("gl_VertexIndex",   EbvVertexIndex,   symbolTable);
-            BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable);
-        }
-
-
-#ifndef GLSLANG_WEB
         if (version >= 300 /* both ES and non-ES */) {
             symbolTable.setVariableExtensions("gl_ViewID_OVR", Num_OVR_multiview_EXTs, OVR_multiview_EXTs);
             BuiltInVariable("gl_ViewID_OVR", EbvViewIndex, symbolTable);
@@ -7800,12 +7806,9 @@
             symbolTable.setFunctionExtensions("shadow2DEXT",        1, &E_GL_EXT_shadow_samplers);
             symbolTable.setFunctionExtensions("shadow2DProjEXT",    1, &E_GL_EXT_shadow_samplers);
         }
-#endif
         // Fall through
 
     case EShLangTessControl:
-
-#ifndef GLSLANG_WEB
         if (profile == EEsProfile && version >= 310) {
             BuiltInVariable("gl_BoundingBoxEXT", EbvBoundingBox, symbolTable);
             symbolTable.setVariableExtensions("gl_BoundingBoxEXT", 1,
@@ -7818,11 +7821,11 @@
                 BuiltInVariable("gl_BoundingBox", EbvBoundingBox, symbolTable);
             }
         }
-#endif
         // Fall through
 
     case EShLangTessEvaluation:
     case EShLangGeometry:
+#endif
         SpecialQualifier("gl_Position",   EvqPosition,   EbvPosition,   symbolTable);
         SpecialQualifier("gl_PointSize",  EvqPointSize,  EbvPointSize,  symbolTable);
 
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index 45385d9..fcc509d 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -3815,7 +3815,7 @@
         case EbtFloat: PROMOTE(setDConst, double, Get); break; \
         case EbtInt: PROMOTE(setIConst, int, Get); break; \
         case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \
-        case EbtBool: PROMOTE(setBConst, bool, Get); break; \
+        case EbtBool: PROMOTE_TO_BOOL(Get); break; \
         default: return node; \
         }
 #else
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index da221c1..aa888e5 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -83,6 +83,7 @@
     globalInputDefaults.clear();
     globalOutputDefaults.clear();
 
+#ifndef GLSLANG_WEB
     // "Shaders in the transform
     // feedback capturing mode have an initial global default of
     //     layout(xfb_buffer = 0) out;"
@@ -94,6 +95,7 @@
 
     if (language == EShLangGeometry)
         globalOutputDefaults.layoutStream = 0;
+#endif
 
     if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main")
         infoSink.info.message(EPrefixError, "Source entry point must be \"main\"");
@@ -215,6 +217,7 @@
 
 void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
 {
+#ifndef GLSLANG_WEB
     if (pragmaCallback)
         pragmaCallback(loc.line, tokens);
 
@@ -287,6 +290,7 @@
         warn(loc, "not implemented", "#pragma once", "");
     } else if (tokens[0].compare("glslang_binary_double_output") == 0)
         intermediate.setBinaryDoubleOutput();
+#endif
 }
 
 //
@@ -1396,6 +1400,7 @@
 // See if the operation is being done in an illegal location.
 void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
 {
+#ifndef GLSLANG_WEB
     switch (op) {
     case EOpBarrier:
         if (language == EShLangTessControl) {
@@ -1448,6 +1453,7 @@
     default:
         break;
     }
+#endif
 }
 
 #ifndef GLSLANG_WEB
@@ -2467,6 +2473,7 @@
         bool errorReturn = false;
 
         switch(binaryNode->getOp()) {
+#ifndef GLSLANG_WEB
         case EOpIndexDirect:
         case EOpIndexIndirect:
             // ...  tessellation control shader ...
@@ -2482,10 +2489,8 @@
                         error(loc, "tessellation-control per-vertex output l-value must be indexed with gl_InvocationID", "[]", "");
                 }
             }
-
             break; // left node is checked by base class
-        case EOpIndexDirectStruct:
-            break; // left node is checked by base class
+#endif
         case EOpVectorSwizzle:
             errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft());
             if (!errorReturn) {
@@ -3319,18 +3324,6 @@
             if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)
                 error(loc, "vertex input cannot be further qualified", "", "");
             break;
-
-        case EShLangTessControl:
-            if (qualifier.patch)
-                error(loc, "can only use on output in tessellation-control shader", "patch", "");
-            break;
-
-        case EShLangTessEvaluation:
-            break;
-
-        case EShLangGeometry:
-            break;
-
         case EShLangFragment:
             if (publicType.userDef) {
                 profileRequires(loc, EEsProfile, 300, nullptr, "fragment-shader struct input");
@@ -3341,12 +3334,16 @@
                     requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array");
             }
             break;
-
-        case EShLangCompute:
+#ifndef GLSLANG_WEB
+       case EShLangCompute:
             if (! symbolTable.atBuiltInLevel())
                 error(loc, "global storage input qualifier cannot be used in a compute shader", "in", "");
             break;
-
+       case EShLangTessControl:
+            if (qualifier.patch)
+                error(loc, "can only use on output in tessellation-control shader", "patch", "");
+            break;
+#endif
         default:
             break;
         }
@@ -3364,18 +3361,6 @@
             }
 
             break;
-
-        case EShLangTessControl:
-            break;
-
-        case EShLangTessEvaluation:
-            if (qualifier.patch)
-                error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
-            break;
-
-        case EShLangGeometry:
-            break;
-
         case EShLangFragment:
             profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output");
             if (publicType.basicType == EbtStruct) {
@@ -3394,10 +3379,15 @@
                 error(loc, "cannot contain a double, int64, or uint64", GetStorageQualifierString(qualifier.storage), "");
         break;
 
+#ifndef GLSLANG_WEB
         case EShLangCompute:
             error(loc, "global storage output qualifier cannot be used in a compute shader", "out", "");
             break;
-
+        case EShLangTessEvaluation:
+            if (qualifier.patch)
+                error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
+            break;
+#endif
         default:
             break;
         }
@@ -6407,9 +6397,7 @@
     if (symbol == nullptr)
         reservedErrorCheck(loc, identifier);
 
-#ifndef GLSLANG_WEB
     inheritGlobalDefaults(type.getQualifier());
-#endif
 
     // Declare the variable
     if (type.isArray()) {
@@ -6457,12 +6445,14 @@
 // Pick up global defaults from the provide global defaults into dst.
 void TParseContext::inheritGlobalDefaults(TQualifier& dst) const
 {
+#ifndef GLSLANG_WEB
     if (dst.storage == EvqVaryingOut) {
         if (! dst.hasStream() && language == EShLangGeometry)
             dst.layoutStream = globalOutputDefaults.layoutStream;
         if (! dst.hasXfbBuffer())
             dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
     }
+#endif
 }
 
 //
@@ -7411,6 +7401,7 @@
         if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.isPushConstant())
             requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier");
         break;
+#ifndef GLSLANG_WEB
     case EvqBuffer:
         requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block");
@@ -7425,11 +7416,9 @@
         if (language == EShLangFragment) {
             profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block");
         }
-#ifndef GLSLANG_WEB
         else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) {
             error(loc, "input blocks cannot be used in a mesh shader", "out", "");
         }
-#endif
         break;
     case EvqVaryingOut:
         profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block");
@@ -7446,7 +7435,6 @@
             error(loc, "output blocks cannot be used in a task shader", "out", "");
         }
         break;
-#ifndef GLSLANG_WEB
     case EvqPayloadNV:
         profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV block");
         requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask),
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index ec01050..b01cbe3 100755
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -1755,6 +1755,11 @@
     intermediate->addProcesses(p);
 }
 
+void TShader::setInvertY(bool invert)                   { intermediate->setInvertY(invert); }
+void TShader::setNanMinMaxClamp(bool useNonNan)         { intermediate->setNanMinMaxClamp(useNonNan); }
+
+#ifndef GLSLANG_WEB
+
 // Set binding base for given resource type
 void TShader::setShiftBinding(TResourceType res, unsigned int base) {
     intermediate->setShiftBinding(res, base);
@@ -1782,7 +1787,7 @@
 // Enables binding automapping using TIoMapper
 void TShader::setAutoMapBindings(bool map)              { intermediate->setAutoMapBindings(map); }
 // Enables position.Y output negation in vertex shader
-void TShader::setInvertY(bool invert)                   { intermediate->setInvertY(invert); }
+
 // Fragile: currently within one stage: simple auto-assignment of location
 void TShader::setAutoMapLocations(bool map)             { intermediate->setAutoMapLocations(map); }
 void TShader::addUniformLocationOverride(const char* name, int loc)
@@ -1793,15 +1798,16 @@
 {
     intermediate->setUniformLocationBase(base);
 }
-// See comment above TDefaultHlslIoMapper in iomapper.cpp:
-#ifdef ENABLE_HLSL
-void TShader::setHlslIoMapping(bool hlslIoMap)          { intermediate->setHlslIoMapping(hlslIoMap); }
-#endif
-void TShader::setFlattenUniformArrays(bool flatten)     { intermediate->setFlattenUniformArrays(flatten); }
 void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
-void TShader::setNanMinMaxClamp(bool useNonNan)         { intermediate->setNanMinMaxClamp(useNonNan); }
 void TShader::setResourceSetBinding(const std::vector<std::string>& base)   { intermediate->setResourceSetBinding(base); }
 void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
+#endif
+
+#ifdef ENABLE_HLSL
+// See comment above TDefaultHlslIoMapper in iomapper.cpp:
+void TShader::setHlslIoMapping(bool hlslIoMap)          { intermediate->setHlslIoMapping(hlslIoMap); }
+void TShader::setFlattenUniformArrays(bool flatten)     { intermediate->setFlattenUniformArrays(flatten); }
+#endif
 
 //
 // Turn the shader strings into a parse tree in the TIntermediate.
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index 17cc224..05ace4d 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -524,10 +524,11 @@
 {
     switch(stage) {
     case EShLangVertex:         return "vertex";
+    case EShLangFragment:       return "fragment";
+#ifndef GLSLANG_WEB
     case EShLangTessControl:    return "tessellation control";
     case EShLangTessEvaluation: return "tessellation evaluation";
     case EShLangGeometry:       return "geometry";
-    case EShLangFragment:       return "fragment";
     case EShLangCompute:        return "compute";
     case EShLangRayGenNV:       return "ray-generation";
     case EShLangIntersectNV:    return "intersection";
@@ -537,6 +538,7 @@
     case EShLangCallableNV:     return "callable";
     case EShLangMeshNV:         return "mesh";
     case EShLangTaskNV:         return "task";
+#endif
     default:                    return "unknown stage";
     }
 }
diff --git a/glslang/MachineIndependent/glslang.m4 b/glslang/MachineIndependent/glslang.m4
index aef15f6..1bc12d2 100644
--- a/glslang/MachineIndependent/glslang.m4
+++ b/glslang/MachineIndependent/glslang.m4
@@ -1361,6 +1361,7 @@
         $$.init($1.loc);
         $$.qualifier.storage = EvqUniform;
     }
+GLSLANG_WEB_EXCLUDE_ON
     | SHARED {
         parseContext.globalCheck($1.loc, "shared");
         parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
@@ -1369,7 +1370,6 @@
         $$.init($1.loc);
         $$.qualifier.storage = EvqShared;
     }
-GLSLANG_WEB_EXCLUDE_ON
     | BUFFER {
         parseContext.globalCheck($1.loc, "buffer");
         $$.init($1.loc);
diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y
index ca0bff1..bc32ade 100644
--- a/glslang/MachineIndependent/glslang.y
+++ b/glslang/MachineIndependent/glslang.y
@@ -1361,6 +1361,7 @@
         $$.init($1.loc);
         $$.qualifier.storage = EvqUniform;
     }
+
     | SHARED {
         parseContext.globalCheck($1.loc, "shared");
         parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
@@ -1369,7 +1370,6 @@
         $$.init($1.loc);
         $$.qualifier.storage = EvqShared;
     }
-
     | BUFFER {
         parseContext.globalCheck($1.loc, "buffer");
         $$.init($1.loc);
diff --git a/glslang/MachineIndependent/glslang_tab.cpp b/glslang/MachineIndependent/glslang_tab.cpp
index 0fb7f77..499b20f 100644
--- a/glslang/MachineIndependent/glslang_tab.cpp
+++ b/glslang/MachineIndependent/glslang_tab.cpp
@@ -958,7 +958,7 @@
     1143,  1170,  1179,  1186,  1194,  1201,  1208,  1216,  1226,  1233,
     1244,  1250,  1253,  1260,  1264,  1268,  1277,  1287,  1290,  1301,
     1304,  1307,  1311,  1315,  1320,  1324,  1331,  1335,  1340,  1346,
-    1352,  1359,  1364,  1373,  1378,  1390,  1404,  1410,  1415,  1423,
+    1352,  1359,  1365,  1373,  1378,  1390,  1404,  1410,  1415,  1423,
     1431,  1439,  1447,  1454,  1458,  1463,  1468,  1473,  1478,  1483,
     1487,  1491,  1495,  1499,  1505,  1516,  1523,  1526,  1535,  1540,
     1550,  1555,  1563,  1567,  1577,  1580,  1586,  1592,  1599,  1609,
@@ -5796,7 +5796,7 @@
     break;
 
   case 162:
-#line 1364 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 1365 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.globalCheck((yyvsp[0].lex).loc, "shared");
         parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp
index da51eba..1293923 100644
--- a/glslang/MachineIndependent/linkValidate.cpp
+++ b/glslang/MachineIndependent/linkValidate.cpp
@@ -614,11 +614,11 @@
     // overlap/alias/missing I/O, etc.
     inOutLocationCheck(infoSink);
 
+#ifndef GLSLANG_WEB
     // invocations
     if (invocations == TQualifier::layoutNotSet)
         invocations = 1;
 
-#ifndef GLSLANG_WEB
     if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipVertex"))
         error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipVertex (gl_ClipDistance is preferred)");
     if (inIoAccessed("gl_CullDistance") && inIoAccessed("gl_ClipVertex"))
@@ -1045,6 +1045,7 @@
     // So, for the case of dvec3, we need two independent ioRanges.
 
     int collision = -1; // no collision
+#ifndef GLSLANG_WEB
     if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
         (qualifier.isPipeInput() || qualifier.isPipeOutput())) {
         // Dealing with dvec3 in/out split across two locations.
@@ -1071,7 +1072,9 @@
             if (collision < 0)
                 usedIo[set].push_back(range2);
         }
-    } else {
+    } else
+#endif
+    {
         // Not a dvec3 in/out split across two locations, generic path.
         // Need a single IO-range block.
 
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index b2ac737..2dcacff 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -226,45 +226,48 @@
 class TIntermediate {
 public:
     explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
-        implicitThisName("@this"), implicitCounterName("@count"),
         language(l),
 #ifdef ENABLE_HLSL
+        implicitThisName("@this"), implicitCounterName("@count"),
         source(EShSourceNone),
 #endif
         profile(p), version(v), treeRoot(0),
         numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
+        invertY(false),
+        useStorageBuffer(false),
+        nanMinMaxClamp(false),
+        depthReplacing(false)
+#ifndef GLSLANG_WEB
+        ,
+        useVulkanMemoryModel(false),
         invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
         inputPrimitive(ElgNone), outputPrimitive(ElgNone),
         pixelCenterInteger(false), originUpperLeft(false),
         vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
-        postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
+        postDepthCoverage(false), depthLayout(EldNone), 
         hlslFunctionality1(false),
         blendEquations(0), xfbMode(false), multiStream(false),
-#ifndef GLSLANG_WEB
         layoutOverrideCoverage(false),
         geoPassthroughEXT(false),
         numShaderRecordNVBlocks(0),
         computeDerivativeMode(LayoutDerivativeNone),
         primitives(TQualifier::layoutNotSet),
         numTaskNVBlocks(0),
-#endif
         autoMapBindings(false),
         autoMapLocations(false),
-        invertY(false),
         flattenUniformArrays(false),
         useUnknownFormat(false),
         hlslOffsets(false),
-        useStorageBuffer(false),
-        useVulkanMemoryModel(false),
         hlslIoMapping(false),
         useVariablePointers(false),
         textureSamplerTransformMode(EShTexSampTransKeep),
         needToLegalize(false),
         binaryDoubleOutput(false),
         usePhysicalStorageBuffer(false),
-        uniformLocationBase(0),
-        nanMinMaxClamp(false)
+        uniformLocationBase(0)
+#endif
     {
+#ifndef GLSLANG_WEB
         localSize[0] = 1;
         localSize[1] = 1;
         localSize[2] = 1;
@@ -272,147 +275,9 @@
         localSizeSpecId[1] = TQualifier::layoutNotSet;
         localSizeSpecId[2] = TQualifier::layoutNotSet;
         xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
-
         shiftBinding.fill(0);
-    }
-    void setLimits(const TBuiltInResource& r) { resources = r; }
-
-    bool postProcess(TIntermNode*, EShLanguage);
-#ifdef GLSLANG_WEB
-    void output(TInfoSink&, bool tree) { }
-#else
-    void output(TInfoSink&, bool tree);
 #endif
-    void removeTree();
-
-#ifdef ENABLE_HLSL
-    void setSource(EShSource s) { source = s; }
-    EShSource getSource() const { return source; }
-#else
-    void setSource(EShSource s) { assert(s == EShSourceGlsl); }
-    EShSource getSource() const { return EShSourceGlsl; }
-#endif
-    void setEntryPointName(const char* ep)
-    {
-        entryPointName = ep;
-        processes.addProcess("entry-point");
-        processes.addArgument(entryPointName);
     }
-    void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; }
-    const std::string& getEntryPointName() const { return entryPointName; }
-    const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
-
-    void setShiftBinding(TResourceType res, unsigned int shift)
-    {
-        shiftBinding[res] = shift;
-
-        const char* name = getResourceName(res);
-        if (name != nullptr)
-            processes.addIfNonZero(name, shift);
-    }
-
-    unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
-
-    void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set)
-    {
-        if (shift == 0) // ignore if there's no shift: it's a no-op.
-            return;
-
-        shiftBindingForSet[res][set] = shift;
-
-        const char* name = getResourceName(res);
-        if (name != nullptr) {
-            processes.addProcess(name);
-            processes.addArgument(shift);
-            processes.addArgument(set);
-        }
-    }
-
-    int getShiftBindingForSet(TResourceType res, unsigned int set) const
-    {
-        const auto shift = shiftBindingForSet[res].find(set);
-        return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
-    }
-    bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
-
-    void setResourceSetBinding(const std::vector<std::string>& shift)
-    {
-        resourceSetBinding = shift;
-        if (shift.size() > 0) {
-            processes.addProcess("resource-set-binding");
-            for (int s = 0; s < (int)shift.size(); ++s)
-                processes.addArgument(shift[s]);
-        }
-    }
-    const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
-    void setAutoMapBindings(bool map)
-    {
-        autoMapBindings = map;
-        if (autoMapBindings)
-            processes.addProcess("auto-map-bindings");
-    }
-    bool getAutoMapBindings() const { return autoMapBindings; }
-    void setAutoMapLocations(bool map)
-    {
-        autoMapLocations = map;
-        if (autoMapLocations)
-            processes.addProcess("auto-map-locations");
-    }
-    bool getAutoMapLocations() const { return autoMapLocations; }
-    void setInvertY(bool invert)
-    {
-        invertY = invert;
-        if (invertY)
-            processes.addProcess("invert-y");
-    }
-    bool getInvertY() const { return invertY; }
-
-    void setFlattenUniformArrays(bool flatten)
-    {
-        flattenUniformArrays = flatten;
-        if (flattenUniformArrays)
-            processes.addProcess("flatten-uniform-arrays");
-    }
-    bool getFlattenUniformArrays() const { return flattenUniformArrays; }
-    void setNoStorageFormat(bool b)
-    {
-        useUnknownFormat = b;
-        if (useUnknownFormat)
-            processes.addProcess("no-storage-format");
-    }
-    bool getNoStorageFormat() const { return useUnknownFormat; }
-    void setUseStorageBuffer()
-    {
-        useStorageBuffer = true;
-        processes.addProcess("use-storage-buffer");
-    }
-    bool usingStorageBuffer() const { return useStorageBuffer; }
-    void setUseVulkanMemoryModel()
-    {
-        useVulkanMemoryModel = true;
-        processes.addProcess("use-vulkan-memory-model");
-    }
-    bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
-    void setUsePhysicalStorageBuffer()
-    {
-        usePhysicalStorageBuffer = true;
-    }
-    bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
-    void setUseVariablePointers()
-    {
-        useVariablePointers = true;
-        processes.addProcess("use-variable-pointers");
-    }
-    bool usingVariablePointers() const { return useVariablePointers; }
-
-    template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
-    bool hasCounterBufferName(const TString& name) const {
-        size_t len = strlen(implicitCounterName);
-        return name.size() > len &&
-               name.compare(name.size() - len, len, implicitCounterName) == 0;
-    }
-
-    void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
 
     void setVersion(int v) { version = v; }
     int getVersion() const { return version; }
@@ -476,14 +341,35 @@
     int getNumEntryPoints() const { return numEntryPoints; }
     int getNumErrors() const { return numErrors; }
     void addPushConstantCount() { ++numPushConstants; }
-#ifdef GLSLANG_WEB
-    int getNumPushConstants() const { return 0; }
-    void addShaderRecordNVCount() { }
-    void addTaskNVCount() { }
+    void setLimits(const TBuiltInResource& r) { resources = r; }
+
+    bool postProcess(TIntermNode*, EShLanguage);
+    void removeTree();
+
+    void setEntryPointName(const char* ep)
+    {
+        entryPointName = ep;
+        processes.addProcess("entry-point");
+        processes.addArgument(entryPointName);
+    }
+    void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; }
+    const std::string& getEntryPointName() const { return entryPointName; }
+    const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
+
+    void setInvertY(bool invert)
+    {
+        invertY = invert;
+        if (invertY)
+            processes.addProcess("invert-y");
+    }
+    bool getInvertY() const { return invertY; }
+
+#ifdef ENABLE_HLSL
+    void setSource(EShSource s) { source = s; }
+    EShSource getSource() const { return source; }
 #else
-    int getNumPushConstants() const { return numPushConstants; }
-    void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; }
-    void addTaskNVCount() { ++numTaskNVBlocks; }
+    void setSource(EShSource s) { assert(s == EShSourceGlsl); }
+    EShSource getSource() const { return EShSourceGlsl; }
 #endif
 
     bool isRecursive() const { return recursive; }
@@ -562,6 +448,143 @@
     void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
     void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
 
+    void setUseStorageBuffer()
+    {
+        useStorageBuffer = true;
+        processes.addProcess("use-storage-buffer");
+    }
+    bool usingStorageBuffer() const { return useStorageBuffer; }
+    void setDepthReplacing() { depthReplacing = true; }
+    bool isDepthReplacing() const { return depthReplacing; }
+
+#ifdef GLSLANG_WEB
+    void output(TInfoSink&, bool tree) { }
+
+    bool getXfbMode() const { return false; }
+    bool isMultiStream() const { return false; }
+    TLayoutGeometry getOutputPrimitive() const { return ElgNone; }
+    bool getPostDepthCoverage() const { return false; }
+    bool getEarlyFragmentTests() const { return false; }
+    TLayoutDepth getDepth() const { return EldNone; }
+    bool getPixelCenterInteger() const { return false; }
+    void setOriginUpperLeft() { }
+    bool getOriginUpperLeft() const { return true; }
+    TInterlockOrdering getInterlockOrdering() const { return EioNone; }
+
+    bool getAutoMapBindings() const { return false; }
+    bool getAutoMapLocations() const { return false; }
+    int getNumPushConstants() const { return 0; }
+    void addShaderRecordNVCount() { }
+    void addTaskNVCount() { }
+    void setUseVulkanMemoryModel() { }
+    bool usingVulkanMemoryModel() const { return false; }
+    bool usingPhysicalStorageBuffer() const { return false; }
+    bool usingVariablePointers() const { return false; }
+#else
+    void output(TInfoSink&, bool tree);
+
+    void setShiftBinding(TResourceType res, unsigned int shift)
+    {
+        shiftBinding[res] = shift;
+
+        const char* name = getResourceName(res);
+        if (name != nullptr)
+            processes.addIfNonZero(name, shift);
+    }
+
+    unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
+
+    void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set)
+    {
+        if (shift == 0) // ignore if there's no shift: it's a no-op.
+            return;
+
+        shiftBindingForSet[res][set] = shift;
+
+        const char* name = getResourceName(res);
+        if (name != nullptr) {
+            processes.addProcess(name);
+            processes.addArgument(shift);
+            processes.addArgument(set);
+        }
+    }
+
+    int getShiftBindingForSet(TResourceType res, unsigned int set) const
+    {
+        const auto shift = shiftBindingForSet[res].find(set);
+        return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
+    }
+    bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
+
+    void setResourceSetBinding(const std::vector<std::string>& shift)
+    {
+        resourceSetBinding = shift;
+        if (shift.size() > 0) {
+            processes.addProcess("resource-set-binding");
+            for (int s = 0; s < (int)shift.size(); ++s)
+                processes.addArgument(shift[s]);
+        }
+    }
+    const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
+    void setAutoMapBindings(bool map)
+    {
+        autoMapBindings = map;
+        if (autoMapBindings)
+            processes.addProcess("auto-map-bindings");
+    }
+    bool getAutoMapBindings() const { return autoMapBindings; }
+    void setAutoMapLocations(bool map)
+    {
+        autoMapLocations = map;
+        if (autoMapLocations)
+            processes.addProcess("auto-map-locations");
+    }
+    bool getAutoMapLocations() const { return autoMapLocations; }
+
+    void setFlattenUniformArrays(bool flatten)
+    {
+        flattenUniformArrays = flatten;
+        if (flattenUniformArrays)
+            processes.addProcess("flatten-uniform-arrays");
+    }
+    bool getFlattenUniformArrays() const { return flattenUniformArrays; }
+    void setNoStorageFormat(bool b)
+    {
+        useUnknownFormat = b;
+        if (useUnknownFormat)
+            processes.addProcess("no-storage-format");
+    }
+    bool getNoStorageFormat() const { return useUnknownFormat; }
+    void setUseVulkanMemoryModel()
+    {
+        useVulkanMemoryModel = true;
+        processes.addProcess("use-vulkan-memory-model");
+    }
+    bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
+    void setUsePhysicalStorageBuffer()
+    {
+        usePhysicalStorageBuffer = true;
+    }
+    bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
+    void setUseVariablePointers()
+    {
+        useVariablePointers = true;
+        processes.addProcess("use-variable-pointers");
+    }
+    bool usingVariablePointers() const { return useVariablePointers; }
+
+    template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
+    bool hasCounterBufferName(const TString& name) const {
+        size_t len = strlen(implicitCounterName);
+        return name.size() > len &&
+               name.compare(name.size() - len, len, implicitCounterName) == 0;
+    }
+
+    void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
+    int getNumPushConstants() const { return numPushConstants; }
+    void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; }
+    void addTaskNVCount() { ++numTaskNVBlocks; }
+
     bool setInvocations(int i)
     {
         if (invocations != TQualifier::layoutNotSet)
@@ -631,7 +654,6 @@
         return true;
     }
     int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; }
-
     void setXfbMode() { xfbMode = true; }
     bool getXfbMode() const { return xfbMode; }
     void setMultiStream() { multiStream = true; }
@@ -644,14 +666,10 @@
         return true;
     }
     TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; }
-    void setOriginUpperLeft() { originUpperLeft = true; }
-    bool getOriginUpperLeft() const { return originUpperLeft; }
-    void setPixelCenterInteger() { pixelCenterInteger = true; }
-    bool getPixelCenterInteger() const { return pixelCenterInteger; }
-    void setEarlyFragmentTests() { earlyFragmentTests = true; }
-    bool getEarlyFragmentTests() const { return earlyFragmentTests; }
     void setPostDepthCoverage() { postDepthCoverage = true; }
     bool getPostDepthCoverage() const { return postDepthCoverage; }
+    void setEarlyFragmentTests() { earlyFragmentTests = true; }
+    bool getEarlyFragmentTests() const { return earlyFragmentTests; }
     bool setDepth(TLayoutDepth d)
     {
         if (depthLayout != EldNone)
@@ -660,8 +678,66 @@
         return true;
     }
     TLayoutDepth getDepth() const { return depthLayout; }
-    void setDepthReplacing() { depthReplacing = true; }
-    bool isDepthReplacing() const { return depthReplacing; }
+    void setOriginUpperLeft() { originUpperLeft = true; }
+    bool getOriginUpperLeft() const { return originUpperLeft; }
+    void setPixelCenterInteger() { pixelCenterInteger = true; }
+    bool getPixelCenterInteger() const { return pixelCenterInteger; }
+    void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
+    unsigned int getBlendEquations() const { return blendEquations; }
+    bool setXfbBufferStride(int buffer, unsigned stride)
+    {
+        if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd)
+            return xfbBuffers[buffer].stride == stride;
+        xfbBuffers[buffer].stride = stride;
+        return true;
+    }
+    unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
+    int addXfbBufferOffset(const TType&);
+    unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
+    unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const;
+    void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
+    bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
+    void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
+    bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
+    void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
+    ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
+    bool setPrimitives(int m)
+    {
+        if (primitives != TQualifier::layoutNotSet)
+            return primitives == m;
+        primitives = m;
+        return true;
+    }
+    int getPrimitives() const { return primitives; }
+    const char* addSemanticName(const TString& name)
+    {
+        return semanticNameSet.insert(name).first->c_str();
+    }
+    void addUniformLocationOverride(const char* nameStr, int location)
+    {
+        std::string name = nameStr;
+        uniformLocationOverrides[name] = location;
+    }
+
+    int getUniformLocationOverride(const char* nameStr) const
+    {
+        std::string name = nameStr;
+        auto pos = uniformLocationOverrides.find(name);
+        if (pos == uniformLocationOverrides.end())
+            return -1;
+        else
+            return pos->second;
+    }
+
+    void setUniformLocationBase(int base) { uniformLocationBase = base; }
+    int getUniformLocationBase() const { return uniformLocationBase; }
+
+    void setNeedsLegalization() { needToLegalize = true; }
+    bool needsLegalization() const { return needToLegalize; }
+
+    void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
+    bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
+#endif
 
 #ifdef ENABLE_HLSL
     void setHlslFunctionality1() { hlslFunctionality1 = true; }
@@ -686,9 +762,6 @@
     bool usingHlslIoMapping() { return false; }
 #endif
 
-    void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
-    unsigned int getBlendEquations() const { return blendEquations; }
-
     void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
     void merge(TInfoSink&, TIntermediate&);
     void finalCheck(TInfoSink&, bool keepUncalled);
@@ -703,19 +776,6 @@
     static int computeTypeLocationSize(const TType&, EShLanguage);
     static int computeTypeUniformLocationSize(const TType&);
 
-#ifndef GLSLANG_WEB
-    bool setXfbBufferStride(int buffer, unsigned stride)
-    {
-        if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd)
-            return xfbBuffers[buffer].stride == stride;
-        xfbBuffers[buffer].stride = stride;
-        return true;
-    }
-    unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
-    int addXfbBufferOffset(const TType&);
-    unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
-    unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const;
-#endif
     static int getBaseAlignmentScalar(const TType&, int& size);
     static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
     static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);
@@ -726,28 +786,8 @@
     static int getBlockSize(const TType& blockType);
     static int computeBufferReferenceTypeSize(const TType&);
     bool promote(TIntermOperator*);
-
-#ifndef GLSLANG_WEB
-    void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
-    bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
-    void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
-    bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
-    void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
-    ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
-    bool setPrimitives(int m)
-    {
-        if (primitives != TQualifier::layoutNotSet)
-            return primitives == m;
-        primitives = m;
-        return true;
-    }
-    int getPrimitives() const { return primitives; }
-#endif
-
-    const char* addSemanticName(const TString& name)
-    {
-        return semanticNameSet.insert(name).first->c_str();
-    }
+    void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; }
+    bool getNanMinMaxClamp() const { return nanMinMaxClamp; }
 
     void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; }
     const std::string& getSourceFile() const { return sourceFile; }
@@ -764,37 +804,6 @@
     void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
     const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
 
-    void addUniformLocationOverride(const char* nameStr, int location)
-    {
-        std::string name = nameStr;
-        uniformLocationOverrides[name] = location;
-    }
-
-    int getUniformLocationOverride(const char* nameStr) const
-    {
-        std::string name = nameStr;
-        auto pos = uniformLocationOverrides.find(name);
-        if (pos == uniformLocationOverrides.end())
-            return -1;
-        else
-            return pos->second;
-    }
-
-    void setUniformLocationBase(int base) { uniformLocationBase = base; }
-    int getUniformLocationBase() const { return uniformLocationBase; }
-
-    void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; }
-    bool getNanMinMaxClamp() const { return nanMinMaxClamp; }
-
-    void setNeedsLegalization() { needToLegalize = true; }
-    bool needsLegalization() const { return needToLegalize; }
-
-    void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
-    bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
-
-    const char* const implicitThisName;
-    const char* const implicitCounterName;
-
     // Certain explicit conversions are allowed conditionally
 #ifdef GLSLANG_WEB
     bool getArithemeticInt8Enabled() const { return false; }
@@ -849,19 +858,25 @@
     bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
     TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
     std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
-#ifdef GLSLANG_WEB
-    bool extensionRequested(const char *extension) const { return false; }
-#else
-    // I think this function should go away.
+
+    // JohnK: I think this function should go away.
     // This data structure is just a log to pass on to back ends.
     // Versioning and extensions are handled in Version.cpp, with a rich
     // set of functions for querying stages, versions, extension enable/disabled, etc.
+#ifdef GLSLANG_WEB
+    bool extensionRequested(const char *extension) const { return false; }
+#else
     bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
 #endif
+
     static const char* getResourceName(TResourceType);
 
     const EShLanguage language;  // stage, known at construction time
 #ifdef ENABLE_HLSL
+public:
+    const char* const implicitThisName;
+    const char* const implicitCounterName;
+protected:
     EShSource source;            // source language, known a bit later
 #endif
     std::string entryPointName;
@@ -879,6 +894,12 @@
     int numErrors;
     int numPushConstants;
     bool recursive;
+    bool invertY;
+    bool useStorageBuffer;
+    bool nanMinMaxClamp;            // true if desiring min/max/clamp to favor non-NaN over NaN
+    bool depthReplacing;
+#ifndef GLSLANG_WEB
+    bool useVulkanMemoryModel;
     int invocations;
     int vertices;
     TLayoutGeometry inputPrimitive;
@@ -894,21 +915,17 @@
     bool earlyFragmentTests;
     bool postDepthCoverage;
     TLayoutDepth depthLayout;
-    bool depthReplacing;
     bool hlslFunctionality1;
     int blendEquations;        // an 'or'ing of masks of shifts of TBlendEquationShift
     bool xfbMode;
     std::vector<TXfbBuffer> xfbBuffers;     // all the data we need to track per xfb buffer
     bool multiStream;
-
-#ifndef GLSLANG_WEB
     bool layoutOverrideCoverage;
     bool geoPassthroughEXT;
     int numShaderRecordNVBlocks;
     ComputeDerivativeMode computeDerivativeMode;
     int primitives;
     int numTaskNVBlocks;
-#endif
 
     // Base shift values
     std::array<unsigned int, EResCount> shiftBinding;
@@ -919,23 +936,29 @@
     std::vector<std::string> resourceSetBinding;
     bool autoMapBindings;
     bool autoMapLocations;
-    bool invertY;
     bool flattenUniformArrays;
     bool useUnknownFormat;
     bool hlslOffsets;
-    bool useStorageBuffer;
-    bool useVulkanMemoryModel;
     bool hlslIoMapping;
     bool useVariablePointers;
 
-    std::set<TString> ioAccessed;           // set of names of statically read/written I/O that might need extra checking
-    std::vector<TIoRange> usedIo[4];        // sets of used locations, one for each of in, out, uniform, and buffers
-    std::vector<TOffsetRange> usedAtomics;  // sets of bindings used by atomic counters
-    std::unordered_set<int> usedConstantId; // specialization constant ids used
     std::set<TString> semanticNameSet;
 
     EShTextureSamplerTransformMode textureSamplerTransformMode;
 
+    bool needToLegalize;
+    bool binaryDoubleOutput;
+    bool usePhysicalStorageBuffer;
+
+    std::unordered_map<std::string, int> uniformLocationOverrides;
+    int uniformLocationBase;
+#endif
+
+    std::unordered_set<int> usedConstantId; // specialization constant ids used
+    std::vector<TOffsetRange> usedAtomics;  // sets of bindings used by atomic counters
+    std::vector<TIoRange> usedIo[4];        // sets of used locations, one for each of in, out, uniform, and buffers
+    // set of names of statically read/written I/O that might need extra checking
+    std::set<TString> ioAccessed;
     // source code of shader, useful as part of debug information
     std::string sourceFile;
     std::string sourceText;
@@ -946,14 +969,6 @@
     // for OpModuleProcessed, or equivalent
     TProcesses processes;
 
-    bool needToLegalize;
-    bool binaryDoubleOutput;
-    bool usePhysicalStorageBuffer;
-
-    std::unordered_map<std::string, int> uniformLocationOverrides;
-    int uniformLocationBase;
-    bool nanMinMaxClamp;            // true if desiring min/max/clamp to favor non-NaN over NaN
-
 private:
     void operator=(TIntermediate&); // prevent assignments
 };