//
// Copyright (C) 2013 LunarG, Inc.
// Copyright (C) 2017 ARM Limited.
//
// 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.
//

//
// Do link-time merging and validation of intermediate representations.
//
// Basic model is that during compilation, each compilation unit (shader) is
// compiled into one TIntermediate instance.  Then, at link time, multiple
// units for the same stage can be merged together, which can generate errors.
// Then, after all merging, a single instance of TIntermediate represents
// the whole stage.  A final error check can be done on the resulting stage,
// even if no merging was done (i.e., the stage was only one compilation unit).
//

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

namespace glslang {

//
// Link-time error emitter.
//
void TIntermediate::error(TInfoSink& infoSink, const char* message)
{
    infoSink.info.prefix(EPrefixError);
    infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";

    ++numErrors;
}

// Link-time warning.
void TIntermediate::warn(TInfoSink& infoSink, const char* message)
{
    infoSink.info.prefix(EPrefixWarning);
    infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
}

// TODO: 4.4 offset/align:  "Two blocks linked together in the same program with the same block
// name must have the exact same set of members qualified with offset and their integral-constant
// expression values must be the same, or a link-time error results."

//
// Merge the information from 'unit' into 'this'
//
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
{
    mergeCallGraphs(infoSink, unit);
    mergeModes(infoSink, unit);
    mergeTrees(infoSink, unit);
}

void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
{
    if (unit.getNumEntryPoints() > 0) {
        if (getNumEntryPoints() > 0)
            error(infoSink, "can't handle multiple entry points per stage");
        else {
            entryPointName = unit.getEntryPointName();
            entryPointMangledName = unit.getEntryPointMangledName();
        }
    }
    numEntryPoints += unit.getNumEntryPoints();

    callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
}

#define MERGE_MAX(member) member = std::max(member, unit.member)
#define MERGE_TRUE(member) if (unit.member) member = unit.member;

void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
{
    if (language != unit.language)
        error(infoSink, "stages must match when linking into a single stage");

    if (source == EShSourceNone)
        source = unit.source;
    if (source != unit.source)
        error(infoSink, "can't link compilation units from different source languages");

    if (treeRoot == nullptr) {
        profile = unit.profile;
        version = unit.version;
        requestedExtensions = unit.requestedExtensions;
    } else {
        if ((profile == EEsProfile) != (unit.profile == EEsProfile))
            error(infoSink, "Cannot cross link ES and desktop profiles");
        else if (unit.profile == ECompatibilityProfile)
            profile = ECompatibilityProfile;
        version = std::max(version, unit.version);
        requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
    }

    MERGE_MAX(spvVersion.spv);
    MERGE_MAX(spvVersion.vulkanGlsl);
    MERGE_MAX(spvVersion.vulkan);
    MERGE_MAX(spvVersion.openGl);

    numErrors += unit.getNumErrors();
    numPushConstants += unit.numPushConstants;

    if (unit.invocations != TQualifier::layoutNotSet) {
        if (invocations == TQualifier::layoutNotSet)
            invocations = unit.invocations;
        else if (invocations != unit.invocations)
            error(infoSink, "number of invocations must match between compilation units");
    }

    if (vertices == TQualifier::layoutNotSet)
        vertices = unit.vertices;
    else if (vertices != unit.vertices) {
        if (language == EShLangGeometry
#ifdef NV_EXTENSIONS
            || language == EShLangMeshNV
#endif
            )
            error(infoSink, "Contradictory layout max_vertices values");
        else if (language == EShLangTessControl)
            error(infoSink, "Contradictory layout vertices values");
        else
            assert(0);
    }
#ifdef NV_EXTENSIONS
    if (primitives == TQualifier::layoutNotSet)
        primitives = unit.primitives;
    else if (primitives != unit.primitives) {
        if (language == EShLangMeshNV)
            error(infoSink, "Contradictory layout max_primitives values");
        else
            assert(0);
    }
#endif

    if (inputPrimitive == ElgNone)
        inputPrimitive = unit.inputPrimitive;
    else if (inputPrimitive != unit.inputPrimitive)
        error(infoSink, "Contradictory input layout primitives");

    if (outputPrimitive == ElgNone)
        outputPrimitive = unit.outputPrimitive;
    else if (outputPrimitive != unit.outputPrimitive)
        error(infoSink, "Contradictory output layout primitives");

    if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
        error(infoSink, "gl_FragCoord redeclarations must match across shaders");

    if (vertexSpacing == EvsNone)
        vertexSpacing = unit.vertexSpacing;
    else if (vertexSpacing != unit.vertexSpacing)
        error(infoSink, "Contradictory input vertex spacing");

    if (vertexOrder == EvoNone)
        vertexOrder = unit.vertexOrder;
    else if (vertexOrder != unit.vertexOrder)
        error(infoSink, "Contradictory triangle ordering");

    MERGE_TRUE(pointMode);

    for (int i = 0; i < 3; ++i) {
        if (localSize[i] > 1)
            localSize[i] = unit.localSize[i];
        else if (localSize[i] != unit.localSize[i])
            error(infoSink, "Contradictory local size");

        if (localSizeSpecId[i] != TQualifier::layoutNotSet)
            localSizeSpecId[i] = unit.localSizeSpecId[i];
        else if (localSizeSpecId[i] != unit.localSizeSpecId[i])
            error(infoSink, "Contradictory local size specialization ids");
    }

    MERGE_TRUE(earlyFragmentTests);
    MERGE_TRUE(postDepthCoverage);

    if (depthLayout == EldNone)
        depthLayout = unit.depthLayout;
    else if (depthLayout != unit.depthLayout)
        error(infoSink, "Contradictory depth layouts");

    MERGE_TRUE(depthReplacing);
    MERGE_TRUE(hlslFunctionality1);

    blendEquations |= unit.blendEquations;

    MERGE_TRUE(xfbMode);

    for (size_t b = 0; b < xfbBuffers.size(); ++b) {
        if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd)
            xfbBuffers[b].stride = unit.xfbBuffers[b].stride;
        else if (xfbBuffers[b].stride != unit.xfbBuffers[b].stride)
            error(infoSink, "Contradictory xfb_stride");
        xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride);
        if (unit.xfbBuffers[b].containsDouble)
            xfbBuffers[b].containsDouble = true;
        // TODO: 4.4 link: enhanced layouts: compare ranges
    }

    MERGE_TRUE(multiStream);

#ifdef NV_EXTENSIONS
    MERGE_TRUE(layoutOverrideCoverage);
    MERGE_TRUE(geoPassthroughEXT);
