//
// Copyright (C) 2016-2017 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.
//

#ifndef GLSLANG_WEB

#include "../Include/Common.h"
#include "../Include/InfoSink.h"

#include "gl_types.h"
#include "iomapper.h"

//
// Map IO bindings.
//
// High-level algorithm for one stage:
//
// 1. Traverse all code (live+dead) to find the explicitly provided bindings.
//
// 2. Traverse (just) the live code to determine which non-provided bindings
//    require auto-numbering.  We do not auto-number dead ones.
//
// 3. Traverse all the code to apply the bindings:
//    a. explicitly given bindings are offset according to their type
//    b. implicit live bindings are auto-numbered into the holes, using
//       any open binding slot.
//    c. implicit dead bindings are left un-bound.
//

namespace glslang {

class TVarGatherTraverser : public TLiveTraverser {
public:
    TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList)
      : TLiveTraverser(i, traverseDeadCode, true, true, false)
      , inputList(inList)
      , outputList(outList)
      , uniformList(uniformList)
    {
    }

    virtual void visitSymbol(TIntermSymbol* base)
    {
        TVarLiveMap* target = nullptr;
        if (base->getQualifier().storage == EvqVaryingIn)
            target = &inputList;
        else if (base->getQualifier().storage == EvqVaryingOut)
            target = &outputList;
        else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
            target = &uniformList;
        if (target) {
            TVarEntryInfo ent = {base->getId(), base, ! traverseAll};
            ent.stage = intermediate.getStage();
            TVarLiveMap::iterator at = target->find(
                ent.symbol->getName()); // std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById());
            if (at != target->end() && at->second.id == ent.id)
                at->second.live = at->second.live || ! traverseAll; // update live state
            else
                (*target)[ent.symbol->getName()] = ent;
        }
    }

private:
    TVarLiveMap&    inputList;
    TVarLiveMap&    outputList;
    TVarLiveMap&    uniformList;
};

class TVarSetTraverser : public TLiveTraverser
{
public:
    TVarSetTraverser(const TIntermediate& i, const TVarLiveMap& inList, const TVarLiveMap& outList, const TVarLiveMap& uniformList)
      : TLiveTraverser(i, true, true, true, false)
      , inputList(inList)
      , outputList(outList)
      , uniformList(uniformList)
    {
    }

    virtual void visitSymbol(TIntermSymbol* base) {
        const TVarLiveMap* source;
        if (base->getQualifier().storage == EvqVaryingIn)
            source = &inputList;
        else if (base->getQualifier().storage == EvqVaryingOut)
            source = &outputList;
        else if (base->getQualifier().isUniformOrBuffer())
            source = &uniformList;
        else
            return;

        TVarEntryInfo ent = { base->getId() };
        TVarLiveMap::const_iterator at = source->find(base->getName());
        if (at == source->end())
            return;

        if (at->second.id != ent.id)
            return;

        if (at->second.newBinding != -1)
            base->getWritableType().getQualifier().layoutBinding = at->second.newBinding;
        if (at->second.newSet != -1)
            base->getWritableType().getQualifier().layoutSet = at->second.newSet;
        if (at->second.newLocation != -1)
            base->getWritableType().getQualifier().layoutLocation = at->second.newLocation;
        if (at->second.newComponent != -1)
            base->getWritableType().getQualifier().layoutComponent = at->second.newComponent;
        if (at->second.newIndex != -1)
            base->getWritableType().getQualifier().layoutIndex = at->second.newIndex;
    }

  private:
    const TVarLiveMap&    inputList;
    const TVarLiveMap&    outputList;
    const TVarLiveMap&    uniformList;
};

struct TNotifyUniformAdaptor
{
    EShLanguage stage;
    TIoMapResolver& resolver;
    inline TNotifyUniformAdaptor(EShLanguage s, TIoMapResolver& r)
      : stage(s)
      , resolver(r)
    {
    }

    inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey)
    {
        resolver.notifyBinding(stage, entKey.second);
    }

private:
    TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&) = delete;
};

struct TNotifyInOutAdaptor
{
    EShLanguage stage;
    TIoMapResolver& resolver;
    inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r) 
      : stage(s)
      , resolver(r)
    {
    }

    inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey)
    {
        resolver.notifyInOut(stage, entKey.second);
    }

private:
    TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&) = delete;
};

struct TResolverUniformAdaptor {
    TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e)
      : stage(s)
      , resolver(r)
      , infoSink(i)
      , error(e)
    {
    }

    inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey) {
        TVarEntryInfo& ent = entKey.second;
        ent.newLocation = -1;
        ent.newComponent = -1;
        ent.newBinding = -1;
        ent.newSet = -1;
        ent.newIndex = -1;
        const bool isValid = resolver.validateBinding(stage, ent);
        if (isValid) {
            resolver.resolveBinding(stage, ent);
            resolver.resolveSet(stage, ent);
            resolver.resolveUniformLocation(stage, ent);

            if (ent.newBinding != -1) {
                if (ent.newBinding >= int(TQualifier::layoutBindingEnd)) {
                    TString err = "mapped binding out of range: " + entKey.first;

                    infoSink.info.message(EPrefixInternalError, err.c_str());
                    error = true;
                }
            }
            if (ent.newSet != -1) {
                if (ent.newSet >= int(TQualifier::layoutSetEnd)) {
                    TString err = "mapped set out of range: " + entKey.first;

                    infoSink.info.message(EPrefixInternalError, err.c_str());
                    error = true;
                }
            }
        } else {
            TString errorMsg = "Invalid binding: " + entKey.first;
            infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
            error = true;
        }
    }

    inline void setStage(EShLanguage s) { stage = s; }

    EShLanguage     stage;
    TIoMapResolver& resolver;
    TInfoSink&      infoSink;
    bool&           error;

