//
// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
// Copyright (C) 2012-2015 LunarG, Inc.
// Copyright (C) 2015-2018 Google, 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.
//

//
// Build the intermediate representation.
//

#include "localintermediate.h"
#include "RemoveTree.h"
#include "SymbolTable.h"
#include "propagateNoContraction.h"

#include <cfloat>
#include <utility>
#include <tuple>

namespace glslang {

////////////////////////////////////////////////////////////////////////////
//
// First set of functions are to help build the intermediate representation.
// These functions are not member functions of the nodes.
// They are called from parser productions.
//
/////////////////////////////////////////////////////////////////////////////

//
// Add a terminal node for an identifier in an expression.
//
// Returns the added node.
//

TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray,
                                        TIntermTyped* constSubtree, const TSourceLoc& loc)
{
    TIntermSymbol* node = new TIntermSymbol(id, name, type);
    node->setLoc(loc);
    node->setConstArray(constArray);
    node->setConstSubtree(constSubtree);

    return node;
}

TIntermSymbol* TIntermediate::addSymbol(const TIntermSymbol& intermSymbol)
{
    return addSymbol(intermSymbol.getId(),
                     intermSymbol.getName(),
                     intermSymbol.getType(),
                     intermSymbol.getConstArray(),
                     intermSymbol.getConstSubtree(),
                     intermSymbol.getLoc());
}

TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable)
{
    glslang::TSourceLoc loc; // just a null location
    loc.init();

    return addSymbol(variable, loc);
}

TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, const TSourceLoc& loc)
{
    return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), variable.getConstArray(), variable.getConstSubtree(), loc);
}

TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc)
{
    TConstUnionArray unionArray;  // just a null constant

    return addSymbol(0, "", type, unionArray, nullptr, loc);
}

//
// Connect two nodes with a new parent that does a binary operation on the nodes.
//
// Returns the added node.
//
// Returns nullptr if the working conversions and promotions could not be found.
//
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
{
    // No operations work on blocks
    if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
        return nullptr;

    // Convert "reference +/- int" and "reference - reference" to integer math
    if ((op == EOpAdd || op == EOpSub) && extensionRequested(E_GL_EXT_buffer_reference2)) {

        // No addressing math on struct with unsized array.
        if ((left->isReference() && left->getType().getReferentType()->containsUnsizedArray()) ||
            (right->isReference() && right->getType().getReferentType()->containsUnsizedArray())) {
            return nullptr;
        }

        if (left->isReference() && isTypeInt(right->getBasicType())) {
            const TType& referenceType = left->getType();
            TIntermConstantUnion* size = addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(left->getType()), loc, true);
            left  = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64));

            right = createConversion(EbtInt64, right);
            right = addBinaryMath(EOpMul, right, size, loc);

            TIntermTyped *node = addBinaryMath(op, left, right, loc);
            node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
            return node;
        }

        if (op == EOpAdd && right->isReference() && isTypeInt(left->getBasicType())) {
            const TType& referenceType = right->getType();
            TIntermConstantUnion* size = addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(right->getType()), loc, true);
            right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));

            left  = createConversion(EbtInt64, left);
            left  = addBinaryMath(EOpMul, left, size, loc);

            TIntermTyped *node = addBinaryMath(op, left, right, loc);
            node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
            return node;
        }

        if (op == EOpSub && left->isReference() && right->isReference()) {
            TIntermConstantUnion* size = addConstantUnion((long long)computeBufferReferenceTypeSize(left->getType()), loc, true);

            left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64));
            right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));

            left = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, left, TType(EbtInt64));
            right = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, right, TType(EbtInt64));

            left = addBinaryMath(EOpSub, left, right, loc);

            TIntermTyped *node = addBinaryMath(EOpDiv, left, size, loc);
            return node;
        }

        // No other math operators supported on references
        if (left->isReference() || right->isReference()) {
            return nullptr;
        }
    }

    // Try converting the children's base types to compatible types.
    auto children = addConversion(op, left, right);
    left = std::get<0>(children);
    right = std::get<1>(children);

    if (left == nullptr || right == nullptr)
        return nullptr;

    // Convert the children's type shape to be compatible.
    addBiShapeConversion(op, left, right);
    if (left == nullptr || right == nullptr)
        return nullptr;

    //
    // Need a new node holding things together.  Make
    // one and promote it to the right type.
    //
    TIntermBinary* node = addBinaryNode(op, left, right, loc);
    if (! promote(node))
        return nullptr;

    node->updatePrecision();

    //
    // If they are both (non-specialization) constants, they must be folded.
    // (Unless it's the sequence (comma) operator, but that's handled in addComma().)
    //
    TIntermConstantUnion *leftTempConstant = node->getLeft()->getAsConstantUnion();
    TIntermConstantUnion *rightTempConstant = node->getRight()->getAsConstantUnion();
    if (leftTempConstant && rightTempConstant) {
        TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant);
        if (folded)
            return folded;
    }

    // If can propagate spec-constantness and if the operation is an allowed
    // specialization-constant operation, make a spec-constant.
    if (specConstantPropagates(*node->getLeft(), *node->getRight()) && isSpecializationOperation(*node))
        node->getWritableType().getQualifier().makeSpecConstant();

    // If must propagate nonuniform, make a nonuniform.
    if ((node->getLeft()->getQualifier().isNonUniform() || node->getRight()->getQualifier().isNonUniform()) &&
            isNonuniformPropagating(node->getOp()))
        node->getWritableType().getQualifier().nonUniform = true;

    return node;
}

//
// Low level: add binary node (no promotions or other argument modifications)
//
TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) const
{
    // build the node
    TIntermBinary* node = new TIntermBinary(op);
    if (loc.line == 0)
        loc = left->getLoc();
    node->setLoc(loc);
    node->setLeft(left);
    node->setRight(right);

    return node;
}

//
// like non-type form, but sets node's type.
//
TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc, const TType& type) const
{
    TIntermBinary* node = addBinaryNode(op, left, right, loc);
    node->setType(type);
    return node;
}

//
// Low level: add unary node (no promotions or other argument modifications)
//
TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc) const
{
    TIntermUnary* node = new TIntermUnary(op);
    if (loc.line == 0)
        loc = child->getLoc();
    node->setLoc(loc);
    node->setOperand(child);

    return node;
}

//
// like non-type form, but sets node's type.
//
TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc, const TType& type) const
{
    TIntermUnary* node = addUnaryNode(op, child, loc);
    node->setType(type);
    return node;
}

//
// Connect two nodes through an assignment.
//
// Returns the added node.
//
// Returns nullptr if the 'right' type could not be converted to match the 'left' type,
// or the resulting operation cannot be properly promoted.
//
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
{
    // No block assignment
    if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
        return nullptr;

    // Convert "reference += int" to "reference = reference + int". We need this because the
    // "reference + int" calculation involves a cast back to the original type, which makes it
    // not an lvalue.
    if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference() &&
        extensionRequested(E_GL_EXT_buffer_reference2)) {

        if (!(right->getType().isScalar() && right->getType().isIntegerDomain()))
            return nullptr;

        TIntermTyped* node = addBinaryMath(op == EOpAddAssign ? EOpAdd : EOpSub, left, right, loc);
        if (!node)
            return nullptr;

        TIntermSymbol* symbol = left->getAsSymbolNode();
        left = addSymbol(*symbol);

        node = addAssign(EOpAssign, left, node, loc);
        return node;
    }

    //
    // Like adding binary math, except the conversion can only go
    // from right to left.
    //

    // convert base types, nullptr return means not possible
    right = addConversion(op, left->getType(), right);
    if (right == nullptr)
        return nullptr;

    // convert shape
    right = addUniShapeConversion(op, left->getType(), right);

    // build the node
    TIntermBinary* node = addBinaryNode(op, left, right, loc);

    if (! promote(node))
        return nullptr;

    node->updatePrecision();

    return node;
}

//
// Connect two nodes through an index operator, where the left node is the base
// of an array or struct, and the right node is a direct or indirect offset.
//
// Returns the added node.
// The caller should set the type of the returned node.
//
TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc)
{
    // caller should set the type
    return addBinaryNode(op, base, index, loc);
}

//
// Add one node as the parent of another that it operates on.
//
// Returns the added node.
//
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc)
{
    if (child == 0)
        return nullptr;

    if (child->getType().getBasicType() == EbtBlock)
        return nullptr;

    switch (op) {
    case EOpLogicalNot:
        if (getSource() == EShSourceHlsl) {
            break; // HLSL can promote logical not
        }

        if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
            return nullptr;
        }
        break;

    case EOpPostIncrement:
    case EOpPreIncrement:
    case EOpPostDecrement:
    case EOpPreDecrement:
    case EOpNegative:
        if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
            return nullptr;
    default: break; // some compilers want this
    }

    //
    // Do we need to promote the operand?
    //
    TBasicType newType = EbtVoid;
    switch (op) {
    case EOpConstructBool:   newType = EbtBool;   break;
    case EOpConstructFloat:  newType = EbtFloat;  break;
    case EOpConstructInt:    newType = EbtInt;    break;
    case EOpConstructUint:   newType = EbtUint;   break;
#ifndef GLSLANG_WEB
    case EOpConstructInt8:   newType = EbtInt8;   break;
    case EOpConstructUint8:  newType = EbtUint8;  break;
    case EOpConstructInt16:  newType = EbtInt16;  break;
    case EOpConstructUint16: newType = EbtUint16; break;
    case EOpConstructInt64:  newType = EbtInt64;  break;
    case EOpConstructUint64: newType = EbtUint64; break;
    case EOpConstructDouble: newType = EbtDouble; break;
    case EOpConstructFloat16: newType = EbtFloat16; break;
#endif
    default: break; // some compilers want this
    }

    if (newType != EbtVoid) {
        child = addConversion(op, TType(newType, EvqTemporary, child->getVectorSize(),
                                                               child->getMatrixCols(),
                                                               child->getMatrixRows(),
                                                               child->isVector()),
                              child);
        if (child == nullptr)
            return nullptr;
    }

    //
    // For constructors, we are now done, it was all in the conversion.
    // TODO: but, did this bypass constant folding?
    //
    switch (op) {
    case EOpConstructInt8:
    case EOpConstructUint8:
    case EOpConstructInt16:
    case EOpConstructUint16:
    case EOpConstructInt:
    case EOpConstructUint:
    case EOpConstructInt64:
    case EOpConstructUint64:
    case EOpConstructBool:
    case EOpConstructFloat:
    case EOpConstructDouble:
    case EOpConstructFloat16:
        return child;
    default: break; // some compilers want this
    }

    //
    // Make a new node for the operator.
    //
    TIntermUnary* node = addUnaryNode(op, child, loc);

    if (! promote(node))
        return nullptr;

    node->updatePrecision();

    // If it's a (non-specialization) constant, it must be folded.
    if (node->getOperand()->getAsConstantUnion())
        return node->getOperand()->getAsConstantUnion()->fold(op, node->getType());

    // If it's a specialization constant, the result is too,
    // if the operation is allowed for specialization constants.
    if (node->getOperand()->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node))
        node->getWritableType().getQualifier().makeSpecConstant();

    // If must propagate nonuniform, make a nonuniform.
    if (node->getOperand()->getQualifier().isNonUniform() && isNonuniformPropagating(node->getOp()))
        node->getWritableType().getQualifier().nonUniform = true;

    return node;
}

TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary,
    TIntermNode* childNode, const TType& returnType)
{
    if (unary) {
        //
        // Treat it like a unary operator.
        // addUnaryMath() should get the type correct on its own;
        // including constness (which would differ from the prototype).
        //
        TIntermTyped* child = childNode->getAsTyped();
        if (child == nullptr)
            return nullptr;

        if (child->getAsConstantUnion()) {
            TIntermTyped* folded = child->getAsConstantUnion()->fold(op, returnType);
            if (folded)
                return folded;
        }

        return addUnaryNode(op, child, child->getLoc(), returnType);
    } else {
        // setAggregateOperater() calls fold() for constant folding
        TIntermTyped* node = setAggregateOperator(childNode, op, returnType, loc);

        return node;
    }
}

//
// This is the safe way to change the operator on an aggregate, as it
// does lots of error checking and fixing.  Especially for establishing
// a function call's operation on its set of parameters.  Sequences
// of instructions are also aggregates, but they just directly set
// their operator to EOpSequence.
//
// Returns an aggregate node, which could be the one passed in if
// it was already an aggregate.
//
TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc)
{
    TIntermAggregate* aggNode;

    //
    // Make sure we have an aggregate.  If not turn it into one.
    //
    if (node != nullptr) {
        aggNode = node->getAsAggregate();
        if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
            //
            // Make an aggregate containing this node.
            //
            aggNode = new TIntermAggregate();
            aggNode->getSequence().push_back(node);
            if (loc.line == 0)
                loc = node->getLoc();
        }
    } else
        aggNode = new TIntermAggregate();

    //
    // Set the operator.
    //
    aggNode->setOperator(op);
    if (loc.line != 0)
        aggNode->setLoc(loc);

    aggNode->setType(type);

    return fold(aggNode);
}

bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const
{
    //
    // Does the base type even allow the operation?
    //
    switch (node->getBasicType()) {
    case EbtVoid:
        return false;
    case EbtAtomicUint:
    case EbtSampler:
    case EbtAccStructNV:
        // opaque types can be passed to functions
        if (op == EOpFunction)
            break;

        // HLSL can assign samplers directly (no constructor)
        if (getSource() == EShSourceHlsl && node->getBasicType() == EbtSampler)
            break;

        // samplers can get assigned via a sampler constructor
        // (well, not yet, but code in the rest of this function is ready for it)
        if (node->getBasicType() == EbtSampler && op == EOpAssign &&
            node->getAsOperator() != nullptr && node->getAsOperator()->getOp() == EOpConstructTextureSampler)
            break;

        // otherwise, opaque types can't even be operated on, let alone converted
        return false;
    default:
        break;
    }

    return true;
}