#endif

    for (unsigned int i = 0; i < unit.shiftBinding.size(); ++i) {
        if (unit.shiftBinding[i] > 0)
            setShiftBinding((TResourceType)i, unit.shiftBinding[i]);
    }

    for (unsigned int i = 0; i < unit.shiftBindingForSet.size(); ++i) {
        for (auto it = unit.shiftBindingForSet[i].begin(); it != unit.shiftBindingForSet[i].end(); ++it)
            setShiftBindingForSet((TResourceType)i, it->second, it->first);
    }

    resourceSetBinding.insert(resourceSetBinding.end(), unit.resourceSetBinding.begin(), unit.resourceSetBinding.end());

    MERGE_TRUE(autoMapBindings);
    MERGE_TRUE(autoMapLocations);
    MERGE_TRUE(invertY);
    MERGE_TRUE(flattenUniformArrays);
    MERGE_TRUE(useUnknownFormat);
    MERGE_TRUE(hlslOffsets);
    MERGE_TRUE(useStorageBuffer);
    MERGE_TRUE(hlslIoMapping);

    // TODO: sourceFile
    // TODO: sourceText
    // TODO: processes

    MERGE_TRUE(needToLegalize);
    MERGE_TRUE(binaryDoubleOutput);
}

//
// Merge the 'unit' AST into 'this' AST.
// That includes rationalizing the unique IDs, which were set up independently,
// and might have overlaps that are not the same symbol, or might have different
// IDs for what should be the same shared symbol.
//
void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
{
    if (unit.treeRoot == nullptr)
        return;

    if (treeRoot == nullptr) {
        treeRoot = unit.treeRoot;
        return;
    }

    // Getting this far means we have two existing trees to merge...
#ifdef NV_EXTENSIONS
    numShaderRecordNVBlocks += unit.numShaderRecordNVBlocks;
#endif

#ifdef NV_EXTENSIONS
    numTaskNVBlocks += unit.numTaskNVBlocks;
#endif

    // Get the top-level globals of each unit
    TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
    TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence();

    // Get the linker-object lists
    TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
    const TIntermSequence& unitLinkerObjects = unit.findLinkerObjects()->getSequence();

    // Map by global name to unique ID to rationalize the same object having
    // differing IDs in different trees.
    TMap<TString, int> idMap;
    int maxId;
    seedIdMap(idMap, maxId);
    remapIds(idMap, maxId + 1, unit);

    mergeBodies(infoSink, globals, unitGlobals);
    mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
    ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
}

// Traverser that seeds an ID map with all built-ins, and tracks the
// maximum ID used.
// (It would be nice to put this in a function, but that causes warnings
// on having no bodies for the copy-constructor/operator=.)
class TBuiltInIdTraverser : public TIntermTraverser {
public:
    TBuiltInIdTraverser(TMap<TString, int>& idMap) : idMap(idMap), maxId(0) { }
    // If it's a built in, add it to the map.
    // Track the max ID.
    virtual void visitSymbol(TIntermSymbol* symbol)
    {
        const TQualifier& qualifier = symbol->getType().getQualifier();
        if (qualifier.builtIn != EbvNone)
            idMap[symbol->getName()] = symbol->getId();
        maxId = std::max(maxId, symbol->getId());
    }
    int getMaxId() const { return maxId; }
protected:
    TBuiltInIdTraverser(TBuiltInIdTraverser&);
    TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&);
    TMap<TString, int>& idMap;
    int maxId;
};

// Traverser that seeds an ID map with non-builtins.
// (It would be nice to put this in a function, but that causes warnings
// on having no bodies for the copy-constructor/operator=.)
class TUserIdTraverser : public TIntermTraverser {
public:
    TUserIdTraverser(TMap<TString, int>& idMap) : idMap(idMap) { }
    // If its a non-built-in global, add it to the map.
    virtual void visitSymbol(TIntermSymbol* symbol)
    {
        const TQualifier& qualifier = symbol->getType().getQualifier();
        if (qualifier.builtIn == EbvNone)
            idMap[symbol->getName()] = symbol->getId();
    }

protected:
    TUserIdTraverser(TUserIdTraverser&);
    TUserIdTraverser& operator=(TUserIdTraverser&);
    TMap<TString, int>& idMap; // over biggest id
};

// Initialize the the ID map with what we know of 'this' AST.
void TIntermediate::seedIdMap(TMap<TString, int>& idMap, int& maxId)
{
    // all built-ins everywhere need to align on IDs and contribute to the max ID
    TBuiltInIdTraverser builtInIdTraverser(idMap);
    treeRoot->traverse(&builtInIdTraverser);
    maxId = builtInIdTraverser.getMaxId();

    // user variables in the linker object list need to align on ids
    TUserIdTraverser userIdTraverser(idMap);
    findLinkerObjects()->traverse(&userIdTraverser);
}

// Traverser to map an AST ID to what was known from the seeding AST.
// (It would be nice to put this in a function, but that causes warnings
// on having no bodies for the copy-constructor/operator=.)
class TRemapIdTraverser : public TIntermTraverser {
public:
    TRemapIdTraverser(const TMap<TString, int>& idMap, int idShift) : idMap(idMap), idShift(idShift) { }
    // Do the mapping:
    //  - if the same symbol, adopt the 'this' ID
    //  - otherwise, ensure a unique ID by shifting to a new space
    virtual void visitSymbol(TIntermSymbol* symbol)
    {
        const TQualifier& qualifier = symbol->getType().getQualifier();
        bool remapped = false;
        if (qualifier.isLinkable() || qualifier.builtIn != EbvNone) {
            auto it = idMap.find(symbol->getName());
            if (it != idMap.end()) {
                symbol->changeId(it->second);
                remapped = true;
            }
        }
        if (!remapped)
            symbol->changeId(symbol->getId() + idShift);
    }
protected:
    TRemapIdTraverser(TRemapIdTraverser&);
    TRemapIdTraverser& operator=(TRemapIdTraverser&);
    const TMap<TString, int>& idMap;
    int idShift;
};

void TIntermediate::remapIds(const TMap<TString, int>& idMap, int idShift, TIntermediate& unit)
{
    // Remap all IDs to either share or be unique, as dictated by the idMap and idShift.
    TRemapIdTraverser idTraverser(idMap, idShift);
    unit.getTreeRoot()->traverse(&idTraverser);
}