private:
    TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&) = delete;
};

struct TResolverInOutAdaptor {
    TResolverInOutAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e)
      : stage(s)
      , resolver(r)
      , infoSink(i)
      , error(e)
    {
    }

    inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey)
    {
        TVarEntryInfo& ent = entKey.second;
        ent.newLocation = -1;
        ent.newComponent = -1;
        ent.newBinding = -1;
        ent.newSet = -1;
        ent.newIndex = -1;
        const bool isValid = resolver.validateInOut(stage, ent);
        if (isValid) {
            resolver.resolveInOutLocation(stage, ent);
            resolver.resolveInOutComponent(stage, ent);
            resolver.resolveInOutIndex(stage, ent);
        } else {
            TString errorMsg;
            if (ent.symbol->getType().getQualifier().semanticName != nullptr) {
                errorMsg = "Invalid shader In/Out variable semantic: ";
                errorMsg += ent.symbol->getType().getQualifier().semanticName;
            } else {
                errorMsg = "Invalid shader In/Out variable: ";
                errorMsg += ent.symbol->getName();
            }
            infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
            error = true;
        }
    }

    inline void setStage(EShLanguage s) { stage = s; }

    EShLanguage     stage;
    TIoMapResolver& resolver;
    TInfoSink&      infoSink;
    bool&           error;

private:
    TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&) = delete;
};

// The class is used for reserving explicit uniform locations and ubo/ssbo/opaque bindings

struct TSymbolValidater
{
    TSymbolValidater(TIoMapResolver& r, TInfoSink& i, TVarLiveMap* in[EShLangCount], TVarLiveMap* out[EShLangCount],
                     TVarLiveMap* uniform[EShLangCount], bool& hadError)
        : preStage(EShLangCount)
        , currentStage(EShLangCount)
        , nextStage(EShLangCount)
        , resolver(r)
        , infoSink(i)
        , hadError(hadError)
    {
        memcpy(inVarMaps, in, EShLangCount * (sizeof(TVarLiveMap*)));
        memcpy(outVarMaps, out, EShLangCount * (sizeof(TVarLiveMap*)));
        memcpy(uniformVarMap, uniform, EShLangCount * (sizeof(TVarLiveMap*)));
    }

    inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey) {
        TVarEntryInfo& ent1 = entKey.second;
        TIntermSymbol* base = ent1.symbol;
        const TType& type = ent1.symbol->getType();
        const TString& name = entKey.first;
        TString mangleName1, mangleName2;
        type.appendMangledName(mangleName1);
        EShLanguage stage = ent1.stage;
        if (currentStage != stage) {
            preStage = currentStage;
            currentStage = stage;
            nextStage = EShLangCount;
            for (int i = currentStage + 1; i < EShLangCount; i++) {
                if (inVarMaps[i] != nullptr)
                    nextStage = static_cast<EShLanguage>(i);
            }
        }
        if (base->getQualifier().storage == EvqVaryingIn) {
            // validate stage in;
            if (preStage == EShLangCount)
                return;
            if (outVarMaps[preStage] != nullptr) {
                auto ent2 = outVarMaps[preStage]->find(name);
                if (ent2 != outVarMaps[preStage]->end()) {
                    ent2->second.symbol->getType().appendMangledName(mangleName2);
                    if (mangleName1 == mangleName2)
                        return;
                    else {
                        TString err = "Invalid In/Out variable type : " + entKey.first;
                        infoSink.info.message(EPrefixInternalError, err.c_str());
                        hadError = true;
                    }
                }
                return;
            }
        } else if (base->getQualifier().storage == EvqVaryingOut) {
            // validate stage out;
            if (nextStage == EShLangCount)
                return;
            if (outVarMaps[nextStage] != nullptr) {
                auto ent2 = inVarMaps[nextStage]->find(name);
                if (ent2 != inVarMaps[nextStage]->end()) {
                    ent2->second.symbol->getType().appendMangledName(mangleName2);
                    if (mangleName1 == mangleName2)
                        return;
                    else {
                        TString err = "Invalid In/Out variable type : " + entKey.first;
                        infoSink.info.message(EPrefixInternalError, err.c_str());
                        hadError = true;
                    }
                }
                return;
            }
        } else if (base->getQualifier().isUniformOrBuffer() && ! base->getQualifier().isPushConstant()) {
            // validate uniform type;
            for (int i = 0; i < EShLangCount; i++) {
                if (i != currentStage && outVarMaps[i] != nullptr) {
                    auto ent2 = uniformVarMap[i]->find(name);
                    if (ent2 != uniformVarMap[i]->end()) {
                        ent2->second.symbol->getType().appendMangledName(mangleName2);
                        if (mangleName1 != mangleName2) {
                            TString err = "Invalid Uniform variable type : " + entKey.first;
                            infoSink.info.message(EPrefixInternalError, err.c_str());
                            hadError = true;
                        }
                        mangleName2.clear();
                    }
                }
            }
        }
    }
    TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], *uniformVarMap[EShLangCount];
    // Use for mark pre stage, to get more interface symbol information.
    EShLanguage preStage, currentStage, nextStage;
    // Use for mark current shader stage for resolver
    TIoMapResolver& resolver;
    TInfoSink& infoSink;
    bool& hadError;