// This is 'mechanism' here, it does any conversion told.
// It is about basic type, not about shape.
// The policy comes from the shader or the calling code.
TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped* node) const
{
    //
    // Add a new newNode for the conversion.
    //
    TIntermUnary* newNode = nullptr;

    TOperator newOp = EOpNull;

    bool convertToIntTypes = (convertTo == EbtInt8  || convertTo == EbtUint8  ||
                              convertTo == EbtInt16 || convertTo == EbtUint16 ||
                              convertTo == EbtInt   || convertTo == EbtUint   ||
                              convertTo == EbtInt64 || convertTo == EbtUint64);

    bool convertFromIntTypes = (node->getBasicType() == EbtInt8  || node->getBasicType() == EbtUint8  ||
                                node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16 ||
                                node->getBasicType() == EbtInt   || node->getBasicType() == EbtUint   ||
                                node->getBasicType() == EbtInt64 || node->getBasicType() == EbtUint64);

    bool convertToFloatTypes = (convertTo == EbtFloat16 || convertTo == EbtFloat || convertTo == EbtDouble);

    bool convertFromFloatTypes = (node->getBasicType() == EbtFloat16 ||
                                  node->getBasicType() == EbtFloat ||
                                  node->getBasicType() == EbtDouble);

    if (! getArithemeticInt8Enabled()) {
        if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) ||
            ((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes))
            return nullptr;
    }

    if (! getArithemeticInt16Enabled()) {
        if (((convertTo == EbtInt16 || convertTo == EbtUint16) && ! convertFromIntTypes) ||
            ((node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16) && ! convertToIntTypes))
            return nullptr;
    }

    if (! getArithemeticFloat16Enabled()) {
        if ((convertTo == EbtFloat16 && ! convertFromFloatTypes) ||
            (node->getBasicType() == EbtFloat16 && ! convertToFloatTypes))
            return nullptr;
    }

    switch (convertTo) {
#ifndef GLSLANG_WEB
    case EbtDouble:
        switch (node->getBasicType()) {
        case EbtUint:    newOp = EOpConvUintToDouble;    break;
        case EbtBool:    newOp = EOpConvBoolToDouble;    break;
        case EbtFloat:   newOp = EOpConvFloatToDouble;   break;
        case EbtInt:     newOp = EOpConvIntToDouble;     break;
        case EbtInt8:    newOp = EOpConvInt8ToDouble;    break;
        case EbtUint8:   newOp = EOpConvUint8ToDouble;   break;
        case EbtInt16:   newOp = EOpConvInt16ToDouble;   break;
        case EbtUint16:  newOp = EOpConvUint16ToDouble;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToDouble; break;
        case EbtInt64:   newOp = EOpConvInt64ToDouble;   break;
        case EbtUint64:  newOp = EOpConvUint64ToDouble;  break;
        default:
            return nullptr;
        }
        break;
#endif
    case EbtFloat:
        switch (node->getBasicType()) {
        case EbtInt:     newOp = EOpConvIntToFloat;     break;
        case EbtUint:    newOp = EOpConvUintToFloat;    break;
        case EbtBool:    newOp = EOpConvBoolToFloat;    break;
#ifndef GLSLANG_WEB
        case EbtDouble:  newOp = EOpConvDoubleToFloat;  break;
        case EbtInt8:    newOp = EOpConvInt8ToFloat;    break;
        case EbtUint8:   newOp = EOpConvUint8ToFloat;   break;
        case EbtInt16:   newOp = EOpConvInt16ToFloat;   break;
        case EbtUint16:  newOp = EOpConvUint16ToFloat;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToFloat; break;
        case EbtInt64:   newOp = EOpConvInt64ToFloat;   break;
        case EbtUint64:  newOp = EOpConvUint64ToFloat;  break;
#endif
        default:
            return nullptr;
        }
        break;
#ifndef GLSLANG_WEB
    case EbtFloat16:
        switch (node->getBasicType()) {
        case EbtInt8:   newOp = EOpConvInt8ToFloat16;   break;
        case EbtUint8:  newOp = EOpConvUint8ToFloat16;  break;
        case EbtInt16:  newOp = EOpConvInt16ToFloat16;  break;
        case EbtUint16: newOp = EOpConvUint16ToFloat16; break;
        case EbtInt:    newOp = EOpConvIntToFloat16;    break;
        case EbtUint:   newOp = EOpConvUintToFloat16;   break;
        case EbtBool:   newOp = EOpConvBoolToFloat16;   break;
        case EbtFloat:  newOp = EOpConvFloatToFloat16;  break;
        case EbtDouble: newOp = EOpConvDoubleToFloat16; break;
        case EbtInt64:  newOp = EOpConvInt64ToFloat16;  break;
        case EbtUint64: newOp = EOpConvUint64ToFloat16; break;
        default:
            return nullptr;
        }
        break;
#endif
    case EbtBool:
        switch (node->getBasicType()) {
        case EbtInt:     newOp = EOpConvIntToBool;     break;
        case EbtUint:    newOp = EOpConvUintToBool;    break;
        case EbtFloat:   newOp = EOpConvFloatToBool;   break;
#ifndef GLSLANG_WEB
        case EbtDouble:  newOp = EOpConvDoubleToBool;  break;
        case EbtInt8:    newOp = EOpConvInt8ToBool;    break;
        case EbtUint8:   newOp = EOpConvUint8ToBool;   break;
        case EbtInt16:   newOp = EOpConvInt16ToBool;   break;
        case EbtUint16:  newOp = EOpConvUint16ToBool;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToBool; break;
        case EbtInt64:   newOp = EOpConvInt64ToBool;   break;
        case EbtUint64:  newOp = EOpConvUint64ToBool;  break;
#endif
        default:
            return nullptr;
        }
        break;
#ifndef GLSLANG_WEB
    case EbtInt8:
        switch (node->getBasicType()) {
        case EbtUint8:   newOp = EOpConvUint8ToInt8;   break;
        case EbtInt16:   newOp = EOpConvInt16ToInt8;   break;
        case EbtUint16:  newOp = EOpConvUint16ToInt8;  break;
        case EbtInt:     newOp = EOpConvIntToInt8;     break;
        case EbtUint:    newOp = EOpConvUintToInt8;    break;
        case EbtInt64:   newOp = EOpConvInt64ToInt8;   break;
        case EbtUint64:  newOp = EOpConvUint64ToInt8;  break;
        case EbtBool:    newOp = EOpConvBoolToInt8;    break;
        case EbtFloat:   newOp = EOpConvFloatToInt8;   break;
        case EbtDouble:  newOp = EOpConvDoubleToInt8;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToInt8; break;
        default:
            return nullptr;
        }
        break;
    case EbtUint8:
        switch (node->getBasicType()) {
        case EbtInt8:    newOp = EOpConvInt8ToUint8;    break;
        case EbtInt16:   newOp = EOpConvInt16ToUint8;   break;
        case EbtUint16:  newOp = EOpConvUint16ToUint8;  break;
        case EbtInt:     newOp = EOpConvIntToUint8;     break;
        case EbtUint:    newOp = EOpConvUintToUint8;    break;
        case EbtInt64:   newOp = EOpConvInt64ToUint8;   break;
        case EbtUint64:  newOp = EOpConvUint64ToUint8;  break;
        case EbtBool:    newOp = EOpConvBoolToUint8;    break;
        case EbtFloat:   newOp = EOpConvFloatToUint8;   break;
        case EbtDouble:  newOp = EOpConvDoubleToUint8;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToUint8; break;
        default:
            return nullptr;
        }
        break;

    case EbtInt16:
        switch (node->getBasicType()) {
        case EbtUint8:   newOp = EOpConvUint8ToInt16;   break;
        case EbtInt8:    newOp = EOpConvInt8ToInt16;    break;
        case EbtUint16:  newOp = EOpConvUint16ToInt16;  break;
        case EbtInt:     newOp = EOpConvIntToInt16;     break;
        case EbtUint:    newOp = EOpConvUintToInt16;    break;
        case EbtInt64:   newOp = EOpConvInt64ToInt16;   break;
        case EbtUint64:  newOp = EOpConvUint64ToInt16;  break;
        case EbtBool:    newOp = EOpConvBoolToInt16;    break;
        case EbtFloat:   newOp = EOpConvFloatToInt16;   break;
        case EbtDouble:  newOp = EOpConvDoubleToInt16;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToInt16; break;
        default:
            return nullptr;
        }
        break;
    case EbtUint16:
        switch (node->getBasicType()) {
        case EbtInt8:    newOp = EOpConvInt8ToUint16;    break;
        case EbtUint8:   newOp = EOpConvUint8ToUint16;   break;
        case EbtInt16:   newOp = EOpConvInt16ToUint16;   break;
        case EbtInt:     newOp = EOpConvIntToUint16;     break;
        case EbtUint:    newOp = EOpConvUintToUint16;    break;
        case EbtInt64:   newOp = EOpConvInt64ToUint16;   break;
        case EbtUint64:  newOp = EOpConvUint64ToUint16;  break;
        case EbtBool:    newOp = EOpConvBoolToUint16;    break;
        case EbtFloat:   newOp = EOpConvFloatToUint16;   break;
        case EbtDouble:  newOp = EOpConvDoubleToUint16;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToUint16; break;
        default:
            return nullptr;
        }
        break;
#endif

    case EbtInt:
        switch (node->getBasicType()) {
        case EbtUint:    newOp = EOpConvUintToInt;    break;
        case EbtBool:    newOp = EOpConvBoolToInt;    break;
        case EbtFloat:   newOp = EOpConvFloatToInt;   break;
#ifndef GLSLANG_WEB
        case EbtInt8:    newOp = EOpConvInt8ToInt;    break;
        case EbtUint8:   newOp = EOpConvUint8ToInt;   break;
        case EbtInt16:   newOp = EOpConvInt16ToInt;   break;
        case EbtUint16:  newOp = EOpConvUint16ToInt;  break;
        case EbtDouble:  newOp = EOpConvDoubleToInt;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToInt; break;
        case EbtInt64:   newOp = EOpConvInt64ToInt;   break;
        case EbtUint64:  newOp = EOpConvUint64ToInt;  break;
#endif
        default:
            return nullptr;
        }
        break;
    case EbtUint:
        switch (node->getBasicType()) {
        case EbtInt:     newOp = EOpConvIntToUint;     break;
        case EbtBool:    newOp = EOpConvBoolToUint;    break;
        case EbtFloat:   newOp = EOpConvFloatToUint;   break;
#ifndef GLSLANG_WEB
        case EbtInt8:    newOp = EOpConvInt8ToUint;    break;
        case EbtUint8:   newOp = EOpConvUint8ToUint;   break;
        case EbtInt16:   newOp = EOpConvInt16ToUint;   break;
        case EbtUint16:  newOp = EOpConvUint16ToUint;  break;
        case EbtDouble:  newOp = EOpConvDoubleToUint;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToUint; break;
        case EbtInt64:   newOp = EOpConvInt64ToUint;   break;
        case EbtUint64:  newOp = EOpConvUint64ToUint;  break;
#endif
        default:
            return nullptr;
        }
        break;
#ifndef GLSLANG_WEB
    case EbtInt64:
        switch (node->getBasicType()) {
        case EbtInt8:    newOp = EOpConvInt8ToInt64;    break;
        case EbtUint8:   newOp = EOpConvUint8ToInt64;   break;
        case EbtInt16:   newOp = EOpConvInt16ToInt64;   break;
        case EbtUint16:  newOp = EOpConvUint16ToInt64;  break;
        case EbtInt:     newOp = EOpConvIntToInt64;     break;
        case EbtUint:    newOp = EOpConvUintToInt64;    break;
        case EbtBool:    newOp = EOpConvBoolToInt64;    break;
        case EbtFloat:   newOp = EOpConvFloatToInt64;   break;
        case EbtDouble:  newOp = EOpConvDoubleToInt64;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToInt64; break;
        case EbtUint64:  newOp = EOpConvUint64ToInt64;  break;
        default:
            return nullptr;
        }
        break;
    case EbtUint64:
        switch (node->getBasicType()) {
        case EbtInt8:    newOp = EOpConvInt8ToUint64;    break;
        case EbtUint8:   newOp = EOpConvUint8ToUint64;   break;
        case EbtInt16:   newOp = EOpConvInt16ToUint64;   break;
        case EbtUint16:  newOp = EOpConvUint16ToUint64;  break;
        case EbtInt:     newOp = EOpConvIntToUint64;     break;
        case EbtUint:    newOp = EOpConvUintToUint64;    break;
        case EbtBool:    newOp = EOpConvBoolToUint64;    break;
        case EbtFloat:   newOp = EOpConvFloatToUint64;   break;
        case EbtDouble:  newOp = EOpConvDoubleToUint64;  break;
        case EbtFloat16: newOp = EOpConvFloat16ToUint64; break;
        case EbtInt64:   newOp = EOpConvInt64ToUint64;   break;
        default:
            return nullptr;
        }
        break;
#endif
    default:
        return nullptr;
    }

    TType newType(convertTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
    newNode = addUnaryNode(newOp, node, node->getLoc(), newType);

    if (node->getAsConstantUnion()) {
        // 8/16-bit storage extensions don't support 8/16-bit constants, so don't fold conversions
        // to those types
        if ((getArithemeticInt8Enabled() || !(convertTo == EbtInt8 || convertTo == EbtUint8)) &&
            (getArithemeticInt16Enabled() || !(convertTo == EbtInt16 || convertTo == EbtUint16)) &&
            (getArithemeticFloat16Enabled() || !(convertTo == EbtFloat16))) {
            TIntermTyped* folded = node->getAsConstantUnion()->fold(newOp, newType);
            if (folded)
                return folded;
        }
    }

    // Propagate specialization-constant-ness, if allowed
    if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode))
        newNode->getWritableType().getQualifier().makeSpecConstant();

    return newNode;
}

TIntermTyped* TIntermediate::addConversion(TBasicType convertTo, TIntermTyped* node) const
{
    return createConversion(convertTo, node);
}