//
// Merge the function bodies and global-level initializers from unitGlobals into globals.
// Will error check duplication of function bodies for the same signature.
//
void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, const TIntermSequence& unitGlobals)
{
    // TODO: link-time performance: Processing in alphabetical order will be faster

    // Error check the global objects, not including the linker objects
    for (unsigned int child = 0; child < globals.size() - 1; ++child) {
        for (unsigned int unitChild = 0; unitChild < unitGlobals.size() - 1; ++unitChild) {
            TIntermAggregate* body = globals[child]->getAsAggregate();
            TIntermAggregate* unitBody = unitGlobals[unitChild]->getAsAggregate();
            if (body && unitBody && body->getOp() == EOpFunction && unitBody->getOp() == EOpFunction && body->getName() == unitBody->getName()) {
                error(infoSink, "Multiple function bodies in multiple compilation units for the same signature in the same stage:");
                infoSink.info << "    " << globals[child]->getAsAggregate()->getName() << "\n";
            }
        }
    }

    // Merge the global objects, just in front of the linker objects
    globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1);
}

//
// Merge the linker objects from unitLinkerObjects into linkerObjects.
// Duplication is expected and filtered out, but contradictions are an error.
//
void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects)
{
    // Error check and merge the linker objects (duplicates should not be created)
    std::size_t initialNumLinkerObjects = linkerObjects.size();
    for (unsigned int unitLinkObj = 0; unitLinkObj < unitLinkerObjects.size(); ++unitLinkObj) {
        bool merge = true;
        for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) {
            TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
            TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
            assert(symbol && unitSymbol);
            if (symbol->getName() == unitSymbol->getName()) {
                // filter out copy
                merge = false;

                // but if one has an initializer and the other does not, update
                // the initializer
                if (symbol->getConstArray().empty() && ! unitSymbol->getConstArray().empty())
                    symbol->setConstArray(unitSymbol->getConstArray());

                // Similarly for binding
                if (! symbol->getQualifier().hasBinding() && unitSymbol->getQualifier().hasBinding())
                    symbol->getQualifier().layoutBinding = unitSymbol->getQualifier().layoutBinding;

                // Update implicit array sizes
                mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType());

                // Check for consistent types/qualification/initializers etc.
                mergeErrorCheck(infoSink, *symbol, *unitSymbol, false);
            }
        }
        if (merge)
            linkerObjects.push_back(unitLinkerObjects[unitLinkObj]);
    }
}

// TODO 4.5 link functionality: cull distance array size checking

// Recursively merge the implicit array sizes through the objects' respective type trees.
void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
{
    if (type.isUnsizedArray()) {
        if (unitType.isUnsizedArray()) {
            type.updateImplicitArraySize(unitType.getImplicitArraySize());
            if (unitType.isArrayVariablyIndexed())
                type.setArrayVariablyIndexed();
        } else if (unitType.isSizedArray())
            type.changeOuterArraySize(unitType.getOuterArraySize());
    }

    // Type mismatches are caught and reported after this, just be careful for now.
    if (! type.isStruct() || ! unitType.isStruct() || type.getStruct()->size() != unitType.getStruct()->size())
        return;

    for (int i = 0; i < (int)type.getStruct()->size(); ++i)
        mergeImplicitArraySizes(*(*type.getStruct())[i].type, *(*unitType.getStruct())[i].type);
}

//
// Compare two global objects from two compilation units and see if they match
// well enough.  Rules can be different for intra- vs. cross-stage matching.
//
// This function only does one of intra- or cross-stage matching per call.
//
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage)
{
    bool writeTypeComparison = false;

    // Types have to match
    if (symbol.getType() != unitSymbol.getType()) {
        // but, we make an exception if one is an implicit array and the other is sized
        if (! (symbol.getType().isArray() && unitSymbol.getType().isArray() &&
                symbol.getType().sameElementType(unitSymbol.getType()) &&
                (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()))) {
            error(infoSink, "Types must match:");
            writeTypeComparison = true;
        }
    }

    // Qualifiers have to (almost) match

    // Storage...
    if (symbol.getQualifier().storage != unitSymbol.getQualifier().storage) {
        error(infoSink, "Storage qualifiers must match:");
        writeTypeComparison = true;
    }

    // Precision...
    if (symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
        error(infoSink, "Precision qualifiers must match:");
        writeTypeComparison = true;
    }

    // Invariance...
    if (! crossStage && symbol.getQualifier().invariant != unitSymbol.getQualifier().invariant) {
        error(infoSink, "Presence of invariant qualifier must match:");
        writeTypeComparison = true;
    }

    // Precise...
    if (! crossStage && symbol.getQualifier().noContraction != unitSymbol.getQualifier().noContraction) {
        error(infoSink, "Presence of precise qualifier must match:");
        writeTypeComparison = true;
    }

    // Auxiliary and interpolation...
    if (symbol.getQualifier().centroid  != unitSymbol.getQualifier().centroid ||
        symbol.getQualifier().smooth    != unitSymbol.getQualifier().smooth ||
        symbol.getQualifier().flat      != unitSymbol.getQualifier().flat ||
        symbol.getQualifier().sample    != unitSymbol.getQualifier().sample ||
        symbol.getQualifier().patch     != unitSymbol.getQualifier().patch ||
        symbol.getQualifier().nopersp   != unitSymbol.getQualifier().nopersp) {
        error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
        writeTypeComparison = true;
    }

    // Memory...
    if (symbol.getQualifier().coherent          != unitSymbol.getQualifier().coherent ||
        symbol.getQualifier().devicecoherent    != unitSymbol.getQualifier().devicecoherent ||
        symbol.getQualifier().queuefamilycoherent  != unitSymbol.getQualifier().queuefamilycoherent ||
        symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent ||
        symbol.getQualifier().subgroupcoherent  != unitSymbol.getQualifier().subgroupcoherent ||
        symbol.getQualifier().nonprivate        != unitSymbol.getQualifier().nonprivate ||
        symbol.getQualifier().volatil           != unitSymbol.getQualifier().volatil ||
        symbol.getQualifier().restrict          != unitSymbol.getQualifier().restrict ||
        symbol.getQualifier().readonly          != unitSymbol.getQualifier().readonly ||
        symbol.getQualifier().writeonly         != unitSymbol.getQualifier().writeonly) {
        error(infoSink, "Memory qualifiers must match:");
        writeTypeComparison = true;
    }

    // Layouts...
    // TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec
    //       requires separate user-supplied offset from actual computed offset, but
    //       current implementation only has one offset.
    if (symbol.getQualifier().layoutMatrix    != unitSymbol.getQualifier().layoutMatrix ||
        symbol.getQualifier().layoutPacking   != unitSymbol.getQualifier().layoutPacking ||
        symbol.getQualifier().layoutLocation  != unitSymbol.getQualifier().layoutLocation ||
        symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent ||
        symbol.getQualifier().layoutIndex     != unitSymbol.getQualifier().layoutIndex ||
        symbol.getQualifier().layoutBinding   != unitSymbol.getQualifier().layoutBinding ||
        (symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset))) {
        error(infoSink, "Layout qualification must match:");
        writeTypeComparison = true;
    }

    // Initializers have to match, if both are present, and if we don't already know the types don't match
    if (! writeTypeComparison) {
        if (! symbol.getConstArray().empty() && ! unitSymbol.getConstArray().empty()) {
            if (symbol.getConstArray() != unitSymbol.getConstArray()) {
                error(infoSink, "Initializers must match:");
                infoSink.info << "    " << symbol.getName() << "\n";
            }
        }
    }

    if (writeTypeComparison)
        infoSink.info << "    " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus \"" <<
                                                             unitSymbol.getType().getCompleteString() << "\"\n";
}