private:
    TSymbolValidater& operator=(TSymbolValidater&) = delete;
};

struct TSlotCollector {
    TSlotCollector(TIoMapResolver& r, TInfoSink& i) : resolver(r), infoSink(i) { }

    inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey) {
        resolver.reserverStorageSlot(entKey.second, infoSink);
        resolver.reserverResourceSlot(entKey.second, infoSink);
    }
    TIoMapResolver& resolver;
    TInfoSink& infoSink;

private:
    TSlotCollector& operator=(TSlotCollector&) = delete;
};

TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate)
    : intermediate(intermediate)
    , nextUniformLocation(intermediate.getUniformLocationBase())
    , nextInputLocation(0)
    , nextOutputLocation(0)
{
    memset(stageMask, false, sizeof(bool) * (EShLangCount + 1));
}

int TDefaultIoResolverBase::getBaseBinding(TResourceType res, unsigned int set) const {
    return selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set));
}

const std::vector<std::string>& TDefaultIoResolverBase::getResourceSetBinding() const {
    return intermediate.getResourceSetBinding();
}

bool TDefaultIoResolverBase::doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }

bool TDefaultIoResolverBase::doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); }

TDefaultIoResolverBase::TSlotSet::iterator TDefaultIoResolverBase::findSlot(int set, int slot) {
    return std::lower_bound(slots[set].begin(), slots[set].end(), slot);
}

bool TDefaultIoResolverBase::checkEmpty(int set, int slot) {
    TSlotSet::iterator at = findSlot(set, slot);
    return ! (at != slots[set].end() && *at == slot);
}

int TDefaultIoResolverBase::reserveSlot(int set, int slot, int size) {
    TSlotSet::iterator at = findSlot(set, slot);
    // tolerate aliasing, by not double-recording aliases
    // (policy about appropriateness of the alias is higher up)
    for (int i = 0; i < size; i++) {
        if (at == slots[set].end() || *at != slot + i)
            at = slots[set].insert(at, slot + i);
        ++at;
    }
    return slot;
}

int TDefaultIoResolverBase::getFreeSlot(int set, int base, int size) {
    TSlotSet::iterator at = findSlot(set, base);
    if (at == slots[set].end())
        return reserveSlot(set, base, size);
    // look for a big enough gap
    for (; at != slots[set].end(); ++at) {
        if (*at - base >= size)
            break;
        base = *at + 1;
    }
    return reserveSlot(set, base, size);
}

int TDefaultIoResolverBase::resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) {
    const TType& type = ent.symbol->getType();
    if (type.getQualifier().hasSet()) {
        return ent.newSet = type.getQualifier().layoutSet;
    }
    // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN)
    if (getResourceSetBinding().size() == 1) {
        return ent.newSet = atoi(getResourceSetBinding()[0].c_str());
    }
    return ent.newSet = 0;
}

int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) {
    const TType& type = ent.symbol->getType();
    const char* name = ent.symbol->getName().c_str();
    // kick out of not doing this
    if (! doAutoLocationMapping()) {
        return ent.newLocation = -1;
    }
    // no locations added if already present, a built-in variable, a block, or an opaque
    if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
        type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) {
        return ent.newLocation = -1;
    }
    // no locations on blocks of built-in variables
    if (type.isStruct()) {
        if (type.getStruct()->size() < 1) {
            return ent.newLocation = -1;
        }
        if ((*type.getStruct())[0].type->isBuiltIn()) {
            return ent.newLocation = -1;
        }
    }
    int location = intermediate.getUniformLocationOverride(name);
    if (location != -1) {
        return ent.newLocation = location;
    }
    location = nextUniformLocation;
    nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type);
    return ent.newLocation = location;
}

int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) {
    const TType& type = ent.symbol->getType();
    // kick out of not doing this
    if (! doAutoLocationMapping()) {
        return ent.newLocation = -1;
    }

    // no locations added if already present, or a built-in variable
    if (type.getQualifier().hasLocation() || type.isBuiltIn()) {
        return ent.newLocation = -1;
    }

    // no locations on blocks of built-in variables
    if (type.isStruct()) {
        if (type.getStruct()->size() < 1) {
            return ent.newLocation = -1;
        }
        if ((*type.getStruct())[0].type->isBuiltIn()) {
            return ent.newLocation = -1;
        }
    }
    // point to the right input or output location counter
    int& nextLocation = type.getQualifier().isPipeInput() ? nextInputLocation : nextOutputLocation;
    // Placeholder. This does not do proper cross-stage lining up, nor
    // work with mixed location/no-location declarations.
    int location = nextLocation;
    int typeLocationSize;
    // Don’t take into account the outer-most array if the stage’s
    // interface is automatically an array.
    typeLocationSize = computeTypeLocationSize(type, stage);
    nextLocation += typeLocationSize;
    return ent.newLocation = location;
}

int TDefaultIoResolverBase::resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) {
    return ent.newComponent = -1;
}

int TDefaultIoResolverBase::resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) { return ent.newIndex = -1; }

uint32_t TDefaultIoResolverBase::computeTypeLocationSize(const TType& type, EShLanguage stage) {
    int typeLocationSize;
    // Don’t take into account the outer-most array if the stage’s
    // interface is automatically an array.
    if (type.getQualifier().isArrayedIo(stage)) {
        TType elementType(type, 0);
        typeLocationSize = TIntermediate::computeTypeLocationSize(elementType, stage);
    } else {
        typeLocationSize = TIntermediate::computeTypeLocationSize(type, stage);
    }
    return typeLocationSize;
}