// For converting a pair of operands to a binary operation to compatible
// types with each other, relative to the operation in 'op'.
// This does not cover assignment operations, which is asymmetric in that the
// left type is not changeable.
// See addConversion(op, type, node) for assignments and unary operation
// conversions.
//
// Generally, this is focused on basic type conversion, not shape conversion.
// See addShapeConversion() for shape conversions.
//
// Returns the converted pair of nodes.
// Returns <nullptr, nullptr> when there is no conversion.
std::tuple<TIntermTyped*, TIntermTyped*>
TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1)
{
    if (!isConversionAllowed(op, node0) || !isConversionAllowed(op, node1))
        return std::make_tuple(nullptr, nullptr);

    if (node0->getType() != node1->getType()) {
        // If differing structure, then no conversions.
        if (node0->isStruct() || node1->isStruct())
            return std::make_tuple(nullptr, nullptr);

        // If differing arrays, then no conversions.
        if (node0->getType().isArray() || node1->getType().isArray())
            return std::make_tuple(nullptr, nullptr);

        // No implicit conversions for operations involving cooperative matrices
        if (node0->getType().isCoopMat() || node1->getType().isCoopMat())
            return std::make_tuple(node0, node1);
    }

    auto promoteTo = std::make_tuple(EbtNumTypes, EbtNumTypes);

    switch (op) {
    //
    // List all the binary ops that can implicitly convert one operand to the other's type;
    // This implements the 'policy' for implicit type conversion.
    //
    case EOpLessThan:
    case EOpGreaterThan:
    case EOpLessThanEqual:
    case EOpGreaterThanEqual:
    case EOpEqual:
    case EOpNotEqual:

    case EOpAdd:
    case EOpSub:
    case EOpMul:
    case EOpDiv:
    case EOpMod:

    case EOpVectorTimesScalar:
    case EOpVectorTimesMatrix:
    case EOpMatrixTimesVector:
    case EOpMatrixTimesScalar:

    case EOpAnd:
    case EOpInclusiveOr:
    case EOpExclusiveOr:

    case EOpSequence:          // used by ?:

        if (node0->getBasicType() == node1->getBasicType())
            return std::make_tuple(node0, node1);

        promoteTo = getConversionDestinatonType(node0->getBasicType(), node1->getBasicType(), op);
        if (std::get<0>(promoteTo) == EbtNumTypes || std::get<1>(promoteTo) == EbtNumTypes)
            return std::make_tuple(nullptr, nullptr);

        break;

    case EOpLogicalAnd:
    case EOpLogicalOr:
    case EOpLogicalXor:
        if (getSource() == EShSourceHlsl)
            promoteTo = std::make_tuple(EbtBool, EbtBool);
        else
            return std::make_tuple(node0, node1);
        break;

    // There are no conversions needed for GLSL; the shift amount just needs to be an
    // integer type, as does the base.
    // HLSL can promote bools to ints to make this work.
    case EOpLeftShift:
    case EOpRightShift:
        if (getSource() == EShSourceHlsl) {
            TBasicType node0BasicType = node0->getBasicType();
            if (node0BasicType == EbtBool)
                node0BasicType = EbtInt;
            if (node1->getBasicType() == EbtBool)
                promoteTo = std::make_tuple(node0BasicType, EbtInt);
            else
                promoteTo = std::make_tuple(node0BasicType, node1->getBasicType());
        } else {
            if (isTypeInt(node0->getBasicType()) && isTypeInt(node1->getBasicType()))
                return std::make_tuple(node0, node1);
            else
                return std::make_tuple(nullptr, nullptr);
        }
        break;

    default:
        if (node0->getType() == node1->getType())
            return std::make_tuple(node0, node1);

        return std::make_tuple(nullptr, nullptr);
    }

    TIntermTyped* newNode0;
    TIntermTyped* newNode1;

    if (std::get<0>(promoteTo) != node0->getType().getBasicType()) {
        if (node0->getAsConstantUnion())
            newNode0 = promoteConstantUnion(std::get<0>(promoteTo), node0->getAsConstantUnion());
        else
            newNode0 = createConversion(std::get<0>(promoteTo), node0);
    } else
        newNode0 = node0;

    if (std::get<1>(promoteTo) != node1->getType().getBasicType()) {
        if (node1->getAsConstantUnion())
            newNode1 = promoteConstantUnion(std::get<1>(promoteTo), node1->getAsConstantUnion());
        else
            newNode1 = createConversion(std::get<1>(promoteTo), node1);
    } else
        newNode1 = node1;

    return std::make_tuple(newNode0, newNode1);
}

//
// Convert the node's type to the given type, as allowed by the operation involved: 'op'.
// For implicit conversions, 'op' is not the requested conversion, it is the explicit
// operation requiring the implicit conversion.
//
// Binary operation conversions should be handled by addConversion(op, node, node), not here.
//
// Returns a node representing the conversion, which could be the same
// node passed in if no conversion was needed.
//
// Generally, this is focused on basic type conversion, not shape conversion.
// See addShapeConversion() for shape conversions.
//
// Return nullptr if a conversion can't be done.
//
TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node)
{
    if (!isConversionAllowed(op, node))
        return nullptr;

    // Otherwise, if types are identical, no problem
    if (type == node->getType())
        return node;

    // If one's a structure, then no conversions.
    if (type.isStruct() || node->isStruct())
        return nullptr;

    // If one's an array, then no conversions.
    if (type.isArray() || node->getType().isArray())
        return nullptr;

    // Note: callers are responsible for other aspects of shape,
    // like vector and matrix sizes.

    TBasicType promoteTo;
    // GL_EXT_shader_16bit_storage can't do OpConstantComposite with
    // 16-bit types, so disable promotion for those types.
    bool canPromoteConstant = true;

    switch (op) {
    //
    // Explicit conversions (unary operations)
    //
    case EOpConstructBool:
        promoteTo = EbtBool;
        break;
    case EOpConstructFloat:
        promoteTo = EbtFloat;
        break;
    case EOpConstructInt:
        promoteTo = EbtInt;
        break;
    case EOpConstructUint:
        promoteTo = EbtUint;
        break;
#ifndef GLSLANG_WEB
    case EOpConstructDouble:
        promoteTo = EbtDouble;
        break;
    case EOpConstructFloat16:
        promoteTo = EbtFloat16;
        canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
                             extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16);
        break;
    case EOpConstructInt8:
        promoteTo = EbtInt8;
        canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
                             extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8);
        break;
    case EOpConstructUint8:
        promoteTo = EbtUint8;
        canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
                             extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8);
        break;
    case EOpConstructInt16:
        promoteTo = EbtInt16;
        canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
                             extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16);
        break;
    case EOpConstructUint16:
        promoteTo = EbtUint16;
        canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
                             extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16);
        break;
    case EOpConstructInt64:
        promoteTo = EbtInt64;
        break;
    case EOpConstructUint64:
        promoteTo = EbtUint64;
        break;
#endif

    case EOpLogicalNot:

    case EOpFunctionCall:

    case EOpReturn:
    case EOpAssign:
    case EOpAddAssign:
    case EOpSubAssign:
    case EOpMulAssign:
    case EOpVectorTimesScalarAssign:
    case EOpMatrixTimesScalarAssign:
    case EOpDivAssign:
    case EOpModAssign:
    case EOpAndAssign:
    case EOpInclusiveOrAssign:
    case EOpExclusiveOrAssign:

    case EOpAtan:
    case EOpClamp:
    case EOpCross:
    case EOpDistance:
    case EOpDot:
    case EOpDst:
    case EOpFaceForward:
    case EOpFma:
    case EOpFrexp:
    case EOpLdexp:
    case EOpMix:
    case EOpLit:
    case EOpMax:
    case EOpMin:
    case EOpModf:
    case EOpPow:
    case EOpReflect:
    case EOpRefract:
    case EOpSmoothStep:
    case EOpStep:

    case EOpSequence:
    case EOpConstructStruct:
    case EOpConstructCooperativeMatrix:

        if (type.isReference() || node->getType().isReference()) {
            // types must match to assign a reference
            if (type == node->getType())
                return node;
            else
                return nullptr;
        }

        if (type.getBasicType() == node->getType().getBasicType())
            return node;

        if (canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op))
            promoteTo = type.getBasicType();
        else
            return nullptr;
        break;

    // For GLSL, there are no conversions needed; the shift amount just needs to be an
    // integer type, as do the base/result.
    // HLSL can convert the shift from a bool to an int.
    case EOpLeftShiftAssign:
    case EOpRightShiftAssign:
    {
        if (getSource() == EShSourceHlsl && node->getType().getBasicType() == EbtBool)
            promoteTo = type.getBasicType();
        else {
            if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType()))
                return node;
            else
                return nullptr;
        }
        break;
    }

    default:
        // default is to require a match; all exceptions should have case statements above

        if (type.getBasicType() == node->getType().getBasicType())
            return node;
        else
            return nullptr;
    }

    if (canPromoteConstant && node->getAsConstantUnion())
        return promoteConstantUnion(promoteTo, node->getAsConstantUnion());

    //
    // Add a new newNode for the conversion.
    //
    TIntermTyped* newNode = createConversion(promoteTo, node);

    return newNode;
}

// Convert the node's shape of type for the given type, as allowed by the
// operation involved: 'op'.  This is for situations where there is only one
// direction to consider doing the shape conversion.
//
// This implements policy, it call addShapeConversion() for the mechanism.
//
// Generally, the AST represents allowed GLSL shapes, so this isn't needed
// for GLSL.  Bad shapes are caught in conversion or promotion.
//
// Return 'node' if no conversion was done. Promotion handles final shape
// checking.
//
TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node)
{
    // some source languages don't do this
    switch (getSource()) {
    case EShSourceHlsl:
        break;
    case EShSourceGlsl:
    default:
        return node;
    }

    // some operations don't do this
    switch (op) {
    case EOpFunctionCall:
    case EOpReturn:
        break;

    case EOpMulAssign:
        // want to support vector *= scalar native ops in AST and lower, not smear, similarly for
        // matrix *= scalar, etc.

    case EOpAddAssign:
    case EOpSubAssign:
    case EOpDivAssign:
    case EOpAndAssign:
    case EOpInclusiveOrAssign:
    case EOpExclusiveOrAssign:
    case EOpRightShiftAssign:
    case EOpLeftShiftAssign:
        if (node->getVectorSize() == 1)
            return node;
        break;

    case EOpAssign:
        break;

    case EOpMix:
        break;

    default:
        return node;
    }

    return addShapeConversion(type, node);
}

// Convert the nodes' shapes to be compatible for the operation 'op'.
//
// This implements policy, it call addShapeConversion() for the mechanism.
//
// Generally, the AST represents allowed GLSL shapes, so this isn't needed
// for GLSL.  Bad shapes are caught in conversion or promotion.
//
void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode)
{
    // some source languages don't do this
    switch (getSource()) {
    case EShSourceHlsl:
        break;
    case EShSourceGlsl:
    default:
        return;
    }

    // some operations don't do this
    // 'break' will mean attempt bidirectional conversion
    switch (op) {
    case EOpMulAssign:
    case EOpAssign:
    case EOpAddAssign:
    case EOpSubAssign:
    case EOpDivAssign:
    case EOpAndAssign:
    case EOpInclusiveOrAssign:
    case EOpExclusiveOrAssign:
    case EOpRightShiftAssign:
    case EOpLeftShiftAssign:
        // switch to unidirectional conversion (the lhs can't change)
        rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode);
        return;

    case EOpMul:
        // matrix multiply does not change shapes
        if (lhsNode->isMatrix() && rhsNode->isMatrix())
            return;
    case EOpAdd:
    case EOpSub:
    case EOpDiv:
        // want to support vector * scalar native ops in AST and lower, not smear, similarly for
        // matrix * vector, etc.
        if (lhsNode->getVectorSize() == 1 || rhsNode->getVectorSize() == 1)
            return;
        break;

    case EOpRightShift:
    case EOpLeftShift:
        // can natively support the right operand being a scalar and the left a vector,
        // but not the reverse
        if (rhsNode->getVectorSize() == 1)
            return;
        break;

    case EOpLessThan:
    case EOpGreaterThan:
    case EOpLessThanEqual:
    case EOpGreaterThanEqual:

    case EOpEqual:
    case EOpNotEqual:

    case EOpLogicalAnd:
    case EOpLogicalOr:
    case EOpLogicalXor:

    case EOpAnd:
    case EOpInclusiveOr:
    case EOpExclusiveOr:

    case EOpMix:
        break;

    default:
        return;
    }

    // Do bidirectional conversions
    if (lhsNode->getType().isScalarOrVec1() || rhsNode->getType().isScalarOrVec1()) {
        if (lhsNode->getType().isScalarOrVec1())
            lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
        else
            rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
    }
    lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
    rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
}

// Convert the node's shape of type for the given type, as allowed by the
// operation involved: 'op'.
//
// Generally, the AST represents allowed GLSL shapes, so this isn't needed
// for GLSL.  Bad shapes are caught in conversion or promotion.
//
// Return 'node' if no conversion was done. Promotion handles final shape
// checking.
//
TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* node)
{
    // no conversion needed
    if (node->getType() == type)
        return node;

    // structures and arrays don't change shape, either to or from
    if (node->getType().isStruct() || node->getType().isArray() ||
        type.isStruct() || type.isArray())
        return node;

    // The new node that handles the conversion
    TOperator constructorOp = mapTypeToConstructorOp(type);

    if (getSource() == EShSourceHlsl) {
        // HLSL rules for scalar, vector and matrix conversions:
        // 1) scalar can become anything, initializing every component with its value
        // 2) vector and matrix can become scalar, first element is used (warning: truncation)
        // 3) matrix can become matrix with less rows and/or columns (warning: truncation)
        // 4) vector can become vector with less rows size (warning: truncation)
        // 5a) vector 4 can become 2x2 matrix (special case) (same packing layout, its a reinterpret)
        // 5b) 2x2 matrix can become vector 4 (special case) (same packing layout, its a reinterpret)

        const TType &sourceType = node->getType();

        // rule 1 for scalar to matrix is special
        if (sourceType.isScalarOrVec1() && type.isMatrix()) {

            // HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix.  Left to its
            // own devices, the constructor from a scalar would populate the diagonal.  This forces replication
            // to every matrix element.

            // Note that if the node is complex (e.g, a function call), we don't want to duplicate it here
            // repeatedly, so we copy it to a temp, then use the temp.
            const int matSize = type.computeNumComponents();
            TIntermAggregate* rhsAggregate = new TIntermAggregate();

            const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr);

            if (!isSimple) {
                assert(0); // TODO: use node replicator service when available.
            }

            for (int x = 0; x < matSize; ++x)
                rhsAggregate->getSequence().push_back(node);

            return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc());
        }

        // rule 1 and 2
        if ((sourceType.isScalar() && !type.isScalar()) || (!sourceType.isScalar() && type.isScalar()))
            return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());

        // rule 3 and 5b
        if (sourceType.isMatrix()) {
            // rule 3
            if (type.isMatrix()) {
                if ((sourceType.getMatrixCols() != type.getMatrixCols() || sourceType.getMatrixRows() != type.getMatrixRows()) &&
                    sourceType.getMatrixCols() >= type.getMatrixCols() && sourceType.getMatrixRows() >= type.getMatrixRows())
                    return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
            // rule 5b
            } else if (type.isVector()) {
                if (type.getVectorSize() == 4 && sourceType.getMatrixCols() == 2 && sourceType.getMatrixRows() == 2)
                    return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
            }
        }

        // rule 4 and 5a
        if (sourceType.isVector()) {
            // rule 4
            if (type.isVector())
            {
                if (sourceType.getVectorSize() > type.getVectorSize())
                    return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
            // rule 5a
            } else if (type.isMatrix()) {
                if (sourceType.getVectorSize() == 4 && type.getMatrixCols() == 2 && type.getMatrixRows() == 2)
                    return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
            }
        }
    }

    // scalar -> vector or vec1 -> vector or
    // vector -> scalar or
    // bigger vector -> smaller vector
    if ((node->getType().isScalarOrVec1() && type.isVector()) ||
        (node->getType().isVector() && type.isScalar()) ||
        (node->isVector() && type.isVector() && node->getVectorSize() > type.getVectorSize()))
        return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());

    return node;
}