//
// Do final link-time error checking of a complete (merged) intermediate representation.
// (Much error checking was done during merging).
//
// Also, lock in defaults of things not set, including array sizes.
//
void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
{
    if (getTreeRoot() == nullptr)
        return;

    if (numEntryPoints < 1) {
        if (source == EShSourceGlsl)
            error(infoSink, "Missing entry point: Each stage requires one entry point");
        else
            warn(infoSink, "Entry point not found");
    }

    if (numPushConstants > 1)
        error(infoSink, "Only one push_constant block is allowed per stage");

    // recursion and missing body checking
    checkCallGraphCycles(infoSink);
    checkCallGraphBodies(infoSink, keepUncalled);

    // overlap/alias/missing I/O, etc.
    inOutLocationCheck(infoSink);

    // invocations
    if (invocations == TQualifier::layoutNotSet)
        invocations = 1;

    if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipVertex"))
        error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipVertex (gl_ClipDistance is preferred)");
    if (inIoAccessed("gl_CullDistance") && inIoAccessed("gl_ClipVertex"))
        error(infoSink, "Can only use one of gl_CullDistance or gl_ClipVertex (gl_ClipDistance is preferred)");

    if (userOutputUsed() && (inIoAccessed("gl_FragColor") || inIoAccessed("gl_FragData")))
        error(infoSink, "Cannot use gl_FragColor or gl_FragData when using user-defined outputs");
    if (inIoAccessed("gl_FragColor") && inIoAccessed("gl_FragData"))
        error(infoSink, "Cannot use both gl_FragColor and gl_FragData");

    for (size_t b = 0; b < xfbBuffers.size(); ++b) {
        if (xfbBuffers[b].containsDouble)
            RoundToPow2(xfbBuffers[b].implicitStride, 8);

        // "It is a compile-time or link-time error to have
        // any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or
        // in different compilation units. While xfb_stride can be declared multiple times for the same buffer, it is a
        // compile-time or link-time error to have different values specified for the stride for the same buffer."
        if (xfbBuffers[b].stride != TQualifier::layoutXfbStrideEnd && xfbBuffers[b].implicitStride > xfbBuffers[b].stride) {
            error(infoSink, "xfb_stride is too small to hold all buffer entries:");
            infoSink.info.prefix(EPrefixError);
            infoSink.info << "    xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << ", minimum stride needed: " << xfbBuffers[b].implicitStride << "\n";
        }
        if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd)
            xfbBuffers[b].stride = xfbBuffers[b].implicitStride;

        // "If the buffer is capturing any
        // outputs with double-precision components, the stride must be a multiple of 8, otherwise it must be a
        // multiple of 4, or a compile-time or link-time error results."
        if (xfbBuffers[b].containsDouble && ! IsMultipleOfPow2(xfbBuffers[b].stride, 8)) {
            error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double:");
            infoSink.info.prefix(EPrefixError);
            infoSink.info << "    xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
        } else if (! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) {
            error(infoSink, "xfb_stride must be multiple of 4:");
            infoSink.info.prefix(EPrefixError);
            infoSink.info << "    xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
        }

        // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
        // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
        if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) {
            error(infoSink, "xfb_stride is too large:");
            infoSink.info.prefix(EPrefixError);
            infoSink.info << "    xfb_buffer " << (unsigned int)b << ", components (1/4 stride) needed are " << xfbBuffers[b].stride/4 << ", gl_MaxTransformFeedbackInterleavedComponents is " << resources.maxTransformFeedbackInterleavedComponents << "\n";
        }
    }

    switch (language) {
    case EShLangVertex:
        break;
    case EShLangTessControl:
        if (vertices == TQualifier::layoutNotSet)
            error(infoSink, "At least one shader must specify an output layout(vertices=...)");
        break;
    case EShLangTessEvaluation:
        if (source == EShSourceGlsl) {
            if (inputPrimitive == ElgNone)
                error(infoSink, "At least one shader must specify an input layout primitive");
            if (vertexSpacing == EvsNone)
                vertexSpacing = EvsEqual;
            if (vertexOrder == EvoNone)
                vertexOrder = EvoCcw;
        }
        break;
    case EShLangGeometry:
        if (inputPrimitive == ElgNone)
            error(infoSink, "At least one shader must specify an input layout primitive");
        if (outputPrimitive == ElgNone)
            error(infoSink, "At least one shader must specify an output layout primitive");
        if (vertices == TQualifier::layoutNotSet)
            error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
        break;
    case EShLangFragment:
        // for GL_ARB_post_depth_coverage, EarlyFragmentTest is set automatically in 
        // ParseHelper.cpp. So if we reach here, this must be GL_EXT_post_depth_coverage 
        // requiring explicit early_fragment_tests
        if (getPostDepthCoverage() && !getEarlyFragmentTests())
            error(infoSink, "post_depth_coverage requires early_fragment_tests");
        break;
    case EShLangCompute:
        break;

#ifdef NV_EXTENSIONS
    case EShLangRayGenNV:
    case EShLangIntersectNV:
    case EShLangAnyHitNV:
    case EShLangClosestHitNV:
    case EShLangMissNV:
    case EShLangCallableNV:
        if (numShaderRecordNVBlocks > 1)
            error(infoSink, "Only one shaderRecordNV buffer block is allowed per stage");
        break;
    case EShLangMeshNV:
        // NV_mesh_shader doesn't allow use of both single-view and per-view builtins.
        if (inIoAccessed("gl_Position") && inIoAccessed("gl_PositionPerViewNV"))
            error(infoSink, "Can only use one of gl_Position or gl_PositionPerViewNV");
        if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipDistancePerViewNV"))
            error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipDistancePerViewNV");
        if (inIoAccessed("gl_CullDistance") && inIoAccessed("gl_CullDistancePerViewNV"))
            error(infoSink, "Can only use one of gl_CullDistance or gl_CullDistancePerViewNV");
        if (inIoAccessed("gl_Layer") && inIoAccessed("gl_LayerPerViewNV"))
            error(infoSink, "Can only use one of gl_Layer or gl_LayerPerViewNV");
        if (inIoAccessed("gl_ViewportMask") && inIoAccessed("gl_ViewportMaskPerViewNV"))
            error(infoSink, "Can only use one of gl_ViewportMask or gl_ViewportMaskPerViewNV");
        if (outputPrimitive == ElgNone)
            error(infoSink, "At least one shader must specify an output layout primitive");
        if (vertices == TQualifier::layoutNotSet)
            error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
        if (primitives == TQualifier::layoutNotSet)
            error(infoSink, "At least one shader must specify a layout(max_primitives = value)");
        // fall through
    case EShLangTaskNV:
        if (numTaskNVBlocks > 1)
            error(infoSink, "Only one taskNV interface block is allowed per shader");
        break;
#endif

    default:
        error(infoSink, "Unknown Stage.");
        break;
    }

    // Process the tree for any node-specific work.
    class TFinalLinkTraverser : public TIntermTraverser {
    public:
        TFinalLinkTraverser() { }
        virtual ~TFinalLinkTraverser() { }

        virtual void visitSymbol(TIntermSymbol* symbol)
        {
            // Implicitly size arrays.
            // If an unsized array is left as unsized, it effectively
            // becomes run-time sized.
            symbol->getWritableType().adoptImplicitArraySizes(false);
        }
    } finalLinkTraverser;

    treeRoot->traverse(&finalLinkTraverser);
}