//TDefaultGlslIoResolver
TResourceType TDefaultGlslIoResolver::getResourceType(const glslang::TType& type) {
    if (isImageType(type)) {
        return EResImage;
    }
    if (isTextureType(type)) {
        return EResTexture;
    }
    if (isSsboType(type)) {
        return EResSsbo;
    }
    if (isSamplerType(type)) {
        return EResSampler;
    }
    if (isUboType(type)) {
        return EResUbo;
    }
    return EResCount;
}

TDefaultGlslIoResolver::TDefaultGlslIoResolver(const TIntermediate& intermediate)
    : TDefaultIoResolverBase(intermediate)
    , preStage(EShLangCount)
    , currentStage(EShLangCount)
{ }

int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) {
    const TType& type = ent.symbol->getType();
    const TString& name = IsAnonymous(ent.symbol->getName()) ?
                            ent.symbol->getType().getTypeName()
                            :
                            ent.symbol->getName();
    if (currentStage != stage) {
        preStage = currentStage;
        currentStage = stage;
    }
    // kick out of not doing this
    if (! doAutoLocationMapping()) {
        return ent.newLocation = -1;
    }
    // expand the location to each element if the symbol is a struct or array
    if (type.getQualifier().hasLocation()) {
        return ent.newLocation = type.getQualifier().layoutLocation;
    }
    // no locations added if already present, or a built-in variable
    if (type.isBuiltIn()) {
        return ent.newLocation = -1;
    }
    // no locations on blocks of built-in variables
    if (type.isStruct()) {
        if (type.getStruct()->size() < 1) {
            return ent.newLocation = -1;
        }
        if ((*type.getStruct())[0].type->isBuiltIn()) {
            return ent.newLocation = -1;
        }
    }
    int typeLocationSize = computeTypeLocationSize(type, stage);
    int location = type.getQualifier().layoutLocation;
    bool hasLocation = false;
    EShLanguage keyStage(EShLangCount);
    TStorageQualifier storage;
    storage = EvqInOut;
    if (type.getQualifier().isPipeInput()) {
        // If this symbol is a input, search pre stage's out
        keyStage = preStage;
    }
    if (type.getQualifier().isPipeOutput()) {
        // If this symbol is a output, search next stage's in
        keyStage = currentStage;
    }
    // The in/out in current stage is not declared with location, but it is possible declared
    // with explicit location in other stages, find the storageSlotMap firstly to check whether
    // the in/out has location
    int resourceKey = buildStorageKey(keyStage, storage);
    if (! storageSlotMap[resourceKey].empty()) {
        TVarSlotMap::iterator iter = storageSlotMap[resourceKey].find(name);
        if (iter != storageSlotMap[resourceKey].end()) {
            // If interface resource be found, set it has location and this symbol's new location
            // equal the symbol's explicit location declarated in pre or next stage.
            //
            // vs:    out vec4 a;
            // fs:    layout(..., location = 3,...) in vec4 a;
            hasLocation = true;
            location = iter->second;
            // if we want deal like that:
            // vs:    layout(location=4) out vec4 a;
            //        out vec4 b;
            //
            // fs:    in vec4 a;
            //        layout(location = 4) in vec4 b;
            // we need retraverse the map.
        }
        if (! hasLocation) {
            // If interface resource note found, It's mean the location in two stage are both implicit declarat.
            // So we should find a new slot for this interface.
            //
            // vs: out vec4 a;
            // fs: in vec4 a;
            location = getFreeSlot(resourceKey, 0, typeLocationSize);
            storageSlotMap[resourceKey][name] = location;
        }
    } else {
        // the first interface declarated in a program.
        TVarSlotMap varSlotMap;
        location = getFreeSlot(resourceKey, 0, typeLocationSize);
        varSlotMap[name] = location;
        storageSlotMap[resourceKey] = varSlotMap;
    }
    //Update location
    return ent.newLocation = location;
}