bool TIntermediate::isIntegralPromotion(TBasicType from, TBasicType to) const
{
    // integral promotions
    if (to == EbtInt) {
        switch(from) {
        case EbtInt8:
        case EbtInt16:
        case EbtUint8:
        case EbtUint16:
            return true;
        default:
            break;
        }
    }
    return false;
}

bool TIntermediate::isFPPromotion(TBasicType from, TBasicType to) const
{
    // floating-point promotions
    if (to == EbtDouble) {
        switch(from) {
        case EbtFloat16:
        case EbtFloat:
            return true;
        default:
            break;
        }
    }
    return false;
}

bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const
{
#ifdef GLSLANG_WEB
    return false;
#endif

    switch (from) {
    case EbtInt:
        switch(to) {
        case EbtUint:
            return version >= 400 || getSource() == EShSourceHlsl;
        case EbtInt64:
        case EbtUint64:
            return true;
        default:
            break;
        }
        break;
    case EbtUint:
        switch(to) {
        case EbtInt64:
        case EbtUint64:
            return true;
        default:
            break;
        }
        break;
    case EbtInt8:
        switch (to) {
        case EbtUint8:
        case EbtInt16:
        case EbtUint16:
        case EbtUint:
        case EbtInt64:
        case EbtUint64:
            return true;
        default:
            break;
        }
        break;
    case EbtUint8:
        switch (to) {
        case EbtInt16:
        case EbtUint16:
        case EbtUint:
        case EbtInt64:
        case EbtUint64:
            return true;
        default:
            break;
        }
        break;
    case EbtInt16:
        switch(to) {
        case EbtUint16:
        case EbtUint:
        case EbtInt64:
        case EbtUint64:
            return true;
        default:
            break;
        }
        break;
    case EbtUint16:
        switch(to) {
        case EbtUint:
        case EbtInt64:
        case EbtUint64:
            return true;
        default:
            break;
        }
        break;
    case EbtInt64:
        if (to == EbtUint64) {
            return true;
        }
        break;
    default:
        break;
    }
    return false;
}

bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const
{
#ifdef GLSLANG_WEB
    return false;
#endif

    if (to == EbtFloat && from == EbtFloat16) {
        return true;
    } else {
        return false;
    }
}

bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const
{
    switch (from) {
    case EbtInt:
    case EbtUint:
        switch(to) {
        case EbtFloat:
        case EbtDouble:
            return true;
        default:
            break;
        }
        break;
#ifndef GLSLANG_WEB
    case EbtInt8:
    case EbtUint8:
    case EbtInt16:
    case EbtUint16:
        switch (to) {
        case EbtFloat16:
        case EbtFloat:
        case EbtDouble:
            return true;
        default:
            break;
        }
        break;
    case EbtInt64:
    case EbtUint64:
        if (to == EbtDouble) {
            return true;
        }
        break;
#endif
    default:
        break;
    }
    return false;
}

//
// See if the 'from' type is allowed to be implicitly converted to the
// 'to' type.  This is not about vector/array/struct, only about basic type.
//
bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const
{
    if (isEsProfile() || version == 110)
        return false;

    if (from == to)
        return true;

    // TODO: Move more policies into language-specific handlers.
    // Some languages allow more general (or potentially, more specific) conversions under some conditions.
    if (getSource() == EShSourceHlsl) {
        const bool fromConvertable = (from == EbtFloat || from == EbtDouble || from == EbtInt || from == EbtUint || from == EbtBool);
        const bool toConvertable = (to == EbtFloat || to == EbtDouble || to == EbtInt || to == EbtUint || to == EbtBool);

        if (fromConvertable && toConvertable) {
            switch (op) {
            case EOpAndAssign:               // assignments can perform arbitrary conversions
            case EOpInclusiveOrAssign:       // ...
            case EOpExclusiveOrAssign:       // ...
            case EOpAssign:                  // ...
            case EOpAddAssign:               // ...
            case EOpSubAssign:               // ...
            case EOpMulAssign:               // ...
            case EOpVectorTimesScalarAssign: // ...
            case EOpMatrixTimesScalarAssign: // ...
            case EOpDivAssign:               // ...
            case EOpModAssign:               // ...
            case EOpReturn:                  // function returns can also perform arbitrary conversions
            case EOpFunctionCall:            // conversion of a calling parameter
            case EOpLogicalNot:
            case EOpLogicalAnd:
            case EOpLogicalOr:
            case EOpLogicalXor:
            case EOpConstructStruct:
                return true;
            default:
                break;
            }
        }
    }

    bool explicitTypesEnabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
                                extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8) ||
                                extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16) ||
                                extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int32) ||
                                extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int64) ||
                                extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16) ||
                                extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float32) ||
                                extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float64);

    if (explicitTypesEnabled) {
        // integral promotions
        if (isIntegralPromotion(from, to)) {
            return true;
        }

        // floating-point promotions
        if (isFPPromotion(from, to)) {
            return true;
        }

        // integral conversions
        if (isIntegralConversion(from, to)) {
            return true;
        }

        // floating-point conversions
        if (isFPConversion(from, to)) {
           return true;
        }

        // floating-integral conversions
        if (isFPIntegralConversion(from, to)) {
           return true;
        }

        // hlsl supported conversions
        if (getSource() == EShSourceHlsl) {
            if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat))
                return true;
        }
    } else {
        switch (to) {
        case EbtDouble:
            switch (from) {
            case EbtInt:
            case EbtUint:
            case EbtInt64:
            case EbtUint64:
            case EbtFloat:
            case EbtDouble:
                return true;
            case EbtInt16:
            case EbtUint16:
                return extensionRequested(E_GL_AMD_gpu_shader_int16);
            case EbtFloat16:
                return extensionRequested(E_GL_AMD_gpu_shader_half_float);
            default:
                return false;
           }
        case EbtFloat:
            switch (from) {
            case EbtInt:
            case EbtUint:
            case EbtFloat:
                 return true;
            case EbtBool:
                 return getSource() == EShSourceHlsl;
            case EbtInt16:
            case EbtUint16:
                return extensionRequested(E_GL_AMD_gpu_shader_int16);
            case EbtFloat16:
                return 
                    extensionRequested(E_GL_AMD_gpu_shader_half_float) ||
                    getSource() == EShSourceHlsl;
            default:
                 return false;
            }
        case EbtUint:
            switch (from) {
            case EbtInt:
                 return version >= 400 || getSource() == EShSourceHlsl;
            case EbtUint:
                return true;
            case EbtBool:
                return getSource() == EShSourceHlsl;
            case EbtInt16:
            case EbtUint16:
                return extensionRequested(E_GL_AMD_gpu_shader_int16);
            default:
                return false;
            }
        case EbtInt:
            switch (from) {
            case EbtInt:
                return true;
            case EbtBool:
                return getSource() == EShSourceHlsl;
            case EbtInt16:
                return extensionRequested(E_GL_AMD_gpu_shader_int16);
            default:
                return false;
            }
        case EbtUint64:
            switch (from) {
            case EbtInt:
            case EbtUint:
            case EbtInt64:
            case EbtUint64:
                return true;
            case EbtInt16:
            case EbtUint16:
                return extensionRequested(E_GL_AMD_gpu_shader_int16);
            default:
                return false;
            }
        case EbtInt64:
            switch (from) {
            case EbtInt:
            case EbtInt64:
                return true;
            case EbtInt16:
                return extensionRequested(E_GL_AMD_gpu_shader_int16);
            default:
                return false;
            }
        case EbtFloat16:
            switch (from) {
            case EbtInt16:
            case EbtUint16:
                return extensionRequested(E_GL_AMD_gpu_shader_int16);
            case EbtFloat16:
                return extensionRequested(E_GL_AMD_gpu_shader_half_float);
            default:
                break;
            }
            return false;
        case EbtUint16:
            switch (from) {
            case EbtInt16:
            case EbtUint16:
                return extensionRequested(E_GL_AMD_gpu_shader_int16);
            default:
                break;
            }
            return false;
        default:
            return false;
        }
    }

    return false;
}

static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBasicType uintType)
{
#ifdef GLSLANG_WEB
    return false;
#endif

    switch(sintType) {
    case EbtInt8:
        switch(uintType) {
        case EbtUint8:
        case EbtUint16:
        case EbtUint:
        case EbtUint64:
            return false;
        default:
            assert(false);
            return false;
        }
        break;
    case EbtInt16:
        switch(uintType) {
        case EbtUint8:
            return true;
        case EbtUint16:
        case EbtUint:
        case EbtUint64:
            return false;
        default:
            assert(false);
            return false;
        }
        break;
    case EbtInt:
        switch(uintType) {
        case EbtUint8:
        case EbtUint16:
            return true;
        case EbtUint:
            return false;
        default:
            assert(false);
            return false;
        }
        break;
    case EbtInt64:
        switch(uintType) {
        case EbtUint8:
        case EbtUint16:
        case EbtUint:
            return true;
        case EbtUint64:
            return false;
        default:
            assert(false);
            return false;
        }
        break;
    default:
        assert(false);
        return false;
    }
}


static TBasicType getCorrespondingUnsignedType(TBasicType type)
{
#ifdef GLSLANG_WEB
    assert(type == EbtInt);
    return EbtUint;
#endif

    switch(type) {
    case EbtInt8:
        return EbtUint8;
    case EbtInt16:
        return EbtUint16;
    case EbtInt:
        return EbtUint;
    case EbtInt64:
        return EbtUint64;
    default:
        assert(false);
        return EbtNumTypes;
    }
}

// Implements the following rules
//    - If either operand has type float64_t or derived from float64_t,
//      the other shall be converted to float64_t or derived type.
//    - Otherwise, if either operand has type float32_t or derived from
//      float32_t, the other shall be converted to float32_t or derived type.
//    - Otherwise, if either operand has type float16_t or derived from
//      float16_t, the other shall be converted to float16_t or derived type.
//    - Otherwise, if both operands have integer types the following rules
//      shall be applied to the operands:
//      - If both operands have the same type, no further conversion
//        is needed.
//      - Otherwise, if both operands have signed integer types or both
//        have unsigned integer types, the operand with the type of lesser
//        integer conversion rank shall be converted to the type of the
//        operand with greater rank.
//      - Otherwise, if the operand that has unsigned integer type has rank
//        greater than or equal to the rank of the type of the other
//        operand, the operand with signed integer type shall be converted
//        to the type of the operand with unsigned integer type.
//      - Otherwise, if the type of the operand with signed integer type can
//        represent all of the values of the type of the operand with
//        unsigned integer type, the operand with unsigned integer type
//        shall be converted to the type of the operand with signed
//        integer type.
//      - Otherwise, both operands shall be converted to the unsigned
//        integer type corresponding to the type of the operand with signed
//        integer type.

std::tuple<TBasicType, TBasicType> TIntermediate::getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const
{
    TBasicType res0 = EbtNumTypes;
    TBasicType res1 = EbtNumTypes;

    if (isEsProfile() || version == 110)
        return std::make_tuple(res0, res1);

    if (getSource() == EShSourceHlsl) {
        if (canImplicitlyPromote(type1, type0, op)) {
            res0 = type0;
            res1 = type0;
        } else if (canImplicitlyPromote(type0, type1, op)) {
            res0 = type1;
            res1 = type1;
        }
        return std::make_tuple(res0, res1);
    }

    if ((type0 == EbtDouble && canImplicitlyPromote(type1, EbtDouble, op)) ||
        (type1 == EbtDouble && canImplicitlyPromote(type0, EbtDouble, op)) ) {
        res0 = EbtDouble;
        res1 = EbtDouble;
    } else if ((type0 == EbtFloat && canImplicitlyPromote(type1, EbtFloat, op)) ||
               (type1 == EbtFloat && canImplicitlyPromote(type0, EbtFloat, op)) ) {
        res0 = EbtFloat;
        res1 = EbtFloat;
    } else if ((type0 == EbtFloat16 && canImplicitlyPromote(type1, EbtFloat16, op)) ||
               (type1 == EbtFloat16 && canImplicitlyPromote(type0, EbtFloat16, op)) ) {
        res0 = EbtFloat16;
        res1 = EbtFloat16;
    } else if (isTypeInt(type0) && isTypeInt(type1) &&
               (canImplicitlyPromote(type0, type1, op) || canImplicitlyPromote(type1, type0, op))) {
        if ((isTypeSignedInt(type0) && isTypeSignedInt(type1)) ||
            (isTypeUnsignedInt(type0) && isTypeUnsignedInt(type1))) {
            if (getTypeRank(type0) < getTypeRank(type1)) {
                res0 = type1;
                res1 = type1;
            } else {
                res0 = type0;
                res1 = type0;
            }
        } else if (isTypeUnsignedInt(type0) && (getTypeRank(type0) > getTypeRank(type1))) {
            res0 = type0;
            res1 = type0;
        } else if (isTypeUnsignedInt(type1) && (getTypeRank(type1) > getTypeRank(type0))) {
            res0 = type1;
            res1 = type1;
        } else if (isTypeSignedInt(type0)) {
            if (canSignedIntTypeRepresentAllUnsignedValues(type0, type1)) {
                res0 = type0;
                res1 = type0;
            } else {
                res0 = getCorrespondingUnsignedType(type0);
                res1 = getCorrespondingUnsignedType(type0);
            }
        } else if (isTypeSignedInt(type1)) {
            if (canSignedIntTypeRepresentAllUnsignedValues(type1, type0)) {
                res0 = type1;
                res1 = type1;
            } else {
                res0 = getCorrespondingUnsignedType(type1);
                res1 = getCorrespondingUnsignedType(type1);
            }
        }
    }

    return std::make_tuple(res0, res1);
}