//
// See if the call graph contains any static recursion, which is disallowed
// by the specification.
//
void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink)
{
    // Clear fields we'll use for this.
    for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
        call->visited = false;
        call->currentPath = false;
        call->errorGiven = false;
    }

    //
    // Loop, looking for a new connected subgraph.  One subgraph is handled per loop iteration.
    //

    TCall* newRoot;
    do {
        // See if we have unvisited parts of the graph.
        newRoot = 0;
        for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
            if (! call->visited) {
                newRoot = &(*call);
                break;
            }
        }

        // If not, we are done.
        if (! newRoot)
            break;

        // Otherwise, we found a new subgraph, process it:
        // See what all can be reached by this new root, and if any of
        // that is recursive.  This is done by depth-first traversals, seeing
        // if a new call is found that was already in the currentPath (a back edge),
        // thereby detecting recursion.
        std::list<TCall*> stack;
        newRoot->currentPath = true; // currentPath will be true iff it is on the stack
        stack.push_back(newRoot);
        while (! stack.empty()) {
            // get a caller
            TCall* call = stack.back();

            // Add to the stack just one callee.
            // This algorithm always terminates, because only !visited and !currentPath causes a push
            // and all pushes change currentPath to true, and all pops change visited to true.
            TGraph::iterator child = callGraph.begin();
            for (; child != callGraph.end(); ++child) {

                // If we already visited this node, its whole subgraph has already been processed, so skip it.
                if (child->visited)
                    continue;

                if (call->callee == child->caller) {
                    if (child->currentPath) {
                        // Then, we found a back edge
                        if (! child->errorGiven) {
                            error(infoSink, "Recursion detected:");
                            infoSink.info << "    " << call->callee << " calling " << child->callee << "\n";
                            child->errorGiven = true;
                            recursive = true;
                        }
                    } else {
                        child->currentPath = true;
                        stack.push_back(&(*child));
                        break;
                    }
                }
            }
            if (child == callGraph.end()) {
                // no more callees, we bottomed out, never look at this node again
                stack.back()->currentPath = false;
                stack.back()->visited = true;
                stack.pop_back();
            }
        }  // end while, meaning nothing left to process in this subtree

    } while (newRoot);  // redundant loop check; should always exit via the 'break' above
}

//
// See which functions are reachable from the entry point and which have bodies.
// Reachable ones with missing bodies are errors.
// Unreachable bodies are dead code.
//
void TIntermediate::checkCallGraphBodies(TInfoSink& infoSink, bool keepUncalled)
{
    // Clear fields we'll use for this.
    for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
        call->visited = false;
        call->calleeBodyPosition = -1;
    }

    // The top level of the AST includes function definitions (bodies).
    // Compare these to function calls in the call graph.
    // We'll end up knowing which have bodies, and if so,
    // how to map the call-graph node to the location in the AST.
    TIntermSequence &functionSequence = getTreeRoot()->getAsAggregate()->getSequence();
    std::vector<bool> reachable(functionSequence.size(), true); // so that non-functions are reachable
    for (int f = 0; f < (int)functionSequence.size(); ++f) {
        glslang::TIntermAggregate* node = functionSequence[f]->getAsAggregate();
        if (node && (node->getOp() == glslang::EOpFunction)) {
            if (node->getName().compare(getEntryPointMangledName().c_str()) != 0)
                reachable[f] = false; // so that function bodies are unreachable, until proven otherwise
            for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
                if (call->callee == node->getName())
                    call->calleeBodyPosition = f;
            }
        }
    }

    // Start call-graph traversal by visiting the entry point nodes.
    for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
        if (call->caller.compare(getEntryPointMangledName().c_str()) == 0)
            call->visited = true;
    }

    // Propagate 'visited' through the call-graph to every part of the graph it
    // can reach (seeded with the entry-point setting above).
    bool changed;
    do {
        changed = false;
        for (auto call1 = callGraph.begin(); call1 != callGraph.end(); ++call1) {
            if (call1->visited) {
                for (TGraph::iterator call2 = callGraph.begin(); call2 != callGraph.end(); ++call2) {
                    if (! call2->visited) {
                        if (call1->callee == call2->caller) {
                            changed = true;
                            call2->visited = true;
                        }
                    }
                }
            }
        }
    } while (changed);

    // Any call-graph node set to visited but without a callee body is an error.
    for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
        if (call->visited) {
            if (call->calleeBodyPosition == -1) {
                error(infoSink, "No function definition (body) found: ");
                infoSink.info << "    " << call->callee << "\n";
            } else
                reachable[call->calleeBodyPosition] = true;
        }
    }

    // Bodies in the AST not reached by the call graph are dead;
    // clear them out, since they can't be reached and also can't
    // be translated further due to possibility of being ill defined.
    if (! keepUncalled) {
        for (int f = 0; f < (int)functionSequence.size(); ++f) {
            if (! reachable[f])
                functionSequence[f] = nullptr;
        }
        functionSequence.erase(std::remove(functionSequence.begin(), functionSequence.end(), nullptr), functionSequence.end());
    }
}