int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) {
    const TType& type = ent.symbol->getType();
    const TString& name = IsAnonymous(ent.symbol->getName()) ?
                            ent.symbol->getType().getTypeName()
                            :
                            ent.symbol->getName();
    // kick out of not doing this
    if (! doAutoLocationMapping()) {
        return ent.newLocation = -1;
    }
    // expand the location to each element if the symbol is a struct or array
    if (type.getQualifier().hasLocation() && (type.isStruct() || type.isArray())) {
        return ent.newLocation = type.getQualifier().layoutLocation;
    } else {
        // no locations added if already present, a built-in variable, a block, or an opaque
        if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
            type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) {
            return ent.newLocation = -1;
        }
        // no locations on blocks of built-in variables
        if (type.isStruct()) {
            if (type.getStruct()->size() < 1) {
                return ent.newLocation = -1;
            }
            if ((*type.getStruct())[0].type->isBuiltIn()) {
                return ent.newLocation = -1;
            }
        }
    }
    int location = intermediate.getUniformLocationOverride(name.c_str());
    if (location != -1) {
        return ent.newLocation = location;
    }

    int size = TIntermediate::computeTypeUniformLocationSize(type);

    // The uniform in current stage is not declared with location, but it is possible declared
    // with explicit location in other stages, find the storageSlotMap firstly to check whether
    // the uniform has location
    bool hasLocation = false;
    int resourceKey = buildStorageKey(EShLangCount, EvqUniform);
    TVarSlotMap& slotMap = storageSlotMap[resourceKey];
    // Check dose shader program has uniform resource
    if (! slotMap.empty()) {
        // If uniform resource not empty, try find a same name uniform
        TVarSlotMap::iterator iter = slotMap.find(name);
        if (iter != slotMap.end()) {
            // If uniform resource be found, set it has location and this symbol's new location
            // equal the uniform's explicit location declarated in other stage.
            //
            // vs:    uniform vec4 a;
            // fs:    layout(..., location = 3,...) uniform vec4 a;
            hasLocation = true;
            location = iter->second;
        }
        if (! hasLocation) {
            // No explicit location declaraten in other stage.
            // So we should find a new slot for this uniform.
            //
            // vs:    uniform vec4 a;
            // fs:    uniform vec4 a;
            location = getFreeSlot(resourceKey, 0, computeTypeLocationSize(type, currentStage));
            storageSlotMap[resourceKey][name] = location;
        }
    } else {
        // the first uniform declarated in a program.
        TVarSlotMap varSlotMap;
        location = getFreeSlot(resourceKey, 0, size);
        varSlotMap[name] = location;
        storageSlotMap[resourceKey] = varSlotMap;
    }
    return ent.newLocation = location;
}

int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) {
    const TType& type = ent.symbol->getType();
    const TString& name = IsAnonymous(ent.symbol->getName()) ?
                            ent.symbol->getType().getTypeName()
                            :
                            ent.symbol->getName();
    // On OpenGL arrays of opaque types take a seperate binding for each element
    int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
    TResourceType resource = getResourceType(type);
    // don't need to handle uniform symbol, it will be handled in resolveUniformLocation
    if (resource == EResUbo && type.getBasicType() != EbtBlock) {
        return ent.newBinding = -1;
    }
    // There is no 'set' qualifier in OpenGL shading language, each resource has its own
    // binding name space, so remap the 'set' to resource type which make each resource
    // binding is valid from 0 to MAX_XXRESOURCE_BINDINGS
    int set = resource;
    if (resource < EResCount) {
        if (type.getQualifier().hasBinding()) {
            ent.newBinding = reserveSlot(set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding, numBindings);
            return ent.newBinding;
        } else if (ent.live && doAutoBindingMapping()) {
            // The resource in current stage is not declared with binding, but it is possible declared
            // with explicit binding in other stages, find the resourceSlotMap firstly to check whether
            // the resource has binding, don't need to allocate if it already has a binding
            bool hasBinding = false;
            if (! resourceSlotMap[resource].empty()) {
                TVarSlotMap::iterator iter = resourceSlotMap[resource].find(name);
                if (iter != resourceSlotMap[resource].end()) {
                    hasBinding = true;
                    ent.newBinding = iter->second;
                }
            }
            if (! hasBinding) {
                TVarSlotMap varSlotMap;
                // find free slot, the caller did make sure it passes all vars with binding
                // first and now all are passed that do not have a binding and needs one
                int binding = getFreeSlot(resource, getBaseBinding(resource, set), numBindings);
                varSlotMap[name] = binding;
                resourceSlotMap[resource] = varSlotMap;
                ent.newBinding = binding;
            }
            return ent.newBinding;
        }
    }
    return ent.newBinding = -1;
}

void TDefaultGlslIoResolver::beginResolve(EShLanguage stage) {
    // reset stage state
    if (stage == EShLangCount)
        preStage = currentStage = stage;
    // update stage state
    else if (currentStage != stage) {
        preStage = currentStage;
        currentStage = stage;
    }
}

void TDefaultGlslIoResolver::endResolve(EShLanguage /*stage*/) {
    // TODO nothing
}

void TDefaultGlslIoResolver::beginCollect(EShLanguage stage) {
    // reset stage state
    if (stage == EShLangCount)
        preStage = currentStage = stage;
    // update stage state
    else if (currentStage != stage) {
        preStage = currentStage;
        currentStage = stage;
    }
}

void TDefaultGlslIoResolver::endCollect(EShLanguage /*stage*/) {
    // TODO nothing
}

void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
    const TType& type = ent.symbol->getType();
    const TString& name = IsAnonymous(ent.symbol->getName()) ?
                            ent.symbol->getType().getTypeName()
                            :
                            ent.symbol->getName();
    TStorageQualifier storage = type.getQualifier().storage;
    EShLanguage stage(EShLangCount);
    switch (storage) {
    case EvqUniform:
        if (type.getBasicType() != EbtBlock && type.getQualifier().hasLocation()) {
            //
            // Reserve the slots for the uniforms who has explicit location
            int storageKey = buildStorageKey(EShLangCount, EvqUniform);
            int location = type.getQualifier().layoutLocation;
            TVarSlotMap& varSlotMap = storageSlotMap[storageKey];
            TVarSlotMap::iterator iter = varSlotMap.find(name);
            if (iter == varSlotMap.end()) {
                int numLocations = TIntermediate::computeTypeUniformLocationSize(type);
                reserveSlot(storageKey, location, numLocations);
                varSlotMap[name] = location;
            } else {
                // Allocate location by name for OpenGL driver, so the uniform in different
                // stages should be declared with the same location
                if (iter->second != location) {
                    TString errorMsg = "Invalid location: " + name;
                    infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
                    hasError = true;
                }
            }
        }
        break;
    case EvqVaryingIn:
    case EvqVaryingOut:
        //
        // Reserve the slots for the inout who has explicit location
        if (type.getQualifier().hasLocation()) {
            stage = storage == EvqVaryingIn ? preStage : stage;
            stage = storage == EvqVaryingOut ? currentStage : stage;
            int storageKey = buildStorageKey(stage, EvqInOut);
            int location = type.getQualifier().layoutLocation;
            TVarSlotMap& varSlotMap = storageSlotMap[storageKey];
            TVarSlotMap::iterator iter = varSlotMap.find(name);
            if (iter == varSlotMap.end()) {
                int numLocations = TIntermediate::computeTypeUniformLocationSize(type);
                reserveSlot(storageKey, location, numLocations);
                varSlotMap[name] = location;
            } else {
                // Allocate location by name for OpenGL driver, so the uniform in different
                // stages should be declared with the same location
                if (iter->second != location) {
                    TString errorMsg = "Invalid location: " + name;
                    infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
                    hasError = true;
                }
            }
        }
        break;
    default:
        break;
    }
}