//
// Given a type, find what operation would fully construct it.
//
TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
{
    TOperator op = EOpNull;

    if (type.getQualifier().isNonUniform())
        return EOpConstructNonuniform;

    if (type.isCoopMat())
        return EOpConstructCooperativeMatrix;

    switch (type.getBasicType()) {
    case EbtStruct:
        op = EOpConstructStruct;
        break;
    case EbtSampler:
        if (type.getSampler().isCombined())
            op = EOpConstructTextureSampler;
        break;
    case EbtFloat:
        if (type.isMatrix()) {
            switch (type.getMatrixCols()) {
            case 2:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructMat2x2; break;
                case 3: op = EOpConstructMat2x3; break;
                case 4: op = EOpConstructMat2x4; break;
                default: break; // some compilers want this
                }
                break;
            case 3:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructMat3x2; break;
                case 3: op = EOpConstructMat3x3; break;
                case 4: op = EOpConstructMat3x4; break;
                default: break; // some compilers want this
                }
                break;
            case 4:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructMat4x2; break;
                case 3: op = EOpConstructMat4x3; break;
                case 4: op = EOpConstructMat4x4; break;
                default: break; // some compilers want this
                }
                break;
            default: break; // some compilers want this
            }
        } else {
            switch(type.getVectorSize()) {
            case 1: op = EOpConstructFloat; break;
            case 2: op = EOpConstructVec2;  break;
            case 3: op = EOpConstructVec3;  break;
            case 4: op = EOpConstructVec4;  break;
            default: break; // some compilers want this
            }
        }
        break;
    case EbtInt:
        if (type.getMatrixCols()) {
            switch (type.getMatrixCols()) {
            case 2:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructIMat2x2; break;
                case 3: op = EOpConstructIMat2x3; break;
                case 4: op = EOpConstructIMat2x4; break;
                default: break; // some compilers want this
                }
                break;
            case 3:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructIMat3x2; break;
                case 3: op = EOpConstructIMat3x3; break;
                case 4: op = EOpConstructIMat3x4; break;
                default: break; // some compilers want this
                }
                break;
            case 4:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructIMat4x2; break;
                case 3: op = EOpConstructIMat4x3; break;
                case 4: op = EOpConstructIMat4x4; break;
                default: break; // some compilers want this
                }
                break;
            }
        } else {
            switch(type.getVectorSize()) {
            case 1: op = EOpConstructInt;   break;
            case 2: op = EOpConstructIVec2; break;
            case 3: op = EOpConstructIVec3; break;
            case 4: op = EOpConstructIVec4; break;
            default: break; // some compilers want this
            }
        }
        break;
    case EbtUint:
        if (type.getMatrixCols()) {
            switch (type.getMatrixCols()) {
            case 2:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructUMat2x2; break;
                case 3: op = EOpConstructUMat2x3; break;
                case 4: op = EOpConstructUMat2x4; break;
                default: break; // some compilers want this
                }
                break;
            case 3:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructUMat3x2; break;
                case 3: op = EOpConstructUMat3x3; break;
                case 4: op = EOpConstructUMat3x4; break;
                default: break; // some compilers want this
                }
                break;
            case 4:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructUMat4x2; break;
                case 3: op = EOpConstructUMat4x3; break;
                case 4: op = EOpConstructUMat4x4; break;
                default: break; // some compilers want this
                }
                break;
            }
        } else {
            switch(type.getVectorSize()) {
            case 1: op = EOpConstructUint;  break;
            case 2: op = EOpConstructUVec2; break;
            case 3: op = EOpConstructUVec3; break;
            case 4: op = EOpConstructUVec4; break;
            default: break; // some compilers want this
            }
        }
        break;
    case EbtBool:
        if (type.getMatrixCols()) {
            switch (type.getMatrixCols()) {
            case 2:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructBMat2x2; break;
                case 3: op = EOpConstructBMat2x3; break;
                case 4: op = EOpConstructBMat2x4; break;
                default: break; // some compilers want this
                }
                break;
            case 3:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructBMat3x2; break;
                case 3: op = EOpConstructBMat3x3; break;
                case 4: op = EOpConstructBMat3x4; break;
                default: break; // some compilers want this
                }
                break;
            case 4:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructBMat4x2; break;
                case 3: op = EOpConstructBMat4x3; break;
                case 4: op = EOpConstructBMat4x4; break;
                default: break; // some compilers want this
                }
                break;
            }
        } else {
            switch(type.getVectorSize()) {
            case 1:  op = EOpConstructBool;  break;
            case 2:  op = EOpConstructBVec2; break;
            case 3:  op = EOpConstructBVec3; break;
            case 4:  op = EOpConstructBVec4; break;
            default: break; // some compilers want this
            }
        }
        break;
#ifndef GLSLANG_WEB
    case EbtDouble:
        if (type.getMatrixCols()) {
            switch (type.getMatrixCols()) {
            case 2:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructDMat2x2; break;
                case 3: op = EOpConstructDMat2x3; break;
                case 4: op = EOpConstructDMat2x4; break;
                default: break; // some compilers want this
                }
                break;
            case 3:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructDMat3x2; break;
                case 3: op = EOpConstructDMat3x3; break;
                case 4: op = EOpConstructDMat3x4; break;
                default: break; // some compilers want this
                }
                break;
            case 4:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructDMat4x2; break;
                case 3: op = EOpConstructDMat4x3; break;
                case 4: op = EOpConstructDMat4x4; break;
                default: break; // some compilers want this
                }
                break;
            }
        } else {
            switch(type.getVectorSize()) {
            case 1: op = EOpConstructDouble; break;
            case 2: op = EOpConstructDVec2;  break;
            case 3: op = EOpConstructDVec3;  break;
            case 4: op = EOpConstructDVec4;  break;
            default: break; // some compilers want this
            }
        }
        break;
    case EbtFloat16:
        if (type.getMatrixCols()) {
            switch (type.getMatrixCols()) {
            case 2:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructF16Mat2x2; break;
                case 3: op = EOpConstructF16Mat2x3; break;
                case 4: op = EOpConstructF16Mat2x4; break;
                default: break; // some compilers want this
                }
                break;
            case 3:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructF16Mat3x2; break;
                case 3: op = EOpConstructF16Mat3x3; break;
                case 4: op = EOpConstructF16Mat3x4; break;
                default: break; // some compilers want this
                }
                break;
            case 4:
                switch (type.getMatrixRows()) {
                case 2: op = EOpConstructF16Mat4x2; break;
                case 3: op = EOpConstructF16Mat4x3; break;
                case 4: op = EOpConstructF16Mat4x4; break;
                default: break; // some compilers want this
                }
                break;
            }
        }
        else {
            switch (type.getVectorSize()) {
            case 1: op = EOpConstructFloat16;  break;
            case 2: op = EOpConstructF16Vec2;  break;
            case 3: op = EOpConstructF16Vec3;  break;
            case 4: op = EOpConstructF16Vec4;  break;
            default: break; // some compilers want this
            }
        }
        break;
    case EbtInt8:
        switch(type.getVectorSize()) {
        case 1: op = EOpConstructInt8;   break;
        case 2: op = EOpConstructI8Vec2; break;
        case 3: op = EOpConstructI8Vec3; break;
        case 4: op = EOpConstructI8Vec4; break;
        default: break; // some compilers want this
        }
        break;
    case EbtUint8:
        switch(type.getVectorSize()) {
        case 1: op = EOpConstructUint8;  break;
        case 2: op = EOpConstructU8Vec2; break;
        case 3: op = EOpConstructU8Vec3; break;
        case 4: op = EOpConstructU8Vec4; break;
        default: break; // some compilers want this
        }
        break;
    case EbtInt16:
        switch(type.getVectorSize()) {
        case 1: op = EOpConstructInt16;   break;
        case 2: op = EOpConstructI16Vec2; break;
        case 3: op = EOpConstructI16Vec3; break;
        case 4: op = EOpConstructI16Vec4; break;
        default: break; // some compilers want this
        }
        break;
    case EbtUint16:
        switch(type.getVectorSize()) {
        case 1: op = EOpConstructUint16;  break;
        case 2: op = EOpConstructU16Vec2; break;
        case 3: op = EOpConstructU16Vec3; break;
        case 4: op = EOpConstructU16Vec4; break;
        default: break; // some compilers want this
        }
        break;
    case EbtInt64:
        switch(type.getVectorSize()) {
        case 1: op = EOpConstructInt64;   break;
        case 2: op = EOpConstructI64Vec2; break;
        case 3: op = EOpConstructI64Vec3; break;
        case 4: op = EOpConstructI64Vec4; break;
        default: break; // some compilers want this
        }
        break;
    case EbtUint64:
        switch(type.getVectorSize()) {
        case 1: op = EOpConstructUint64;  break;
        case 2: op = EOpConstructU64Vec2; break;
        case 3: op = EOpConstructU64Vec3; break;
        case 4: op = EOpConstructU64Vec4; break;
        default: break; // some compilers want this
        }
        break;
    case EbtReference:
        op = EOpConstructReference;
        break;
#endif
    default:
        break;
    }

    return op;
}

//
// Safe way to combine two nodes into an aggregate.  Works with null pointers,
// a node that's not a aggregate yet, etc.
//
// Returns the resulting aggregate, unless nullptr was passed in for
// both existing nodes.
//
TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right)
{
    if (left == nullptr && right == nullptr)
        return nullptr;

    TIntermAggregate* aggNode = nullptr;
    if (left != nullptr)
        aggNode = left->getAsAggregate();
    if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
        aggNode = new TIntermAggregate;
        if (left != nullptr)
            aggNode->getSequence().push_back(left);
    }

    if (right != nullptr)
        aggNode->getSequence().push_back(right);

    return aggNode;
}

TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc)
{
    TIntermAggregate* aggNode = growAggregate(left, right);
    if (aggNode)
        aggNode->setLoc(loc);

    return aggNode;
}

//
// Turn an existing node into an aggregate.
//
// Returns an aggregate, unless nullptr was passed in for the existing node.
//
TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node)
{
    if (node == nullptr)
        return nullptr;

    TIntermAggregate* aggNode = new TIntermAggregate;
    aggNode->getSequence().push_back(node);
    aggNode->setLoc(node->getLoc());

    return aggNode;
}

TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& loc)
{
    if (node == nullptr)
        return nullptr;

    TIntermAggregate* aggNode = new TIntermAggregate;
    aggNode->getSequence().push_back(node);
    aggNode->setLoc(loc);

    return aggNode;
}

//
// Make an aggregate with an empty sequence.
//
TIntermAggregate* TIntermediate::makeAggregate(const TSourceLoc& loc)
{
    TIntermAggregate* aggNode = new TIntermAggregate;
    aggNode->setLoc(loc);

    return aggNode;
}

//
// For "if" test nodes.  There are three children; a condition,
// a true path, and a false path.  The two paths are in the
// nodePair.
//
// Returns the selection node created.
//
TIntermSelection* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc)
{
    //
    // Don't prune the false path for compile-time constants; it's needed
    // for static access analysis.
    //

    TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
    node->setLoc(loc);

    return node;
}

TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc)
{
    // However, the lowest precedence operators of the sequence operator ( , ) and the assignment operators
    // ... are not included in the operators that can create a constant expression.
    //
    // if (left->getType().getQualifier().storage == EvqConst &&
    //    right->getType().getQualifier().storage == EvqConst) {

    //    return right;
    //}

    TIntermTyped *commaAggregate = growAggregate(left, right, loc);
    commaAggregate->getAsAggregate()->setOperator(EOpComma);
    commaAggregate->setType(right->getType());
    commaAggregate->getWritableType().getQualifier().makeTemporary();

    return commaAggregate;
}

TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, const TSourceLoc& loc)
{
    TIntermMethod* method = new TIntermMethod(object, type, *name);
    method->setLoc(loc);

    return method;
}