//
// Satisfy rules for location qualifiers on inputs and outputs
//
void TIntermediate::inOutLocationCheck(TInfoSink& infoSink)
{
    // ES 3.0 requires all outputs to have location qualifiers if there is more than one output
    bool fragOutWithNoLocation = false;
    int numFragOut = 0;

    // TODO: linker functionality: location collision checking

    TIntermSequence& linkObjects = findLinkerObjects()->getSequence();
    for (size_t i = 0; i < linkObjects.size(); ++i) {
        const TType& type = linkObjects[i]->getAsTyped()->getType();
        const TQualifier& qualifier = type.getQualifier();
        if (language == EShLangFragment) {
            if (qualifier.storage == EvqVaryingOut && qualifier.builtIn == EbvNone) {
                ++numFragOut;
                if (!qualifier.hasAnyLocation())
                    fragOutWithNoLocation = true;
            }
        }
    }

    if (profile == EEsProfile) {
        if (numFragOut > 1 && fragOutWithNoLocation)
            error(infoSink, "when more than one fragment shader output, all must have location qualifiers");
    }
}

TIntermAggregate* TIntermediate::findLinkerObjects() const
{
    // Get the top-level globals
    TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();

    // Get the last member of the sequences, expected to be the linker-object lists
    assert(globals.back()->getAsAggregate()->getOp() == EOpLinkerObjects);

    return globals.back()->getAsAggregate();
}

// See if a variable was both a user-declared output and used.
// Note: the spec discusses writing to one, but this looks at read or write, which
// is more useful, and perhaps the spec should be changed to reflect that.
bool TIntermediate::userOutputUsed() const
{
    const TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();

    bool found = false;
    for (size_t i = 0; i < linkerObjects.size(); ++i) {
        const TIntermSymbol& symbolNode = *linkerObjects[i]->getAsSymbolNode();
        if (symbolNode.getQualifier().storage == EvqVaryingOut &&
            symbolNode.getName().compare(0, 3, "gl_") != 0 &&
            inIoAccessed(symbolNode.getName())) {
            found = true;
            break;
        }
    }

    return found;
}

// Accumulate locations used for inputs, outputs, and uniforms, and check for collisions
// as the accumulation is done.
//
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
//
// typeCollision is set to true if there is no direct collision, but the types in the same location
// are different.
//
int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& type, bool& typeCollision)
{
    typeCollision = false;

    int set;
    if (qualifier.isPipeInput())
        set = 0;
    else if (qualifier.isPipeOutput())
        set = 1;
    else if (qualifier.storage == EvqUniform)
        set = 2;
    else if (qualifier.storage == EvqBuffer)
        set = 3;
    else
        return -1;

    int size;
    if (qualifier.isUniformOrBuffer() || qualifier.isTaskMemory()) {
        if (type.isSizedArray())
            size = type.getCumulativeArraySize();
        else
            size = 1;
    } else {
        // Strip off the outer array dimension for those having an extra one.
        if (type.isArray() && qualifier.isArrayedIo(language)) {
            TType elementType(type, 0);
            size = computeTypeLocationSize(elementType, language);
        } else
            size = computeTypeLocationSize(type, language);
    }

    // Locations, and components within locations.
    //
    // Almost always, dealing with components means a single location is involved.
    // The exception is a dvec3. From the spec:
    //
    // "A dvec3 will consume all four components of the first location and components 0 and 1 of
    // the second location. This leaves components 2 and 3 available for other component-qualified
    // declarations."
    //
    // That means, without ever mentioning a component, a component range
    // for a different location gets specified, if it's not a vertex shader input. (!)
    // (A vertex shader input will show using only one location, even for a dvec3/4.)
    //
    // So, for the case of dvec3, we need two independent ioRanges.

    int collision = -1; // no collision
    if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
        (qualifier.isPipeInput() || qualifier.isPipeOutput())) {
        // Dealing with dvec3 in/out split across two locations.
        // Need two io-ranges.
        // The case where the dvec3 doesn't start at component 0 was previously caught as overflow.

        // First range:
        TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
        TRange componentRange(0, 3);
        TIoRange range(locationRange, componentRange, type.getBasicType(), 0);

        // check for collisions
        collision = checkLocationRange(set, range, type, typeCollision);
        if (collision < 0) {
            usedIo[set].push_back(range);

            // Second range:
            TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1);
            TRange componentRange2(0, 1);
            TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0);

            // check for collisions
            collision = checkLocationRange(set, range2, type, typeCollision);
            if (collision < 0)
                usedIo[set].push_back(range2);
        }
    } else {
        // Not a dvec3 in/out split across two locations, generic path.
        // Need a single IO-range block.

        TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1);
        TRange componentRange(0, 3);
        if (qualifier.hasComponent() || type.getVectorSize() > 0) {
            int consumedComponents = type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1);
            if (qualifier.hasComponent())
                componentRange.start = qualifier.layoutComponent;
            componentRange.last  = componentRange.start + consumedComponents - 1;
        }

        // combine location and component ranges
        TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0);

        // check for collisions, except for vertex inputs on desktop targeting OpenGL
        if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0)
            collision = checkLocationRange(set, range, type, typeCollision);

        if (collision < 0)
            usedIo[set].push_back(range);
    }

    return collision;
}

// Compare a new (the passed in) 'range' against the existing set, and see
// if there are any collisions.
//
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
//
int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TType& type, bool& typeCollision)
{
    for (size_t r = 0; r < usedIo[set].size(); ++r) {
        if (range.overlap(usedIo[set][r])) {
            // there is a collision; pick one
            return std::max(range.location.start, usedIo[set][r].location.start);
        } else if (range.location.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) {
            // aliased-type mismatch
            typeCollision = true;
            return std::max(range.location.start, usedIo[set][r].location.start);
        }
    }

    return -1; // no collision
}