void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
    const TType& type = ent.symbol->getType();
    const TString& name = IsAnonymous(ent.symbol->getName()) ?
                            ent.symbol->getType().getTypeName()
                            :
                            ent.symbol->getName();
    int resource = getResourceType(type);
    if (type.getQualifier().hasBinding()) {
        TVarSlotMap& varSlotMap = resourceSlotMap[resource];
        TVarSlotMap::iterator iter = varSlotMap.find(name);
        int binding = type.getQualifier().layoutBinding;
        if (iter == varSlotMap.end()) {
            // Reserve the slots for the ubo, ssbo and opaques who has explicit binding
            int numBindings = type.isSizedArray() ? type.getCumulativeArraySize() : 1;
            varSlotMap[name] = binding;
            reserveSlot(resource, binding, numBindings);
        } else {
            // Allocate binding by name for OpenGL driver, so the resource in different
            // stages should be declared with the same binding
            if (iter->second != binding) {
                TString errorMsg = "Invalid binding: " + name;
                infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
                hasError = true;
            }
        }
    }
}

//TDefaultGlslIoResolver end

/*
 * Basic implementation of glslang::TIoMapResolver that replaces the
 * previous offset behavior.
 * It does the same, uses the offsets for the corresponding uniform
 * types. Also respects the EOptionAutoMapBindings flag and binds
 * them if needed.
 */
/*
 * Default resolver
 */
struct TDefaultIoResolver : public TDefaultIoResolverBase {
    TDefaultIoResolver(const TIntermediate& intermediate) : TDefaultIoResolverBase(intermediate) { }

    bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; }

    TResourceType getResourceType(const glslang::TType& type) override {
        if (isImageType(type)) {
            return EResImage;
        }
        if (isTextureType(type)) {
            return EResTexture;
        }
        if (isSsboType(type)) {
            return EResSsbo;
        }
        if (isSamplerType(type)) {
            return EResSampler;
        }
        if (isUboType(type)) {
            return EResUbo;
        }
        return EResCount;
    }

    int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override {
        const TType& type = ent.symbol->getType();
        const int set = getLayoutSet(type);
        // On OpenGL arrays of opaque types take a seperate binding for each element
        int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
        TResourceType resource = getResourceType(type);
        if (resource < EResCount) {
            if (type.getQualifier().hasBinding()) {
                return ent.newBinding = reserveSlot(
                           set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding, numBindings);
            } else if (ent.live && doAutoBindingMapping()) {
                // find free slot, the caller did make sure it passes all vars with binding
                // first and now all are passed that do not have a binding and needs one
                return ent.newBinding = getFreeSlot(set, getBaseBinding(resource, set), numBindings);
            }
        }
        return ent.newBinding = -1;
    }
};

#ifdef ENABLE_HLSL
/********************************************************************************
The following IO resolver maps types in HLSL register space, as follows:

t - for shader resource views (SRV)
   TEXTURE1D
   TEXTURE1DARRAY
   TEXTURE2D
   TEXTURE2DARRAY
   TEXTURE3D
   TEXTURECUBE
   TEXTURECUBEARRAY
   TEXTURE2DMS
   TEXTURE2DMSARRAY
   STRUCTUREDBUFFER
   BYTEADDRESSBUFFER
   BUFFER
   TBUFFER

s - for samplers
   SAMPLER
   SAMPLER1D
   SAMPLER2D
   SAMPLER3D
   SAMPLERCUBE
   SAMPLERSTATE
   SAMPLERCOMPARISONSTATE

u - for unordered access views (UAV)
   RWBYTEADDRESSBUFFER
   RWSTRUCTUREDBUFFER
   APPENDSTRUCTUREDBUFFER
   CONSUMESTRUCTUREDBUFFER
   RWBUFFER
   RWTEXTURE1D
   RWTEXTURE1DARRAY
   RWTEXTURE2D
   RWTEXTURE2DARRAY
   RWTEXTURE3D

b - for constant buffer views (CBV)
   CBUFFER
   CONSTANTBUFFER
 ********************************************************************************/
struct TDefaultHlslIoResolver : public TDefaultIoResolverBase {
    TDefaultHlslIoResolver(const TIntermediate& intermediate) : TDefaultIoResolverBase(intermediate) { }

    bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; }

    TResourceType getResourceType(const glslang::TType& type) override {
        if (isUavType(type)) {
            return EResUav;
        }
        if (isSrvType(type)) {
            return EResTexture;
        }
        if (isSamplerType(type)) {
            return EResSampler;
        }
        if (isUboType(type)) {
            return EResUbo;
        }
        return EResCount;
    }

    int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override {
        const TType& type = ent.symbol->getType();
        const int set = getLayoutSet(type);
        TResourceType resource = getResourceType(type);
        if (resource < EResCount) {
            if (type.getQualifier().hasBinding()) {
                return ent.newBinding = reserveSlot(set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding);
            } else if (ent.live && doAutoBindingMapping()) {
                // find free slot, the caller did make sure it passes all vars with binding
                // first and now all are passed that do not have a binding and needs one
                return ent.newBinding = getFreeSlot(set, getBaseBinding(resource, set));
            }
        }
        return ent.newBinding = -1;
    }
};
#endif

// Map I/O variables to provided offsets, and make bindings for
// unbound but live variables.
//
// Returns false if the input is too malformed to do this.
bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSink& infoSink, TIoMapResolver* resolver) {
    bool somethingToDo = ! intermediate.getResourceSetBinding().empty() || intermediate.getAutoMapBindings() ||
                         intermediate.getAutoMapLocations();
    // Restrict the stricter condition to further check 'somethingToDo' only if 'somethingToDo' has not been set, reduce
    // unnecessary or insignificant for-loop operation after 'somethingToDo' have been true.
    for (int res = 0; (res < EResCount && !somethingToDo); ++res) {
        somethingToDo = somethingToDo || (intermediate.getShiftBinding(TResourceType(res)) != 0) ||
                        intermediate.hasShiftBindingForSet(TResourceType(res));
    }
    if (! somethingToDo && resolver == nullptr)
        return true;
    if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
        return false;
    TIntermNode* root = intermediate.getTreeRoot();
    if (root == nullptr)
        return false;
    // if no resolver is provided, use the default resolver with the given shifts and auto map settings
    TDefaultIoResolver defaultResolver(intermediate);
#ifdef ENABLE_HLSL
    TDefaultHlslIoResolver defaultHlslResolver(intermediate);
    if (resolver == nullptr) {
        // TODO: use a passed in IO mapper for this
        if (intermediate.usingHlslIoMapping())
            resolver = &defaultHlslResolver;
        else
            resolver = &defaultResolver;
    }
    resolver->addStage(stage);
#else
    resolver = &defaultResolver;
#endif

    TVarLiveMap inVarMap, outVarMap, uniformVarMap;
    TVarLiveVector inVector, outVector, uniformVector;
    TVarGatherTraverser iter_binding_all(intermediate, true, inVarMap, outVarMap, uniformVarMap);
    TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
    root->traverse(&iter_binding_all);
    iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
    while (! iter_binding_live.functions.empty()) {
        TIntermNode* function = iter_binding_live.functions.back();
        iter_binding_live.functions.pop_back();
        function->traverse(&iter_binding_live);
    }
    // sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
    std::for_each(inVarMap.begin(), inVarMap.end(),
                  [&inVector](TVarLivePair p) { inVector.push_back(p); });
    std::sort(inVector.begin(), inVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
        return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
    });
    std::for_each(outVarMap.begin(), outVarMap.end(),
                  [&outVector](TVarLivePair p) { outVector.push_back(p); });
    std::sort(outVector.begin(), outVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
        return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
    });
    std::for_each(uniformVarMap.begin(), uniformVarMap.end(),
                  [&uniformVector](TVarLivePair p) { uniformVector.push_back(p); });
    std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
        return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
    });
    bool hadError = false;
    TNotifyInOutAdaptor inOutNotify(stage, *resolver);
    TNotifyUniformAdaptor uniformNotify(stage, *resolver);
    TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError);
    TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError);
    resolver->beginNotifications(stage);
    std::for_each(inVector.begin(), inVector.end(), inOutNotify);
    std::for_each(outVector.begin(), outVector.end(), inOutNotify);
    std::for_each(uniformVector.begin(), uniformVector.end(), uniformNotify);
    resolver->endNotifications(stage);
    resolver->beginResolve(stage);
    std::for_each(inVector.begin(), inVector.end(), inOutResolve);
    std::for_each(inVector.begin(), inVector.end(), [&inVarMap](TVarLivePair p) {
        auto at = inVarMap.find(p.second.symbol->getName());
        if (at != inVarMap.end())
            at->second = p.second;
    });
    std::for_each(outVector.begin(), outVector.end(), inOutResolve);
    std::for_each(outVector.begin(), outVector.end(), [&outVarMap](TVarLivePair p) {
        auto at = outVarMap.find(p.second.symbol->getName());
        if (at != outVarMap.end())
            at->second = p.second;
    });
    std::for_each(uniformVector.begin(), uniformVector.end(), uniformResolve);
    std::for_each(uniformVector.begin(), uniformVector.end(), [&uniformVarMap](TVarLivePair p) {
        auto at = uniformVarMap.find(p.second.symbol->getName());
        if (at != uniformVarMap.end())
            at->second = p.second;
    });
    resolver->endResolve(stage);
    if (!hadError) {
        TVarSetTraverser iter_iomap(intermediate, inVarMap, outVarMap, uniformVarMap);
        root->traverse(&iter_iomap);
    }
    return !hadError;
}