//
// For "?:" test nodes.  There are three children; a condition,
// a true path, and a false path.  The two paths are specified
// as separate parameters. For vector 'cond', the true and false
// are not paths, but vectors to mix.
//
// Specialization constant operations include
//     - The ternary operator ( ? : )
//
// Returns the selection node created, or nullptr if one could not be.
//
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock,
                                          const TSourceLoc& loc)
{
    // If it's void, go to the if-then-else selection()
    if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) {
        TIntermNodePair pair = { trueBlock, falseBlock };
        TIntermSelection* selection = addSelection(cond, pair, loc);
        if (getSource() == EShSourceHlsl)
            selection->setNoShortCircuit();

        return selection;
    }

    //
    // Get compatible types.
    //
    auto children = addConversion(EOpSequence, trueBlock, falseBlock);
    trueBlock = std::get<0>(children);
    falseBlock = std::get<1>(children);

    if (trueBlock == nullptr || falseBlock == nullptr)
        return nullptr;

    // Handle a vector condition as a mix
    if (!cond->getType().isScalarOrVec1()) {
        TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary,
                               cond->getType().getVectorSize());
        // smear true/false operands as needed
        trueBlock = addUniShapeConversion(EOpMix, targetVectorType, trueBlock);
        falseBlock = addUniShapeConversion(EOpMix, targetVectorType, falseBlock);

        // After conversion, types have to match.
        if (falseBlock->getType() != trueBlock->getType())
            return nullptr;

        // make the mix operation
        TIntermAggregate* mix = makeAggregate(loc);
        mix = growAggregate(mix, falseBlock);
        mix = growAggregate(mix, trueBlock);
        mix = growAggregate(mix, cond);
        mix->setType(targetVectorType);
        mix->setOp(EOpMix);

        return mix;
    }

    // Now have a scalar condition...

    // Convert true and false expressions to matching types
    addBiShapeConversion(EOpMix, trueBlock, falseBlock);

    // After conversion, types have to match.
    if (falseBlock->getType() != trueBlock->getType())
        return nullptr;

    // Eliminate the selection when the condition is a scalar and all operands are constant.
    if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
        if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
            return trueBlock;
        else
            return falseBlock;
    }

    //
    // Make a selection node.
    //
    TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
    node->setLoc(loc);
    node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision);

    if ((cond->getQualifier().isConstant() && specConstantPropagates(*trueBlock, *falseBlock)) ||
        (cond->getQualifier().isSpecConstant() && trueBlock->getQualifier().isConstant() &&
                                                 falseBlock->getQualifier().isConstant()))
        node->getQualifier().makeSpecConstant();
    else
        node->getQualifier().makeTemporary();

    if (getSource() == EShSourceHlsl)
        node->setNoShortCircuit();

    return node;
}

//
// Constant terminal nodes.  Has a union that contains bool, float or int constants
//
// Returns the constant union node created.
//

TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, const TSourceLoc& loc, bool literal) const
{
    TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t);
    node->getQualifier().storage = EvqConst;
    node->setLoc(loc);
    if (literal)
        node->setLiteral();

    return node;
}
TIntermConstantUnion* TIntermediate::addConstantUnion(signed char i8, const TSourceLoc& loc, bool literal) const
{
    TConstUnionArray unionArray(1);
    unionArray[0].setI8Const(i8);

    return addConstantUnion(unionArray, TType(EbtInt8, EvqConst), loc, literal);
}

TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned char u8, const TSourceLoc& loc, bool literal) const
{
    TConstUnionArray unionArray(1);
    unionArray[0].setUConst(u8);

    return addConstantUnion(unionArray, TType(EbtUint8, EvqConst), loc, literal);
}

TIntermConstantUnion* TIntermediate::addConstantUnion(signed short i16, const TSourceLoc& loc, bool literal) const
{
    TConstUnionArray unionArray(1);
    unionArray[0].setI16Const(i16);

    return addConstantUnion(unionArray, TType(EbtInt16, EvqConst), loc, literal);
}

TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned short u16, const TSourceLoc& loc, bool literal) const
{
    TConstUnionArray unionArray(1);
    unionArray[0].setU16Const(u16);

    return addConstantUnion(unionArray, TType(EbtUint16, EvqConst), loc, literal);
}

TIntermConstantUnion* TIntermediate::addConstantUnion(int i, const TSourceLoc& loc, bool literal) const
{
    TConstUnionArray unionArray(1);
    unionArray[0].setIConst(i);

    return addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc, literal);
}

TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, const TSourceLoc& loc, bool literal) const
{
    TConstUnionArray unionArray(1);
    unionArray[0].setUConst(u);

    return addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc, literal);
}

TIntermConstantUnion* TIntermediate::addConstantUnion(long long i64, const TSourceLoc& loc, bool literal) const
{
    TConstUnionArray unionArray(1);
    unionArray[0].setI64Const(i64);

    return addConstantUnion(unionArray, TType(EbtInt64, EvqConst), loc, literal);
}

TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned long long u64, const TSourceLoc& loc, bool literal) const
{
    TConstUnionArray unionArray(1);
    unionArray[0].setU64Const(u64);

    return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal);
}

TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const
{
    TConstUnionArray unionArray(1);
    unionArray[0].setBConst(b);

    return addConstantUnion(unionArray, TType(EbtBool, EvqConst), loc, literal);
}

TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const
{
    assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);

    TConstUnionArray unionArray(1);
    unionArray[0].setDConst(d);

    return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal);
}

TIntermConstantUnion* TIntermediate::addConstantUnion(const TString* s, const TSourceLoc& loc, bool literal) const
{
    TConstUnionArray unionArray(1);
    unionArray[0].setSConst(s);

    return addConstantUnion(unionArray, TType(EbtString, EvqConst), loc, literal);
}

// Put vector swizzle selectors onto the given sequence
void TIntermediate::pushSelector(TIntermSequence& sequence, const TVectorSelector& selector, const TSourceLoc& loc)
{
    TIntermConstantUnion* constIntNode = addConstantUnion(selector, loc);
    sequence.push_back(constIntNode);
}

// Put matrix swizzle selectors onto the given sequence
void TIntermediate::pushSelector(TIntermSequence& sequence, const TMatrixSelector& selector, const TSourceLoc& loc)
{
    TIntermConstantUnion* constIntNode = addConstantUnion(selector.coord1, loc);
    sequence.push_back(constIntNode);
    constIntNode = addConstantUnion(selector.coord2, loc);
    sequence.push_back(constIntNode);
}

// Make an aggregate node that has a sequence of all selectors.
template TIntermTyped* TIntermediate::addSwizzle<TVectorSelector>(TSwizzleSelectors<TVectorSelector>& selector, const TSourceLoc& loc);
template TIntermTyped* TIntermediate::addSwizzle<TMatrixSelector>(TSwizzleSelectors<TMatrixSelector>& selector, const TSourceLoc& loc);
template<typename selectorType>
TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selector, const TSourceLoc& loc)
{
    TIntermAggregate* node = new TIntermAggregate(EOpSequence);

    node->setLoc(loc);
    TIntermSequence &sequenceVector = node->getSequence();

    for (int i = 0; i < selector.size(); i++)
        pushSelector(sequenceVector, selector[i], loc);

    return node;
}

//
// Follow the left branches down to the root of an l-value
// expression (just "." and []).
//
// Return the base of the l-value (where following indexing quits working).
// Return nullptr if a chain following dereferences cannot be followed.
//
// 'swizzleOkay' says whether or not it is okay to consider a swizzle
// a valid part of the dereference chain.
//
const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay)
{
    do {
        const TIntermBinary* binary = node->getAsBinaryNode();
        if (binary == nullptr)
            return node;
        TOperator op = binary->getOp();
        if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && op != EOpMatrixSwizzle)
            return nullptr;
        if (! swizzleOkay) {
            if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle)
                return nullptr;
            if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
                (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
                ! binary->getLeft()->getType().isArray())
                return nullptr;
        }
        node = node->getAsBinaryNode()->getLeft();
    } while (true);
}

//
// Create while and do-while loop nodes.
//
TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst,
    const TSourceLoc& loc)
{
    TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
    node->setLoc(loc);

    return node;
}

//
// Create a for-loop sequence.
//
TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test,
    TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TIntermLoop*& node)
{
    node = new TIntermLoop(body, test, terminal, testFirst);
    node->setLoc(loc);

    // make a sequence of the initializer and statement, but try to reuse the
    // aggregate already created for whatever is in the initializer, if there is one
    TIntermAggregate* loopSequence = (initializer == nullptr ||
                                      initializer->getAsAggregate() == nullptr) ? makeAggregate(initializer, loc)
                                                                                : initializer->getAsAggregate();
    if (loopSequence != nullptr && loopSequence->getOp() == EOpSequence)
        loopSequence->setOp(EOpNull);
    loopSequence = growAggregate(loopSequence, node);
    loopSequence->setOperator(EOpSequence);

    return loopSequence;
}

//
// Add branches.
//
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc)
{
    return addBranch(branchOp, nullptr, loc);
}

TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& loc)
{
    TIntermBranch* node = new TIntermBranch(branchOp, expression);
    node->setLoc(loc);

    return node;
}

//
// This is to be executed after the final root is put on top by the parsing
// process.
//
bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
{
    if (root == nullptr)
        return true;

    // Finish off the top-level sequence
    TIntermAggregate* aggRoot = root->getAsAggregate();
    if (aggRoot && aggRoot->getOp() == EOpNull)
        aggRoot->setOperator(EOpSequence);

#ifndef GLSLANG_WEB
    // Propagate 'noContraction' label in backward from 'precise' variables.
    glslang::PropagateNoContraction(*this);

    switch (textureSamplerTransformMode) {
    case EShTexSampTransKeep:
        break;
    case EShTexSampTransUpgradeTextureRemoveSampler:
        performTextureUpgradeAndSamplerRemovalTransformation(root);
        break;
    }
#endif

    return true;
}

void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable)
{
    // Add top-level nodes for declarations that must be checked cross
    // compilation unit by a linker, yet might not have been referenced
    // by the AST.
    //
    // Almost entirely, translation of symbols is driven by what's present
    // in the AST traversal, not by translating the symbol table.
    //
    // However, there are some special cases:
    //  - From the specification: "Special built-in inputs gl_VertexID and
    //    gl_InstanceID are also considered active vertex attributes."
    //  - Linker-based type mismatch error reporting needs to see all
    //    uniforms/ins/outs variables and blocks.
    //  - ftransform() can make gl_Vertex and gl_ModelViewProjectionMatrix active.
    //

    // if (ftransformUsed) {
        // TODO: 1.1 lowering functionality: track ftransform() usage
    //    addSymbolLinkageNode(root, symbolTable, "gl_Vertex");
    //    addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix");
    //}

    if (language == EShLangVertex) {
        // the names won't be found in the symbol table unless the versions are right,
        // so version logic does not need to be repeated here
        addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID");
        addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
    }

    // Add a child to the root node for the linker objects
    linkage->setOperator(EOpLinkerObjects);
    treeRoot = growAggregate(treeRoot, linkage);
}

//
// Add the given name or symbol to the list of nodes at the end of the tree used
// for link-time checking and external linkage.
//

void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable& symbolTable, const TString& name)
{
    TSymbol* symbol = symbolTable.find(name);
    if (symbol)
        addSymbolLinkageNode(linkage, *symbol->getAsVariable());
}

void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol& symbol)
{
    const TVariable* variable = symbol.getAsVariable();
    if (! variable) {
        // This must be a member of an anonymous block, and we need to add the whole block
        const TAnonMember* anon = symbol.getAsAnonMember();
        variable = &anon->getAnonContainer();
    }
    TIntermSymbol* node = addSymbol(*variable);
    linkage = growAggregate(linkage, node);
}

//
// Add a caller->callee relationship to the call graph.
// Assumes the strings are unique per signature.
//
void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& caller, const TString& callee)
{
    // Duplicates are okay, but faster to not keep them, and they come grouped by caller,
    // as long as new ones are push on the same end we check on for duplicates
    for (TGraph::const_iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
        if (call->caller != caller)
            break;
        if (call->callee == callee)
            return;
    }

    callGraph.push_front(TCall(caller, callee));
}

//
// This deletes the tree.
//
void TIntermediate::removeTree()
{
    if (treeRoot)
        RemoveAllTreeNodes(treeRoot);
}