// Accumulate bindings and offsets, and check for collisions
// as the accumulation is done.
//
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
//
int TIntermediate::addUsedOffsets(int binding, int offset, int numOffsets)
{
    TRange bindingRange(binding, binding);
    TRange offsetRange(offset, offset + numOffsets - 1);
    TOffsetRange range(bindingRange, offsetRange);

    // check for collisions, except for vertex inputs on desktop
    for (size_t r = 0; r < usedAtomics.size(); ++r) {
        if (range.overlap(usedAtomics[r])) {
            // there is a collision; pick one
            return std::max(offset, usedAtomics[r].offset.start);
        }
    }

    usedAtomics.push_back(range);

    return -1; // no collision
}

// Accumulate used constant_id values.
//
// Return false is one was already used.
bool TIntermediate::addUsedConstantId(int id)
{
    if (usedConstantId.find(id) != usedConstantId.end())
        return false;

    usedConstantId.insert(id);

    return true;
}

// Recursively figure out how many locations are used up by an input or output type.
// Return the size of type, as measured by "locations".
int TIntermediate::computeTypeLocationSize(const TType& type, EShLanguage stage)
{
    // "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n
    // consecutive locations..."
    if (type.isArray()) {
        // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
        // TODO: are there valid cases of having an unsized array with a location?  If so, running this code too early.
        TType elementType(type, 0);
        if (type.isSizedArray()
#ifdef NV_EXTENSIONS
            && !type.getQualifier().isPerView()
#endif
            )
            return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage);
        else {
#ifdef NV_EXTENSIONS
            // unset perViewNV attributes for arrayed per-view outputs: "perviewNV vec4 v[MAX_VIEWS][3];"
            elementType.getQualifier().perViewNV = false;
#endif
            return computeTypeLocationSize(elementType, stage);
        }
    }

    // "The locations consumed by block and structure members are determined by applying the rules above
    // recursively..."
    if (type.isStruct()) {
        int size = 0;
        for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
            TType memberType(type, member);
            size += computeTypeLocationSize(memberType, stage);
        }
        return size;
    }

    // ES: "If a shader input is any scalar or vector type, it will consume a single location."

    // Desktop: "If a vertex shader input is any scalar or vector type, it will consume a single location. If a non-vertex
    // shader input is a scalar or vector type other than dvec3 or dvec4, it will consume a single location, while
    // types dvec3 or dvec4 will consume two consecutive locations. Inputs of type double and dvec2 will
    // consume only a single location, in all stages."
    if (type.isScalar())
        return 1;
    if (type.isVector()) {
        if (stage == EShLangVertex && type.getQualifier().isPipeInput())
            return 1;
        if (type.getBasicType() == EbtDouble && type.getVectorSize() > 2)
            return 2;
        else
            return 1;
    }

    // "If the declared input is an n x m single- or double-precision matrix, ...
    // The number of locations assigned for each matrix will be the same as
    // for an n-element array of m-component vectors..."
    if (type.isMatrix()) {
        TType columnType(type, 0);
        return type.getMatrixCols() * computeTypeLocationSize(columnType, stage);
    }

    assert(0);
    return 1;
}

// Same as computeTypeLocationSize but for uniforms
int TIntermediate::computeTypeUniformLocationSize(const TType& type)
{
    // "Individual elements of a uniform array are assigned
    // consecutive locations with the first element taking location
    // location."
    if (type.isArray()) {
        // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
        TType elementType(type, 0);
        if (type.isSizedArray()) {
            return type.getOuterArraySize() * computeTypeUniformLocationSize(elementType);
        } else {
            // TODO: are there valid cases of having an implicitly-sized array with a location?  If so, running this code too early.
            return computeTypeUniformLocationSize(elementType);
        }
    }

    // "Each subsequent inner-most member or element gets incremental
    // locations for the entire structure or array."
    if (type.isStruct()) {
        int size = 0;
        for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
            TType memberType(type, member);
            size += computeTypeUniformLocationSize(memberType);
        }
        return size;
    }

    return 1;
}

// Accumulate xfb buffer ranges and check for collisions as the accumulation is done.
//
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
//
int TIntermediate::addXfbBufferOffset(const TType& type)
{
    const TQualifier& qualifier = type.getQualifier();

    assert(qualifier.hasXfbOffset() && qualifier.hasXfbBuffer());
    TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer];

    // compute the range
    unsigned int size = computeTypeXfbSize(type, buffer.containsDouble);
    buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size);
    TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1);

    // check for collisions
    for (size_t r = 0; r < buffer.ranges.size(); ++r) {
        if (range.overlap(buffer.ranges[r])) {
            // there is a collision; pick an example to return
            return std::max(range.start, buffer.ranges[r].start);
        }
    }

    buffer.ranges.push_back(range);

    return -1;  // no collision
}

// Recursively figure out how many bytes of xfb buffer are used by the given type.
// Return the size of type, in bytes.
// Sets containsDouble to true if the type contains a double.
// N.B. Caller must set containsDouble to false before calling.
unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& containsDouble) const
{
    // "...if applied to an aggregate containing a double, the offset must also be a multiple of 8,
    // and the space taken in the buffer will be a multiple of 8.
    // ...within the qualified entity, subsequent components are each
    // assigned, in order, to the next available offset aligned to a multiple of
    // that component's size.  Aggregate types are flattened down to the component
    // level to get this sequence of components."

    if (type.isArray()) {
        // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
        assert(type.isSizedArray());
        TType elementType(type, 0);
        return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble);
    }

    if (type.isStruct()) {
        unsigned int size = 0;
        bool structContainsDouble = false;
        for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
            TType memberType(type, member);
            // "... if applied to
            // an aggregate containing a double, the offset must also be a multiple of 8,
            // and the space taken in the buffer will be a multiple of 8."
            bool memberContainsDouble = false;
            int memberSize = computeTypeXfbSize(memberType, memberContainsDouble);
            if (memberContainsDouble) {
                structContainsDouble = true;
                RoundToPow2(size, 8);
            }
            size += memberSize;
        }

        if (structContainsDouble) {
            containsDouble = true;
            RoundToPow2(size, 8);
        }
        return size;
    }

    int numComponents;
    if (type.isScalar())
        numComponents = 1;
    else if (type.isVector())
        numComponents = type.getVectorSize();
    else if (type.isMatrix())
        numComponents = type.getMatrixCols() * type.getMatrixRows();
    else {
        assert(0);
        numComponents = 1;
    }

    if (type.getBasicType() == EbtDouble) {
        containsDouble = true;
        return 8 * numComponents;
    } else
        return 4 * numComponents;
}

const int baseAlignmentVec4Std140 = 16;

