diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 969c091..8cdc032 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1,2578 +1,2578 @@
-//
-//Copyright (C) 2014 LunarG, Inc.
-//
-//All rights reserved.
-//
-//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 3Dlabs Inc. Ltd. 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 HOLDERS 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.
-
-//
-// Author: John Kessenich, LunarG
-//
-// Visit the nodes in the glslang intermediate tree representation to
-// translate them to SPIR-V.
-//
-
-#include "spirv.h"
-#include "GlslangToSpv.h"
-#include "SpvBuilder.h"
-#include "GLSL450Lib.h"
-
-// Glslang includes
-#include "glslang/MachineIndependent/localintermediate.h"
-#include "glslang/MachineIndependent/SymbolTable.h"
-
-#include <string>
-#include <map>
-#include <list>
-#include <vector>
-#include <stack>
-#include <fstream>
-
-namespace {
-
-const int GlslangMagic = 0x51a;
-
-//
-// The main holder of information for translating glslang to SPIR-V.
-//
-// Derives from the AST walking base class.
-//
-class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
-public:
-    TGlslangToSpvTraverser(const glslang::TIntermediate*);
-    virtual ~TGlslangToSpvTraverser();
-
-    bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*);
-    bool visitBinary(glslang::TVisit, glslang::TIntermBinary*);
-    void visitConstantUnion(glslang::TIntermConstantUnion*);
-    bool visitSelection(glslang::TVisit, glslang::TIntermSelection*);
-    bool visitSwitch(glslang::TVisit, glslang::TIntermSwitch*);
-    void visitSymbol(glslang::TIntermSymbol* symbol);
-    bool visitUnary(glslang::TVisit, glslang::TIntermUnary*);
-    bool visitLoop(glslang::TVisit, glslang::TIntermLoop*);
-    bool visitBranch(glslang::TVisit visit, glslang::TIntermBranch*);
-
-    void dumpSpv(std::vector<unsigned int>& out) { builder.dump(out); }
-
-protected:
-    spv::Id createSpvVariable(const glslang::TIntermSymbol*);
-    spv::Id getSampledType(const glslang::TSampler&);
-    spv::Id convertGlslangToSpvType(const glslang::TType& type);
-
-    bool isShaderEntrypoint(const glslang::TIntermAggregate* node);
-    void makeFunctions(const glslang::TIntermSequence&);
-    void makeGlobalInitializers(const glslang::TIntermSequence&);
-    void visitFunctions(const glslang::TIntermSequence&);
-    void handleFunctionEntry(const glslang::TIntermAggregate* node);
-    void translateArguments(const glslang::TIntermSequence& glslangArguments, std::vector<spv::Id>& arguments);
-    spv::Id handleBuiltInFunctionCall(const glslang::TIntermAggregate*);
-    spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*);
-
-    spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true);
-    spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, bool isFloat);
-    spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destTypeId, spv::Id operand);
-    spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
-    spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands);
-    spv::Id createNoArgOperation(glslang::TOperator op);
-    spv::Id getSymbolId(const glslang::TIntermSymbol* node);
-    void addDecoration(spv::Id id, spv::Decoration dec);
-    void addMemberDecoration(spv::Id id, int member, spv::Decoration dec);
-    spv::Id createSpvConstant(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst);
-
-    spv::Function* shaderEntry;
-    int sequenceDepth;
-
-    // There is a 1:1 mapping between a spv builder and a module; this is thread safe
-    spv::Builder builder;
-    bool inMain;
-    bool mainTerminated;
-    bool linkageOnly;
-    const glslang::TIntermediate* glslangIntermediate;
-    spv::Id stdBuiltins;
-
-    std::map<int, spv::Id> symbolValues;
-    std::set<int> constReadOnlyParameters;  // set of formal function parameters that have glslang qualifier constReadOnly, so we know they are not local function "const" that are write-once
-    std::map<std::string, spv::Function*> functionMap;
-    std::map<const glslang::TTypeList*, spv::Id> structMap;
-    std::map<const glslang::TTypeList*, std::vector<int> > memberRemapper;  // for mapping glslang block indices to spv indices (e.g., due to hidden members)
-    std::stack<bool> breakForLoop;  // false means break for switch
-    std::stack<glslang::TIntermTyped*> loopTerminal;  // code from the last part of a for loop: for(...; ...; terminal), needed for e.g., continue };
-};
-
-//
-// Helper functions for translating glslang representations to SPIR-V enumerants.
-//
-
-// Translate glslang profile to SPIR-V source language.
-spv::SourceLanguage TranslateSourceLanguage(EProfile profile)
-{
-    switch (profile) {
-    case ENoProfile:
-    case ECoreProfile:
-    case ECompatibilityProfile:
-        return spv::SourceLanguageGLSL;
-    case EEsProfile:
-        return spv::SourceLanguageESSL;
-    default:
-        return spv::SourceLanguageUnknown;
-    }
-}
-
-// Translate glslang language (stage) to SPIR-V execution model.
-spv::ExecutionModel TranslateExecutionModel(EShLanguage stage)
-{
-    switch (stage) {
-    case EShLangVertex:           return spv::ExecutionModelVertex;
-    case EShLangTessControl:      return spv::ExecutionModelTessellationControl;
-    case EShLangTessEvaluation:   return spv::ExecutionModelTessellationEvaluation;
-    case EShLangGeometry:         return spv::ExecutionModelGeometry;
-    case EShLangFragment:         return spv::ExecutionModelFragment;
-    case EShLangCompute:          return spv::ExecutionModelGLCompute;
-    default:
-        spv::MissingFunctionality("GLSL stage");
-        return spv::ExecutionModelFragment;
-    }
-}
-
-// Translate glslang type to SPIR-V storage class.
-spv::StorageClass TranslateStorageClass(const glslang::TType& type)
-{
-    if (type.getQualifier().isPipeInput())
-        return spv::StorageClassInput;
-    else if (type.getQualifier().isPipeOutput())
-        return spv::StorageClassOutput;
-    else if (type.getQualifier().isUniformOrBuffer()) {
-        if (type.getBasicType() == glslang::EbtBlock)
-            return spv::StorageClassUniform;
-        else
-            return spv::StorageClassUniformConstant;
-        // TODO: how are we distuingishing between default and non-default non-writable uniforms?  Do default uniforms even exist?
-    } else {
-        switch (type.getQualifier().storage) {
-        case glslang::EvqShared:        return spv::StorageClassWorkgroupLocal;  break;
-        case glslang::EvqGlobal:        return spv::StorageClassPrivateGlobal;
-        case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
-        case glslang::EvqTemporary:     return spv::StorageClassFunction;
-        default: 
-            spv::MissingFunctionality("unknown glslang storage class");
-            return spv::StorageClassFunction;
-        }
-    }
-}
-
-// Translate glslang sampler type to SPIR-V dimensionality.
-spv::Dim TranslateDimensionality(const glslang::TSampler& sampler)
-{
-    switch (sampler.dim) {
-    case glslang::Esd1D:     return spv::Dim1D;
-    case glslang::Esd2D:     return spv::Dim2D;
-    case glslang::Esd3D:     return spv::Dim3D;
-    case glslang::EsdCube:   return spv::DimCube;
-    case glslang::EsdRect:   return spv::DimRect;
-    case glslang::EsdBuffer: return spv::DimBuffer;
-    default:
-        spv::MissingFunctionality("unknown sampler dimension");
-        return spv::Dim2D;
-    }
-}
-
-// Translate glslang type to SPIR-V precision decorations.
-spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
-{
-    switch (type.getQualifier().precision) {
-    case glslang::EpqLow:    return spv::DecorationPrecisionLow;
-    case glslang::EpqMedium: return spv::DecorationPrecisionMedium;
-    case glslang::EpqHigh:   return spv::DecorationPrecisionHigh;
-    default:
-        return spv::NoPrecision;
-    }
-}
-
-// Translate glslang type to SPIR-V block decorations.
-spv::Decoration TranslateBlockDecoration(const glslang::TType& type)
-{
-    if (type.getBasicType() == glslang::EbtBlock) {
-        switch (type.getQualifier().storage) {
-        case glslang::EvqUniform:      return spv::DecorationBlock;
-        case glslang::EvqBuffer:       return spv::DecorationBufferBlock;
-        case glslang::EvqVaryingIn:    return spv::DecorationBlock;
-        case glslang::EvqVaryingOut:   return spv::DecorationBlock;
-        default:
-            spv::MissingFunctionality("kind of block");
-            break;
-        }
-    }
-
-    return (spv::Decoration)spv::BadValue;
-}
-
-// Translate glslang type to SPIR-V layout decorations.
-spv::Decoration TranslateLayoutDecoration(const glslang::TType& type)
-{
-    if (type.isMatrix()) {
-        switch (type.getQualifier().layoutMatrix) {
-        case glslang::ElmRowMajor:
-            return spv::DecorationRowMajor;
-        default:
-            return spv::DecorationColMajor;
-        }
-    } else {
-        switch (type.getBasicType()) {
-        default:
-            return (spv::Decoration)spv::BadValue;
-            break;
-        case glslang::EbtBlock:
-            switch (type.getQualifier().storage) {
-            case glslang::EvqUniform:
-            case glslang::EvqBuffer:
-                switch (type.getQualifier().layoutPacking) {
-                case glslang::ElpShared:  return spv::DecorationGLSLShared;
-                case glslang::ElpStd140:  return spv::DecorationGLSLStd140;
-                case glslang::ElpStd430:  return spv::DecorationGLSLStd430;
-                case glslang::ElpPacked:  return spv::DecorationGLSLPacked;
-                default:
-                    spv::MissingFunctionality("uniform block layout");
-                    return spv::DecorationGLSLShared;
-                }
-            case glslang::EvqVaryingIn:
-            case glslang::EvqVaryingOut:
-                if (type.getQualifier().layoutPacking != glslang::ElpNone)
-                    spv::MissingFunctionality("in/out block layout");
-                return (spv::Decoration)spv::BadValue;
-            default:
-                spv::MissingFunctionality("block storage qualification");
-                return (spv::Decoration)spv::BadValue;
-            }
-        }
-    }
-}
-
-// Translate glslang type to SPIR-V interpolation decorations.
-spv::Decoration TranslateInterpolationDecoration(const glslang::TType& type)
-{
-    if (type.getQualifier().smooth)
-        return spv::DecorationSmooth;
-    if (type.getQualifier().nopersp)
-        return spv::DecorationNoperspective;
-    else if (type.getQualifier().patch)
-        return spv::DecorationPatch;
-    else if (type.getQualifier().flat)
-        return spv::DecorationFlat;
-    else if (type.getQualifier().centroid)
-        return spv::DecorationCentroid;
-    else if (type.getQualifier().sample)
-        return spv::DecorationSample;
-    else
-        return (spv::Decoration)spv::BadValue;
-}
-
-// If glslang type is invaraiant, return SPIR-V invariant decoration.
-spv::Decoration TranslateInvariantDecoration(const glslang::TType& type)
-{
-    if (type.getQualifier().invariant)
-        return spv::DecorationInvariant;
-    else
-        return (spv::Decoration)spv::BadValue;
-}
-
-// Translate glslang built-in variable to SPIR-V built in decoration.
-spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn)
-{
-    switch (builtIn) {
-    case glslang::EbvPosition:             return spv::BuiltInPosition;
-    case glslang::EbvPointSize:            return spv::BuiltInPointSize;
-    case glslang::EbvClipVertex:           return spv::BuiltInClipVertex;
-    case glslang::EbvClipDistance:         return spv::BuiltInClipDistance;
-    case glslang::EbvCullDistance:         return spv::BuiltInCullDistance;
-    case glslang::EbvVertexId:             return spv::BuiltInVertexId;
-    case glslang::EbvInstanceId:           return spv::BuiltInInstanceId;
-    case glslang::EbvPrimitiveId:          return spv::BuiltInPrimitiveId;
-    case glslang::EbvInvocationId:         return spv::BuiltInInvocationId;
-    case glslang::EbvLayer:                return spv::BuiltInLayer;
-    case glslang::EbvViewportIndex:        return spv::BuiltInViewportIndex;
-    case glslang::EbvTessLevelInner:       return spv::BuiltInTessLevelInner;
-    case glslang::EbvTessLevelOuter:       return spv::BuiltInTessLevelOuter;
-    case glslang::EbvTessCoord:            return spv::BuiltInTessCoord;
-    case glslang::EbvPatchVertices:        return spv::BuiltInPatchVertices;
-    case glslang::EbvFragCoord:            return spv::BuiltInFragCoord;
-    case glslang::EbvPointCoord:           return spv::BuiltInPointCoord;
-    case glslang::EbvFace:                 return spv::BuiltInFrontFacing;
-    case glslang::EbvSampleId:             return spv::BuiltInSampleId;
-    case glslang::EbvSamplePosition:       return spv::BuiltInSamplePosition;
-    case glslang::EbvSampleMask:           return spv::BuiltInSampleMask;
-    case glslang::EbvFragColor:            return spv::BuiltInFragColor;
-    case glslang::EbvFragData:             return spv::BuiltInFragColor;
-    case glslang::EbvFragDepth:            return spv::BuiltInFragDepth;
-    case glslang::EbvHelperInvocation:     return spv::BuiltInHelperInvocation;
-    case glslang::EbvNumWorkGroups:        return spv::BuiltInNumWorkgroups;
-    case glslang::EbvWorkGroupSize:        return spv::BuiltInWorkgroupSize;
-    case glslang::EbvWorkGroupId:          return spv::BuiltInWorkgroupId;
-    case glslang::EbvLocalInvocationId:    return spv::BuiltInLocalInvocationId;
-    case glslang::EbvLocalInvocationIndex: return spv::BuiltInLocalInvocationIndex;
-    case glslang::EbvGlobalInvocationId:   return spv::BuiltInGlobalInvocationId;
-    default:                               return (spv::BuiltIn)spv::BadValue;
-    }
-}
-
-//
-// Implement the TGlslangToSpvTraverser class.
-//
-
-TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate)
-    : TIntermTraverser(true, false, true), shaderEntry(0), sequenceDepth(0),
-      builder(GlslangMagic),
-      inMain(false), mainTerminated(false), linkageOnly(false),
-      glslangIntermediate(glslangIntermediate)
-{
-    spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage());
-
-    builder.clearAccessChain();
-    builder.setSource(TranslateSourceLanguage(glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
-    stdBuiltins = builder.import("GLSL.std.450");
-    builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
-    shaderEntry = builder.makeMain();
-    builder.addEntryPoint(executionModel, shaderEntry);
-
-    // Add the source extensions
-    const std::set<std::string>& sourceExtensions = glslangIntermediate->getRequestedExtensions();
-    for (std::set<std::string>::const_iterator it = sourceExtensions.begin(); it != sourceExtensions.end(); ++it)
-        builder.addSourceExtension(it->c_str());
-
-    // Add the top-level modes for this shader.
-
-    if (glslangIntermediate->getXfbMode())
-        builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb);
-
-    unsigned int mode;
-    switch (glslangIntermediate->getStage()) {
-    case EShLangVertex:
-        break;
-
-    case EShLangTessControl:
-        builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
-        break;
-
-    case EShLangTessEvaluation:
-        switch (glslangIntermediate->getInputPrimitive()) {
-        case glslang::ElgTriangles:           mode = spv::ExecutionModeInputTriangles;     break;
-        case glslang::ElgQuads:               mode = spv::ExecutionModeInputQuads;         break;
-        case glslang::ElgIsolines:            mode = spv::ExecutionModeInputIsolines;      break;
-        default:                              mode = spv::BadValue;    break;
-        }
-        if (mode != spv::BadValue)
-            builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
-
-        // TODO
-        //builder.addExecutionMode(spv::VertexSpacingMdName, glslangIntermediate->getVertexSpacing());
-        //builder.addExecutionMode(spv::VertexOrderMdName, glslangIntermediate->getVertexOrder());
-        //builder.addExecutionMode(spv::PointModeMdName, glslangIntermediate->getPointMode());
-        break;
-
-    case EShLangGeometry:
-        switch (glslangIntermediate->getInputPrimitive()) {
-        case glslang::ElgPoints:             mode = spv::ExecutionModeInputPoints;             break;
-        case glslang::ElgLines:              mode = spv::ExecutionModeInputLines;              break;
-        case glslang::ElgLinesAdjacency:     mode = spv::ExecutionModeInputLinesAdjacency;     break;
-        case glslang::ElgTriangles:          mode = spv::ExecutionModeInputTriangles;          break;
-        case glslang::ElgTrianglesAdjacency: mode = spv::ExecutionModeInputTrianglesAdjacency; break;
-        default:                             mode = spv::BadValue;         break;
-        }
-        if (mode != spv::BadValue)
-            builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
-        builder.addExecutionMode(shaderEntry, spv::ExecutionModeInvocations, glslangIntermediate->getInvocations());
-
-        switch (glslangIntermediate->getOutputPrimitive()) {
-        case glslang::ElgPoints:        mode = spv::ExecutionModeOutputPoints;                 break;
-        case glslang::ElgLineStrip:     mode = spv::ExecutionModeOutputLineStrip;              break;
-        case glslang::ElgTriangleStrip: mode = spv::ExecutionModeOutputTriangleStrip;          break;
-        default:                        mode = spv::BadValue;              break;
-        }
-        if (mode != spv::BadValue)
-            builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
-        builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
-        break;
-
-    case EShLangFragment:
-        if (glslangIntermediate->getPixelCenterInteger())
-            builder.addExecutionMode(shaderEntry, spv::ExecutionModePixelCenterInteger);
-        if (glslangIntermediate->getOriginUpperLeft())
-            builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginUpperLeft);
-        break;
-
-    case EShLangCompute:
-        break;
-
-    default:
-        break;
-    }
-
-}
-
-TGlslangToSpvTraverser::~TGlslangToSpvTraverser()
-{
-    if (! mainTerminated) {
-        spv::Block* lastMainBlock = shaderEntry->getLastBlock();
-        builder.setBuildPoint(lastMainBlock);
-        builder.leaveFunction(true);
-    }
-}
-
-//
-// Implement the traversal functions.
-//
-// Return true from interior nodes to have the external traversal
-// continue on to children.  Return false if children were
-// already processed.
-//
-
-//
-// Symbols can turn into 
-//  - uniform/input reads
-//  - output writes
-//  - complex lvalue base setups:  foo.bar[3]....  , where we see foo and start up an access chain
-//  - something simple that degenerates into the last bullet
-//
-void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
-{
-    // getSymbolId() will set up all the IO decorations on the first call.
-    // Formal function parameters were mapped during makeFunctions().
-    spv::Id id = getSymbolId(symbol);
-    
-    if (! linkageOnly) {
-        // Prepare to generate code for the access
-
-        // L-value chains will be computed left to right.  We're on the symbol now,
-        // which is the left-most part of the access chain, so now is "clear" time,
-        // followed by setting the base.
-        builder.clearAccessChain();
-
-        // For now, we consider all user variables as being in memory, so they are pointers,
-        // except for "const in" arguments to a function, which are an intermediate object.
-        // See comments in handleUserFunctionCall().
-        glslang::TStorageQualifier qualifier = symbol->getQualifier().storage;
-        if (qualifier == glslang::EvqConstReadOnly && constReadOnlyParameters.find(symbol->getId()) != constReadOnlyParameters.end())
-            builder.setAccessChainRValue(id);
-        else
-            builder.setAccessChainLValue(id);
-    }
-}
-
-bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
-{
-    // First, handle special cases
-    switch (node->getOp()) {
-    case glslang::EOpAssign:
-    case glslang::EOpAddAssign:
-    case glslang::EOpSubAssign:
-    case glslang::EOpMulAssign:
-    case glslang::EOpVectorTimesMatrixAssign:
-    case glslang::EOpVectorTimesScalarAssign:
-    case glslang::EOpMatrixTimesScalarAssign:
-    case glslang::EOpMatrixTimesMatrixAssign:
-    case glslang::EOpDivAssign:
-    case glslang::EOpModAssign:
-    case glslang::EOpAndAssign:
-    case glslang::EOpInclusiveOrAssign:
-    case glslang::EOpExclusiveOrAssign:
-    case glslang::EOpLeftShiftAssign:
-    case glslang::EOpRightShiftAssign:
-        // A bin-op assign "a += b" means the same thing as "a = a + b"
-        // where a is evaluated before b. For a simple assignment, GLSL
-        // says to evaluate the left before the right.  So, always, left
-        // node then right node.
-        {
-            // get the left l-value, save it away
-            builder.clearAccessChain();
-            node->getLeft()->traverse(this);
-            spv::Builder::AccessChain lValue = builder.getAccessChain();
-
-            // evaluate the right
-            builder.clearAccessChain();
-            node->getRight()->traverse(this);
-            spv::Id rValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
-
-            if (node->getOp() != glslang::EOpAssign) {
-                // the left is also an r-value
-                builder.setAccessChain(lValue);
-                spv::Id leftRValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType()));
-
-                // do the operation
-                rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()), 
-                                               convertGlslangToSpvType(node->getType()), leftRValue, rValue,
-                                               node->getType().getBasicType());
-
-                // these all need their counterparts in createBinaryOperation()
-                if (rValue == 0)
-                    spv::MissingFunctionality("createBinaryOperation");
-            }
-
-            // store the result
-            builder.setAccessChain(lValue);
-            builder.accessChainStore(rValue);
-
-            // assignments are expressions having an rValue after they are evaluated...
-            builder.clearAccessChain();
-            builder.setAccessChainRValue(rValue);
-        }
-        return false;
-    case glslang::EOpIndexDirect:
-    case glslang::EOpIndexDirectStruct:
-        {
-            // Get the left part of the access chain.
-            node->getLeft()->traverse(this);
-
-            // Add the next element in the chain
-
-            int index = 0;
-            if (node->getRight()->getAsConstantUnion() == 0)
-                spv::MissingFunctionality("direct index without a constant node");
-            else 
-                index = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
-
-            if (node->getLeft()->getBasicType() == glslang::EbtBlock && node->getOp() == glslang::EOpIndexDirectStruct) {
-                // This may be, e.g., an anonymous block-member selection, which generally need
-                // index remapping due to hidden members in anonymous blocks.
-                std::vector<int>& remapper = memberRemapper[node->getLeft()->getType().getStruct()];
-                if (remapper.size() == 0)
-                    spv::MissingFunctionality("block without member remapping");
-                else
-                    index = remapper[index];
-            }
-
-            if (! node->getLeft()->getType().isArray() &&
-                node->getLeft()->getType().isVector() &&
-                node->getOp() == glslang::EOpIndexDirect) {
-                // This is essentially a hard-coded vector swizzle of size 1,
-                // so short circuit the access-chain stuff with a swizzle.
-                std::vector<unsigned> swizzle;
-                swizzle.push_back(node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst());
-                builder.accessChainPushSwizzle(swizzle);
-            } else {
-                // normal case for indexing array or structure or block
-                builder.accessChainPush(builder.makeIntConstant(index), convertGlslangToSpvType(node->getType()));
-            }
-        }
-        return false;
-    case glslang::EOpIndexIndirect:
-        {
-            // Structure or array or vector indirection.
-            // Will use native SPIR-V access-chain for struct and array indirection;
-            // matrices are arrays of vectors, so will also work for a matrix.
-            // Will use the access chain's 'component' for variable index into a vector.
-
-            // This adapter is building access chains left to right.
-            // Set up the access chain to the left.
-            node->getLeft()->traverse(this);
-
-            // save it so that computing the right side doesn't trash it
-            spv::Builder::AccessChain partial = builder.getAccessChain();
-
-            // compute the next index in the chain
-            builder.clearAccessChain();
-            node->getRight()->traverse(this);
-            spv::Id index = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
-
-            // restore the saved access chain
-            builder.setAccessChain(partial);
-
-            if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector())
-                builder.accessChainPushComponent(index);
-            else
-                builder.accessChainPush(index, convertGlslangToSpvType(node->getType()));
-        }
-        return false;
-    case glslang::EOpVectorSwizzle:
-        {
-            node->getLeft()->traverse(this);
-            glslang::TIntermSequence& swizzleSequence = node->getRight()->getAsAggregate()->getSequence();
-            std::vector<unsigned> swizzle;
-            for (int i = 0; i < (int)swizzleSequence.size(); ++i)
-                swizzle.push_back(swizzleSequence[i]->getAsConstantUnion()->getConstArray()[0].getIConst());
-            builder.accessChainPushSwizzle(swizzle);
-        }
-        return false;
-    default:
-        break;
-    }
-
-    // Assume generic binary op...
-
-    // Get the operands
-    builder.clearAccessChain();
-    node->getLeft()->traverse(this);
-    spv::Id left = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType()));
-
-    builder.clearAccessChain();
-    node->getRight()->traverse(this);
-    spv::Id right = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
-
-    spv::Id result;
-    spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
-
-    result = createBinaryOperation(node->getOp(), precision, 
-                                   convertGlslangToSpvType(node->getType()), left, right,
-                                   node->getLeft()->getType().getBasicType());
-
-    if (! result) {
-        spv::MissingFunctionality("glslang binary operation");
-    } else {
-        builder.clearAccessChain();
-        builder.setAccessChainRValue(result);
-
-        return false;
-    }
-
-    return true;
-}
-
-bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node)
-{
-    builder.clearAccessChain();
-    node->getOperand()->traverse(this);
-    spv::Id operand = builder.accessChainLoad(TranslatePrecisionDecoration(node->getOperand()->getType()));
-
-    spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
-
-    // it could be a conversion
-    spv::Id result = createConversion(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand);
-
-    // if not, then possibly an operation
-    if (! result)
-        result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand, node->getBasicType() == glslang::EbtFloat || node->getBasicType() == glslang::EbtDouble);
-
-    if (result) {
-        builder.clearAccessChain();
-        builder.setAccessChainRValue(result);
-
-        return false; // done with this node
-    }
-
-    // it must be a special case, check...
-    switch (node->getOp()) {
-    case glslang::EOpPostIncrement:
-    case glslang::EOpPostDecrement:
-    case glslang::EOpPreIncrement:
-    case glslang::EOpPreDecrement:
-        {
-            // we need the integer value "1" or the floating point "1.0" to add/subtract
-            spv::Id one = node->getBasicType() == glslang::EbtFloat ?
-                                     builder.makeFloatConstant(1.0F) :
-                                     builder.makeIntConstant(1);
-            glslang::TOperator op;
-            if (node->getOp() == glslang::EOpPreIncrement ||
-                node->getOp() == glslang::EOpPostIncrement)
-                op = glslang::EOpAdd;
-            else
-                op = glslang::EOpSub;
-
-            spv::Id result = createBinaryOperation(op, TranslatePrecisionDecoration(node->getType()), 
-                                                     convertGlslangToSpvType(node->getType()), operand, one, 
-                                                     node->getType().getBasicType());
-            if (result == 0)
-                spv::MissingFunctionality("createBinaryOperation for unary");
-
-            // The result of operation is always stored, but conditionally the
-            // consumed result.  The consumed result is always an r-value.
-            builder.accessChainStore(result);
-            builder.clearAccessChain();
-            if (node->getOp() == glslang::EOpPreIncrement ||
-                node->getOp() == glslang::EOpPreDecrement)
-                builder.setAccessChainRValue(result);
-            else
-                builder.setAccessChainRValue(operand);
-        }
-
-        return false;
-
-    case glslang::EOpEmitStreamVertex:
-        builder.createNoResultOp(spv::OpEmitStreamVertex, operand);
-        return false;
-    case glslang::EOpEndStreamPrimitive:
-        builder.createNoResultOp(spv::OpEndStreamPrimitive, operand);
-        return false;
-
-    default:
-        spv::MissingFunctionality("glslang unary");
-        break;
-    }
-
-    return true;
-}
-
-bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TIntermAggregate* node)
-{
-    spv::Id result;
-    glslang::TOperator binOp = glslang::EOpNull;
-    bool reduceComparison = true;
-    bool isMatrix = false;
-    bool noReturnValue = false;
-
-    assert(node->getOp());
-
-    spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
-
-    switch (node->getOp()) {
-    case glslang::EOpSequence:
-    {
-        if (preVisit)
-            ++sequenceDepth;
-        else
-            --sequenceDepth;
-
-        if (sequenceDepth == 1) {
-            // If this is the parent node of all the functions, we want to see them
-            // early, so all call points have actual SPIR-V functions to reference.
-            // In all cases, still let the traverser visit the children for us.
-            makeFunctions(node->getAsAggregate()->getSequence());
-
-            // Also, we want all globals initializers to go into the entry of main(), before
-            // anything else gets there, so visit out of order, doing them all now.
-            makeGlobalInitializers(node->getAsAggregate()->getSequence());
-
-            // Initializers are done, don't want to visit again, but functions link objects need to be processed,
-            // so do them manually.
-            visitFunctions(node->getAsAggregate()->getSequence());
-
-            return false;
-        }
-
-        return true;
-    }
-    case glslang::EOpLinkerObjects:
-    {
-        if (visit == glslang::EvPreVisit)
-            linkageOnly = true;
-        else
-            linkageOnly = false;
-
-        return true;
-    }
-    case glslang::EOpComma:
-    {
-        // processing from left to right naturally leaves the right-most
-        // lying around in the access chain
-        glslang::TIntermSequence& glslangOperands = node->getSequence();
-        for (int i = 0; i < (int)glslangOperands.size(); ++i)
-            glslangOperands[i]->traverse(this);
-
-        return false;
-    }
-    case glslang::EOpFunction:
-        if (visit == glslang::EvPreVisit) {
-            if (isShaderEntrypoint(node)) {
-                inMain = true;
-                builder.setBuildPoint(shaderEntry->getLastBlock());
-            } else {
-                handleFunctionEntry(node);
-            }
-        } else {
-            if (inMain)
-                mainTerminated = true;
-            builder.leaveFunction(inMain);
-            inMain = false;
-        }
-
-        return true;
-    case glslang::EOpParameters:
-        // Parameters will have been consumed by EOpFunction processing, but not
-        // the body, so we still visited the function node's children, making this
-        // child redundant.
-        return false;
-    case glslang::EOpFunctionCall:
-    {
-        if (node->isUserDefined())
-            result = handleUserFunctionCall(node);
-        else
-            result = handleBuiltInFunctionCall(node);
-
-        if (! result) {
-            spv::MissingFunctionality("glslang function call");
-            glslang::TConstUnionArray emptyConsts;
-            int nextConst = 0;
-            result = createSpvConstant(node->getType(), emptyConsts, nextConst);
-        }
-        builder.clearAccessChain();
-        builder.setAccessChainRValue(result);
-
-        return false;
-    }
-    case glslang::EOpConstructMat2x2:
-    case glslang::EOpConstructMat2x3:
-    case glslang::EOpConstructMat2x4:
-    case glslang::EOpConstructMat3x2:
-    case glslang::EOpConstructMat3x3:
-    case glslang::EOpConstructMat3x4:
-    case glslang::EOpConstructMat4x2:
-    case glslang::EOpConstructMat4x3:
-    case glslang::EOpConstructMat4x4:
-    case glslang::EOpConstructDMat2x2:
-    case glslang::EOpConstructDMat2x3:
-    case glslang::EOpConstructDMat2x4:
-    case glslang::EOpConstructDMat3x2:
-    case glslang::EOpConstructDMat3x3:
-    case glslang::EOpConstructDMat3x4:
-    case glslang::EOpConstructDMat4x2:
-    case glslang::EOpConstructDMat4x3:
-    case glslang::EOpConstructDMat4x4:
-        isMatrix = true;
-        // fall through
-    case glslang::EOpConstructFloat:
-    case glslang::EOpConstructVec2:
-    case glslang::EOpConstructVec3:
-    case glslang::EOpConstructVec4:
-    case glslang::EOpConstructDouble:
-    case glslang::EOpConstructDVec2:
-    case glslang::EOpConstructDVec3:
-    case glslang::EOpConstructDVec4:
-    case glslang::EOpConstructBool:
-    case glslang::EOpConstructBVec2:
-    case glslang::EOpConstructBVec3:
-    case glslang::EOpConstructBVec4:
-    case glslang::EOpConstructInt:
-    case glslang::EOpConstructIVec2:
-    case glslang::EOpConstructIVec3:
-    case glslang::EOpConstructIVec4:
-    case glslang::EOpConstructUint:
-    case glslang::EOpConstructUVec2:
-    case glslang::EOpConstructUVec3:
-    case glslang::EOpConstructUVec4:
-    case glslang::EOpConstructStruct:
-    {
-        std::vector<spv::Id> arguments;
-        translateArguments(node->getSequence(), arguments);
-        spv::Id resultTypeId = convertGlslangToSpvType(node->getType());
-        spv::Id constructed;
-        if (node->getOp() == glslang::EOpConstructStruct || node->getType().isArray()) {
-            std::vector<spv::Id> constituents;
-            for (int c = 0; c < (int)arguments.size(); ++c)
-                constituents.push_back(arguments[c]);
-            constructed = builder.createCompositeConstruct(resultTypeId, constituents);
-        } else {
-            if (isMatrix)
-                constructed = builder.createMatrixConstructor(precision, arguments, resultTypeId);
-            else
-                constructed = builder.createConstructor(precision, arguments, resultTypeId);
-        }
-
-        builder.clearAccessChain();
-        builder.setAccessChainRValue(constructed);
-
-        return false;
-    }
-
-    // These six are component-wise compares with component-wise results.
-    // Forward on to createBinaryOperation(), requesting a vector result.
-    case glslang::EOpLessThan:
-    case glslang::EOpGreaterThan:
-    case glslang::EOpLessThanEqual:
-    case glslang::EOpGreaterThanEqual:
-    case glslang::EOpVectorEqual:
-    case glslang::EOpVectorNotEqual:
-    {
-        // Map the operation to a binary
-        binOp = node->getOp();
-        reduceComparison = false;
-        switch (node->getOp()) {
-        case glslang::EOpVectorEqual:     binOp = glslang::EOpVectorEqual;      break;
-        case glslang::EOpVectorNotEqual:  binOp = glslang::EOpVectorNotEqual;   break;
-        default:                          binOp = node->getOp();                break;
-        }
-
-        break;
-    }
-    case glslang::EOpMul:
-        // compontent-wise matrix multiply      
-        binOp = glslang::EOpMul;
-        break;
-    case glslang::EOpOuterProduct:
-        // two vectors multiplied to make a matrix
-        binOp = glslang::EOpOuterProduct;
-        break;
-    case glslang::EOpDot:
-    {
-        // for scalar dot product, use multiply        
-        glslang::TIntermSequence& glslangOperands = node->getSequence();
-        if (! glslangOperands[0]->getAsTyped()->isVector())
-            binOp = glslang::EOpMul;
-        break;
-    }
-    case glslang::EOpMod:
-        // when an aggregate, this is the floating-point mod built-in function,
-        // which can be emitted by the one in createBinaryOperation()
-        binOp = glslang::EOpMod;
-        break;
-    case glslang::EOpArrayLength:
-    {
-        glslang::TIntermTyped* typedNode = node->getSequence()[0]->getAsTyped();
-        assert(typedNode);
-        spv::Id length = builder.makeIntConstant(typedNode->getType().getArraySize());
-
-        builder.clearAccessChain();
-        builder.setAccessChainRValue(length);
-
-        return false;
-    }
-    case glslang::EOpEmitVertex:
-    case glslang::EOpEndPrimitive:
-    case glslang::EOpBarrier:
-    case glslang::EOpMemoryBarrier:
-    case glslang::EOpMemoryBarrierAtomicCounter:
-    case glslang::EOpMemoryBarrierBuffer:
-    case glslang::EOpMemoryBarrierImage:
-    case glslang::EOpMemoryBarrierShared:
-    case glslang::EOpGroupMemoryBarrier:
-        noReturnValue = true;
-        // These all have 0 operands and will naturally finish up in the code below for 0 operands
-        break;
-
-    default:
-        break;
-    }
-
-    //
-    // See if it maps to a regular operation.
-    //
-
-    if (binOp != glslang::EOpNull) {
-        glslang::TIntermTyped* left = node->getSequence()[0]->getAsTyped();
-        glslang::TIntermTyped* right = node->getSequence()[1]->getAsTyped();
-        assert(left && right);
-
-        builder.clearAccessChain();
-        left->traverse(this);
-        spv::Id leftId = builder.accessChainLoad(TranslatePrecisionDecoration(left->getType()));
-
-        builder.clearAccessChain();
-        right->traverse(this);
-        spv::Id rightId = builder.accessChainLoad(TranslatePrecisionDecoration(right->getType()));
-
-        result = createBinaryOperation(binOp, precision, 
-                                       convertGlslangToSpvType(node->getType()), leftId, rightId, 
-                                       left->getType().getBasicType(), reduceComparison);
-
-        // code above should only make binOp that exists in createBinaryOperation
-        if (result == 0)
-            spv::MissingFunctionality("createBinaryOperation for aggregate");
-
-        builder.clearAccessChain();
-        builder.setAccessChainRValue(result);
-
-        return false;
-    }
-
-    glslang::TIntermSequence& glslangOperands = node->getSequence();
-    std::vector<spv::Id> operands;
-    for (int arg = 0; arg < (int)glslangOperands.size(); ++arg) {
-        builder.clearAccessChain();
-        glslangOperands[arg]->traverse(this);
-
-        // special case l-value operands; there are just a few
-        bool lvalue = false;
-        switch (node->getOp()) {
-        //case glslang::EOpFrexp:
-        case glslang::EOpModf:
-            if (arg == 1)
-                lvalue = true;
-            break;
-        //case glslang::EOpUAddCarry:
-        //case glslang::EOpUSubBorrow:
-        //case glslang::EOpUMulExtended:
-        default:
-            break;
-        }
-        if (lvalue)
-            operands.push_back(builder.accessChainGetLValue());
-        else
-            operands.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangOperands[arg]->getAsTyped()->getType())));
-    }
-    switch (glslangOperands.size()) {
-    case 0:
-        result = createNoArgOperation(node->getOp());
-        break;
-    case 1:
-        result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands.front(), node->getType().getBasicType() == glslang::EbtFloat || node->getType().getBasicType() == glslang::EbtDouble);
-        break;
-    default:
-        result = createMiscOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands);
-        break;
-    }
-
-    if (noReturnValue)
-        return false;
-
-    if (! result) {
-        spv::MissingFunctionality("glslang aggregate");
-        return true;
-    } else {
-        builder.clearAccessChain();
-        builder.setAccessChainRValue(result);
-        return false;
-    }
-}
-
-bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang::TIntermSelection* node)
-{
-    // This path handles both if-then-else and ?:
-    // The if-then-else has a node type of void, while
-    // ?: has a non-void node type
-    spv::Id result = 0;
-    if (node->getBasicType() != glslang::EbtVoid) {
-        // don't handle this as just on-the-fly temporaries, because there will be two names
-        // and better to leave SSA to later passes
-        result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
-    }
-
-    // emit the condition before doing anything with selection
-    node->getCondition()->traverse(this);
-
-    // make an "if" based on the value created by the condition
-    spv::Builder::If ifBuilder(builder.accessChainLoad(spv::NoPrecision), builder);
-
-    if (node->getTrueBlock()) {
-        // emit the "then" statement
-        node->getTrueBlock()->traverse(this);
-        if (result)
-            builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getTrueBlock()->getAsTyped()->getType())), result);
-    }
-
-    if (node->getFalseBlock()) {
-        ifBuilder.makeBeginElse();
-        // emit the "else" statement
-        node->getFalseBlock()->traverse(this);
-        if (result)
-            builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getFalseBlock()->getAsTyped()->getType())), result);
-    }
-
-    ifBuilder.makeEndIf();
-
-    if (result) {
-        // GLSL only has r-values as the result of a :?, but
-        // if we have an l-value, that can be more efficient if it will
-        // become the base of a complex r-value expression, because the
-        // next layer copies r-values into memory to use the access-chain mechanism
-        builder.clearAccessChain();
-        builder.setAccessChainLValue(result);
-    }
-
-    return false;
-}
-
-bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::TIntermSwitch* node)
-{
-    // emit and get the condition before doing anything with switch
-    node->getCondition()->traverse(this);
-    spv::Id selector = builder.accessChainLoad(TranslatePrecisionDecoration(node->getCondition()->getAsTyped()->getType()));
-
-    // browse the children to sort out code segments
-    int defaultSegment = -1;
-    std::vector<TIntermNode*> codeSegments;
-    glslang::TIntermSequence& sequence = node->getBody()->getSequence();
-    std::vector<int> caseValues;
-    std::vector<int> valueIndexToSegment(sequence.size());  // note: probably not all are used, it is an overestimate
-    for (glslang::TIntermSequence::iterator c = sequence.begin(); c != sequence.end(); ++c) {
-        TIntermNode* child = *c;
-        if (child->getAsBranchNode() && child->getAsBranchNode()->getFlowOp() == glslang::EOpDefault)
-            defaultSegment = codeSegments.size();
-        else if (child->getAsBranchNode() && child->getAsBranchNode()->getFlowOp() == glslang::EOpCase) {
-            valueIndexToSegment[caseValues.size()] = codeSegments.size();
-            caseValues.push_back(child->getAsBranchNode()->getExpression()->getAsConstantUnion()->getConstArray()[0].getIConst());
-        } else
-            codeSegments.push_back(child);
-    }
-
-    // handle the case where the last code segment is missing, due to no code 
-    // statements between the last case and the end of the switch statement
-    if ((caseValues.size() && (int)codeSegments.size() == valueIndexToSegment[caseValues.size() - 1]) ||
-        (int)codeSegments.size() == defaultSegment)
-        codeSegments.push_back(nullptr);
-
-    // make the switch statement
-    std::vector<spv::Block*> segmentBlocks; // returned, as the blocks allocated in the call
-    builder.makeSwitch(selector, codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, segmentBlocks);
-
-    // emit all the code in the segments
-    breakForLoop.push(false);
-    for (unsigned int s = 0; s < codeSegments.size(); ++s) {
-        builder.nextSwitchSegment(segmentBlocks, s);
-        if (codeSegments[s])
-            codeSegments[s]->traverse(this);
-        else
-            builder.addSwitchBreak();
-    }
-    breakForLoop.pop();
-
-    builder.endSwitch(segmentBlocks);
-
-    return false;
-}
-
-void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node)
-{
-    int nextConst = 0;
-    spv::Id constant = createSpvConstant(node->getType(), node->getConstArray(), nextConst);
-
-    builder.clearAccessChain();
-    builder.setAccessChainRValue(constant);
-}
-
-bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIntermLoop* node)
-{
-    // body emission needs to know what the for-loop terminal is when it sees a "continue"
-    loopTerminal.push(node->getTerminal());
-
-    builder.makeNewLoop();
-
-    bool bodyOut = false;
-    if (! node->testFirst()) {
-        builder.endLoopHeaderWithoutTest();
-        if (node->getBody()) {
-            breakForLoop.push(true);
-            node->getBody()->traverse(this);
-            breakForLoop.pop();
-        }
-        bodyOut = true;
-        builder.createBranchToLoopTest();
-    }
-
-    if (node->getTest()) {
-        node->getTest()->traverse(this);
-        // the AST only contained the test computation, not the branch, we have to add it
-        spv::Id condition = builder.accessChainLoad(TranslatePrecisionDecoration(node->getTest()->getType()));
-        builder.createLoopTestBranch(condition);
-    }
-
-    if (! bodyOut && node->getBody()) {
-        breakForLoop.push(true);
-        node->getBody()->traverse(this);
-        breakForLoop.pop();
-    }
-
-    if (loopTerminal.top())
-        loopTerminal.top()->traverse(this);
-
-    builder.closeLoop();
-
-    loopTerminal.pop();
-
-    return false;
-}
-
-bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::TIntermBranch* node)
-{
-    if (node->getExpression())
-        node->getExpression()->traverse(this);
-
-    switch (node->getFlowOp()) {
-    case glslang::EOpKill:
-        builder.makeDiscard();
-        break;
-    case glslang::EOpBreak:
-        if (breakForLoop.top())
-            builder.createLoopExit();
-        else
-            builder.addSwitchBreak();
-        break;
-    case glslang::EOpContinue:
-        if (loopTerminal.top())
-            loopTerminal.top()->traverse(this);
-        builder.createLoopContinue();
-        break;
-    case glslang::EOpReturn:
-        if (inMain)
-            builder.makeMainReturn();
-        else if (node->getExpression())
-            builder.makeReturn(false, builder.accessChainLoad(TranslatePrecisionDecoration(node->getExpression()->getType())));
-        else
-            builder.makeReturn();
-
-        builder.clearAccessChain();
-        break;
-
-    default:
-        spv::MissingFunctionality("branch type");
-        break;
-    }
-
-    return false;
-}
-
-spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* node)
-{
-    // First, steer off constants, which are not SPIR-V variables, but 
-    // can still have a mapping to a SPIR-V Id.
-    if (node->getQualifier().storage == glslang::EvqConst) {
-        int nextConst = 0;
-        return createSpvConstant(node->getType(), node->getConstArray(), nextConst);
-    }
-
-    // Now, handle actual variables
-    spv::StorageClass storageClass = TranslateStorageClass(node->getType());
-    spv::Id spvType = convertGlslangToSpvType(node->getType());
-
-    const char* name = node->getName().c_str();
-    if (glslang::IsAnonymous(name))
-        name = "";
-
-    return builder.createVariable(storageClass, spvType, name);
-}
-
-// Return type Id of the sampled type.
-spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
-{
-    switch (sampler.type) {
-        case glslang::EbtFloat:    return builder.makeFloatType(32);
-        case glslang::EbtInt:      return builder.makeIntType(32);
-        case glslang::EbtUint:     return builder.makeUintType(32);
-        default:
-            spv::MissingFunctionality("sampled type");
-            return builder.makeFloatType(32);
-    }
-}
-
-// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
-spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type)
-{
-    spv::Id spvType = 0;
-
-    switch (type.getBasicType()) {
-    case glslang::EbtVoid:
-        spvType = builder.makeVoidType();
-        if (type.isArray())
-            spv::MissingFunctionality("array of void");
-        break;
-    case glslang::EbtFloat:
-        spvType = builder.makeFloatType(32);
-        break;
-    case glslang::EbtDouble:
-        spvType = builder.makeFloatType(64);
-        break;
-    case glslang::EbtBool:
-        spvType = builder.makeBoolType();
-        break;
-    case glslang::EbtInt:
-        spvType = builder.makeIntType(32);
-        break;
-    case glslang::EbtUint:
-        spvType = builder.makeUintType(32);
-        break;
-    case glslang::EbtSampler:
-        {
-            const glslang::TSampler& sampler = type.getSampler();
-            spvType = builder.makeSampler(getSampledType(sampler), TranslateDimensionality(sampler), 
-                                          sampler.image ? spv::Builder::samplerContentImage : spv::Builder::samplerContentTextureFilter,
-                                          sampler.arrayed, sampler.shadow, sampler.ms);
-        }
-        break;
-    case glslang::EbtStruct:
-    case glslang::EbtBlock:
-        {
-            // If we've seen this struct type, return it
-            const glslang::TTypeList* glslangStruct = type.getStruct();
-            std::vector<spv::Id> structFields;
-            spvType = structMap[glslangStruct];
-            if (spvType)
-                break;
-
-            // else, we haven't seen it...
-
-            // Create a vector of struct types for SPIR-V to consume
-            int memberDelta = 0;  // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
-            if (type.getBasicType() == glslang::EbtBlock)
-                memberRemapper[glslangStruct].resize(glslangStruct->size());
-            for (int i = 0; i < (int)glslangStruct->size(); i++) {
-                glslang::TType& glslangType = *(*glslangStruct)[i].type;
-                if (glslangType.hiddenMember()) {
-                    ++memberDelta;
-                    if (type.getBasicType() == glslang::EbtBlock)
-                        memberRemapper[glslangStruct][i] = -1;
-                } else {
-                    if (type.getBasicType() == glslang::EbtBlock)
-                        memberRemapper[glslangStruct][i] = i - memberDelta;
-                    structFields.push_back(convertGlslangToSpvType(glslangType));
-                }
-            }
-
-            // Make the SPIR-V type
-            spvType = builder.makeStructType(structFields, type.getTypeName().c_str());
-            structMap[glslangStruct] = spvType;
-
-            // Name and decorate the non-hidden members
-            for (int i = 0; i < (int)glslangStruct->size(); i++) {
-                glslang::TType& glslangType = *(*glslangStruct)[i].type;
-                int member = i;
-                if (type.getBasicType() == glslang::EbtBlock)
-                    member = memberRemapper[glslangStruct][i];
-                // using -1 above to indicate a hidden member
-                if (member >= 0) {
-                    builder.addMemberName(spvType, member, glslangType.getFieldName().c_str());
-                    addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangType));
-                    addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangType));
-                    addMemberDecoration(spvType, member, TranslateInterpolationDecoration(glslangType));
-                    addMemberDecoration(spvType, member, TranslateInvariantDecoration(glslangType));
-                    if (glslangType.getQualifier().hasLocation())
-                        builder.addMemberDecoration(spvType, member, spv::DecorationLocation, glslangType.getQualifier().layoutLocation);
-                    if (glslangType.getQualifier().hasComponent())
-                        builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangType.getQualifier().layoutComponent);
-                    if (glslangType.getQualifier().hasXfbOffset())
-                        builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutXfbOffset);
-
-                    // built-in variable decorations
-                    int builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn);
-                    if (builtIn != spv::BadValue)
-                        builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, builtIn);
-                }
-            }
-
-            // Decorate the structure
-            addDecoration(spvType, TranslateLayoutDecoration(type));
-            addDecoration(spvType, TranslateBlockDecoration(type));
-            if (type.getQualifier().hasStream())
-                builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
-            if (glslangIntermediate->getXfbMode()) {
-                if (type.getQualifier().hasXfbStride())
-                    builder.addDecoration(spvType, spv::DecorationStride, type.getQualifier().layoutXfbStride);
-                if (type.getQualifier().hasXfbBuffer())
-                    builder.addDecoration(spvType, spv::DecorationXfbBuffer, type.getQualifier().layoutXfbBuffer);
-            }
-        }
-        break;
-    default:
-        spv::MissingFunctionality("basic type");
-        break;
-    }
-
-    if (type.isMatrix())
-        spvType = builder.makeMatrixType(spvType, type.getMatrixCols(), type.getMatrixRows());
-    else {
-        // If this variable has a vector element count greater than 1, create a SPIR-V vector
-        if (type.getVectorSize() > 1)
-            spvType = builder.makeVectorType(spvType, type.getVectorSize());
-    }
-
-    if (type.isArray()) {
-        unsigned arraySize;
-        if (! type.isExplicitlySizedArray()) {
-            spv::MissingFunctionality("Unsized array");
-            arraySize = 8;
-        } else
-            arraySize = type.getArraySize();
-        spvType = builder.makeArrayType(spvType, arraySize);
-    }
-
-    return spvType;
-}
-
-bool TGlslangToSpvTraverser::isShaderEntrypoint(const glslang::TIntermAggregate* node)
-{
-    return node->getName() == "main(";
-}
-
-// Make all the functions, skeletally, without actually visiting their bodies.
-void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
-{
-    for (int f = 0; f < (int)glslFunctions.size(); ++f) {
-        glslang::TIntermAggregate* glslFunction = glslFunctions[f]->getAsAggregate();
-        if (! glslFunction || glslFunction->getOp() != glslang::EOpFunction || isShaderEntrypoint(glslFunction))
-            continue;
-
-        // We're on a user function.  Set up the basic interface for the function now,
-        // so that it's available to call.
-        // Translating the body will happen later.
-        //
-        // Typically (except for a "const in" parameter), an address will be passed to the 
-        // function.  What it is an address of varies:
-        //
-        // - "in" parameters not marked as "const" can be written to without modifying the argument,
-        //  so that write needs to be to a copy, hence the address of a copy works.
-        //
-        // - "const in" parameters can just be the r-value, as no writes need occur.
-        //
-        // - "out" and "inout" arguments can't be done as direct pointers, because GLSL has
-        // copy-in/copy-out semantics.  They can be handled though with a pointer to a copy.
-
-        std::vector<spv::Id> paramTypes;
-        glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence();
-
-        for (int p = 0; p < (int)parameters.size(); ++p) {
-            const glslang::TType& paramType = parameters[p]->getAsTyped()->getType();
-            spv::Id typeId = convertGlslangToSpvType(paramType);
-            if (paramType.getQualifier().storage != glslang::EvqConstReadOnly)
-                typeId = builder.makePointer(spv::StorageClassFunction, typeId);
-            else
-                constReadOnlyParameters.insert(parameters[p]->getAsSymbolNode()->getId());
-            paramTypes.push_back(typeId);
-        }
-
-        spv::Block* functionBlock;
-        spv::Function *function = builder.makeFunctionEntry(convertGlslangToSpvType(glslFunction->getType()), glslFunction->getName().c_str(),
-                                                              paramTypes, &functionBlock);
-
-        // Track function to emit/call later
-        functionMap[glslFunction->getName().c_str()] = function;
-
-        // Set the parameter id's
-        for (int p = 0; p < (int)parameters.size(); ++p) {
-            symbolValues[parameters[p]->getAsSymbolNode()->getId()] = function->getParamId(p);
-            // give a name too
-            builder.addName(function->getParamId(p), parameters[p]->getAsSymbolNode()->getName().c_str());
-        }
-    }
-}
-
-// Process all the initializers, while skipping the functions and link objects
-void TGlslangToSpvTraverser::makeGlobalInitializers(const glslang::TIntermSequence& initializers)
-{
-    builder.setBuildPoint(shaderEntry->getLastBlock());
-    for (int i = 0; i < (int)initializers.size(); ++i) {
-        glslang::TIntermAggregate* initializer = initializers[i]->getAsAggregate();
-        if (initializer && initializer->getOp() != glslang::EOpFunction && initializer->getOp() != glslang::EOpLinkerObjects) {
-
-            // We're on a top-level node that's not a function.  Treat as an initializer, whose
-            // code goes into the beginning of main.
-            initializer->traverse(this);
-        }
-    }
-}
-
-// Process all the functions, while skipping initializers.
-void TGlslangToSpvTraverser::visitFunctions(const glslang::TIntermSequence& glslFunctions)
-{
-    for (int f = 0; f < (int)glslFunctions.size(); ++f) {
-        glslang::TIntermAggregate* node = glslFunctions[f]->getAsAggregate();
-        if (node && (node->getOp() == glslang::EOpFunction || node->getOp() == glslang ::EOpLinkerObjects))
-            node->traverse(this);
-    }
-}
-
-void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate* node)
-{
-    // SPIR-V functions should already be in the functionMap from the prepass 
-    // that called makeFunctions().
-    spv::Function* function = functionMap[node->getName().c_str()];
-    spv::Block* functionBlock = function->getEntryBlock();
-    builder.setBuildPoint(functionBlock);
-}
-
-void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermSequence& glslangArguments, std::vector<spv::Id>& arguments)
-{
-    for (int i = 0; i < (int)glslangArguments.size(); ++i) {
-        builder.clearAccessChain();
-        glslangArguments[i]->traverse(this);
-        arguments.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArguments[i]->getAsTyped()->getType())));
-    }
-}
-
-spv::Id TGlslangToSpvTraverser::handleBuiltInFunctionCall(const glslang::TIntermAggregate* node)
-{
-    std::vector<spv::Id> arguments;
-    translateArguments(node->getSequence(), arguments);
-
-    std::vector<spv::Id> argTypes;
-    for (int a = 0; a < (int)arguments.size(); ++a)
-        argTypes.push_back(builder.getTypeId(arguments[a]));
-
-    spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
-
-    if (node->getName() == "ftransform(") {
-        spv::MissingFunctionality("ftransform()");
-        //spv::Id vertex = builder.createVariable(spv::StorageShaderGlobal, spv::VectorType::get(spv::makeFloatType(), 4),
-        //                                                             "gl_Vertex_sim");
-        //spv::Id matrix = builder.createVariable(spv::StorageShaderGlobal, spv::VectorType::get(spv::makeFloatType(), 4),
-        //                                                             "gl_ModelViewProjectionMatrix_sim");
-        return 0;
-    }
-
-    if (node->getName().substr(0, 7) == "texture" || node->getName().substr(0, 5) == "texel" || node->getName().substr(0, 6) == "shadow") {
-        const glslang::TSampler sampler = node->getSequence()[0]->getAsTyped()->getType().getSampler();
-        spv::Builder::TextureParameters params = { };
-        params.sampler = arguments[0];
-
-        // special case size query
-        if (node->getName().find("textureSize", 0) != std::string::npos) {
-            if (arguments.size() > 1) {
-                params.lod = arguments[1];
-                return builder.createTextureQueryCall(spv::OpTextureQuerySizeLod, params);
-            } else
-                return builder.createTextureQueryCall(spv::OpTextureQuerySize, params);
-        }
-
-        // special case the number of samples query
-        if (node->getName().find("textureSamples", 0) != std::string::npos)
-            return builder.createTextureQueryCall(spv::OpTextureQuerySamples, params);
-
-        // special case the other queries
-        if (node->getName().find("Query", 0) != std::string::npos) {
-            if (node->getName().find("Levels", 0) != std::string::npos)
-                return builder.createTextureQueryCall(spv::OpTextureQueryLevels, params);
-            else if (node->getName().find("Lod", 0) != std::string::npos) {
-                params.coords = arguments[1];
-                return builder.createTextureQueryCall(spv::OpTextureQueryLod, params);
-            } else
-                spv::MissingFunctionality("glslang texture query");
-        }
-
-        // This is no longer a query....
-
-        bool lod = node->getName().find("Lod", 0) != std::string::npos;
-        bool proj = node->getName().find("Proj", 0) != std::string::npos;
-        bool offsets = node->getName().find("Offsets", 0) != std::string::npos;
-        bool offset = ! offsets && node->getName().find("Offset", 0) != std::string::npos;
-        bool fetch = node->getName().find("Fetch", 0) != std::string::npos;
-        bool gather = node->getName().find("Gather", 0) != std::string::npos;
-        bool grad = node->getName().find("Grad", 0) != std::string::npos;
-
-        if (fetch)
-            spv::MissingFunctionality("texel fetch");
-        if (gather)
-            spv::MissingFunctionality("texture gather");
-
-        // check for bias argument
-        bool bias = false;
-        if (! lod && ! gather && ! grad && ! fetch) {
-            int nonBiasArgCount = 2;
-            if (offset)
-                ++nonBiasArgCount;
-            if (grad)
-                nonBiasArgCount += 2;
-
-            if ((int)arguments.size() > nonBiasArgCount)
-                bias = true;
-        }
-
-        bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
-
-        // set the rest of the arguments
-        params.coords = arguments[1];
-        int extraArgs = 0;
-        if (cubeCompare)
-            params.Dref = arguments[2];
-        if (lod) {
-            params.lod = arguments[2];
-            ++extraArgs;
-        }
-        if (grad) {
-            params.gradX = arguments[2 + extraArgs];
-            params.gradY = arguments[3 + extraArgs];
-            extraArgs += 2;
-        }
-        //if (gather && compare) {
-        //    params.compare = arguments[2 + extraArgs];
-        //    ++extraArgs;
-        //}
-        if (offset | offsets) {
-            params.offset = arguments[2 + extraArgs];
-            ++extraArgs;
-        }
-        if (bias) {
-            params.bias = arguments[2 + extraArgs];
-            ++extraArgs;
-        }
-
-        return builder.createTextureCall(precision, convertGlslangToSpvType(node->getType()), proj, params);
-    }
-
-    spv::MissingFunctionality("built-in function call");
-
-    return 0;
-}
-
-spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAggregate* node)
-{
-    // Grab the function's pointer from the previously created function
-    spv::Function* function = functionMap[node->getName().c_str()];
-    if (! function)
-        return 0;
-
-    const glslang::TIntermSequence& glslangArgs = node->getSequence();
-    const glslang::TQualifierList& qualifiers = node->getQualifierList();
-
-    //  See comments in makeFunctions() for details about the semantics for parameter passing.
-    //
-    // These imply we need a four step process:
-    // 1. Evaluate the arguments
-    // 2. Allocate and make copies of in, out, and inout arguments
-    // 3. Make the call
-    // 4. Copy back the results
-
-    // 1. Evaluate the arguments
-    std::vector<spv::Builder::AccessChain> lValues;
-    std::vector<spv::Id> rValues;
-    for (int a = 0; a < (int)glslangArgs.size(); ++a) {
-        // build l-value
-        builder.clearAccessChain();
-        glslangArgs[a]->traverse(this);
-        // keep outputs as l-values, evaluate input-only as r-values
-        if (qualifiers[a] != glslang::EvqConstReadOnly) {
-            // save l-value
-            lValues.push_back(builder.getAccessChain());
-        } else {
-            // process r-value
-            rValues.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArgs[a]->getAsTyped()->getType())));
-        }
-    }
-
-    // 2. Allocate space for anything needing a copy, and if it's "in" or "inout"
-    // copy the original into that space.
-    //
-    // Also, build up the list of actual arguments to pass in for the call
-    int lValueCount = 0;
-    int rValueCount = 0;
-    std::vector<spv::Id> spvArgs;
-    for (int a = 0; a < (int)glslangArgs.size(); ++a) {
-        spv::Id arg;
-        if (qualifiers[a] != glslang::EvqConstReadOnly) {
-            // need space to hold the copy
-            const glslang::TType& paramType = glslangArgs[a]->getAsTyped()->getType();
-            arg = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(paramType), "param");
-            if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) {
-                // need to copy the input into output space
-                builder.setAccessChain(lValues[lValueCount]);
-                spv::Id copy = builder.accessChainLoad(spv::NoPrecision);  // TODO: get precision
-                builder.createStore(copy, arg);
-            }
-            ++lValueCount;
-        } else {
-            arg = rValues[rValueCount];
-            ++rValueCount;
-        }
-        spvArgs.push_back(arg);
-    }
-
-    // 3. Make the call.
-    spv::Id result = builder.createFunctionCall(function, spvArgs);
-
-    // 4. Copy back out an "out" arguments.
-    lValueCount = 0;
-    for (int a = 0; a < (int)glslangArgs.size(); ++a) {
-        if (qualifiers[a] != glslang::EvqConstReadOnly) {
-            if (qualifiers[a] == glslang::EvqOut || qualifiers[a] == glslang::EvqInOut) {
-                spv::Id copy = builder.createLoad(spvArgs[a]);
-                builder.setAccessChain(lValues[lValueCount]);
-                builder.accessChainStore(copy);
-            }
-            ++lValueCount;
-        }
-    }
-
-    return result;
-}
-
-// Translate AST operation to SPV operation, already having SPV-based operands/types.
-spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv::Decoration precision, 
-                                                      spv::Id typeId, spv::Id left, spv::Id right,
-                                                      glslang::TBasicType typeProxy, bool reduceComparison)
-{
-    bool isUnsigned = typeProxy == glslang::EbtUint;
-    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
-
-    spv::Op binOp = spv::OpNop;
-    bool needsPromotion = true;
-    bool comparison = false;
-
-    switch (op) {
-    case glslang::EOpAdd:
-    case glslang::EOpAddAssign:
-        if (isFloat)
-            binOp = spv::OpFAdd;
-        else
-            binOp = spv::OpIAdd;
-        break;
-    case glslang::EOpSub:
-    case glslang::EOpSubAssign:
-        if (isFloat)
-            binOp = spv::OpFSub;
-        else
-            binOp = spv::OpISub;
-        break;
-    case glslang::EOpMul:
-    case glslang::EOpMulAssign:
-        if (isFloat)
-            binOp = spv::OpFMul;
-        else
-            binOp = spv::OpIMul;
-        break;
-    case glslang::EOpVectorTimesScalar:
-    case glslang::EOpVectorTimesScalarAssign:
-        if (builder.isVector(right))
-            std::swap(left, right);
-        assert(builder.isScalar(right));
-        binOp = spv::OpVectorTimesScalar;
-        needsPromotion = false;
-        break;
-    case glslang::EOpVectorTimesMatrix:
-    case glslang::EOpVectorTimesMatrixAssign:
-        assert(builder.isVector(left));
-        assert(builder.isMatrix(right));
-        binOp = spv::OpVectorTimesMatrix;
-        break;
-    case glslang::EOpMatrixTimesVector:
-        assert(builder.isMatrix(left));
-        assert(builder.isVector(right));
-        binOp = spv::OpMatrixTimesVector;
-        break;
-    case glslang::EOpMatrixTimesScalar:
-    case glslang::EOpMatrixTimesScalarAssign:
-        if (builder.isMatrix(right))
-            std::swap(left, right);
-        assert(builder.isScalar(right));
-        binOp = spv::OpMatrixTimesScalar;
-        break;
-    case glslang::EOpMatrixTimesMatrix:
-    case glslang::EOpMatrixTimesMatrixAssign:
-        assert(builder.isMatrix(left));
-        assert(builder.isMatrix(right));
-        binOp = spv::OpMatrixTimesMatrix;
-        break;
-    case glslang::EOpOuterProduct:
-        binOp = spv::OpOuterProduct;
-        needsPromotion = false;
-        break;
-
-    case glslang::EOpDiv:
-    case glslang::EOpDivAssign:
-        if (isFloat)
-            binOp = spv::OpFDiv;
-        else if (isUnsigned)
-            binOp = spv::OpUDiv;
-        else
-            binOp = spv::OpSDiv;
-        break;
-    case glslang::EOpMod:
-    case glslang::EOpModAssign:
-        if (isFloat)
-            binOp = spv::OpFMod;
-        else if (isUnsigned)
-            binOp = spv::OpUMod;
-        else
-            binOp = spv::OpSMod;
-        break;
-    case glslang::EOpRightShift:
-    case glslang::EOpRightShiftAssign:
-        if (isUnsigned)
-            binOp = spv::OpShiftRightLogical;
-        else
-            binOp = spv::OpShiftRightArithmetic;
-        break;
-    case glslang::EOpLeftShift:
-    case glslang::EOpLeftShiftAssign:
-        binOp = spv::OpShiftLeftLogical;
-        break;
-    case glslang::EOpAnd:
-    case glslang::EOpAndAssign:
-        binOp = spv::OpBitwiseAnd;
-        break;
-    case glslang::EOpLogicalAnd:
-        needsPromotion = false;
-        binOp = spv::OpLogicalAnd;
-        break;
-    case glslang::EOpInclusiveOr:
-    case glslang::EOpInclusiveOrAssign:
-        binOp = spv::OpBitwiseOr;
-        break;
-    case glslang::EOpLogicalOr:
-        needsPromotion = false;
-        binOp = spv::OpLogicalOr;
-        break;
-    case glslang::EOpExclusiveOr:
-    case glslang::EOpExclusiveOrAssign:
-        binOp = spv::OpBitwiseXor;
-        break;
-    case glslang::EOpLogicalXor:
-        needsPromotion = false;
-        binOp = spv::OpLogicalXor;
-        break;
-
-    case glslang::EOpLessThan:
-    case glslang::EOpGreaterThan:
-    case glslang::EOpLessThanEqual:
-    case glslang::EOpGreaterThanEqual:
-    case glslang::EOpEqual:
-    case glslang::EOpNotEqual:
-    case glslang::EOpVectorEqual:
-    case glslang::EOpVectorNotEqual:
-        comparison = true;
-        break;
-    default:
-        break;
-    }
-
-    if (binOp != spv::OpNop) {
-        if (builder.isMatrix(left) || builder.isMatrix(right)) {
-            switch (binOp) {
-            case spv::OpMatrixTimesScalar:
-            case spv::OpVectorTimesMatrix:
-            case spv::OpMatrixTimesVector:
-            case spv::OpMatrixTimesMatrix:
-                break;
-            case spv::OpFDiv:
-                // turn it into a multiply...
-                assert(builder.isMatrix(left) && builder.isScalar(right));
-                right = builder.createBinOp(spv::OpFDiv, builder.getTypeId(right), builder.makeFloatConstant(1.0F), right);
-                binOp = spv::OpFMul;
-                break;
-            default:
-                spv::MissingFunctionality("binary operation on matrix");
-                break;
-            }
-
-            spv::Id id = builder.createBinOp(binOp, typeId, left, right);
-            builder.setPrecision(id, precision);
-
-            return id;
-        }
-
-        // No matrix involved; make both operands be the same number of components, if needed
-        if (needsPromotion)
-            builder.promoteScalar(precision, left, right);
-
-        spv::Id id = builder.createBinOp(binOp, typeId, left, right);
-        builder.setPrecision(id, precision);
-
-        return id;
-    }
-
-    if (! comparison)
-        return 0;
-
-    // Comparison instructions
-
-    if (reduceComparison && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) {
-        assert(op == glslang::EOpEqual || op == glslang::EOpNotEqual);
-
-        return builder.createCompare(precision, left, right, op == glslang::EOpEqual);
-    }
-
-    switch (op) {
-    case glslang::EOpLessThan:
-        if (isFloat)
-            binOp = spv::OpFOrdLessThan;
-        else if (isUnsigned)
-            binOp = spv::OpULessThan;
-        else
-            binOp = spv::OpSLessThan;
-        break;
-    case glslang::EOpGreaterThan:
-        if (isFloat)
-            binOp = spv::OpFOrdGreaterThan;
-        else if (isUnsigned)
-            binOp = spv::OpUGreaterThan;
-        else
-            binOp = spv::OpSGreaterThan;
-        break;
-    case glslang::EOpLessThanEqual:
-        if (isFloat)
-            binOp = spv::OpFOrdLessThanEqual;
-        else if (isUnsigned)
-            binOp = spv::OpULessThanEqual;
-        else
-            binOp = spv::OpSLessThanEqual;
-        break;
-    case glslang::EOpGreaterThanEqual:
-        if (isFloat)
-            binOp = spv::OpFOrdGreaterThanEqual;
-        else if (isUnsigned)
-            binOp = spv::OpUGreaterThanEqual;
-        else
-            binOp = spv::OpSGreaterThanEqual;
-        break;
-    case glslang::EOpEqual:
-    case glslang::EOpVectorEqual:
-        if (isFloat)
-            binOp = spv::OpFOrdEqual;
-        else
-            binOp = spv::OpIEqual;
-        break;
-    case glslang::EOpNotEqual:
-    case glslang::EOpVectorNotEqual:
-        if (isFloat)
-            binOp = spv::OpFOrdNotEqual;
-        else
-            binOp = spv::OpINotEqual;
-        break;
-    default:
-        break;
-    }
-
-    if (binOp != spv::OpNop) {
-        spv::Id id = builder.createBinOp(binOp, typeId, left, right);
-        builder.setPrecision(id, precision);
-
-        return id;
-    }
-
-    return 0;
-}
-
-spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, bool isFloat)
-{
-    spv::Op unaryOp = spv::OpNop;
-    int libCall = -1;
-
-    switch (op) {
-    case glslang::EOpNegative:
-        if (isFloat)
-            unaryOp = spv::OpFNegate;
-        else
-            unaryOp = spv::OpSNegate;
-        break;
-
-    case glslang::EOpLogicalNot:
-    case glslang::EOpVectorLogicalNot:
-    case glslang::EOpBitwiseNot:
-        unaryOp = spv::OpNot;
-        break;
-    
-    case glslang::EOpDeterminant:
-        libCall = GLSL_STD_450::Determinant;
-        break;
-    case glslang::EOpMatrixInverse:
-        libCall = GLSL_STD_450::MatrixInverse;
-        break;
-    case glslang::EOpTranspose:
-        unaryOp = spv::OpTranspose;
-        break;
-
-    case glslang::EOpRadians:
-        libCall = GLSL_STD_450::Radians;
-        break;
-    case glslang::EOpDegrees:
-        libCall = GLSL_STD_450::Degrees;
-        break;
-    case glslang::EOpSin:
-        libCall = GLSL_STD_450::Sin;
-        break;
-    case glslang::EOpCos:
-        libCall = GLSL_STD_450::Cos;
-        break;
-    case glslang::EOpTan:
-        libCall = GLSL_STD_450::Tan;
-        break;
-    case glslang::EOpAcos:
-        libCall = GLSL_STD_450::Acos;
-        break;
-    case glslang::EOpAsin:
-        libCall = GLSL_STD_450::Asin;
-        break;
-    case glslang::EOpAtan:
-        libCall = GLSL_STD_450::Atan;
-        break;
-
-    case glslang::EOpAcosh:
-        libCall = GLSL_STD_450::Acosh;
-        break;
-    case glslang::EOpAsinh:
-        libCall = GLSL_STD_450::Asinh;
-        break;
-    case glslang::EOpAtanh:
-        libCall = GLSL_STD_450::Atanh;
-        break;
-    case glslang::EOpTanh:
-        libCall = GLSL_STD_450::Tanh;
-        break;
-    case glslang::EOpCosh:
-        libCall = GLSL_STD_450::Cosh;
-        break;
-    case glslang::EOpSinh:
-        libCall = GLSL_STD_450::Sinh;
-        break;
-
-    case glslang::EOpLength:
-        libCall = GLSL_STD_450::Length;
-        break;
-    case glslang::EOpNormalize:
-        libCall = GLSL_STD_450::Normalize;
-        break;
-
-    case glslang::EOpExp:
-        libCall = GLSL_STD_450::Exp;
-        break;
-    case glslang::EOpLog:
-        libCall = GLSL_STD_450::Log;
-        break;
-    case glslang::EOpExp2:
-        libCall = GLSL_STD_450::Exp2;
-        break;
-    case glslang::EOpLog2:
-        libCall = GLSL_STD_450::Log2;
-        break;
-    case glslang::EOpSqrt:
-        libCall = GLSL_STD_450::Sqrt;
-        break;
-    case glslang::EOpInverseSqrt:
-        libCall = GLSL_STD_450::InverseSqrt;
-        break;
-
-    case glslang::EOpFloor:
-        libCall = GLSL_STD_450::Floor;
-        break;
-    case glslang::EOpTrunc:
-        libCall = GLSL_STD_450::Trunc;
-        break;
-    case glslang::EOpRound:
-        libCall = GLSL_STD_450::Round;
-        break;
-    case glslang::EOpRoundEven:
-        libCall = GLSL_STD_450::RoundEven;
-        break;
-    case glslang::EOpCeil:
-        libCall = GLSL_STD_450::Ceil;
-        break;
-    case glslang::EOpFract:
-        libCall = GLSL_STD_450::Fract;
-        break;
-
-    case glslang::EOpIsNan:
-        unaryOp = spv::OpIsNan;
-        break;
-    case glslang::EOpIsInf:
-        unaryOp = spv::OpIsInf;
-        break;
-
-    case glslang::EOpFloatBitsToInt:
-        libCall = GLSL_STD_450::FloatBitsToInt;
-        break;
-    case glslang::EOpFloatBitsToUint:
-        libCall = GLSL_STD_450::FloatBitsToUint;
-        break;
-    case glslang::EOpIntBitsToFloat:
-        libCall = GLSL_STD_450::IntBitsToFloat;
-        break;
-    case glslang::EOpUintBitsToFloat:
-        libCall = GLSL_STD_450::UintBitsToFloat;
-        break;
-    case glslang::EOpPackSnorm2x16:
-        libCall = GLSL_STD_450::PackSnorm2x16;
-        break;
-    case glslang::EOpUnpackSnorm2x16:
-        libCall = GLSL_STD_450::UnpackSnorm2x16;
-        break;
-    case glslang::EOpPackUnorm2x16:
-        libCall = GLSL_STD_450::PackUnorm2x16;
-        break;
-    case glslang::EOpUnpackUnorm2x16:
-        libCall = GLSL_STD_450::UnpackUnorm2x16;
-        break;
-    case glslang::EOpPackHalf2x16:
-        libCall = GLSL_STD_450::PackHalf2x16;
-        break;
-    case glslang::EOpUnpackHalf2x16:
-        libCall = GLSL_STD_450::UnpackHalf2x16;
-        break;
-
-    case glslang::EOpDPdx:
-        unaryOp = spv::OpDPdx;
-        break;
-    case glslang::EOpDPdy:
-        unaryOp = spv::OpDPdy;
-        break;
-    case glslang::EOpFwidth:
-        unaryOp = spv::OpFwidth;
-        break;
-    case glslang::EOpDPdxFine:
-        unaryOp = spv::OpDPdxFine;
-        break;
-    case glslang::EOpDPdyFine:
-        unaryOp = spv::OpDPdyFine;
-        break;
-    case glslang::EOpFwidthFine:
-        unaryOp = spv::OpFwidthFine;
-        break;
-    case glslang::EOpDPdxCoarse:
-        unaryOp = spv::OpDPdxCoarse;
-        break;
-    case glslang::EOpDPdyCoarse:
-        unaryOp = spv::OpDPdyCoarse;
-        break;
-    case glslang::EOpFwidthCoarse:
-        unaryOp = spv::OpFwidthCoarse;
-        break;
-
-    case glslang::EOpAny:
-        unaryOp = spv::OpAny;
-        break;
-    case glslang::EOpAll:
-        unaryOp = spv::OpAll;
-        break;
-
-    case glslang::EOpAbs:
-        libCall = GLSL_STD_450::Abs;
-        break;
-    case glslang::EOpSign:
-        libCall = GLSL_STD_450::Sign;
-        break;
-
-    default:
-        return 0;
-    }
-
-    spv::Id id;
-    if (libCall >= 0) {
-        std::vector<spv::Id> args;
-        args.push_back(operand);
-        id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, args);
-    } else
-        id = builder.createUnaryOp(unaryOp, typeId, operand);
-
-    builder.setPrecision(id, precision);
-
-    return id;
-}
-
-spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destType, spv::Id operand)
-{
-    spv::Op convOp = spv::OpNop;
-    spv::Id zero = 0;
-    spv::Id one = 0;
-
-    int vectorSize = builder.isVectorType(destType) ? builder.getNumTypeComponents(destType) : 0;
-
-    switch (op) {
-    case glslang::EOpConvIntToBool:
-    case glslang::EOpConvUintToBool:
-        zero = builder.makeUintConstant(0);
-        zero = makeSmearedConstant(zero, vectorSize);
-        return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
-
-    case glslang::EOpConvFloatToBool:
-        zero = builder.makeFloatConstant(0.0F);
-        zero = makeSmearedConstant(zero, vectorSize);
-        return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
-
-    case glslang::EOpConvDoubleToBool:
-        zero = builder.makeDoubleConstant(0.0);
-        zero = makeSmearedConstant(zero, vectorSize);
-        return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
-
-    case glslang::EOpConvBoolToFloat:
-        convOp = spv::OpSelect;
-        zero = builder.makeFloatConstant(0.0);
-        one  = builder.makeFloatConstant(1.0);
-        break;
-    case glslang::EOpConvBoolToDouble:
-        convOp = spv::OpSelect;
-        zero = builder.makeDoubleConstant(0.0);
-        one  = builder.makeDoubleConstant(1.0);
-        break;
-    case glslang::EOpConvBoolToInt:
-        zero = builder.makeIntConstant(0);
-        one  = builder.makeIntConstant(1);
-        convOp = spv::OpSelect;
-        break;
-    case glslang::EOpConvBoolToUint:
-        zero = builder.makeUintConstant(0);
-        one  = builder.makeUintConstant(1);
-        convOp = spv::OpSelect;
-        break;
-
-    case glslang::EOpConvIntToFloat:
-    case glslang::EOpConvIntToDouble:
-        convOp = spv::OpConvertSToF;
-        break;
-
-    case glslang::EOpConvUintToFloat:
-    case glslang::EOpConvUintToDouble:
-        convOp = spv::OpConvertUToF;
-        break;
-
-    case glslang::EOpConvDoubleToFloat:
-    case glslang::EOpConvFloatToDouble:
-        convOp = spv::OpFConvert;
-        break;
-
-    case glslang::EOpConvFloatToInt:
-    case glslang::EOpConvDoubleToInt:
-        convOp = spv::OpConvertFToS;
-        break;
-
-    case glslang::EOpConvUintToInt:
-    case glslang::EOpConvIntToUint:
-        convOp = spv::OpBitcast;
-        break;
-
-    case glslang::EOpConvFloatToUint:
-    case glslang::EOpConvDoubleToUint:
-        convOp = spv::OpConvertFToU;
-        break;
-    default:
-        break;
-    }
-
-    spv::Id result = 0;
-    if (convOp == spv::OpNop)
-        return result;
-
-    if (convOp == spv::OpSelect) {
-        zero = makeSmearedConstant(zero, vectorSize);
-        one  = makeSmearedConstant(one, vectorSize);
-        result = builder.createTriOp(convOp, destType, operand, one, zero);
-    } else
-        result = builder.createUnaryOp(convOp, destType, operand);
-
-    builder.setPrecision(result, precision);
-
-    return result;
-}
-
-spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vectorSize)
-{
-    if (vectorSize == 0)
-        return constant;
-
-    spv::Id vectorTypeId = builder.makeVectorType(builder.getTypeId(constant), vectorSize);
-    std::vector<spv::Id> components;
-    for (int c = 0; c < vectorSize; ++c)
-        components.push_back(constant);
-    return builder.makeCompositeConstant(vectorTypeId, components);
-}
-
-spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands)
-{
-    spv::Op opCode = spv::OpNop;
-    int libCall = -1;
-
-    switch (op) {
-    case glslang::EOpMin:
-        libCall = GLSL_STD_450::Min;
-        break;
-    case glslang::EOpModf:
-        libCall = GLSL_STD_450::Modf;
-        break;
-    case glslang::EOpMax:
-        libCall = GLSL_STD_450::Max;
-        break;
-    case glslang::EOpPow:
-        libCall = GLSL_STD_450::Pow;
-        break;
-    case glslang::EOpDot:
-        opCode = spv::OpDot;
-        break;
-    case glslang::EOpAtan:
-        libCall = GLSL_STD_450::Atan2;
-        break;
-
-    case glslang::EOpClamp:
-        libCall = GLSL_STD_450::Clamp;
-        break;
-    case glslang::EOpMix:
-        libCall = GLSL_STD_450::Mix;
-        break;
-    case glslang::EOpStep:
-        libCall = GLSL_STD_450::Step;
-        break;
-    case glslang::EOpSmoothStep:
-        libCall = GLSL_STD_450::SmoothStep;
-        break;
-
-    case glslang::EOpDistance:
-        libCall = GLSL_STD_450::Distance;
-        break;
-    case glslang::EOpCross:
-        libCall = GLSL_STD_450::Cross;
-        break;
-    case glslang::EOpFaceForward:
-        libCall = GLSL_STD_450::FaceForward;
-        break;
-    case glslang::EOpReflect:
-        libCall = GLSL_STD_450::Reflect;
-        break;
-    case glslang::EOpRefract:
-        libCall = GLSL_STD_450::Refract;
-        break;
-    default:
-        return 0;
-    }
-
-    spv::Id id = 0;
-    if (libCall >= 0)
-        id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, operands);
-    else {
-        switch (operands.size()) {
-        case 0:
-            // should all be handled by visitAggregate and createNoArgOperation
-            assert(0);
-            return 0;
-        case 1:
-            // should all be handled by createUnaryOperation
-            assert(0);
-            return 0;
-        case 2:
-            id = builder.createBinOp(opCode, typeId, operands[0], operands[1]);
-            break;
-        case 3:
-            id = builder.createTernaryOp(opCode, typeId, operands[0], operands[1], operands[2]);
-            break;
-        default:
-            // These do not exist yet
-            assert(0 && "operation with more than 3 operands");
-            break;
-        }
-    }
-
-    builder.setPrecision(id, precision);
-
-    return id;
-}
-
-// Intrinsics with no arguments, no return value, and no precision.
-spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op)
-{
-    // TODO: get the barrier operands correct
-
-    switch (op) {
-    case glslang::EOpEmitVertex:
-        builder.createNoResultOp(spv::OpEmitVertex);
-        return 0;
-    case glslang::EOpEndPrimitive:
-        builder.createNoResultOp(spv::OpEndPrimitive);
-        return 0;
-    case glslang::EOpBarrier:
-        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsAllMemory);
-        builder.createControlBarrier(spv::ExecutionScopeDevice);
-        return 0;
-    case glslang::EOpMemoryBarrier:
-        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsAllMemory);
-        return 0;
-    case glslang::EOpMemoryBarrierAtomicCounter:
-        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsAtomicCounterMemoryMask);
-        return 0;
-    case glslang::EOpMemoryBarrierBuffer:
-        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsUniformMemoryMask);
-        return 0;
-    case glslang::EOpMemoryBarrierImage:
-        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsImageMemoryMask);
-        return 0;
-    case glslang::EOpMemoryBarrierShared:
-        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsWorkgroupLocalMemoryMask);
-        return 0;
-    case glslang::EOpGroupMemoryBarrier:
-        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsWorkgroupGlobalMemoryMask);
-        return 0;
-    default:
-        spv::MissingFunctionality("operation with no arguments");
-        return 0;
-    }
-}
-
-spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol)
-{
-    std::map<int, spv::Id>::iterator iter;
-    iter = symbolValues.find(symbol->getId());
-    spv::Id id;
-    if (symbolValues.end() != iter) {
-        id = iter->second;
-        return id;
-    }
-
-    // it was not found, create it
-    id = createSpvVariable(symbol);
-    symbolValues[symbol->getId()] = id;
-
-    if (! symbol->getType().isStruct()) {
-        addDecoration(id, TranslatePrecisionDecoration(symbol->getType()));
-        addDecoration(id, TranslateInterpolationDecoration(symbol->getType()));
-        if (symbol->getQualifier().hasLocation())
-            builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
-        if (symbol->getQualifier().hasIndex())
-            builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
-        if (symbol->getQualifier().hasComponent())
-            builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent);
-        if (glslangIntermediate->getXfbMode()) {
-            if (symbol->getQualifier().hasXfbStride())
-                builder.addDecoration(id, spv::DecorationStride, symbol->getQualifier().layoutXfbStride);
-            if (symbol->getQualifier().hasXfbBuffer())
-                builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer);
-            if (symbol->getQualifier().hasXfbOffset())
-                builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset);
-        }
-    }
-
-    addDecoration(id, TranslateInvariantDecoration(symbol->getType()));
-    if (symbol->getQualifier().hasStream())
-        builder.addDecoration(id, spv::DecorationStream, symbol->getQualifier().layoutStream);
-    if (symbol->getQualifier().hasSet())
-        builder.addDecoration(id, spv::DecorationDescriptorSet, symbol->getQualifier().layoutSet);
-    if (symbol->getQualifier().hasBinding())
-        builder.addDecoration(id, spv::DecorationBinding, symbol->getQualifier().layoutBinding);
-    if (glslangIntermediate->getXfbMode()) {
-        if (symbol->getQualifier().hasXfbStride())
-            builder.addDecoration(id, spv::DecorationStride, symbol->getQualifier().layoutXfbStride);
-        if (symbol->getQualifier().hasXfbBuffer())
-            builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer);
-    }
-
-    // built-in variable decorations
-    int builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn);
-    if (builtIn != spv::BadValue)
-        builder.addDecoration(id, spv::DecorationBuiltIn, builtIn);
-
-    if (linkageOnly)
-        builder.addDecoration(id, spv::DecorationNoStaticUse);
-
-    return id;
-}
-
-void TGlslangToSpvTraverser::addDecoration(spv::Id id, spv::Decoration dec)
-{
-    if (dec != spv::BadValue)
-        builder.addDecoration(id, dec);
-}
-
-void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::Decoration dec)
-{
-    if (dec != spv::BadValue)
-        builder.addMemberDecoration(id, (unsigned)member, dec);
-}
-
-// Use 'consts' as the flattened glslang source of scalar constants to recursively
-// build the aggregate SPIR-V constant.
-//
-// If there are not enough elements present in 'consts', 0 will be substituted;
-// an empty 'consts' can be used to create a fully zeroed SPIR-V constant.
-//
-spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangType, const glslang::TConstUnionArray& consts, int& nextConst)
-{
-    // vector of constants for SPIR-V
-    std::vector<spv::Id> spvConsts;
-
-    // Type is used for struct and array constants
-    spv::Id typeId = convertGlslangToSpvType(glslangType);
-
-    if (glslangType.isArray()) {
-        glslang::TType elementType;
-        elementType.shallowCopy(glslangType);   // TODO: desktop arrays of arrays functionality will need a deeper copy to avoid modifying the original
-        elementType.dereference();
-        for (int i = 0; i < glslangType.getArraySize(); ++i)
-            spvConsts.push_back(createSpvConstant(elementType, consts, nextConst));
-    } else if (glslangType.isMatrix()) {
-        glslang::TType vectorType;
-        vectorType.shallowCopy(glslangType);
-        vectorType.dereference();
-        for (int col = 0; col < glslangType.getMatrixCols(); ++col)
-            spvConsts.push_back(createSpvConstant(vectorType, consts, nextConst));
-    } else if (glslangType.getStruct()) {
-        glslang::TVector<glslang::TTypeLoc>::const_iterator iter;
-        for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter)
-            spvConsts.push_back(createSpvConstant(*iter->type, consts, nextConst));
-    } else if (glslangType.isVector()) {
-        for (unsigned int i = 0; i < (unsigned int)glslangType.getVectorSize(); ++i) {
-            bool zero = nextConst >= consts.size();
-            switch (glslangType.getBasicType()) {
-            case glslang::EbtInt:
-                spvConsts.push_back(builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst()));
-                break;
-            case glslang::EbtUint:
-                spvConsts.push_back(builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst()));
-                break;
-            case glslang::EbtFloat:
-                spvConsts.push_back(builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
-                break;
-            case glslang::EbtDouble:
-                spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst()));
-                break;
-            case glslang::EbtBool:
-                spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst()));
-                break;
-            default:
-                spv::MissingFunctionality("constant vector type");
-                break;
-            }
-            ++nextConst;
-        }
-    } else {
-        // we have a non-aggregate (scalar) constant
-        bool zero = nextConst >= consts.size();
-        spv::Id scalar = 0;
-        switch (glslangType.getBasicType()) {
-        case glslang::EbtInt:
-            scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst());
-            break;
-        case glslang::EbtUint:
-            scalar = builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst());
-            break;
-        case glslang::EbtFloat:
-            scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst());
-            break;
-        case glslang::EbtDouble:
-            scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst());
-            break;
-        case glslang::EbtBool:
-            scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst());
-            break;
-        default:
-            spv::MissingFunctionality("constant scalar type");
-            break;
-        }
-        ++nextConst;
-        return scalar;
-    }
-
-    return builder.makeCompositeConstant(typeId, spvConsts);
-}
-
-};  // end anonymous namespace
-
-namespace glslang {
-
-// Write SPIR-V out to a binary file
-void OutputSpv(const std::vector<unsigned int>& spirv, const char* baseName)
-{
-    std::ofstream out;
-    std::string fileName(baseName);
-    fileName.append(".spv");
-    out.open(fileName.c_str(), std::ios::binary | std::ios::out);
-    for (int i = 0; i < (int)spirv.size(); ++i) {
-        unsigned int word = spirv[i];
-        out.write((const char*)&word, 4);
-    }
-    out.close();
-}
-
-//
-// Set up the glslang traversal
-//
-void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv)
-{
-    TIntermNode* root = intermediate.getTreeRoot();
-
-    if (root == 0)
-        return;
-
-    glslang::GetThreadPoolAllocator().push();
-
-    TGlslangToSpvTraverser it(&intermediate);
-
-    root->traverse(&it);
-
-    it.dumpSpv(spirv);
-
-    glslang::GetThreadPoolAllocator().pop();
-}
-
-}; // end namespace glslang
+//
+//Copyright (C) 2014 LunarG, Inc.
+//
+//All rights reserved.
+//
+//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 3Dlabs Inc. Ltd. 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 HOLDERS 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.
+
+//
+// Author: John Kessenich, LunarG
+//
+// Visit the nodes in the glslang intermediate tree representation to
+// translate them to SPIR-V.
+//
+
+#include "spirv.h"
+#include "GlslangToSpv.h"
+#include "SpvBuilder.h"
+#include "GLSL450Lib.h"
+
+// Glslang includes
+#include "glslang/MachineIndependent/localintermediate.h"
+#include "glslang/MachineIndependent/SymbolTable.h"
+
+#include <string>
+#include <map>
+#include <list>
+#include <vector>
+#include <stack>
+#include <fstream>
+
+namespace {
+
+const int GlslangMagic = 0x51a;
+
+//
+// The main holder of information for translating glslang to SPIR-V.
+//
+// Derives from the AST walking base class.
+//
+class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
+public:
+    TGlslangToSpvTraverser(const glslang::TIntermediate*);
+    virtual ~TGlslangToSpvTraverser();
+
+    bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*);
+    bool visitBinary(glslang::TVisit, glslang::TIntermBinary*);
+    void visitConstantUnion(glslang::TIntermConstantUnion*);
+    bool visitSelection(glslang::TVisit, glslang::TIntermSelection*);
+    bool visitSwitch(glslang::TVisit, glslang::TIntermSwitch*);
+    void visitSymbol(glslang::TIntermSymbol* symbol);
+    bool visitUnary(glslang::TVisit, glslang::TIntermUnary*);
+    bool visitLoop(glslang::TVisit, glslang::TIntermLoop*);
+    bool visitBranch(glslang::TVisit visit, glslang::TIntermBranch*);
+
+    void dumpSpv(std::vector<unsigned int>& out) { builder.dump(out); }
+
+protected:
+    spv::Id createSpvVariable(const glslang::TIntermSymbol*);
+    spv::Id getSampledType(const glslang::TSampler&);
+    spv::Id convertGlslangToSpvType(const glslang::TType& type);
+
+    bool isShaderEntrypoint(const glslang::TIntermAggregate* node);
+    void makeFunctions(const glslang::TIntermSequence&);
+    void makeGlobalInitializers(const glslang::TIntermSequence&);
+    void visitFunctions(const glslang::TIntermSequence&);
+    void handleFunctionEntry(const glslang::TIntermAggregate* node);
+    void translateArguments(const glslang::TIntermSequence& glslangArguments, std::vector<spv::Id>& arguments);
+    spv::Id handleBuiltInFunctionCall(const glslang::TIntermAggregate*);
+    spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*);
+
+    spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true);
+    spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, bool isFloat);
+    spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destTypeId, spv::Id operand);
+    spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
+    spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands);
+    spv::Id createNoArgOperation(glslang::TOperator op);
+    spv::Id getSymbolId(const glslang::TIntermSymbol* node);
+    void addDecoration(spv::Id id, spv::Decoration dec);
+    void addMemberDecoration(spv::Id id, int member, spv::Decoration dec);
+    spv::Id createSpvConstant(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst);
+
+    spv::Function* shaderEntry;
+    int sequenceDepth;
+
+    // There is a 1:1 mapping between a spv builder and a module; this is thread safe
+    spv::Builder builder;
+    bool inMain;
+    bool mainTerminated;
+    bool linkageOnly;
+    const glslang::TIntermediate* glslangIntermediate;
+    spv::Id stdBuiltins;
+
+    std::map<int, spv::Id> symbolValues;
+    std::set<int> constReadOnlyParameters;  // set of formal function parameters that have glslang qualifier constReadOnly, so we know they are not local function "const" that are write-once
+    std::map<std::string, spv::Function*> functionMap;
+    std::map<const glslang::TTypeList*, spv::Id> structMap;
+    std::map<const glslang::TTypeList*, std::vector<int> > memberRemapper;  // for mapping glslang block indices to spv indices (e.g., due to hidden members)
+    std::stack<bool> breakForLoop;  // false means break for switch
+    std::stack<glslang::TIntermTyped*> loopTerminal;  // code from the last part of a for loop: for(...; ...; terminal), needed for e.g., continue };
+};
+
+//
+// Helper functions for translating glslang representations to SPIR-V enumerants.
+//
+
+// Translate glslang profile to SPIR-V source language.
+spv::SourceLanguage TranslateSourceLanguage(EProfile profile)
+{
+    switch (profile) {
+    case ENoProfile:
+    case ECoreProfile:
+    case ECompatibilityProfile:
+        return spv::SourceLanguageGLSL;
+    case EEsProfile:
+        return spv::SourceLanguageESSL;
+    default:
+        return spv::SourceLanguageUnknown;
+    }
+}
+
+// Translate glslang language (stage) to SPIR-V execution model.
+spv::ExecutionModel TranslateExecutionModel(EShLanguage stage)
+{
+    switch (stage) {
+    case EShLangVertex:           return spv::ExecutionModelVertex;
+    case EShLangTessControl:      return spv::ExecutionModelTessellationControl;
+    case EShLangTessEvaluation:   return spv::ExecutionModelTessellationEvaluation;
+    case EShLangGeometry:         return spv::ExecutionModelGeometry;
+    case EShLangFragment:         return spv::ExecutionModelFragment;
+    case EShLangCompute:          return spv::ExecutionModelGLCompute;
+    default:
+        spv::MissingFunctionality("GLSL stage");
+        return spv::ExecutionModelFragment;
+    }
+}
+
+// Translate glslang type to SPIR-V storage class.
+spv::StorageClass TranslateStorageClass(const glslang::TType& type)
+{
+    if (type.getQualifier().isPipeInput())
+        return spv::StorageClassInput;
+    else if (type.getQualifier().isPipeOutput())
+        return spv::StorageClassOutput;
+    else if (type.getQualifier().isUniformOrBuffer()) {
+        if (type.getBasicType() == glslang::EbtBlock)
+            return spv::StorageClassUniform;
+        else
+            return spv::StorageClassUniformConstant;
+        // TODO: how are we distuingishing between default and non-default non-writable uniforms?  Do default uniforms even exist?
+    } else {
+        switch (type.getQualifier().storage) {
+        case glslang::EvqShared:        return spv::StorageClassWorkgroupLocal;  break;
+        case glslang::EvqGlobal:        return spv::StorageClassPrivateGlobal;
+        case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
+        case glslang::EvqTemporary:     return spv::StorageClassFunction;
+        default: 
+            spv::MissingFunctionality("unknown glslang storage class");
+            return spv::StorageClassFunction;
+        }
+    }
+}
+
+// Translate glslang sampler type to SPIR-V dimensionality.
+spv::Dim TranslateDimensionality(const glslang::TSampler& sampler)
+{
+    switch (sampler.dim) {
+    case glslang::Esd1D:     return spv::Dim1D;
+    case glslang::Esd2D:     return spv::Dim2D;
+    case glslang::Esd3D:     return spv::Dim3D;
+    case glslang::EsdCube:   return spv::DimCube;
+    case glslang::EsdRect:   return spv::DimRect;
+    case glslang::EsdBuffer: return spv::DimBuffer;
+    default:
+        spv::MissingFunctionality("unknown sampler dimension");
+        return spv::Dim2D;
+    }
+}
+
+// Translate glslang type to SPIR-V precision decorations.
+spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
+{
+    switch (type.getQualifier().precision) {
+    case glslang::EpqLow:    return spv::DecorationPrecisionLow;
+    case glslang::EpqMedium: return spv::DecorationPrecisionMedium;
+    case glslang::EpqHigh:   return spv::DecorationPrecisionHigh;
+    default:
+        return spv::NoPrecision;
+    }
+}
+
+// Translate glslang type to SPIR-V block decorations.
+spv::Decoration TranslateBlockDecoration(const glslang::TType& type)
+{
+    if (type.getBasicType() == glslang::EbtBlock) {
+        switch (type.getQualifier().storage) {
+        case glslang::EvqUniform:      return spv::DecorationBlock;
+        case glslang::EvqBuffer:       return spv::DecorationBufferBlock;
+        case glslang::EvqVaryingIn:    return spv::DecorationBlock;
+        case glslang::EvqVaryingOut:   return spv::DecorationBlock;
+        default:
+            spv::MissingFunctionality("kind of block");
+            break;
+        }
+    }
+
+    return (spv::Decoration)spv::BadValue;
+}
+
+// Translate glslang type to SPIR-V layout decorations.
+spv::Decoration TranslateLayoutDecoration(const glslang::TType& type)
+{
+    if (type.isMatrix()) {
+        switch (type.getQualifier().layoutMatrix) {
+        case glslang::ElmRowMajor:
+            return spv::DecorationRowMajor;
+        default:
+            return spv::DecorationColMajor;
+        }
+    } else {
+        switch (type.getBasicType()) {
+        default:
+            return (spv::Decoration)spv::BadValue;
+            break;
+        case glslang::EbtBlock:
+            switch (type.getQualifier().storage) {
+            case glslang::EvqUniform:
+            case glslang::EvqBuffer:
+                switch (type.getQualifier().layoutPacking) {
+                case glslang::ElpShared:  return spv::DecorationGLSLShared;
+                case glslang::ElpStd140:  return spv::DecorationGLSLStd140;
+                case glslang::ElpStd430:  return spv::DecorationGLSLStd430;
+                case glslang::ElpPacked:  return spv::DecorationGLSLPacked;
+                default:
+                    spv::MissingFunctionality("uniform block layout");
+                    return spv::DecorationGLSLShared;
+                }
+            case glslang::EvqVaryingIn:
+            case glslang::EvqVaryingOut:
+                if (type.getQualifier().layoutPacking != glslang::ElpNone)
+                    spv::MissingFunctionality("in/out block layout");
+                return (spv::Decoration)spv::BadValue;
+            default:
+                spv::MissingFunctionality("block storage qualification");
+                return (spv::Decoration)spv::BadValue;
+            }
+        }
+    }
+}
+
+// Translate glslang type to SPIR-V interpolation decorations.
+spv::Decoration TranslateInterpolationDecoration(const glslang::TType& type)
+{
+    if (type.getQualifier().smooth)
+        return spv::DecorationSmooth;
+    if (type.getQualifier().nopersp)
+        return spv::DecorationNoperspective;
+    else if (type.getQualifier().patch)
+        return spv::DecorationPatch;
+    else if (type.getQualifier().flat)
+        return spv::DecorationFlat;
+    else if (type.getQualifier().centroid)
+        return spv::DecorationCentroid;
+    else if (type.getQualifier().sample)
+        return spv::DecorationSample;
+    else
+        return (spv::Decoration)spv::BadValue;
+}
+
+// If glslang type is invaraiant, return SPIR-V invariant decoration.
+spv::Decoration TranslateInvariantDecoration(const glslang::TType& type)
+{
+    if (type.getQualifier().invariant)
+        return spv::DecorationInvariant;
+    else
+        return (spv::Decoration)spv::BadValue;
+}
+
+// Translate glslang built-in variable to SPIR-V built in decoration.
+spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn)
+{
+    switch (builtIn) {
+    case glslang::EbvPosition:             return spv::BuiltInPosition;
+    case glslang::EbvPointSize:            return spv::BuiltInPointSize;
+    case glslang::EbvClipVertex:           return spv::BuiltInClipVertex;
+    case glslang::EbvClipDistance:         return spv::BuiltInClipDistance;
+    case glslang::EbvCullDistance:         return spv::BuiltInCullDistance;
+    case glslang::EbvVertexId:             return spv::BuiltInVertexId;
+    case glslang::EbvInstanceId:           return spv::BuiltInInstanceId;
+    case glslang::EbvPrimitiveId:          return spv::BuiltInPrimitiveId;
+    case glslang::EbvInvocationId:         return spv::BuiltInInvocationId;
+    case glslang::EbvLayer:                return spv::BuiltInLayer;
+    case glslang::EbvViewportIndex:        return spv::BuiltInViewportIndex;
+    case glslang::EbvTessLevelInner:       return spv::BuiltInTessLevelInner;
+    case glslang::EbvTessLevelOuter:       return spv::BuiltInTessLevelOuter;
+    case glslang::EbvTessCoord:            return spv::BuiltInTessCoord;
+    case glslang::EbvPatchVertices:        return spv::BuiltInPatchVertices;
+    case glslang::EbvFragCoord:            return spv::BuiltInFragCoord;
+    case glslang::EbvPointCoord:           return spv::BuiltInPointCoord;
+    case glslang::EbvFace:                 return spv::BuiltInFrontFacing;
+    case glslang::EbvSampleId:             return spv::BuiltInSampleId;
+    case glslang::EbvSamplePosition:       return spv::BuiltInSamplePosition;
+    case glslang::EbvSampleMask:           return spv::BuiltInSampleMask;
+    case glslang::EbvFragColor:            return spv::BuiltInFragColor;
+    case glslang::EbvFragData:             return spv::BuiltInFragColor;
+    case glslang::EbvFragDepth:            return spv::BuiltInFragDepth;
+    case glslang::EbvHelperInvocation:     return spv::BuiltInHelperInvocation;
+    case glslang::EbvNumWorkGroups:        return spv::BuiltInNumWorkgroups;
+    case glslang::EbvWorkGroupSize:        return spv::BuiltInWorkgroupSize;
+    case glslang::EbvWorkGroupId:          return spv::BuiltInWorkgroupId;
+    case glslang::EbvLocalInvocationId:    return spv::BuiltInLocalInvocationId;
+    case glslang::EbvLocalInvocationIndex: return spv::BuiltInLocalInvocationIndex;
+    case glslang::EbvGlobalInvocationId:   return spv::BuiltInGlobalInvocationId;
+    default:                               return (spv::BuiltIn)spv::BadValue;
+    }
+}
+
+//
+// Implement the TGlslangToSpvTraverser class.
+//
+
+TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate)
+    : TIntermTraverser(true, false, true), shaderEntry(0), sequenceDepth(0),
+      builder(GlslangMagic),
+      inMain(false), mainTerminated(false), linkageOnly(false),
+      glslangIntermediate(glslangIntermediate)
+{
+    spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage());
+
+    builder.clearAccessChain();
+    builder.setSource(TranslateSourceLanguage(glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
+    stdBuiltins = builder.import("GLSL.std.450");
+    builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
+    shaderEntry = builder.makeMain();
+    builder.addEntryPoint(executionModel, shaderEntry);
+
+    // Add the source extensions
+    const std::set<std::string>& sourceExtensions = glslangIntermediate->getRequestedExtensions();
+    for (std::set<std::string>::const_iterator it = sourceExtensions.begin(); it != sourceExtensions.end(); ++it)
+        builder.addSourceExtension(it->c_str());
+
+    // Add the top-level modes for this shader.
+
+    if (glslangIntermediate->getXfbMode())
+        builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb);
+
+    unsigned int mode;
+    switch (glslangIntermediate->getStage()) {
+    case EShLangVertex:
+        break;
+
+    case EShLangTessControl:
+        builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
+        break;
+
+    case EShLangTessEvaluation:
+        switch (glslangIntermediate->getInputPrimitive()) {
+        case glslang::ElgTriangles:           mode = spv::ExecutionModeInputTriangles;     break;
+        case glslang::ElgQuads:               mode = spv::ExecutionModeInputQuads;         break;
+        case glslang::ElgIsolines:            mode = spv::ExecutionModeInputIsolines;      break;
+        default:                              mode = spv::BadValue;    break;
+        }
+        if (mode != spv::BadValue)
+            builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
+
+        // TODO
+        //builder.addExecutionMode(spv::VertexSpacingMdName, glslangIntermediate->getVertexSpacing());
+        //builder.addExecutionMode(spv::VertexOrderMdName, glslangIntermediate->getVertexOrder());
+        //builder.addExecutionMode(spv::PointModeMdName, glslangIntermediate->getPointMode());
+        break;
+
+    case EShLangGeometry:
+        switch (glslangIntermediate->getInputPrimitive()) {
+        case glslang::ElgPoints:             mode = spv::ExecutionModeInputPoints;             break;
+        case glslang::ElgLines:              mode = spv::ExecutionModeInputLines;              break;
+        case glslang::ElgLinesAdjacency:     mode = spv::ExecutionModeInputLinesAdjacency;     break;
+        case glslang::ElgTriangles:          mode = spv::ExecutionModeInputTriangles;          break;
+        case glslang::ElgTrianglesAdjacency: mode = spv::ExecutionModeInputTrianglesAdjacency; break;
+        default:                             mode = spv::BadValue;         break;
+        }
+        if (mode != spv::BadValue)
+            builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
+        builder.addExecutionMode(shaderEntry, spv::ExecutionModeInvocations, glslangIntermediate->getInvocations());
+
+        switch (glslangIntermediate->getOutputPrimitive()) {
+        case glslang::ElgPoints:        mode = spv::ExecutionModeOutputPoints;                 break;
+        case glslang::ElgLineStrip:     mode = spv::ExecutionModeOutputLineStrip;              break;
+        case glslang::ElgTriangleStrip: mode = spv::ExecutionModeOutputTriangleStrip;          break;
+        default:                        mode = spv::BadValue;              break;
+        }
+        if (mode != spv::BadValue)
+            builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
+        builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
+        break;
+
+    case EShLangFragment:
+        if (glslangIntermediate->getPixelCenterInteger())
+            builder.addExecutionMode(shaderEntry, spv::ExecutionModePixelCenterInteger);
+        if (glslangIntermediate->getOriginUpperLeft())
+            builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginUpperLeft);
+        break;
+
+    case EShLangCompute:
+        break;
+
+    default:
+        break;
+    }
+
+}
+
+TGlslangToSpvTraverser::~TGlslangToSpvTraverser()
+{
+    if (! mainTerminated) {
+        spv::Block* lastMainBlock = shaderEntry->getLastBlock();
+        builder.setBuildPoint(lastMainBlock);
+        builder.leaveFunction(true);
+    }
+}
+
+//
+// Implement the traversal functions.
+//
+// Return true from interior nodes to have the external traversal
+// continue on to children.  Return false if children were
+// already processed.
+//
+
+//
+// Symbols can turn into 
+//  - uniform/input reads
+//  - output writes
+//  - complex lvalue base setups:  foo.bar[3]....  , where we see foo and start up an access chain
+//  - something simple that degenerates into the last bullet
+//
+void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
+{
+    // getSymbolId() will set up all the IO decorations on the first call.
+    // Formal function parameters were mapped during makeFunctions().
+    spv::Id id = getSymbolId(symbol);
+    
+    if (! linkageOnly) {
+        // Prepare to generate code for the access
+
+        // L-value chains will be computed left to right.  We're on the symbol now,
+        // which is the left-most part of the access chain, so now is "clear" time,
+        // followed by setting the base.
+        builder.clearAccessChain();
+
+        // For now, we consider all user variables as being in memory, so they are pointers,
+        // except for "const in" arguments to a function, which are an intermediate object.
+        // See comments in handleUserFunctionCall().
+        glslang::TStorageQualifier qualifier = symbol->getQualifier().storage;
+        if (qualifier == glslang::EvqConstReadOnly && constReadOnlyParameters.find(symbol->getId()) != constReadOnlyParameters.end())
+            builder.setAccessChainRValue(id);
+        else
+            builder.setAccessChainLValue(id);
+    }
+}
+
+bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
+{
+    // First, handle special cases
+    switch (node->getOp()) {
+    case glslang::EOpAssign:
+    case glslang::EOpAddAssign:
+    case glslang::EOpSubAssign:
+    case glslang::EOpMulAssign:
+    case glslang::EOpVectorTimesMatrixAssign:
+    case glslang::EOpVectorTimesScalarAssign:
+    case glslang::EOpMatrixTimesScalarAssign:
+    case glslang::EOpMatrixTimesMatrixAssign:
+    case glslang::EOpDivAssign:
+    case glslang::EOpModAssign:
+    case glslang::EOpAndAssign:
+    case glslang::EOpInclusiveOrAssign:
+    case glslang::EOpExclusiveOrAssign:
+    case glslang::EOpLeftShiftAssign:
+    case glslang::EOpRightShiftAssign:
+        // A bin-op assign "a += b" means the same thing as "a = a + b"
+        // where a is evaluated before b. For a simple assignment, GLSL
+        // says to evaluate the left before the right.  So, always, left
+        // node then right node.
+        {
+            // get the left l-value, save it away
+            builder.clearAccessChain();
+            node->getLeft()->traverse(this);
+            spv::Builder::AccessChain lValue = builder.getAccessChain();
+
+            // evaluate the right
+            builder.clearAccessChain();
+            node->getRight()->traverse(this);
+            spv::Id rValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
+
+            if (node->getOp() != glslang::EOpAssign) {
+                // the left is also an r-value
+                builder.setAccessChain(lValue);
+                spv::Id leftRValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType()));
+
+                // do the operation
+                rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()), 
+                                               convertGlslangToSpvType(node->getType()), leftRValue, rValue,
+                                               node->getType().getBasicType());
+
+                // these all need their counterparts in createBinaryOperation()
+                if (rValue == 0)
+                    spv::MissingFunctionality("createBinaryOperation");
+            }
+
+            // store the result
+            builder.setAccessChain(lValue);
+            builder.accessChainStore(rValue);
+
+            // assignments are expressions having an rValue after they are evaluated...
+            builder.clearAccessChain();
+            builder.setAccessChainRValue(rValue);
+        }
+        return false;
+    case glslang::EOpIndexDirect:
+    case glslang::EOpIndexDirectStruct:
+        {
+            // Get the left part of the access chain.
+            node->getLeft()->traverse(this);
+
+            // Add the next element in the chain
+
+            int index = 0;
+            if (node->getRight()->getAsConstantUnion() == 0)
+                spv::MissingFunctionality("direct index without a constant node");
+            else 
+                index = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
+
+            if (node->getLeft()->getBasicType() == glslang::EbtBlock && node->getOp() == glslang::EOpIndexDirectStruct) {
+                // This may be, e.g., an anonymous block-member selection, which generally need
+                // index remapping due to hidden members in anonymous blocks.
+                std::vector<int>& remapper = memberRemapper[node->getLeft()->getType().getStruct()];
+                if (remapper.size() == 0)
+                    spv::MissingFunctionality("block without member remapping");
+                else
+                    index = remapper[index];
+            }
+
+            if (! node->getLeft()->getType().isArray() &&
+                node->getLeft()->getType().isVector() &&
+                node->getOp() == glslang::EOpIndexDirect) {
+                // This is essentially a hard-coded vector swizzle of size 1,
+                // so short circuit the access-chain stuff with a swizzle.
+                std::vector<unsigned> swizzle;
+                swizzle.push_back(node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst());
+                builder.accessChainPushSwizzle(swizzle);
+            } else {
+                // normal case for indexing array or structure or block
+                builder.accessChainPush(builder.makeIntConstant(index), convertGlslangToSpvType(node->getType()));
+            }
+        }
+        return false;
+    case glslang::EOpIndexIndirect:
+        {
+            // Structure or array or vector indirection.
+            // Will use native SPIR-V access-chain for struct and array indirection;
+            // matrices are arrays of vectors, so will also work for a matrix.
+            // Will use the access chain's 'component' for variable index into a vector.
+
+            // This adapter is building access chains left to right.
+            // Set up the access chain to the left.
+            node->getLeft()->traverse(this);
+
+            // save it so that computing the right side doesn't trash it
+            spv::Builder::AccessChain partial = builder.getAccessChain();
+
+            // compute the next index in the chain
+            builder.clearAccessChain();
+            node->getRight()->traverse(this);
+            spv::Id index = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
+
+            // restore the saved access chain
+            builder.setAccessChain(partial);
+
+            if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector())
+                builder.accessChainPushComponent(index);
+            else
+                builder.accessChainPush(index, convertGlslangToSpvType(node->getType()));
+        }
+        return false;
+    case glslang::EOpVectorSwizzle:
+        {
+            node->getLeft()->traverse(this);
+            glslang::TIntermSequence& swizzleSequence = node->getRight()->getAsAggregate()->getSequence();
+            std::vector<unsigned> swizzle;
+            for (int i = 0; i < (int)swizzleSequence.size(); ++i)
+                swizzle.push_back(swizzleSequence[i]->getAsConstantUnion()->getConstArray()[0].getIConst());
+            builder.accessChainPushSwizzle(swizzle);
+        }
+        return false;
+    default:
+        break;
+    }
+
+    // Assume generic binary op...
+
+    // Get the operands
+    builder.clearAccessChain();
+    node->getLeft()->traverse(this);
+    spv::Id left = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType()));
+
+    builder.clearAccessChain();
+    node->getRight()->traverse(this);
+    spv::Id right = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
+
+    spv::Id result;
+    spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
+
+    result = createBinaryOperation(node->getOp(), precision, 
+                                   convertGlslangToSpvType(node->getType()), left, right,
+                                   node->getLeft()->getType().getBasicType());
+
+    if (! result) {
+        spv::MissingFunctionality("glslang binary operation");
+    } else {
+        builder.clearAccessChain();
+        builder.setAccessChainRValue(result);
+
+        return false;
+    }
+
+    return true;
+}
+
+bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node)
+{
+    builder.clearAccessChain();
+    node->getOperand()->traverse(this);
+    spv::Id operand = builder.accessChainLoad(TranslatePrecisionDecoration(node->getOperand()->getType()));
+
+    spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
+
+    // it could be a conversion
+    spv::Id result = createConversion(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand);
+
+    // if not, then possibly an operation
+    if (! result)
+        result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand, node->getBasicType() == glslang::EbtFloat || node->getBasicType() == glslang::EbtDouble);
+
+    if (result) {
+        builder.clearAccessChain();
+        builder.setAccessChainRValue(result);
+
+        return false; // done with this node
+    }
+
+    // it must be a special case, check...
+    switch (node->getOp()) {
+    case glslang::EOpPostIncrement:
+    case glslang::EOpPostDecrement:
+    case glslang::EOpPreIncrement:
+    case glslang::EOpPreDecrement:
+        {
+            // we need the integer value "1" or the floating point "1.0" to add/subtract
+            spv::Id one = node->getBasicType() == glslang::EbtFloat ?
+                                     builder.makeFloatConstant(1.0F) :
+                                     builder.makeIntConstant(1);
+            glslang::TOperator op;
+            if (node->getOp() == glslang::EOpPreIncrement ||
+                node->getOp() == glslang::EOpPostIncrement)
+                op = glslang::EOpAdd;
+            else
+                op = glslang::EOpSub;
+
+            spv::Id result = createBinaryOperation(op, TranslatePrecisionDecoration(node->getType()), 
+                                                     convertGlslangToSpvType(node->getType()), operand, one, 
+                                                     node->getType().getBasicType());
+            if (result == 0)
+                spv::MissingFunctionality("createBinaryOperation for unary");
+
+            // The result of operation is always stored, but conditionally the
+            // consumed result.  The consumed result is always an r-value.
+            builder.accessChainStore(result);
+            builder.clearAccessChain();
+            if (node->getOp() == glslang::EOpPreIncrement ||
+                node->getOp() == glslang::EOpPreDecrement)
+                builder.setAccessChainRValue(result);
+            else
+                builder.setAccessChainRValue(operand);
+        }
+
+        return false;
+
+    case glslang::EOpEmitStreamVertex:
+        builder.createNoResultOp(spv::OpEmitStreamVertex, operand);
+        return false;
+    case glslang::EOpEndStreamPrimitive:
+        builder.createNoResultOp(spv::OpEndStreamPrimitive, operand);
+        return false;
+
+    default:
+        spv::MissingFunctionality("glslang unary");
+        break;
+    }
+
+    return true;
+}
+
+bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TIntermAggregate* node)
+{
+    spv::Id result;
+    glslang::TOperator binOp = glslang::EOpNull;
+    bool reduceComparison = true;
+    bool isMatrix = false;
+    bool noReturnValue = false;
+
+    assert(node->getOp());
+
+    spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
+
+    switch (node->getOp()) {
+    case glslang::EOpSequence:
+    {
+        if (preVisit)
+            ++sequenceDepth;
+        else
+            --sequenceDepth;
+
+        if (sequenceDepth == 1) {
+            // If this is the parent node of all the functions, we want to see them
+            // early, so all call points have actual SPIR-V functions to reference.
+            // In all cases, still let the traverser visit the children for us.
+            makeFunctions(node->getAsAggregate()->getSequence());
+
+            // Also, we want all globals initializers to go into the entry of main(), before
+            // anything else gets there, so visit out of order, doing them all now.
+            makeGlobalInitializers(node->getAsAggregate()->getSequence());
+
+            // Initializers are done, don't want to visit again, but functions link objects need to be processed,
+            // so do them manually.
+            visitFunctions(node->getAsAggregate()->getSequence());
+
+            return false;
+        }
+
+        return true;
+    }
+    case glslang::EOpLinkerObjects:
+    {
+        if (visit == glslang::EvPreVisit)
+            linkageOnly = true;
+        else
+            linkageOnly = false;
+
+        return true;
+    }
+    case glslang::EOpComma:
+    {
+        // processing from left to right naturally leaves the right-most
+        // lying around in the access chain
+        glslang::TIntermSequence& glslangOperands = node->getSequence();
+        for (int i = 0; i < (int)glslangOperands.size(); ++i)
+            glslangOperands[i]->traverse(this);
+
+        return false;
+    }
+    case glslang::EOpFunction:
+        if (visit == glslang::EvPreVisit) {
+            if (isShaderEntrypoint(node)) {
+                inMain = true;
+                builder.setBuildPoint(shaderEntry->getLastBlock());
+            } else {
+                handleFunctionEntry(node);
+            }
+        } else {
+            if (inMain)
+                mainTerminated = true;
+            builder.leaveFunction(inMain);
+            inMain = false;
+        }
+
+        return true;
+    case glslang::EOpParameters:
+        // Parameters will have been consumed by EOpFunction processing, but not
+        // the body, so we still visited the function node's children, making this
+        // child redundant.
+        return false;
+    case glslang::EOpFunctionCall:
+    {
+        if (node->isUserDefined())
+            result = handleUserFunctionCall(node);
+        else
+            result = handleBuiltInFunctionCall(node);
+
+        if (! result) {
+            spv::MissingFunctionality("glslang function call");
+            glslang::TConstUnionArray emptyConsts;
+            int nextConst = 0;
+            result = createSpvConstant(node->getType(), emptyConsts, nextConst);
+        }
+        builder.clearAccessChain();
+        builder.setAccessChainRValue(result);
+
+        return false;
+    }
+    case glslang::EOpConstructMat2x2:
+    case glslang::EOpConstructMat2x3:
+    case glslang::EOpConstructMat2x4:
+    case glslang::EOpConstructMat3x2:
+    case glslang::EOpConstructMat3x3:
+    case glslang::EOpConstructMat3x4:
+    case glslang::EOpConstructMat4x2:
+    case glslang::EOpConstructMat4x3:
+    case glslang::EOpConstructMat4x4:
+    case glslang::EOpConstructDMat2x2:
+    case glslang::EOpConstructDMat2x3:
+    case glslang::EOpConstructDMat2x4:
+    case glslang::EOpConstructDMat3x2:
+    case glslang::EOpConstructDMat3x3:
+    case glslang::EOpConstructDMat3x4:
+    case glslang::EOpConstructDMat4x2:
+    case glslang::EOpConstructDMat4x3:
+    case glslang::EOpConstructDMat4x4:
+        isMatrix = true;
+        // fall through
+    case glslang::EOpConstructFloat:
+    case glslang::EOpConstructVec2:
+    case glslang::EOpConstructVec3:
+    case glslang::EOpConstructVec4:
+    case glslang::EOpConstructDouble:
+    case glslang::EOpConstructDVec2:
+    case glslang::EOpConstructDVec3:
+    case glslang::EOpConstructDVec4:
+    case glslang::EOpConstructBool:
+    case glslang::EOpConstructBVec2:
+    case glslang::EOpConstructBVec3:
+    case glslang::EOpConstructBVec4:
+    case glslang::EOpConstructInt:
+    case glslang::EOpConstructIVec2:
+    case glslang::EOpConstructIVec3:
+    case glslang::EOpConstructIVec4:
+    case glslang::EOpConstructUint:
+    case glslang::EOpConstructUVec2:
+    case glslang::EOpConstructUVec3:
+    case glslang::EOpConstructUVec4:
+    case glslang::EOpConstructStruct:
+    {
+        std::vector<spv::Id> arguments;
+        translateArguments(node->getSequence(), arguments);
+        spv::Id resultTypeId = convertGlslangToSpvType(node->getType());
+        spv::Id constructed;
+        if (node->getOp() == glslang::EOpConstructStruct || node->getType().isArray()) {
+            std::vector<spv::Id> constituents;
+            for (int c = 0; c < (int)arguments.size(); ++c)
+                constituents.push_back(arguments[c]);
+            constructed = builder.createCompositeConstruct(resultTypeId, constituents);
+        } else {
+            if (isMatrix)
+                constructed = builder.createMatrixConstructor(precision, arguments, resultTypeId);
+            else
+                constructed = builder.createConstructor(precision, arguments, resultTypeId);
+        }
+
+        builder.clearAccessChain();
+        builder.setAccessChainRValue(constructed);
+
+        return false;
+    }
+
+    // These six are component-wise compares with component-wise results.
+    // Forward on to createBinaryOperation(), requesting a vector result.
+    case glslang::EOpLessThan:
+    case glslang::EOpGreaterThan:
+    case glslang::EOpLessThanEqual:
+    case glslang::EOpGreaterThanEqual:
+    case glslang::EOpVectorEqual:
+    case glslang::EOpVectorNotEqual:
+    {
+        // Map the operation to a binary
+        binOp = node->getOp();
+        reduceComparison = false;
+        switch (node->getOp()) {
+        case glslang::EOpVectorEqual:     binOp = glslang::EOpVectorEqual;      break;
+        case glslang::EOpVectorNotEqual:  binOp = glslang::EOpVectorNotEqual;   break;
+        default:                          binOp = node->getOp();                break;
+        }
+
+        break;
+    }
+    case glslang::EOpMul:
+        // compontent-wise matrix multiply      
+        binOp = glslang::EOpMul;
+        break;
+    case glslang::EOpOuterProduct:
+        // two vectors multiplied to make a matrix
+        binOp = glslang::EOpOuterProduct;
+        break;
+    case glslang::EOpDot:
+    {
+        // for scalar dot product, use multiply        
+        glslang::TIntermSequence& glslangOperands = node->getSequence();
+        if (! glslangOperands[0]->getAsTyped()->isVector())
+            binOp = glslang::EOpMul;
+        break;
+    }
+    case glslang::EOpMod:
+        // when an aggregate, this is the floating-point mod built-in function,
+        // which can be emitted by the one in createBinaryOperation()
+        binOp = glslang::EOpMod;
+        break;
+    case glslang::EOpArrayLength:
+    {
+        glslang::TIntermTyped* typedNode = node->getSequence()[0]->getAsTyped();
+        assert(typedNode);
+        spv::Id length = builder.makeIntConstant(typedNode->getType().getArraySize());
+
+        builder.clearAccessChain();
+        builder.setAccessChainRValue(length);
+
+        return false;
+    }
+    case glslang::EOpEmitVertex:
+    case glslang::EOpEndPrimitive:
+    case glslang::EOpBarrier:
+    case glslang::EOpMemoryBarrier:
+    case glslang::EOpMemoryBarrierAtomicCounter:
+    case glslang::EOpMemoryBarrierBuffer:
+    case glslang::EOpMemoryBarrierImage:
+    case glslang::EOpMemoryBarrierShared:
+    case glslang::EOpGroupMemoryBarrier:
+        noReturnValue = true;
+        // These all have 0 operands and will naturally finish up in the code below for 0 operands
+        break;
+
+    default:
+        break;
+    }
+
+    //
+    // See if it maps to a regular operation.
+    //
+
+    if (binOp != glslang::EOpNull) {
+        glslang::TIntermTyped* left = node->getSequence()[0]->getAsTyped();
+        glslang::TIntermTyped* right = node->getSequence()[1]->getAsTyped();
+        assert(left && right);
+
+        builder.clearAccessChain();
+        left->traverse(this);
+        spv::Id leftId = builder.accessChainLoad(TranslatePrecisionDecoration(left->getType()));
+
+        builder.clearAccessChain();
+        right->traverse(this);
+        spv::Id rightId = builder.accessChainLoad(TranslatePrecisionDecoration(right->getType()));
+
+        result = createBinaryOperation(binOp, precision, 
+                                       convertGlslangToSpvType(node->getType()), leftId, rightId, 
+                                       left->getType().getBasicType(), reduceComparison);
+
+        // code above should only make binOp that exists in createBinaryOperation
+        if (result == 0)
+            spv::MissingFunctionality("createBinaryOperation for aggregate");
+
+        builder.clearAccessChain();
+        builder.setAccessChainRValue(result);
+
+        return false;
+    }
+
+    glslang::TIntermSequence& glslangOperands = node->getSequence();
+    std::vector<spv::Id> operands;
+    for (int arg = 0; arg < (int)glslangOperands.size(); ++arg) {
+        builder.clearAccessChain();
+        glslangOperands[arg]->traverse(this);
+
+        // special case l-value operands; there are just a few
+        bool lvalue = false;
+        switch (node->getOp()) {
+        //case glslang::EOpFrexp:
+        case glslang::EOpModf:
+            if (arg == 1)
+                lvalue = true;
+            break;
+        //case glslang::EOpUAddCarry:
+        //case glslang::EOpUSubBorrow:
+        //case glslang::EOpUMulExtended:
+        default:
+            break;
+        }
+        if (lvalue)
+            operands.push_back(builder.accessChainGetLValue());
+        else
+            operands.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangOperands[arg]->getAsTyped()->getType())));
+    }
+    switch (glslangOperands.size()) {
+    case 0:
+        result = createNoArgOperation(node->getOp());
+        break;
+    case 1:
+        result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands.front(), node->getType().getBasicType() == glslang::EbtFloat || node->getType().getBasicType() == glslang::EbtDouble);
+        break;
+    default:
+        result = createMiscOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands);
+        break;
+    }
+
+    if (noReturnValue)
+        return false;
+
+    if (! result) {
+        spv::MissingFunctionality("glslang aggregate");
+        return true;
+    } else {
+        builder.clearAccessChain();
+        builder.setAccessChainRValue(result);
+        return false;
+    }
+}
+
+bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang::TIntermSelection* node)
+{
+    // This path handles both if-then-else and ?:
+    // The if-then-else has a node type of void, while
+    // ?: has a non-void node type
+    spv::Id result = 0;
+    if (node->getBasicType() != glslang::EbtVoid) {
+        // don't handle this as just on-the-fly temporaries, because there will be two names
+        // and better to leave SSA to later passes
+        result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
+    }
+
+    // emit the condition before doing anything with selection
+    node->getCondition()->traverse(this);
+
+    // make an "if" based on the value created by the condition
+    spv::Builder::If ifBuilder(builder.accessChainLoad(spv::NoPrecision), builder);
+
+    if (node->getTrueBlock()) {
+        // emit the "then" statement
+        node->getTrueBlock()->traverse(this);
+        if (result)
+            builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getTrueBlock()->getAsTyped()->getType())), result);
+    }
+
+    if (node->getFalseBlock()) {
+        ifBuilder.makeBeginElse();
+        // emit the "else" statement
+        node->getFalseBlock()->traverse(this);
+        if (result)
+            builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getFalseBlock()->getAsTyped()->getType())), result);
+    }
+
+    ifBuilder.makeEndIf();
+
+    if (result) {
+        // GLSL only has r-values as the result of a :?, but
+        // if we have an l-value, that can be more efficient if it will
+        // become the base of a complex r-value expression, because the
+        // next layer copies r-values into memory to use the access-chain mechanism
+        builder.clearAccessChain();
+        builder.setAccessChainLValue(result);
+    }
+
+    return false;
+}
+
+bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::TIntermSwitch* node)
+{
+    // emit and get the condition before doing anything with switch
+    node->getCondition()->traverse(this);
+    spv::Id selector = builder.accessChainLoad(TranslatePrecisionDecoration(node->getCondition()->getAsTyped()->getType()));
+
+    // browse the children to sort out code segments
+    int defaultSegment = -1;
+    std::vector<TIntermNode*> codeSegments;
+    glslang::TIntermSequence& sequence = node->getBody()->getSequence();
+    std::vector<int> caseValues;
+    std::vector<int> valueIndexToSegment(sequence.size());  // note: probably not all are used, it is an overestimate
+    for (glslang::TIntermSequence::iterator c = sequence.begin(); c != sequence.end(); ++c) {
+        TIntermNode* child = *c;
+        if (child->getAsBranchNode() && child->getAsBranchNode()->getFlowOp() == glslang::EOpDefault)
+            defaultSegment = codeSegments.size();
+        else if (child->getAsBranchNode() && child->getAsBranchNode()->getFlowOp() == glslang::EOpCase) {
+            valueIndexToSegment[caseValues.size()] = codeSegments.size();
+            caseValues.push_back(child->getAsBranchNode()->getExpression()->getAsConstantUnion()->getConstArray()[0].getIConst());
+        } else
+            codeSegments.push_back(child);
+    }
+
+    // handle the case where the last code segment is missing, due to no code 
+    // statements between the last case and the end of the switch statement
+    if ((caseValues.size() && (int)codeSegments.size() == valueIndexToSegment[caseValues.size() - 1]) ||
+        (int)codeSegments.size() == defaultSegment)
+        codeSegments.push_back(nullptr);
+
+    // make the switch statement
+    std::vector<spv::Block*> segmentBlocks; // returned, as the blocks allocated in the call
+    builder.makeSwitch(selector, codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, segmentBlocks);
+
+    // emit all the code in the segments
+    breakForLoop.push(false);
+    for (unsigned int s = 0; s < codeSegments.size(); ++s) {
+        builder.nextSwitchSegment(segmentBlocks, s);
+        if (codeSegments[s])
+            codeSegments[s]->traverse(this);
+        else
+            builder.addSwitchBreak();
+    }
+    breakForLoop.pop();
+
+    builder.endSwitch(segmentBlocks);
+
+    return false;
+}
+
+void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node)
+{
+    int nextConst = 0;
+    spv::Id constant = createSpvConstant(node->getType(), node->getConstArray(), nextConst);
+
+    builder.clearAccessChain();
+    builder.setAccessChainRValue(constant);
+}
+
+bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIntermLoop* node)
+{
+    // body emission needs to know what the for-loop terminal is when it sees a "continue"
+    loopTerminal.push(node->getTerminal());
+
+    builder.makeNewLoop();
+
+    bool bodyOut = false;
+    if (! node->testFirst()) {
+        builder.endLoopHeaderWithoutTest();
+        if (node->getBody()) {
+            breakForLoop.push(true);
+            node->getBody()->traverse(this);
+            breakForLoop.pop();
+        }
+        bodyOut = true;
+        builder.createBranchToLoopTest();
+    }
+
+    if (node->getTest()) {
+        node->getTest()->traverse(this);
+        // the AST only contained the test computation, not the branch, we have to add it
+        spv::Id condition = builder.accessChainLoad(TranslatePrecisionDecoration(node->getTest()->getType()));
+        builder.createLoopTestBranch(condition);
+    }
+
+    if (! bodyOut && node->getBody()) {
+        breakForLoop.push(true);
+        node->getBody()->traverse(this);
+        breakForLoop.pop();
+    }
+
+    if (loopTerminal.top())
+        loopTerminal.top()->traverse(this);
+
+    builder.closeLoop();
+
+    loopTerminal.pop();
+
+    return false;
+}
+
+bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::TIntermBranch* node)
+{
+    if (node->getExpression())
+        node->getExpression()->traverse(this);
+
+    switch (node->getFlowOp()) {
+    case glslang::EOpKill:
+        builder.makeDiscard();
+        break;
+    case glslang::EOpBreak:
+        if (breakForLoop.top())
+            builder.createLoopExit();
+        else
+            builder.addSwitchBreak();
+        break;
+    case glslang::EOpContinue:
+        if (loopTerminal.top())
+            loopTerminal.top()->traverse(this);
+        builder.createLoopContinue();
+        break;
+    case glslang::EOpReturn:
+        if (inMain)
+            builder.makeMainReturn();
+        else if (node->getExpression())
+            builder.makeReturn(false, builder.accessChainLoad(TranslatePrecisionDecoration(node->getExpression()->getType())));
+        else
+            builder.makeReturn();
+
+        builder.clearAccessChain();
+        break;
+
+    default:
+        spv::MissingFunctionality("branch type");
+        break;
+    }
+
+    return false;
+}
+
+spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* node)
+{
+    // First, steer off constants, which are not SPIR-V variables, but 
+    // can still have a mapping to a SPIR-V Id.
+    if (node->getQualifier().storage == glslang::EvqConst) {
+        int nextConst = 0;
+        return createSpvConstant(node->getType(), node->getConstArray(), nextConst);
+    }
+
+    // Now, handle actual variables
+    spv::StorageClass storageClass = TranslateStorageClass(node->getType());
+    spv::Id spvType = convertGlslangToSpvType(node->getType());
+
+    const char* name = node->getName().c_str();
+    if (glslang::IsAnonymous(name))
+        name = "";
+
+    return builder.createVariable(storageClass, spvType, name);
+}
+
+// Return type Id of the sampled type.
+spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
+{
+    switch (sampler.type) {
+        case glslang::EbtFloat:    return builder.makeFloatType(32);
+        case glslang::EbtInt:      return builder.makeIntType(32);
+        case glslang::EbtUint:     return builder.makeUintType(32);
+        default:
+            spv::MissingFunctionality("sampled type");
+            return builder.makeFloatType(32);
+    }
+}
+
+// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
+spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type)
+{
+    spv::Id spvType = 0;
+
+    switch (type.getBasicType()) {
+    case glslang::EbtVoid:
+        spvType = builder.makeVoidType();
+        if (type.isArray())
+            spv::MissingFunctionality("array of void");
+        break;
+    case glslang::EbtFloat:
+        spvType = builder.makeFloatType(32);
+        break;
+    case glslang::EbtDouble:
+        spvType = builder.makeFloatType(64);
+        break;
+    case glslang::EbtBool:
+        spvType = builder.makeBoolType();
+        break;
+    case glslang::EbtInt:
+        spvType = builder.makeIntType(32);
+        break;
+    case glslang::EbtUint:
+        spvType = builder.makeUintType(32);
+        break;
+    case glslang::EbtSampler:
+        {
+            const glslang::TSampler& sampler = type.getSampler();
+            spvType = builder.makeSampler(getSampledType(sampler), TranslateDimensionality(sampler), 
+                                          sampler.image ? spv::Builder::samplerContentImage : spv::Builder::samplerContentTextureFilter,
+                                          sampler.arrayed, sampler.shadow, sampler.ms);
+        }
+        break;
+    case glslang::EbtStruct:
+    case glslang::EbtBlock:
+        {
+            // If we've seen this struct type, return it
+            const glslang::TTypeList* glslangStruct = type.getStruct();
+            std::vector<spv::Id> structFields;
+            spvType = structMap[glslangStruct];
+            if (spvType)
+                break;
+
+            // else, we haven't seen it...
+
+            // Create a vector of struct types for SPIR-V to consume
+            int memberDelta = 0;  // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
+            if (type.getBasicType() == glslang::EbtBlock)
+                memberRemapper[glslangStruct].resize(glslangStruct->size());
+            for (int i = 0; i < (int)glslangStruct->size(); i++) {
+                glslang::TType& glslangType = *(*glslangStruct)[i].type;
+                if (glslangType.hiddenMember()) {
+                    ++memberDelta;
+                    if (type.getBasicType() == glslang::EbtBlock)
+                        memberRemapper[glslangStruct][i] = -1;
+                } else {
+                    if (type.getBasicType() == glslang::EbtBlock)
+                        memberRemapper[glslangStruct][i] = i - memberDelta;
+                    structFields.push_back(convertGlslangToSpvType(glslangType));
+                }
+            }
+
+            // Make the SPIR-V type
+            spvType = builder.makeStructType(structFields, type.getTypeName().c_str());
+            structMap[glslangStruct] = spvType;
+
+            // Name and decorate the non-hidden members
+            for (int i = 0; i < (int)glslangStruct->size(); i++) {
+                glslang::TType& glslangType = *(*glslangStruct)[i].type;
+                int member = i;
+                if (type.getBasicType() == glslang::EbtBlock)
+                    member = memberRemapper[glslangStruct][i];
+                // using -1 above to indicate a hidden member
+                if (member >= 0) {
+                    builder.addMemberName(spvType, member, glslangType.getFieldName().c_str());
+                    addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangType));
+                    addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangType));
+                    addMemberDecoration(spvType, member, TranslateInterpolationDecoration(glslangType));
+                    addMemberDecoration(spvType, member, TranslateInvariantDecoration(glslangType));
+                    if (glslangType.getQualifier().hasLocation())
+                        builder.addMemberDecoration(spvType, member, spv::DecorationLocation, glslangType.getQualifier().layoutLocation);
+                    if (glslangType.getQualifier().hasComponent())
+                        builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangType.getQualifier().layoutComponent);
+                    if (glslangType.getQualifier().hasXfbOffset())
+                        builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutXfbOffset);
+
+                    // built-in variable decorations
+                    int builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn);
+                    if (builtIn != spv::BadValue)
+                        builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, builtIn);
+                }
+            }
+
+            // Decorate the structure
+            addDecoration(spvType, TranslateLayoutDecoration(type));
+            addDecoration(spvType, TranslateBlockDecoration(type));
+            if (type.getQualifier().hasStream())
+                builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
+            if (glslangIntermediate->getXfbMode()) {
+                if (type.getQualifier().hasXfbStride())
+                    builder.addDecoration(spvType, spv::DecorationStride, type.getQualifier().layoutXfbStride);
+                if (type.getQualifier().hasXfbBuffer())
+                    builder.addDecoration(spvType, spv::DecorationXfbBuffer, type.getQualifier().layoutXfbBuffer);
+            }
+        }
+        break;
+    default:
+        spv::MissingFunctionality("basic type");
+        break;
+    }
+
+    if (type.isMatrix())
+        spvType = builder.makeMatrixType(spvType, type.getMatrixCols(), type.getMatrixRows());
+    else {
+        // If this variable has a vector element count greater than 1, create a SPIR-V vector
+        if (type.getVectorSize() > 1)
+            spvType = builder.makeVectorType(spvType, type.getVectorSize());
+    }
+
+    if (type.isArray()) {
+        unsigned arraySize;
+        if (! type.isExplicitlySizedArray()) {
+            spv::MissingFunctionality("Unsized array");
+            arraySize = 8;
+        } else
+            arraySize = type.getArraySize();
+        spvType = builder.makeArrayType(spvType, arraySize);
+    }
+
+    return spvType;
+}
+
+bool TGlslangToSpvTraverser::isShaderEntrypoint(const glslang::TIntermAggregate* node)
+{
+    return node->getName() == "main(";
+}
+
+// Make all the functions, skeletally, without actually visiting their bodies.
+void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
+{
+    for (int f = 0; f < (int)glslFunctions.size(); ++f) {
+        glslang::TIntermAggregate* glslFunction = glslFunctions[f]->getAsAggregate();
+        if (! glslFunction || glslFunction->getOp() != glslang::EOpFunction || isShaderEntrypoint(glslFunction))
+            continue;
+
+        // We're on a user function.  Set up the basic interface for the function now,
+        // so that it's available to call.
+        // Translating the body will happen later.
+        //
+        // Typically (except for a "const in" parameter), an address will be passed to the 
+        // function.  What it is an address of varies:
+        //
+        // - "in" parameters not marked as "const" can be written to without modifying the argument,
+        //  so that write needs to be to a copy, hence the address of a copy works.
+        //
+        // - "const in" parameters can just be the r-value, as no writes need occur.
+        //
+        // - "out" and "inout" arguments can't be done as direct pointers, because GLSL has
+        // copy-in/copy-out semantics.  They can be handled though with a pointer to a copy.
+
+        std::vector<spv::Id> paramTypes;
+        glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence();
+
+        for (int p = 0; p < (int)parameters.size(); ++p) {
+            const glslang::TType& paramType = parameters[p]->getAsTyped()->getType();
+            spv::Id typeId = convertGlslangToSpvType(paramType);
+            if (paramType.getQualifier().storage != glslang::EvqConstReadOnly)
+                typeId = builder.makePointer(spv::StorageClassFunction, typeId);
+            else
+                constReadOnlyParameters.insert(parameters[p]->getAsSymbolNode()->getId());
+            paramTypes.push_back(typeId);
+        }
+
+        spv::Block* functionBlock;
+        spv::Function *function = builder.makeFunctionEntry(convertGlslangToSpvType(glslFunction->getType()), glslFunction->getName().c_str(),
+                                                              paramTypes, &functionBlock);
+
+        // Track function to emit/call later
+        functionMap[glslFunction->getName().c_str()] = function;
+
+        // Set the parameter id's
+        for (int p = 0; p < (int)parameters.size(); ++p) {
+            symbolValues[parameters[p]->getAsSymbolNode()->getId()] = function->getParamId(p);
+            // give a name too
+            builder.addName(function->getParamId(p), parameters[p]->getAsSymbolNode()->getName().c_str());
+        }
+    }
+}
+
+// Process all the initializers, while skipping the functions and link objects
+void TGlslangToSpvTraverser::makeGlobalInitializers(const glslang::TIntermSequence& initializers)
+{
+    builder.setBuildPoint(shaderEntry->getLastBlock());
+    for (int i = 0; i < (int)initializers.size(); ++i) {
+        glslang::TIntermAggregate* initializer = initializers[i]->getAsAggregate();
+        if (initializer && initializer->getOp() != glslang::EOpFunction && initializer->getOp() != glslang::EOpLinkerObjects) {
+
+            // We're on a top-level node that's not a function.  Treat as an initializer, whose
+            // code goes into the beginning of main.
+            initializer->traverse(this);
+        }
+    }
+}
+
+// Process all the functions, while skipping initializers.
+void TGlslangToSpvTraverser::visitFunctions(const glslang::TIntermSequence& glslFunctions)
+{
+    for (int f = 0; f < (int)glslFunctions.size(); ++f) {
+        glslang::TIntermAggregate* node = glslFunctions[f]->getAsAggregate();
+        if (node && (node->getOp() == glslang::EOpFunction || node->getOp() == glslang ::EOpLinkerObjects))
+            node->traverse(this);
+    }
+}
+
+void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate* node)
+{
+    // SPIR-V functions should already be in the functionMap from the prepass 
+    // that called makeFunctions().
+    spv::Function* function = functionMap[node->getName().c_str()];
+    spv::Block* functionBlock = function->getEntryBlock();
+    builder.setBuildPoint(functionBlock);
+}
+
+void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermSequence& glslangArguments, std::vector<spv::Id>& arguments)
+{
+    for (int i = 0; i < (int)glslangArguments.size(); ++i) {
+        builder.clearAccessChain();
+        glslangArguments[i]->traverse(this);
+        arguments.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArguments[i]->getAsTyped()->getType())));
+    }
+}
+
+spv::Id TGlslangToSpvTraverser::handleBuiltInFunctionCall(const glslang::TIntermAggregate* node)
+{
+    std::vector<spv::Id> arguments;
+    translateArguments(node->getSequence(), arguments);
+
+    std::vector<spv::Id> argTypes;
+    for (int a = 0; a < (int)arguments.size(); ++a)
+        argTypes.push_back(builder.getTypeId(arguments[a]));
+
+    spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
+
+    if (node->getName() == "ftransform(") {
+        spv::MissingFunctionality("ftransform()");
+        //spv::Id vertex = builder.createVariable(spv::StorageShaderGlobal, spv::VectorType::get(spv::makeFloatType(), 4),
+        //                                                             "gl_Vertex_sim");
+        //spv::Id matrix = builder.createVariable(spv::StorageShaderGlobal, spv::VectorType::get(spv::makeFloatType(), 4),
+        //                                                             "gl_ModelViewProjectionMatrix_sim");
+        return 0;
+    }
+
+    if (node->getName().substr(0, 7) == "texture" || node->getName().substr(0, 5) == "texel" || node->getName().substr(0, 6) == "shadow") {
+        const glslang::TSampler sampler = node->getSequence()[0]->getAsTyped()->getType().getSampler();
+        spv::Builder::TextureParameters params = { };
+        params.sampler = arguments[0];
+
+        // special case size query
+        if (node->getName().find("textureSize", 0) != std::string::npos) {
+            if (arguments.size() > 1) {
+                params.lod = arguments[1];
+                return builder.createTextureQueryCall(spv::OpTextureQuerySizeLod, params);
+            } else
+                return builder.createTextureQueryCall(spv::OpTextureQuerySize, params);
+        }
+
+        // special case the number of samples query
+        if (node->getName().find("textureSamples", 0) != std::string::npos)
+            return builder.createTextureQueryCall(spv::OpTextureQuerySamples, params);
+
+        // special case the other queries
+        if (node->getName().find("Query", 0) != std::string::npos) {
+            if (node->getName().find("Levels", 0) != std::string::npos)
+                return builder.createTextureQueryCall(spv::OpTextureQueryLevels, params);
+            else if (node->getName().find("Lod", 0) != std::string::npos) {
+                params.coords = arguments[1];
+                return builder.createTextureQueryCall(spv::OpTextureQueryLod, params);
+            } else
+                spv::MissingFunctionality("glslang texture query");
+        }
+
+        // This is no longer a query....
+
+        bool lod = node->getName().find("Lod", 0) != std::string::npos;
+        bool proj = node->getName().find("Proj", 0) != std::string::npos;
+        bool offsets = node->getName().find("Offsets", 0) != std::string::npos;
+        bool offset = ! offsets && node->getName().find("Offset", 0) != std::string::npos;
+        bool fetch = node->getName().find("Fetch", 0) != std::string::npos;
+        bool gather = node->getName().find("Gather", 0) != std::string::npos;
+        bool grad = node->getName().find("Grad", 0) != std::string::npos;
+
+        if (fetch)
+            spv::MissingFunctionality("texel fetch");
+        if (gather)
+            spv::MissingFunctionality("texture gather");
+
+        // check for bias argument
+        bool bias = false;
+        if (! lod && ! gather && ! grad && ! fetch) {
+            int nonBiasArgCount = 2;
+            if (offset)
+                ++nonBiasArgCount;
+            if (grad)
+                nonBiasArgCount += 2;
+
+            if ((int)arguments.size() > nonBiasArgCount)
+                bias = true;
+        }
+
+        bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
+
+        // set the rest of the arguments
+        params.coords = arguments[1];
+        int extraArgs = 0;
+        if (cubeCompare)
+            params.Dref = arguments[2];
+        if (lod) {
+            params.lod = arguments[2];
+            ++extraArgs;
+        }
+        if (grad) {
+            params.gradX = arguments[2 + extraArgs];
+            params.gradY = arguments[3 + extraArgs];
+            extraArgs += 2;
+        }
+        //if (gather && compare) {
+        //    params.compare = arguments[2 + extraArgs];
+        //    ++extraArgs;
+        //}
+        if (offset | offsets) {
+            params.offset = arguments[2 + extraArgs];
+            ++extraArgs;
+        }
+        if (bias) {
+            params.bias = arguments[2 + extraArgs];
+            ++extraArgs;
+        }
+
+        return builder.createTextureCall(precision, convertGlslangToSpvType(node->getType()), proj, params);
+    }
+
+    spv::MissingFunctionality("built-in function call");
+
+    return 0;
+}
+
+spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAggregate* node)
+{
+    // Grab the function's pointer from the previously created function
+    spv::Function* function = functionMap[node->getName().c_str()];
+    if (! function)
+        return 0;
+
+    const glslang::TIntermSequence& glslangArgs = node->getSequence();
+    const glslang::TQualifierList& qualifiers = node->getQualifierList();
+
+    //  See comments in makeFunctions() for details about the semantics for parameter passing.
+    //
+    // These imply we need a four step process:
+    // 1. Evaluate the arguments
+    // 2. Allocate and make copies of in, out, and inout arguments
+    // 3. Make the call
+    // 4. Copy back the results
+
+    // 1. Evaluate the arguments
+    std::vector<spv::Builder::AccessChain> lValues;
+    std::vector<spv::Id> rValues;
+    for (int a = 0; a < (int)glslangArgs.size(); ++a) {
+        // build l-value
+        builder.clearAccessChain();
+        glslangArgs[a]->traverse(this);
+        // keep outputs as l-values, evaluate input-only as r-values
+        if (qualifiers[a] != glslang::EvqConstReadOnly) {
+            // save l-value
+            lValues.push_back(builder.getAccessChain());
+        } else {
+            // process r-value
+            rValues.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArgs[a]->getAsTyped()->getType())));
+        }
+    }
+
+    // 2. Allocate space for anything needing a copy, and if it's "in" or "inout"
+    // copy the original into that space.
+    //
+    // Also, build up the list of actual arguments to pass in for the call
+    int lValueCount = 0;
+    int rValueCount = 0;
+    std::vector<spv::Id> spvArgs;
+    for (int a = 0; a < (int)glslangArgs.size(); ++a) {
+        spv::Id arg;
+        if (qualifiers[a] != glslang::EvqConstReadOnly) {
+            // need space to hold the copy
+            const glslang::TType& paramType = glslangArgs[a]->getAsTyped()->getType();
+            arg = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(paramType), "param");
+            if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) {
+                // need to copy the input into output space
+                builder.setAccessChain(lValues[lValueCount]);
+                spv::Id copy = builder.accessChainLoad(spv::NoPrecision);  // TODO: get precision
+                builder.createStore(copy, arg);
+            }
+            ++lValueCount;
+        } else {
+            arg = rValues[rValueCount];
+            ++rValueCount;
+        }
+        spvArgs.push_back(arg);
+    }
+
+    // 3. Make the call.
+    spv::Id result = builder.createFunctionCall(function, spvArgs);
+
+    // 4. Copy back out an "out" arguments.
+    lValueCount = 0;
+    for (int a = 0; a < (int)glslangArgs.size(); ++a) {
+        if (qualifiers[a] != glslang::EvqConstReadOnly) {
+            if (qualifiers[a] == glslang::EvqOut || qualifiers[a] == glslang::EvqInOut) {
+                spv::Id copy = builder.createLoad(spvArgs[a]);
+                builder.setAccessChain(lValues[lValueCount]);
+                builder.accessChainStore(copy);
+            }
+            ++lValueCount;
+        }
+    }
+
+    return result;
+}
+
+// Translate AST operation to SPV operation, already having SPV-based operands/types.
+spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv::Decoration precision, 
+                                                      spv::Id typeId, spv::Id left, spv::Id right,
+                                                      glslang::TBasicType typeProxy, bool reduceComparison)
+{
+    bool isUnsigned = typeProxy == glslang::EbtUint;
+    bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
+
+    spv::Op binOp = spv::OpNop;
+    bool needsPromotion = true;
+    bool comparison = false;
+
+    switch (op) {
+    case glslang::EOpAdd:
+    case glslang::EOpAddAssign:
+        if (isFloat)
+            binOp = spv::OpFAdd;
+        else
+            binOp = spv::OpIAdd;
+        break;
+    case glslang::EOpSub:
+    case glslang::EOpSubAssign:
+        if (isFloat)
+            binOp = spv::OpFSub;
+        else
+            binOp = spv::OpISub;
+        break;
+    case glslang::EOpMul:
+    case glslang::EOpMulAssign:
+        if (isFloat)
+            binOp = spv::OpFMul;
+        else
+            binOp = spv::OpIMul;
+        break;
+    case glslang::EOpVectorTimesScalar:
+    case glslang::EOpVectorTimesScalarAssign:
+        if (builder.isVector(right))
+            std::swap(left, right);
+        assert(builder.isScalar(right));
+        binOp = spv::OpVectorTimesScalar;
+        needsPromotion = false;
+        break;
+    case glslang::EOpVectorTimesMatrix:
+    case glslang::EOpVectorTimesMatrixAssign:
+        assert(builder.isVector(left));
+        assert(builder.isMatrix(right));
+        binOp = spv::OpVectorTimesMatrix;
+        break;
+    case glslang::EOpMatrixTimesVector:
+        assert(builder.isMatrix(left));
+        assert(builder.isVector(right));
+        binOp = spv::OpMatrixTimesVector;
+        break;
+    case glslang::EOpMatrixTimesScalar:
+    case glslang::EOpMatrixTimesScalarAssign:
+        if (builder.isMatrix(right))
+            std::swap(left, right);
+        assert(builder.isScalar(right));
+        binOp = spv::OpMatrixTimesScalar;
+        break;
+    case glslang::EOpMatrixTimesMatrix:
+    case glslang::EOpMatrixTimesMatrixAssign:
+        assert(builder.isMatrix(left));
+        assert(builder.isMatrix(right));
+        binOp = spv::OpMatrixTimesMatrix;
+        break;
+    case glslang::EOpOuterProduct:
+        binOp = spv::OpOuterProduct;
+        needsPromotion = false;
+        break;
+
+    case glslang::EOpDiv:
+    case glslang::EOpDivAssign:
+        if (isFloat)
+            binOp = spv::OpFDiv;
+        else if (isUnsigned)
+            binOp = spv::OpUDiv;
+        else
+            binOp = spv::OpSDiv;
+        break;
+    case glslang::EOpMod:
+    case glslang::EOpModAssign:
+        if (isFloat)
+            binOp = spv::OpFMod;
+        else if (isUnsigned)
+            binOp = spv::OpUMod;
+        else
+            binOp = spv::OpSMod;
+        break;
+    case glslang::EOpRightShift:
+    case glslang::EOpRightShiftAssign:
+        if (isUnsigned)
+            binOp = spv::OpShiftRightLogical;
+        else
+            binOp = spv::OpShiftRightArithmetic;
+        break;
+    case glslang::EOpLeftShift:
+    case glslang::EOpLeftShiftAssign:
+        binOp = spv::OpShiftLeftLogical;
+        break;
+    case glslang::EOpAnd:
+    case glslang::EOpAndAssign:
+        binOp = spv::OpBitwiseAnd;
+        break;
+    case glslang::EOpLogicalAnd:
+        needsPromotion = false;
+        binOp = spv::OpLogicalAnd;
+        break;
+    case glslang::EOpInclusiveOr:
+    case glslang::EOpInclusiveOrAssign:
+        binOp = spv::OpBitwiseOr;
+        break;
+    case glslang::EOpLogicalOr:
+        needsPromotion = false;
+        binOp = spv::OpLogicalOr;
+        break;
+    case glslang::EOpExclusiveOr:
+    case glslang::EOpExclusiveOrAssign:
+        binOp = spv::OpBitwiseXor;
+        break;
+    case glslang::EOpLogicalXor:
+        needsPromotion = false;
+        binOp = spv::OpLogicalXor;
+        break;
+
+    case glslang::EOpLessThan:
+    case glslang::EOpGreaterThan:
+    case glslang::EOpLessThanEqual:
+    case glslang::EOpGreaterThanEqual:
+    case glslang::EOpEqual:
+    case glslang::EOpNotEqual:
+    case glslang::EOpVectorEqual:
+    case glslang::EOpVectorNotEqual:
+        comparison = true;
+        break;
+    default:
+        break;
+    }
+
+    if (binOp != spv::OpNop) {
+        if (builder.isMatrix(left) || builder.isMatrix(right)) {
+            switch (binOp) {
+            case spv::OpMatrixTimesScalar:
+            case spv::OpVectorTimesMatrix:
+            case spv::OpMatrixTimesVector:
+            case spv::OpMatrixTimesMatrix:
+                break;
+            case spv::OpFDiv:
+                // turn it into a multiply...
+                assert(builder.isMatrix(left) && builder.isScalar(right));
+                right = builder.createBinOp(spv::OpFDiv, builder.getTypeId(right), builder.makeFloatConstant(1.0F), right);
+                binOp = spv::OpFMul;
+                break;
+            default:
+                spv::MissingFunctionality("binary operation on matrix");
+                break;
+            }
+
+            spv::Id id = builder.createBinOp(binOp, typeId, left, right);
+            builder.setPrecision(id, precision);
+
+            return id;
+        }
+
+        // No matrix involved; make both operands be the same number of components, if needed
+        if (needsPromotion)
+            builder.promoteScalar(precision, left, right);
+
+        spv::Id id = builder.createBinOp(binOp, typeId, left, right);
+        builder.setPrecision(id, precision);
+
+        return id;
+    }
+
+    if (! comparison)
+        return 0;
+
+    // Comparison instructions
+
+    if (reduceComparison && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) {
+        assert(op == glslang::EOpEqual || op == glslang::EOpNotEqual);
+
+        return builder.createCompare(precision, left, right, op == glslang::EOpEqual);
+    }
+
+    switch (op) {
+    case glslang::EOpLessThan:
+        if (isFloat)
+            binOp = spv::OpFOrdLessThan;
+        else if (isUnsigned)
+            binOp = spv::OpULessThan;
+        else
+            binOp = spv::OpSLessThan;
+        break;
+    case glslang::EOpGreaterThan:
+        if (isFloat)
+            binOp = spv::OpFOrdGreaterThan;
+        else if (isUnsigned)
+            binOp = spv::OpUGreaterThan;
+        else
+            binOp = spv::OpSGreaterThan;
+        break;
+    case glslang::EOpLessThanEqual:
+        if (isFloat)
+            binOp = spv::OpFOrdLessThanEqual;
+        else if (isUnsigned)
+            binOp = spv::OpULessThanEqual;
+        else
+            binOp = spv::OpSLessThanEqual;
+        break;
+    case glslang::EOpGreaterThanEqual:
+        if (isFloat)
+            binOp = spv::OpFOrdGreaterThanEqual;
+        else if (isUnsigned)
+            binOp = spv::OpUGreaterThanEqual;
+        else
+            binOp = spv::OpSGreaterThanEqual;
+        break;
+    case glslang::EOpEqual:
+    case glslang::EOpVectorEqual:
+        if (isFloat)
+            binOp = spv::OpFOrdEqual;
+        else
+            binOp = spv::OpIEqual;
+        break;
+    case glslang::EOpNotEqual:
+    case glslang::EOpVectorNotEqual:
+        if (isFloat)
+            binOp = spv::OpFOrdNotEqual;
+        else
+            binOp = spv::OpINotEqual;
+        break;
+    default:
+        break;
+    }
+
+    if (binOp != spv::OpNop) {
+        spv::Id id = builder.createBinOp(binOp, typeId, left, right);
+        builder.setPrecision(id, precision);
+
+        return id;
+    }
+
+    return 0;
+}
+
+spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, bool isFloat)
+{
+    spv::Op unaryOp = spv::OpNop;
+    int libCall = -1;
+
+    switch (op) {
+    case glslang::EOpNegative:
+        if (isFloat)
+            unaryOp = spv::OpFNegate;
+        else
+            unaryOp = spv::OpSNegate;
+        break;
+
+    case glslang::EOpLogicalNot:
+    case glslang::EOpVectorLogicalNot:
+    case glslang::EOpBitwiseNot:
+        unaryOp = spv::OpNot;
+        break;
+    
+    case glslang::EOpDeterminant:
+        libCall = GLSL_STD_450::Determinant;
+        break;
+    case glslang::EOpMatrixInverse:
+        libCall = GLSL_STD_450::MatrixInverse;
+        break;
+    case glslang::EOpTranspose:
+        unaryOp = spv::OpTranspose;
+        break;
+
+    case glslang::EOpRadians:
+        libCall = GLSL_STD_450::Radians;
+        break;
+    case glslang::EOpDegrees:
+        libCall = GLSL_STD_450::Degrees;
+        break;
+    case glslang::EOpSin:
+        libCall = GLSL_STD_450::Sin;
+        break;
+    case glslang::EOpCos:
+        libCall = GLSL_STD_450::Cos;
+        break;
+    case glslang::EOpTan:
+        libCall = GLSL_STD_450::Tan;
+        break;
+    case glslang::EOpAcos:
+        libCall = GLSL_STD_450::Acos;
+        break;
+    case glslang::EOpAsin:
+        libCall = GLSL_STD_450::Asin;
+        break;
+    case glslang::EOpAtan:
+        libCall = GLSL_STD_450::Atan;
+        break;
+
+    case glslang::EOpAcosh:
+        libCall = GLSL_STD_450::Acosh;
+        break;
+    case glslang::EOpAsinh:
+        libCall = GLSL_STD_450::Asinh;
+        break;
+    case glslang::EOpAtanh:
+        libCall = GLSL_STD_450::Atanh;
+        break;
+    case glslang::EOpTanh:
+        libCall = GLSL_STD_450::Tanh;
+        break;
+    case glslang::EOpCosh:
+        libCall = GLSL_STD_450::Cosh;
+        break;
+    case glslang::EOpSinh:
+        libCall = GLSL_STD_450::Sinh;
+        break;
+
+    case glslang::EOpLength:
+        libCall = GLSL_STD_450::Length;
+        break;
+    case glslang::EOpNormalize:
+        libCall = GLSL_STD_450::Normalize;
+        break;
+
+    case glslang::EOpExp:
+        libCall = GLSL_STD_450::Exp;
+        break;
+    case glslang::EOpLog:
+        libCall = GLSL_STD_450::Log;
+        break;
+    case glslang::EOpExp2:
+        libCall = GLSL_STD_450::Exp2;
+        break;
+    case glslang::EOpLog2:
+        libCall = GLSL_STD_450::Log2;
+        break;
+    case glslang::EOpSqrt:
+        libCall = GLSL_STD_450::Sqrt;
+        break;
+    case glslang::EOpInverseSqrt:
+        libCall = GLSL_STD_450::InverseSqrt;
+        break;
+
+    case glslang::EOpFloor:
+        libCall = GLSL_STD_450::Floor;
+        break;
+    case glslang::EOpTrunc:
+        libCall = GLSL_STD_450::Trunc;
+        break;
+    case glslang::EOpRound:
+        libCall = GLSL_STD_450::Round;
+        break;
+    case glslang::EOpRoundEven:
+        libCall = GLSL_STD_450::RoundEven;
+        break;
+    case glslang::EOpCeil:
+        libCall = GLSL_STD_450::Ceil;
+        break;
+    case glslang::EOpFract:
+        libCall = GLSL_STD_450::Fract;
+        break;
+
+    case glslang::EOpIsNan:
+        unaryOp = spv::OpIsNan;
+        break;
+    case glslang::EOpIsInf:
+        unaryOp = spv::OpIsInf;
+        break;
+
+    case glslang::EOpFloatBitsToInt:
+        libCall = GLSL_STD_450::FloatBitsToInt;
+        break;
+    case glslang::EOpFloatBitsToUint:
+        libCall = GLSL_STD_450::FloatBitsToUint;
+        break;
+    case glslang::EOpIntBitsToFloat:
+        libCall = GLSL_STD_450::IntBitsToFloat;
+        break;
+    case glslang::EOpUintBitsToFloat:
+        libCall = GLSL_STD_450::UintBitsToFloat;
+        break;
+    case glslang::EOpPackSnorm2x16:
+        libCall = GLSL_STD_450::PackSnorm2x16;
+        break;
+    case glslang::EOpUnpackSnorm2x16:
+        libCall = GLSL_STD_450::UnpackSnorm2x16;
+        break;
+    case glslang::EOpPackUnorm2x16:
+        libCall = GLSL_STD_450::PackUnorm2x16;
+        break;
+    case glslang::EOpUnpackUnorm2x16:
+        libCall = GLSL_STD_450::UnpackUnorm2x16;
+        break;
+    case glslang::EOpPackHalf2x16:
+        libCall = GLSL_STD_450::PackHalf2x16;
+        break;
+    case glslang::EOpUnpackHalf2x16:
+        libCall = GLSL_STD_450::UnpackHalf2x16;
+        break;
+
+    case glslang::EOpDPdx:
+        unaryOp = spv::OpDPdx;
+        break;
+    case glslang::EOpDPdy:
+        unaryOp = spv::OpDPdy;
+        break;
+    case glslang::EOpFwidth:
+        unaryOp = spv::OpFwidth;
+        break;
+    case glslang::EOpDPdxFine:
+        unaryOp = spv::OpDPdxFine;
+        break;
+    case glslang::EOpDPdyFine:
+        unaryOp = spv::OpDPdyFine;
+        break;
+    case glslang::EOpFwidthFine:
+        unaryOp = spv::OpFwidthFine;
+        break;
+    case glslang::EOpDPdxCoarse:
+        unaryOp = spv::OpDPdxCoarse;
+        break;
+    case glslang::EOpDPdyCoarse:
+        unaryOp = spv::OpDPdyCoarse;
+        break;
+    case glslang::EOpFwidthCoarse:
+        unaryOp = spv::OpFwidthCoarse;
+        break;
+
+    case glslang::EOpAny:
+        unaryOp = spv::OpAny;
+        break;
+    case glslang::EOpAll:
+        unaryOp = spv::OpAll;
+        break;
+
+    case glslang::EOpAbs:
+        libCall = GLSL_STD_450::Abs;
+        break;
+    case glslang::EOpSign:
+        libCall = GLSL_STD_450::Sign;
+        break;
+
+    default:
+        return 0;
+    }
+
+    spv::Id id;
+    if (libCall >= 0) {
+        std::vector<spv::Id> args;
+        args.push_back(operand);
+        id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, args);
+    } else
+        id = builder.createUnaryOp(unaryOp, typeId, operand);
+
+    builder.setPrecision(id, precision);
+
+    return id;
+}
+
+spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destType, spv::Id operand)
+{
+    spv::Op convOp = spv::OpNop;
+    spv::Id zero = 0;
+    spv::Id one = 0;
+
+    int vectorSize = builder.isVectorType(destType) ? builder.getNumTypeComponents(destType) : 0;
+
+    switch (op) {
+    case glslang::EOpConvIntToBool:
+    case glslang::EOpConvUintToBool:
+        zero = builder.makeUintConstant(0);
+        zero = makeSmearedConstant(zero, vectorSize);
+        return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
+
+    case glslang::EOpConvFloatToBool:
+        zero = builder.makeFloatConstant(0.0F);
+        zero = makeSmearedConstant(zero, vectorSize);
+        return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
+
+    case glslang::EOpConvDoubleToBool:
+        zero = builder.makeDoubleConstant(0.0);
+        zero = makeSmearedConstant(zero, vectorSize);
+        return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
+
+    case glslang::EOpConvBoolToFloat:
+        convOp = spv::OpSelect;
+        zero = builder.makeFloatConstant(0.0);
+        one  = builder.makeFloatConstant(1.0);
+        break;
+    case glslang::EOpConvBoolToDouble:
+        convOp = spv::OpSelect;
+        zero = builder.makeDoubleConstant(0.0);
+        one  = builder.makeDoubleConstant(1.0);
+        break;
+    case glslang::EOpConvBoolToInt:
+        zero = builder.makeIntConstant(0);
+        one  = builder.makeIntConstant(1);
+        convOp = spv::OpSelect;
+        break;
+    case glslang::EOpConvBoolToUint:
+        zero = builder.makeUintConstant(0);
+        one  = builder.makeUintConstant(1);
+        convOp = spv::OpSelect;
+        break;
+
+    case glslang::EOpConvIntToFloat:
+    case glslang::EOpConvIntToDouble:
+        convOp = spv::OpConvertSToF;
+        break;
+
+    case glslang::EOpConvUintToFloat:
+    case glslang::EOpConvUintToDouble:
+        convOp = spv::OpConvertUToF;
+        break;
+
+    case glslang::EOpConvDoubleToFloat:
+    case glslang::EOpConvFloatToDouble:
+        convOp = spv::OpFConvert;
+        break;
+
+    case glslang::EOpConvFloatToInt:
+    case glslang::EOpConvDoubleToInt:
+        convOp = spv::OpConvertFToS;
+        break;
+
+    case glslang::EOpConvUintToInt:
+    case glslang::EOpConvIntToUint:
+        convOp = spv::OpBitcast;
+        break;
+
+    case glslang::EOpConvFloatToUint:
+    case glslang::EOpConvDoubleToUint:
+        convOp = spv::OpConvertFToU;
+        break;
+    default:
+        break;
+    }
+
+    spv::Id result = 0;
+    if (convOp == spv::OpNop)
+        return result;
+
+    if (convOp == spv::OpSelect) {
+        zero = makeSmearedConstant(zero, vectorSize);
+        one  = makeSmearedConstant(one, vectorSize);
+        result = builder.createTriOp(convOp, destType, operand, one, zero);
+    } else
+        result = builder.createUnaryOp(convOp, destType, operand);
+
+    builder.setPrecision(result, precision);
+
+    return result;
+}
+
+spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vectorSize)
+{
+    if (vectorSize == 0)
+        return constant;
+
+    spv::Id vectorTypeId = builder.makeVectorType(builder.getTypeId(constant), vectorSize);
+    std::vector<spv::Id> components;
+    for (int c = 0; c < vectorSize; ++c)
+        components.push_back(constant);
+    return builder.makeCompositeConstant(vectorTypeId, components);
+}
+
+spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands)
+{
+    spv::Op opCode = spv::OpNop;
+    int libCall = -1;
+
+    switch (op) {
+    case glslang::EOpMin:
+        libCall = GLSL_STD_450::Min;
+        break;
+    case glslang::EOpModf:
+        libCall = GLSL_STD_450::Modf;
+        break;
+    case glslang::EOpMax:
+        libCall = GLSL_STD_450::Max;
+        break;
+    case glslang::EOpPow:
+        libCall = GLSL_STD_450::Pow;
+        break;
+    case glslang::EOpDot:
+        opCode = spv::OpDot;
+        break;
+    case glslang::EOpAtan:
+        libCall = GLSL_STD_450::Atan2;
+        break;
+
+    case glslang::EOpClamp:
+        libCall = GLSL_STD_450::Clamp;
+        break;
+    case glslang::EOpMix:
+        libCall = GLSL_STD_450::Mix;
+        break;
+    case glslang::EOpStep:
+        libCall = GLSL_STD_450::Step;
+        break;
+    case glslang::EOpSmoothStep:
+        libCall = GLSL_STD_450::SmoothStep;
+        break;
+
+    case glslang::EOpDistance:
+        libCall = GLSL_STD_450::Distance;
+        break;
+    case glslang::EOpCross:
+        libCall = GLSL_STD_450::Cross;
+        break;
+    case glslang::EOpFaceForward:
+        libCall = GLSL_STD_450::FaceForward;
+        break;
+    case glslang::EOpReflect:
+        libCall = GLSL_STD_450::Reflect;
+        break;
+    case glslang::EOpRefract:
+        libCall = GLSL_STD_450::Refract;
+        break;
+    default:
+        return 0;
+    }
+
+    spv::Id id = 0;
+    if (libCall >= 0)
+        id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, operands);
+    else {
+        switch (operands.size()) {
+        case 0:
+            // should all be handled by visitAggregate and createNoArgOperation
+            assert(0);
+            return 0;
+        case 1:
+            // should all be handled by createUnaryOperation
+            assert(0);
+            return 0;
+        case 2:
+            id = builder.createBinOp(opCode, typeId, operands[0], operands[1]);
+            break;
+        case 3:
+            id = builder.createTernaryOp(opCode, typeId, operands[0], operands[1], operands[2]);
+            break;
+        default:
+            // These do not exist yet
+            assert(0 && "operation with more than 3 operands");
+            break;
+        }
+    }
+
+    builder.setPrecision(id, precision);
+
+    return id;
+}
+
+// Intrinsics with no arguments, no return value, and no precision.
+spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op)
+{
+    // TODO: get the barrier operands correct
+
+    switch (op) {
+    case glslang::EOpEmitVertex:
+        builder.createNoResultOp(spv::OpEmitVertex);
+        return 0;
+    case glslang::EOpEndPrimitive:
+        builder.createNoResultOp(spv::OpEndPrimitive);
+        return 0;
+    case glslang::EOpBarrier:
+        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsAllMemory);
+        builder.createControlBarrier(spv::ExecutionScopeDevice);
+        return 0;
+    case glslang::EOpMemoryBarrier:
+        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsAllMemory);
+        return 0;
+    case glslang::EOpMemoryBarrierAtomicCounter:
+        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsAtomicCounterMemoryMask);
+        return 0;
+    case glslang::EOpMemoryBarrierBuffer:
+        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsUniformMemoryMask);
+        return 0;
+    case glslang::EOpMemoryBarrierImage:
+        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsImageMemoryMask);
+        return 0;
+    case glslang::EOpMemoryBarrierShared:
+        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsWorkgroupLocalMemoryMask);
+        return 0;
+    case glslang::EOpGroupMemoryBarrier:
+        builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsWorkgroupGlobalMemoryMask);
+        return 0;
+    default:
+        spv::MissingFunctionality("operation with no arguments");
+        return 0;
+    }
+}
+
+spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol)
+{
+    std::map<int, spv::Id>::iterator iter;
+    iter = symbolValues.find(symbol->getId());
+    spv::Id id;
+    if (symbolValues.end() != iter) {
+        id = iter->second;
+        return id;
+    }
+
+    // it was not found, create it
+    id = createSpvVariable(symbol);
+    symbolValues[symbol->getId()] = id;
+
+    if (! symbol->getType().isStruct()) {
+        addDecoration(id, TranslatePrecisionDecoration(symbol->getType()));
+        addDecoration(id, TranslateInterpolationDecoration(symbol->getType()));
+        if (symbol->getQualifier().hasLocation())
+            builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
+        if (symbol->getQualifier().hasIndex())
+            builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
+        if (symbol->getQualifier().hasComponent())
+            builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent);
+        if (glslangIntermediate->getXfbMode()) {
+            if (symbol->getQualifier().hasXfbStride())
+                builder.addDecoration(id, spv::DecorationStride, symbol->getQualifier().layoutXfbStride);
+            if (symbol->getQualifier().hasXfbBuffer())
+                builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer);
+            if (symbol->getQualifier().hasXfbOffset())
+                builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset);
+        }
+    }
+
+    addDecoration(id, TranslateInvariantDecoration(symbol->getType()));
+    if (symbol->getQualifier().hasStream())
+        builder.addDecoration(id, spv::DecorationStream, symbol->getQualifier().layoutStream);
+    if (symbol->getQualifier().hasSet())
+        builder.addDecoration(id, spv::DecorationDescriptorSet, symbol->getQualifier().layoutSet);
+    if (symbol->getQualifier().hasBinding())
+        builder.addDecoration(id, spv::DecorationBinding, symbol->getQualifier().layoutBinding);
+    if (glslangIntermediate->getXfbMode()) {
+        if (symbol->getQualifier().hasXfbStride())
+            builder.addDecoration(id, spv::DecorationStride, symbol->getQualifier().layoutXfbStride);
+        if (symbol->getQualifier().hasXfbBuffer())
+            builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer);
+    }
+
+    // built-in variable decorations
+    int builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn);
+    if (builtIn != spv::BadValue)
+        builder.addDecoration(id, spv::DecorationBuiltIn, builtIn);
+
+    if (linkageOnly)
+        builder.addDecoration(id, spv::DecorationNoStaticUse);
+
+    return id;
+}
+
+void TGlslangToSpvTraverser::addDecoration(spv::Id id, spv::Decoration dec)
+{
+    if (dec != spv::BadValue)
+        builder.addDecoration(id, dec);
+}
+
+void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::Decoration dec)
+{
+    if (dec != spv::BadValue)
+        builder.addMemberDecoration(id, (unsigned)member, dec);
+}
+
+// Use 'consts' as the flattened glslang source of scalar constants to recursively
+// build the aggregate SPIR-V constant.
+//
+// If there are not enough elements present in 'consts', 0 will be substituted;
+// an empty 'consts' can be used to create a fully zeroed SPIR-V constant.
+//
+spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangType, const glslang::TConstUnionArray& consts, int& nextConst)
+{
+    // vector of constants for SPIR-V
+    std::vector<spv::Id> spvConsts;
+
+    // Type is used for struct and array constants
+    spv::Id typeId = convertGlslangToSpvType(glslangType);
+
+    if (glslangType.isArray()) {
+        glslang::TType elementType;
+        elementType.shallowCopy(glslangType);   // TODO: desktop arrays of arrays functionality will need a deeper copy to avoid modifying the original
+        elementType.dereference();
+        for (int i = 0; i < glslangType.getArraySize(); ++i)
+            spvConsts.push_back(createSpvConstant(elementType, consts, nextConst));
+    } else if (glslangType.isMatrix()) {
+        glslang::TType vectorType;
+        vectorType.shallowCopy(glslangType);
+        vectorType.dereference();
+        for (int col = 0; col < glslangType.getMatrixCols(); ++col)
+            spvConsts.push_back(createSpvConstant(vectorType, consts, nextConst));
+    } else if (glslangType.getStruct()) {
+        glslang::TVector<glslang::TTypeLoc>::const_iterator iter;
+        for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter)
+            spvConsts.push_back(createSpvConstant(*iter->type, consts, nextConst));
+    } else if (glslangType.isVector()) {
+        for (unsigned int i = 0; i < (unsigned int)glslangType.getVectorSize(); ++i) {
+            bool zero = nextConst >= consts.size();
+            switch (glslangType.getBasicType()) {
+            case glslang::EbtInt:
+                spvConsts.push_back(builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst()));
+                break;
+            case glslang::EbtUint:
+                spvConsts.push_back(builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst()));
+                break;
+            case glslang::EbtFloat:
+                spvConsts.push_back(builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
+                break;
+            case glslang::EbtDouble:
+                spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst()));
+                break;
+            case glslang::EbtBool:
+                spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst()));
+                break;
+            default:
+                spv::MissingFunctionality("constant vector type");
+                break;
+            }
+            ++nextConst;
+        }
+    } else {
+        // we have a non-aggregate (scalar) constant
+        bool zero = nextConst >= consts.size();
+        spv::Id scalar = 0;
+        switch (glslangType.getBasicType()) {
+        case glslang::EbtInt:
+            scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst());
+            break;
+        case glslang::EbtUint:
+            scalar = builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst());
+            break;
+        case glslang::EbtFloat:
+            scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst());
+            break;
+        case glslang::EbtDouble:
+            scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst());
+            break;
+        case glslang::EbtBool:
+            scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst());
+            break;
+        default:
+            spv::MissingFunctionality("constant scalar type");
+            break;
+        }
+        ++nextConst;
+        return scalar;
+    }
+
+    return builder.makeCompositeConstant(typeId, spvConsts);
+}
+
+};  // end anonymous namespace
+
+namespace glslang {
+
+// Write SPIR-V out to a binary file
+void OutputSpv(const std::vector<unsigned int>& spirv, const char* baseName)
+{
+    std::ofstream out;
+    std::string fileName(baseName);
+    fileName.append(".spv");
+    out.open(fileName.c_str(), std::ios::binary | std::ios::out);
+    for (int i = 0; i < (int)spirv.size(); ++i) {
+        unsigned int word = spirv[i];
+        out.write((const char*)&word, 4);
+    }
+    out.close();
+}
+
+//
+// Set up the glslang traversal
+//
+void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv)
+{
+    TIntermNode* root = intermediate.getTreeRoot();
+
+    if (root == 0)
+        return;
+
+    glslang::GetThreadPoolAllocator().push();
+
+    TGlslangToSpvTraverser it(&intermediate);
+
+    root->traverse(&it);
+
+    it.dumpSpv(spirv);
+
+    glslang::GetThreadPoolAllocator().pop();
+}
+
+}; // end namespace glslang