//
// Implement the part of KHR_vulkan_glsl that lists the set of operations
// that can result in a specialization constant operation.
//
// "5.x Specialization Constant Operations"
//
//    Only some operations discussed in this section may be applied to a
//    specialization constant and still yield a result that is as
//    specialization constant.  The operations allowed are listed below.
//    When a specialization constant is operated on with one of these
//    operators and with another constant or specialization constant, the
//    result is implicitly a specialization constant.
//
//     - int(), uint(), and bool() constructors for type conversions
//       from any of the following types to any of the following types:
//         * int
//         * uint
//         * bool
//     - vector versions of the above conversion constructors
//     - allowed implicit conversions of the above
//     - swizzles (e.g., foo.yx)
//     - The following when applied to integer or unsigned integer types:
//         * unary negative ( - )
//         * binary operations ( + , - , * , / , % )
//         * shift ( <<, >> )
//         * bitwise operations ( & , | , ^ )
//     - The following when applied to integer or unsigned integer scalar types:
//         * comparison ( == , != , > , >= , < , <= )
//     - The following when applied to the Boolean scalar type:
//         * not ( ! )
//         * logical operations ( && , || , ^^ )
//         * comparison ( == , != )"
//
// This function just handles binary and unary nodes.  Construction
// rules are handled in construction paths that are not covered by the unary
// and binary paths, while required conversions will still show up here
// as unary converters in the from a construction operator.
//
bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const
{
    // The operations resulting in floating point are quite limited
    // (However, some floating-point operations result in bool, like ">",
    // so are handled later.)
    if (node.getType().isFloatingDomain()) {
        switch (node.getOp()) {
        case EOpIndexDirect:
        case EOpIndexIndirect:
        case EOpIndexDirectStruct:
        case EOpVectorSwizzle:
        case EOpConvFloatToDouble:
        case EOpConvDoubleToFloat:
        case EOpConvFloat16ToFloat:
        case EOpConvFloatToFloat16:
        case EOpConvFloat16ToDouble:
        case EOpConvDoubleToFloat16:
            return true;
        default:
            return false;
        }
    }

    // Check for floating-point arguments
    if (const TIntermBinary* bin = node.getAsBinaryNode())
        if (bin->getLeft() ->getType().isFloatingDomain() ||
            bin->getRight()->getType().isFloatingDomain())
            return false;

    // So, for now, we can assume everything left is non-floating-point...

    // Now check for integer/bool-based operations
    switch (node.getOp()) {

    // dereference/swizzle
    case EOpIndexDirect:
    case EOpIndexIndirect:
    case EOpIndexDirectStruct:
    case EOpVectorSwizzle:

    // (u)int* -> bool
    case EOpConvInt8ToBool:
    case EOpConvInt16ToBool:
    case EOpConvIntToBool:
    case EOpConvInt64ToBool:
    case EOpConvUint8ToBool:
    case EOpConvUint16ToBool:
    case EOpConvUintToBool:
    case EOpConvUint64ToBool:

    // bool -> (u)int*
    case EOpConvBoolToInt8:
    case EOpConvBoolToInt16:
    case EOpConvBoolToInt:
    case EOpConvBoolToInt64:
    case EOpConvBoolToUint8:
    case EOpConvBoolToUint16:
    case EOpConvBoolToUint:
    case EOpConvBoolToUint64:

    // int8_t -> (u)int*
    case EOpConvInt8ToInt16:
    case EOpConvInt8ToInt:
    case EOpConvInt8ToInt64:
    case EOpConvInt8ToUint8:
    case EOpConvInt8ToUint16:
    case EOpConvInt8ToUint:
    case EOpConvInt8ToUint64:

    // int16_t -> (u)int*
    case EOpConvInt16ToInt8:
    case EOpConvInt16ToInt:
    case EOpConvInt16ToInt64:
    case EOpConvInt16ToUint8:
    case EOpConvInt16ToUint16:
    case EOpConvInt16ToUint:
    case EOpConvInt16ToUint64:

    // int32_t -> (u)int*
    case EOpConvIntToInt8:
    case EOpConvIntToInt16:
    case EOpConvIntToInt64:
    case EOpConvIntToUint8:
    case EOpConvIntToUint16:
    case EOpConvIntToUint:
    case EOpConvIntToUint64:

    // int64_t -> (u)int*
    case EOpConvInt64ToInt8:
    case EOpConvInt64ToInt16:
    case EOpConvInt64ToInt:
    case EOpConvInt64ToUint8:
    case EOpConvInt64ToUint16:
    case EOpConvInt64ToUint:
    case EOpConvInt64ToUint64:

    // uint8_t -> (u)int*
    case EOpConvUint8ToInt8:
    case EOpConvUint8ToInt16:
    case EOpConvUint8ToInt:
    case EOpConvUint8ToInt64:
    case EOpConvUint8ToUint16:
    case EOpConvUint8ToUint:
    case EOpConvUint8ToUint64:

    // uint16_t -> (u)int*
    case EOpConvUint16ToInt8:
    case EOpConvUint16ToInt16:
    case EOpConvUint16ToInt:
    case EOpConvUint16ToInt64:
    case EOpConvUint16ToUint8:
    case EOpConvUint16ToUint:
    case EOpConvUint16ToUint64:

    // uint32_t -> (u)int*
    case EOpConvUintToInt8:
    case EOpConvUintToInt16:
    case EOpConvUintToInt:
    case EOpConvUintToInt64:
    case EOpConvUintToUint8:
    case EOpConvUintToUint16:
    case EOpConvUintToUint64:

    // uint64_t -> (u)int*
    case EOpConvUint64ToInt8:
    case EOpConvUint64ToInt16:
    case EOpConvUint64ToInt:
    case EOpConvUint64ToInt64:
    case EOpConvUint64ToUint8:
    case EOpConvUint64ToUint16:
    case EOpConvUint64ToUint:

    // unary operations
    case EOpNegative:
    case EOpLogicalNot:
    case EOpBitwiseNot:

    // binary operations
    case EOpAdd:
    case EOpSub:
    case EOpMul:
    case EOpVectorTimesScalar:
    case EOpDiv:
    case EOpMod:
    case EOpRightShift:
    case EOpLeftShift:
    case EOpAnd:
    case EOpInclusiveOr:
    case EOpExclusiveOr:
    case EOpLogicalOr:
    case EOpLogicalXor:
    case EOpLogicalAnd:
    case EOpEqual:
    case EOpNotEqual:
    case EOpLessThan:
    case EOpGreaterThan:
    case EOpLessThanEqual:
    case EOpGreaterThanEqual:
        return true;
    default:
        return false;
    }
}

// Is the operation one that must propagate nonuniform?
bool TIntermediate::isNonuniformPropagating(TOperator op) const
{
    // "* All Operators in Section 5.1 (Operators), except for assignment,
    //    arithmetic assignment, and sequence
    //  * Component selection in Section 5.5
    //  * Matrix components in Section 5.6
    //  * Structure and Array Operations in Section 5.7, except for the length
    //    method."
    switch (op) {
    case EOpPostIncrement:
    case EOpPostDecrement:
    case EOpPreIncrement:
    case EOpPreDecrement:

    case EOpNegative:
    case EOpLogicalNot:
    case EOpVectorLogicalNot:
    case EOpBitwiseNot:

    case EOpAdd:
    case EOpSub:
    case EOpMul:
    case EOpDiv:
    case EOpMod:
    case EOpRightShift:
    case EOpLeftShift:
    case EOpAnd:
    case EOpInclusiveOr:
    case EOpExclusiveOr:
    case EOpEqual:
    case EOpNotEqual:
    case EOpLessThan:
    case EOpGreaterThan:
    case EOpLessThanEqual:
    case EOpGreaterThanEqual:
    case EOpVectorTimesScalar:
    case EOpVectorTimesMatrix:
    case EOpMatrixTimesVector:
    case EOpMatrixTimesScalar:

    case EOpLogicalOr:
    case EOpLogicalXor:
    case EOpLogicalAnd:

    case EOpIndexDirect:
    case EOpIndexIndirect:
    case EOpIndexDirectStruct:
    case EOpVectorSwizzle:
        return true;

    default:
        break;
    }

    return false;
}

////////////////////////////////////////////////////////////////
//
// Member functions of the nodes used for building the tree.
//
////////////////////////////////////////////////////////////////

//
// Say whether or not an operation node changes the value of a variable.
//
// Returns true if state is modified.
//
bool TIntermOperator::modifiesState() const
{
    switch (op) {
    case EOpPostIncrement:
    case EOpPostDecrement:
    case EOpPreIncrement:
    case EOpPreDecrement:
    case EOpAssign:
    case EOpAddAssign:
    case EOpSubAssign:
    case EOpMulAssign:
    case EOpVectorTimesMatrixAssign:
    case EOpVectorTimesScalarAssign:
    case EOpMatrixTimesScalarAssign:
    case EOpMatrixTimesMatrixAssign:
    case EOpDivAssign:
    case EOpModAssign:
    case EOpAndAssign:
    case EOpInclusiveOrAssign:
    case EOpExclusiveOrAssign:
    case EOpLeftShiftAssign:
    case EOpRightShiftAssign:
        return true;
    default:
        return false;
    }
}

//
// returns true if the operator is for one of the constructors
//
bool TIntermOperator::isConstructor() const
{
    return op > EOpConstructGuardStart && op < EOpConstructGuardEnd;
}

//
// Make sure the type of an operator is appropriate for its
// combination of operation and operand type.  This will invoke
// promoteUnary, promoteBinary, etc as needed.
//
// Returns false if nothing makes sense.
//
bool TIntermediate::promote(TIntermOperator* node)
{
    if (node == nullptr)
        return false;

    if (node->getAsUnaryNode())
        return promoteUnary(*node->getAsUnaryNode());

    if (node->getAsBinaryNode())
        return promoteBinary(*node->getAsBinaryNode());

    if (node->getAsAggregate())
        return promoteAggregate(*node->getAsAggregate());

    return false;
}

//
// See TIntermediate::promote
//
bool TIntermediate::promoteUnary(TIntermUnary& node)
{
    const TOperator op    = node.getOp();
    TIntermTyped* operand = node.getOperand();

    switch (op) {
    case EOpLogicalNot:
        // Convert operand to a boolean type
        if (operand->getBasicType() != EbtBool) {
            // Add constructor to boolean type. If that fails, we can't do it, so return false.
            TIntermTyped* converted = addConversion(op, TType(EbtBool), operand);
            if (converted == nullptr)
                return false;

            // Use the result of converting the node to a bool.
            node.setOperand(operand = converted); // also updates stack variable
        }
        break;
    case EOpBitwiseNot:
        if (!isTypeInt(operand->getBasicType()))
            return false;
        break;
    case EOpNegative:
    case EOpPostIncrement:
    case EOpPostDecrement:
    case EOpPreIncrement:
    case EOpPreDecrement:
        if (!isTypeInt(operand->getBasicType()) &&
            operand->getBasicType() != EbtFloat &&
            operand->getBasicType() != EbtFloat16 &&
            operand->getBasicType() != EbtDouble)

            return false;
        break;

    default:
        if (operand->getBasicType() != EbtFloat)

            return false;
    }

    node.setType(operand->getType());
    node.getWritableType().getQualifier().makeTemporary();

    return true;
}

void TIntermUnary::updatePrecision()
{
    if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
        if (operand->getQualifier().precision > getQualifier().precision)
            getQualifier().precision = operand->getQualifier().precision;
    }
}

//
// See TIntermediate::promote
//
bool TIntermediate::promoteBinary(TIntermBinary& node)
{
    TOperator     op    = node.getOp();
    TIntermTyped* left  = node.getLeft();
    TIntermTyped* right = node.getRight();

    // Arrays and structures have to be exact matches.
    if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct)
        && left->getType() != right->getType())
        return false;

    // Base assumption:  just make the type the same as the left
    // operand.  Only deviations from this will be coded.
    node.setType(left->getType());
    node.getWritableType().getQualifier().clear();

    // Composite and opaque types don't having pending operator changes, e.g.,
    // array, structure, and samplers.  Just establish final type and correctness.
    if (left->isArray() || left->getBasicType() == EbtStruct || left->getBasicType() == EbtSampler) {
        switch (op) {
        case EOpEqual:
        case EOpNotEqual:
            if (left->getBasicType() == EbtSampler) {
                // can't compare samplers
                return false;
            } else {
                // Promote to conditional
                node.setType(TType(EbtBool));
            }

            return true;

        case EOpAssign:
            // Keep type from above

            return true;

        default:
            return false;
        }
    }

    //
    // We now have only scalars, vectors, and matrices to worry about.
    //

    // HLSL implicitly promotes bool -> int for numeric operations.
    // (Implicit conversions to make the operands match each other's types were already done.)
    if (getSource() == EShSourceHlsl &&
        (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)) {
        switch (op) {
        case EOpLessThan:
        case EOpGreaterThan:
        case EOpLessThanEqual:
        case EOpGreaterThanEqual:

        case EOpRightShift:
        case EOpLeftShift:

        case EOpMod:

        case EOpAnd:
        case EOpInclusiveOr:
        case EOpExclusiveOr:

        case EOpAdd:
        case EOpSub:
        case EOpDiv:
        case EOpMul:
            if (left->getBasicType() == EbtBool)
                left  = createConversion(EbtInt, left);
            if (right->getBasicType() == EbtBool)
                right = createConversion(EbtInt, right);
            if (left == nullptr || right == nullptr)
                return false;
            node.setLeft(left);
            node.setRight(right);

            // Update the original base assumption on result type..
            node.setType(left->getType());
            node.getWritableType().getQualifier().clear();

            break;

        default:
            break;
        }
    }

    // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that)
    switch (op) {
    case EOpLessThan:
    case EOpGreaterThan:
    case EOpLessThanEqual:
    case EOpGreaterThanEqual:
        // Relational comparisons need numeric types and will promote to scalar Boolean.
        if (left->getBasicType() == EbtBool)
            return false;

        node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize()));
        break;

    case EOpEqual:
    case EOpNotEqual:
        if (getSource() == EShSourceHlsl) {
            const int resultWidth = std::max(left->getVectorSize(), right->getVectorSize());

            // In HLSL, == or != on vectors means component-wise comparison.
            if (resultWidth > 1) {
                op = (op == EOpEqual) ? EOpVectorEqual : EOpVectorNotEqual;
                node.setOp(op);
            }

            node.setType(TType(EbtBool, EvqTemporary, resultWidth));
        } else {
            // All the above comparisons result in a bool (but not the vector compares)
            node.setType(TType(EbtBool));
        }
        break;

    case EOpLogicalAnd:
    case EOpLogicalOr:
    case EOpLogicalXor:
        // logical ops operate only on Booleans or vectors of Booleans.
        if (left->getBasicType() != EbtBool || left->isMatrix())
                return false;

        if (getSource() == EShSourceGlsl) {
            // logical ops operate only on scalar Booleans and will promote to scalar Boolean.
            if (left->isVector())
                return false;
        }

        node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize()));
        break;

    case EOpRightShift:
    case EOpLeftShift:
    case EOpRightShiftAssign:
    case EOpLeftShiftAssign:

    case EOpMod:
    case EOpModAssign:

    case EOpAnd:
    case EOpInclusiveOr:
    case EOpExclusiveOr:
    case EOpAndAssign:
    case EOpInclusiveOrAssign:
    case EOpExclusiveOrAssign:
        if (getSource() == EShSourceHlsl)
            break;

        // Check for integer-only operands.
        if (!isTypeInt(left->getBasicType()) && !isTypeInt(right->getBasicType()))
            return false;
        if (left->isMatrix() || right->isMatrix())
            return false;

        break;

    case EOpAdd:
    case EOpSub:
    case EOpDiv:
    case EOpMul:
    case EOpAddAssign:
    case EOpSubAssign:
    case EOpMulAssign:
    case EOpDivAssign:
        // check for non-Boolean operands
        if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)
            return false;

    default:
        break;
    }

    // Compare left and right, and finish with the cases where the operand types must match
    switch (op) {
    case EOpLessThan:
    case EOpGreaterThan:
    case EOpLessThanEqual:
    case EOpGreaterThanEqual:

    case EOpEqual:
    case EOpNotEqual:
    case EOpVectorEqual:
    case EOpVectorNotEqual:

    case EOpLogicalAnd:
    case EOpLogicalOr:
    case EOpLogicalXor:
        return left->getType() == right->getType();

    case EOpMod:
    case EOpModAssign:

    case EOpAnd:
    case EOpInclusiveOr:
    case EOpExclusiveOr:
    case EOpAndAssign:
    case EOpInclusiveOrAssign:
    case EOpExclusiveOrAssign:

    case EOpAdd:
    case EOpSub:
    case EOpDiv:

    case EOpAddAssign:
    case EOpSubAssign:
    case EOpDivAssign:
        // Quick out in case the types do match
        if (left->getType() == right->getType())
            return true;

        // Fall through

    case EOpMul:
    case EOpMulAssign:
        // At least the basic type has to match
        if (left->getBasicType() != right->getBasicType())
            return false;

    default:
        break;
    }

    if (left->getType().isCoopMat() || right->getType().isCoopMat()) {
        if (left->getType().isCoopMat() && right->getType().isCoopMat() &&
            *left->getType().getTypeParameters() != *right->getType().getTypeParameters()) {
            return false;
        }
        switch (op) {
        case EOpMul:
        case EOpMulAssign:
            if (left->getType().isCoopMat() && right->getType().isCoopMat()) {
                return false;
            }
            if (op == EOpMulAssign && right->getType().isCoopMat()) {
                return false;
            }
            node.setOp(op == EOpMulAssign ? EOpMatrixTimesScalarAssign : EOpMatrixTimesScalar);
            if (right->getType().isCoopMat()) {
                node.setType(right->getType());
            }
            return true;
        case EOpAdd:
        case EOpSub:
        case EOpDiv:
        case EOpAssign:
            // These require both to be cooperative matrices
            if (!left->getType().isCoopMat() || !right->getType().isCoopMat()) {
                return false;
            }
            return true;
        default:
            break;
        }
        return false;
    }

    // Finish handling the case, for all ops, where both operands are scalars.
    if (left->isScalar() && right->isScalar())
        return true;

    // Finish handling the case, for all ops, where there are two vectors of different sizes
    if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize() && right->getVectorSize() > 1)
        return false;

    //
    // We now have a mix of scalars, vectors, or matrices, for non-relational operations.
    //

    // Can these two operands be combined, what is the resulting type?
    TBasicType basicType = left->getBasicType();
    switch (op) {
    case EOpMul:
        if (!left->isMatrix() && right->isMatrix()) {
            if (left->isVector()) {
                if (left->getVectorSize() != right->getMatrixRows())
                    return false;
                node.setOp(op = EOpVectorTimesMatrix);
                node.setType(TType(basicType, EvqTemporary, right->getMatrixCols()));
            } else {
                node.setOp(op = EOpMatrixTimesScalar);
                node.setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), right->getMatrixRows()));
            }
        } else if (left->isMatrix() && !right->isMatrix()) {
            if (right->isVector()) {
                if (left->getMatrixCols() != right->getVectorSize())
                    return false;
                node.setOp(op = EOpMatrixTimesVector);
                node.setType(TType(basicType, EvqTemporary, left->getMatrixRows()));
            } else {
                node.setOp(op = EOpMatrixTimesScalar);
            }
        } else if (left->isMatrix() && right->isMatrix()) {
            if (left->getMatrixCols() != right->getMatrixRows())
                return false;
            node.setOp(op = EOpMatrixTimesMatrix);
            node.setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), left->getMatrixRows()));
        } else if (! left->isMatrix() && ! right->isMatrix()) {
            if (left->isVector() && right->isVector()) {
                ; // leave as component product
            } else if (left->isVector() || right->isVector()) {
                node.setOp(op = EOpVectorTimesScalar);
                if (right->isVector())
                    node.setType(TType(basicType, EvqTemporary, right->getVectorSize()));
            }
        } else {
            return false;
        }
        break;
    case EOpMulAssign:
        if (! left->isMatrix() && right->isMatrix()) {
            if (left->isVector()) {
                if (left->getVectorSize() != right->getMatrixRows() || left->getVectorSize() != right->getMatrixCols())
                    return false;
                node.setOp(op = EOpVectorTimesMatrixAssign);
            } else {
                return false;
            }
        } else if (left->isMatrix() && !right->isMatrix()) {
            if (right->isVector()) {
                return false;
            } else {
                node.setOp(op = EOpMatrixTimesScalarAssign);
            }
        } else if (left->isMatrix() && right->isMatrix()) {
            if (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows())
                return false;
            node.setOp(op = EOpMatrixTimesMatrixAssign);
        } else if (!left->isMatrix() && !right->isMatrix()) {
            if (left->isVector() && right->isVector()) {
                // leave as component product
            } else if (left->isVector() || right->isVector()) {
                if (! left->isVector())
                    return false;
                node.setOp(op = EOpVectorTimesScalarAssign);
            }
        } else {
            return false;
        }
        break;

    case EOpRightShift:
    case EOpLeftShift:
    case EOpRightShiftAssign:
    case EOpLeftShiftAssign:
        if (right->isVector() && (! left->isVector() || right->getVectorSize() != left->getVectorSize()))
            return false;
        break;

    case EOpAssign:
        if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())
            return false;
        // fall through

    case EOpAdd:
    case EOpSub:
    case EOpDiv:
    case EOpMod:
    case EOpAnd:
    case EOpInclusiveOr:
    case EOpExclusiveOr:
    case EOpAddAssign:
    case EOpSubAssign:
    case EOpDivAssign:
    case EOpModAssign:
    case EOpAndAssign:
    case EOpInclusiveOrAssign:
    case EOpExclusiveOrAssign:

        if ((left->isMatrix() && right->isVector()) ||
            (left->isVector() && right->isMatrix()) ||
            left->getBasicType() != right->getBasicType())
            return false;
        if (left->isMatrix() && right->isMatrix() && (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()))
            return false;
        if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
            return false;
        if (right->isVector() || right->isMatrix()) {
            node.getWritableType().shallowCopy(right->getType());
            node.getWritableType().getQualifier().makeTemporary();
        }
        break;

    default:
        return false;
    }

    //
    // One more check for assignment.
    //
    switch (op) {
    // The resulting type has to match the left operand.
    case EOpAssign:
    case EOpAddAssign:
    case EOpSubAssign:
    case EOpMulAssign:
    case EOpDivAssign:
    case EOpModAssign:
    case EOpAndAssign:
    case EOpInclusiveOrAssign:
    case EOpExclusiveOrAssign:
    case EOpLeftShiftAssign:
    case EOpRightShiftAssign:
        if (node.getType() != left->getType())
            return false;
        break;
    default:
        break;
    }

    return true;
}