// Return the size and alignment of a component of the given type.
// The size is returned in the 'size' parameter
// Return value is the alignment..
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
{
    switch (type.getBasicType()) {
    case EbtInt64:
    case EbtUint64:
    case EbtDouble:  size = 8; return 8;
    case EbtFloat16: size = 2; return 2;
    case EbtInt8:
    case EbtUint8:   size = 1; return 1;
    case EbtInt16:
    case EbtUint16:  size = 2; return 2;
    default:         size = 4; return 4;
    }
}

// Implement base-alignment and size rules from section 7.6.2.2 Standard Uniform Block Layout
// Operates recursively.
//
// If std140 is true, it does the rounding up to vec4 size required by std140,
// otherwise it does not, yielding std430 rules.
//
// The size is returned in the 'size' parameter
//
// The stride is only non-0 for arrays or matrices, and is the stride of the
// top-level object nested within the type.  E.g., for an array of matrices,
// it is the distances needed between matrices, despite the rules saying the
// stride comes from the flattening down to vectors.
//
// Return value is the alignment of the type.
int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, bool std140, bool rowMajor)
{
    int alignment;

    // When using the std140 storage layout, structures will be laid out in buffer
    // storage with its members stored in monotonically increasing order based on their
    // location in the declaration. A structure and each structure member have a base
    // offset and a base alignment, from which an aligned offset is computed by rounding
    // the base offset up to a multiple of the base alignment. The base offset of the first
    // member of a structure is taken from the aligned offset of the structure itself. The
    // base offset of all other structure members is derived by taking the offset of the
    // last basic machine unit consumed by the previous member and adding one. Each
    // structure member is stored in memory at its aligned offset. The members of a top-
    // level uniform block are laid out in buffer storage by treating the uniform block as
    // a structure with a base offset of zero.
    //
    //   1. If the member is a scalar consuming N basic machine units, the base alignment is N.
    //
    //   2. If the member is a two- or four-component vector with components consuming N basic
    //      machine units, the base alignment is 2N or 4N, respectively.
    //
    //   3. If the member is a three-component vector with components consuming N
    //      basic machine units, the base alignment is 4N.
    //
    //   4. If the member is an array of scalars or vectors, the base alignment and array
    //      stride are set to match the base alignment of a single array element, according
    //      to rules (1), (2), and (3), and rounded up to the base alignment of a vec4. The
    //      array may have padding at the end; the base offset of the member following
    //      the array is rounded up to the next multiple of the base alignment.
    //
    //   5. If the member is a column-major matrix with C columns and R rows, the
    //      matrix is stored identically to an array of C column vectors with R
    //      components each, according to rule (4).
    //
    //   6. If the member is an array of S column-major matrices with C columns and
    //      R rows, the matrix is stored identically to a row of S X C column vectors
    //      with R components each, according to rule (4).
    //
    //   7. If the member is a row-major matrix with C columns and R rows, the matrix
    //      is stored identically to an array of R row vectors with C components each,
    //      according to rule (4).
    //
    //   8. If the member is an array of S row-major matrices with C columns and R
    //      rows, the matrix is stored identically to a row of S X R row vectors with C
    //      components each, according to rule (4).
    //
    //   9. If the member is a structure, the base alignment of the structure is N , where
    //      N is the largest base alignment value of any    of its members, and rounded
    //      up to the base alignment of a vec4. The individual members of this substructure
    //      are then assigned offsets by applying this set of rules recursively,
    //      where the base offset of the first member of the sub-structure is equal to the
    //      aligned offset of the structure. The structure may have padding at the end;
    //      the base offset of the member following the sub-structure is rounded up to
    //      the next multiple of the base alignment of the structure.
    //
    //   10. If the member is an array of S structures, the S elements of the array are laid
    //       out in order, according to rule (9).
    //
    //   Assuming, for rule 10:  The stride is the same as the size of an element.

    stride = 0;
    int dummyStride;

    // rules 4, 6, 8, and 10
    if (type.isArray()) {
        // TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
        TType derefType(type, 0);
        alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
        if (std140)
            alignment = std::max(baseAlignmentVec4Std140, alignment);
        RoundToPow2(size, alignment);
        stride = size;  // uses full matrix size for stride of an array of matrices (not quite what rule 6/8, but what's expected)
                        // uses the assumption for rule 10 in the comment above
        size = stride * type.getOuterArraySize();
        return alignment;
    }

    // rule 9
    if (type.getBasicType() == EbtStruct) {
        const TTypeList& memberList = *type.getStruct();

        size = 0;
        int maxAlignment = std140 ? baseAlignmentVec4Std140 : 0;
        for (size_t m = 0; m < memberList.size(); ++m) {
            int memberSize;
            // modify just the children's view of matrix layout, if there is one for this member
            TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
            int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, std140,
                                                   (subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
            maxAlignment = std::max(maxAlignment, memberAlignment);
            RoundToPow2(size, memberAlignment);
            size += memberSize;
        }

        // The structure may have padding at the end; the base offset of
        // the member following the sub-structure is rounded up to the next
        // multiple of the base alignment of the structure.
        RoundToPow2(size, maxAlignment);

        return maxAlignment;
    }

    // rule 1
    if (type.isScalar())
        return getBaseAlignmentScalar(type, size);

    // rules 2 and 3
    if (type.isVector()) {
        int scalarAlign = getBaseAlignmentScalar(type, size);
        switch (type.getVectorSize()) {
        case 1: // HLSL has this, GLSL does not
            return scalarAlign;
        case 2:
            size *= 2;
            return 2 * scalarAlign;
        default:
            size *= type.getVectorSize();
            return 4 * scalarAlign;
        }
    }

    // rules 5 and 7
    if (type.isMatrix()) {
        // rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
        TType derefType(type, 0, rowMajor);

        alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
        if (std140)
            alignment = std::max(baseAlignmentVec4Std140, alignment);
        RoundToPow2(size, alignment);
        stride = size;  // use intra-matrix stride for stride of a just a matrix
        if (rowMajor)
            size = stride * type.getMatrixRows();
        else
            size = stride * type.getMatrixCols();

        return alignment;
    }

    assert(0);  // all cases should be covered above
    size = baseAlignmentVec4Std140;
    return baseAlignmentVec4Std140;
}

// To aid the basic HLSL rule about crossing vec4 boundaries.
bool TIntermediate::improperStraddle(const TType& type, int size, int offset)
{
    if (! type.isVector() || type.isArray())
        return false;

    return size <= 16 ? offset / 16 != (offset + size - 1) / 16
                      : offset % 16 != 0;
}

} // end namespace glslang