// Map I/O variables to provided offsets, and make bindings for
// unbound but live variables.
//
// Returns false if the input is too malformed to do this.
bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSink& infoSink, TIoMapResolver* resolver) {

    bool somethingToDo = ! intermediate.getResourceSetBinding().empty() || intermediate.getAutoMapBindings() ||
                         intermediate.getAutoMapLocations();
    // Restrict the stricter condition to further check 'somethingToDo' only if 'somethingToDo' has not been set, reduce
    // unnecessary or insignificant for-loop operation after 'somethingToDo' have been true.
    for (int res = 0; (res < EResCount && !somethingToDo); ++res) {
        somethingToDo = somethingToDo || (intermediate.getShiftBinding(TResourceType(res)) != 0) ||
                        intermediate.hasShiftBindingForSet(TResourceType(res));
    }
    if (! somethingToDo && resolver == nullptr) {
        return true;
    }
    if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive()) {
        return false;
    }
    TIntermNode* root = intermediate.getTreeRoot();
    if (root == nullptr) {
        return false;
    }
    // if no resolver is provided, use the default resolver with the given shifts and auto map settings
    TDefaultGlslIoResolver defaultResolver(intermediate);
    if (resolver == nullptr) {
        resolver = &defaultResolver;
    }
    resolver->addStage(stage);
    inVarMaps[stage] = new TVarLiveMap, outVarMaps[stage] = new TVarLiveMap(), uniformVarMap[stage] = new TVarLiveMap();
    TVarGatherTraverser iter_binding_all(intermediate, true, *inVarMaps[stage], *outVarMaps[stage],
                                         *uniformVarMap[stage]);
    TVarGatherTraverser iter_binding_live(intermediate, false, *inVarMaps[stage], *outVarMaps[stage],
                                          *uniformVarMap[stage]);
    root->traverse(&iter_binding_all);
    iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
    while (! iter_binding_live.functions.empty()) {
        TIntermNode* function = iter_binding_live.functions.back();
        iter_binding_live.functions.pop_back();
        function->traverse(&iter_binding_live);
    }
    TNotifyInOutAdaptor inOutNotify(stage, *resolver);
    TNotifyUniformAdaptor uniformNotify(stage, *resolver);
    // Resolve current stage input symbol location with previous stage output here,
    // uniform symbol, ubo, ssbo and opaque symbols are per-program resource,
    // will resolve uniform symbol location and ubo/ssbo/opaque binding in doMap()
    resolver->beginNotifications(stage);
    std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), inOutNotify);
    std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), inOutNotify);
    std::for_each(uniformVarMap[stage]->begin(), uniformVarMap[stage]->end(), uniformNotify);
    resolver->endNotifications(stage);
    TSlotCollector slotCollector(*resolver, infoSink);
    resolver->beginCollect(stage);
    std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), slotCollector);
    std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), slotCollector);
    std::for_each(uniformVarMap[stage]->begin(), uniformVarMap[stage]->end(), slotCollector);
    resolver->endCollect(stage);
    intermediates[stage] = &intermediate;
    return !hadError;
}

bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
    resolver->endResolve(EShLangCount);
    if (!hadError) {
        //Resolve uniform location, ubo/ssbo/opaque bindings across stages
        TResolverUniformAdaptor uniformResolve(EShLangCount, *resolver, infoSink, hadError);
        TResolverInOutAdaptor inOutResolve(EShLangCount, *resolver, infoSink, hadError);
        TSymbolValidater symbolValidater(*resolver, infoSink, inVarMaps, outVarMaps, uniformVarMap, hadError);
        TVarLiveVector uniformVector;
        resolver->beginResolve(EShLangCount);
        for (int stage = EShLangVertex; stage < EShLangCount; stage++) {
            if (inVarMaps[stage] != nullptr) {
                inOutResolve.setStage(EShLanguage(stage));
                std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), symbolValidater);
                std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), inOutResolve);
                std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), symbolValidater);
                std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), inOutResolve);
            }
            if (uniformVarMap[stage] != nullptr) {
                uniformResolve.setStage(EShLanguage(stage));
                // sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
                std::for_each(uniformVarMap[stage]->begin(), uniformVarMap[stage]->end(),
                              [&uniformVector](TVarLivePair p) { uniformVector.push_back(p); });
            }
        }
        std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
            return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
        });
        std::for_each(uniformVector.begin(), uniformVector.end(), symbolValidater);
        std::for_each(uniformVector.begin(), uniformVector.end(), uniformResolve);
        std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
            return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
        });
        resolver->endResolve(EShLangCount);
        for (size_t stage = 0; stage < EShLangCount; stage++) {
            if (intermediates[stage] != nullptr) {
                // traverse each stage, set new location to each input/output and unifom symbol, set new binding to
                // ubo, ssbo and opaque symbols
                TVarLiveMap** pUniformVarMap = uniformVarMap;
                std::for_each(uniformVector.begin(), uniformVector.end(), [pUniformVarMap, stage](TVarLivePair p) {
                    auto at = pUniformVarMap[stage]->find(p.second.symbol->getName());
                    if (at != pUniformVarMap[stage]->end())
                        at->second = p.second;
                });
                TVarSetTraverser iter_iomap(*intermediates[stage], *inVarMaps[stage], *outVarMaps[stage],
                                            *uniformVarMap[stage]);
                intermediates[stage]->getTreeRoot()->traverse(&iter_iomap);
            }
        }
        return !hadError;
    } else {
        return false;
    }
}

} // end namespace glslang

#endif // GLSLANG_WEB