//
// See TIntermediate::promote
//
bool TIntermediate::promoteAggregate(TIntermAggregate& node)
{
    TOperator op = node.getOp();
    TIntermSequence& args = node.getSequence();
    const int numArgs = static_cast<int>(args.size());

    // Presently, only hlsl does intrinsic promotions.
    if (getSource() != EShSourceHlsl)
        return true;

    // set of opcodes that can be promoted in this manner.
    switch (op) {
    case EOpAtan:
    case EOpClamp:
    case EOpCross:
    case EOpDistance:
    case EOpDot:
    case EOpDst:
    case EOpFaceForward:
    // case EOpFindMSB: TODO:
    // case EOpFindLSB: TODO:
    case EOpFma:
    case EOpMod:
    case EOpFrexp:
    case EOpLdexp:
    case EOpMix:
    case EOpLit:
    case EOpMax:
    case EOpMin:
    case EOpModf:
    // case EOpGenMul: TODO:
    case EOpPow:
    case EOpReflect:
    case EOpRefract:
    // case EOpSinCos: TODO:
    case EOpSmoothStep:
    case EOpStep:
        break;
    default:
        return true;
    }

    // TODO: array and struct behavior

    // Try converting all nodes to the given node's type
    TIntermSequence convertedArgs(numArgs, nullptr);

    // Try to convert all types to the nonConvArg type.
    for (int nonConvArg = 0; nonConvArg < numArgs; ++nonConvArg) {
        // Try converting all args to this arg's type
        for (int convArg = 0; convArg < numArgs; ++convArg) {
            convertedArgs[convArg] = addConversion(op, args[nonConvArg]->getAsTyped()->getType(),
                                                   args[convArg]->getAsTyped());
        }

        // If we successfully converted all the args, use the result.
        if (std::all_of(convertedArgs.begin(), convertedArgs.end(),
                        [](const TIntermNode* node) { return node != nullptr; })) {

            std::swap(args, convertedArgs);
            return true;
        }
    }

    return false;
}

void TIntermBinary::updatePrecision()
{
    if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
        getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
        if (getQualifier().precision != EpqNone) {
            left->propagatePrecision(getQualifier().precision);
            right->propagatePrecision(getQualifier().precision);
        }
    }
}

void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
{
    if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat && getBasicType() != EbtFloat16))
        return;

    getQualifier().precision = newPrecision;

    TIntermBinary* binaryNode = getAsBinaryNode();
    if (binaryNode) {
        binaryNode->getLeft()->propagatePrecision(newPrecision);
        binaryNode->getRight()->propagatePrecision(newPrecision);

        return;
    }

    TIntermUnary* unaryNode = getAsUnaryNode();
    if (unaryNode) {
        unaryNode->getOperand()->propagatePrecision(newPrecision);

        return;
    }

    TIntermAggregate* aggregateNode = getAsAggregate();
    if (aggregateNode) {
        TIntermSequence operands = aggregateNode->getSequence();
        for (unsigned int i = 0; i < operands.size(); ++i) {
            TIntermTyped* typedNode = operands[i]->getAsTyped();
            if (! typedNode)
                break;
            typedNode->propagatePrecision(newPrecision);
        }

        return;
    }

    TIntermSelection* selectionNode = getAsSelectionNode();
    if (selectionNode) {
        TIntermTyped* typedNode = selectionNode->getTrueBlock()->getAsTyped();
        if (typedNode) {
            typedNode->propagatePrecision(newPrecision);
            typedNode = selectionNode->getFalseBlock()->getAsTyped();
            if (typedNode)
                typedNode->propagatePrecision(newPrecision);
        }

        return;
    }
}

TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const
{
    const TConstUnionArray& rightUnionArray = node->getConstArray();
    int size = node->getType().computeNumComponents();

    TConstUnionArray leftUnionArray(size);

    for (int i=0; i < size; i++) {

#define PROMOTE(Set, CType, Get) leftUnionArray[i].Set(static_cast<CType>(rightUnionArray[i].Get()))
#define PROMOTE_TO_BOOL(Get) leftUnionArray[i].setBConst(rightUnionArray[i].Get() != 0)

#ifdef GLSLANG_WEB
#define TO_ALL(Get)   \
        switch (promoteTo) { \
        case EbtFloat: PROMOTE(setDConst, double, Get); break; \
        case EbtInt: PROMOTE(setIConst, int, Get); break; \
        case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \
        case EbtBool: PROMOTE_TO_BOOL(Get); break; \
        default: return node; \
        }
#else
#define TO_ALL(Get)   \
        switch (promoteTo) { \
        case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
        case EbtFloat: PROMOTE(setDConst, double, Get); break; \
        case EbtDouble: PROMOTE(setDConst, double, Get); break; \
        case EbtInt8: PROMOTE(setI8Const, char, Get); break; \
        case EbtInt16: PROMOTE(setI16Const, short, Get); break; \
        case EbtInt: PROMOTE(setIConst, int, Get); break; \
        case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \
        case EbtUint8: PROMOTE(setU8Const, unsigned char, Get); break; \
        case EbtUint16: PROMOTE(setU16Const, unsigned short, Get); break; \
        case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \
        case EbtUint64: PROMOTE(setU64Const, unsigned long long, Get); break; \
        case EbtBool: PROMOTE_TO_BOOL(Get); break; \
        default: return node; \
        }
#endif

        switch (node->getType().getBasicType()) {
        case EbtFloat: TO_ALL(getDConst); break;
        case EbtInt: TO_ALL(getIConst); break;
        case EbtUint: TO_ALL(getUConst); break;
        case EbtBool: TO_ALL(getBConst); break;
#ifndef GLSLANG_WEB
        case EbtFloat16: TO_ALL(getDConst); break;
        case EbtDouble: TO_ALL(getDConst); break;
        case EbtInt8: TO_ALL(getI8Const); break;
        case EbtInt16: TO_ALL(getI16Const); break;
        case EbtInt64: TO_ALL(getI64Const); break;
        case EbtUint8: TO_ALL(getU8Const); break;
        case EbtUint16: TO_ALL(getU16Const); break;
        case EbtUint64: TO_ALL(getU64Const); break;
#endif
        default: return node;
        }
    }

    const TType& t = node->getType();

    return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()),
                            node->getLoc());
}

void TIntermAggregate::setPragmaTable(const TPragmaTable& pTable)
{
    assert(pragmaTable == nullptr);
    pragmaTable = new TPragmaTable;
    *pragmaTable = pTable;
}

// If either node is a specialization constant, while the other is
// a constant (or specialization constant), the result is still
// a specialization constant.
bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TIntermTyped& node2)
{
    return (node1.getType().getQualifier().isSpecConstant() && node2.getType().getQualifier().isConstant()) ||
           (node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
}

struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
    void visitSymbol(TIntermSymbol* symbol) override {
        if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
            symbol->getWritableType().getSampler().setCombined(true);
        }
    }
    bool visitAggregate(TVisit, TIntermAggregate* ag) override {
        using namespace std;
        TIntermSequence& seq = ag->getSequence();
        TQualifierList& qual = ag->getQualifierList();

        // qual and seq are indexed using the same indices, so we have to modify both in lock-step
        assert(seq.size() == qual.size() || qual.empty());

        size_t write = 0;
        for (size_t i = 0; i < seq.size(); ++i) {
            TIntermSymbol* symbol = seq[i]->getAsSymbolNode();
            if (symbol && symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler()) {
                // remove pure sampler variables
                continue;
            }

            TIntermNode* result = seq[i];

            // replace constructors with sampler/textures
            TIntermAggregate *constructor = seq[i]->getAsAggregate();
            if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
                if (!constructor->getSequence().empty())
                    result = constructor->getSequence()[0];
            }

            // write new node & qualifier
            seq[write] = result;
            if (!qual.empty())
                qual[write] = qual[i];
            write++;
        }

        seq.resize(write);
        if (!qual.empty())
            qual.resize(write);

        return true;
    }
};

void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root)
{
    TextureUpgradeAndSamplerRemovalTransform transform;
    root->traverse(&transform);
}

const char* TIntermediate::getResourceName(TResourceType res)
{
    switch (res) {
    case EResSampler: return "shift-sampler-binding";
    case EResTexture: return "shift-texture-binding";
    case EResImage:   return "shift-image-binding";
    case EResUbo:     return "shift-UBO-binding";
    case EResSsbo:    return "shift-ssbo-binding";
    case EResUav:     return "shift-uav-binding";
    default:
        assert(0); // internal error: should only be called with valid resource types.
        return nullptr;
    }
}


} // end namespace glslang
